搭 Agent harness 最难的部分之一,是构造它的工具。
Claude 完全通过 工具调用 行动,但 Claude API 里可以用多种原语来构造工具,例如 bash、skills 和 代码执行。(关于 Claude API 上的 programmatic tool calling,可参见 @RLanceMartin 的新文章。)
那么该怎么设计 Agent 的工具?给一个通用工具(如 bash 或代码执行)?还是五十个专用工具,每个场景一个?
要站在模型的立场想:给你一道很难的数学题,你希望有什么工具?这取决于你自己的能力。
纸笔是最低配置,但只能手算。计算器更好,但你得会用更高级的功能。最快最强的是电脑,前提是你会写代码并执行。
这对设计 Agent 很有用:工具要贴合模型自身的能力。可怎么知道那些能力是什么?得观察、读它的输出、做实验——学会像 Agent 一样看。
如果你在搭 Agent,会碰到和我们一样的问题:何时加工具、何时删、怎么区分。下面是我们做 Claude Code 时的答案,包括一开始做错的地方。
用 AskUserQuestion 工具改进 elicitation

做 AskUserQuestion 工具时,目标是提升 Claude 提问的能力(常称作 elicitation)。
Claude 本来可以用纯文本提问,但我们发现回答那些问题感觉多花了不必要的时间。怎么降低摩擦、提高用户与 Claude 之间的沟通带宽?
尝试 1:改 ExitPlanTool
第一种做法是给 ExitPlanTool 加一个参数,让它在计划旁边带一组问题。实现最省事,但 Claude 会困惑:我们同时在要一份计划和关于计划的一组问题。若用户答案与计划冲突怎么办?Claude 要不要调两次 ExitPlanTool?我们知道这条路不通,于是推倒重来。(为何做 ExitPlanTool,见 提示词缓存那篇。)
尝试 2:改输出格式
接下来,我们改 Claude 的输出说明,让它用稍作修改的 markdown 格式提问。例如,输出带括号备选的项目符号问题列表,再解析并做成给用户的 UI。
Claude 大多能产出这种格式,但不稳定:会多加句子、丢掉选项,或干脆放弃结构。换下一种。
尝试 3:AskUserQuestion 工具

最终我们做成一个 Claude 随时可调的工具,并在 Plan Mode 下特别提示它调用。工具触发时弹出模态框展示问题,并阻塞 Agent 循环直到用户作答。
这让我们可以提示 Claude 给出结构化输出,并确保给用户多个选项。用户也能组合使用,例如在 Agent SDK 里调用,或在 Skill 里引用。
最重要的是,Claude 似乎愿意调用这个工具,输出也好用。毕竟,再精巧的工具,Claude 不会调也没用。
这是 Claude Code 里 elicitation 的最终形态吗?大概不是。Claude 更强了,服务它的工具也要跟着变。下一节是一个曾经有用、后来开始碍事的工具。
随能力更新:tasks 与 todos

Claude Code 刚上线时,我们发现模型需要一份 todo 列表 才能不跑偏。Todos 可在开头写好,做完再勾掉。于是我们给了 Claude TodoWrite 工具,用来写入或更新 Todos 并展示给用户。
即便如此,Claude 还是常忘掉要做什么。我们每隔 5 轮插入系统提醒,把目标再告诉它。
模型变强后,To-do 列表显得束缚。一直被提醒 todo 列表,Claude 会觉得必须死守列表,而不是发现需要改道时修改它。我们也看到 Opus 4.5 用 subagent 好得多了,但 subagent 怎么在一份共享 todo 上协调?
于是我们用 Task 工具 替换了 TodoWrite。Todos 侧重让模型不跑偏;tasks 则帮助 Agent 彼此沟通。Tasks 可带依赖、跨 subagent 同步更新,模型也能改、能删。
模型能力上去后,曾经需要的工具可能变成约束。要 不断回头检查 哪些工具还需要。这也是为什么最好只支持一小批能力画像相近的模型。
设计搜索接口
我们做过最重要的工具,是让 Claude 自己找上下文的那些。
Claude Code 内部刚发布时用的是 RAG:向量库预索引代码库,harness 在每次回复前检索相关片段交给 Claude。RAG 又快又强,但要索引和配置,跨环境也脆弱。更关键的是:上下文是给 Claude 的,不是它自己找的。
既然 Claude 能搜网页,为什么不能搜你的代码库?给它 Grep 工具,就能让它自己搜文件、自己攒上下文。
Claude 越聪明,在合适工具下就越会自己构建上下文。
引入 Agent Skills 时,我们把渐进披露(progressive disclosure)形式化了:Agent 可通过探索增量发现相关上下文。
Claude 可以读 Skill 文件,那些文件再引用其他文件,模型可递归读取。实际上,Skill 的常见用法就是给 Claude 加更多搜索能力,比如教它怎么用某个 API 或查数据库。
一年下来,Claude 从几乎不会自己攒上下文,变成能跨多层文件嵌套搜索,找到刚好需要的那一段。
渐进披露现在是我们在不加新工具的前提下加功能的常用手法。下一节说明原因。
渐进披露:Claude Code Guide Agent
Claude Code 目前大约有 20 个工具,团队经常回头问:要不要这么多才最有效。加新工具门槛很高,因为又多给模型一个要权衡的选项。
例如,我们发现 Claude 对自己怎么用 Claude Code 不够了解。问它怎么加 MCP、某个 slash 命令做什么,它答不上来。
本可以把这些信息全塞进系统提示词,但用户很少问这些,只会加重上下文腐化(context rot),干扰 Claude Code 的主业:写代码。
于是我们试渐进披露:给 Claude 一个文档链接,需要时再加载和搜索。这能用,但 Claude 会把大块文档拉进上下文,才能找到用户一句话就能得到的答案。
于是我们做了 Claude Code Guide——用户一问 Claude Code 本身,Claude 就调用的 subagent。Subagent 在自己的上下文里搜文档,按详细说明搜索和抽取,只交回答案。主 Agent 的上下文保持干净。
这不是完美方案(问它怎么配置自己时仍可能糊涂),但我们在不加新工具的前提下扩大了 Claude 的行动空间。
像 Agent 一样看是艺术,不是科学
给模型设计工具既是艺术也是科学。高度依赖你用的模型、Agent 的目标,以及它运行的环境。
最好的建议?常做实验,读输出,试新东西。最重要的是,试着像 Agent 一样看。
开始使用 Claude Code。
本文作者 Thariq Shihipar,Anthropic Member of Technical Staff,负责 Claude Code。