Claude Code团队成员Thariq的Agent开发心得:Seeing like an agent

0 阅读7分钟

众所周知,在一个agent中,大模型通过Tool calling来实现各种各样的功能,但是工具的方式多种多样,它可能是bash命令,可能是已经备受认可的skills,也可能通过直接运行代码实现。 那么我们在搭建一个智能体时,应该如何设置工具的提供方式呢?Thariq则提出,这没有标准答案,核心在于我们应该代入到agent自身的视角,像agent一样思考问题,让你的设计模式和agent的能力相契合。

举个例子:面对一道运算量极大的数学题,一个小朋友手上的工具可以是纸笔、计算器,也可以是计算机——工具一个比一个强大。但前提是,这个小朋友得会用。工具再强,驾驭不了也是白搭。工具的选择,要和能力相匹配。 对 agent 工程也是如此,了解模型的能力边界没有捷径,只能靠持续观察模型的输出、反复试验,把自己代入 agent 的视角去感知。

那么Claude Code团队是如何做的呢?Thariq给出了一些他们在构建claude code过程中的实践经验:

1. AskUserQuestion 工具的诞生

屏幕截图 2026-03-03 195242.png

最初,团队尝试在 ExitPlanTool 中添加一个参数,让模型在产出计划的同时给出需要用户澄清的问题。这看似方便,却让 Claude 陷入困惑:为什么要同时输出一个 plan 和关于这个 plan 的疑问?如果用户的回答与原有 plan 冲突该怎么办?是否需要调用两次 EditPlanTool?

于是团队换了个思路:修改输出格式要求,单独划出一块让 Claude 输出问题,这样 UI 侧也更好渲染。但 Claude 并不总是遵守格式约束,稳定性依然差强人意。

既然约束输出格式稳定性不好,claude code团队就干脆把"提问"这件事封装成一个独立工具——AskUserQuestion Tool。通过提示词引导 Claude 在 plan mode 下主动调用它,借助工具的参数格式来保证稳定性,同时也让该能力在 agent SDK、skill 等场景中更易复用。

2. 从 Todos 到 Tasks 的演进

Claude Code 上线初期,团队发现模型在执行任务时很容易"跑偏"——做着做着就忘了最初的目标。为此,团队给 Claude 配备了 TodoWrite 工具,让它把待办事项写下来、逐项打钩。但即便如此,Claude 仍会时不时"失忆",团队不得不在系统层面再加一个机制:每隔 5 轮对话,就插入一条提醒,告诉它当前目标是什么。

这套组合拳在早期是奏效的。但随着模型能力持续提升,问题开始反转:固定的提醒反而干扰了 Claude 的判断,让它误以为必须死守 Todo 列表,无法根据实际情况灵活调整。与此同时,随着多 agent 协作场景增多(Opus 4.5 的子 agent 调用能力大幅提升),新问题浮出水面:多个子 agent 之间,如何共享和协调同一份 Todo List?

面对这些问题,团队用 Task Tool 替换了 TodoWrite。两者在定位上有根本差异:Todo 的核心是"提醒模型不要走偏",Task 的核心是"帮助多个 agent 相互协作"。Task 支持设置依赖关系、跨子 agent 同步状态,模型也可以主动修改和删除它,而不是只能机械地打钩。

随着模型能力的提升,那些曾经必不可少的工具,很可能会悄悄变成新的瓶颈。定期回头审视工具设计、重新评估已有假设,是 agent 工程中不可忽视的一环。

3. 搜索接口的设计

Claude Code 最初使用 RAG 向量数据库来为模型提供代码上下文——查询速度快,检索能力也不弱。但有几个明显的硬伤:需要提前建立索引、需要额外的环境配置,在不同项目环境下稳定性参差不齐。更关键的是,上下文是被"喂"给 Claude 的,而不是由它自己主动去找的。

一个简单的转变打开了新思路:既然 Claude 能在网上搜索信息,为什么不能在代码库里搜索呢?团队给 Claude 配置了 Grep 工具,让它能自行检索文件、主动构建上下文。效果相当显著,也引出了一条有趣的规律:模型越聪明,一旦配备了合适的工具,它自主构建上下文的能力就越强。 工具的价值,很大程度上取决于模型能否真正"用好"它。

随后,Agent Skills 的引入将这一思路进一步深化。Claude 可以读取一个 skill 文件,而该文件里又包含对其他文件的引用,Claude 可以顺着线索一层层递归读取下去,就像在一棵知识树上不断向下探索。短短一年,Claude 在上下文构建能力上完成了显著跨越——从几乎无法自主获取上下文,到能够跨越多个层级进行嵌套搜索,精准定位所需内容。

4. 渐进式披露

Claude Code 目前大约有 20 个工具,团队始终在审视这个数字是否合理。增加一个新工具的门槛很高——每多一个选项,模型在每次决策时就多一种可能性需要考虑,这会带来额外的认知负担。于是,核心命题变成了:如何在不新增工具的前提下,持续扩展 agent 的能力边界?

有一个问题困扰了团队一段时间:Claude 对"自己"其实并不那么了解。如果你问它"怎么添加一个 MCP"或者"slash command 是什么意思",它往往给不出准确的回答。

最直觉的做法是把这些信息塞进 system prompt。但用户询问此类问题的频率其实很低,把大量使用说明放进 system prompt,只会造成上下文"信息污染",干扰 Claude 执行它真正的核心任务——写代码。

于是团队尝试给 Claude 提供一个文档链接,让它按需自行加载。方向是对的,但实际效果差强人意——Claude 为了找到一个答案,会把大量无关内容全部加载进来,既低效又浪费上下文窗口。

最终的方案是构建一个专职的 Claude Code Guide 子 Agent:当用户询问 Claude Code 自身的用法时,主 Agent 把问题转交给它,由它负责在文档中精准定位答案。结果是:在不新增任何工具的前提下,Claude 的能力边界得到了有效扩展。

渐进式披露的本质,是"按需展开"的信息架构思路:不把所有能力平铺在模型面前,而是通过分层结构,让模型在真正需要的时候才去主动发现并加载对应的上下文与能力。

尾声:这是一门艺术

如果你期待从这篇文章里提炼出一套放之四海而皆准的工具设计规则,那可能要让你失望了——Thariq自己也坦承,这并不存在。工具的设计取决于你所使用的模型、agent的目标场景以及它所处的运行环境,没有哪个方案是永远正确的。

但有一件事是可以确定的:多做实验,认真读懂模型的输出,不断挑战已有的假设,并且时刻提醒自己——把自己带入agent的视角,像agent一样思考

这就是"Seeing like an agent"的真正含义。

原文链接:x.com/trq212/stat…