像智能体一样思考:Claude Code工具设计实践
DataHot 速览
本文由Anthropic团队分享其在构建Claude Code时设计智能体工具的经验。作者提出一个框架:为智能体选择工具应基于其自身能力,并通过观察和实验来理解其能力。他们通过三个迭代版本开发了AskUserQuestion工具以改进启发式提问,用Task工具替换TodoWrite以更好地支持子代理协作,并用Grep工具替代RAG以让Claude自主搜索代码库。文章强调随着模型能力增强,曾经有用的工具可能成为限制,需要不断重新审视。
为什么值得关注:文章提供了数据Agent(如ChatBI/Text-to-SQL)工具设计的实战方法论,对构建智能分析代理的开发者具有直接参考价值。
本文目录 8 节
译文
AI 逐段翻译构建智能体框架最难的部分之一就是构造其工具。
Claude完全通过工具调用来运作,但在Claude API中,有多种方式可以使用诸如bash、技能和代码执行等原语来构造工具。(你可以在@RLanceMartin的新文章中了解更多关于Claude API编程式工具调用的信息)。
那么,如何设计你的智能体工具呢?是给它一个像bash或代码执行这样的通用工具?还是五十个专用工具,每个用例一个?
设身处地为模型想想,假如给你一道难题,你希望用什么工具来解决?这取决于你自己的技能组合!
纸是最低要求,但手动计算会受到限制。计算器会更好,但你需要知道如何使用更高级的选项。最快最强大的选择是电脑,但你必须知道如何使用它来编写和执行代码。
这是一个设计智能体的有用框架。你想给它提供适合其自身能力的工具。但你怎么知道这些能力是什么?你需要注意、阅读其输出、进行实验。你要学会像智能体一样去看。
如果你正在构建智能体,你会面临和我们一样的问题:何时添加工具、何时移除工具,以及如何区分。以下是我们构建Claude Code时如何回答这些问题的,包括我们最初出错的地方。
使用AskUserQuestion工具改进启发式提问

在构建AskUserQuestion工具时,我们的目标是提高Claude提问(通常称为启发式提问)的能力。
虽然Claude可以用纯文本提问,但我们发现回答这些问题感觉花费了不必要的时间。我们如何降低这种摩擦并提高用户与Claude之间的沟通带宽?
尝试1:修改ExitPlanTool
我们尝试的第一种方法是在ExitPlanTool中添加一个参数,使其包含一系列问题以及计划。这是最容易实现的修复,但它使Claude困惑,因为我们同时要求一个计划和关于计划的问题。如果用户的回答与计划内容冲突怎么办?Claude是否需要调用ExitPlanTool两次?我们知道这种策略行不通,所以回到了绘图板。(你可以在我们关于提示缓存的文章中了解更多关于为什么我们制作ExitPlanTool的内容)
尝试2:改变输出格式
接下来,我们尝试更新Claude的输出指令,使其提供一种稍作修改的markdown格式用于提问。例如,我们可以要求它输出带有方括号中选项的要点问题列表。然后我们可以解析并将该问题格式化为用户的UI。
Claude通常能产生这种格式,但不可靠。它可能会附加额外的句子、漏掉选项或完全放弃结构。转向下一种方法。
尝试3:AskUserQuestion工具

最后,我们决定创建一个Claude可以随时调用的工具,但在计划模式下特别提示它这样做。当工具触发时,我们会显示一个模态框来显示问题,并阻塞代理的循环直到用户回答。
这个工具允许我们提示Claude提供结构化输出,并帮助确保Claude给用户提供多个选项。它还为用户提供了组合此功能的方法,例如在Agent SDK中调用它,或在技能中引用它。
最重要的是,Claude似乎喜欢调用这个工具,我们发现其输出效果很好。毕竟,即使设计最好的工具,如果Claude不理解如何调用它,也不会起作用。
这是Claude Code中启发式提问的最终形式吗?我们表示怀疑。随着Claude能力增强,服务于它的工具也必须进化。下一节展示了一个曾经有帮助的工具开始碍事的案例。
随能力更新:任务和待办事项

当我们首次发布Claude Code时,我们意识到模型需要一个待办事项列表来保持正轨。待办事项可以在开始时编写,并在模型完成工作时勾选。为此,我们给了Claude TodoWrite工具,它用于写入或更新待办事项并向用户显示。
但即便如此,我们经常看到Claude忘记它必须做什么。为了适应,我们每5轮插入系统提醒,提醒Claude其目标。
随着模型的改进,它们发现待办事项列表具有局限性。收到待办事项列表的提醒让Claude觉得必须坚持列表,而不是在意识到需要改变方向时修改它。我们还看到Opus 4.5在使用子代理方面变得更好,但子代理如何协调共享的待办事项列表?
看到这一点,我们用Task工具替换了TodoWrite功能。待办事项侧重于保持模型在正轨上,而任务帮助代理之间相互通信。任务可以包含依赖关系,在子代理之间共享更新,模型可以修改和删除它们。
随着模型能力的增强,你的模型曾经需要的工具现在可能限制它们。重要的是要不断重新审视以前关于需要什么工具的假设。这也是为什么坚持支持一小组能力概况相当相似的模型很有用。
设计搜索界面
我们构建的最重要的工具是那些让Claude自己找到上下文的工具。
当Claude Code首次内部发布时,我们使用了RAG:向量数据库会预先索引代码库,框架会检索相关片段并在每次响应前交给Claude。虽然RAG强大且快速,但它需要索引和设置,并且可能在各种环境中变得脆弱。最重要的是,Claude是被给予这个上下文,而不是自己找到上下文。
但如果Claude能在网上搜索,为什么它不能搜索你的代码库呢?通过给Claude一个Grep工具,我们可以让它自己搜索文件并构建上下文。
随着Claude变得更聪明,在获得合适工具的情况下,它越来越擅长构建自己的上下文。
当我们推出Agent Skills时,我们正式确立了一种渐进式披露的理念,允许代理通过探索逐步发现相关上下文。
Claude现在可以读取技能文件,而这些文件又可以引用模型能够递归读取的其他文件。事实上,技能的一个常见用途是为Claude添加更多搜索能力,比如给它使用API或查询数据库的指令。
在一年时间里,Claude从不能真正构建自己的上下文,发展到能在多层文件中进行嵌套搜索,以找到所需的精确上下文。
渐进式披露现在是我们用来在不添加工具的情况下添加新功能的常用技术。在下一节中,我们将解释原因。
渐进式披露:Claude Code指南代理
Claude Code目前拥有约20个工具,我们的团队经常重新评估是否需要所有这些工具才能让Claude最有效。添加新工具的门槛很高,因为这会提供给模型一个额外的选择来考虑。
例如,我们注意到Claude对如何使用Claude Code了解不够。如果你问它如何添加MCP或某个斜杠命令是做什么的,它将无法回答。
我们可以把所有这些信息放在系统提示中,但鉴于用户很少问这些问题,这会造成上下文腐烂,干扰Claude Code的主要工作:编写代码。
相反,我们尝试了渐进式披露:我们给Claude一个指向其文档的链接,它可以在需要时加载和搜索。这有效,但Claude会把大块文档拉入上下文,以找到一个用户本来一句话就能得到的答案。
因此,我们构建了Claude Code指南——一个Claude在用户询问Claude Code本身时调用的子代理。子代理在自己的上下文中进行文档搜索,遵循详细的搜索和提取说明,只返回答案。主代理的上下文保持干净。
虽然这不是一个完美的解决方案(当用户问Claude如何设置自身时,它仍然可能感到困惑),但我们能够在不添加新工具的情况下为Claude的行动空间增加功能。
像代理一样观察是一门艺术,而非科学
为你的模型设计工具既是一门艺术,也是一门科学。这在很大程度上取决于你使用的模型、代理的目标以及其运行的环境。
我们最好的建议是什么?经常实验,阅读你的输出,尝试新事物。最重要的是,尝试像代理一样观察。
立即开始使用Claude Code。
关于作者: Thariq Shihipar是Anthropic的技术人员,从事Claude Code的工作。
这篇内容对你有用吗?
反馈只用于改善内容筛选,不等同于收藏