Skip to content

Commit 0514c47

Browse files
committed
完成「Agent实现原理与实践」二到六,共五篇文章
1 parent 2030032 commit 0514c47

13 files changed

Lines changed: 2501 additions & 0 deletions

File tree

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
根据你分享的网页内容,这里为你整理并转换成排版清晰、结构分明的 **Markdown** 格式:
2+
3+
---
4+
5+
# 编写高效的智能体工具——使用智能体本身
6+
7+
**发布日期**:2025年9月11日
8+
9+
*智能体的效率完全取决于我们赋予它们的工具。本文将分享如何编写高质量的工具与评估流程,以及如何通过使用 Claude 针对自身优化工具来提升整体性能。*
10+
11+
[Model Context Protocol (MCP)](https://www.anthropic.com/engineering/writing-tools-for-agents) 可以为 LLM 智能体赋予成百上千种工具来解决现实世界的任务。但我们该如何让这些工具发挥最大效用?
12+
13+
在本文中,我们将介绍我们在提升各种智能体 AI 系统性能方面最有效的技术。内容包括:
14+
15+
* 构建和测试你的工具原型
16+
* 利用智能体创建并运行全面的工具评估
17+
* 与 Claude Code 等智能体协同,自动提升工具的性能
18+
19+
最后,我们将总结在探索过程中发现的**编写高质量工具的核心原则**
20+
21+
* 选择合适的工具进行开发(以及避开不适合的工具)
22+
* 通过命名空间(Namespacing)划分清晰的功能边界
23+
* 从工具向智能体返回有价值的上下文
24+
* 针对 Token 效率优化工具的响应内容
25+
* 对工具的描述和规范进行提示词工程(Prompt Engineering)
26+
27+
---
28+
29+
## 什么是工具?
30+
31+
在计算机科学中,**确定性系统**(Deterministic systems)在给定相同输入时每次都会产生完全相同的输出。而**非确定性系统**(Non-deterministic systems)——比如智能体——即使在相同的初始条件下,也可能产生多样化的响应。
32+
33+
传统的软件开发是在确定性系统之间建立契约。例如,调用函数 `getWeather("NYC")` 每次都会以完全相同的方式获取纽约市的天气。
34+
35+
**工具(Tools)**是一种新型软件,它反映了**确定性系统****非确定性智能体**之间的契约。当用户提问 *“我今天需要带伞吗?”* 时,智能体可能会调用天气工具,也可能根据通用知识回答,甚至可能先询问具体的地理位置。有时,智能体还可能会产生幻觉,或者无法正确理解如何使用某个工具。
36+
37+
因此,为智能体编写软件需要从根本上转变思维:我们不能再像为其他开发者或系统编写函数和 API 那样去编写工具和 MCP 服务器,而是必须**面向智能体进行设计**
38+
39+
我们的目标是:通过利用工具追求多样化的成功策略,扩大智能体在解决广泛任务时的有效“表面积”。幸运的是,根据我们的经验,那些对智能体最“符合人体工程学”(Ergonomic)的工具,往往对人类来说也出奇地直观易懂。
40+
41+
---
42+
43+
## 如何编写工具
44+
45+
在本节中,我们将介绍如何与智能体协同来编写并改进工具。
46+
47+
### 1. 构建原型
48+
49+
在亲自动手之前,很难预料智能体觉得哪些工具好用、哪些不好用。你可以先快速搭建一个工具原型并在本地进行测试。
50+
51+
* **提供文档**:如果你使用 Claude Code 来编写工具,为 Claude 提供工具将依赖的软件库、API 或 SDK(包括 MCP SDK)的文档会很有帮助。
52+
* **本地连接**:将你的工具封装在本地 MCP 服务器或桌面扩展(DXT)中。
53+
* 连接到 **Claude Code**:运行 `claude mcp add <name> <command> [args...]`
54+
* 连接到 **Claude Desktop** 应用:导航至 `Settings > Developer``Settings > Extensions`
55+
56+
57+
58+
### 2. 运行评估
59+
60+
你需要通过运行评估来系统地衡量 Claude 使用工具的效果。建议协同智能体来帮助分析结果并决定如何改进工具。
61+
62+
* **生成评估任务**:任务应源于现实世界的使用场景,并基于真实的数据源和业务服务(例如内部知识库和微服务),避免使用过于简单的“沙盒”环境。
63+
> **优秀任务示例**
64+
> * *“下周与 Jane 安排一个会议,讨论我们最新的 Acme Corp 项目。附上上一次项目规划会议的记录,并预订一间会议室。”*
65+
> * *“客户 ID 9182 报告说他们的一次购买被扣款了三次。查找所有相关日志,并确定是否有其他客户受到相同问题的影响。”*
66+
>
67+
>
68+
69+
70+
> **较弱任务示例**
71+
> * *“下周与 jane@acme.corp 安排一个会议。”*
72+
> * *“在支付日志中搜索 purchase_complete 且 customer_id=9182。”*
73+
>
74+
>
75+
76+
77+
* **运行评估流程**:建议通过直接的 LLM API 调用来编程式地运行评估。使用简单的智能体循环(包装了交替执行的 LLM API 和工具调用的 `while` 循环)。在系统提示词中,**引导智能体在调用工具前先输出其推理和反馈内容**(思维链 CoT),这能显著提升大模型的实际表现。
78+
* **分析结果**:观察智能体在何处卡壳或感到困惑。检查工具调用指标:大量冗余的工具调用可能意味着需要调整分页或 Token 限制参数;大量的参数错误报错则意味着工具描述需要更清晰。
79+
80+
### 3. 与智能体协同优化
81+
82+
你可以直接把评估智能体的运行日志复制到 Claude Code 中,让它帮你分析结果并重构工具。
83+
84+
在实际测试中,这种基于留出测试集(Held-out test sets)的自动化优化表现优异,其最终提取的性能提升甚至超越了研究员手动编写的“专家级”工具实现。
85+
86+
---
87+
88+
## 高效编写工具的指导原则
89+
90+
### 原则一:为智能体选择“对”的工具
91+
92+
工具并不是越多越好。一个常见的错误是直接把现有的软件功能或 API 接口原封不动地包装成工具,而不考虑其是否适合智能体。
93+
94+
* **避免高消耗的暴力搜索**:如果一个工具直接返回“所有联系人”,智能体就必须逐个 Token 地去阅读,这会极大地浪费其宝贵的上下文空间。
95+
* **整合与提炼**:建立少数几个针对高影响工作流的精细工具。
96+
* *改进前*:分别提供 `list_users``list_events``create_event`
97+
* *改进后*:合并为一个 `schedule_event` 工具,自动查找空闲时间并安排日程。
98+
* *改进前*:提供 `read_logs`
99+
* *改进后*:提供 `search_logs`,仅返回相关的日志行及上下文。
100+
101+
102+
103+
### 原则二:为工具划分命名空间(Namespacing)
104+
105+
当工具功能重叠或目的模糊时,智能体容易混淆。通过通用前缀对相关工具进行分组(例如:按服务划分 `asana_search``jira_search`;按资源划分 `asana_projects_search``asana_users_search`),可以帮助智能体在正确的时间选择正确的工具。
106+
107+
### 原则三:返回有意义的上下文
108+
109+
工具实现应优先返回高信号(高价值)的信息。
110+
111+
* **多用语义化语言,少用低级技术标识符**:相比于加密的 UUID、Mime 类型或复杂的图片 URL,诸如 `name``file_type` 这样人类可读的字段更有助于智能体的下一步决策。
112+
* **控制返回格式**:如果智能体既需要自然语言输出,又需要技术 ID 来触发下游工具,可以在工具中暴露一个 `ResponseFormat` 枚举参数,让智能体自主控制返回“简要(CONCISE)”还是“详细(DETAILED)”的响应,从而节省多达 $\sim 1/3$ 的 Token。
113+
114+
```typescript
115+
enum ResponseFormat {
116+
DETAILED = "detailed",
117+
CONCISE = "concise"
118+
}
119+
120+
```
121+
122+
### 原则四:优化 Token 效率
123+
124+
针对可能返回大量数据的工具,务必实现分页(Pagination)、范围选择、过滤或截断(Truncation)机制,并设置合理的默认参数。
125+
126+
* 在 Claude Code 中,默认将工具响应限制在 25,000 个 Token 以内。
127+
* 当工具抛出错误(例如输入验证失败)时,应通过提示词工程让错误信息清晰地传达**具体的、可操作的改进建议**,而不是返回晦涩的错误代码或一整段堆栈轨迹(Tracebacks)。
128+
129+
### 原则五:对工具描述进行提示词工程
130+
131+
工具的描述和规范会被直接加载到智能体的上下文中。编写工具描述时,把它当成你在向团队里的新员工介绍这个工具:
132+
133+
* **将隐式背景显性化**:明确说明特殊的查询格式、利基术语的定义以及底层资源之间的关系。
134+
* **消除参数歧义**:使用严谨的数据模型,避免含糊的命名。例如,不要使用 `user` 作为参数名,而应使用 `user_id`
135+
136+
精确的工具描述改进效果显著。在 Anthropic 对 `Claude Sonnet 3.5` 进行精细化工具描述调整后,其在 **SWE-bench Verified** 评估中取得了行业领先(State-of-the-art) incremental 的优异表现。

0 commit comments

Comments
 (0)