返回探索
资讯VibeFix 编辑部更新于 2026年10月10日

DuckDB Agent Mode:当数据库 CLI 开始为 AI 编程 Agent 重新设计输出

DuckDB v2.0 的 CLI 学会了识别调用方是不是 AI Agent:方框表格换成紧凑 Markdown、截断显式声明、错误走 JSON、长查询先报成本。官方用 22 个 TPC-H 自然语言问答实测,输出 token 降 59%,却也诚实承认总成本只省 0.5%。这是开发者工具为“模型读者”重写输出的范式转移样本。

深色终端窗口中显示代码的计算机屏幕,象征为 AI Agent 重新设计的数据库 CLI 输出

数据库的命令行界面,是从"人坐在终端前"这个假设里长出来的。对齐的列、方框边线、分页器,都是为了让人眼扫读更舒服。DuckDB 官方博客 10 月 9 日的公告里,却多了一个新角色:DuckDB v2.0 的 CLI 学会了判断"另一端的读者不是人",并为它换上一整套输出规则。这件事值得写,因为它不是一次功能更新,而是一整类开发者工具正在经历的范式转移的第一个清晰样本。读完官方博客全文,最大的感受是:DuckDB 团队想清楚的不是"怎么省 token",而是"模型的阅读方式和人到底哪里不一样"——所有改造都从这四个差异里长出来,条条有出处。(日期口径:DuckDB 博客采用日期永久链接,/2026/10/09/ 即发布日期;页面正文无内联日期戳,特此说明。)

CLI 的第二读者

官方博客的 TL;DR 写得很直白:新版 CLI 的 Agent Mode,能让 AI 编程 Agent 更快、以更少的 token 拿到正确结果。触发条件也直白——当 CLI 侦测到调用方是 Agent 时,不再输出对齐的方框表格,改成紧凑的 Markdown 表格;截断结果会明确声明被截断了;失控查询会被提前叫停;错误走 stderr 以 JSON 格式报告;执行前长的查询先把 Planner 的成本估算报出来,让 Agent 决定是等还是改写。

这里真正有意思的不是技术细节,而是 DuckDB 把"读者"二分了。同一套 CLI,面对人和面对模型,输出的是两种方言。这个二分以前只存在于文档和 API 里(人类看文档、机器调 API),现在它下沉到了最朴素的命令行界面。理由也足够现实:博客里点名的 Claude Code、Codex、Cursor、Gemini CLI、GitHub Copilot,现在都是 duckdb -c "..." 的重度用户——每次 shell 调用把 stdout 通过管道抓走,丢给语言模型。DuckDB 团队说,这"很快成为一种常见用法"。一个 CLI 的调用者多数不再是人,这件事本身,就是 vibe coding 时代留给工具作者的考题。

指纹侦查:没有统一规范,本身就是新闻

深色终端窗口中的命令行界面

Agent Mode 的第一步是"认出你是谁",而认出的方式堪称侦探工作:扫描一串环境变量——AI_AGENT、AGENT(Claude Code、Goose、Amp)、CLAUDECODE(Claude Code)、CODEX_CI、CODEX_SANDBOX、CODEX_THREAD_ID(Codex)、CURSOR_AGENT(Cursor)、GEMINI_CLI(Gemini CLI)、COPILOT_AGENT、COPILOT_CLI、COPILOT_AGENT_SESSION_ID(GitHub Copilot)。只有当其中之一被设置、stdout 不是终端、且用户没有在命令行里显式指定输出格式时,模式才会开启。

读到这里应该停一下:一个主流开源数据库的 CLI,居然要靠收集各家 Agent 的环境变量"指纹"来判断调用方身份。这说明各家 coding agent 至今没有就"我是谁"达成任何统一规范——没有约定的 env var、没有标准化的 handshake,只有各自为政的命名。DuckDB 团队在博客里也承认,"这方面还没有统一的惯例",并开放了 issue 和 PR(#26167)请社区反馈,点名欢迎"Agent 被误判、输出把 Agent 搞糊涂"的 transcript——要的是真实翻车记录,不是 feature request。我的判断是:这段侦测代码是整个 Agent Mode 里寿命最短、也最有时代标本价值的部分。它迟早会被某个标准取代(大概率是某个 Agent 协议顺手定义一个 AI_AGENT 之类的约定),但在标准到来之前,所有想做"模型友好输出"的工具,都得先当一回指纹侦探。这种"先脏活、后标准"的节奏,恰恰是生态早期最真实的样子。

顺带一提,没被任何变量标记的 Agent 也不会被落下:如果一次写入管道失败,CLI 会在 stderr 里留一行提示,告诉调用方 -agent 的存在。第一次出错就是第一次自我介绍——这个设计很克制,也很有信心:不打扰人,只在机器需要时开口。

输出改造清单:为"不会追问的读者"重写规则

博客把人与模型的差异列了四条,每一条都对应一个输出改造,逻辑链条非常干净,值得逐条拆开看:

第一,模型没有终端,没有滚动条和分页器,看不到的就是不存在。于是结果集默认只完整打印 1000 行 / 10000 字节,超出的变成"前 20 行 + 后 20 行 + 显式省略标记行 + footer 说明"。注意这个省略是显式的:… 4960 rows omitted … 这样的标记行就摆在表格中间,footer 还会写明 first 20 and last 20 of 5000 rows 并附上完整结果的 order-independent hash。旧版的 (40 shown) 页脚人眼一扫就懂,模型却可能直接略过然后对着没见过的数据下结论——Agent Mode 把"被截断"这件事从页脚小字升级成了表格正文的一部分。这是整套改造里最有产品sense的一笔:它修的不是 token,而是模型的幻觉来源。

第二,模型按 token 付费,对齐用的空格和边框字符全是纯成本。于是方框表格换成无对齐填充的 Markdown 紧凑表,列类型直接写进表头单元格(name:VARCHAR 这种形式)。官方数据是典型结果集小 25% 到 65%,宽表省得最多。Markdown 还有个附带好处:Agent 的对话记录被人打开时,表格依然能被正确渲染——人机两读,一份输出。

第三,模型靠文本模式匹配处理错误。于是错误走 stderr 输出结构化 JSON,复用已有的 errors_as_json 设置,连 shell 自身的错误(比如打错的 dot 命令)也被包进同一结构。细节里有个很漂亮的减法:shell 主动丢掉了 candidates 字段,因为 message 里已经列出了候选项——一个"no matching function"错误因此从 2.7 kB 瘦下来。连错误信息都要做 token 预算,这就是为模型读者写作的日常。

第四,模型不能"再问一句",所以长查询要在执行前先报数。Planner 预计要读一百万行以上时,估算先走 stderr 打印出来,Agent 可以决定等、中断还是改写;执行中的进度条也换成每 5 秒一行的纯文本 progress: 42% (elapsed 12.0s, remaining ~16.5s)。再加上 .tables 一行一个表、带近似行数和列信息的紧凑 schema 输出,Agent 摸清库结构只需要一次调用。

还有个工程细节很见功力:因为紧凑表不需要预先算列宽,结果可以流式输出;达到上限后剩下的行只计数和哈希,超过上限再多 10 万行就直接停掉查询并报告下界。博客里举的例子——对 10 亿行的 range 查询 30 毫秒返回,footer 写 first 20 of at least 102400 rows (query stopped early)。该停就停,不替模型烧钱等一个它根本读不完的结果。顺带说一句,这个 footer 的哈希还有个很妙的用途:它不依赖行顺序,还能区分 NULL 和字符串 'NULL'。Agent 想知道"改完代码结果变没变",对比两个 footer 就行,不用把两份结果全打印出来——这是在用密码学思路替模型省 token。

几个可调旋钮也值得记下来,因为它们暴露了设计者的取舍观:行数与字节上限用 .maxrows N / .maxbytes N 调(-1 或 0 表示不限),超长单元格在 500 字符处截断并打上 …(+4500 chars) 这样的可见标记(.maxcellwidth N 可调)。footer 的打印规则是:空结果、10 行以上的结果、被截断的结果都打印;唯独"被提前停止"的查询不打印——因为哈希覆盖不了完整结果,团队宁可不给,也不给一个可能误导的哈希。这种"不完整就不承诺"的克制,和前面把截断标记写进表格正文是同一个逻辑:对模型读者,含糊的代价比沉默大。

EXPLAIN 也换了一套方言:默认 compact 格式,一行一个算子、按深度缩进,估算值、实际行数和耗时写在括号里,后面跟算子属性;EXPLAIN ANALYZE 开头先给一行摘要,比如 QUERY (time=0.0012s, read=1.2 MB)。这是个正式的 format,所以 EXPLAIN (FORMAT compact) 在非 Agent Mode 下也能用——好的 Agent 化设计,最后都会回流成对人也有用的功能,这几乎是条规律。

官方实测:59% 的 token 下降,与 0.5% 的总成本——诚实的数据

SQL 查询界面与数据结果展示

为了验证效果,DuckDB 团队请 Claude Code 做了一组对照实验:22 个 TPC-H 问题,跑在 scale factor 100 的数据集上,问题全部用纯自然语言表述、不给 SQL;Agent Mode 开和关各跑三遍,共 132 次运行,次次都答对。Agent Mode 下模型读到的 DuckDB 输出从 123.6k token 降到 50.8k token,降幅 59%。Claude 自己还写了一份实验报告(含完整数据和一个后续实验),官方博客直接引用了它的总结:"Agent mode 修掉了终端 shell 里那些悄悄误导模型的东西。"

然后博客话锋一转,主动交代了"但是":省下的 token 只占总输入的约 0.5%,因为每一轮都要重读 Agent 的 system prompt,那才是 token 大头;总耗时也没省,Agent Mode 的运行反而多用了几轮(237 对 224)。注意这个 0.5% 的口径:分母是"全部输入 token",而 Agent Mode 省的是"模型读回的输出"这部分。在 Claude Code 这种 system prompt 巨大的旗舰 Agent 配置里,输出占比本来就小;但换到小模型、弱 Agent、或者一条跑几十步的数据 pipeline 里,输出 token 的占比会显著放大。所以 0.5% 不是这个优化的上限,而是它在"最不利于它"的配置下测出的下限——官方没说这句话,但数据替他们说了。

这种诚实值得单独拎出来说。在充斥着"降本 90%"式营销的 AI 工具圈子里,一个团队把"我们的优化在总账单上几乎可以忽略"写进官方博客,是罕见的。这恰恰让 59% 这个数字更可信,也逼我们去想一个更对的问题:token 优化的真实 ROI 到底在哪里?

我的答案是三条,都不在账单上。第一是正确性收益:显式截断标记 + order-independent hash,修的是"模型对着没见过的数据下结论"这类静默错误——这种错误的代价不是 token,是错答案,而错答案的代价没法用 token 计价。第二是步骤收益:错误 JSON 化、schema 一次给全、长查询先报数,省的是 Agent 的试错轮次;虽然这次实验里轮次还多了几轮,但方向是对的,调优空间在实现细节而非方向上。第三是长尾收益:省 59% 的是"模型读回的输出"那部分,在小模型、弱 Agent、长 pipeline 里,这部分占比会比 Claude Code 的旗舰配置高得多。官方没有为了好看而挑选实验配置,这种不粉饰,本身就是一种技术判断力。

开关与礼貌:好的 Agent 化,第一课是"说人话"

控制层面,DuckDB 给了 -agent / -no-agent 两个强制开关,可以和 -csv、-json 等格式 flag 组合(duckdb -agent -csv 保留 Agent 行为只换行打印方式);.show 会报告模式是否激活以及侦测到了哪个 Agent。所有显式设置(.mode、.maxrows、EXPLAIN (FORMAT ...)、.duckdbrc)优先级都高于自动侦测——自动化的第一原则永远是"别覆盖人的明确意图"。

最耐人寻味的是那行启动提示。第一版实现每次运行打印三行解释(634 字节),比大多数查询结果还大;团队意识到模型在多次调用间是保持上下文的,解释一遍就够,于是砍到只剩一行 stderr:说明为什么开启、怎么关掉(-no-agent),以及去哪里看完整说明(.help agent)。不想看的人可以在 ~/.duckdbrc 里加 .startup_text none 关掉。

这行的设计哲学可以提炼成一句话:为模型做的自动化,必须对人保持透明、可解释、可一键关闭。Agent Mode 开了就是开了,它会告诉你它开了、为什么开、怎么关。.help agent 里还贴心地指了几条 Agent 自己可能找不到的路:SET max_execution_time 限查询时长、DESCRIBE 只看列不跑查询、SUMMARIZE 快速画像、duckdb_functions() 查函数文档。连"帮助"都是写给第二读者的。

一张给工具作者的检查清单

DuckDB 这篇博客最有价值的部分,其实是它无意中给出的一张"模型读者"适配检查清单。任何一个 dev tool 作者都可以拿着它自查,而且每一项背后都是一个具体的翻车场景:

第一,你的输出里有没有"人眼能脑补、模型会误读"的信息?方框表格的 (40 shown) 页脚就是典型——人一看便知,模型却可能直接略过。所有依赖"扫一眼就懂"的视觉暗示(对齐、颜色、省略号、分页符),在管道里都会失效。要么显式声明,要么别用。

第二,你的错误信息是给人看的还是给模式匹配看的?人读 traceback 能抓重点,Agent 靠的是正则和 JSON 解析。错误结构化不是锦上添花,是 Agent 能不能"读懂错了什么"的前提。DuckDB 连 shell 自身的报错都包进同一 JSON 结构,这个彻底程度值得学。

第三,你的长耗时操作有没有"先报价"机制?人看到进度条会耐心等,Agent 没有耐心这个概念——它只有 token 预算和步骤预算。Planner 估算先行、每 5 秒一行纯文本进度,本质上是把"要不要继续"的决策权交还给调用方。不给报价的长查询,在 Agent 眼里就是失控的开销黑洞。

第四,你的自动化对人是否透明、可关?Agent Mode 的启动行只占一行 stderr,讲清原因、关闭方式和文档入口;所有显式配置优先级高于自动侦测。这套"礼貌"规范应该成为所有 Agent 化改造的底线:模型需要自动化,人需要知情权,两者不冲突,但必须同时满足。

把这四条反过来读,就是 vibe coding 时代工具设计的及格线。而 DuckDB 的聪明之处在于,它没有另起一个 --for-llm 的平行宇宙,而是让同一套 CLI 根据读者自动切换方言——维护成本一份,用户体验两份。

结语:所有 dev tool 都要准备"模型版输出"了

DuckDB 不是第一家意识到这个问题的团队(博客里还提到了 Carlo Piovesan 早前 .mode llm 的提案,字节预算和提前停止的思路就源自那里),但它是第一家把"侦测—切换—解释—可覆盖"做成完整闭环、随大版本(v2.0)发布的数据库。它的样本意义在于证明了一件事:为模型读者做一版输出,不是加个 --json 就能糊弄过去的——截断语义、错误结构、成本预告、进度反馈,每一处都要重新想一遍"这个读者和人有什么不同"。

接下来会发生什么不难预测。指纹侦测这种脏活会被标准化取代——当 Agent 协议里出现统一的身份声明时,这段环境变量列表就可以删了。而"紧凑、可机读、显式声明截断、错误结构化"这套输出规范,会从数据库 CLI 蔓延到构建工具、测试 runner、包管理器……所有今天还在往管道里倒人类格式化文本的 dev tool。DuckDB 只是第一个把"第二读者"写进 release note 的。跟不上的工具,结局不是被替代,而是悄悄变成 Agent 眼里"又贵又容易误读"的那个选项——这才是最安静的淘汰方式。

还有一层更值得玩味:当工具开始为模型读者优化输出,模型的"阅读体验"就成了一种新的竞争维度。以前 CLI 比的是功能和速度,以后可能要比"谁更少让 Agent 犯错"。DuckDB 用 59% 的 token 降幅和一次诚实的 0.5% 交代,率先在这条赛道上立了个标杆——不夸大、不回避,把难看的数字也摆上台面。这种姿态本身,就是给所有后来者的示范:为模型设计输出,首先要学会用模型的视角诚实地度量自己。

如果你在用 coding agent 跑数据分析,升级到 DuckDB v2.0 后什么都不用配:只要 Agent 设了环境变量、输出走的是管道而非终端,Agent Mode 会自己打开。想亲眼看看模型看到的世界,跑一句 duckdb -agent -c "SUMMARIZE FROM 'my_data.parquet'" | cat 就行——管道另一端没有人,但从此有了一位被认真对待的读者。而所有还在输出方框表格的 CLI,都该问自己一句:你的第二读者是谁?读完这篇,不妨去翻翻你最常用的那个命令行工具的输出,想想它经不经得起模型的阅读。

原始来源

浏览项目广场发布你的项目

相关文章

REA 项目概念图:coding agent 通过 MCP 调用反编译工具分析二进制程序
资讯
REA 单日涨星 1.3 万登顶 GitHub Trending:给 coding agent 装上反编译器

10 月 9 日,REA(Reverse Engineer Anything)单日新增约 1.3 万颗星,登顶 GitHub Trending dev-tools 日榜。它把反编译、反汇编与静态分析封装成 MCP server + CLI,一句 npx rea-agents setup 就能让 Claude Code、Cursor 等 12 种 coding agent 读懂没有源码的二进制。从 DX-Ball 的字节级复刻到 Notion 的剪贴板追踪,本文拆解它的方法论、能力版图,以及逆向工程绕不开的灰色地带。

产品动态开发工作流AI 编程实践
Parseable 可观测性平台的 trace 瀑布流界面
资讯
180MB 单文件跑起完整可观测性:Parseable 登上 Show HN,Simon Willison 让 Codex 亲自部署验证

Parseable 10 月 6 日登上 Show HN:AGPL 开源、Rust 编写、单个约 180MB 二进制文件即完整可观测性后端。Simon Willison 让 Codex 自行摸索部署,并把 Datasette 的 OpenTelemetry trace 灌进去看到了 span 瀑布流。本文拆解单文件哲学、AGPL 的 Elastic 往事、与 Datadog/Grafana/SigNoz 的格局对比,以及三盆冷水。

开源项目观察可观测性Rust