首页/技术博客/为MCP代理编写有效工具
为MCP代理编写有效工具
AI技术

为MCP代理编写有效工具

赵小姐(专栏作家)
2025/9/17
8分钟
22
AI前沿发展

Agent只和我们给他们的工具一样有效。我们分享如何编写高质量的工具和评估,以及如何使用Claude为自己优化工具来提高绩效。

模型上下文协议(MCP)可以为LLM代理提供可能的数百种工具来解决现实世界的任务。但是,我们如何使这些工具最有效呢?

在这篇文章中,1我们描述了我们在各种代理AI系统中提高性能的最有效技术。

我们首先介绍您如何:

构建和测试工具的原型
使用代理创建并运行工具的全面评估
与Claude Code等代理协作,自动提高工具的性能

我们以编写我们在此过程中确定的高质量工具的关键原则结束:

选择合适的工具来实现(而不是实施)
命名空间工具,以定义功能中的明确边界
将有意义的上下文从工具返回到代理
优化工具响应以提高令牌效率
提示工程工具描述和规格

head1.jpg 这是一张图片,描绘了工程师如何使用Claude Code来评估代理工具的功效。 构建评估程序允许您系统地测量工具的性能。您可以使用Claude Code自动优化您的工具,以抵御此评估。 什么是工具?

在计算中,确定性系统每次给出相同的输入时产生相同的输出,non-deterministic而非确定性系统(如代理)即使在相同的启动条件下也能产生不同的响应。

当我们传统上编写软件时,我们是在确定性系统之间建立契约。例如,一个函数调用像getWeather(“NYC”)总是会以完全相同的方式在纽约市的天气每次被称为。

工具是一种新型软件,它反映了确定性系统与非确定性代理之间的契约。当用户问“我今天应该带雨伞吗?”时,代理可能会打电话给天气工具,从一般知识中回答,甚至首先询问有关位置的澄清问题。偶尔,代理可能会产生幻觉,甚至无法掌握如何使用工具。

这意味着在为代理编写软件时从根本上重新思考我们的方法:我们不需要像为其他开发人员或系统编写函数和API那样编写工具和MCP服务器,我们需要为代理设计它们。

我们的目标是通过使用工具追求各种成功策略来增加代理可以有效解决各种任务的表面积。幸运的是,根据我们的经验,对于代理来说,最“人体工程学”的工具最终也会令人惊讶地直观地掌握为人类。 如何编写工具

在本节中,我们将介绍如何与代理协作编写和改进您给他们的工具。开始,快速启动工具原型,并在本地进行测试。接下来,进行全面评估,以衡量后续变化。与代理一起工作,您可以重复评估和改进工具的过程,直到您的代理在现实世界的任务中获得强大的性能。 构建原型

很难预测哪些工具代理商会找到符合人体工程学的工具,以及如果没有亲自动手,他们就不会使用哪些工具。开始,快速启动您的工具原型。如果您使用Claude Code编写工具(可能一次性),则有助于为您的工具所依赖的任何软件库,API或SDK(包括MCP SDK)提供Claude文档。LLM友好的文档通常可以在平面中找到llms.txt官方文档站点上的文件(这是我们的API)。

将工具包装在本地 MCP 服务器或桌面扩展 (DXT) 中将允许您在 Claude Code 或 Claude Desktop 应用程序中连接和测试工具。

要将本地 MCP 服务器连接到 Claude Code,请运行claude mcp add <name> <command> [args...]. .

要将本地 MCP 服务器或 DXT 连接到 Claude Desktop 应用程序,请导航到Settings > Developer或Settings > Extensions分别。

工具也可以直接传递到 Anthropic API 调用中,进行编程测试。

自己测试工具以识别任何粗糙的边缘。收集用户的反馈,围绕用例和提示建立直觉,你期望你的工具启用。 运行评估

接下来,你需要通过运行评估来衡量克劳德如何使用你的工具。从生成大量基于现实世界用途的评估任务开始。我们建议与代理商合作,帮助分析您的结果并确定如何改进您的工具。在我们的工具评估食谱中,看到这个过程端到端。 这张图测量了人类书面与人类书面的测试集的准确性。克劳德优化的Slack MCP服务器。 我们内部 Slack 工具的展示测试集性能

生成评估任务

使用您早期的原型,Claude Code可以快速探索您的工具并创建数十个提示和响应对。提示应该受到现实世界的启发,并基于现实的数据源和服务(例如,内部知识库和微服务)。我们建议您避免过于简单化或肤浅的“沙盒”环境,这些环境不会对工具进行足够复杂的压力测试。强大的评估任务可能需要多个工具调用 - 可能数十个。

以下是一些强有力的任务的例子:

下周安排与Jane的会面,讨论我们最新的Acme Corp项目。附上我们上次项目规划会议的笔记,并预订会议室。
客户ID 9182报告称,他们一次购买尝试被收取了三次费用。查找所有相关日志条目,并确定是否有任何其他客户受到同一问题的影响。
客户Sarah Chen刚刚提交了取消请求。准备一个保留报价。确定:(1)他们为什么要离开,(2)保留报价最引人注目,(3)在提出要约之前我们应该注意的任何风险因素。

以下是一些较弱的任务:

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

每个评估提示应与可验证的响应或结果配对。你的验证者可以像地面真相和样本反应之间的精确字符串比较一样简单,或者像招募克劳德来判断响应一样先进。避免过于严格的验证器,由于格式,标点符号或有效的替代措辞等虚假差异而拒绝正确响应。

对于每个提示响应对,您还可以选择指定您期望代理在解决任务时调用的工具,以衡量代理在评估期间是否成功抓住每个工具的目的。但是,由于可能有多个有效路径可以正确完成任务,因此请尽量避免过度指定或过度拟合策略。

运行评估

我们建议使用直接的 LLM API 调用以编程方式运行您的评估。使用简单的代理循环(while-loops 包装交替的 LLM API 和工具调用:每个评估任务一个循环。每个评估代理都应该给出一个单一的任务提示和你的工具。

在评估代理的系统提示中,我们建议指示代理不仅输出结构化响应块(用于验证),还输出推理和反馈块。before 在工具调用和响应块之前指示代理输出这些可以通过触发思想链(CoT)行为来增加LLMs的有效智能。

如果您正在与Claude一起进行评估,则可以打开“现成的”类似功能的交错思维。这将有助于您探索为什么代理会调用某些工具,并突出显示工具描述和规格中的特定改进领域。

除了顶级精度外,我们建议收集其他指标,例如单个工具调用和任务的总运行时间,工具调用总数,总令牌消耗和工具错误。跟踪工具调用可以帮助揭示代理追求的常见工作流程,并为工具提供一些整合机会。 这张图测量了人类书面与人类书面的测试集的准确性。克劳德优化的Asana MCP服务器。 我们内部 Asana 工具的展示测试集性能

分析结果 代理是您在发现问题和提供从矛盾的工具描述到低效工具实现和令人困惑的工具模式的所有内容的反馈方面的有用合作伙伴。然而,请记住,代理在反馈和响应中省略的内容通常比它们所包含的内容更重要。say what they meanLLM并不总是说出他们的意思。

观察你的代理人在哪里被绊倒或困惑。通读评估代理的推理和反馈(或CoT),以识别粗糙的边缘。检查原始成绩单(包括工具调用和工具响应),以捕获代理 CoT 中未明确描述的任何行为。读两行之间;记住,你的评估代理不一定知道正确的答案和策略。

分析您的工具调用指标。许多冗余工具调用可能表明需要对分页或令牌限制参数进行一些调整;许多无效参数的工具错误可能表明工具可以使用更清晰的描述或更好的示例。当我们推出克劳德的网络搜索工具时,我们发现克劳德不必要地追加2025工具的query参数,偏倚搜索结果和有辱人格的性能(我们通过改进工具描述引导克劳德朝着正确的方向前进)。 与代理商合作

你甚至可以让代理分析你的结果,并为你改进你的工具。只需将评估代理的成绩单并粘贴到Claude Code中即可。克劳德是分析成绩单和同时重构大量工具的专家,例如,确保工具实现和描述在做出新更改时保持自我一致。

事实上,这篇文章中的大部分建议来自反复优化我们使用Claude Code的内部工具实现。我们的评估是在内部工作空间之上创建的,反映了我们内部工作流程的复杂性,包括真实项目、文档和消息。

我们依靠坚持的测试集来确保我们不适合我们的“培训”评估。这些测试集表明,我们可以提取额外的性能改进,甚至超出我们通过“专家”工具实现实现的 - 无论这些工具是由我们的研究人员手动编写还是由克劳德本身生成。

在下一节中,我们将分享我们从这个过程中学到的一些东西。 编写有效工具的原则

在本节中,我们将学习成果提炼成编写有效工具的几个指导原则。 为代理商选择合适的工具

更多的工具并不总是能带来更好的结果。我们观察到的一个常见错误是仅包含现有软件功能或API端点的工具 - 无论这些工具是否适合代理。这是因为代理对传统软件有不同的“负担”,也就是说,他们有不同的方式来感知他们可以用这些工具采取的潜在行动。

LLM代理的“上下文”有限(也就是说,它们可以同时处理多少信息是有限的),而计算机内存是廉价和丰富的。考虑在通讯录中搜索联系人的任务。传统软件程序可以有效地存储和处理一个联系人列表,在继续之前检查每个联系人。

但是,如果LLM代理使用返回所有联系人的工具,然后必须逐个令牌读取每个令牌,那么它就会浪费其有限的上下文空间在不相关的信息上(想象一下,通过从上到下阅读每个页面来搜索通讯录中的联系人 - 即通过暴力搜索)。更好和更自然的方法(对于代理和人类一样)是先跳到相关页面(也许按字母顺序找到它)。

我们建议构建一些针对特定高影响力工作流程的周到工具,这些工具可匹配您的评估任务并从那里扩展。在通讯簿的情况下,您可以选择实现search_contacts或message_contact工具而不是Alist_contacts工具。

工具可以整合功能,multiple在引擎盖下处理潜在的多个离散操作(或API调用)。例如,工具可以使用相关元数据丰富工具响应,或在单个工具调用中处理频繁的多步任务。

Here are some examples:

而不是实施一个list_users,list_events,以及create_event工具,考虑实施Aschedule_event查找可用性并安排事件的工具。
Instead of implementing a read_logs tool, consider implementing a search_logs tool which only returns relevant log lines and some surrounding context.
Instead of implementing get_customer_by_id, list_transactions, and list_notes tools, implement a get_customer_context tool which compiles all of a customer’s recent & relevant information all at once.

Make sure each tool you build has a clear, distinct purpose. Tools should enable agents to subdivide and solve tasks in much the same way that a human would, given access to the same underlying resources, and simultaneously reduce the context that would have otherwise been consumed by intermediate outputs.

太多的工具或重叠的工具也会分散代理商对高效策略的注意力。仔细,有选择地规划您构建(或不构建)的工具可以真正获得回报。 命名 spaceing your tools

您的AI代理可能会访问数十台MCP服务器和数百种不同的工具,包括其他开发人员的工具。当工具在功能上重叠或具有模糊的目的时,代理可能会混淆使用哪些工具。

名称间距(在常见前缀下对相关工具进行分组)可以帮助划定许多工具之间的界限;MCP客户端有时默认执行此操作。例如,按服务对工具进行命名(例如,asana_search,jira_search) 和按资源(例如,asana_projects_search,asana_users_search),可以帮助代理在正确的时间选择正确的工具。

我们发现在基于前缀和后缀的命名间隔之间进行选择,以对我们的工具使用评估产生非平凡的影响。效果因LLM而异,我们鼓励您根据自己的评估选择命名方案。

代理可能会调用错误的工具,调用具有错误参数的正确工具,调用太少的工具,或者不正确地处理工具响应。通过选择性地实现名称反映任务自然细分的工具,您可以同时减少加载到代理上下文中的工具和工具描述的数量,并将代理计算从代理的上下文中卸载到工具调用本身。这降低了代理人犯错的整体风险。 从您的工具中返回有意义的上下文

同样,工具实现应注意只将高信号信息返回给代理。它们应优先考虑上下文相关性而不是灵活性,并避免采用低级技术标识符(例如:uuid,256px_image_url,mime_type。字段像name,image_url,以及file_type更有可能直接告知代理人的下游行动和反应。

代理也倾向于与自然语言名称,术语或标识符比使用神秘标识符更成功。我们发现,仅仅将任意字母数字UUID解析为更具语义意义和可解释的语言(甚至是0索引的ID方案),通过减少幻觉,显着提高了克劳德在检索任务中的精度。

在某些情况下,代理可能需要灵活地与自然语言和技术标识符输出交互,如果只是为了触发下游工具调用(例如,search_user(name=’jane’)→send_message(id=12345)。您可以通过曝光一个简单的功能来启用两者。response_format工具中的枚举参数,允许代理控制工具是否返回“concise”或“detailed”响应(下图)。

您可以添加更多格式以获得更大的灵活性,类似于 GraphQL,您可以在其中准确选择要接收哪些信息。以下是 ResponseFormat enum 以控制工具响应冗长性的示例:

enum ResponseFormat { DETAILED = "detailed", CONCISE = "concise" }

以下是详细工具响应(206 令牌)的示例: 此代码片段描述了详细工具响应的示例。

这里是一个简洁的工具响应(72个令牌)的示例: 此代码片段描绘了一个简洁的工具响应。 Slack 线程和线程回复由 unique 识别thread_ts需要获取线程回复。thread_ts以及其他ID(channel_id,user_id)可以从A中检索“detailed”工具响应,以启用需要进一步的工具调用,需要这些。“concise”工具响应仅返回线程内容并排除 ID。在这个例子中,我们使用 ~1⁄3 的令牌“concise”工具响应。

甚至你的工具响应结构(例如XML、JSON或Markdown)也会对评估性能产生影响:没有一刀切的解决方案。这是因为LLM经过下一个令牌预测的训练,并且倾向于使用与训练数据相匹配的格式表现更好。最佳响应结构将因任务和代理而有很大差异。我们鼓励您根据自己的评估选择最佳响应结构。 优化工具响应以提高令牌效率

优化环境质量很重要。但是,quantity 优化工具响应中返回给代理的上下文数量也是如此。

我们建议实现分页、范围选择、过滤和/或截断与合理的默认参数值的某种组合,用于任何可能占用大量上下文的工具响应。对于Claude Code,我们默认将工具响应限制为25,000个令牌。我们期望代理的有效上下文长度会随着时间的推移而增长,但需要保持上下文效率更高的工具。

如果您选择截断响应,请务必使用有用的说明引导代理。您可以直接鼓励代理追求更具令牌效率的策略,例如进行许多小型和有针对性的搜索,而不是对知识检索任务进行单一,广泛的搜索。类似地,如果工具调用出现错误(例如,在输入验证期间),则可以提示设计错误响应以清楚地传达特定和可操作的改进,而不是不透明的错误代码或回溯。

以下是截断工具响应的示例: 这张图片描绘了一个截断的工具响应的例子。

下面是一个无益的错误响应的例子: 这张图片描绘了一个无益的工具响应的例子。

下面是一个有用的错误响应的例子: 此图像描绘了一个有用的错误响应的示例。 工具截断和错误响应可以引导代理转向更省号的工具使用行为(使用过滤器或分页),或者给出正确格式化的工具输入的例子。 提示工程您的工具描述

我们现在来到最有效的改进工具的方法之一:提示工程您的工具描述和规格。因为这些被加载到你的代理的上下文中,它们可以共同引导代理走向有效的工具调用行为。

在编写工具描述和规格时,想想你如何向团队中的新员工描述你的工具。考虑你可能隐含地带来的上下文——专门的查询格式,利基术语的定义,底层资源之间的关系——并明确。通过明确描述(并用严格的数据模型执行)预期输入和输出来避免歧义。特别是,输入参数应该明确命名:而不是命名的参数user, 尝试一个命名的参数user_id. .

通过您的评估,您可以更有信心地衡量您的快速工程的影响。即使是对工具描述的微小改进也可以产生显着的改进。Claude Sonnet 3.5 在我们对工具描述进行精确改进,显著降低错误率和提高任务完成度后,在 SWE 板凳上取得了最先进的性能。

Developer Guide您可以在我们的开发人员指南中找到工具定义的其他最佳实践。如果您正在为Claude构建工具,我们还建议阅读有关工具如何动态加载到Claude的系统提示中。最后,如果您正在为MCP服务器编写工具,则工具注释有助于披露哪些工具需要开放世界访问或进行破坏性更改。 展望未来

为了为代理构建有效的工具,我们需要将我们的软件开发实践从可预测的确定性模式重新定位为非确定性模式。

通过我们在本文中描述的迭代,评估驱动过程,我们已经确定了使工具成功的一致模式:有效的工具是有意和明确定义的,明智地使用代理上下文,可以在不同的工作流程中组合在一起,并使代理能够直观地解决现实世界的任务。

在未来,我们期望代理与世界互动的具体机制将不断发展 - 从更新到MCP协议升级到底层LLM本身。通过系统化,评估驱动的方法来改进代理工具,我们可以确保随着代理变得更有能力,他们使用的工具将随之发展。 致谢

作者信息
赵小姐

赵小姐

专栏作家

专注于AI技术应用和企业数字化转型,拥有丰富的项目实践经验。

需要技术支持?

如果您对文章内容有疑问,或需要相关的技术解决方案,欢迎联系我们的专业团队。

联系我们