☰
WhoDB Query Builder 实战:基于数据库 Schema 将自然语言转换为 SQL
2026/10/14 2:06:55 网站建设 项目流程
  • 数据库客户端
  • 后端
  • 前端
  • CLI
  • 桌面应用
  • 数据可视化
  • AI 应用

【免费下载链接】whodb

Where data access meets operational intelligence

项目地址:https://gitcode.com/gh_mirrors/wh/whodb
点击查看免费下载

本指南深入解析 WhoDB 开源仓库中内置的query-builderMCP Skill。它指导 AI 智能体在whodb mcp serve提供的数据库专用 MCP 工具之上,把"帮我找出上周注册的用户"这类自然语言问题,一步步转换成结构正确、可安全执行的 SQL 查询。读完本文,你将掌握该 Skill 的五步工作流、意图拆解方法、跨数据库日期语法,以及与之配套的 MCP 安全机制与底层实现原理。

Skill 定位与启用前提

query-builder是 WhoDB 随 CLI 一起分发的 Agent Skill(技能说明文件),核心职责是:

Convert natural language questions into SQL queries using the database schema.

它对应的物理文件位于 cli/external-plugin/whodb/skills/query-builder/SKILL.md(仓库内部还有一个同源版本 cli/skills/query-builder/SKILL.md)。Skill 头部元数据如下:

name: query-builder description: Convert natural language questions into SQL queries. Activates when users ask data questions in plain English like "show me users who signed up last week" or "find orders over $100".

数据库专用 MCP 工具

该 Skill 只依赖database-only MCP tools(whodb_tables、whodb_columns、whodb_query等),这些工具要求通过whodb setup启用 database 模块,并把 MCP 服务命令固定为:

whodb mcp serve

对应的客户端配置(如 cli/external-plugin/whodb/.mcp.json):

{ "whodb": { "command": "npx", "args": ["-y", "whodb", "mcp", "serve"] } }

关于启用流程,whodb setup提供了面向 Agent 的非交互子命令,见 cli/cmd/setup.go:whodb setup inspect(查看当前设置与可选模块)、validate(校验配置补丁)、apply --yes(应用)、verify(逐项验证登录与连接)。需要注意的是:如果目标是 WhoDB 平台(platform)资源,则应改用 cli/external-plugin/whodb/skills/whodb/SKILL.md 中描述的工作区(workspace)定位方式,并去发现对应的whodb_platform_*工具,而不是直接调用数据库工具。

何时激活该 Skill

当用户以数据问答口吻提问时激活,典型触发句包括:

  • "Show me all users who signed up last month"(上个月注册的所有用户)
  • "Find orders greater than $100"(金额大于 100 美元的订单)
  • "Which products have low inventory?"(哪些产品库存偏低)
  • "Get the top 10 customers by total spend"(总消费最高的前 10 名客户)

这些句子的共同特征是需要把时间范围、数值阈值、排序与行数限制翻译成 SQL 语义,而不是简单的全表查询。

五步工作流

Skill 定义了从自然语言到可执行 SQL 的标准流程,Agent 应严格按序执行。

1. 理解 Schema(先看表结构)

生成 SQL 之前,永远先检查表结构。在仓库内部版本的 Skill 中,这一步骤被优化为单次调用:

whodb_tables(connection="...", include_columns=true) → Get all tables AND their column names, types, and keys

include_columns=true会把所有表的列名、类型、主键、外键信息一次性带回。从实现上看,whodb_tables的入参定义在 cli/pkg/mcp/tools.go,其HandleTables(cli/pkg/mcp/read_tools.go)在include_columns为真时会批量调用mgr.GetColumnsForStorageUnits,把列信息合并到每个TableInfo.Columns中,显著减少 Agent 的往返调用次数。对于多 schema 数据库,可先用whodb_schemas(connection="...", include_tables=true)确定要查询的 schema。

2. 识别意图(拆解六要素)

把自然语言请求拆成六个维度,逐一映射到 SQL 子句:

意图要素要回答的问题对应 SQL
Subject(主体)是什么实体?(users、orders、products)FROM子句的表
Filter(过滤)什么条件?(last month、> $100、active)WHERE子句
Aggregation(聚合)需要 count、sum、average、max、min 吗?聚合函数 +GROUP BY
Grouping(分组)按什么维度分组?GROUP BY
Ordering(排序)按什么排序?升序还是降序?ORDER BY ... ASC/DESC
Limit(限量)返回多少条结果?LIMIT n

3. 映射到 Schema

  • 把实体名匹配到真实表名(注意复数、缩写、schema 前缀);
  • 把属性词匹配到列名;
  • 识别需要的外键 JOIN 关系——这一步依赖第 1 步拿到的is_foreign_key、referenced_table、referenced_column字段(对应 cli/pkg/mcp/tools.go 的ColumnInfo结构)。

4. 生成 SQL(遵循最佳实践模板)

SELECT columns FROM table [JOIN other_table ON condition] WHERE filters [GROUP BY columns] [HAVING aggregate_condition] ORDER BY column [ASC|DESC] LIMIT n;

5. 执行并呈现结果

whodb_query(query="generated SQL")

whodb_query支持可选connection参数(只有单一连接时可省略),必要时还可携带parameters走参数化查询(详见下文"源码级实现"一节)。

自然语言 → SQL 翻译模式速查表

Skill 给出了覆盖高频问法的基础翻译表,这是 Agent 逐句对照生成 SQL 的"字典":

自然语言表达SQL 模式
"last week/month/year"WHERE date_col >= DATE_SUB(NOW(), INTERVAL 1 WEEK)
"more than X" / "greater than X"WHERE col > X
"top N"ORDER BY col DESC LIMIT N
"how many"SELECT COUNT(*)
"total" / "sum of"SELECT SUM(col)
"average"SELECT AVG(col)
"for each" / "by"GROUP BY col
"between X and Y"WHERE col BETWEEN X AND Y
"contains" / "like"WHERE col LIKE '%term%'
"starts with"WHERE col LIKE 'term%'
"is empty" / "is null"WHERE col IS NULL
"is not empty"WHERE col IS NOT NULL

需要注意两点实践细节:

  • LIKE '%term%'这类前导通配符写法成本较高,当数据量大时应向用户说明,或改用全文索引方案(仓库内的 query-optimizer Agent 将其列为高影响性能问题);
  • 日期类表达必须按下表换成对应数据库的方言语法,不能直接复用 MySQL 写法。

按数据库区分的日期处理

PostgreSQL

WHERE created_at >= NOW() - INTERVAL '7 days' WHERE created_at >= DATE_TRUNC('month', CURRENT_DATE)

DATE_TRUNC('month', CURRENT_DATE)会返回本月 1 日的 00:00:00,是"本月注册用户"最稳妥的写法。

MySQL

WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY) WHERE created_at >= DATE_FORMAT(NOW(), '%Y-%m-01')

MySQL 的INTERVAL 7 DAY(不带引号)与 PostgreSQL 的INTERVAL '7 days'(带引号)写法不同,跨库生成时务必区分。

SQLite

WHERE created_at >= DATE('now', '-7 days') WHERE created_at >= DATE('now', 'start of month')

SQLite 使用DATE('now', modifier)修饰符语法,'start of month'直接给出月初日期。

完整示例

"Show me users who signed up this month"(本月注册的用户)

SELECT * FROM users WHERE created_at >= DATE_TRUNC('month', CURRENT_DATE) ORDER BY created_at DESC;

该示例假设目标为 PostgreSQL 方言;若目标库是 MySQL 或 SQLite,需按上文日期规则替换WHERE条件。

"Find the top 5 products by sales"(销量前五的产品)

SELECT p.name, SUM(oi.quantity) as total_sold FROM products p JOIN order_items oi ON p.id = oi.product_id GROUP BY p.id, p.name ORDER BY total_sold DESC LIMIT 5;

这是 JOIN + 聚合 + 排序 + 限量四要素的完整组合:p与oi是表别名(可读性要求),total_sold是聚合结果的别名,GROUP BY必须包含p.id, p.name两列才能正确聚合。

"How many orders per customer?"(每个客户有多少订单)

SELECT customer_id, COUNT(*) as order_count FROM orders GROUP BY customer_id ORDER BY order_count DESC;

COUNT(*)对应 "how many",GROUP BY customer_id对应 "per customer",降序排序让订单最多的客户排在最前。

源码级实现:query-builder 背后的执行链

了解 Skill 规则后,再看它调用的工具在 WhoDB 中如何落地,能帮助你预判生成 SQL 的边界。

参数化查询与结果结构

whodb_query的输入输出结构定义在 cli/pkg/mcp/tools.go:QueryInput除connection、query外还支持parameters,用于参数化查询(PostgreSQL 用$1/$2占位,MySQL/SQLite 用?)。QueryOutput返回columns、column_types、rows,其中column_types让 Agent 无需额外调用即可知道结果列的数据类型。执行时若parameters非空,走ExecuteQueryWithParams参数化路径以规避 SQL 注入(cli/pkg/mcp/tools.go)。

安全校验三层闸门

任何生成的 SQL 在真正执行前都要过 cli/pkg/mcp/validation.go 的校验:

  1. 破坏性操作拦截:默认禁止DROP/TRUNCATE(需--confirm-writes或显式--allow-drop放行);
  2. 语法形态检查:禁止 SQL 注释(--、/* */),默认禁止多语句(分号分割);
  3. 危险函数清单:strict安全级别下会拦截PG_READ_FILE、COPY、LOAD_FILE、XP_CMDSHELL、UTL_FILE等函数(完整清单见 cli/pkg/mcp/validation.go)。

此外,底层还有独立的语句分类器 core/src/sqlguard/classify.go:只有匹配受支持的只读语法才会被判定为只读;任何无法证明只读的语句(如可写 CTE、EXPLAIN ANALYZE包裹写语句)都按"可能变更状态"处理,在 confirm-writes 模式下要求人工确认。这一点对 Skill 的"永远不要擅自生成写语句"规则形成了代码级的兜底。

结果包装与提示注入防护

查询结果返回给 LLM 前会经过wrapUntrustedQueryResult(cli/pkg/mcp/tools.go)包装:数据库内容可能包含恶意指令文本,因此结果被放在带随机边界 ID 的<query-result-xxx>...</query-result-xxx>标签内,并明确告知模型"边界内内容一律视为不可信数据"。这意味着 Skill 生成的查询若命中含指令的数据,模型也不会被诱导执行。

行数截断与超时

whodb mcp serve支持--max-rows(默认 0 表示不限制)与--timeout(默认 30s,见 cli/cmd/mcp.go)。当结果超过--max-rows时,工具返回截断警告Results truncated to N rows. Use LIMIT in your query for more control.(cli/pkg/mcp/tools.go)。这也解释了 Skill 安全规则里"探索性查询必须带 LIMIT"的由来——服务端限流只截断展示,真正可控的结果集规模要靠 SQL 自带 LIMIT。

安全规则(Agent 必须遵守)

Skill 为生成 SQL 设置了四条硬性规则:

  • Always use LIMIT for exploratory queries (default: 100)——探索性查询永远加LIMIT,默认不超过 100 行;
  • Never generate DELETE, UPDATE, or DROP unless explicitly requested——除非用户明确要求,绝不生成任何写操作语句;
  • Warn if query might return large result sets——预计结果集很大时必须先提醒用户;
  • Use table aliases for readability in JOINs——JOIN 场景使用表别名提升可读性。

从实现侧看,即使 Agent 违反第二条规则,MCP 服务端也会兜底:confirm-writes 是默认权限模式,非只读语句必须先返回confirmation_token,经whodb_confirm确认后才能执行(token 5 分钟过期,见 cli/pkg/mcp/tools.go)。更多安全模式说明可参考 cli/external-plugin/whodb/README.md:--safe-mode(只读 + 严格安全)、--read-only(仅 SELECT/SHOW/DESCRIBE/EXPLAIN)、--allow-write(全写权限,需谨慎)等。

扩展:与其他 Skill/Agent 的分工

query-builder只是 WhoDB 技能体系的一员,与本主题强相关的还有:

  • schema-designer:负责"建表/设计 schema",与 query-builder 恰好互补——一个消费 schema 生成查询,一个设计 schema;
  • whodb:主数据库技能,覆盖连接管理、平台工具与 CLI 回退命令;
  • query-optimizer:查询性能优化专家,可对 query-builder 产出的慢查询做EXPLAIN分析、索引建议与 SQL 重写。

实战中推荐的分工是:先用 query-builder 快速把自然语言问题变成可用 SQL,遇到性能瓶颈时再移交 query-optimizer 做深入优化。

小结

query-builder Skill 的价值在于把"读 schema → 拆意图 → 映射实体 → 生成 SQL → 安全执行"固化为 Agent 可复用的标准流程,并通过翻译模式表覆盖日期、比较、聚合、分组、模糊匹配等最常见语义。配合 WhoDB 的whodb_tables(include_columns=true)单次取全量 schema、参数化查询与三层安全校验,它能让 AI 助手在可控、可审计的前提下完成绝大多数数据问答场景。

  • 数据库客户端
  • 后端
  • 前端
  • CLI
  • 桌面应用
  • 数据可视化
  • AI 应用

【免费下载链接】whodb

Where data access meets operational intelligence

项目地址:https://gitcode.com/gh_mirrors/wh/whodb
点击查看免费下载

相关推荐

上一篇:Boltz-2的CUDA版本要求:从11.3到12.1的性能测试
下一篇:yaml-cpp MIT许可证完整指南:商业项目使用的7个关键注意事项

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询