8.3 Agent 架构:ReAct 范式、规划模块、记忆模块

4.1 介绍了 Agent 的核心概念,这里我们从工程架构视角深入------如何设计一个生产级的 Agent 系统?规划怎么做?记忆怎么管理?工具怎么编排?错误怎么兜底?

📑 目录


Agent 架构总览

复制代码
┌────────────────────────────────────────────────────┐
│                 生产级 Agent 架构                   │
│                                                    │
│  ┌──────────┐  ┌──────────┐  ┌──────────────────┐  │
│  │  规划器   │  │  记忆系统 │  │    工具注册表      │  │
│  │ Planner  │  │ Memory  │  │  Tool Registry   │  │
│  │          │  │ System  │  │                  │  │
│  │ 任务分解  │  │ 短期/长期│  │ 注册/发现/权限   │  │
│  │ 步骤排序  │  │ 向量/摘要│  │ 限流/审计日志    │  │
│  └────┬─────┘  └────┬─────┘  └────────┬─────────┘  │
│       │             │                  │            │
│       └──────┬──────┘                  │            │
│              ↓                         ↓            │
│  ┌──────────────────────────────────────────┐   │
│  │            Agent Core (ReAct Loop)       │   │
│  │                                          │   │
│  │  State ← Observe → Think → Act → Tool   │   │
│  │    ↑________________________________↓    │   │
│  └──────────────────────────────────────────┘   │
│                      │                          │
│              ┌───────┴───────┐                   │
│              ↓               ↓                   │
│  ┌─────────────────┐ ┌─────────────────┐       │
│  │  Output Parser  │ │ Safety Guard    │       │
│  │  (输出解析)      │ │ (安全校验+兜底)  │       │
│  └─────────────────┘ └─────────────────┘       │
│                                                    │
│  外部接口:HTTP API / SSE Stream / WebSocket      │
└────────────────────────────────────────────────────┘

ReAct 的工程实现细节

python 复制代码
import json
from dataclasses import dataclass, field
from enum import Enum
from typing import Optional

class AgentState(Enum):
    IDLE = "idle"
    THINKING = "thinking"
    ACTING = "acting"
    OBSERVING = "observing"
    DONE = "done"
    ERROR = "error"

@dataclass
class AgentStep:
    step_id: int
    thought: str
    action_name: Optional[str] = None
    action_input: Optional[dict] = None
    observation: Optional[str] = None
    state: AgentState = AgentState.IDLE

class ProductionAgent:
    def __init__(self, llm, tools, memory, max_steps=15):
        self.llm = llm
        self.tools = {t.name: t for t in tools}
        self.memory = memory
        self.max_steps = max_steps
        self.history: list[AgentStep] = []
    
    def run(self, task: str) -> str:
        self.memory.add_user_message(task)
        
        for step_num in range(self.max_steps):
            step = AgentStep(step_id=step_num)
            
            # 1. THINK: LLM 生成推理和行动决策
            step.state = AgentState.THINKING
            response = self._call_llm_with_tools()
            step.thought = response.thought
            self.history.append(step)
            
            # 2a. DONE: 直接回答
            if not response.tool_calls:
                step.state = AgentState.DONE
                self.memory.add_assistant_message(response.content)
                return response.content
            
            # 2b. ACT: 调用工具
            for tc in response.tool_calls:
                step.state = AgentState.ACTING
                step.action_name = tc.name
                step.action_input = tc.args
                
                result = self._safe_execute(tc.name, tc.args)
                
                # 3. OBSERVE: 记录结果
                step.state = AgentState.OBSERVING
                step.observation = str(result)[:500]  # 截断防止过长
                self.memory.add_tool_result(tc.id, result)
        
        return f"达到最大步数 {self.max_steps},未完成任务"
    
    def _safe_execute(self, name, args):
        """安全执行工具(带异常捕获和超时)"""
        tool = self.tools.get(name)
        if not tool:
            return f"Error: 未知的工具 '{name}'"
        try:
            return tool.execute(**args)
        except Exception as e:
            return f"Error: {type(e).__name__}: {str(e)}"

规划模块:从反应式到前瞻式

复制代码
反应式 ReAct(4.1 介绍的基础版):
想一步做一步,走一步看步
→ 简单但容易绕弯路

前瞻式 Plan-and-Execute:
先花时间做完整计划,确认后逐步执行

Plan 模块的关键能力:
1. 任务分解:把大目标拆成可执行的子任务
2. 依赖分析:识别子任务之间的先后顺序
3. 资源评估:预估需要的工具和数据
4. 动态重计划:执行中发现问题时能调整后续步骤

class Planner:
    def plan(self, task: str) -> list[SubTask]:
        prompt = f"""将以下任务分解为具体的执行步骤:
{task}

要求:
- 每个步骤应该是可独立验证完成的
- 标注每个步骤所需的工具
- 标注步骤之间的依赖关系
- 最多不超过 {self.max_steps} 步

输出 JSON 格式的步骤列表。"""
        plan_json = self.llm.generate(prompt)
        return self._parse_plan(plan_json)

记忆系统的架构设计

(详见 4.2,这里补充工程要点)

复制代码
生产级记忆系统的关键设计:

1. 异步写入:
   记忆存储不要阻塞主流程
   写入操作放到后台队列异步完成

2. 分级存储:
   Redis (热数据/会话内记忆) → PostgreSQL (用户画像) → Vector DB (长期语义记忆)

3. TTL 过期:
   临时记忆设置过期时间,自动清理防止膨胀

4. 隐私隔离:
   不同用户/租户的记忆严格隔离
   支持遗忘权(GDPR right to be forgotten)

5. 一致性保障:
   记读写入后立即可读(至少最终一致性)

Agent 安全与兜底机制

安全措施 说明
工具白名单 只允许调用预定义的工具,禁止任意代码执行
输入输出过滤 注入检测、敏感信息脱敏
操作确认 危险操作(删数据/发邮件)需二次确认
步数限制 防止无限循环消耗 Token 和时间
成本预算 单次对话 Token 上限和费用上限
人工接管 Agent 不确定时主动请求人类介入
操作审计 所有 Tool Call 记录完整的日志

❌ 常见误区

  • ❌ Agent 越智能越好 --- 生产环境的 Agent 应该是「可控的智能」,不是「自由的智能」
  • ❌ 忽略安全机制 --- Agent 有工具调用能力 = 有破坏力,安全必须第一优先级
  • ❌ 一次设计到位 --- 先从最简化的 ReAct 开始,根据实际需求逐步增加复杂度