前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
返回 AI 情报前线
All News · 全部资讯10183
  • 提示注入检测为何被同义改写绕过
  • Synapse 打通编程助手的记忆与配置
  • vLLM 与 SGLang 新增 TPU 原生后端
  • 给水印检测加门控,减少误选与修复风险
  • 用本地语音组件搭建可打断的 AI 助手
  • Claude Code 误删复盘:命令钩子的盲区
  • Mac 跨应用文本助手如何读取界面
  • 用 AI 编程智能体清理电视广告与预装应用
  • DeepSeek开放生产推理框架DeepInfer
  • 京东大促期间暂停外部安全测试
  • Coral NPU补齐矩阵单元与开源编译链
  • 向量检索与知识图谱如何协同支撑 RAG
  • 让编程助手接入浏览器完成调试闭环
  • 先验证分类器,再让 AI 排查运行轨迹
  • 录制模型响应,隔离评测代码与模型变动
  • 审查 AI 生成 PR,先核对任务边界
  • 用有效吞吐压测确定模型接口并发上限
  • Agent 改一个字段,如何证明操作正确
  • 用多任务决策模型自动分流 CVE 漏洞
  • 逐步核算 Token,定位 Agent 的结构性浪费
  • Agent 生成 SQL,如何控制重跑漂移
  • 审核超时后的任务释放与计费隔离
  • DeepSeek 开源大规模推理框架 DeepInfer
  • DeepInfer 开源,公开大规模推理部署能力
  • Cloudflare预览低价结构化抽取模型
  • Headroom 在本地压缩智能体上下文
  • 智能体改记忆,如何验证没有误伤
  • llama-server 工具控制与停止条件现兼容问题
  • 模型快十倍,智能体为何只快一点
  • 用决策模型做评测,先调分类阈值
  • 编码 Agent 实测:成本之外看交付细节
  • Mercury 3 发布:主打高速生成与百万上下文
  • 用 Node 拆解向量池化与检索质量
  • 补齐 Oracle 方言约束,轻量模型首答率跃升
  • 拆解 Claude Code 的完整智能体循环
  • 邮件 Agent 重试前先校验退信
  • 用信号队列约束 Agent 等待邮件
  • 用 Cloudflare 搭建 Agent 收信中枢
  • 一次字符串替换如何让线上文章翻倍
  • AI 搭项目失败,先确认代码是否拉取成功
  • 检索匹配再高,也救不了过期知识库
  • 本地模型帮你给常用命令起快捷名
  • MCP 无状态改版涉及哪些迁移工作
  • 检查 Supabase 服务端鉴权的信任来源
  • 流式 AI 接口延迟该如何拆分测量
  • 模型故障切换如何追踪实际调用路径
  • 百灵开放五款语音模型供开发者组合
  • Drex Max 为电脑操作智能体输出决策概率
  • 无人值守的 Claude 循环如何耗尽额度
  • Bedrock为Claude提供严格结构化输出
  • 错误码搜不准?给向量检索补上 BM25
  • 已加载 51 / 10183
8.0
热点
AI SCORE
技术实践2026-10-20 17:43

Agent 生成 SQL,如何控制重跑漂移

dev.to · AI#Agent#数据库#可复现性
Editor brief · 编辑速览

文章比较低温单次生成与多次采样筛选两种 SQL 起草方案,并提出在自有数据库结构上回放评测的选择方法。重点是记录 SQL 原文与归一化指纹,识别重复生成时的查询和执行计划变化。

文章思维导图
Knowledge map
拖拽缩放
Full translation

完整中文译文

设想一个许多团队都可能经历的周二:Agent 重新起草了前一天生成过的查询,审阅者又批准了一遍,而执行计划却悄悄从索引查找变成了全表扫描。没有人修改 prompt,schema 对比结果为空,服务提供商也没有宣布模型变更。接着,两位工程师花了整整一个下午争论:起草流程究竟应该固定为一个确定性输出,还是有意多采样几次,再从中筛选。

这个问题需要一套决策规则,而不是凭个人喜好争论,因为答案决定了你如何分配免费 token 额度、CI 究竟能可靠地断言什么,以及代码审阅时你能给出怎样的依据。下面会公平呈现两种我认为最站得住脚的立场,提供一套可在你自己的 schema 上复现、用来区分两者效果的测试框架,再给出选择规则。本文不提供任何服务商基准测试结论;你据以行动的每一个数字,都应该来自自己的回放测试。

1. 公平陈述两种站得住脚的立场

立场 A——固定输出。 以 temperature 0 发起一次调用,保存完整的 SQL 文本和规范化后的指纹,把后续任何漂移都当作需要审阅的差异,而不是噪声。这一立场的理由在于成本和流程:每份草稿只调用一次,免费额度就能覆盖更多场景;单一产物也方便附在 pull request 中、添加批注,以及在 dialect 迁移后重新检查。

它的弱点是,temperature 0 并不保证确定性。服务商侧的批处理、采样过程中浮点运算不满足结合律,以及未公开的模型修订,都可能让完全相同的输入产生不同输出。因此,立场 A 仍然需要指纹和保存下来的执行计划,不能只存一个字符串。

立场 B——多次采样。 请求 k 个候选结果,对每一个进行静态检查,再根据明确规定的成本模型,保留通过检查且执行计划成本最低的那个。理由是覆盖面:引号规则、日期运算、窗口 frame 等 dialect 边界情况,会以不同样本之间的差异显现出来;而单次贪心解码往往会把这些问题藏在看似笃定的语法背后——解析能通过,行为却不对。

它的弱点是选择偏差和成本。静态检查无法发现语义错误,因此筛选主要是在给看起来合理的候选结果重新排序;而在免费额度下,采样五次来获得一份被接受的草稿,大约会消耗单次采样五倍的预算。

双方已经达成的共识。 你需要规范化指纹、捕获的执行计划,以及审批记录。这部分共识最值得先落地,下面的测试框架正是从这里开始。

2. 三步搭建可回放的草稿测试框架

目标是写一个脚本:接收 prompt,获取候选结果,记录数据库实际如何处理它们,并在行为未经批准就发生变化时让 CI 失败。下面的示例均为说明用途,代码可以运行,但通过标准必须根据你的 schema 调整。

第 1 步——在下一次调用前守住预算

# draft_harness.py (illustrative)
from dataclasses import dataclass

@dataclass
class Budget:
    limit: int
    used: int = 0

    def charge(self, prompt: str, completion: str) -> None:
        # Rough guard only: approximate token count, not provider billing.
        estimate = (len(prompt) + len(completion)) // 4
        if self.used + estimate > self.limit:
            raise RuntimeError("draft budget exhausted; stop before the next call")
        self.used += estimate

每生成一个候选结果就计入消耗,不要等整个 prompt 处理完再计入,否则 k=5 的循环一旦遇到不顺的情况,就可能让免费额度的消耗达到预期的五倍。这个预算保护刻意采用了粗略估算,你还应该同时记录服务商实际报告的用量。

第 2 步——解析、限制表访问并生成指纹

import hashlib, sqlglot

WRITE_NODES = (sqlglot.exp.Insert, sqlglot.exp.Update, sqlglot.exp.Delete)

def inspect(sql: str, dialect: str, allowed_tables: set[str]) -> dict:
    tree = sqlglot.parse_one(sql, read=dialect)
    tables = {t.name.lower() for t in tree.find_all(sqlglot.exp.Table)}
    return {
        "parses": True,
        "unknown_tables": sorted(tables - allowed_tables),
        "has_write": any(tree.find(node) for node in WRITE_NODES),
        "fingerprint": hashlib.sha256(tree.sql(dialect=dialect).encode()).hexdigest()[:12],
    }

对规范化后的语法树生成指纹,而不是直接对原始文本生成指纹,可以消除空白和注释变动带来的干扰。因此,指纹变化就意味着查询结构发生了变化。任何引用未知表的候选结果,都应在执行前拒绝;同时显式传入 dialect 参数,避免把 Postgres 草稿悄悄当作通用 SQL 来验证。

第 3 步——捕获执行计划,并针对变化设置断言

import sqlite3

def plan(sql: str, db_path: str) -> list[str]:
    with sqlite3.connect(db_path) as conn:
        return [row[3] for row in conn.execute("EXPLAIN QUERY PLAN " + sql)]

将 (prompt_hash, fingerprint, plan, approved_by) 保存在一个纳入仓库版本管理的小表中。随后,CI 回放每个已保存的 prompt,先比较指纹,再比较执行计划;只要出现任何未经批准的差异,就判定失败。执行计划取决于具体数据库引擎,所以 SQLite 的执行计划只能作为初步预警信号;在信任结果之前,需要到目标引擎上重新捕获执行计划。

立场 B 的筛选规则

def pick(candidates: list[dict]) -> dict:
    clean = [c for c in candidates if not c["unknown_tables"] and not c["has_write"]]
    if not clean:
        raise ValueError("no candidate passed static checks")
    return min(clean, key=lambda c: (len(c["plan"]), c["fingerprint"]))

用执行计划长度充当临时成本模型,只对小型测试数据集说得过去。在把它用于任何重要场景之前,应替换成数据库引擎的成本估算,或通过探测获取行数。

3. 免费算力改变了什么,又没有改变什么

免费资源改变了这场争论中的成本因素,却没有改变正确性要求。原本负担不起的 k=5 循环,现在可能用得起了,但指纹、执行计划捕获和人工审批的必要性丝毫未变。运营方为本文提供的说明提到了 MonkeyCode 的免费模型访问和免费服务器选项,其中包括 1000 万 token 的免费额度。应将这些视为项目推广材料中的可用性声明,而不是实测吞吐量;在据此规划 CI 预算之前,请确认当前条款。

披露:本文是 MonkeyCode 产品推广活动的一部分。

一个实用的安排是,在免费服务器上运行起草和回放循环,让测试框架有一个稳定的运行环境;再把免费模型额度用在 prompt 回放上,而不是探索性聊天上。无论如何,都应让测试框架保持与服务商无关:即使 endpoint 发生变化,已保存的指纹和执行计划仍然是判断依据。

5. 局限性,以及哪些团队不适合采用

这套测试框架验证的是语法、表访问,以及某个数据库引擎的执行计划结构;它无法告诉你某个 JOIN 是否导致行数膨胀,也无法判断过滤条件是否使用了错误的时区。如果团队没有预发布环境副本、测试数据快照,或能够审批指纹的审阅者,就不应该围绕指纹构建 CI,因为那样只是在把噪声固定下来。

这套方法也不太能适应 dialect 的频繁变化:解析器往往落后于实际数据库引擎,因此解析失败的查询仍可能是正确的。在升级期间,测试框架应将解析失败记录为警告,而不是直接阻断。最后,预算保护只是估算;任何真正花钱生成草稿的团队,都应该在旁边记录服务商报告的用量。

如果你已经在运行回放测试套件,成本最低的下一步就是选出修改最频繁的五个 prompt,今天就记录它们的指纹和执行计划。在决定采用哪一种立场之前,先让 CI 告诉你,它们实际上多久会漂移一次。

如需采取进一步行动,你可以考虑屏蔽此人和/或举报滥用行为。

Original source

本文由 AI 翻译整理自 dev.to · AI,原文版权归原作者所有。

阅读英文原文
上一篇
逐步核算 Token,定位 Agent 的结构性浪费
下一篇
审核超时后的任务释放与计费隔离