让Agent写SQL,到底该给它看什么?只给建表语句,还是顺手塞几行真实数据?这个问题在大多数让Agent起草SQL的团队里反复上演:一条查询过了评审、在预发环境跑通、返回的结果看着像那么回事,但其实是错的。
一位评审怪提示词把数据藏起来了,另一位怪把生产数据行贴进模型上下文的习惯。两个人说的是同一条流水线两端的同一个缺陷,谁也拿不出一个能终结争论的测量结果。
有个例子很能说明问题。需求是"上季度欧盟的活跃客户",只给Schema的上下文会生成 WHERE status = 'active',可这一列实际存的是 A、I、P 这样的单字符,过滤条件匹配到零行。往上下文里加五行样本,模型能照抄这套编码,但一封客户邮箱和一段不完整的地址也一并进了提示词。分歧是真实的,靠直觉解决不了。
立场A:Schema就是契约
第一种立场认为,DDL、注释和约束定义是Agent唯一该拿到的上下文,因为它们稳定、可版本化、可评审。Schema能在拉取请求里做diff、能钉到某个提交、能事后重放,这让Agent的输出具备行数据转储永远给不了的可复现性。支持者还说,如果模型非得靠字面值才能答对,那缺失的知识应该放进受治理的查找表,而不是塞进提示词。
隐私这边的论据同样具体。样本行是把受监管数据搬进第三方推理调用最省事的方式,而多数评审流程根本没记录发出去过哪些行。按这个视角,只给Schema不是限制,是控制手段;任何准确率损失都是文档或参考数据需要补课的信号。
立场B:分布也是契约的一部分
第二种立场认为,很多约定藏在值里而不是DDL里,再多的列注释也找不回来。编码过的状态标志、软删除哨兵值、退款用的负数金额、以最小货币单位存储的金额、带本地偏移列的UTC时间戳、历史导入留下的尾随空格——这些对只读 PRAGMA table_info 的模型统统不可见。踩过这些坑的评审者,往往很快就对只给Schema的提示词失去信任。
这一派通常接受脱敏而不是拒绝样本。如果样本通过一个保留形状和基数、替换敏感字面值的掩码函数生成,准确率收益还在,暴露面收窄了。反方当然会说,掩码函数也是代码,代码在被当作边界信任之前得先有自己的测试。
两边其实都同意模型需要这些信息,分歧在于信息该放在哪、归谁管。只给Schema的一派想把约定提升成有文档的参考数据,样本一派想靠经验观察并做掩码。一个团队完全可以同时持有两种看法:把样本当诊断工具,把参考表当生产环境的修复方案。
出路只有一个小而枯燥的测量。把两种上下文放到同一套冻结的评测集上打分,全部在本地SQLite里跑。第一步冻结30条评测项,每条只存问题、金标准查询和预期结果,不存模型输出。30条是刻意选小的:足够暴露值约定的失败,又便宜到每次改提示词都能重跑。
第二步写两个上下文构建器,一个只吐DDL,另一个吐DDL加每表少量掩码样本,采样要带显式种子,保证跨运行、跨评审者可复现。第三步按结果集打分而不是按字符串比对——把排序后的结果行做哈希,这一个选择就能消掉评审者关于"查询看起来对不对"的大部分分歧。
第四步两种上下文各跑三次,因为单次通过会掩盖评审者迟早要在预发环境里发现的抖动。每个失败打上标签:编码、空值处理、单位换算、语法,标签和评测集放在同一个仓库里。第五步先读失败标签,再读总体准确率——一个靠语法赢两分却输掉所有编码用例的上下文,对报表类工作负载来说就是错误的默认值。
决策规则可以很直接:从只给Schema开始跑一次,如果失败标签里没有值约定类原因,就停手,把精力花在文档上。如果至少三分之一的失败是编码或单位换算,只给受影响的表加掩码样本,再用同一套评测集重跑。按表和按失败原因逐级升级,绝不按项目一刀切,让提示词保持证据允许的那么窄。
这套对比会成倍放大调用量:30条、3次重复、2种上下文,外加每次改提示词后的重跑。MonkeyCode的免费模型额度能消掉起草侧的成本顾虑,免费服务器选项则覆盖跑测试脚本和SQLite夹具。规划之前请到项目页确认当前的token额度和服务器条款,促销会变,这里不把它当作长期承诺。需要说明:本文是作为MonkeyCode产品推广的一部分准备的。
局限也得说清楚。30条是冒烟测试,不是统计上站得住的基准,一季度才出现一次的罕见约定它抓不到。保留形状的掩码仍可能通过基数或时间戳模式泄露信息,没有正式数据处理协议的地方不该用样本上下文。流水线里还没有结果集比对的团队应该先把这个建起来,否则字符串diff会让测试脚本的输出没法读。
热门跟贴