DeepSeek总结的一个面向 DuckDB 的“自然语言转 SQL”代理
来源https://github.com/mehrabr/agentic-duckdb-analystAgentic DuckDB Analyst一个面向 DuckDB 的“自然语言转 SQL”代理它不信任自己的第一个答案。它会编写查询、运行它、检查结果通过从便宜到昂贵的验证阶梯逐步升级然后进行修订——或者诚实地拒绝——而不是返回一个自信的猜测。Text-to-SQL 只是一个已解决的演示。这里的实质是验证阶梯、自洽层以及一个作为一等组件的评测工具——这些才是一个代理工程面试真正会考察的东西。结果离线模拟评测工具由verify_offline.py针对一个确定性模拟对象生成用于验证评测工具本身。请替换为真实模型在完整标准答案集上的数字——并保持失败类别的可见性。questions: 64 execution accuracy: 98.4% decline recall: 100.0% decline precision: 88.9% confidence precision: 100.0% confidence recall: 100.0% accuracy by difficulty: answerable buckets 100%, window 83.3%, unanswerable 100%, ambiguous 100%模拟对象返回正确的 SQL因此这些数字验证的是评测工具而不是模型。唯一的一次失败是故意设置的一次放弃——这也表现为一次不恰当的拒绝将拒绝精确率降至 8/9。替换为真实模型后这些数字才变得有意义。准确率是根据结果集等价性与人工验证的标准答案行进行比较而不是 SQL 字符串匹配——两个不同的查询可能同样正确。验证阶梯成本阶梯我们只在信心需要时才会向上攀登策略在Settings中是明确的因此一个清晰的问题只花费一次模型调用而昂贵的验证只在必要时才进行。层级成本捕获内容触发条件0 — 执行保护免费解析/错误列/类型错误DuckDB 的错误文本会被反馈用于自我修正始终执行1 — 结果合理性便宜空结果 / 全 NULL / 退化结果始终执行2 — 意图对齐1 次调用查询运行但回答了错误的问题将 SQL 反向翻译成英语与意图进行比较verify_mode默认在层级 1 发现异常时触发3 — 自洽性N 次调用抽取独立样本按结果集等价性进行聚类衡量一致性揭示疑虑consistency_mode默认仅在路径不稳时触发如果所有层级都耗尽代理会返回gave_upTrue。一个经过校准的“我无法验证这一点”胜过看似合理的错误数字——并且评测工具会衡量这个不确定性信号是否可信根据实际错误情况的精确率/召回率。为什么标准答案集不是规范的 TPC-H 22 个查询标准的 22 个查询会逐字出现在模型的训练数据中因此根据它们打分衡量的是模型的记忆能力。questions.yaml中包含了针对同一模式的64 个原始提示分为三种类型可回答50 个—— 一个正确的结果。按类别划分单表 12 个连接 12 个聚合 14 个窗口函数 6 个嵌套查询 6 个因此低分可以按类别诊断。不可回答8 个—— 模式中没有这样的列/表/概念例如“客户 1 的电子邮件地址”。正确的行为是拒绝而不是编造 SQL。这是“放弃”真正发挥作用的地方。有歧义6 个—— 存在多种站得住脚的解读例如“前五名客户”——按消费额余额订单数量。正确 答案匹配任何列出的合理解释认可一种站得住脚的解读而不是因为措辞而扣分。因为对于不可回答的问题拒绝是正确答案所以评测工具会单独报告弃权情况拒绝召回率在不可回答的问题中它拒绝了多少和拒绝精确率在所有拒绝中有多少是恰当的——低值意味着它在可回答的问题上也退缩了。信心校准仅针对已承诺的答案进行衡量。可回答/有歧义问题的标准答案集可以被快照analyst snapshot这样对参考查询的不小心修改就不会悄悄地移动目标。局限性请阅读列比较是按位置而不是按排列顺序。正确列但顺序不同将被判错。Spider 测试套件的评估器会搜索排列这是一个 v1 项目诚实地列出而不是隐藏。模式检索是基于词法且较弱的。对于模糊的标识符“balance” ≠c_acctbal它会回退到完整模式。这个接口是显式的——用嵌入相似度替换score_table其他一切都不需要改动。层级 1 是启发式的。一个合法的空结果会触发不必要的层级 2 检查花费一次调用但不会导致错误答案。自洽性需要真实的 temperature 0才能获得独立的样本离线模拟只能近似模拟分歧。运行pipinstall-e.[llm,dev]# 或者 pip install -r requirements.txtmakeverify# 离线合成模式 模拟无需密钥maketest# 19 个单元测试python-manalyst--offlineeval# 模拟端到端python-manalyst--sf1.0eval--snapshotgold_snapshot.json# 真实运行需要密钥python-manalyst--mdmd:my_dbeval# 针对 MotherDuckpython-manalyst--offlineaskhow many ... ?python-manalyst--offline--tracetraces/run.jsonleval# 结构化追踪真实运行使用AnthropicClient需要ANTHROPIC_API_KEY--offline使用模拟对象。在Settings中设置price_in_per_mtok/price_out_per_mtok以查看成本数据。真实运行评测工具通过离线方式针对模拟对象进行自我验证。要获得有意义的数字请将其指向一个真实的模型。以下是确切的步骤。1. 密钥exportANTHROPIC_API_KEYsk-...2. 首先冻结标准答案对标准答案集进行快照这样目标就不会在多次运行之间漂移python-manalyst snapshot--sf1.0--outgold_snapshot.jsonsf1.0大约是 1GB 的 TPC-H 数据生成需要几秒钟在你调试时可以降低到--sf 0.1以获得更快、更便宜的测试。3. 运行持久化包含成本和重复次数python-manalyst\--modelclaude-sonnet-4-6\--price-in3--price-out15\eval--sf1.0--snapshotgold_snapshot.json\--repeat3--outruns/sonnet--price-in / --price-out是每百万 token 的美元价格。请将它们设置为你的提供商当前公布的费率——它们默认值为 0不计算成本正是为了避免硬编码可能过时的数据。--repeat 3会完整运行整个测试套件三次。模型不是确定性的一个数字会掩盖这一点。你会得到主要指标的平均值/标准差/最小值/最大值。--out runs/sonnet会将运行结果写入磁盘。使用 MotherDuck 替代本地 TPC-Hexportmotherduck_token... python-manalyst--modelclaude-sonnet-4-6 --price-in3--price-out15\eval--mdmd:my_db--snapshotgold_snapshot.json--outruns/sonnet-md4. 写入磁盘的内容runs/sonnet/目录下misses.csv—— 仅包含它答错的题目以及它最终确定的 SQL。这是你撰写分析报告时需要的文件。outcomes.csv—— 每个题目每次运行的结果结论、置信度、尝试次数、一致性、成本、延迟、最终 SQL。report.json—— 摘要面板准确率、拒绝召回率/精确率、信心校准、按难度分类的准确率、平均成本/延迟。aggregate.json—— 多次重复运行的平均值/标准差/最小值/最大值。meta.json—— 模型、价格、规模因子、设置、时间戳。5. 按此顺序阅读aggregate.json→ 标题准确率以及它在多次运行间的波动情况。report.json→ 哪些难度类别失败了以及拒绝召回率是否保持它是否仍然拒绝不可回答的问题还是开始编造列了。misses.csv→ 实际的失败案例及其背后的 SQL。分析文章就在这里。比较模型使用不同的--model和--out再次运行步骤 3然后比较两个report.json文件。相同的评测工具相同的冻结标准答案两个模型——这是一个公平的比较也是第二篇分析文章的内容。项目结构analyst/ config.py Settings: 所有配置项 升级策略集中在一处 db.py DuckDB TPC-H 设置, MotherDuck 路径, 只读执行 schema.py 模式描述 词法检索已预留嵌入接口 comparator.py 结果集等价性多重集合、浮点数容忍、顺序无关 consistency.py 层级 3: 聚类独立样本, 衡量一致性 agent.py 四层阶梯 成本感知升级 置信度 gold.py 标准答案题目 快照 metrics.py 按难度分类的准确率, 成本/延迟, 不确定性校准 harness.py 在标准答案集上运行代理, 评分, 报告 llm.py 提供者接口 Anthropic 客户端 离线模拟 用量 trace.py JSONL 运行跟踪器可观测性 cli.py eval / snapshot / ask tests/ 19 个单元测试: comparator, consistency, agent, harness, schema, gold questions.yaml 64 题标准答案集: 可回答 不可回答 有歧义 demo.py 离线夹具完整合成 TPC-H 模拟构建器 run.py 便捷入口点 verify_offline.py 无需网络的冒烟测试路线图v0 版本包含所有四个层级、成本感知升级、检索、快照、跟踪、弃权 校准指标以及一个包含 64 道覆盖可回答、不可回答和有歧义三种类型题目的标准答案集。下一步列排列不变性评分、基于嵌入的检索以及一项真实的分歧研究层级 3 是否真的能捕获单次传递遗漏的错误以及它是否能在对抗性集合上提高拒绝精确率。这项研究将是让项目落地的关键报告。