AI 智能体(Agent)架构设计:从 ReAct 到自主决策系统的完整实践

系统拆解 LLM Agent 的架构模式:ReAct、Reflexion、Plan-and-Solve、AutoGPT。 涵盖感知(Perception)、推理(Reasoning)、记忆(Memory)、工具(Tool)、执行(Execution)五大核心组件的设计与实现。 附基于 LangChain + OpenAI 的完整可运行推演 demo,以及生产环境的护栏与成本优化策略。

🤖 前置依赖:已掌握基础 LLM API 调用、Prompt 工程与 Function Calling。
若基础尚未扎实,请先阅读 LLM API 基础调用指南Prompt 工程深度指南


1. 从对话到行动:为什么需要智能体?

大语言模型本质上是被动响应器—你输入,它输出。但现实世界的问题往往需要多步推理、状态跟踪和外部工具调用。例如:

  • 订机票:搜索航班 → 比价 → 填写预订 → 支付 → 发送确认
  • 竞品分析:抓取竞品价格 → 分析功能差异 → 生成对比报告 → 制作可视化图表
  • 代码审查:读取 PR → 分析变更 → 运行测试 → 检查安全漏洞 → 撰写评审意见

智能体将 LLM 从文本生成器升级为自主执行引擎,让它能够观察世界、做出决策、调用工具、记录结果、反思优化—循环往复直至目标达成。


2. 智能体的五大核心组件

┌─────────────────────────────────────────┐
│              感知(Perception)          │  ← 输入:用户目标、环境状态、工具返回值
├─────────────────────────────────────────┤
│              推理(Reasoning)           │  ← 核心:如何思考、如何计划、如何反思
├─────────────────────────────────────────┤
│              记忆(Memory)              │  ← 持久化:对话历史、经验沉淀、矢量检索
├─────────────────────────────────────────┤
│              工具(Tools)               │  ← 扩展:API 调用、代码执行、数据库查询
├─────────────────────────────────────────┤
│              执行(Execution)           │  ← 行动:调用工具、返回结果、生成回复
└─────────────────────────────────────────┘

2.1 感知(Perception)

感知层负责将外部信息转化为模型可理解的格式。常见策略:

策略说明适用场景
直接注入用户输入直接喂给模型简单问答
结构化摘要用模板抽取关键字段API 返回数据
检索增强从知识库检索相关上下文知识密集型任务
多模态融合图像/音频转文本描述需要视觉/听觉感知的任务
环境快照捕获当前状态(如浏览器 DOM)网页自动化

2.2 推理(Reasoning)

推理是智能体的"大脑"。主流推理模式包括:

1) Chain-of-Thought (CoT)
一步一步地思考。在 Prompt 中加入 “Let’s think step by step” 即可激活。

2) Tree-of-Thought (ToT)
维护一棵搜索树,每个节点是一种可能的推理路径。用投票或评分机制选择最优路径。适合需要探索多个方案的问题(如数学证明、代码生成)。

3) ReAct (Reasoning + Acting)
交替执行 Thought → Action → Observation:先思考,再行动,基于工具返回再思考。这是当前 Agent 应用最广泛的框架模式。

4) Reflexion
在 ReAct 基础上增加自我反思:当任务失败或结果不理想时,系统分析失败原因并调整策略。

推理模式核心思想适用场景代表框架
CoT单步推理链条数学计算、逻辑推断所有 LLM
ToT多路分支 + 回溯开放式问题、创意生成DSPy, entropix
ReAct推理-行动交替循环工具调用、信息检索LangChain, AutoGPT
Reflexion带反思的 ReAct持续改进型任务Self-Refine, Reflexion

2.3 记忆(Memory)

记忆系统决定了 Agent 的上下文延续能力。

记忆层级
├── 工作记忆(Working Memory)
│   └── 当前对话的最近 N 轮
├── 短期记忆(Short-term Memory)
│   └── 可缓存的对话摘要、工具结果
├── 长期记忆(Long-term Memory)
│   ├── 事实性知识(向量数据库检索)
│   └── 经验性知识(历史任务的成败记录)
└── 外部记忆(External Memory)
    └── 笔记、文档、网页、数据库

实现建议:

  • 对话超出窗口 → 用滑动窗口摘要(每 K 轮做一次摘要)
  • 事实检索 → 存入 Chroma / Pinecone / Milvus 等向量库
  • 经验积累 → 用结构化 JSON 记录 Task → Strategy → Result → Feedback

2.4 工具(Tools)

工具将 Agent 的能力边界无限扩展。

# 工具签名规范(OpenAI function calling 风格)
{
    "type": "function",
    "function": {
        "name": "search_flight",
        "description": "搜索指定日期和目的地的航班。",
        "parameters": {
            "type": "object",
            "properties": {
                "origin": {"type": "string", "description": "出发城市代码"},
                "destination": {"type": "string", "description": "到达城市代码"},
                "date": {"type": "string", "description": "出发日期(YYYY-MM-DD)"}
            },
            "required": ["origin", "destination", "date"]
        }
    }
}

2.5 执行(Execution)

执行层负责实际调用工具、处理异常、管理状态。
关键设计原则:

  1. 幂等性:同一参数的工具调用返回相同结果(避免重复付费)
  2. 超时控制:每个工具调用设 10-30 秒上限
  3. 并发限制:同时对同一 API 的并发数设上限
  4. 错误降级:工具失败时,用备用方案或向用户解释

3. ReAct 模式详解

ReAct = Reasoning + Acting。它通过交错式的思考和行动,让 LLM 在每一步都明确自己的意图再行动。

3.1 交互循环

输入:用户目标 "查一下从上海到北京 8 月 10 日的便宜的机票"

循环 1:
  Thought: 用户要查机票,需要调用 search_flight 工具。
           参数:origin=上海 → PVG, destination=北京 → PEK, date=2024-08-10
  Action: search_flight(origin="PVG", destination="PEK", date="2024-08-10")
  Observation: [航班列表:MU5161 ¥580, CA1850 ¥620, ...]

循环 2:
  Thought: 找到了航班列表,需要过滤出便宜的选择。
           MU5161(¥580)和 CA1850(¥620)都是不错的选择。
  Action: 无需进一步调用,直接回复用户。
  Observation: (无)

回复:"为您找到上海 → 北京 8 月 10 日的航班..."

3.2 Prompt 模板

你是智能助理 Agent,负责帮助用户完成目标。

可用工具:
- search_flight(origin, destination, date): 搜索航班
- compare_price(flight_list): 比较价格
- book_ticket(flight_id, passenger): 预订机票

规则:
1. 每次只能调用一个工具
2. 调用工具前,先用 <Thought> 说明你的推理过程
3. 工具返回后,用 <Observation> 记录结果
4. 任务完成时,直接回复用户

历史记录:
{{memory}}

用户目标:{{goal}}

4. 可运行 Python 示例

4.1 基础 ReAct Agent

import os, json, re, openai
from openai import OpenAI

client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

# ====== 工具函数 ======
def search_flight(origin: str, destination: str, date: str):
    """Mock 搜索航班"""
    return [
        {"id": "MU5161", "price": 580, "time": "08:00-10:30"},
        {"id": "CA1850", "price": 620, "time": "14:00-16:20"},
        {"id": "MU5133", "price": 690, "time": "19:00-21:30"},
    ]

def compare_price(flight_ids):
    return f"价格排序: MU5161(¥580) < CA1850(¥620) < MU5133(¥690)"

TOOLS = {
    "search_flight": search_flight,
    "compare_price": compare_price,
}

# ====== Agent 类 ======
class ReActAgent:
    def __init__(self, client):
        self.client = client
        self.memory = []
        self.max_loop = 10

    SYSTEM_PROMPT = """你是一个智能订票代理 Agent。每次只能执行一个操作。
可用工具:search_flight(origin, destination, date), compare_price(flight_ids)
你必须按格式回复:
Thought: [推理过程]
Action: 工具名称(参数) 或 "完成"
"""

    def call_tool(self, action_str):
        m = re.match(r'(\w+)\((.*)\)', action_str)
        if not m:
            return "格式错误"
        name, args = m.group(1), m.group(2)
        # 简单参数解析(生产环境请用 ast.literal_eval)
        try:
            arg_dict = eval(f"dict({args})")
            return TOOLS[name](**arg_dict)
        except Exception as e:
            return f"工具调用错误: {e}"

    def run(self, goal: str):
        self.memory.append({"role": "user", "content": goal})
        for _ in range(self.max_loop):
            messages = [
                {"role": "system", "content": self.SYSTEM_PROMPT},
                *self.memory,
            ]
            resp = self.client.chat.completions.create(
                model="gpt-4o-mini",
                messages=messages,
                temperature=0.2,
            )
            content = resp.choices[0].message.content
            self.memory.append({"role": "assistant", "content": content})

            # 提取 Thought 和 Action
            thought = re.search(r'Thought:\s*(.*?)(?:\n|$)', content, re.DOTALL)
            action = re.search(r'Action:\s*(.*?)(?:\n|$)', content, re.DOTALL)

            if action:
                action_str = action.group(1).strip()
                if "完成" in action_str or not action_str:
                    print("✅ 任务完成")
                    return content
                # 调用工具
                result = self.call_tool(action_str)
                obs = f"Observation: {json.dumps(result, ensure_ascii=False)}"
                self.memory.append({"role": "user", "content": obs})
                print(f"🧠 Thought: {thought.group(1).strip() if thought else 'N/A'}")
                print(f"🔧 Action: {action_str}")
                print(f"📊 {obs}")
            else:
                break

# 运行
agent = ReActAgent(client)
result = agent.run("帮我查 2024-08-10 从上海到北京最便宜的机票")
print("\n=== 最终回复 ===\n", result)

4.2 带向量记忆的 Agent

from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain.agents import AgentExecutor, create_openai_functions_agent
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain.tools import Tool

# 初始化组件
llm = ChatOpenAI(model="gpt-4o-mini")
embedding = OpenAIEmbeddings()
vectorstore = Chroma(embedding_function=embedding, persist_directory="./chroma_db")

# 创建检索工具
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
def retrieve_context(query):
    docs = retriever.invoke(query)
    return "\n".join([d.page_content for d in docs])

retrieval_tool = Tool.from_function(
    func=retrieve_context,
    name="knowledge_retrieval",
    description="从历史文档和公司知识库中检索相关信息。",
)

# Prompt 模板(带记忆插槽)
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个客服 Agent。使用知识库回答用户问题。"),
    MessagesPlaceholder(variable_name="chat_history"),
    ("human", "{input}"),
    MessagesPlaceholder(variable_name="agent_scratchpad"),
])

# 创建 Agent
agent = create_openai_functions_agent(llm, [retrieval_tool], prompt)
executor = AgentExecutor(agent=agent, tools=[retrieval_tool], verbose=True)

# 运行
response = executor.invoke({
    "input": "我们公司支持哪些支付方式?",
    "chat_history": []
})

5. 生产级安全护栏

┌─────────────────────────────────────┐
│ 输入护栏 (Input Guards)             │
│ - Prompt Injection 检测              │
│ - SQL 注入 / XSS 过滤               │
│ - 敏感信息 PII 脱敏                 │
├─────────────────────────────────────┤
│ 工具护栏 (Tool Guards)              │
│ - 参数 Schema 校验                  │
│ - 权限检查(RBAC)                   │
│ - 速率限制与熔断                     │
├─────────────────────────────────────┤
│ 输出护栏 (Output Guards)            │
│ - 有害内容检测                       │
│ - 事实一致性验证                     │
│ - 合规审计日志                       │
└─────────────────────────────────────┘

必备防御规则:

  1. Prompt Injection 检测 — 在输入中检测 “ignore previous instructions”、“you are now in DAN mode” 等攻击向量
  2. 工具参数校验 — 所有工具参数必须经过 Pydantic Schema 校验
  3. 人审触发器 — 高风险操作(如支付、删除数据)必须人工确认
  4. 沙箱执行 — 代码生成必须在受限环境中运行(如 Docker、WASM)

6. 常见架构反模式

反模式问题建议
过度规划Agent 在简单问题上花太多步数为简单任务设置单步快速通道
记忆泄漏敏感对话混入公共上下文按用户/会话隔离记忆
工具蔓延工具太多导致模型选择困难按领域分组,<10 个活跃工具
幻觉自信Agent 基于虚构的 Observation 继续推理要求模型明确标注信息来源
无限循环没有终止条件导致死循环max_loop 限制 + 循环检测
权限过宽Agent 可以调用所有 API最小权限原则 + OAuth scope

7. 生产部署与成本优化

7.1 模型选择策略

层级模型用途成本
路由层规则/小模型意图分类~零
思考层GPT-4o-mini / Claude 3 Haiku推理 Planning$
执行层GPT-4o / Claude 3.5 Sonnet复杂任务 + 代码$$
质检层Claude 3.5 Sonnet / GPT-4o输出审核(可选)$$

7.2 成本估算

对于 1000 次订票查询:

  • GPT-4o-mini 做路由 + 规划:~200K tokens ≈ $0.06
  • GPT-4o 处理复杂逻辑:~50K tokens ≈ $0.50
  • 工具调用 API 费用:取决于第三方 API(如 Skyscanner)
  • 总计:约 $0.56 / 1000 次(不含第三方)

7.3 缓存策略

  • LLM 响应缓存:相同输入的推理结果缓存 5min
  • 工具结果缓存:查询结果 TTL=1h
  • 向量索引缓存:频繁查询的 TopK 结果常驻内存

8. 总结与选型建议

你的场景推荐模式框架起步复杂度
简单工具流ReAct + 2-3 个工具LangChain⭐⭐
需要长期记忆ReAct + 向量库LangChain + Chroma⭐⭐⭐
多智能体协作CrewAI / AutoGenCrewAI⭐⭐⭐
动态规划Plan-and-Solve / ToTDSPy⭐⭐⭐⭐
代码生成ReAct + Code InterpreterOpenAI Code Interpreter⭐⭐
端到端 RPAAutoGPT (无头浏览器)AutoGPT + Playwright⭐⭐⭐⭐⭐

📂 继续阅读:


高价值 FAQ

Q: ReAct 和 AutoGPT 有什么区别?
A: ReAct 是推理模式(理解 → 行动 → 观察),AutoGPT 是实现框架(目标分解 + 记忆 + 工具 + 自主迭代)。你可以用 AutoGPT 来运行 ReAct,也可以用 LangChain 来运行 ReAct。

Q: Agent 和 RAG 怎么结合?
A: RAG 解决知识获取问题,Agent 解决任务执行问题。最佳实践是:将 RAG 封装为一个知识检索工具,Agent 在推理过程中自主决定何时调用这个工具获取知识。

Q: 单智能体和多个单智能体组合,哪个更可靠?
A: 经验法则:简单任务用单智能体,复杂任务用多智能体。单智能体的错误传播短、调试简单;多智能体并行度高、职责更清晰但通信开销和一致性成本更高。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「llm」更多文章