Agent 工具调用:从 Function Calling 到 MCP#
Agent 和 Chatbot 的本质区别:Agent 会"动手"——调用工具、读写数据、执行动作。工具调用(Tool Calling / Function Calling)是 Agent 的核心机制。这篇文章从机制讲起,到工程实践,到 MCP 标准化。
一、Function Calling 的机制#
核心流程:LLM 决定"该调哪个工具、传什么参数",系统执行,结果回填。
注意:LLM 只"决定"调用,不"执行"调用——执行是系统的责任。LLM 输出的是:工具名 + 参数(结构化 JSON)。
二、工具的定义:名称、描述、参数#
工具怎么定义,直接决定 LLM 能不能用对:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
{
"type": "function",
"function": {
"name": "search_resume",
"description": "在简历库中检索候选人。按关键词匹配技能/经历/职位。",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "检索关键词,如'Go 后端 3 年经验'"
},
"limit": {
"type": "integer",
"description": "返回条数,默认 10,最大 50"
}
},
"required": ["query"]
}
}
}
|
三个关键:
我的经验:工具描述是给 LLM 看的文档——“检索简历"和"在简历库中按技能/经历/职位关键词匹配,返回候选人和匹配度”,后者让 LLM 选得更准。
三、工程实践:工具调用的正确姿势#
1. 结果结构要"LLM 友好"#
1
2
3
4
5
6
7
8
9
|
// 错误:返回一堆无关字段,LLM 不知道该提取什么
// 正确:结构清晰 + 字段名语义化
{
"candidates": [
{"name": "张三", "skills": ["Go", "K8s"], "match_score": 92},
{"name": "李四", "skills": ["PHP"], "match_score": 65}
],
"total": 87
}
|
2. 错误要"可重试"#
1
2
3
4
|
// 工具失败返回的错误,LLM 要能理解并重试/换方式
{"error": "参数非法: date 格式应为 YYYY-MM-DD"}
{"error": "上游超时,请重试"}
{"error": "无权限访问该资源"}
|
3. 多轮工具调用(Agent 的"思考链")#
允许多轮工具调用:LLM 可以连续调多个工具(每次调用结果回填上下文,LLM 决定下一步)。
4. 工具循环的安全#
四、从 Function Calling 到 MCP#
演进关系:
五、选型建议#
| 场景 |
方案 |
| 单模型快速开发 |
直接用 Function Calling(最简) |
| 多模型/多应用复用工具 |
MCP(标准化) |
| 企业级工具治理 |
MCP + 鉴权 + 审计 |
| 纯本地小工具 |
Function Calling + 简单函数映射 |
我的实践:AI 面试产品早期用 Function Calling(快),后期工具多了、要复用了(Best 东方 Skills 给外部 LLM 用),迁到 MCP——机制不变,协议标准化。
六、踩坑记录#
- 描述写得太简:LLM 不知道该不该用这工具 → 描述写"能力 + 边界 + 示例"
- 参数校验在 LLM 侧做:LLM 传错参数就报错 → 系统侧宽松解析 + 纠错(日期格式自动归一)
- 工具结果过长:塞进上下文 token 爆炸 → 结果裁剪(只回 Top N + 摘要)
- 并行工具调用滥用:一次调 10 个 → 改成"只调相关的 1-3 个"(LLM 靠描述判断)
工具调用的核心认知:
- 机制:LLM 决定"调什么、传什么",系统执行"真调用"
- 定义质量决定效果:名称清晰、描述写全、参数描述准
- 多轮调用是 Agent 的本质:连续工具调用 = 解决问题的过程
- MCP 是工具层的标准化:Function Calling 是机制,MCP 是协议
Agent 的能力边界 = 工具集的能力边界。 会定义工具、会管理调用循环、会用 MCP 标准化——这是 AI 应用工程师的核心技能。
微信公众号「福清而不淡」
后端架构 · AI 工程 · 云原生的一线实践,扫码关注,不错过更新。
本文已同步发布到公众号,欢迎留言交流。