当前位置: 首页 » 资讯 » 新科技 » 正文

如何为LLM智能体编写工具?Anthropic官方教程来了

IP属地 中国·北京 机器之心Pro 时间:2025-09-12 22:28:19




机器之心报道

机器之心编辑部

好工具,才有好智能体。

智能体(Agent)时代,工具已不再只是传统 API 或函数接口的简单封装,而是决定智能体能否高效完成任务的关键。

为了让智能体真正释放潜力,我们需要重新思考工具开发的方式。传统软件开发依赖确定性逻辑,而智能体是非确定性的,它们在相同输入下可能产生不同输出,这意味着为智能体设计工具需要新的范式。

而新的范式不仅仅是如何开发工具,更在于如何让工具真正发挥最大效能。毕竟,AI 智能体的强大程度取决于我们为其提供的工具,但问题是:如何让这些工具发挥最大效能?

来自 Anthropic 的一篇文章为大家指出了一条可行路径。



原文链接:https://www.anthropic.com/engineering/writing-tools-for-agents

以下是博客内容:

在这篇文章中,Anthropic 介绍了一些在多种 agentic AI 系统中被证明最有效的性能提升技巧。

阅读本文后,你可以做到:

构建并测试工具原型;如何创建并运行全面的评估;与智能体协作(如 Claude Code),自动提升模型性能。



工具的定义

在计算机中,确定性系统在给定相同输入时,每次都会产生相同的输出;而非确定性系统,比如智能体,即便在相同的初始条件下,也可能生成不同的响应。

在传统的软件开发中,我们是在确定性系统之间建立契约。例如,一个关于天气的函数调用 getWeather ("NYC"),无论调用多少次,都将以完全相同的方式返回纽约的天气。

而基于大模型的工具是一种全新的软件形式,它体现的是确定性系统与非确定性智能体之间的契约。

举个例子:当用户问「我今天要带伞吗?」时,智能体可能会调用天气工具、也可能直接基于常识回答,甚至先提出一个澄清性问题(比如确认具体地点)。有时,智能体还可能出现幻觉,或者根本没弄明白该如何使用工具。

这意味着,我们在为智能体编写软件时,必须从根本上重新思考方法:不能再把工具和 MCP 服务器当作普通函数或 API 来写,而是需要专门为智能体设计。

那如何设计工具呢?

如何编写工具?

首先,快速搭建工具原型并在本地进行测试。

接着,进行全面评估来衡量后续改动带来的影响。

在与智能体协作的过程中,你可以不断重复评估与改进这一循环,直到智能体能够在现实任务中表现出强劲的性能。

构建原型

在该教程中,我们以基于 Claude 的智能体构建为例。

如果你使用 Claude Code 来编写工具,最好向 Claude 提供相关的文档,例如工具依赖的软件库、API 或 SDK(包括可能用到的 MCP SDK)。

另外,适合 LLM 阅读的文档通常可以在官方文档网站上以 llms.txt 文件的形式找到,大家可以自行下载。

你也可以将工具封装在本地 MCP 服务器或桌面扩展程序 (DXT) 中,即可在 Claude Code 或 Claude Desktop 应用中连接并测试这些工具。

值得一提的是,如果你要将本地 MCP 服务器连接到 Claude Code,请运行 claude mcp add

[args...]。

此外,要将本地 MCP 服务器或 DXT 连接到 Claude Desktop 应用,请分别前往「设置”>“开发者” 或 “设置”>“扩展程序”」。你也可以将工具直接传入 Anthropic API 调用进行编程测试。

这些做完之后,还要自行测试以发现不足之处。

运行评估

接下来,你需要通过评估来衡量工具的效果。



评估可以分为几个部分进行,首先是生成评估任务。

在你完成早期原型后,Claude Code 可以检验你的工具,并生成数十组提示与响应对。

这些提示应当源自真实的使用场景,并基于真实的数据源和服务(例如内部知识库和微服务)。

本文建议避免使用过于简单或太过于表面的沙盒环境,因为那样无法在足够复杂的条件下对工具进行压力测试。那些高质量的评估任务往往需要多次工具调用,甚至可能多达数十次。

那什么是好的任务评估呢?大家可以参考如下示例:

安排下周与 Jane 会面,讨论我们最新的 Acme Corp 项目。附上我们上次项目规划会议的记录,并预订会议室。客户 ID 9182 报告称,他们单次购买被扣款三次。查找所有相关日志条目,并确定是否有其他客户受到同一问题的影响。客户 Sarah Chen 刚刚提交了取消订单的申请。准备一份留任方案。确定:(1) 他们离开的原因;(2) 哪种留任方案最具吸引力;以及 (3) 在提出方案之前我们应该注意的风险因素。

还有一些较弱的任务:

安排下周与 jane@acme.corp 的会议。在付款日志中搜索 purchase_complete 和 customer_id=9182。查找客户 ID 为 45892 的取消请求。

每个评估 prompt 都应与可验证的响应或结果配对。你设置的验证器可以简单到只是在基本事实和采样响应之间进行精确的字符串比较,也可以高级到请大模型来判断响应。避免使用过于严格的验证器,因为这些验证器会因为格式、标点符号或有效的替代措辞等虚假差异而拒绝正确的响应。

对于每个提示 - 响应对,你还可以选择指定智能体在解决任务时调用的工具,以衡量智能体在评估过程中是否成功掌握了每个工具的用途。但是,由于正确解决任务可能存在多种有效途径,因此请尽量避免过度指定或过度拟合策略。

接着是运行评估。

本文建议通过直接调用 LLM API 以编程方式运行评估。

还可以采用简单的智能体循环(例如用 while 循环交替包装 LLM API 与工具调用):每个评估任务对应一个循环。每个评估智能体应被分配一个任务提示和相关工具。

如果你使用 Claude 运行评估,可以直接启用 interleaved thinking(交错思维)。这样一来你就能探究智能体为何调用或不调用某些工具。

在评估过程中,除了准确率,本文还建议收集智能体的其他指标,例如:

单次工具调用和任务的总运行时间;工具调用总次数;总 token 消耗;工具错误情况。



接下来是结果分析。

通常来讲,有时智能体在反馈和回答中遗漏的内容,往往比它们提到的内容更重要。LLM 并不总是准确表达出它们的真实含义。

你需要观察智能体在什么地方会卡住或感到困惑。我们需要根据反馈,定位工具的薄弱环节。

与此同时,我们需要回顾原始对话记录(包括工具调用和工具响应),以捕捉那些没有明确出现在智能体 CoT 中的行为。记住评估智能体并不一定真正知道正确答案或最佳策略。

另外,还需要分析你的工具调用指标:

冗余调用过多 → 可能说明需要重新设计分页或 token 限制参数;无效参数导致的错误过多 → 可能说明工具需要更清晰的描述或更好的使用示例。

用户还可以与智能体协作。

你甚至可以让智能体直接帮你分析结果并改进工具。

只需将评估智能体的对话记录拼接起来,然后粘贴到 Claude Code 中即可。Claude 擅长分析对话记录,并能一次性重构大量工具。

如何编写高效工具?有哪些原则

选择合适的工具

并不是说工具越多,结果就越好。我们观察到一个现象:工具只是简单封装了现有软件功能或 API 接口,而很多时候调用这些工具是否真正适合智能体还未知。

原因在于,智能体与传统软件有着不同的可供性(affordances),也就是说,它们感知并使用工具的方式与传统软件截然不同

举个例子:LLM 智能体的上下文有限(即一次能处理的信息量有限),而计算机内存廉价且几乎无限。在地址簿中查找联系人这个任务上,传统软件可以高效地逐个存储并处理联系人,检查完一个再检查下一个。

然而,如果一个 LLM 智能体使用的工具返回了所有联系人,并且必须逐个 token 地读完,那么它就会把有限的上下文空间浪费在无关信息上。(想象一下,在地址簿里找联系人时,你得从头到尾一页一页翻阅,这其实就是一种暴力搜索。)

更好、更自然的方式(无论对智能体还是对人类而言)都是直接跳到相关页面(比如按字母顺序定位)。

因此,本文建议先构建少量经过深思熟虑的工具,针对高价值的工作流,并与评估任务保持一致,然后再逐步扩展。在地址簿的例子中,你可以实现一个 search_contacts 或 message_contact 工具,而不是简单地提供一个 list_contacts 工具。

此外,工具还有整合能力,能在底层同时处理多个离散操作(或 API 调用)。

例如,工具可以:

在返回结果时附加相关元数据;或者在一次调用中完成经常需要串联的多步任务。

以下是整合功能的一些示例:

与其分别实现 list_users、list_events 和 create_event 工具,不如实现一个 schedule_event 工具,它可以查找空闲时间并能直接安排其他任务。与其实现一个 read_logs 工具,不如实现一个 search_logs 工具,它只返回相关的日志行以及必要的上下文。与其实现 get_customer_by_id、list_transactions 和 list_notes 工具,不如实现一个 get_customer_context 工具,它能一次性汇总某个客户的所有近期且相关的信息。

所以说,你构建的每个工具都应当具有清晰且独立的目标。工具应当使智能体能够像人类一样,在获取相同底层资源的情况下,去分解并解决任务,同时还能减少原本会被中间结果消耗掉的上下文空间。

过多的工具或功能重叠的工具,反而会分散智能体的注意力,阻碍其选择高效的策略。

因此,谨慎且有选择性地规划哪些工具需要构建(或不需要构建),往往会带来更大的回报。

为工具设置命名空间

AI 智能体可能会接入数十个 MCP 服务器和数百个不同的工具,其中还包括其他开发者编写的工具。

当工具在功能上出现重叠,或者用途模糊不清时,智能体就可能会混淆该用哪个工具。

命名空间(即给相关工具加上统一前缀分组)可以划清不同工具之间的边界;有些 MCP 客户端会默认采用这种方式。

例如,可以按服务进行命名空间划分(如 asana_search、jira_search),也可以按资源划分(如 asana_projects_search、asana_users_search),这样能够帮助智能体在合适的时机选择正确的工具。

本文发现,前缀式命名和后缀式命名在工具使用评估中的效果并不相同。本文建议根据你的评估结果来选择合适的命名方式。

假如不这样做的话,智能体可能会:

调用错误的工具;或者用错误的参数调用正确的工具;又或者调用的工具太少;甚至错误地处理了工具响应。

从工具中返回有意义的上下文

同样,工具实现应注意仅向智能体返回高信号信息。它们应优先考虑上下文相关性而非灵活性,并避免使用低级技术标识符(例如:uuid、256px_image_url、mime_type)。诸如 name、image_url 和 file_type 之类的字段更有可能直接影响智能体的下游操作和响应。

智能体处理自然语言名称、术语或标识符的能力也显著优于处理隐晦的标识符。实践发现,仅仅将任意字母数字 UUID 解析为语义上更有意义且更易于解释的语言(甚至是 0 索引的 ID 方案)就能显著提高 Claude 在检索任务中的准确率,从而减少幻觉。

在某些情况下,智能体可能需要灵活地与自然语言和技术标识符输出进行交互,哪怕只是为了触发下游工具调用(例如,search_user (name=’jane’) → send_message (id=12345))。你可以通过在工具中公开一个简单的 response_format 枚举参数来启用这两种功能,从而允许智能体控制工具返回「简洁」还是「详细」的响应(如下图所示)。

你可以添加更多格式以获得更大的灵活性,类似于 GraphQL,也可以精确选择要接收的信息。以下是一个用于控制工具响应详细程度的 ResponseFormat 枚举示例:

enum ResponseFormat {

DETAILED = "detailed",

ConCISE = "concise"

以下是详细工具响应的示例(206 个 token):



以下是一个简洁工具响应(72 个 token)的示例:

Slack 线程和线程回复由唯一的 thread_ts 标识,这些 thread_ts 是获取线程回复所必需的。thread_ts 和其他 ID(channel_id、user_id)可以从「详细」工具响应中检索,以便后续需要这些 ID 的工具调用。「简洁」工具响应仅返回线程内容,不包含 ID。本例中使用约 1/3 个 token 作为「简洁」工具响应。

你的工具响应结构(例如 XML、JSON 或 Markdown)也会对评估性能产生影响:没有一刀切的解决方案。这是因为 LLM 是基于下一个 token 预测进行训练的,并且往往在使用与其训练数据匹配的格式时表现更佳。最佳响应结构会因任务和智能体而异,建议根据自身的评估选择最佳响应结构。

优化工具响应以提高 token 效率

优化上下文质量至关重要。但优化工具响应中返回给智能体的上下文数量也同样重要。

Anthropic 建议,对于任何可能消耗大量上下文的工具响应,结合分页、范围选择、过滤和 / 或截断功能,并设置合理的默认参数值。对于 Claude Code 来说,工具响应限制默认是 25000 个 token。未来智能体的有效上下文长度会随着时间的推移而增长,但对上下文高效工具的需求会始终存在。

如果你选择截断响应,请务必为智能体提供实用的指导。你可以直接鼓励智能体采用更高效的 token 策略,例如,在知识检索任务中进行多次小规模、有针对性的搜索,而不是进行单一、广泛的搜索。同样,如果工具调用引发错误(例如,在输入验证期间),你可以对错误响应进行提示式设计,以清晰地传达具体且可操作的改进措施,而不是使用晦涩难懂的错误代码或回溯。

以下是截断工具响应的示例:



以下是一个无用的错误响应示例:



以下是一个有用的错误响应示例:



快速构建工具描述

现在来谈谈改进工具的最有效方法之一:快速构建工具描述和规范。由于这些内容会加载到智能体的上下文中,因此它们可以共同引导智能体实现有效的工具调用行为。

在编写工具描述和规范时,请思考如何向团队中的新成员描述你的工具。考虑到可能隐式引入的上下文 —— 专用查询格式、专业术语的定义、底层资源之间的关系 —— 并将其明确化。通过清晰描述(并使用严格的数据模型强制执行)预期的输入和输出,避免歧义。特别是,输入参数的命名应清晰明确:不要使用名为 user 的参数,而应尝试使用名为 user_id 的参数。

通过评估,你可以更有信心地衡量快速构建的影响。即使对工具描述进行微小的改进,也能带来显著的提升。在对工具描述进行精准改进后,Claude Sonnet 3.5 在 SWE-bench Verified 评估中取得了最佳性能,大幅降低了错误率,并提高了任务完成率。

展望未来

为了构建高效的智能体工具,我们需要重新调整软件开发实践,从可预测的确定性模式转向非确定性模式。

通过本文中描述的迭代式、评估驱动的流程,现在已经出现了使工具成功的一致模式:高效的工具应具有清晰明确的定义,能够合理地利用智能体上下文,能够在不同的工作流程中组合使用,并支持智能体直观地解决现实世界中的任务。

Anthropic 预计,智能体与世界交互的具体机制将不断演变 —— 从 MCP 协议的更新到底层 LLM 本身的升级。通过系统化的、评估驱动的方法来改进智能体工具,我们可以确保随着智能体能力的提升,它们所使用的工具也能随之发展。

免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其内容真实性、完整性不作任何保证或承诺。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。

全站最新