Agent 的基本架构由哪些核心组件构成?

#RAG#Agent#面试八股

Agent 的基本架构由哪些核心组件构成?

把 Agent 拆开看,它不是一个模型,而是一套围绕模型的"外骨骼":模型负责决策,其余组件负责让决策变得可执行、可约束、可观测。 不同框架(LangGraph、AutoGen、Coze 等)的命名五花八门,但骨架基本一致,缺了哪一层都会在线上以特定方式出问题。

1. 结论:七层骨架,三层是刚需

最小可用 Agent 只需要 模型 + 工具 + 循环;要做到生产可用,还得补上 上下文/记忆、规划、护栏、观测。 按重要性排序:模型与提示、工具层、运行时循环(刚需)→ 记忆、规划(提质)→ 护栏、观测与评测(保命)。

2. 机制:分层结构

┌───────────────────────────────────────────────┐
│ 接入层:CLI / HTTP API / IM 机器人 / 定时任务   │
├───────────────────────────────────────────────┤
│ 编排层:运行时循环、状态机、中断与恢复          │
│   ┌──────────┐   ┌──────────┐   ┌──────────┐  │
│   │ 规划器    │   │ 反思器    │   │ 路由器    │  │
│   └──────────┘   └──────────┘   └──────────┘  │
├───────────────────────────────────────────────┤
│ 能力层:工具/函数调用、代码执行、检索(RAG)      │
├───────────────────────────────────────────────┤
│ 状态层:短期上下文、长期记忆、任务黑板          │
├───────────────────────────────────────────────┤
│ 模型层:主模型 + 小模型(路由/摘要) + 兜底模型   │
├───────────────────────────────────────────────┤
│ 治理层:权限、护栏、限流预算、日志追踪、评测     │
└───────────────────────────────────────────────┘

关键点:模型层之上的一切都是为了让模型少犯错。把上下文裁剪好、把工具描述写准、把错误信息写清,效果提升往往比换更大的模型明显。

3. 组件职责与典型故障

组件职责常见实现缺少/做错时的表现
模型(Model)决策、生成、解析通用大模型 + 小模型分流复杂任务跑不动,或成本失控
提示模板(Prompt)角色、约束、输出格式系统提示 + few-shot 示例输出格式飘、工具名记错
工具层(Tool)把能力暴露给模型JSON Schema 描述的函数、MCP 服务参数类型错、选错工具、越权
运行时(Runtime)执行动作、管理循环手写 while、LangGraph 图死循环、超时、状态丢失
记忆(Memory)跨轮次保存信息上下文窗口 + 向量库 + 关系库多轮失忆、重复问同样的问题
规划器(Planner)拆解目标、排步骤结构化输出生成 DAG长任务中途跑偏、漏步骤
护栏(Guardrail)输入输出校验、权限规则 + 分类模型 + 白名单提示注入、误删数据、泄露
观测(Tracing)记录每步输入输出OpenTelemetry、Langfuse出问题无法定位到哪一步

4. 用配置描述一个 Agent

把架构写成声明式配置,比散落在代码里更容易 review 和灰度:

# agent.yaml
name: ops-assistant
model:
  primary: gpt-4o-mini          # 主决策模型
  router: gpt-4o-mini           # 意图分类用小模型即可
  temperature: 0.2              # 工具型 Agent 要低温度
prompt:
  system: prompts/ops.md
  max_context_tokens: 12000
tools:
  - name: query_metrics
    schema: schemas/query_metrics.json
    side_effect: read           # read / write,write 需人工确认
  - name: restart_pod
    schema: schemas/restart_pod.json
    side_effect: write
    require_approval: true
memory:
  short_term: { max_turns: 20, strategy: summary }
  long_term: { store: pgvector, top_k: 5 }
runtime:
  max_steps: 12                 # 硬上限,防死循环
  timeout_seconds: 120
  on_error: retry_once_then_ask
guardrails:
  input: [prompt_injection_check, pii_redact]
  output: [schema_validate, secret_scan]
observability:
  trace: otel
  sample_rate: 1.0

装配代码只做一件事:把配置翻译成运行时对象,缺省值全部显式化。

def build_agent(cfg):
    tools = {t["name"]: load_tool(t) for t in cfg["tools"]}
    for t in cfg["tools"]:
        if t.get("side_effect") == "write":
            tools[t["name"]] = require_approval(tools[t["name"]])
    return Agent(
        llm=load_model(cfg["model"]["primary"]),
        system=render(cfg["prompt"]["system"]),
        tools=tools,
        max_steps=cfg["runtime"]["max_steps"],
        memory=build_memory(cfg["memory"]),
        hooks=[guard(cfg["guardrails"]), trace(cfg["observability"])],
    )

hooks 这一层是区别 demo 与生产的分水岭:所有输入输出都过一遍护栏和埋点,而不是靠开发者在每个工具里手动加日志。

5. 常见追问

问:哪些组件可以省? 记忆可以先用滑动窗口顶替,规划器可以先用"每步重新决策"顶替,观测绝对不能省——没有 trace 的 Agent 等于线上盲飞。护栏在只读场景可以简化,写场景必须有。

问:规划器和 ReAct 冲突吗? 不冲突。规划器负责粗粒度步骤,每个步骤内部仍可以用 ReAct 边想边做。区别只是"步骤在什么时候确定"。

问:工具层怎么设计才算合格? 四条:命名动词开头且语义唯一;参数用 JSON Schema 严格约束(枚举、必填、范围);错误返回可读的原因和修复建议;写操作幂等或带确认。工具描述是给模型看的 API 文档,写得含糊,模型就一定会用错。

问:状态放在哪? 短期状态(当前任务、已执行步骤)放运行时内存,进程重启即失效;需要跨会话的放外部存储。别把状态塞进提示词里靠模型自己记,那是最不可靠的存储。

小结

Agent 架构可以概括成"一个模型 + 一圈外骨骼":工具让它能动手,记忆让它不失忆,规划让它不跑偏,护栏和观测让它不出事、出事能查。面试时按"刚需三层、提质两层、保命两层"讲,比罗列框架组件清单更有层次。

笔记加载中…