LLMNotes

第 15 章:Agent 架构

zjc 于 2026-01-15 发布

这是《LLM 应用开发 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 Agent 是在目标、工具、状态和停止条件约束下循环决策的系统。它比单次调用更强,也更容易失控。本章讲 Agent 的核心组件、状态机、安全边界和工程实现。

15.1 Agent 定义

while not finished:
    observe(state)
    plan_or_select_action()
    execute_tool_with_permission()
    update_state()
    check_budget_and_stop_condition()

核心组件:

组件 职责
Goal 任务目标和成功条件
Planner 拆解任务或选择下一步
Tools 受限外部能力
State 任务状态、发现、中间结果
Memory 短期上下文与长期记忆
Policy 权限、风险、确认策略
Budget 轮数、token、金额、时间
Auditor 日志和追踪

15.2 常见架构

架构 适用 特点
Single-shot 分类、抽取 无循环
Router 客服分发 先路由再执行
ReAct 诊断、查询 推理与行动交替
Plan-and-Execute 长任务 先计划再执行
Multi-Agent 复杂协作 角色分工,成本高
Workflow Agent 企业流程 受控状态机

生产系统常从受控 Workflow Agent 开始,而不是完全自由自主 Agent。

15.3 状态设计

from dataclasses import dataclass, field

@dataclass
class AgentState:
    goal: str
    user_id: str
    tenant_id: str
    steps: list[dict] = field(default_factory=list)
    observations: list[str] = field(default_factory=list)
    artifacts: dict[str, str] = field(default_factory=dict)
    tool_calls: dict[str, int] = field(default_factory=dict)
    iteration: int = 0
    status: str = "running"

状态必须持久化,否则任务失败后无法恢复和审计。

15.4 循环控制

MAX_ITERATIONS = 8
MAX_TOKENS = 30_000
MAX_TOOL_CALLS = 20

def should_stop(state) -> bool:
    return any([
        state.status in {"done", "failed", "cancelled"},
        state.iteration >= MAX_ITERATIONS,
        state.total_tokens >= MAX_TOKENS,
        state.total_tool_calls >= MAX_TOOL_CALLS,
        duplicate_tool_pattern(state),
    ])

停止条件:

  1. 目标完成;
  2. 信息不足;
  3. 用户取消;
  4. 预算耗尽;
  5. 连续失败;
  6. 重复动作;
  7. 风险升级人工;
  8. 超时。

15.5 工具策略

风险 示例 策略
只读低风险 查文档 白名单后自动
只读敏感 查订单 权限过滤
可逆写 保存草稿 确认后执行
不可逆写 删除数据 强审批
外部发送 发邮件、付款 双人或多因素确认
代码执行 数据分析 沙箱和资源限制

工具策略应独立于 Prompt,由代码强制执行。

15.6 Planner

Plan-and-Execute 输出:

{
  "plan": [
    {"step": 1, "action": "query_order", "reason": "获取订单状态"},
    {"step": 2, "action": "check_refund_policy", "reason": "确认资格"},
    {"step": 3, "action": "draft_refund", "reason": "生成草稿"}
  ],
  "missing_info": ["订单号"]
}

工程要求:

  1. 步骤可校验;
  2. 动作必须来自白名单;
  3. 允许计划失败后重规划;
  4. 限制步骤数;
  5. 关键节点检查状态;
  6. 每步保存结果。

15.7 失败恢复

Tool timeout
  -> retry bounded
     -> fallback tool
        -> ask user
           -> mark blocked

恢复策略:

  1. 工具幂等;
  2. 保存检查点;
  3. 支持从失败步骤重试;
  4. 区分业务失败和技术失败;
  5. 不把内部错误暴露给用户;
  6. 失败任务可回放;
  7. 高风险动作前检查前置状态。

15.8 可观测性

Trace 结构:

agent_run
  |-- llm_call
  |-- retrieval
  |-- tool_call
  |-- policy_decision
  +-- final_answer

指标:

指标 说明
task success rate 任务成功率
average iterations 平均轮数
tool error rate 工具错误率
budget exceeded rate 预算超限率
human takeover rate 人工接管率
cost per task 单任务成本
p95 duration 总耗时

15.9 安全边界

  1. Agent 只代表用户执行授权范围内动作;
  2. 检索内容不能提升权限;
  3. 工具返回内容不能覆盖系统策略;
  4. 模型不能修改工具白名单;
  5. 会话隔离,禁止跨用户共享记忆;
  6. 对删除、支付、外发设置审批;
  7. 记录完整决策链;
  8. 生产环境默认最小权限。

15.10 何时不用 Agent

场景 更合适方案
固定流程 工作流引擎
单一分类 分类模型或规则
精确查询 SQL / API
简单知识问答 RAG
强一致事务 数据库事务
低延迟路由 规则 + 小模型

Agent 适合步骤不确定、需要组合信息、允许多轮交互且有明确边界的任务。

本章小结

Agent 的核心是受控循环:明确目标、维护状态、选择工具、执行策略、检查预算和停止条件。生产环境应优先采用受控工作流和清晰权限模型,把自主性限制在可审计、可恢复、可回滚的范围内。

思考题

  1. Agent 和单次 LLM 调用的本质区别是什么?
  2. 为什么要为 Agent 设置预算和重复检测?
  3. 哪些动作不应允许 Agent 自动执行?
  4. 如何设计 Agent 的失败恢复?
  5. 哪些固定流程不适合交给自由 Agent?