02. 智能体系统(Agent Systems)¶
⚠️ 时效性说明:本章涉及前沿模型/价格/榜单等信息,可能随版本快速变化;请以论文原文、官方发布页和 API 文档为准。
学习目标:深入理解智能体的架构、能力和应用,掌握工具使用、规划推理和多智能体协作的核心技术。
📌 定位说明:本章侧重智能体系统的研究前沿与理论分析。 - 动手实践(手写 Agent 框架、MCP 开发、项目实战)→ AI Agent 开发实战/ - 框架应用(LangChain/LangGraph Agent 开发)→ LLM 应用/07-Agent 开发基础
目录¶
1. 什么是智能体¶
1.1 智能体的定义¶
智能体(Agent) 是一个能够感知环境、进行决策并执行动作的自主系统。
传统大模型:
输入 → [大模型] → 输出(文本)
↑
静态知识(训练数据截止时间)
智能体系统:
环境感知 → [智能体] → 决策 → 执行动作 → 影响环境
↑
可以:
- 使用工具(Tool Use)
- 访问外部知识(RAG / 搜索)
- 进行多步规划(Planning)
- 与其他智能体协作(Multi-Agent)
- 从反馈中学习(Reflection)
1.2 智能体的核心能力¶
| 能力 | 描述 | 示例 |
|---|---|---|
| 工具使用 | 调用外部 API 和函数 | 查天气、执行代码、搜索 |
| 规划推理 | 分解任务,制定计划 | 多步骤问题解决 |
| 记忆管理 | 短期和长期记忆 | 上下文保持、知识积累 |
| 自主决策 | 根据环境反馈调整 | 错误恢复、策略优化 |
| 多智能体协作 | 与其他智能体配合 | 分工合作、协商沟通 |
1.3 为什么需要智能体¶
大模型的局限:
1. 知识静态 — 无法获取实时信息
2. 无法行动 — 不能直接操作外部系统
3. 计算有限 — 复杂数学计算容易出错
4. 没有记忆 — 无法保持长期上下文
5. 单轮交互 — 难以完成多步骤复杂任务
智能体的解决方案:
1. 工具使用 → 获取实时信息(搜索、API)
2. 环境交互 → 执行实际操作(文件、数据库)
3. 代码执行 → 精确计算和验证(CodeAgent)
4. 记忆系统 → 持久化存储和检索(向量数据库)
5. 多步规划 → 复杂任务分解与执行(ReAct / Plan-and-Execute)
2. 智能体架构¶
2.1 基础架构:ReAct¶
ReAct(Reasoning + Acting) 是智能体的经典架构,由 Yao et al. (2023) 提出。
循环流程:
观察(Observation)
↓
思考(Thought)
↓
行动(Action)
↓
执行 → 环境反馈 → 回到观察
示例流程:
用户:"北京今天天气怎么样?适合穿什么?"
Thought 1: 用户询问北京今天的天气和穿衣建议。
我需要先获取北京的天气信息。
Action 1: get_weather(location="北京", date="今天")
Observation 1: {"temperature": "15°C", "weather": "晴", "wind": "微风"}
Thought 2: 天气是晴天,15°C,微风。
这是一个温暖的春日天气。
建议穿轻薄外套或长袖。
Action 2: finish(answer="北京今天晴天,15°C,微风。建议穿轻薄外套或长袖衬衫。")
2.2 架构组件详解¶
组件 1:感知模块(Perception)¶
import json
class PerceptionModule:
"""感知模块:处理环境输入"""
def process(self, raw_input):
"""
处理原始输入
- 用户消息(文本)
- 工具返回结果(结构化数据)
- 系统状态(事件通知)
"""
if isinstance(raw_input, dict):
# 结构化数据(工具返回)→ 格式化为文本
return self._format_observation(raw_input)
else:
# 文本输入 → 直接传递
return raw_input
def _format_observation(self, data):
"""将结构化数据格式化为可读文本"""
return json.dumps(data, ensure_ascii=False, indent=2)
组件 2:推理引擎(Reasoning Engine)¶
import re
class ReasoningEngine:
"""推理引擎:基于 LLM 进行思考和决策"""
def __init__(self, llm):
self.llm = llm
self.system_prompt = """你是一个智能助手。你可以使用以下工具:
可用工具:
{tools_description}
请按以下格式思考:
Thought: 你的思考过程
Action: 工具名称
Action Input: 工具参数(JSON格式)
或者完成任务:
Thought: 任务完成
Final Answer: 最终答案
"""
def think(self, context, tools_description=""):
"""基于上下文进行推理"""
prompt = self.system_prompt.format(tools_description=tools_description)
response = self.llm.generate(
system_prompt=prompt,
context=context
)
return self._parse_response(response)
def _parse_response(self, response):
"""解析 LLM 输出,提取 Thought 和 Action"""
result = {"thought": "", "action": None, "action_input": {}, "final_answer": None}
# 提取 Thought
thought_match = re.search(r'Thought:\s*(.+?)(?=\n(?:Action|Final)|$)', response, re.DOTALL)
if thought_match:
result["thought"] = thought_match.group(1).strip()
# 提取 Action
action_match = re.search(r'Action:\s*(\w+)', response)
if action_match:
result["action"] = action_match.group(1)
# 提取 Action Input
input_match = re.search(r'Action Input:\s*(\{.+?\})', response, re.DOTALL)
if input_match:
result["action_input"] = json.loads(input_match.group(1))
# 提取 Final Answer
answer_match = re.search(r'Final Answer:\s*(.+?)$', response, re.DOTALL)
if answer_match:
result["final_answer"] = answer_match.group(1).strip()
return result
组件 3:工具执行器(Tool Executor)¶
class ToolExecutor:
"""工具执行器:管理和执行工具"""
def __init__(self):
self.tools = {}
def register_tool(self, name, func, description, parameters):
"""注册工具"""
self.tools[name] = {
'function': func,
'description': description,
'parameters': parameters
}
def execute(self, tool_name, params):
"""执行工具"""
if tool_name not in self.tools:
return f"Error: Tool '{tool_name}' not found"
try:
result = self.tools[tool_name]['function'](**params)
return result
except TypeError as e:
return f"Error: 参数错误 - {str(e)}"
except Exception as e:
return f"Error: 执行失败 - {str(e)}"
def get_tools_description(self):
"""获取所有工具的描述(用于构建 prompt)"""
descriptions = []
for name, tool in self.tools.items():
descriptions.append(f"- {name}: {tool['description']}")
return "\n".join(descriptions)
组件 4:记忆系统(Memory)¶
class MemorySystem:
"""记忆系统:管理短期和长期记忆"""
def __init__(self, max_short_term=10):
# 短期记忆(当前会话的最近 N 条)
self.short_term = []
self.max_short_term = max_short_term
# 长期记忆(向量数据库,实际使用 ChromaDB / FAISS 等)
# self.long_term = VectorDB()
def add_short_term(self, item):
"""添加到短期记忆"""
self.short_term.append(item)
# FIFO:保持最近 N 条
if len(self.short_term) > self.max_short_term:
self.short_term.pop(0)
def get_context(self):
"""获取当前上下文(用于构建 prompt)"""
return "\n".join(self.short_term)
def clear_short_term(self):
"""清空短期记忆(新会话开始时)"""
self.short_term = []
2.3 高级架构模式¶
模式 1:计划-执行(Plan-and-Execute)¶
第一阶段:规划
任务 → [规划器] → 步骤列表
第二阶段:执行
对每个步骤:
步骤 → [执行器] → 结果
第三阶段:验证
结果 → [验证器] → 是否完成/重试
示例:
任务:"帮我订一张明天北京到上海的高铁票"
Plan:
1. 查询明天北京到上海的高铁班次
2. 获取用户偏好的时间和座位类型
3. 选择合适的车次
4. 填写乘客信息
5. 确认订单并支付
Execute:
Step 1 → 查询 API → 返回 10 个班次
Step 2 → 询问用户 → 用户选择 G1,二等座
Step 3 → 选择 G1 → 确认有票
Step 4 → 填写信息 → 成功
Step 5 → 支付 → 完成
模式 2:多智能体协作¶
协调者(Orchestrator)
↓ 分配任务
┌────┴────┬────────┬────────┐
↓ ↓ ↓ ↓
研究Agent 代码Agent 测试Agent 文档Agent
↓ ↓ ↓ ↓
└────────┴────────┴────────┘
↓
协调者整合
↓
最终结果
示例:软件开发(MetaGPT 模式)
- 产品经理 Agent:分析需求 → PRD 文档
- 架构师 Agent:设计系统 → 技术方案
- 工程师 Agent:编写代码 → 源代码
- 测试工程师 Agent:编写测试 → 测试报告
3. 工具使用(Tool Use)¶
3.1 工具的定义和分类¶
# 工具的标准定义(OpenAI Function Calling 格式)
tool_definition = {
"name": "get_weather",
"description": "获取指定城市的天气信息",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市名称,如'北京'"
},
"date": {
"type": "string",
"description": "日期,如'今天'、'明天'或'2026-03-25'"
}
},
"required": ["location"]
}
}
工具分类¶
| 类别 | 功能 | 示例 |
|---|---|---|
| 信息检索 | 获取实时信息 | 搜索引擎、天气 API、新闻 |
| 计算工具 | 精确计算 | 计算器、代码执行器 |
| 外部 API | 调用服务 | 订票、购物、支付 |
| 文件操作 | 读写文件 | 读取文档、保存结果 |
| 数据库 | 数据查询 | SQL 查询、知识库检索 |
| 代码执行 | 运行代码 | Python 沙箱、终端 |
3.2 Function Calling 完整示例¶
"""
OpenAI Function Calling 完整流程
展示了从工具定义到执行再到结果返回的完整循环
"""
import json
from openai import OpenAI
client = OpenAI()
# Step 1: 定义工具
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的天气信息",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "城市名称"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["location"]
}
}
}
]
# Step 2: 发送请求(模型决定是否调用工具)
response = client.chat.completions.create(
model="gpt-5-mini",
messages=[
{"role": "user", "content": "北京今天天气怎么样?"}
],
tools=tools,
tool_choice="auto" # auto: 模型自动决定;none: 不调用;required: 必须调用
)
message = response.choices[0].message
# Step 3: 处理工具调用
if message.tool_calls:
tool_call = message.tool_calls[0]
function_name = tool_call.function.name
arguments = json.loads(tool_call.function.arguments)
# 执行实际函数
def get_weather(location, unit="celsius"):
# 实际应用中调用天气 API
return json.dumps({
"location": location,
"temperature": "15°C" if unit == "celsius" else "59°F",
"weather": "晴",
"wind": "微风"
}, ensure_ascii=False)
result = get_weather(**arguments)
# Step 4: 将工具结果返回给模型
second_response = client.chat.completions.create(
model="gpt-5-mini",
messages=[
{"role": "user", "content": "北京今天天气怎么样?"},
message, # 模型的工具调用消息
{"role": "tool", "tool_call_id": tool_call.id, "content": result}
]
)
print(second_response.choices[0].message.content)
else:
# 模型直接回答(无需工具)
print(message.content)
3.3 工具学习(Tool Learning)¶
阶段 1:工具理解¶
目标:让模型理解工具的用途和参数
方法:
1. 工具描述微调
- 输入:工具定义(JSON Schema)
- 输出:工具用途说明
2. 使用示例学习(Few-shot)
- 输入:任务描述
- 输出:正确的工具调用
示例训练数据:
{
"instruction": "查询北京的天气",
"thought": "用户想查询天气,我应该使用 get_weather 工具",
"action": "get_weather",
"action_input": {"location": "北京", "date": "今天"}
}
阶段 2:工具选择¶
挑战:面对大量工具,如何选择正确的?
解决方案:
1. 工具检索(Tool Retrieval)
- 将工具描述编码为向量
- 根据任务语义检索相关工具
2. 工具排序(Tool Ranking)
- 训练模型评估工具相关性
- 选择 Top-K 个候选工具
3. 工具组合(Tool Composition)
- 复杂任务需要多个工具
- 学习工具之间的依赖关系
阶段 3:工具创造¶
高级能力:根据需求创建新工具
示例:
用户:"我需要计算一个列表的标准差"
模型发现没有直接工具,于是:
1. 分析需求 → 需要标准差计算
2. 生成代码 → 创建临时工具
3. 执行计算 → 获得结果
4. 返回答案 → 包含计算过程
这要求模型具备:
- 代码生成能力
- 理解任务需求
- 验证工具正确性
4. 规划与推理¶
4.1 任务分解(Task Decomposition)¶
方法 1:链式思考(Chain-of-Thought, CoT)¶
问题:"一个农场有鸡和兔,头共 35 个,脚共 94 只。鸡和兔各有多少只?"
CoT 推理:
让我一步步解决这个问题。
设鸡有 x 只,兔有 y 只。
根据题意:
1. x + y = 35 (头的总数)
2. 2x + 4y = 94 (脚的总数)
从方程 1:x = 35 - y
代入方程 2:
2(35 - y) + 4y = 94
70 - 2y + 4y = 94
2y = 24
y = 12
所以兔有 12 只,鸡有 35 - 12 = 23 只。
验证:
头:23 + 12 = 35 ✓
脚:23×2 + 12×4 = 46 + 48 = 94 ✓
方法 2:思维树(Tree of Thoughts, ToT)¶
问题:"24 点游戏,数字是 4, 5, 6, 10"
ToT 推理(探索多个分支,评估后选择最优路径):
Level 1 - 可能的第一次操作:
├── 4 + 5 = 9
├── 4 × 5 = 20
├── 6 + 10 = 16
├── 6 × 10 = 60
├── 10 - 6 = 4
└── ...
Level 2 - 评估每个分支:
├── 4 + 5 = 9 → 剩余 [6, 9, 10] → 评估:可能
├── 4 × 5 = 20 → 剩余 [6, 10, 20] → 评估:可能
├── 6 × 10 = 60 → 剩余 [4, 5, 60] → 评估:不太可能
└── ...
Level 3 - 深入探索有潜力的分支:
分支:4 × 5 = 20,剩余 [6, 10, 20]
├── 20 + 6 = 26 → 剩余 [10, 26] → 无法得到 24
├── 20 - 6 = 14 → 剩余 [10, 14] → 无法得到 24
├── 20 + 10 = 30 → 剩余 [6, 30] → 无法得到 24
└── 10 - 6 = 4 → 剩余 [4, 20] → 20 + 4 = 24 ✓
找到解:(10 - 6) + 4 × 5 = 24
4.2 反思与自我修正(Reflection)¶
class ReflectiveAgent:
"""具备反思能力的智能体"""
def __init__(self, llm):
self.llm = llm
def execute_with_reflection(self, task, max_retries=3):
"""执行任务,支持反思和重试"""
for attempt in range(max_retries):
# 执行任务
result = self.execute(task)
# 反思执行结果
reflection = self.reflect(task, result)
if reflection["is_success"]:
return result
if reflection["should_retry"]:
# 根据反馈调整策略
task = self.adjust_strategy(task, reflection["feedback"])
print(f"重试 {attempt + 1}/{max_retries},调整:{reflection['feedback']}")
else:
break
return result
def reflect(self, task, result):
"""反思执行结果"""
reflection_prompt = f"""
任务:{task}
执行结果:{result}
请反思:
1. 结果是否正确?
2. 过程中是否有错误?
3. 如何改进?
4. 是否需要重试?
请以 JSON 格式输出:
{{"is_success": bool, "should_retry": bool, "feedback": "改进建议"}}
"""
reflection_text = self.llm.generate(reflection_prompt)
return self.parse_reflection(reflection_text)
4.3 结构化输出规划(Structured Output Planning)¶
来源:本节参考自 DeepLearning.AI《Patterns for Highly Autonomous Agents》课程的规划模式。
传统 Agent 使用自由文本进行规划,难以程序化地验证和执行。结构化输出规划要求 LLM 以 JSON Schema 等结构化格式输出计划,使规划结果可直接被代码解析和执行。
from pydantic import BaseModel
from typing import Optional
from enum import Enum
class StepStatus(str, Enum):
PENDING = "pending"
RUNNING = "running"
COMPLETED = "completed"
FAILED = "failed"
class PlanStep(BaseModel):
"""结构化计划中的单个步骤"""
step_id: int
action: str # 要执行的动作描述
tool: Optional[str] # 使用的工具名称
parameters: dict # 工具参数
depends_on: list[int] # 依赖的前置步骤 ID
expected_output: str # 预期输出描述
class StructuredPlan(BaseModel):
"""结构化执行计划"""
goal: str
steps: list[PlanStep]
estimated_steps: int
fallback_strategy: str # 如果计划失败的回退策略
# 使用 LLM 生成结构化计划
STRUCTURED_PLANNING_PROMPT = """
你是一个任务规划专家。请将用户的目标分解为可执行的结构化计划。
用户目标:{goal}
可用工具:
{available_tools}
请严格按照以下 JSON Schema 输出计划:
{schema}
要求:
1. 每个步骤必须指定明确的工具和参数
2. 使用 depends_on 字段表示步骤间的依赖关系
3. 提供回退策略以应对可能的失败
"""
async def generate_structured_plan(
goal: str,
tools: list[dict],
llm_client
) -> StructuredPlan:
"""使用 LLM 生成结构化执行计划"""
schema = StructuredPlan.model_json_schema()
prompt = STRUCTURED_PLANNING_PROMPT.format(
goal=goal,
available_tools="\n".join(f"- {t['name']}: {t['description']}" for t in tools),
schema=schema
)
response = await llm_client.chat.completions.create(
model="gpt-5-mini",
messages=[{"role": "user", "content": prompt}],
response_format={"type": "json_object"} # 强制 JSON 输出
)
plan = StructuredPlan.model_validate_json(response.choices[0].message.content)
return plan
结构化规划的优势:
| 特性 | 自由文本规划 | 结构化输出规划 |
|---|---|---|
| 可解析性 | ❌ 需要正则/启发式 | ✅ 直接 JSON 解析 |
| 依赖关系 | ❌ 隐式,难以推断 | ✅ 显式声明 |
| 并行执行 | ❌ 难以判断 | ✅ 根据 depends_on 拓扑排序 |
| 错误恢复 | ❌ 无回退策略 | ✅ 内置 fallback |
| 可验证性 | ❌ 格式不确定 | ✅ Schema 校验 |
4.4 代码执行即动作(CodeAgent)¶
来源:本节参考自 HuggingFace smolagents 的 CodeAgent 模式。
传统 Agent 通过调用预定义工具来执行动作,能力受限于工具集的覆盖范围。代码执行模式(CodeAgent)让 Agent 直接生成并执行代码来完成任务,极大扩展了 Agent 的能力边界。
┌─────────────────────────────────────────────────────────┐
│ 传统 Tool-Calling Agent vs CodeAgent │
├─────────────────────────┬───────────────────────────────┤
│ Tool-Calling Agent │ CodeAgent │
│ │ │
│ 用户查询 │ 用户查询 │
│ ↓ │ ↓ │
│ 选择工具 ──→ 调用API │ 生成代码 ──→ 沙箱执行 │
│ ↓ │ ↓ │
│ 格式化结果 │ 获取执行结果 │
│ │ │
│ 限制:只能做工具预设的事 │ 优势:可以做任何代码能做的事 │
└─────────────────────────┴───────────────────────────────┘
import subprocess
from pathlib import Path
class CodeAgent:
"""
代码执行 Agent:生成 Python 代码并在沙箱中执行。
参考 HuggingFace smolagents 的 CodeAgent 设计。
"""
def __init__(self, llm_client, allowed_modules=None):
self.llm_client = llm_client
# 白名单机制:只允许导入安全的模块
self.allowed_modules = allowed_modules or [
"math", "json", "re", "datetime", "collections",
"statistics", "itertools", "string", "random"
]
async def run(self, question: str) -> dict:
"""生成代码并执行"""
# Step 1: 生成代码
prompt = f"""你是一个代码执行 Agent。请编写 Python 代码来解决用户的问题。
规则:
1. 只能使用以下模块:{', '.join(self.allowed_modules)}
2. 将最终结果赋值给变量 `result`
3. 不要使用文件操作、网络请求或系统调用
4. 代码必须能在受限环境中安全执行
用户问题:{question}
请直接输出可执行的 Python 代码,不要包含 markdown 标记。"""
response = await self.llm_client.chat.completions.create(
model="gpt-5-mini",
messages=[{"role": "user", "content": prompt}],
temperature=0 # 确定性输出
)
code = response.choices[0].message.content.strip()
# Step 2: 安全检查
if not self._safety_check(code):
return {"success": False, "error": "代码未通过安全检查"}
# Step 3: 沙箱执行
result = self._execute_in_sandbox(code)
return result
def _safety_check(self, code: str) -> bool:
"""基础安全检查"""
dangerous_patterns = [
"import os", "import sys", "import subprocess",
"open(", "exec(", "eval(", "__import__",
"rm -rf", "shutil.rmtree"
]
return not any(pattern in code for pattern in dangerous_patterns)
def _execute_in_sandbox(self, code: str, timeout: int = 30) -> dict:
"""在受限环境中执行代码"""
try:
result = subprocess.run(
["python", "-c", code],
capture_output=True,
text=True,
timeout=timeout
)
if result.returncode == 0:
return {"success": True, "output": result.stdout.strip(), "code": code}
else:
return {"success": False, "error": result.stderr.strip(), "code": code}
except subprocess.TimeoutExpired:
return {"success": False, "error": f"执行超时({timeout}s)"}
except Exception as e:
return {"success": False, "error": str(e)}
⚠️ 安全警告:代码执行模式在生产环境中必须使用严格的沙箱隔离(如 Docker 容器、gVisor、Firecracker 微虚拟机),切勿直接在宿主机上执行 LLM 生成的代码。
5. 多智能体系统¶
5.1 多智能体架构¶
架构 1:层级式(Hierarchical)¶
[管理者 Agent]
|
┌────────────┼────────────┐
↓ ↓ ↓
[子Agent 1] [子Agent 2] [子Agent 3]
| | |
[工具1,2] [工具3,4] [工具5,6]
特点:
✅ 管理者统一分配任务,职责清晰
✅ 子 Agent 专注特定领域
✅ 适合复杂任务的层次化分解
❌ 管理者成为单点瓶颈
架构 2:对等式(Peer-to-Peer)¶
[Agent A] ←→ [Agent B]
↑ ↘ ↑
└────→ [Agent C] ←→ [Agent D]
特点:
✅ 智能体平等协作,无单点故障
✅ 通过协商达成共识
✅ 适合分布式问题求解
❌ 协商成本高,可能陷入死循环
架构 3:市场式(Market-based)¶
任务发布 → [拍卖机制] → Agent 竞标
↓
[Agent A] 中标
↓
执行任务
↓
返回结果
特点:
✅ 基于竞价分配任务,资源优化配置
✅ 适合动态环境和异构 Agent
❌ 拍卖机制设计复杂
5.2 智能体间通信¶
import time
class Message:
"""智能体间消息"""
def __init__(self, sender, receiver, msg_type, content):
self.sender = sender
self.receiver = receiver
self.type = msg_type # REQUEST, INFORM, PROPOSE, ACCEPT, REJECT
self.content = content
self.timestamp = time.time()
class CommunicationBus:
"""通信总线:管理智能体间的消息传递"""
def __init__(self):
self.message_queue = []
def send(self, message: Message):
"""发送消息"""
self.message_queue.append(message)
def receive(self, agent_name: str) -> list[Message]:
"""接收指定 Agent 的消息"""
messages = [
m for m in self.message_queue
if m.receiver == agent_name
]
# 从队列中移除已接收的消息
for m in messages:
self.message_queue.remove(m)
return messages
5.3 实际应用案例¶
案例 1:AutoGPT¶
AutoGPT 架构(自主任务执行):
[目标设定]
↓
[任务生成 Agent] → 分解为子任务
↓
[执行 Agent] → 使用工具执行
↓
[评估 Agent] → 检查结果
↓
┌─┴─┐
↓ ↓
成功 失败 → [反思] → 重试
↓
[记忆存储]
案例 2:MetaGPT(软件开发)¶
角色定义(模拟真实软件团队):
- 产品经理:写 PRD
- 架构师:设计技术方案
- 项目经理:分配任务
- 工程师:写代码
- 测试工程师:写测试用例
工作流程:
1. 产品经理分析需求 → PRD 文档
2. 架构师设计系统 → 技术设计文档
3. 项目经理分解任务 → 任务列表
4. 工程师并行开发 → 代码
5. 测试工程师验证 → 测试报告
6. 迭代优化
案例 3:CrewAI(角色协作)¶
CrewAI 特点:
- 每个 Agent 有明确的 Role、Goal、Backstory
- 支持 Sequential(顺序)和 Hierarchical(层级)流程
- 内置工具集成(搜索、文件、代码等)
- 支持人类反馈注入
典型配置:
Agent("研究员", goal="收集最新AI论文信息", backstory="...")
Agent("分析师", goal="分析论文贡献", backstory="...")
Agent("作者", goal="撰写综述报告", backstory="...")
Task("调研最新注意力机制论文", agent=研究员)
Task("分析各方法优劣", agent=分析师)
Task("撰写综述报告", agent=作者)
6. 智能体应用¶
6.1 个人助手¶
能力:日程管理、邮件处理、信息检索、任务提醒、旅行规划
示例对话:
用户:"帮我安排下周去上海的出差"
Agent:
1. 查询用户日历,找出空闲时间
2. 搜索北京到上海的航班/高铁
3. 推荐合适的酒店
4. 预订机票和酒店(经用户确认)
5. 添加到日历
6. 发送确认邮件
6.2 代码助手¶
能力:代码生成、Bug 修复、代码审查、文档生成、测试用例生成
2025-2026 代表产品:
- Claude Code / Claude Cowork:长任务规划与 agentic coding
- GitHub Copilot Coding Agent:面向开发工作流集成
- Cursor / Windsurf:AI 原生 IDE
- Devin(Cognition):自主软件工程师
6.3 研究助手¶
能力:文献检索、信息整合、数据分析、报告生成
Agent 执行流程:
1. 搜索相关论文(Google Scholar / Semantic Scholar)
2. 提取关键信息(方法、结果、贡献)
3. 按时间线/主题整理
4. 生成综述报告
5. 提供参考文献列表
6.4 客户服务¶
能力:问题理解、知识库检索、多轮对话、工单创建、情绪识别
Agent 执行流程:
1. 理解用户问题(意图识别)
2. 查询知识库 / 订单系统
3. 提供解决方案
4. 执行用户选择的方案
5. 跟进直到问题解决
7. 挑战与未来方向¶
7.1 当前挑战¶
| 挑战 | 描述 | 可能的解决方案 |
|---|---|---|
| 可靠性 | 智能体可能犯错,且难以预测 | 增加验证层、人在回路(HITL) |
| 安全性 | 工具使用可能带来风险 | 权限控制、沙箱环境、审计日志 |
| 效率 | 多步推理成本高 | 模型优化、缓存机制、并行执行 |
| 可解释性 | 决策过程不透明 | 思维链可视化、日志记录 |
| 泛化性 | 对新工具/环境适应慢 | 元学习、快速适应 |
| 成本控制 | 多步调用累积费用高 | Token 预算、智能路由 |
7.2 未来方向¶
方向 1:具身智能(Embodied AI)¶
方向 2:MCP 生态与标准化工具调用¶
MCP(Model Context Protocol)是 2024 年末发布的重要开放标准:
核心价值:
├── 统一接口:以一致方式暴露工具、资源与提示
├── 动态发现:客户端可在运行时发现可用能力
├── 传输灵活:stdio / HTTP / SSE 等多种传输方式
└── 安全边界:隔离执行、权限控制
典型应用:
├── Claude Desktop / Claude Code:MCP 客户端
├── Cursor / VS Code 等 IDE:MCP 集成
└── 业务系统:数据库、文件系统、搜索封装为 MCP Server
详见:[09-MCP协议与工具生态](./09-MCP协议与工具生态.md)
方向 3:原生计算机使用(Computer Use)¶
主流闭源 Agent 正在把 computer use / desktop automation 纳入统一工作流:
核心特性:
├── 直接操作计算机文件系统与桌面 UI
├── 自动化浏览器操作与网页交互
├── 执行代码并获取实时结果
└── 在受控环境中完成端到端任务闭环
代表产品:
├── Anthropic Computer Use:Claude 的桌面操作能力
├── OpenAI Operator:网页任务自动化
└── 开源方案:Browser Use、Skyvern 等
方向 4:Agentic Coding(AI 原生编程)¶
2025-2026 年编程模型的重大演进:
核心能力:
├── 理解项目结构与依赖关系
├── 自主代码生成与修改
├── 测试驱动开发(Test-Driven)
├── 代码审查与优化建议
└── 跨文件重构与依赖管理
代表模型:
├── GPT-5.4:强通用编码与多步骤软件任务
├── Claude Opus 4.6:长任务规划、审查与 agentic coding
├── GitHub Copilot coding agent:面向开发工作流集成
└── Qwen / DeepSeek 开源 coder 系列
开发范式转变:
├── 从 "Copilot"(辅助)到 "Autopilot"(自主)
├── 人类定义目标,AI 完成实现
└── 持续集成中的自主调试修复
8. 动手实践¶
实践 1:构建完整的 ReAct 智能体¶
"""
完整的 ReAct 智能体实现
包含工具注册、推理循环和记忆管理
"""
import json
import re
class SimpleReActAgent:
"""简单的 ReAct 智能体实现"""
def __init__(self, llm, tools=None):
self.llm = llm
self.tools = tools or {}
self.memory = []
def register_tool(self, name, func, description):
"""注册工具"""
self.tools[name] = {"function": func, "description": description}
def run(self, query, max_steps=10):
"""运行智能体"""
self.memory = [f"User: {query}"]
for step in range(max_steps):
# 构建 prompt
tools_desc = "\n".join(
f"- {name}: {info['description']}"
for name, info in self.tools.items()
)
prompt = f"""可用工具:
{tools_desc}
历史记录:
{chr(10).join(self.memory)}
请按格式回答:
Thought: 你的思考
Action: 工具名 或 finish
Action Input: {{"key": "value"}} 或 最终答案"""
# 获取模型输出
response = self.llm.generate(prompt)
# 解析 Thought 和 Action
thought = self._extract(response, r'Thought:\s*(.+?)(?=\n)')
action = self._extract(response, r'Action:\s*(\w+)')
action_input = self._extract(response, r'Action Input:\s*(.+?)$')
print(f"Step {step + 1}:")
print(f" Thought: {thought}")
print(f" Action: {action}")
if action == "finish":
return action_input
# 执行工具
if action in self.tools:
try:
params = json.loads(action_input) if action_input else {}
observation = self.tools[action]["function"](**params)
except Exception as e:
observation = f"Error: {str(e)}"
else:
observation = f"Error: Unknown tool '{action}'"
print(f" Observation: {observation}\n")
# 添加到记忆
self.memory.extend([
f"Thought: {thought}",
f"Action: {action}({action_input})",
f"Observation: {observation}"
])
return "Max steps reached"
def _extract(self, text, pattern):
"""从文本中提取匹配内容"""
match = re.search(pattern, text, re.DOTALL)
return match.group(1).strip() if match else ""
# 使用示例
if __name__ == "__main__":
# 模拟 LLM(实际使用 OpenAI / Anthropic API)
class MockLLM:
def generate(self, prompt):
if "天气" in prompt or "weather" in prompt:
return 'Thought: 用户想查天气\nAction: get_weather\nAction Input: {"location": "北京"}'
return 'Thought: 任务完成\nAction: finish\nAction Input: 北京今天晴天,15°C'
agent = SimpleReActAgent(MockLLM())
agent.register_tool("get_weather", lambda location: "晴天,15°C", "获取天气信息")
result = agent.run("北京天气怎么样?")
print(f"最终答案: {result}")
实践 2:使用 LangGraph 构建智能体¶
"""
使用 LangGraph 构建生产级 ReAct Agent
LangGraph 是 LangChain Agent 的推荐替代方案
"""
from langgraph.prebuilt import create_react_agent
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
# 定义工具(使用 @tool 装饰器)
@tool
def search(query: str) -> str:
"""搜索实时信息"""
# 实际使用 DuckDuckGoSearchRun / Tavily 等
return f"搜索结果:{query} 的相关信息..."
@tool
def calculator(expression: str) -> str:
"""计算数学表达式"""
try:
result = eval(expression) # 生产环境建议用 sympy
return f"计算结果:{expression} = {result}"
except Exception as e:
return f"计算错误:{str(e)}"
# 创建 LLM
llm = ChatOpenAI(model="gpt-5-mini")
# 创建 Agent(LangGraph 方式)
agent = create_react_agent(
model=llm,
tools=[search, calculator]
)
# 运行
response = agent.invoke({
"messages": [{"role": "user", "content": "2024 年诺贝尔物理学奖得主是谁?"}]
})
print(response["messages"][-1].content)
API 迁移说明
langchain.agents.AgentExecutor 和 langchain.agents.create_react_agent 已弃用。 请使用 LangGraph 的 langgraph.prebuilt.create_react_agent。
实践 3:构建多智能体协作系统¶
"""
多智能体协作系统示例
使用协调者模式分配任务
"""
from enum import Enum
from typing import Optional
class AgentRole(str, Enum):
RESEARCHER = "researcher"
WRITER = "writer"
REVIEWER = "reviewer"
class CollaborativeSystem:
"""多智能体协作系统"""
def __init__(self, llm):
self.llm = llm
self.agents = {
AgentRole.RESEARCHER: "你是一个研究专家,负责收集和整理信息。",
AgentRole.WRITER: "你是一个写作专家,负责根据资料撰写文章。",
AgentRole.REVIEWER: "你是一个审阅专家,负责评审文章质量并提出修改建议。",
}
def run(self, topic: str, max_iterations: int = 3) -> str:
"""协作写作流程"""
# Phase 1: 研究
research = self._call_agent(
AgentRole.RESEARCHER,
f"请研究以下主题并整理关键信息:{topic}"
)
# Phase 2: 写作
draft = self._call_agent(
AgentRole.WRITER,
f"基于以下资料撰写文章:\n资料:{research}\n主题:{topic}"
)
# Phase 3: 审阅 + 迭代修改
for i in range(max_iterations):
review = self._call_agent(
AgentRole.REVIEWER,
f"请审阅以下文章,指出问题并给出修改建议:\n{draft}\n\n如果质量合格,请回复 'APPROVED'。"
)
if "APPROVED" in review:
print(f"审阅通过(第 {i + 1} 轮)")
return draft
# 根据反馈修改
draft = self._call_agent(
AgentRole.WRITER,
f"请根据审阅意见修改文章:\n原文:{draft}\n审阅意见:{review}"
)
return draft
def _call_agent(self, role: AgentRole, prompt: str) -> str:
"""调用指定角色的 Agent"""
system_prompt = self.agents[role]
response = self.llm.generate(f"{system_prompt}\n\n{prompt}")
return response
9. 面试常见问题¶
Q1: ReAct 和 Plan-and-Execute 架构有什么区别?各自适合什么场景?¶
答:
ReAct(推理+行动交替):
- 每一步都重新推理,根据上一步结果决定下一步
- 适合:探索性任务、需要实时反馈的任务
- 优点:灵活,能根据环境反馈调整
- 缺点:可能陷入循环,缺乏全局视野
Plan-and-Execute(先规划后执行):
- 先制定完整计划,再逐步执行
- 适合:结构化任务、步骤明确的任务
- 优点:全局视野,执行效率高
- 缺点:计划可能过时,需要重规划机制
最佳实践:两者结合(Adaptive Planning)
- 先制定粗粒度计划
- 执行时用 ReAct 处理细节
- 根据反馈动态调整计划
Q2: Function Calling 和 Prompt-based 工具调用有什么区别?¶
答:
Function Calling(原生函数调用):
- 模型原生支持,输出结构化 JSON
- 可靠性高,格式确定
- OpenAI / Anthropic 等主流 API 支持
- 适合:生产环境
Prompt-based 工具调用(ReAct 格式):
- 通过 prompt 模板引导模型输出 Action
- 需要正则解析,可靠性较低
- 兼容所有 LLM(包括开源模型)
- 适合:研究、原型开发
选择建议:
- 有 Function Calling API → 优先使用
- 开源模型 / 无 API 支持 → Prompt-based
Q3: 多智能体系统中如何避免 Agent 陷入无限循环?¶
答:
常见策略:
1. 最大步数限制(max_steps)
2. 重复检测(检测相同的 Action 连续出现)
3. 成本预算(Token / API 调用次数上限)
4. 超时机制(总执行时间上限)
5. 人类介入(HITL,在关键节点请求人类确认)
6. 质量评估器(独立 Agent 评估当前状态是否收敛)
Q4: CodeAgent 的安全风险有哪些?如何缓解?¶
答:
安全风险:
1. 代码注入:LLM 生成恶意代码(删除文件、网络攻击)
2. 资源滥用:无限循环、内存爆炸
3. 数据泄露:访问敏感文件或环境变量
4. 权限提升:利用系统漏洞获取更高权限
缓解措施:
1. 沙箱隔离:Docker 容器 / gVisor / Firecracker
2. 白名单机制:只允许安全的模块和函数
3. 资源限制:CPU/内存/时间/网络限制
4. 代码审计:静态分析 + LLM 自检
5. 人类审批:高风险操作需人类确认
10. 下一步¶
完成本节后,你应该:
- 理解智能体的核心概念和架构(ReAct, Plan-and-Execute)
- 掌握工具使用和 Function Calling 机制
- 了解任务分解和规划方法(CoT, ToT, 结构化规划)
- 理解 CodeAgent 的原理和安全注意事项
- 理解多智能体系统的协作机制(层级式、对等式、市场式)
- 能够构建简单的智能体应用
下一步:03-RAG 与长文本 — 学习如何让大模型利用外部知识库处理长文本
📝 本章练习¶
🤔 思考题¶
- ReAct vs Plan-and-Execute:ReAct 的"思考-行动-观察"循环和 Plan-and-Execute 的"先规划后执行"各适合什么场景?各自的局限性是什么?
- Function Calling:Function Calling 和直接让模型输出 JSON 格式的工具调用有什么本质区别?为什么需要专门的 Function Calling 机制?
- 多智能体协作:层级式、对等式、市场式三种多智能体协作模式各有什么优劣?在什么场景下该选择哪种?
- CodeAgent 安全:让 LLM 生成并执行代码的安全风险有哪些?如何设计沙箱环境来降低风险?
- Agent 记忆:短期记忆和长期记忆在 Agent 系统中如何实现?向量数据库在 Agent 记忆中扮演什么角色?
💻 代码实践¶
- 入门:使用 OpenAI Function Calling 实现一个简单的工具调用 Agent(支持天气查询和计算器)
- 进阶:实现 ReAct 模式的 Agent,让模型自主决定何时调用工具、何时直接回答
- 高级:构建一个双 Agent 协作系统(规划 Agent + 执行 Agent),完成一个多步骤任务
💡 参考答案
#### 思考题参考答案 **1. ReAct vs Plan-and-Execute** - **ReAct**:适合需要逐步探索、每步依赖上一步结果的场景(如信息检索、调试)。局限:长链容易累积错误,缺乏全局视野 - **Plan-and-Execute**:适合结构化、步骤明确的任务(如项目管理、旅行规划)。局限:计划可能不够灵活,无法应对意外情况 最佳实践:复杂任务可以先用 Plan-and-Execute 生成计划,再用 ReAct 执行每个步骤。 **2. Function Calling** 本质区别: - **Function Calling**:模型经过专门训练,能可靠地输出结构化的函数调用 JSON,参数类型和格式有保证 - **手动 JSON**:依赖 Prompt 工程,格式不稳定,容易出错(如引号嵌套、类型错误) Function Calling 的优势: - 结构化输出保证(JSON Schema 约束) - 并行调用支持(一次返回多个函数调用) - 更低的延迟(不需要复杂的 Prompt) **3. 多智能体协作模式** | 模式 | 优势 | 劣势 | 适用场景 | |------|------|------|---------| | 层级式 | 控制流清晰,易于管理 | 单点瓶颈,灵活性低 | 企业流程、客服系统 | | 对等式 | 灵活,无单点瓶颈 | 协调成本高,可能死锁 | 创意讨论、头脑风暴 | | 市场式 | 资源优化,竞争驱动 | 实现复杂,延迟高 | 任务分配、资源调度 | **4. CodeAgent 安全** 安全风险: - **代码注入**:用户输入中包含恶意代码 - **资源滥用**:无限循环、内存耗尽、网络攻击 - **数据泄露**:代码访问敏感文件或环境变量 - **权限提升**:利用系统漏洞获取更高权限 沙箱设计: - Docker 容器隔离(限制网络、文件系统访问) - 执行超时限制 - 内存/CPU 资源配额 - 只读文件系统 + 白名单目录 - 禁止危险系统调用 **5. Agent 记忆** - **短期记忆**:对话上下文窗口(直接存储在 Prompt 中),容量有限 - **长期记忆**:向量数据库存储历史交互和知识,通过相似度检索召回 向量数据库的角色: - 存储编码后的记忆片段(Embedding) - 支持语义相似度检索(而非精确匹配) - 常用工具:ChromaDB、Pinecone、FAISS #### 代码实践参考答案 **实践 1:Function Calling Agent**import json
from openai import OpenAI
client = OpenAI()
# 定义工具
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名"}
},
"required": ["city"]
}
}
},
{
"type": "function",
"function": {
"name": "calculate",
"description": "执行数学计算",
"parameters": {
"type": "object",
"properties": {
"expression": {"type": "string", "description": "数学表达式"}
},
"required": ["expression"]
}
}
}
]
def execute_tool(name, args):
if name == "get_weather":
return f"{args['city']}:晴,25°C,湿度 60%"
elif name == "calculate":
return str(eval(args["expression"])) # 生产环境应用 ast.literal_eval
def run_agent(user_message):
messages = [{"role": "user", "content": user_message}]
while True:
response = client.chat.completions.create(
model="gpt-4o-mini", messages=messages, tools=tools
)
msg = response.choices[0].message
messages.append(msg)
if msg.tool_calls:
for tc in msg.tool_calls:
args = json.loads(tc.function.arguments)
result = execute_tool(tc.function.name, args)
messages.append({"role": "tool", "tool_call_id": tc.id, "content": result})
else:
return msg.content
print(run_agent("北京今天天气怎么样?如果室外温度25度,体感温度大概多少(用 wind chill 公式估算)?"))
REACT_PROMPT = """你是一个 ReAct 智能体。按以下格式回答:
Question: 用户的问题
Thought: 你的思考过程
Action: 要调用的工具名(参数)
Observation: 工具返回结果
... (重复 Thought/Action/Observation)
Thought: 我现在知道最终答案了
Final Answer: 最终回答
可用工具:search(查询)、calculate(计算)、weather(天气)"""
def react_agent(question, max_steps=5):
messages = [{"role": "user", "content": f"{REACT_PROMPT}\n\nQuestion: {question}"}]
for _ in range(max_steps):
response = client.chat.completions.create(model="gpt-4o-mini", messages=messages, max_tokens=500)
answer = response.choices[0].message.content
messages.append({"role": "assistant", "content": answer})
if "Final Answer:" in answer:
return answer.split("Final Answer:")[-1].strip()
# 解析 Action 并执行
if "Action:" in answer:
action_line = [l for l in answer.split("\n") if l.startswith("Action:")][0]
# 解析并执行工具...
observation = "工具执行结果..."
messages.append({"role": "user", "content": f"Observation: {observation}"})
return "达到最大步数限制"
最后更新日期:2026-04-21 适用版本:LLM 学习教程 v2026.04
审查记录: - 2026-04-20: 全面重写 — 修复嵌套代码块格式错误,完善推理引擎
_parse_response实现,新增面试常见问题章节,新增 CrewAI 案例和 CommunicationBus 代码,更新 Function Calling 示例为完整可运行版本,新增目录导航 - 2026-03-27: 收紧 MCP 与 agentic coding 的宿主/模型边界描述