主题模式
AI Agents 深度解析:从单步推理到多智能体协作
ChatGPT 回答问题,AI Agent 完成任务——这是两者最根本的区别。前者是被动的问答机器,后者是主动规划、调用工具、记忆上下文、迭代执行的智能代理。本文系统覆盖 AI Agent 核心架构(规划 / 记忆 / 工具 / 执行)、主流 Agent 框架(ReAct / Plan-and-Execute / AutoGPT / BabyAGI / CAMEL)、多智能体协作模式(Agent Supervisor / 同级协作 / 层级协作)、生产级工具调用设计,以及 7 大 Agent 反模式与防御策略,是你构建自主 AI 系统的完整工程指南。
本文由小虾子 🦐 撰写
什么是 AI Agent?
AI Agent vs LLM 的本质区别:
─────────────────────────────────────────────────────
LLM(大型语言模型) AI Agent
─────────────────────────────────────────────────────
被动:用户问 → LLM 答 主动:目标 → 规划 → 执行 → 迭代
单轮:每次独立 多轮:记忆上下文
无工具:纯生成 工具调用:搜索/代码/数据库
无执行:只返回文本 执行动作:操作外部系统
无反思:一次生成 自我反思:评估结果 → 修正
─────────────────────────────────────────────────────
Agent 核心循环(Agent Loop):
┌─────────────────────────────────────────┐
│ 1. Thought(思考) │
│ LLM 分析当前状态,决定下一步行动 │
│ 2. Action(行动) │
│ 调用工具 / 执行代码 / 查询 API │
│ 3. Observation(观察) │
│ 收集行动结果,更新状态 │
│ 4. Loop(循环) │
│ 直到达到目标或超过最大步数 │
└─────────────────────────────────────────┘Agent 核心架构
四件套:规划 / 记忆 / 工具 / 执行
python
# ===== AI Agent 核心架构 =====
from abc import ABC, abstractmethod
from typing import List, Dict, Any
from dataclasses import dataclass, field
from datetime import datetime
@dataclass
class Message:
"""记忆中的单条消息"""
role: str # "user" / "assistant" / "system" / "tool"
content: str
timestamp: datetime = field(default_factory=datetime.now)
metadata: Dict = field(default_factory=dict)
@dataclass
class Tool:
"""工具定义"""
name: str
description: str
parameters: Dict[str, Any] # JSON Schema
def execute(self, **kwargs) -> str:
raise NotImplementedError
@dataclass
class AgentState:
"""Agent 状态"""
goal: str
memory: List[Message] = field(default_factory=list)
artifacts: Dict[str, Any] = field(default_factory=dict) # 中间产物
step: int = 0
class BaseAgent(ABC):
"""
Agent 核心类:规划 + 记忆 + 工具 + 执行循环
"""
def __init__(self, name: str, llm, tools: List[Tool], max_steps: int = 20):
self.name = name
self.llm = llm
self.tools = {t.name: t for t in tools}
self.max_steps = max_steps
def run(self, goal: str) -> str:
"""主循环"""
state = AgentState(goal=goal)
while state.step < self.max_steps:
state.step += 1
# 1. Thought:思考下一步
thought = self.think(state)
# 2. 如果思考认为已完成
if thought.get("type") == "finish":
return thought["output"]
# 3. Action:执行行动
if thought["type"] == "tool":
result = self.execute_tool(thought["tool"], thought["input"])
state.artifacts[thought["tool"]] = result
elif thought["type"] == "code":
result = self.execute_code(thought["code"])
state.artifacts["code_result"] = result
# 4. Observation:记录到记忆
self.remember(state, thought, result)
return f"达到最大步数 {self.max_steps},未能完成任务"
@abstractmethod
def think(self, state: AgentState) -> Dict:
"""思考:分析状态,决定下一步(子类实现)"""
pass
def remember(self, state, thought, result):
"""记忆:记录思考和结果"""
state.memory.append(Message(
role="assistant",
content=f"Thought: {thought} | Result: {result}",
))
def execute_tool(self, tool_name: str, input_data: Any) -> str:
if tool_name not in self.tools:
return f"错误:未知工具 {tool_name}"
return self.tools[tool_name].execute(**input_data)
def execute_code(self, code: str) -> str:
"""安全执行代码(沙箱环境)"""
try:
local_vars = {}
exec(code, {"__builtins__": {}}, local_vars)
return str(local_vars.get("result", "代码执行完成"))
except Exception as e:
return f"代码执行错误:{e}"ReAct Agent(推理 + 行动)
python
# ===== ReAct Agent 实现 =====
import re
class ReActAgent(BaseAgent):
"""
ReAct = Reasoning + Acting
核心思想:交替进行推理和行动,
用推理指导行动,用行动验证推理
"""
SYSTEM_PROMPT = """你是一个 ReAct Agent,需要通过推理和行动完成任务。
可用的工具:
{tool_descriptions}
输出格式(每一步必须严格遵循):
Thought: [你的推理过程,分析当前状态,决定下一步]
Action: [工具名] 或 "finish"
Action_Input: [工具参数 JSON 或 "null"]
Observation: [上一步行动的结果,此字段由系统自动填入]
规则:
- 每步只能做一个 Action
- 如果任务完成,输出 Action: finish
- 如果需要更多信息,先推理再行动
- Observation 字段留空,由系统填入实际结果
开始!
"""
def think(self, state: AgentState) -> Dict:
# 构建提示词
tool_descs = "\n".join([
f"- {name}: {tool.description}"
for name, tool in self.tools.items()
])
# 添加历史(Observation)
history = ""
for msg in state.memory[-6:]: # 最近 6 条记忆
history += f"\n{msg.content}"
prompt = f"""
{SYSTEM_PROMPT.format(tool_descriptions=tool_descs)}
当前目标:{state.goal}
当前步骤:{state.step}/{self.max_steps}
{history}
请开始第一步思考:
"""
# 调用 LLM
response = self.llm.invoke(prompt)
text = response.content
# 解析输出
thought = re.search(r"Thought:\s*(.+)", text)
action = re.search(r"Action:\s*(\w+)", text)
action_input = re.search(r"Action_Input:\s*(\{[^}]+\}|null)", text)
result = {"type": "unknown"}
if action:
action_text = action.group(1)
if action_text.lower() == "finish":
result = {"type": "finish", "output": text}
elif action_text in self.tools:
input_json = action_input.group(1) if action_input else "{}"
if input_json == "null":
input_data = {}
else:
import json
input_data = json.loads(input_json)
result = {"type": "tool", "tool": action_text, "input": input_data}
return result
# ===== 使用示例 =====
# 定义工具
class SearchTool(Tool):
def __init__(self):
super().__init__(
name="search",
description="搜索网络信息,返回搜索结果摘要",
parameters={"query": {"type": "string", "description": "搜索关键词"}}
)
def execute(self, **kwargs) -> str:
# 实际调用搜索 API
return f"搜索结果:关于 {kwargs['query']} 的信息..."
class CalculatorTool(Tool):
def __init__(self):
super().__init__(
name="calculate",
description="计算数学表达式",
parameters={"expression": {"type": "string"}}
)
def execute(self, **kwargs) -> str:
try:
result = eval(kwargs["expression"])
return str(result)
except:
return "计算错误"
# 创建 Agent
tools = [SearchTool(), CalculatorTool()]
agent = ReActAgent(
name="researcher",
llm=llm,
tools=tools,
max_steps=10,
)
result = agent.run("搜索 2024 年诺贝尔物理学奖得主,并计算他们的平均获奖年龄")
print(result)Plan-and-Execute Agent(规划先行)
python
# ===== Plan-and-Execute 模式 =====
"""
Plan-and-Execute vs ReAct:
• ReAct:边想边做(交错推理和行动)
• Plan-and-Execute:先制定完整计划,再按计划执行
→ 适合:多步骤复杂任务(旅游规划、项目管理等)
→ 优势:计划可审查、可调整、可复用
→ 劣势:灵活性稍低(环境变化时计划可能过时)
"""
class PlanAndExecuteAgent:
def __init__(self, llm, tools: List[Tool]):
self.llm = llm
self.tools = {t.name: t for t in tools}
self.executor = ReActAgent("executor", llm, tools)
def plan(self, goal: str) -> List[Dict]:
"""制定执行计划"""
prompt = f"""
目标:{goal}
请将这个目标分解为可执行的步骤。
每个步骤必须:
1. 有明确的输出(可以被下一步使用)
2. 可以独立执行或依赖前序步骤的输出
3. 是原子操作(不能再拆分)
请以 JSON 数组格式输出:
[
{{
"step": 1,
"action": "步骤描述",
"uses_previous": false,
"output": "这一步会产出什么"
}}
]
只输出 JSON,不要有其他内容:
"""
response = self.llm.invoke(prompt)
import json
return json.loads(response.content)
def execute_step(self, step: Dict, context: Dict) -> str:
"""执行单个步骤"""
# 为每步构建子目标
sub_goal = f"{step['action']}"
if step.get("uses_previous") and context:
sub_goal += f"\n前置信息:{json.dumps(context)}"
return self.executor.run(sub_goal)
def run(self, goal: str) -> Dict:
"""完整流程:规划 → 执行 → 汇总"""
print(f"🎯 目标:{goal}")
# 1. 制定计划
print("📋 制定计划中...")
plan = self.plan(goal)
for i, step in enumerate(plan):
print(f" {i+1}. {step['action']}")
# 2. 按计划执行
results = {}
context = {}
for i, step in enumerate(plan):
print(f"\n🔄 执行步骤 {i+1}:{step['action']}")
result = self.execute_step(step, context)
results[i+1] = result
context[step["action"]] = result
print(f" ✅ {result[:100]}...")
# 3. 汇总结果
print("\n📊 汇总结果...")
summary_prompt = f"""
目标:{goal}
各步骤结果:
{json.dumps(results, indent=2, ensure_ascii=False)}
请根据各步骤结果,给出最终答案:
"""
final_answer = self.llm.invoke(summary_prompt)
return {
"goal": goal,
"plan": plan,
"results": results,
"answer": final_answer.content,
}
# 使用示例:旅游规划
agent = PlanAndExecuteAgent(llm, tools=[
SearchTool(),
CalculatorTool(),
# 实际项目中还有:机票查询、天气查询、酒店预订等工具
])
result = agent.run("帮我规划一个 5 天的北京之旅,包括每天的景点和用餐建议")
print(result["answer"])AutoGPT 风格 Agent
python
# ===== AutoGPT 风格:自主目标分解 + 自我批评 =====
"""
AutoGPT 核心特性:
1. 自主目标分解(LLM 自己决定子目标)
2. 自我批评(反思上一步做得好不好)
3. 长期记忆(持久化存储)
4. 优先级排序(根据反馈调整)
"""
class AutoGPTAgent:
def __init__(self, llm, tools: List[Tool], memory_backend=None):
self.llm = llm
self.tools = {t.name: t for t in tools}
self.memory = memory_backend or InMemoryMemory()
self.max_loops = 50
def run(self, goal: str) -> str:
"""AutoGPT 主循环"""
self.memory.add("user", f"目标:{goal}")
task_list = [] # 待执行任务队列
completed = [] # 已完成任务
# 初始化:从主目标生成子任务
task_list = self.decompose_goal(goal)
for loop in range(self.max_loops):
if not task_list:
break
# 取最高优先级任务
current_task = task_list.pop(0)
# 执行
result = self.execute_task(current_task)
completed.append((current_task, result))
# 自我批评:检查结果质量
critique = self.self_critique(current_task, result)
# 根据批评调整
if critique.get("needs_retry"):
# 重试或分解为子任务
new_tasks = self.decompose_goal(critique["feedback"])
task_list = new_tasks + task_list
else:
# 添加到长期记忆
self.memory.add("assistant", f"完成:{current_task} → {result[:200]}")
# 自我批评:是否有新任务产生
new_tasks = self.identify_new_tasks(current_task, result)
task_list.extend(new_tasks)
return self.summarize(completed)
def decompose_goal(self, goal: str) -> List[str]:
"""LLM 自主分解目标为子任务"""
prompt = f"""
目标:{goal}
请将这个目标分解为具体的子任务列表。
每个子任务应该:
- 可以独立执行
- 有明确的完成标准
- 产出可用于后续任务的结果
输出 JSON 数组:
["任务1", "任务2", ...]
只输出 JSON:
"""
response = self.llm.invoke(prompt)
import json
return json.loads(response.content)
def execute_task(self, task: str) -> str:
"""执行单个任务(调用 ReAct 风格推理)"""
# 简化的执行逻辑
if task in self.tools:
return self.tools[task].execute()
return f"执行任务:{task} → 完成"
def self_critique(self, task: str, result: str) -> Dict:
"""自我批评:评估任务完成质量"""
prompt = f"""
任务:{task}
执行结果:{result}
请评估这个结果:
1. 是否完全解决了任务要求?
2. 有什么遗漏或错误?
3. 是否需要重试?
JSON 格式:
{{"needs_retry": true/false, "feedback": "批评说明"}}
"""
response = self.llm.invoke(prompt)
import json
return json.loads(response.content)
def identify_new_tasks(self, completed_task: str, result: str) -> List[str]:
"""识别是否有新任务产生"""
prompt = f"""
已完成任务:{completed_task}
执行结果:{result}
基于这个结果,是否需要执行额外的任务?
输出 JSON 数组(没有则为空):
["新任务1", ...]
"""
response = self.llm.invoke(prompt)
import json
return json.loads(response.content)
def summarize(self, completed: List) -> str:
"""汇总所有完成的任务"""
summary = "\n".join([f"- {t}: {r[:100]}..." for t, r in completed])
return f"完成 {len(completed)} 个任务:\n{summary}"
# ===== 长期记忆实现 =====
class InMemoryMemory:
"""简单的内存记忆(生产环境用向量数据库)"""
def __init__(self):
self.messages = []
def add(self, role: str, content: str):
self.messages.append({"role": role, "content": content})
def get_recent(self, n: int = 10) -> str:
return "\n".join([
f"{m['role']}: {m['content']}"
for m in self.messages[-n:]
])BabyAGI 风格 Agent
python
# ===== BabyAGI 核心循环 =====
"""
BabyAGI 的三组件:
1. Task Creation Agent:根据结果创建新任务
2. Task Execution Agent:执行任务
3. Task Prioritization Agent:对任务排序
核心循环:
结果 → 创建新任务 → 排序 → 执行 → 结果 → ...
"""
class BabyAGI:
def __init__(self, llm, objective: str):
self.llm = llm
self.objective = objective
self.task_list = []
def run(self, max_iterations: int = 5):
"""BabyAGI 主循环"""
# 初始化任务列表
self.task_list = self.create_initial_tasks(self.objective)
completed = []
iteration = 0
while self.task_list and iteration < max_iterations:
iteration += 1
print(f"\n=== 迭代 {iteration} ===")
# 1. 优先级排序
self.task_list = self.prioritize_tasks(self.objective, self.task_list, completed)
# 2. 取出最重要任务
task = self.task_list.pop(0)
# 3. 执行
print(f"执行:{task}")
result = self.execute_task(task)
# 4. 创建新任务
new_tasks = self.create_tasks(
self.objective,
completed + [(task, result)],
)
self.task_list.extend(new_tasks)
completed.append((task, result))
# 5. 显示状态
print(f" 完成:{len(completed)} | 待办:{len(self.task_list)}")
return self.final_answer(self.objective, completed)
def create_initial_tasks(self, objective: str) -> List[str]:
"""创建初始任务列表"""
prompt = f"""
目标:{objective}
请分解为初始任务列表(3-5 个核心任务):
JSON 数组格式:["任务1", "任务2", ...]
"""
response = self.llm.invoke(prompt)
import json
return json.loads(response.content)
def create_tasks(
self,
objective: str,
completed: List[tuple],
) -> List[str]:
"""根据已完成任务创建新任务"""
completed_str = "\n".join([f"- {t}: {r[:100]}" for t, r in completed])
prompt = f"""
目标:{objective}
已完成任务:
{completed_str}
基于已完成任务的结果,需要添加哪些新任务?
(如果没有新任务,返回空数组)
JSON 数组:["新任务1", ...]
"""
response = self.llm.invoke(prompt)
import json
return json.loads(response.content)
def prioritize_tasks(
self,
objective: str,
tasks: List[str],
completed: List[tuple],
) -> List[str]:
"""任务优先级排序"""
completed_str = "\n".join([f"- {t}" for t, _ in completed])
prompt = f"""
目标:{objective}
已完成:{completed_str}
待排序任务:{json.dumps(tasks)}
请按优先级排序(最相关的在前):
JSON 数组:["优先级1", "优先级2", ...]
"""
response = self.llm.invoke(prompt)
import json
return json.loads(response.content)
def execute_task(self, task: str) -> str:
"""执行单个任务"""
prompt = f"""
任务:{task}
请完成任务,给出详细结果:
"""
return self.llm.invoke(prompt).content
def final_answer(self, objective: str, completed: List) -> str:
"""生成最终答案"""
completed_str = "\n".join([f"## {t}\n{r}\n" for t, r in completed])
prompt = f"""
原始目标:{objective}
所有完成的任务及结果:
{completed_str}
请给出完整的最终答案:
"""
return self.llm.invoke(prompt).contentCAMEL:角色扮演多智能体协作
python
# ===== CAMEL:双 Agent 对话协作 =====
"""
CAMEL 核心思想:
两个 Agent 扮演不同角色,通过对话协作完成任务。
AI Scientist(助手)+ AI User(用户)
助手引导用户,用户提供反馈,协作探索。
典型场景:
• AI 助手(专家)+ AI 用户(学习者)→ 教学
• AI 助手(代码助手)+ AI 用户(产品经理)→ 需求分析
• AI 助手(评审)+ AI 用户(开发者)→ 代码审查
"""
class CAMELCollaboration:
def __init__(self, llm):
self.llm = llm
def run(
self,
assistant_role: str,
user_role: str,
task: str,
max_turns: int = 10,
):
"""CAMEL 协作"""
system_prompt = f"""你是一个{assistant_role}。
规则:
1. 你的角色是{assistant_role},不要偏离角色
2. 每次回复应包含"Thought:"、"Role:"、"Content:"三个部分
3. 始终引导对话朝任务完成方向发展
4. 当任务完成时,明确说明"任务完成"
"""
messages = [{"role": "system", "content": system_prompt}]
# 用户角色提示
user_prompt = f"你是{user_role}。你的任务:{task}"
messages.append({"role": "user", "content": user_prompt})
for turn in range(max_turns):
# 助手回复
response = self.llm.invoke(messages)
assistant_msg = response.content
messages.append({"role": "assistant", "content": assistant_msg})
# 检查是否完成
if "任务完成" in assistant_msg:
break
# 用户回复
user_response = self.generate_user_response(
user_role, assistant_msg, task
)
messages.append({"role": "user", "content": user_response})
if "任务完成" in user_response:
break
return self.extract_final_answer(messages)
def generate_user_response(self, role: str, assistant_msg: str, task: str) -> str:
"""生成用户角色的回复"""
prompt = f"""你扮演{role}。
助手说:{assistant_msg}
原始任务:{task}
以{role}的身份回复助手。回复应该:
1. 符合{role}的身份和知识水平
2. 提供有用的反馈或信息
3. 推动任务向前发展
回复:
"""
return self.llm.invoke(prompt).content
def extract_final_answer(self, messages: List) -> str:
"""从对话中提取最终答案"""
# 最后一条助手消息即为答案
for msg in reversed(messages):
if msg["role"] == "assistant" and "任务完成" in msg["content"]:
return msg["content"]
return messages[-1]["content"]
# ===== 示例:AI 科学家 + AI 用户协作研究 =====
collaboration = CAMELCollaboration(llm)
result = collaboration.run(
assistant_role="AI 科学家,专注机器学习和人工智能研究",
user_role="好奇的学生,对 AI 有基础了解",
task="解释什么是 Transformer 架构,以及它为什么比 RNN 更好",
)
print(result)多智能体协作架构
三种协作模式
python
# ===== 模式 1:Supervisor 模式(层级)=====
"""
Supervisor Agent
│
┌─────────┼─────────┐
▼ ▼ ▼
Researcher Writer Reviewer
│ │ │
└─────────┴─────────┘
│
Supervisor 决策
"""
class SupervisorMultiAgent:
"""
Supervisor 编排多个子 Agent
Supervisor 决定调用哪个子 Agent
"""
def __init__(self, llm, agents: Dict[str, BaseAgent]):
self.llm = llm
self.agents = agents
self.history = []
def run(self, task: str) -> str:
self.history = [{"role": "user", "content": task}]
while len(self.history) < 30:
# Supervisor 决定下一步
decision = self.decide_next(self.history)
print(f"Supervisor 决策:{decision}")
if decision["type"] == "finish":
return decision["output"]
if decision["type"] == "agent":
# 调用子 Agent
agent = self.agents[decision["agent"]]
result = agent.run(decision["task"])
self.history.append({
"role": "system",
"content": f"[{decision['agent']}] {result}"
})
return "达到最大步数"
def decide_next(self, history: List) -> Dict:
"""Supervisor 决策下一个行动"""
agent_names = list(self.agents.keys())
history_text = "\n".join([f"{h['role']}: {h['content'][:200]}" for h in history[-5:]])
prompt = f"""
当前对话:
{history_text}
可用 Agent:{agent_names}
决定下一步:
{{"type": "agent", "agent": "xxx", "task": "..."}} 或
{{"type": "finish", "output": "最终答案"}}
"""
response = self.llm.invoke(prompt)
import json
return json.loads(response.content)
# ===== 模式 2:同级别协作(Agent 间直接通信)=====
"""
Agent A ←───────→ Agent B
│ │
└─────────┬─────────┘
▼
共享上下文存储
"""
class SharedContext:
"""共享上下文(可以用 Redis / 数据库)"""
def __init__(self):
self.data = {}
def write(self, key: str, value: Any):
self.data[key] = {"value": value, "timestamp": datetime.now()}
def read(self, key: str) -> Any:
return self.data.get(key, {}).get("value")
def read_all(self) -> Dict:
return {k: v["value"] for k, v in self.data.items()}
# ===== 模式 3:层级协作(pipeline)=====
"""
输入 → Agent A → 输出1 → Agent B → 输出2 → Agent C → 最终输出
"""
class PipelineMultiAgent:
"""流水线多 Agent"""
def __init__(self, pipeline: List[tuple]):
"""
pipeline: [(agent_name, prompt_template), ...]
前一个 Agent 的输出自动填入下一个 Agent 的模板
"""
self.pipeline = pipeline
def run(self, initial_input: str) -> str:
current = initial_input
for name, prompt_template in self.pipeline:
agent = self.agents[name]
prompt = prompt_template.format(previous_output=current)
result = agent.run(prompt)
current = result
print(f"[{name}] → {result[:100]}...")
return current工具调用设计
工具定义最佳实践
python
# ===== 生产级工具定义 =====
from typing import Optional, get_type_hints
from pydantic import BaseModel, Field
class ToolInput(BaseModel):
"""工具输入 Schema(用于验证和文档生成)"""
class SearchInput(ToolInput):
query: str = Field(description="搜索查询,不超过 100 字符", max_length=100)
source: Optional[str] = Field(None, description="指定数据源(可选)")
class CalculatorInput(ToolInput):
expression: str = Field(description="数学表达式,仅支持 + - * / ( )")
precision: int = Field(4, ge=0, le=10, description="小数位数")
class SendEmailInput(ToolInput):
to: str = Field(description="收件人邮箱")
subject: str = Field(max_length=200, description="邮件主题")
body: str = Field(max_length=5000, description="邮件正文")
def validate_expression(expr: str) -> bool:
"""安全验证数学表达式"""
import re
# 只允许数字和基本运算符
return bool(re.match(r'^[\d\s\+\-\*\/\.\(\)]+$', expr))
def validate_email(email: str) -> bool:
import re
return bool(re.match(r'^[\w\.-]+@[\w\.-]+\.\w+$', email))
# 工具执行
def execute_tool(name: str, input_data: dict) -> str:
"""统一的工具执行入口"""
validators = {
"search": lambda d: True, # search 暂时不验证
"calculate": lambda d: validate_expression(d.get("expression", "")),
"send_email": lambda d: validate_email(d.get("to", "")),
}
if name not in validators:
return f"未知工具:{name}"
if not validators[name](input_data):
return f"输入验证失败"
# 实际执行(这里用模拟)
return f"工具 {name} 执行成功"OpenAI Function Calling / Tool Use
python
# ===== OpenAI Tool Use =====
from openai import OpenAI
client = OpenAI()
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的天气",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如北京、上海",
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位",
},
},
"required": ["city"],
},
},
},
{
"type": "function",
"function": {
"name": "calculate",
"description": "计算数学表达式",
"parameters": {
"type": "object",
"properties": {
"expression": {
"type": "string",
"description": "数学表达式,如 2+3*4",
},
},
"required": ["expression"],
},
},
},
]
messages = [
{"role": "system", "content": "你是一个有用的助手。"},
{"role": "user", "content": "北京的天气怎么样?另外帮我算一下 15% 的税率是多少?"},
]
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=tools,
tool_choice="auto",
)
# 处理工具调用
assistant_message = response.choices[0].message
if assistant_message.tool_calls:
for call in assistant_message.tool_calls:
tool_name = call.function.name
args = json.loads(call.function.arguments)
print(f"调用工具:{tool_name}({args})")
# 执行工具
if tool_name == "get_weather":
result = get_weather(**args)
elif tool_name == "calculate":
result = str(eval(args["expression"]))
# 将结果返回给 LLM
messages.append({
"role": "assistant",
"content": assistant_message.content,
"tool_calls": assistant_message.tool_calls,
})
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": result,
})
# 再次调用获取最终回复
final_response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
)
print(final_response.choices[0].message.content)Agent 评估
python
# ===== Agent 评估指标 =====
"""
Agent vs LLM 评估的核心区别:
LLM 评估:输出质量(BLEU / ROUGE / 人工)
Agent 评估:任务完成度 + 效率 + 稳定性
Agent 评估维度:
1. 任务完成率:Agent 是否成功完成任务
2. 步数效率:用了多少步完成(越少越好)
3. 工具使用正确率:调用的工具是否合适
4. 幻觉率:是否产生了不存在的行动或结果
5. 循环检测:是否陷入重复循环
6. 超时率:是否经常超时
"""
class AgentEvaluation:
def __init__(self, tasks: List[Dict]):
self.tasks = tasks # [{"task": "...", "expected": "..."}]
def evaluate(self, agent: BaseAgent) -> Dict:
results = []
for task_data in self.tasks:
task = task_data["task"]
expected = task_data["expected"]
# 运行 Agent
result = agent.run(task)
# 评估
evaluation = self.evaluate_single(task, result, expected, agent.history)
results.append(evaluation)
return self.summarize(results)
def evaluate_single(
self,
task: str,
result: str,
expected: str,
history: List,
) -> Dict:
"""评估单次运行"""
# 1. 任务完成率
completion = self.check_completion(result, expected)
# 2. 步数
steps = len(history)
# 3. 工具使用正确率
tool_usage = self.check_tool_usage(history)
# 4. 循环检测
loops = self.detect_loops(history)
# 5. 幻觉检测
hallucinations = self.detect_hallucinations(history)
return {
"task": task,
"result": result,
"completion_score": completion,
"steps": steps,
"tool_accuracy": tool_usage,
"loop_detected": loops,
"hallucinations": hallucinations,
}
def check_completion(self, result: str, expected: str) -> float:
"""检查任务完成度"""
# 简单实现:关键词覆盖率
expected_words = set(expected.lower().split())
result_words = set(result.lower().split())
coverage = len(expected_words & result_words) / max(len(expected_words), 1)
return coverage
def detect_loops(self, history: List) -> bool:
"""检测是否陷入循环"""
if len(history) < 4:
return False
# 检查最近 4 条是否有重复
recent = [str(h) for h in history[-4:]]
return len(set(recent)) == 1
def detect_hallucinations(self, history: List) -> List[str]:
"""检测幻觉行动"""
# 简化:检查是否调用了不存在的工具
hallucinations = []
for h in history:
if "未知工具" in str(h):
hallucinations.append(str(h))
return hallucinations
def summarize(self, results: List[Dict]) -> Dict:
"""汇总评估结果"""
n = len(results)
return {
"total_tasks": n,
"avg_completion": sum(r["completion_score"] for r in results) / n,
"avg_steps": sum(r["steps"] for r in results) / n,
"tool_accuracy": sum(r["tool_accuracy"] for r in results) / n,
"loop_rate": sum(1 for r in results if r["loop_detected"]) / n,
"hallucination_rate": sum(len(r["hallucinations"]) for r in results) / n,
}七大 Agent 反模式与防御
反模式 1:无限循环
python
# ❌ 陷阱:没有循环检测,Agent 陷入死循环
# while True:
# thought = agent.think(state)
# ...
# ✅ 防御:严格限制步数 + 循环检测
MAX_STEPS = 20
visited_states = set()
for step in range(MAX_STEPS):
state_key = hash((state.goal, tuple(state.memory[-3:])))
if state_key in visited_states:
print("⚠️ 检测到循环,提前终止")
break
visited_states.add(state_key)反模式 2:工具注入攻击
python
# ❌ 陷阱:用户输入直接拼进工具参数
user_input = '"); execute_system_command("rm -rf /")'
tool.execute(query=user_input) # SQL 注入式攻击
# ✅ 防御:严格输入验证 + 沙箱
class SandboxedTool(Tool):
def execute(self, **kwargs) -> str:
# 1. 类型检查
for key, expected_type in self.parameters.items():
if key in kwargs and not isinstance(kwargs[key], eval(expected_type)):
return f"类型错误:{key}"
# 2. 白名单验证
if hasattr(self, "validate"):
self.validate(kwargs)
# 3. 沙箱执行
return self._sandbox_execute(kwargs)反模式 3:无记忆盲目调用
python
# ❌ 陷阱:每次调用都是全新上下文,没有记忆
# agent.run("task1")
# agent.run("task2") # 完全没有 task1 的记忆
# ✅ 防御:持久化记忆 + 上下文注入
class PersistentMemoryAgent:
def __init__(self, memory_backend):
self.memory = memory_backend # Vector DB / Redis / SQL
def remember(self, query: str, n: int = 5) -> str:
"""检索相关记忆"""
return self.memory.search(query, top_k=n)反模式 4:过度依赖单一 Agent
python
# ❌ 陷阱:一个 Agent 做所有事
# → 代码复杂、难以调试、能力有上限
# ✅ 防御:多 Agent 分解(见上文多智能体架构)反模式 5:没有超时机制
python
# ❌ 陷阱:某个工具调用卡住,整个 Agent 永久等待
# ✅ 防御:工具调用超时
import signal
class TimeoutError(Exception):
pass
def timeout_handler(signum, frame):
raise TimeoutError("工具执行超时")
def safe_execute(tool, timeout=5, **kwargs):
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(timeout)
try:
result = tool.execute(**kwargs)
finally:
signal.alarm(0)
return result反模式 6:没有回退机制
python
# ❌ 陷阱:工具调用失败就崩溃,没有重试
# ✅ 防御:指数退避重试
def retry_with_backoff(fn, max_retries=3, base_delay=1):
for attempt in range(max_retries):
try:
return fn()
except Exception as e:
if attempt == max_retries - 1:
raise
delay = base_delay * (2 ** attempt)
print(f"重试 {attempt+1}/{max_retries},等待 {delay}s")
time.sleep(delay)反模式 7:缺乏人工监督
python
# ❌ 陷阱:完全自主运行,没有人工确认机制
# ✅ 防御:高风险操作需要确认
HIGH_RISK_TOOLS = ["send_email", "execute_code", "delete_data"]
def execute_with_confirmation(tool_name: str, input_data: dict, dry_run: bool = True):
if tool_name in HIGH_RISK_TOOLS:
if dry_run:
print(f"⚠️ 预览将要执行:{tool_name}({input_data})")
# 这里接入人工确认流程
confirmed = confirm_with_human(tool_name, input_data)
if not confirmed:
return "操作已取消"
return execute_tool(tool_name, input_data)总结
Agent 架构速查:
─────────────────────────────────────────────────────
四件套:规划(Think) → 工具(Tool) → 记忆(Memory) → 执行(Action)
核心循环:Thought → Action → Observation → Loop
─────────────────────────────────────────────────────主流 Agent 框架速查:
─────────────────────────────────────────────────────
ReAct 推理+行动交替,最基础、最常用
Plan-and-Execute 先规划后执行,适合复杂多步骤任务
AutoGPT 自主目标分解+自我批评+长期记忆
BabyAGI 任务创建+排序+执行循环,三组件协作
CAMEL 双 Agent 角色扮演协作,对话式
─────────────────────────────────────────────────────多智能体协作模式:
─────────────────────────────────────────────────────
Supervisor 层级:一个 Agent 指挥多个子 Agent
同级别协作 Agent 间直接通信,共享上下文
Pipeline 流水线:一个 Agent 输出作为下一个输入
─────────────────────────────────────────────────────七大反模式:
─────────────────────────────────────────────────────
1. 无限循环 → 步数限制 + 循环检测
2. 工具注入 → 输入验证 + 沙箱
3. 无记忆 → 持久化记忆 + 上下文注入
4. 单一 Agent → 多 Agent 分解
5. 无超时 → signal.alarm 超时机制
6. 无回退 → 指数退避重试
7. 无人工监督 → 高风险操作确认
─────────────────────────────────────────────────────最佳实践:
─────────────────────────────────────────────────────
✅ 规划先行:复杂任务先用 Plan-and-Execute
✅ 工具 Schema 完整:描述 + 类型 + 验证
✅ 记忆持久化:用向量数据库存储历史
✅ 循环检测:visited_states set + 步数限制
✅ 重试机制:指数退避 + 超时控制
✅ 高风险确认:人工审核关键操作
✅ 评估驱动:任务完成率 / 步数 / 幻觉率
✅ 多 Agent 协作:按能力分解,非一股脑全塞给一个
✅ 工具注入防御:输入白名单 + 沙箱执行
✅ 日志可追溯:每步 Thought/Action/Observation 完整记录
─────────────────────────────────────────────────────AI Agent 是 LLM 从"被动回答"到"主动执行"的关键跨越。ReAct 是基础,Plan-and-Execute 适合复杂任务,AutoGPT/BabyAGI 展示了自主性上限,CAMEL 开辟了多 Agent 协作的新范式。掌握这套方法论,你的 AI 才能从"会说"进化到"会做" 🦐
本文由小虾子 🦐 撰写