一、什么是智能体
在经典智能体框架中,智能体(Agent)一般指能够在环境中感知信息、基于策略做出决策并采取行动,以最大化回报或满足目标约束的系统。
在大模型应用开发中,智能体通常指一种以大语言模型为推理与决策核心,结合记忆、工具调用与环境交互能力,能够进行规划决策并执行动作以达成目标的软件系统。
OpenAI 前安全系统团队负责人翁丽莲(Lilian Weng)于 2023 年 6 月在个人博客中系统化总结了当时流行的 LLM Agent 典型架构。

实际开发中,四个要素并不需要同时出现。可以用一句话总结:
- 必须的:行动(Action)
- 几乎总是存在的:工具(Tool)
- 有条件存在的:计划(Planning)
- 最容易被省略的:记忆(Memory)
说明:以上是工程经验法则,不是严格定义。是否引入规划、记忆等能力,应结合任务复杂度、成本、延迟和可控性权衡。
二、何时需要智能体
智能体是大模型工程实现中复杂度较高的方案,涉及工具调用、记忆、规划、反思与多组件协作。
当任务需要多步决策、动态工具调用或环境交互,且提示词工程、RAG、微调等方式无法满足预期时,可以评估智能体开发。但应同时权衡成本、延迟、可控性与安全风险,不要把智能体作为默认方案。

2.1 开发方式选型总表
| 现象 | 首选手段 | 备选 | 说明 |
|---|---|---|---|
| 缺少工具、需要拆分任务、需要多步决策 | Agent | 工作流编排 | 注意成本、延迟、可控性 |
| 指令遵循效果不好 | 优化提示词、提供示例 | 微调 | 先尝试提示词和示例 |
| 缺少参考资料 | RAG | 多轮检索、重排序 | 关注检索质量与引用检查 |
| 模型缺少领域语言理解 | 继续预训练 | 再微调 | 注意数据覆盖和灾难性遗忘 |
| 规则约束强、格式要求高 | 程序化校验、约束解码、模板 | Agent 兜底重写 | Agent 不是首选 |
| 数据分布与线上不一致 | 收集数据重新微调 | 调整数据策略 | 先分析分布差异 |
这些方式不是互斥的,应按"简单优先、成本递增"的顺序选型。
2.2 提示词工程
如果提示词工程效果不好,首先应尝试优化提示词;如果优化提示词效果仍不好,再分析原因选择其他开发方式。提示词效果不好可能是因为:
- 缺少工具、需要拆分任务等,这类场景天然适合 Agent 开发。
- 指令遵循效果不好,先尝试提供示例;如果效果还不好,可以考虑微调。
- 缺少参考资料,尝试 RAG。
- 模型缺少对领域语言的系统理解,尝试继续预训练。

2.3 RAG
RAG 效果不好可能是因为:
- 检索质量不高、文档冲突或者模型未正确引用资料。此时可以结合 Agent 引入多轮检索、冲突比对以及强制引用检查等,提升结果的可控性和质量。
- 上述情况也可以尝试调整 RAG 的文档切分、重排序等策略以提升质量。
- 模型读不懂语料,即模型拿到了正确的参考资料,但推理不对,缺少领域知识,尝试继续预训练。
2.4 微调
微调效果不好可能是因为:
- 规则约束太强,例如强制要求模型输出特定格式,微调无法保证极高准确率。此时可以考虑通过 Agent 引入格式校验、多次重写等机制,提升生成质量;但格式校验应优先使用程序化校验、约束解码或模板。
- 数据分布和真实分布不一致,例如客服场景中的微调数据经过筛选,线上输入五花八门和训练集不同。可以考虑收集合适的数据重新微调。
- 如果发现模型读不懂语料,应尝试继续预训练,然后再微调。
2.5 继续预训练
只有在系统性缺失领域语言或数据分布时,才需要继续预训练(Continual Pre-Training,CPT)。如果继续预训练效果不好,可能是因为:
- 数据分布没有覆盖使用场景,或者发生了灾难性遗忘,即失去了继续预训练前的能力。此时应该在继续预训练数据集中混合通用语料,并收集数据重新训练。
- 继续预训练效果不好时,通常应该分析原因重新训练,Agent 很难从根本上解决问题。但仍然可以结合 Agent 开发,补充校验和多次重写等机制提升生成质量。这是无奈之举,质量提升有限,治标不治本。
三、工具调用的实现方式
3.1 Function Calling
3.1.1 定义
Function Calling(函数调用),也常称为 Tools Call(工具调用),为模型提供了一种强大而灵活的方式,使其能够与外部系统交互并访问训练数据之外的数据,拓展了模型的能力边界。
3.1.2 流程

以 DeepSeek 官方 API 为例演示 Function Calling。
步骤一:定义工具并向模型发送消息
使用 Linux 命令行工具 curl 测试:
bash
curl https://api.deepseek.com/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${API_KEY}" \
-d '{
"model": "deepseek-chat",
"messages": [
{
"role": "system",
"content": "你是个智能天气查询助手,根据用户的提问自主调用工具"
},
{
"role": "user",
"content": "北京市天气如何?"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "根据用户输入的城市信息,获取该城市的天气",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,只保留最细粒度的地区名称"
}
},
"required": ["city"]
}
}
}
]
}'
步骤二:模型返回调用信息
模型返回的调用信息如下:
json
{
"id": "7cccd00d-f0a5-4b2e-872c-a54bdb767796",
"object": "chat.completion",
"created": 1767176438,
"model": "deepseek-chat",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "我来帮您查询北京市的天气情况。",
"tool_calls": [
{
"index": 0,
"id": "call_00_Kpq3g6mPl9BYlZIe1NSNm3Cs",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\": \"北京\"}"
}
}
]
},
"logprobs": null,
"finish_reason": "tool_calls"
}
],
"usage": {
"prompt_tokens": 336,
"completion_tokens": 52,
"total_tokens": 388,
"prompt_tokens_details": {
"cached_tokens": 0
},
"prompt_cache_hit_tokens": 0,
"prompt_cache_miss_tokens": 336
},
"system_fingerprint": "fp_eaab8d114b_prod0820_fp8_kvcache"
}
说明:arguments 是 JSON 字符串,不是 JSON 对象;finish_reason 为 tool_calls 表示模型请求调用工具。
步骤三:根据调用信息执行函数
根据模型返回的调用信息(函数名称、参数)调用相应的函数,这一步应该在代码中完成,用 curl 无法模拟,省略。
假设调用后返回的信息如下:
json
{
"temp": "2℃",
"text": "晴",
"wind": "西北风3级"
}
步骤四:将调用结果和历史消息打包后发送给模型
完整命令如下:
bash
curl https://api.deepseek.com/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${API_KEY}" \
-d '{
"model": "deepseek-chat",
"messages": [
{
"role": "system",
"content": "你是个智能天气查询助手,根据用户的提问自主调用工具"
},
{
"role": "user",
"content": "北京市天气如何?"
},
{
"role": "assistant",
"content": "我来帮您查询北京市的天气情况。",
"tool_calls": [
{
"index": 0,
"id": "call_00_Kpq3g6mPl9BYlZIe1NSNm3Cs",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\": \"北京\"}"
}
}
]
},
{
"role": "tool",
"tool_call_id": "call_00_Kpq3g6mPl9BYlZIe1NSNm3Cs",
"content": "{\"temp\":\"2℃\",\"text\":\"晴\",\"wind\":\"西北风3级\"}"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "根据用户输入的城市信息,获取该城市的天气",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,只保留最细粒度的地区名称"
}
},
"required": ["city"]
}
}
}
]
}'
步骤五:模型根据函数调用结果整理信息并回答
模型响应如下:
json
{
"id": "4f5f2133-6519-497e-aecc-2bd25a37c747",
"object": "chat.completion",
"created": 1767177264,
"model": "deepseek-chat",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "根据查询结果,北京市当前的天气情况如下:\n\n- 温度:2℃\n- 天气状况:晴\n- 风力:西北风3级\n\n今天北京天气晴朗,温度在2℃左右,风力不大,是个不错的天气。建议您外出时适当保暖,虽然天气晴朗但温度还是偏低的。"
},
"logprobs": null,
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 422,
"completion_tokens": 70,
"total_tokens": 492,
"prompt_tokens_details": {
"cached_tokens": 384
},
"prompt_cache_hit_tokens": 384,
"prompt_cache_miss_tokens": 38
},
"system_fingerprint": "fp_eaab8d114b_prod0820_fp8_kvcache"
}
3.1.3 Function Calling 的不足
-
工具实现与复用成本高,协作困难
开发者需要自己实现工具,并编写可被调用的描述信息。工具通常与业务、环境绑定,复用难、共享难、生态扩展慢。
-
规范碎片化,跨模型适配负担重
不同厂商定义的 Function Calling 规范不同,开发者可能需要为同一个工具编写多份描述信息,维护成本和一致性风险较高。
-
可靠性不足
工具可能没有经过足够调试。如果描述信息不完善,模型可能在某些场景下不能正确调用工具,工具可靠性不足。
3.2 最小 Python 示例
以下示例使用 OpenAI Python SDK 调用兼容接口,演示完整的工具调用闭环。运行前请安装 openai,并设置环境变量 DEEPSEEK_API_KEY。
python
import json
import os
from openai import OpenAI
client = OpenAI(
api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url="https://api.deepseek.com",
)
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "根据用户输入的城市信息,获取该城市的天气",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,只保留最细粒度的地区名称",
}
},
"required": ["city"],
},
},
}
]
def get_weather(city: str) -> dict:
# 这里替换为真实天气 API 调用
return {
"temp": "2℃",
"text": "晴",
"wind": "西北风3级",
}
messages = [
{
"role": "system",
"content": "你是个智能天气查询助手,根据用户的提问自主调用工具",
},
{
"role": "user",
"content": "北京市天气如何?",
},
]
response = client.chat.completions.create(
model="deepseek-chat",
messages=messages,
tools=tools,
)
message = response.choices[0].message
messages.append(message.model_dump(exclude_none=True))
if message.tool_calls:
for tool_call in message.tool_calls:
if tool_call.function.name == "get_weather":
args = json.loads(tool_call.function.arguments)
result = get_weather(args["city"])
messages.append(
{
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(result, ensure_ascii=False),
}
)
final_response = client.chat.completions.create(
model="deepseek-chat",
messages=messages,
tools=tools,
)
print(final_response.choices[0].message.content)
else:
print(message.content)
四、MCP
4.1 定义
MCP(Model Context Protocol,模型上下文协议)是一套标准化的通讯协议,旨在规范 AI 模型和外部工具、数据源的连接方式,由 Anthropic(Claude 母公司)于 2024 年 11 月提出。
MCP 可以类比为 AI 时代的 USB-C 通用接口:开发者只需按标准开发一次 MCP Server,任何支持该协议的 AI 应用都能即插即用。

通过 MCP 协议,AI 应用和 MCP Server 可以建立多对多的双向数据流。
4.2 角色与流程
MCP 可以理解为对 Function Calling 的进一步封装和拓展。需要准确区分角色:
- Host:AI 应用本身,例如 IDE、聊天客户端或 Agent 应用。
- Client:Host 内部负责与 MCP Server 建立连接、发送请求的协议客户端。
- Server:按 MCP 协议暴露工具、资源、提示词的服务端。
- 模型:根据上下文决定是否调用工具、调用哪个工具以及传什么参数。
- Server:负责执行工具并返回结果。
MCP 并不是"由 MCP Server 决定是否调用工具"。模型仍然负责决策,Host/Client 负责按协议发起调用,Server 负责执行。

典型流程如下:
- Host(AI 应用)启动并连接 MCP Server。
- MCP Client 与 Server 初始化并协商能力。
- Server 暴露 Tools(工具)、Resources(资源)、Prompts(提示词)等能力。
- 模型根据上下文决定是否调用工具。
- Host/Client 向 MCP Server 发送工具调用请求。
- MCP Server 执行工具并返回结果。
- Host 将结果交给模型,生成最终回答。
4.3 MCP 的三大模块
-
Tools(工具)
最常用的模块。MCP Server 暴露可调用工具,供 AI 应用发现和调用。
-
Resources(资源)
MCP Server 提供的被动数据源,例如文件、数据库等,可以被 AI 应用主动获取,作为模型上下文传递。
-
Prompts(提示词)
MCP Server 提供的预置提示词模板,由 AI 应用主动获取后发给大模型。AI 应用也可以和用户交互,补全模板中的关键信息。
实际开发中最常用的是 Tools 模块。
4.4 MCP 相较于 Function Calling 的优势
-
降低协作与复用成本
MCP 协议允许开发者把工具暴露为 MCP Server,可以被多个 AI 应用复用,减少重复开发和共享困难。
-
降低跨模型适配负担
Function Calling 规范存在厂商差异,而 MCP 通过标准化协议降低同一工具在多个 AI 应用之间适配的成本。
-
支持工具发现与生态扩展
MCP 支持按协议发现 Server 提供的能力,有利于形成工具生态。
-
除工具外还支持资源和提示词
MCP 不仅覆盖工具调用,还覆盖 Resources 和 Prompts,能力边界比单一 Function Calling 更宽。
4.5 Function Calling 与 MCP 对比
| 维度 | Function Calling | MCP |
|---|---|---|
| 工具定义位置 | 通常在 AI 应用内定义 | 由独立 MCP Server 暴露 |
| 复用性 | 较低,易与业务绑定 | 较高,可被多个 AI 应用复用 |
| 跨模型适配 | 需按厂商规范分别适配 | 协议标准化,适配负担较低 |
| 工具发现 | 多为静态配置 | 支持协议化能力发现 |
| 资源与提示词 | 通常不覆盖 | 支持 Resources、Prompts |
| 运维复杂度 | 相对简单 | 需要维护 Server、连接和权限 |
| 适用场景 | 单应用快速集成 | 多应用、多工具、生态化集成 |
4.6 MCP 使用注意事项
MCP 并不自动保证工具可靠性和安全性。实际使用中仍需关注:
- 工具参数校验和返回结果校验;
- 最小权限原则;
- 认证、授权与租户隔离;
- 沙箱执行、超时、重试和幂等;
- 审计日志与调用链追踪;
- 提示注入、越权访问和数据泄露风险;
- MCP Server 的版本管理和可用性运维。
五、安全、评估与可观测性
5.1 安全
- 工具调用前进行参数校验,不信任模型生成的参数。
- 遵循最小权限原则,避免工具拥有过大权限。
- 高风险工具放入沙箱执行,并设置超时、重试和幂等机制。
- 记录工具调用审计日志,包含调用方、参数摘要、结果摘要和耗时。
- 防范提示注入,不把不可信内容直接当作高优先级指令。
- API Key 使用环境变量或密钥管理服务,不要写入代码仓库。
5.2 评估指标
建议至少关注:
- 任务成功率;
- 工具调用准确率;
- 参数正确率;
- 平均调用轮次;
- 单次任务成本;
- 端到端延迟;
- 人工接管率;
- 失败原因分布。
5.3 可观测性
建议记录:
- 模型输入输出摘要;
- 工具调用名称、参数和结果;
- 每轮耗时和 token 消耗;
- 错误码和重试次数;
- 用户反馈与人工修正记录。
六、常见问题
Q1:什么时候应该用智能体?
当任务需要多步决策、动态工具调用或环境交互,且提示词工程、RAG、微调等方式无法满足预期时,再评估智能体。不要默认使用智能体。
Q2:Function Calling 和 MCP 是什么关系?
Function Calling 是模型调用工具的能力机制;MCP 是规范 AI 应用与外部工具、数据源连接方式的标准化协议。MCP 可以理解为对工具调用能力的进一步封装和生态化拓展,而不是简单替代。
Q3:工具调用结果一定要回传给模型吗?
通常需要。模型需要根据工具结果组织最终回答。也可以由业务代码直接消费工具结果,但是否回传取决于产品流程。
Q4:格式要求很高时应该用 Agent 吗?
优先使用程序化校验、约束解码、模板等确定性手段。Agent 可以作为兜底重写机制,但不是首选。