ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SA-04 ACI工具设计方法论

SA-04 ACI工具设计方法论 工具即提示Agent-Computer InterfaceACI设计方法论系列导航00 系列导航 · 01 单 Agent 总论 · 02 ReAct 原理 · 03 手写内核 ·04 ACI 工具设计· 05 上下文工程 · 06 两个增强变体 · 07 上线前清单小提一句 由于平台每日发布笔记数量限制目前系列笔记还没全部上传。后续内容会持续更新大家可以先点个关注、收藏以免错过~引子这是整个系列投入产出比最高的一篇第 1 篇给过一张表单步成功率p决定长程任务的一切。单步成功率 p10 步成功率20 步成功率0.9035%12%0.9560%36%0.9882%67%0.9990%82%现在的问题是怎么把 p 从 0.90 提到 0.98换更强的模型能提一点但贵且很快遇到瓶颈。真正有效的手段是ACIAgent-Computer Interface设计也就是把工具接口设计对。这是 Anthropic 在构建 SWE-bench Agent 时得出的头号经验他们的原话是投入在工具定义上的提示工程精力应当与投入在 system prompt 上的同等。换句话说工具描述不是文档它是提示词的一部分而且是每一步都会被重读的那部分。一、ACI 与 HCI模型是一种什么样的用户Anthropic 用的类比是像做人机交互HCI设计一样做 ACI 设计。这个类比很好但要知道模型这个用户和人有几个本质区别维度人类用户模型用户交互通道视觉 直觉 常识只有文本且只能看到你放进上下文的文本错误处理看到报错会试错、会查文档只能从错误信息里学且这次学到的下次不一定记得除非你还留在上下文里记忆长期记忆、跨会话本次上下文内的记忆出了窗口就是陌生人耐心 / 成本免费每读一个 token 都要钱和时间常识有能脑补缺失信息形式上有但脑补出来的就是幻觉反馈循环可以问同事只能靠你返回的错误信息由此得到 ACI 设计的第一原则不要假设模型能推断任何东西。任何它没有在上下文里看到的信息对它都不存在任何它看起来推断出来的东西都可能是编的。这条原则长出了下面全部 12 条军规。二、工具定义的七要素模板一个合格的工具定义应该长这样以search_logs为例- search_logs 用途 按服务名与时间范围检索错误日志返回日志条目摘要。 何时用 已经确定要查某个具体服务的日志时。 何时不用尚未确定错误发生在哪一层网关 / 服务 / DB时——先用 query_metrics 定位层级。 参数 service string 必填 服务名若 5xx 产生于网关层此处填 gateway since string 必填 绝对时间格式 YYYY-MM-DD HH:mm:ss 不知道当前时间请先调用 get_current_time level string 可选 枚举 error|warn|info默认 error limit integer 可选 1-100默认 20 返回 最多 limit 条日志摘要每行 时间 服务 消息 若被截断会注明匹配总数。 常见错误传入相对时间如 30分钟前会导致解析失败必须使用绝对时间。七要素要素作用缺了会怎样用途一句话说明它是干什么的模型靠猜何时用正向触发条件该用的时候不用何时不用负向边界不该用的时候乱用最常被省略参数含必填/枚举/默认值/单位/格式消除参数歧义参数乱填、缺参数、格式错返回含形状与截断行为让模型知道能拿到什么重复调用、误判没有结果常见错误把踩过的坑写回描述同一个错反复犯与其他工具的分界见何时不用工具混淆选择准确率暴跌其中“何时不用”是我最想强调的一条。我们在自己系统里做过统计加上负向边界后工具误选率下降最明显的就是这一项。因为模型犯的错往往不是不知道该用什么而是两个都像对的。三、12 条军规A 组命名与边界工具名是自解释的动宾短语且两两互斥。反面教材get_data/query/fetch_info三个工具同时存在模型和人类都无法区分。判断标准把工具名和描述盖住用途字段只看名字能否猜出该不该用。每个工具显式写何时不用。见上。尤其是能力有重叠的工具对如search_logsvsquery_metrics必须互相点名“若你要找的是数值随时间的变化趋势用 query_metrics 而不是本工具。”能合并就合并不能合并就切干净。高频共现的两个操作如查指标和查该指标的历史基线应合成一个带参数的工具而不是两个。切分的原则是按决策语义切不按后端接口切。别把你们微服务的边界直接暴露给模型。B 组参数设计格式贴近模型在自然文本中见过的形式。模型的先验来自互联网文本。它见过无数次2026-09-30 14:20:00几乎没见过2026-09-30T14:20:00.00008:00|slot:3。用前者。不要制造格式开销format overhead。Anthropic 的原话避免让模型做它不擅长且需要精确计数的体力活。三类典型陷阱陷阱例子后果要求精确计数“传入要修改的行号范围”模型数错行数改错地方要求复杂转义“把这段代码的字符串转义后传入”转义漏一个反斜杠语法错要求重排/排序“按依赖顺序传入模块列表”顺序错执行失败修法一律是让工具接受更宽松的输入由代码做规范化。比如让工具接受文件路径 函数名而不是行号。参数要自带防错能力Poka-yoke。见第 4 节这是本组最重要的一条。C 组返回设计返回可据以决策的信息而不是原始数据 dump。模型需要的是这个指标在 t-11m 突增不是 1800 个采样点。让工具在服务端做降采样、聚合、异常标注把计算放在工具里而不是放在模型的上下文里。截断必须显式标注并告诉模型怎么拿更多。第 3 篇的truncate()已经处理了这点。补充截断信息里最好带一句如需查看第 N 到 M 条调用read_range(handle, start, end)。结构化优先但保持自然语言可读。纯 JSON 对模型友好但费 token纯文本省 token 但易误读。折中用简短的自然语言行 明确的字段名如时间 服务 消息的固定行格式。模型对固定行格式的解析准确率极高且比 JSON 省 30~50% token。D 组错误与反馈错误信息必须可操作说清错在哪 怎么改。❌✅Error 400[ToolError] search_logs 的 since 参数需要绝对时间YYYY-MM-DD HH:mm:ss收到 30分钟前。请先调用 get_current_time 获得当前时间再换算。File not found[ToolError] read_repo_file 找不到 /src/db/pool.py。仓库中的候选路径[order-service/db/pool.py, common/db/pool.py]。路径必须是从仓库根开始的绝对路径。第二条里那个候选路径是神来之笔把纠错所需的信息直接放进错误里模型一次就能改对而不是把找不到文件当成一次探索去反复试。空结果必须区分真的没有与查询条件错了。[]是最糟糕的返回模型无法判断是没有错误日志好事“还是服务名写错了坏事”。返回匹配 0 条。可能原因(a) 该服务在此时间窗内确无 error 级日志 (b) service 名称不正确已知服务order, gateway, payment。 建议先调用 list_services 确认服务名。把线上踩过的坑写回工具描述。工具描述应该是一个活的文档。每当你从 trace 里发现一类新的工具误用就往描述的常见错误里加一条。这是 ACI 唯一正确的迭代方式——不是拍脑袋重写而是由失败案例驱动。第 4 节的混淆矩阵和第 7 节的评测就是在告诉你该往哪儿加。四、Poka-yoke让错误在接口层面不可能发生“防错”poka-yoke源自丰田生产体系指的是通过设计让错误无法发生而不是靠操作者小心。Anthropic 的经典案例他们的 SWE-bench Agent 在移出根目录后用相对路径频繁出错。修法不是在 prompt 里提醒模型用绝对路径而是把工具参数改成强制绝对路径。此后该错误归零。这个案例的精髓在于约束放在代码里而不是放在提示里。提示是建议代码是物理定律。一批可以直接抄的 poka-yoke 清单风险弱做法提示强做法接口路径写错“请使用绝对路径”参数 schema 要求以/开头收到相对路径时自动基于仓库根解析并在返回中告知解析结果时间写错“请使用绝对时间”提供get_current_time工具参数接受30m这类枚举化相对偏移并由服务端换算枚举写错描述里列出枚举用 JSON Schemaenum约束非法值直接拒绝并回候选删改误操作“请谨慎操作”dry_run参数默认 True写操作标记side_effectTrue走授权钩子返回过大“结果可能很长”强制分页 上限如limit ≤ 100超限直接拒绝并提示收窄条件参数单位歧义“window 单位是分钟”参数名带单位window30m或只接受带单位的字符串危险命令“不要执行 rm”工具层做命令白名单非白名单直接拒绝所以每当你想在 prompt 里写请注意……的时候先问一句这个约束能不能放进代码能放进代码的绝不留给提示。五、工具数量为什么全集是个坏主意5.1 甜点区⚠️ 经验值缺严格定量研究但在多个团队复现过 10 个精选工具通常优于 50 个全集。原因有三选择准确率随候选数下降。这是最直接的原因候选翻倍误选率不是线性上升而是在语义相近的工具上集中爆发。工具描述本身是固定 token 开销。算一笔账20 个工具 × 平均 150 token 3000 token 工具定义 每一步都要重发除非命中前缀缓存 12 步 × 3000 36,000 token —— 纯工具描述不含任何任务内容这还没算它对注意力的稀释。3. 工具越多边界越难写干净。50 个工具里不可能两两互斥必然有重叠重叠就是误选的温床。5.2 超过 10 个怎么办三层路由按需加载长尾层 · 按需检索不常驻可 20 个提供 search_tools(query)让模型按名字取用领域层 · 按任务类型预加载3~5 个任务路由时确定例如代码类任务 → 加载 git / diff / test核心层 · 常驻上下文5~8 个高频、跨任务通用search / read / finish ...⚠️ 第三层有个真实风险模型不知道自己不知道什么。它不会去search_tools一个它压根没听说过的工具。所以长尾层只适合模型大概率知道该能力存在、只是不知道确切名字的场景如公司内部几十个数据接口。如果能力本身模型没概念检索工具救不了你。5.3 与 MCP 的关系MCPModel Context Protocol解决的是工具接入的标准化怎么把外部系统接进来不解决工具选择的质量问题。恰恰相反MCP 让接入变得极其容易反而使工具全集问题更严重能接不等于该接。接入之后本文的裁剪与路由逻辑依然要自己做。六、返回值的形状一个被严重低估的杠杆同样的信息返回形状不同模型的下一步决策质量可以差很多。四条具体建议6.1 给结论而不是原料。query_metrics返回 1800 个采样点 vs 返回降采样 6 点 一句『在 t-11m 发生突增斜率 20×』。后者可能只有 50 token但包含了模型真正需要的决策依据。让工具承担计算让模型承担判断。6.2 空结果要给归因建议。见军规 116.3 大内容给句柄不给全文。❌ Observation: 20000 token 的完整日志 ✅ Observation: 匹配 187 条已存入 handlelog://a3f1。前 5 条预览 t-11m order ConnectionPoolExhausted: timeout waiting for connection ... 调 read_range(log://a3f1, start, end) 可读取指定区间。这同时解决了三个问题上下文膨胀、注意力稀释、“模型以为自己看完了全部”。6.4 让返回自带下一步提示。在返回末尾加一行[下一步建议] 若需确认该变更的 diff调用 read_repo_file(path, refv2.14.0)。这属于引导而非控制模型可以忽略它但在它没主意时非常有效。⚠️ 注意别滥用加太多会让返回变长且可能诱导模型放弃自主判断。七、怎么评测你的工具集一个 60 行的评测脚本ACI 改得好不好不能靠感觉。下面这个脚本能测出工具选择准确率和参数质量跑一次几分钟importjson,asyncio,collections# 评测用例只测给定上下文模型该选哪个工具CASES[{ctx:订单服务 5xx 突增需要确认是从哪一分钟开始涨的。,expect_action:query_metrics,expect_args_keys:[service,metric]},{ctx:已确认错误产生于网关层现在要看网关在这一时段的错误日志。,expect_action:search_logs,expect_args_keys:[service,since]},{ctx:我怀疑是 v2.14.0 改了连接池配置想看这个文件的这个版本。,expect_action:read_repo_file,expect_args_keys:[path]},# ... 建议 50 条覆盖每个工具的正例与易混淆反例]PROBE你有以下工具 {specs} 当前情况{ctx} 请只输出一个 JSON 动作块表示你的下一步 json {{action: ..., args: {{...}}}} asyncdefeval_aci(tools,llm,casesCASES):specstools.render()hit0arg_ok0unparsable0confusecollections.Counter()forcincases:rawawaitllm(PROBE.format(specsspecs,ctxc[ctx]))thought,callparse_output(raw)# 复用第 3 篇的解析器ifcall.name__unparsable__:unparsable1continueifcall.namec[expect_action]:hit1else:confuse[(c[expect_action],call.name)]1# 混淆对ifall(kincall.argsforkinc[expect_args_keys]):arg_ok1nlen(cases)print(f工具名准确率 :{hit/n:.1%})print(f必填参数完整率:{arg_ok/n:.1%})print(f格式非法率 :{unparsable/n:.1%})print(\n最易混淆的工具对期望 → 实际)for(exp,got),kinconfuse.most_common(10):print(f{exp}→{got}{k}次)return{action_acc:hit/n,arg_acc:arg_ok/n,unparsable:unparsable/n}怎么用这个结果指标健康阈值不达标时怎么办工具名准确率≥ 95%核心工具 ≥ 98%看混淆对给这两个工具加何时不用仍不行就合并它们必填参数完整率≥ 95%参数描述里把必填参数的作用写清楚或提供默认值格式非法率≤ 2%换更强的模型或改进解析层第 3 篇那个混淆矩阵是本脚本最有价值的输出。它会精确告诉你哪两个工具在模型眼里长得一样。这是你改写描述的唯一依据。我见过最典型的混淆是search语义检索与lookup精确查找修法是合并成一个带mode参数的工具。⚠️ 提醒这个测的是单步工具选择不等于任务成功率。它可以作为 p 的一个快速代理指标但不能替代端到端评测第 7 篇。八、案例OpsAgent 的工具改造前后改造前典型的API 文档式定义- query_metrics(service, metric, window): 查询指标 - search_logs(service, since, limit): 搜索日志 - read_file(path, ref): 读文件 - run_cmd(cmd): 执行命令 - finish(answer): 结束问题query_metrics和search_logs边界不清since没说时间格式read_file没说路径基准run_cmd完全开放危险没有任何何时不用。改造后- query_metrics 用途查询服务的监控时序已降采样用于判断指标的形态突增/渐变/周期与起始时间点。 何时不用要查的是具体日志文本 → 用 search_logs要看代码 → 用 read_repo_file。 参数service string 必填metric string 必填枚举http_5xx_rate|p99_latency|qps|error_count window string 可选 默认 30m格式 数字m|h|d 返回降采样后的 时间-数值 序列≤12 点 一句形态判断如在 t-11m 突增。 - search_logs 见第 2 节七要素模板 - read_repo_file 用途读取代码仓库中某文件在某版本的内容。 参数path string 必填**必须是仓库根的绝对路径以 / 开头** ref string 可选 版本/tag/commit默认当前主干 返回文件内容800 行时截断并注明不存在时返回 3 个最相近的候选路径。 - run_readonly_cmd 用途在受限 shell 中执行**只读**命令ls/git show/git log/git diff/cat。 何时不用任何会修改状态的操作部署、回滚、写文件——本工具会直接拒绝请改为给出建议等人工执行。 参数cmd string 必填 返回stdout截断至 2000 字符非白名单命令返回拒绝原因与白名单。 - finish 用途当你已有足够证据支撑结论时调用。 参数answer string 必填 根因 证据链每步引用 Observation 建议动作四处关键改动metric改成枚举消除指标名乱编。read_repo_file的路径约束 候选路径纠错消灭文件找不到的反复试错。run_cmd→run_readonly_cmd 白名单权限最小化从工具定义层面就完成了。每个工具都有何时不用消除混淆。这套改动配合第 7 篇的评测通常能把单步成功率往上推 5~10 个百分点。按第 1 篇的表那是 20 步任务从 36% 到 67% 的差距。这是整个系列里最便宜的一次改进。九、小结这一篇的核心就一句工具定义不是文档是每一步都会被模型重读一遍的提示词所以值得你投入跟 system prompt 同等的心力。落到执行层面最便宜也最确定的收益来自两件事。一是把七要素模板连同何时不用当铁律先把工具边界写死二是用那份评测脚本跑出混淆矩阵盯住模型究竟在哪两个工具之间犯晕再照着改描述。注意别凭猜测迭代——混淆矩阵是唯一可靠的依据。下一篇聊上下文工程。长程任务里它是另一个容易被低估、但同样直接决定 p 的杠杆。上一篇03 手写生产级ReAct内核下一篇05 长程 Agent 的上下文工程截断、摘要压缩与检索回放 - 需要明天上传笔记今天的发布限额到了参考Anthropic,Building Effective Agents, 2024-12ACI、poka-yoke、绝对路径案例、工具定义与提示工程同等投入。Yao et al.,ReAct: Synergizing Reasoning and Acting in Language Models, ICLR 2023, arXiv:2210.03629。Liu et al.,Lost in the Middle: How Language Models Use Long Contexts, TACL 2024上下文长度与注意力衰减。
返回列表