Seeing Like an Agent: Tool Design Lessons from Building Claude Code

A deep dive into Thariq Shihipar's article on how the Anthropic team designed, tested, and evolved tools for Claude Code by learning to see from the model's point of view.

Original: Thariq Shihipar, "Seeing like an agent: how we design tools in Claude Code", Anthropic Blog, 2026-04-10

[TOC]

一、引言:行动空间的设计难题

构建 AI Agent 最难的部分不是模型本身,而是设计它的行动空间(Action Space)——也就是工具的集合。Claude Code 的架构师 Thariq 一上来就抛出了这个问题:

你应该给 Agent 一个通用工具(如 bash),还是五十个专用工具?

他用了一个很直觉的类比来回答:

  • 纸笔 → 最简单,但全靠人算
  • 计算器 → 更快,但要会用高级功能
  • 电脑 → 最强,但得会写代码

工具不是越多越好,而是要匹配使用者的真实能力边界。 对模型来说也一样。

但问题来了:你怎么知道模型的能力边界在哪里?Thariq 的回答很朴素——读它的输出,做实验,反复试。这种用直觉和观察来驱动设计的方式,被他称为 "像 Agent 一样思考"(See like an Agent)


二、工具设计的三个演进案例

案例一:AskUserQuestion 工具

Claude 本来就可以直接在文本中提问,但这样做有几个问题:用户回答效率低、交互体验割裂。团队想让 Claude 能更高效地向用户提问。

尝试 1:在 ExitPlanTool 里加参数

在退出计划工具里塞一个问題数组。想法是省掉额外工具,但这就让 ExitPlanTool 同时承担了两个职责——既要做计划,又要问问题。Claude 被搞糊涂了:如果用户的答案和计划矛盾怎么办?需要调用两次 ExitPlanTool 吗?

尝试 2:改输出格式

让 Claude 按特定 Markdown 格式输出问题,再解析成 UI。看起来很轻量,但 Claude 输出不稳定——会多写句子、漏掉选项、甚至直接丢掉格式。

尝试 3(最终方案 ✅):独立的 AskUserQuestion 工具

一个专用的 Tool,Claude 可以在任何时刻调用,但在 plan mode 下特别鼓励使用。触发后会弹出一个模态框,阻塞 Agent 循环直到用户回答。

这个方案成功的关键不只在于技术实现,更在于一个更底层的洞察:再精妙的工具设计,如果 Claude 不"喜欢"调用它,就没有价值。 而独立工具让 Claude 能结构化地调用,输出也稳定地好。

Thariq 说,这远不是"提问交互"的最终形态——模型变强了,服务它的工具也要跟着进化。


案例二:TodoWrite → Task Tool 的升级

早期 Claude Code 有个直觉正确的设计:给 Claude 一个 TodoWrite 工具,帮它记录要做的事。系统还在每 5 轮插入提醒,确保它记得目标。

这在早期模型上工作得很好。但后来问题来了:

  • 更强的 Claude 不需要反复提醒,提醒反而变成了干扰
  • 强制提醒让 Claude 以为"必须严格遵循列表",失去了调整计划的灵活性
  • Opus 4.5 的 subagent 能力大幅提升,多个子 Agent 如何共享同一个待办列表?

于是 TodoWrite 被替换为 Task Tool

维度 TodoWrite Task Tool
核心目标 防止模型忘事 Agent 间协作通信
适用场景 单 Agent 多 Agent 协作
灵活性 低,容易变成约束 高,支持修改、删除、依赖
跨 Agent 共享 不支持 支持

这个案例揭示了一条很锋利的原则:随着模型能力提升,曾经必要的工具可能变成新的枷锁。你以为是拐杖,其实成了狗绳。


案例三:搜索接口的演进——从 RAG 到 Skills

这是整篇文章技术密度最高的部分。

阶段演进:

RAG 向量检索(被动接收)
        ↓
Grep 工具(主动搜索,一层)
        ↓
Agent Skills(递归嵌套,多层探索)
        ↓
Subagent 专业分工(claude-code-guide)

早期 Claude Code 用传统 RAG:向量数据库预索引整个代码库,每次调用把最相关的片段塞给 Claude。快是快,但问题重重:

  • 需要预索引,环境一换就崩
  • 语义相似 ≠ 逻辑相关,经常搜到"看起来像但没用"的内容
  • 最关键的——Claude 是被动接收的,它不知道自己"还缺什么"

引入 Grep 工具是个转折点。让 Claude 自己搜索文件、自己构建上下文,比喂给它检索结果效果好得多。模型越聪明,给对工具后它自己找上下文的能力就越强。

然后 Agent Skills 出现了。Skill 本质上就是一个给 Claude 看的说明书文件——描述某项能力的使用方式,引用其他文件,可以递归嵌套。Claude 读 skill 文件后,可以像工程师一样"顺藤摸瓜":

skill 文件 A
  └─ 引用 → 文件 B(API 文档)
                └─ 引用 → 文件 C(鉴权说明)
                      └─ 引用 → 文件 D(示例代码)

这就是渐进式披露(Progressive Disclosure)的雏形——让 Agent 通过探索发现信息,而不是一次性灌输。

一年时间,Claude 从几乎无法自主构建上下文,发展到能跨多层文件递归嵌套搜索、精准定位所需信息。


三、传统 RAG 与 Agent Skills 的核心对比

这个对比是全篇最让人产生共鸣的部分。

传统 RAG 是什么?

一句话:系统替 Claude 决定了"该看什么"。建向量索引、搜、塞给模型。

传统 RAG 的问题

问题 说明
预索引成本高 使用前必须建立、维护向量索引
环境依赖脆弱 跨机器、跨环境容易出错
检索质量不稳定 语义相似 ≠ 逻辑相关
无法推理式探索 不能根据第一步结果决定下一步找什么
被动接收 Claude 没有参与信息获取过程

最后一点是最根本的:Claude 被剥夺了"好奇心"——它无法主动判断"我还需要什么"。

Agent Skills 是什么?

给模型读的"说明书文件"。它本质上是提示词管理工具,把能力的边界条件和用法写进文件里,让模型按需读取、递归探索。

RAG vs Agent Skills

维度 传统 RAG Agent Skills
信息获取方式 被动接收 主动探索
探索深度 一次性检索 递归多层嵌套
推理能力 无(只会检索) 有(根据结果决定下一步)
环境依赖 需要预索引 零配置,读文件即可
扩展方式 改索引/改代码 写 skill 文件
适应性 依赖索引新鲜度 动态适配

两者并非对立

一个经常被忽视的点:RAG 并没有被淘汰。在超大规模知识库、实时性要求高的场景下,RAG 仍然是好选择。Cursor、GitHub Copilot 等产品中,RAG 和 Agent 模式是共存的——

用 RAG 做粗筛,用 Agent 做精读和推理。

RAG 从"主角"变成了 Agent 工具箱里的一个普通工具。


四、渐进式披露:不加工具的能力扩展

什么是渐进式披露?

这个概念来自 UI 设计——只在需要时展示复杂信息。应用到 Agent 上就是:

不在一开始就把所有信息塞给模型,让它像人类工程师一样,边探索边按需获取。

为什么需要?

核心问题:上下文腐烂(Context Rot)

Claude Code 有它自己的文档。用户偶尔会问"如何添加 MCP?"、"斜杠命令是什么?"。但这类问题发生频率极低。如果把所有文档塞进 system prompt,99% 的时间里都是噪音——代码能力下降,换来极少被用到的知识。

怎么实现?

Claude Code 的解法:claude-code-guide subagent

用户问:"如何添加 MCP?"
        │
        ▼ 主 Claude 识别意图,触发 subagent
        │
   ┌────┴──────────────────────┐
   │  subagent 内部             │
   │  ├─ 按指令搜索文档          │
   │  ├─ 递归读取相关文件        │
   │  └─ 精准整理并返回答案      │
   └───────────────────────────┘
        │
        ▼ 主 Claude 回答用户(上下文未被污染)

主 Agent 的上下文保持干净,专注于写代码。知识型内容按需加载,互不干扰。

三重价值

工程价值——零工具扩展能力

传统:新功能 → 新工具 → 修改代码部署
渐进式披露:新功能 → 写 skill 文件 / subagent → 动态可插拔

Claude Code 大约只有 20 个工具,新增门槛极高。渐进式披露让团队在不增加工具的前提下扩展 Claude 的能力边界

认知价值——减少干扰,聚焦核心

主 Agent 不用在无关信息上浪费注意力。

架构价值——专业分工

每个 subagent 有专属的搜索指令和返回格式,比通用 Agent 精准得多。能力从"代码层"转移到了"知识层"。


五、一年的演进轨迹

早期
  │
  ├─ RAG 喂给 Claude(被动接收)
  │
中期
  ├─ Grep 工具:Claude 主动搜索(一层)
  │
引入 Skills
  ├─ 递归引用,多层嵌套探索
  │
2024~2025
  ├─ Subagent 专业分工
  └─ 渐进式披露成为标准范式

这条路不是设计出来的,是踩坑踩出来的。每一个阶段都是因为上一个阶段的工具不再匹配模型的能力。


六、核心原则整理

原则 一句话
工具匹配能力 不是越多越好,要贴合模型真实能力
Claude 要"喜欢"调用 工具设计符合模型直觉,强迫调用效果差
持续重新审视 模型变强后,旧工具可能变成枷锁
渐进式披露优先 新功能先考虑 skill/subagent,而非新增工具
避免上下文腐烂 system prompt 只放高频必要信息
主动探索优于被动接收 让模型自己找上下文,而非系统代劳

七、结语

Thariq 在结尾说的话值得反复读:

"为模型设计工具,是艺术与科学的结合。它高度依赖于你使用的模型、Agent 的目标以及它运行的环境。多实验,读输出,尝试新事物。像 Agent 一样思考。"

读到这我最大的感受是:这不是一篇教你"该怎么做"的文章,而是一篇教你"该怎么想"的文章。

从 RAG 到 Skills、从 TodoWrite 到 Task Tool、从 system prompt 到渐进式披露——每一次演进背后,不是架构师的纸上谈兵,而是团队真正站在模型视角、观察它的困惑、理解它的能力边界后做出的权衡。

工具不是给人设计的,是给模型设计的。

这句话放在更广的维度上也成立。构建 AI 系统的很多"正确决策",都不来自对框架的熟练,而来自对模型行为的敏感和尊重。


原文:Thariq Shihipar, "Seeing like an agent: how we design tools in Claude Code", Anthropic Blog, April 10, 2026
链接:https://claude.com/blog/seeing-like-an-agent

评论

此博客中的热门博文

我写了半年 prompt,最后发现最好的技巧就三个