65.4%
Level C 规则注入
+34.6pp vs 基线
76.9%
Level D/H 最优
+46.1pp vs 基线
1. 研究动机
当你对 AI Agent 说"上个季度收入增长了多少",它面对的真正挑战不是写 SQL——而是理解:
- "收入" 是指 Net Revenue(成功支付 - 退款),不是订单金额
- "上个季度" 是指财季(Feb-Apr),不是自然季(Jan-Mar)
- "增长" 需要跟哪个基准对比
这些部落知识(Tribal Knowledge)从未被写进数据仓库,只存在于业务团队的集体记忆里。我们的实验目标是量化:把这些上下文喂给模型,到底能提升多少 SQL 准确率?以及,怎么喂最有效?
H₁(核心假设):向 Agent 注入精准业务上下文后,SQL 正确率显著高于仅提供表结构的基线。
2. 实验设计
五个 Context Level
每个 Level 在上一级基础上递增上下文量,形成严格的因果链:
A:Schema Only
5 张表的 DDL
~1,000 chars
B:+ Business Defs
列含义 & 取值说明
+1,100 chars
C:+ Filtered NL Rules
查询相关的业务规则
按 depends_on 筛选注入
D:Schema Graph
图结构的列→规则映射
视觉化表关联
H:D + Inferred
从规则推导的隐性知识
推理增强
数据集 & 规则
基于 dbt jaffle_shop 生成合成数据(200 客户、1,000 订单、5 张表)。Faker + seed=42 保证可复现。数据中刻意构造了真实世界的脏数据(channel NULL 值、部分退款记录缺失等),确保每条规则都有对应的数据场景。
Rule-3: Net Revenue
Net = SUM(success) − SUM(refunded)
需 JOIN raw_payments(不是直接用 raw_orders.amount)
Rule-4: Fiscal Quarter
Q1 = Feb–Apr, Q2 = May–Jul
非自然季——90% 的查询涉及
Rule-5: Churn vs Dormant
Dormant = 1 季度无订单
Churned = 连续 2 季度零订单
Rule-6: Channel NULL
2025-03 前 ~5% channel 为 NULL
渠道查询需 IS NOT NULL
Rule-7: Refund Independent
退款独立查询,不需 JOIN 找原始记录
某些退款缺少原始支付记录
Rule-8: MAU Definition
MAU = DISTINCT user_id
WHERE status IN ('completed','shipped')
Rule-9: ARPU
ARPU = Net Revenue / 活跃用户数
分母排除 cancelled 订单
Rule-11: Return Rate
退货率 = COUNT(returned) / COUNT(all)
用 raw_orders.status,非 payments
26 条测试查询
| 分类 | 数量 | 示例 |
| rule_dependent | 16 | "2026 Q1 净收入 vs 2025 Q1 增长?" — 需要 Rule-3 + Rule-4 |
| control | 7 | "库存低于 5 件的产品有哪些?" — 纯 SQL,不需规则 |
| ambiguous | 3 | "客单价(AOV)是多少?" — 可用不同公式,测规则是否引导正确路径 |
评测方法
硬指标(Hard Metric):模型生成的 SQL 执行结果与 Ground Truth 逐行逐列精确比较。我们实现了多层容差匹配:
- 浮点容差:自动识别小数 vs 百分比(0.88 ≈ 88.0)
- 月份格式匹配:整数月与字符串月互认(1 ≈ '2025-01')
- 列子集匹配:当模型返回多余列时(SELECT *),自动截断到 GT 列数
- 行子集匹配:当模型返回更少行时(如 LIMIT),检查是否为 GT 的子集
所有评测规则均为客观、可复现的算法,不依赖人工判断,消除了假阴性(false negative)对结论的干扰。
3. 结果
主结果表
| Level | 方法 | 准确率 | Δ 前级 | Δ 基线 | 结论 |
| A |
Schema Only |
30.8% |
— | — |
裸跑基线 |
| B |
+ Business Definitions |
42.3% |
+11.5pp |
+11.5pp |
列含义有帮助但有限 |
| C |
+ Filtered NL Rules |
65.4% |
+23.1pp |
+34.6pp |
🔥 规则注入是最大跳跃 |
| D |
Schema Graph + Rules |
76.9% |
+11.5pp |
+46.1pp |
🏆 图结构是最优形态 |
| H |
D + Inferred Knowledge |
76.9% |
0 |
+46.1pp |
= D:推理增强未超越手工结构 |
可视化:边际增益
按难度分类
| 难度 | Level A | Level B | Level C | Level D | Level H |
| Easy (8) | 37.5% | 62.5% | 75.0% | 75.0% | 75.0% |
| Medium (13) | 23.1% | 30.8% | 53.8% | 76.9% | 76.9% |
| Hard (5) | 40.0% | 60.0% | 80.0% | 80.0% | 80.0% |
最显著改进在 medium 难度:23.1% → 76.9%(+53.8pp)——这些查询最需要业务规则来消除歧义。
D vs H:逐题对比
| 状态 | 查询 | 说明 |
| Both ✅ | 18 题 | D 和 H 均正确 |
| H✅ D❌ | Q1, Q9 | 推理增强修复了 2 道题 |
| H❌ D✅ | Q2, Q18 | 但推理也引入了 2 道新错误 |
| Both ❌ | Q12, Q16, Q21 | 3 道顽固错误,超出当前方法能力 |
D 和 H 净效果完全相同——推理增强的收益(+2)被引入的噪音(-2)完全抵消。结论:手工构建的结构化上下文已达到当前模型的能力天花板。
4. 关键发现
Finding 1:业务上下文是 Text-to-SQL 的第一性要素。
从 A(裸 Schema,30.8%)到 C(注入规则,65.4%),准确率翻了一倍多。仅仅让模型"知道收入是 Net Revenue"、 "知道财季从 2 月开始",就能解决一半以上的错误。模型不缺 SQL 能力——缺的是"数据是什么意思"。
Finding 2:上下文的结构比数量更重要。
Level C 和 Level D 给模型的是同样的规则内容,区别只在于排列方式:C 是扁平列表,D 是图结构的列→规则映射。这 11.5pp 的差距证明:同样信息,结构化呈现使模型能更准确地定位和应用规则。这对 Agent 架构设计有直接启示——MCP context 的组织方式可能比 context 的内容更重要。
Finding 3:手工结构化已达天花板,推理增强不是银弹。
Level H 在 D 的基础上注入了从规则推导出的深层知识(列权威性、时间锚定、常见陷阱等),但最终准确率与 D 完全相同。推理增强修复了 2 道题,但也引入了 2 道新错误——净收益为零。自动推理的"噪音成本"恰好抵消了其"洞察收益"。
5. 方法论说明
为什么是 5 个 Level?
我们刻意设计了 A→B→C→D→H 的因果链,每个 Level 只增加一种新元素:
- A→B:隔离"列含义"的效果
- B→C:隔离"业务规则"的效果(最关键的跳跃)
- C→D:隔离"结构化呈现"的效果(同样的规则,不同的组织方式)
- D→H:隔离"推理增强"的效果(同样的结构,加上推导出的知识)
假阴性消除
我们投入了大量精力确保评测体系不会"冤枉"模型:
- 浮点格式:模型输出 0.88(小数),GT 要求 88.0(百分比)→ 自动识别为等值
- 月份格式:模型输出 1(整数),GT 用 '2025-01'(字符串)→ 自动匹配
- SELECT * 列数:模型用 `SELECT *` 返回 6 列,GT 只要 3 列 → 自动截断到正确列数
- LIMIT 行数:模型返回 top 5,GT 返回全部 → 检查子集关系
- LEFT vs INNER JOIN:提示中加入明确的 LEFT JOIN 指引
模型方差控制
DeepSeek V4 Flash 存在显著方差——同一 prompt 两次运行可能得到不同 SQL。我们通过以下方式控制:
- Temperature = 0(最小化随机性)
- 每个 Level 单次运行 26 题,记录原始 SQL 以备审计
- 所有结论基于 Level 间对比(同一模型、同一批次运行),避免跨时间比较引入偏差
6. 局限与展望
已知局限
- 合成数据:5 表、200 客户、1,000 订单的规模远小于真实企业环境。表间关系的复杂度和脏数据的多样性有限。
- 规则覆盖不全:Q12(列选择错误)、Q16(渠道占比)和 Q21(NTILE 分位)三道顽固错误提示我们——当前 8 条规则覆盖不了所有边缘情况。
- 单一模型:仅测试了 DeepSeek V4 Flash。不同模型的"上下文敏感度"可能不同——这是下一步实验的方向。
- 仅测文本上下文:没有测试结构化 API(如 MCP context tools)或少量示例(few-shot)。
对 Agent 架构的启示
这项实验的结果直接关联到 a16z 最近提出的 "Your Data Agents Need Context" 论点。我们的量化证据表明:Context Layer 的设计——不仅是"有什么上下文",更是"上下文怎么组织"——是决定 Agent 表现的第一性因素。
如果你在构建数据 Agent 或 Context Layer,欢迎交流。