Agent系统架构怎么选?
大模型 Agent 核心组件选型与架构实现,百度面试题详解
原题:请设计一个大语言模型Agent系统,阐述你的设计思路、核心组件选择以及技术实现方案,并解释为什么采用这样的设计架构。
Prompt工程 · 百度真题
30 秒回答
- 明确Agent核心能力边界(规划、记忆、工具、执行)
- 阐述ReAct/CoT等推理范式选择依据
- 设计可扩展的工具注册与调用机制
- 说明记忆模块的分层设计(短期/长期)
回答与解析
答案要点
- 明确Agent核心能力边界(规划、记忆、工具、执行)
- 阐述ReAct/CoT等推理范式选择依据
- 设计可扩展的工具注册与调用机制
- 说明记忆模块的分层设计(短期/长期)
- 考虑安全与异常处理机制
整体架构:分层解耦的模块化设计
┌─────────────────────────────────────┐
│ 交互层 (API/GUI) │
├─────────────────────────────────────┤
│ 推理引擎层 │ ReAct/CoT规划器 │
│ (LLM Core) │ 意图识别与槽位填充 │
├─────────────────────────────────────┤
│ 能力层 │ 工具注册中心 │
│ (Tools) │ 记忆管理(短期/长期) │
│ │ 知识检索(RAG) │
├─────────────────────────────────────┤
│ 执行层 │ 工具执行沙箱 │
│ (Execution)│ 结果校验与重试机制 │
└─────────────────────────────────────┘
核心组件设计
1. 推理引擎:ReAct + Function Calling 双模态
- 复杂任务用ReAct(Reasoning + Acting):Thought → Action → Observation循环
- 结构化任务直接用Function Calling,降低token消耗
- 通过意图分类器自动路由,阈值可调
2. 工具系统:动态注册 + 契约化描述
# 核心思路:工具自描述,LLM零代码接入
@tool_registry.register(
name="search",
description="搜索引擎,用于获取实时信息",
params_schema={"query": "string", "top_k": "int"}
)
async def search_tool(params): ...
- 工具描述用JSON Schema,支持嵌套和依赖
- 执行层隔离:敏感操作进沙箱,网络请求限流
3. 记忆分层:三级缓存策略
| 层级 | 载体 | 用途 | 实现 |
|---|---|---|---|
| 工作记忆 | Context Window | 当前对话 | 滑动窗口+摘要压缩 |
| 短期记忆 | Redis/内存 | 会话级 | 最近N轮 + 实体提取 |
| 长期记忆 | 向量库 | 用户画像 | 定期反思生成+embedding |
4. 规划与反思:自我修正机制
- 执行前:分解子任务,生成依赖图(DAG检查循环依赖)
- 执行中:超时/异常触发重规划,最多3次回溯
- 执行后:成功/失败样本入库,用于后续SFT
关键设计决策
| 决策点 | 选择 | 原因 |
|---|---|---|
| 单Agent vs 多Agent | 单Agent为主,多Agent为辅 | 降低协调复杂度,特定场景(代码生成+测试)用多Agent |
| 同步 vs 异步执行 | 用户可见路径同步,后台任务异步 | 平衡体验与吞吐量 |
| 模型选择 | 大小模型级联 | 简单意图用小模型(如ERNIE-Tiny),复杂推理用大模型 |
异常处理与安全保障
- 幻觉检测:工具返回结果与LLM生成答案做一致性校验(NLI模型)
- 权限控制:工具打标签(read/write/dangerous),敏感操作需二次确认
- 熔断机制:单工具失败率>30%自动降级,切换备用方案
口语版讲法(约4分钟)
- 一句话定位:Agent系统本质是让LLM从对话者变成执行者
- 推理引擎:ReAct与Function Calling双模态,按任务复杂度路由
- 工具系统:动态注册加契约化描述,执行层隔离防风险
- 记忆分层:工作记忆、短期记忆、长期记忆各有载体
- 异常处理:幻觉检测、权限控制、熔断机制
这道题问的是Agent系统设计,我觉得本质上是问你怎么让大模型从一个只会聊天的对话者,变成一个能调用工具、能规划、能自我纠错的执行者。那我的核心思路是分层解耦,把推理、工具、记忆、执行拆成独立的模块,这样每一层都能独立演进和替换。
先说推理引擎。很多人上来就选ReAct或者Function Calling,但实际落地你会发现,没有一种范式能通吃所有场景。ReAct适合复杂推理,比如客服退款场景里,用户说“我买了东西但没收到,商家说发了,平台又让我找物流”,这种多轮、多实体、需要边思考边查的,ReAct的Thought-Action-Observation循环就很合适。但如果是结构化的任务,比如“查一下订单号123456的状态”,直接用Function Calling调API就完了,还走ReAct反而浪费token。所以我会设计一个意图分类器,根据任务复杂度自动路由,简单任务走Function Calling,复杂任务走ReAct,阈值可以调。
再说工具系统。我把它设计成动态注册加契约化描述。每个工具自己声明名字、描述、参数schema,用JSON Schema描述,LLM看到就能理解怎么用。这样新工具接入时不用改代码,注册一下就行。但这里有个坑:工具调用不能直接暴露给外部,必须隔离。比如执行层我会用沙箱,敏感操作比如写数据库或发消息,要额外鉴权。网络请求也要限流,防止工具被恶意调用。
记忆这块,我分了三级。工作记忆就是当前对话的上下文窗口,用Sliding Window加摘要压缩,保证不超长。短期记忆用Redis存最近N轮对话和提取的实体,支持会话内的状态恢复。长期记忆用向量库存用户画像,但不是简单存对话历史,而是定期让LLM反思生成摘要,比如“用户喜欢晚上购物,常买母婴类商品”,然后embedding存起来。这样下次对话可以直接检索相关画像,不用翻历史。
规划与自我修正方面,执行前我会把任务分解成子任务,生成依赖图,检查有没有循环依赖。执行中如果超时或异常,触发重规划,最多回溯三次。执行后成功或失败的样本入库,后面可以做SFT微调。
最后是异常处理。我特别关注三点:一是Hallucination检测,工具返回的结果和LLM生成的答案做一致性校验,用NLI模型打分,分数低就重试或降级。二是权限控制,工具打标签,read/write/dangerous,敏感操作要用户二次确认。三是熔断机制,单个工具失败率超过30%自动降级,切到备用方案。
其实还有一个方向我一直在想,就是多Agent协作。虽然目前单Agent为主,但比如代码生成加测试这种场景,一个Agent写代码,另一个Agent跑测试、写报告,天然适合拆开。不过多Agent的协调成本很高,对话轮次会指数增长,所以我会先做Agent内Reflexion,让单个Agent自己反思优化,而不是一上来就上多Agent。
所以整体上,我更倾向于把Agent系统看作一个可编程的执行框架,LLM是大脑,工具是手脚,记忆是便签,异常处理是安全气囊。每个部分单独看都不复杂,但合在一起要稳定、可扩展、能兜底,这才是设计的关键。
关键一句:多Agent协作的协调成本高,先做Agent内Reflexion自我反思,再考虑拆成多Agent。
面试官还可能这样问
- 问法 1 · 场景切入
假设你负责一个电商客服Agent,用户说‘帮我查一下订单,然后如果发货了提醒我’,这种多步任务你怎么设计系统来拆解和执行?
- 问法 2 · 层层追问
你设计Agent系统时,核心组件会怎么划分?……那这些组件之间怎么协作?……再具体点,比如工具调用和记忆管理,你用什么机制保证它们能灵活扩展?
- 问法 3 · 直球架构
设计一个大模型Agent系统,要涵盖规划、记忆、工具和执行四个核心能力,请给一个分层架构方案,并解释为什么选这个设计。