一句话版本:Planning & Reasoning 是让 AI Agent 从"接受指令执行"升级为"主动拆解目标、制定计划、边做边想、遇障碍能调整"的核心能力框架。
普世方法论
从"反射弧"到"前额叶"的范式转移
普通的 LLM 调用像脊髓反射——刺激进来,立即输出响应,没有中间状态。
带 Planning & Reasoning 的 Agent 像人类前额叶皮质——接到目标后,先在脑内推演多步,构建执行计划,执行中持续监控,遇到障碍重新规划。这就是为什么说 Agent 架构是「有意识地在执行」,而不是「有问必答」。
完整流程(一眼看懂)
三个核心概念
🧭 Planning(规划)
把大目标拆成有序的子任务序列。决定先做什么、后做什么、哪些可以并行。
🧠 Reasoning(推理)
在每一步执行前后进行判断:这一步做对了吗?下一步该怎么走?遇到矛盾信息如何取舍?
🔄 Loop Detection
发现 Agent 陷入重复执行同一步骤的无效循环,及时中断并重新规划。这是移动端尤其关键的能力。
📡 Context Window
上下文窗口是 LLM 每次调用能"看到"的信息上限。Planning 的很多设计决策都是为了不超出这个限制。
Planning & Reasoning 不是一个单一模块,而是分布在整个 Agent 生命周期里的能力层。下面从三个层次拆解它的工作机制。
第一层:目标理解与任务分解(Goal Decomposition)
用户说的话 ≠ Agent 要做的事
用户说"帮我把本周学习计划写进日历",但 Agent 实际需要做的是:解析日期范围 → 查询已有日历事件 → 根据空闲时间生成计划 → 格式化为日历条目 → 调用日历 API 写入。
这个"翻译过程"就是 Task Decomposition,是 Planning 的第一步。
{
"goal": "把本周学习计划写进日历",
"subtasks": [
{ "id": 1, "action": "解析本周日期范围", "depends_on": [] },
{ "id": 2, "action": "查询已有日历事件", "depends_on": [1] },
{ "id": 3, "action": "生成学习计划条目", "depends_on": [2] },
{ "id": 4, "action": "写入日历 API", "depends_on": [3], "fallback": "generate_pdf" }
]
}
第二层:执行中推理(In-context Reasoning)
每一步执行后都要"想一想"
Reasoning 不是一次性的前置动作,而是穿插在每个子任务之间的持续判断。标准的 ReAct 模式就是这样工作的:
关键:每次 Thought 不只是"下一步做什么",还包括"之前的结果是否符合预期、是否需要修正计划"。这就是 Belief Update。
第三层:异常处理与 Loop Detection
Agent 最怕两种情况:卡死 和 死转
🚫 卡死(Deadlock)
子任务 A 等待 B 的结果,B 又依赖 A 的输出。Agent 会一直等待,永远无法推进。
🔁 死转(Infinite Loop)
Agent 反复执行相同的操作,每次都以为自己在进步,但实际上原地打转。例如:反复查询同一个空结果。
Loop Detection 的实现方式:记录每一步的 action + input 指纹,如果在窗口期内出现 N 次重复,强制终止并触发 Re-Plan。
这个岗位要求懂 ReAct、Plan-and-Execute、Multi-Agent 三种模式。它们都是 Planning & Reasoning 的不同架构实现,但适用场景和权衡完全不同。
三种模式核心对比
| 模式 | 规划时机 | 适合场景 | 最大风险 | 典型框架 |
| ReAct |
每步实时推理,边做边想 |
短任务、交互式、需要动态响应 |
容易陷入局部最优,看不到全局 |
LangChain Agent |
| Plan-and-Execute |
先完整规划,再按序执行 |
长任务、步骤已知、需要整体一致性 |
前期规划错了,后面全部跑偏 |
LangGraph |
| Multi-Agent |
多个 Agent 各自规划各自负责域 |
复杂大任务、专业分工、并行执行 |
协调成本高,Agent 间信息不同步 |
CrewAI / AutoGen |
移动端的特殊约束
| 约束 | 对 Planning 的影响 | 解决思路 |
| 网络不稳定 | 工具调用可能中途失败 | 每个子任务设置超时和 Fallback 策略 |
| 算力受限 | 不能跑复杂的多步推理 | 端侧小模型做简单规划,复杂推理路由到云端 |
| 用户打断 | 任务执行中用户改变意图 | 支持 Plan 的暂停和修改,而不是全部重来 |
| 电量/内存 | 长链规划消耗资源 | 设置最大步数上限,超出后压缩计划 |
三个生活化类比,让你真正理解 Planning & Reasoning 的本质,而不只是记住名词。
类比一:外卖骑手 vs 高德导航
ReAct 模式
老司机骑手
凭经验在路口临时决策——这条路堵了就走旁边那条。每一步都是当下的最优判断,不需要提前规划全程。
↕ 对比
Plan-and-Execute 模式
高德导航规划路线
出发前先计算完整路径,包括预计到达每个路口的时间。中途如果检测到拥堵,会触发"重新规划"——这就是 Re-Plan 机制。
类比二:医生诊断 = Reasoning 过程
Agent Reasoning
病人描述症状
咳嗽 + 发烧 + 喉咙痛
Thought: 可能是流感或细菌感染
Action: 做个血常规检查(Tool Use)
Observation: 白细胞数量正常
Thought: 应该是病毒感染,不是细菌
Action: 开抗病毒药
= ReAct 的工作方式
关键对应
每个 Thought 都在排除可能性
Reasoning 的本质是基于证据缩小可能性空间。每次工具调用(检查)之后,Agent 根据结果更新自己对"当前情况"的判断,这叫 Belief Update。
如果血常规结果丢失(工具调用失败),医生会选择重新检查或换一种检测方式——这就是 Error Recovery。
类比三:厨师 vs 流水线工人
粗粒度规划
大厨做复杂菜
脑里有整道菜的画面,知道"炖汤要 2 小时、炒菜只要 5 分钟",所以先下锅炖汤,同时准备其他食材。这是并行规划——有依赖关系意识。
↕ 对比
细粒度规划
流水线工人
每次只执行分配的一个动作,不需要知道整体流程,执行速度快但没有全局意识。对应 Agent 里的单步 ReAct——快速但缺乏并行优化。
初学者和面试候选人最常犯的 5 个认知错误。这些错误在面试中很容易暴露,提前知道就是优势。
🔴 高频错误 #1
把 Planning 和 Prompt Engineering 混淆
以为写一个很长的 System Prompt 把步骤全列出来就是 Planning。但这只是"把计划硬编码进 Prompt",无法在运行时动态调整。
真正的 Planning 是运行时生成的结构化任务图,能根据执行结果动态修改子任务的顺序和内容。
🔴 高频错误 #2
认为 Reasoning 只发生在"想"的阶段
以为 Reasoning 就是 Chain-of-Thought,只是在生成答案时让模型"一步步思考"。忽略了 Reasoning 贯穿整个执行周期——包括对工具返回结果的解读和异常处理。
Observation → Thought 这个环节是最容易被忽视也是最重要的 Reasoning 节点,它决定了 Agent 是否能从错误中恢复。
🟡 中频错误 #3
Loop Detection 只检查"相同输出"
只比较 Agent 输出的文字是否重复,而不检查行为是否重复。比如每次输出的文字稍有不同,但都在调用同一个工具查同一个数据——这是语义上的死循环,字面检查检测不到。
需要对 (action_type, normalized_input) 做哈希指纹比较,而不是对原始文本做字符串匹配。
🟡 中频错误 #4
把 Multi-Agent 当作 Planning 的升级版
认为"任务复杂了就上 Multi-Agent",但实际上 Multi-Agent 主要解决的是专业分工问题,而不是规划复杂度问题。
先问"这个任务需要真正的专业分工吗?"——如果不需要,单 Agent 配合 Plan-and-Execute 就足够。
🟢 偶发错误 #5
认为 Re-Plan 越频繁越好
以为"发现问题就重新规划"是最可靠的策略。但每次 Re-Plan 都意味着上下文重建和 LLM 调用,在移动端成本极高。
Re-Plan 应该设置触发阈值:只有执行失败率超过阈值、或遇到计划外的重大变化时,才触发全局 Re-Plan。小偏差用局部修复。
用 Speakeasy 语言学习 App 作为主战场,把三种模式落地到真实需求里。Speakeasy 项目
1
场景:用户说"帮我解释一下刚才这句话哪里语法错了"
这是一个短交互任务,推荐用 ReAct 模式。
Thought: 需要识别语法错误
→
Action: 调用语法分析工具
→
Observation: 返回错误位置
→
Thought: 如何解释最易懂?
→
Action: 生成解释 + 例句
整个流程 2-3 步,无需复杂规划。关键是 Reasoning 质量——"如何解释最易懂"这个判断需要结合用户的历史学习记录。
2
场景:用户说"帮我制定一个月的英语学习计划,写进我的日历"
这是一个长任务,推荐用 Plan-and-Execute 模式。
Plan: 拆解为 5 个子任务
→
查询当前词汇水平
→
查询本月空闲时间段
→
生成个性化计划
→
写入日历 API
→
验证写入结果
{
"plan_id": "speakeasy_monthly_plan_001",
"status": "executing",
"tasks": [
{ "id": 1, "status": "done", "result": "B2 level" },
{ "id": 2, "status": "done", "result": "17 available slots" },
{ "id": 3, "status": "running" },
{ "id": 4, "status": "pending", "fallback": "generate_pdf" }
]
}
用户说"帮我找到我上周没完成的练习",但用户上周根本没做过任何练习。
查询上周练习记录
→
Observation: 空结果
→
Thought: 也许是查询条件问题
→
扩大时间范围再查
→
仍然空
→
⚠️ Loop Detected!
function detectLoop(actionHistory, windowSize = 3) {
const recent = actionHistory.slice(-windowSize);
const fingerprints = recent.map(a =>
`${a.tool}:${JSON.stringify(a.normalized_input)}`
);
return fingerprints.some((f, i) => fingerprints.indexOf(f) !== i);
}
用法:三问深挖是最快建立"真理解"的方式。每次看到一个概念,连续问三次"为什么",直到触底——触底的地方就是你真正需要记住的核心原理。
为什么 Agent 需要 Planning?
概念基础
W1
为什么需要 Planning?
因为复杂任务无法在一次 LLM 调用中完成
用户的很多真实需求需要 5-10 个步骤:查询数据 → 处理数据 → 调用外部 API → 验证结果 → 格式化输出。单次调用只能生成文字,无法真正执行这些操作。
W2
为什么不能把所有步骤写进一个 Prompt 让模型一次完成?
因为每个步骤的输入依赖上一步骤的运行时结果,而这些结果在 Prompt 写作时是未知的
你无法在写 Prompt 时就知道"日历查询会返回什么空闲时间段"——这是一个运行时才能知道的值。所以必须把执行拆成有状态的多步,每步等待真实结果再决定下一步。
W3
为什么 LLM 不能自己记住上一步的结果?
因为 LLM 本质上是无状态的——每次调用都是全新的,它没有跨调用的持久内存
LLM 不是一个持续运行的程序,它是一个每次接收完整上下文、输出一段文字的函数。"记忆"这件事必须由调用方(Agent 框架)维护,把每步结果手动拼进下一次调用的 Context 里。这就是为什么 Agent 框架要管理状态。
Planning 存在的根本原因是:LLM 无状态 + 任务有状态 → 必须由外部框架在多次调用之间维护状态和协调顺序。Planning 就是这个协调机制的设计。
为什么 ReAct 比直接调用 LLM 效果好?
模式理解
W1
为什么 ReAct 效果更好?
因为它让模型能根据工具的真实返回结果来修正自己的行为
直接调用 LLM 时,模型只能基于训练数据"猜"答案。ReAct 让模型先行动、再观察、再推理,用真实世界的反馈来纠正错误方向。
W2
为什么模型不能一次就预测出正确的行动序列?
因为现实环境是不确定的——工具可能失败、数据可能不存在、外部状态随时在变
就算模型训练时见过类似任务,它也无法预知"用户的日历里具体有哪些事件"、"今天的天气"、"某个 API 是否可用"。这些都是只有在运行时才能知道的信息。
W3
为什么 LLM 的训练数据无法覆盖运行时的真实情况?
因为训练数据是过去的静态快照,而现实世界是实时动态变化的
LLM 的训练截止日期意味着它对之后发生的任何事情一无所知。更根本的是,即便是训练时包含的信息,也是"世界的一般规律",而不是"你个人账户里今天有什么"。ReAct 通过工具调用把 LLM 的通用能力和运行时的私有/实时数据连接起来,这才是它真正的价值。
ReAct 本质上解决的不是"让模型更聪明"的问题,而是"让模型能接触到自己不知道的信息"的问题。工具调用是 LLM 与真实世界之间的接口。
为什么 Loop Detection 在移动端特别关键?
移动端专题
W1
为什么 Loop Detection 在移动端格外重要?
因为移动端的工具调用失败率远高于服务器端,失败本身就是死循环的主要触发器
网络抖动、API 超时、权限不足……这些在服务器端很少见的情况,在移动端是家常便饭。每次工具调用失败,Agent 都会"以为自己还没完成任务"而继续重试,极易陷入重试死循环。
W2
为什么工具调用失败会导致 Agent 重试而不是报错退出?
因为 Agent 的 Reasoning 逻辑会把"工具返回空/错误"解读为"任务尚未完成",而不是"环境出了问题"
Agent 没有"这是网络问题"的概念,它看到的只是"我想查的数据没拿到"。它的 Reasoning 会产生"可能是查询条件不对,换一种方式试试"的 Thought,这在有数据时是正确行为,但在数据根本不存在时就会无限循环。
W3
为什么 Agent 不能区分"数据不存在"和"网络出了问题"?
因为从 Agent 的视角,两者都表现为"工具返回了空结果或错误码"——Agent 看不到底层的网络层
Agent 工作在语义层(我想查日历数据),网络错误发生在传输层(TCP 超时)。工具调用的封装把底层错误翻译成了语义层的"查询失败",Agent 无法区分是"真没数据"还是"网络挂了"。解决方案是在工具层加上结构化的错误码(ERR_NETWORK vs ERR_NOT_FOUND),让 Reasoning 层能做出不同的决策。
Loop Detection 的底层问题是:Agent 的 Reasoning 缺乏对"环境层错误"的感知。长期解决方案不只是检测死循环,而是给工具调用加入丰富的错误语义,让 Agent 能做出更准确的 Belief Update。
为什么 Belief Update 是 Reasoning 最核心的机制?
推理本质
W1
为什么说 Belief Update 是核心?
因为 Reasoning 的所有决策都建立在"当前 Belief"之上——Belief 错了,后续所有推理都会跑偏
Agent 的每一个 Thought("下一步应该做什么")本质上是:基于我对当前世界的理解(Belief),选择最优行动。如果 Belief 不准确,这个推理过程再严密也没用——垃圾进垃圾出(Garbage in, Garbage out)在 Agent 里的体现就是 Belief 错误。
W2
为什么 Belief 容易出错?
因为工具返回的数据是"原始的",需要 Agent 自己解读——而解读过程正是幻觉产生的地方
工具返回 {"duration": 60},Agent 需要判断这是60秒还是60分钟。工具返回空数组,Agent 需要判断这是"数据不存在"还是"查询条件有问题"。每次解读都可能出错。LLM 的天性是"合理推断"而不是"谨慎确认",在不确定时容易填充错误的 Belief。
W3
为什么 LLM 会"合理推断"而不是"谨慎确认"?
因为 LLM 是在"预测最可能的下一个 token"——而不是在"确认事实真相";它的训练目标是流畅合理,不是精确准确
训练 LLM 的目标函数是"预测下一个 token 的概率分布"——让输出看起来自然、合理。这和"确保每个事实都有来源"是完全不同的目标。在歧义情况下,LLM 自然倾向于给出"听起来最合理的解读"而不是"承认不确定性"。这是它的本性,不是 bug。解决方案是在工具返回值层面消除歧义,而不是期待 LLM 自己变谨慎。
这个三问的底层洞察是:幻觉问题的根源不在"模型不够聪明",而在"数据接口不够语义化"。提升 Belief 准确性最有效的方法,是在工具返回值里消除歧义(加单位、加错误类型、加语义注释),而不只是在 Prompt 里要求模型"要谨慎"。
为什么工具调用需要幂等性?这和 Agent 架构有什么关系?
工程可靠性
W1
为什么 Agent 的工具调用需要幂等性?
因为在网络不稳定的环境下,Agent 无法确认一次调用是否真的成功,会进行重试——如果工具不幂等,重试就会产生重复副作用
正常的 API 调用失败了,人类会知道"上次没成功,这次重试"。但 Agent 的情况更复杂:调用可能"发出去了但没收到确认"——这时候 Agent 不知道调用有没有生效,重试可能导致操作被执行了两次。
W2
为什么 Agent 不知道"发出去了但没收到确认"这种情况?
因为从 Agent 的视角,"超时"和"没执行"看起来完全一样——都是没有收到返回结果
工具调用超时时,Agent 看到的就是"等了3秒,没有任何返回"。它无法区分"工具服务器根本没收到请求"和"工具服务器收到了请求并执行了,但回复在网络上丢失了"。唯一安全的处理方式就是重试,但重试必须以幂等性为前提。
W3
为什么这个问题在移动端特别严重?
因为移动端的网络是"断断续续"的,不是"全通或全断"——最容易出现"发出去了但回复没收到"这种中间状态
WiFi 切换到 4G 的瞬间、地铁进隧道的瞬间、手机从后台切回前台的瞬间——这些都是网络中断的高发时刻,正好可能发生在工具调用的"等待回复"阶段。这不是偶发情况,是移动端的常态。因此幂等性在移动端 Agent 里是必须而不是可选的设计。
幂等性表面上是一个工具层的工程问题,但它深刻影响 Agent 的可靠性。一个没有幂等性保证的 Agent,在移动端环境下必然会出现重复创建数据的问题——而用户不会原谅"帮我创建了3个相同的日历事件"这种低级错误。
为什么 Multi-Agent 比单 Agent 更难控制?
架构权衡
W1
为什么 Multi-Agent 更难控制?
因为每个 Agent 都有自己的 Belief 和决策逻辑,多个 Belief 之间可能产生矛盾,而协调这些矛盾需要额外的机制
单 Agent 只有一套 Belief——世界在它眼中是统一的。Multi-Agent 中,Agent A 认为"任务3已完成",Agent B 认为"任务3还在进行中",这种 Belief 不同步会导致重复执行、冲突写入、决策矛盾。
W2
为什么多个 Belief 之间容易不同步?
因为 Agent 之间的通信是异步的——一个 Agent 更新了状态,其他 Agent 不会立刻知道
这和分布式系统里的"一致性问题"完全一样:多个节点各自维护状态,节点间通信有延迟,在任意时刻,不同节点看到的"系统状态"可能不一致。Multi-Agent 本质上就是把分布式系统的全部难题带进了 Agent 架构。
W3
为什么分布式一致性在 Agent 里比在普通系统里更难解决?
因为普通分布式系统用严格的协议(如两阶段提交)保证一致性,但 Agent 的行为是 LLM 生成的——LLM 不能像数据库那样提供事务保证
数据库可以用"锁"来防止并发冲突;Agent 的"决策"是 LLM 生成的自然语言,没有原子性,没有回滚机制(LLM 不能"撤销"一个已经生成的决策)。这就是为什么 Multi-Agent 的协调器(Orchestrator)需要精心设计:它不能依赖 Agent 自己保证一致性,必须在外层强制施加约束。
Multi-Agent 把分布式系统的难题(一致性、并发控制、故障恢复)和 LLM 的不确定性(生成是随机的、不可精确控制)叠加在了一起。这解释了为什么"Multi-Agent 看起来很强大,实际上生产落地非常困难"——这两个挑战单独处理都很复杂,叠加在一起就是指数级的复杂度。
这个 Tab 专门为新手设计。下面列出的不是技术细节,而是"第一次接触 Agent 架构时,脑子里最容易形成的错误画面"。每一条都点开看看,确认自己没有这个误解。
5 个新手最常见的错误心智模型
❌ 错误认知 #1
"Agent = 一个特别聪明的聊天机器人"
▾
✅ 正确认知
Agent 是一个能自主执行操作、改变外部世界状态的系统,聊天只是它的一种交互方式
聊天机器人的本质是"输入文字 → 输出文字",它不会真的帮你把事情做了。Agent 的本质是"接收目标 → 调用工具 → 改变外部状态"——比如真的帮你在日历里创建了事件、真的发出了一封邮件、真的在代码仓库里提交了一个 PR。
这个区别决定了 Agent 架构的所有复杂性:一旦能改变外部世界,就需要考虑权限、回滚、错误处理、幂等性……这些都是聊天机器人不需要考虑的问题。
Speakeasy 里如果只是"生成一个学习建议",那是聊天机器人。但如果是"把这个建议写进你的日历,并且明天提醒你",那就是 Agent——它真的修改了你的日历数据。
❌ 错误认知 #2
"Planning 是在开始前做的,做完就不用管了"
▾
✅ 正确认知
Planning 是持续的——执行中随时可能需要修改计划
很多人把 Planning 理解成项目启动前的"需求分析"——做一次就定了。但真实的 Agent 执行环境充满了不确定性:API 返回了意外的数据、用户中途改变了要求、某个子任务比预期耗时更长……这些都需要实时修正计划。
更精确的理解是:Planning = 维护一个随时可以被修改的"活的任务图",而不是一张写死的流程图。
就像做饭时发现冰箱里没有计划中的食材,你不会"放弃做饭",而是调整菜谱。Agent 的 Re-Plan 就是这个动态调整的能力。
❌ 错误认知 #3
"LLM 有记忆,上次对话的内容它还记得"
▾
✅ 正确认知
LLM 完全无状态——每次调用都是全新的,"记忆"是由调用方手动传入的
这是最反直觉的一个认知:当你在 ChatGPT 里和它聊天,感觉它"记住了"你说过的话,实际上是因为每次你发消息时,整个对话历史都被偷偷塞进了这次调用的 Prompt 里。
对 Agent 框架来说,这意味着:每次调用 LLM 时,开发者必须手动决定"把哪些上下文塞进这次的 Prompt"。塞太多:超出 Context Window 限制,报错。塞太少:LLM 不知道之前发生了什么,做出错误判断。这就是 Context Window 管理的核心挑战。
Speakeasy 里,如果用户说"继续我上周没做完的练习",Agent 并不是"记住了"上周的练习——而是框架把上周的练习记录从数据库查出来,拼进了这次 LLM 调用的 Prompt 里。
❌ 错误认知 #4
"工具调用就是调用函数,很简单"
▾
✅ 正确认知
工具调用是 Agent 与外部世界的接口,需要处理权限、失败、幂等性、结果解读等一系列复杂问题
函数调用只需要"调用成功/抛异常"两种状态。但工具调用面临的现实情况是:
• 权限问题:Agent 有权限调这个工具吗?
• 幂等性:如果调用了两次(因为第一次超时),会重复创建数据吗?
• 结果解读:API 返回了 200 但数据是空的,Agent 应该认为"成功了但没数据"还是"调用失败了"?
• 副作用:这个工具调用会不会产生用户不知情的后果?
这就是为什么岗位要求专门的"工具调用规范设计"能力。
Speakeasy 里调用日历写入 API 时,如果网络超时、Agent 重试,就可能创建两个相同的日历事件。需要在工具层实现幂等性(比如先检查是否已存在)。
❌ 错误认知 #5
"Agent 越自主越好,让它自己做决定就行"
▾
✅ 正确认知
自主性和可控性需要精心平衡——过度自主的 Agent 会在用户不知情的情况下做出破坏性的操作
Agent 架构里有一个基本原则叫做"人类在回路"(Human-in-the-Loop):越是不可逆的操作(发邮件、删文件、转账),越需要在执行前请求用户确认,而不是 Agent 自己判断。
新手的本能是"让 Agent 更聪明、更自主",但经验丰富的架构师想的是"在哪些节点需要暂停和确认、如何设计回滚机制"。这两种思维模式的差距就是这个岗位在选拔的东西。
Speakeasy 里,Agent 帮你生成学习计划是低风险的(随时可以改);但如果 Agent 要"自动取消你明天的会议来给学习腾出时间",这就是高风险操作,必须先问你。
新手必须补的三个前置概念
📦 Context Window 是什么
LLM 每次调用能"看到"的最大 token 数量。超出了就会被截断或报错。Agent 框架的很多设计都是在管理这个限制。
🔑 Token 是什么
LLM 处理文字的基本单位,大约 1 个中文字 = 1-2 个 token,1 个英文单词 ≈ 1-1.5 个 token。Context Window 的大小以 token 计。
🗃️ State Machine 是什么
描述系统在不同"状态"之间如何转移的模型。LangGraph 就是把 Agent 的执行流程建模为状态机,每个节点是一个状态,边是条件转移。
🧩 幂等性 是什么
一个操作执行一次和执行多次的效果相同。对 Agent 的工具调用极重要——网络重试时不能产生重复副作用。
5 道测验,验证你是真的理解了还是只是看完了。点击选项后会立即显示解析。
Q1. 用户要求"帮我规划本周所有会议并自动发送会议邀请",最适合哪种 Agent 模式?
B
Plan-and-Execute,因为任务步骤明确且需要整体一致性
D
直接用 Prompt Engineering 列出步骤就够了
Plan-and-Execute 最合适:这个任务的步骤是确定的(查会议→排日程→发邀请),需要整体一致性,中途如果邀请发送失败要能局部重试。ReAct 会让每步都"想一下",对这种确定性任务太低效。
Q2. ReAct 模式的核心循环是?
A
Thought → Action → Observation → Thought…
B
Plan → Execute → Review → Plan…
C
Input → Process → Output
D
Query → Retrieve → Generate
ReAct(Reasoning + Acting)的核心贡献是把推理和行动交替进行,每次行动后观察结果,再用结果指导下一次推理。B 是 Plan-and-Execute 的逻辑,C 是普通 LLM 调用,D 是 RAG。
Q3. Loop Detection 应该基于什么进行检测?
C
检测 (工具名 + 标准化输入) 的组合是否在窗口期内重复出现
A 太宽松(文字稍变就检测不到);B 会误杀正常的长任务;D 只是性能监控,不是逻辑检测。正确做法是检测行为指纹重复——同一工具用相似的输入参数被反复调用,才是真正的死循环信号。
Q4. 根据"三问深挖"的分析,LLM 在 Agent 框架里"记住上一步结果"的真实机制是什么?
A
LLM 有内置的短期记忆模块,自动记住最近的调用
C
Agent 框架把上一步的结果手动拼接进下一次调用的 Prompt/Context 里
LLM 完全无状态。所谓"记住",是 Agent 框架维护了一个状态对象,每次调用 LLM 时把相关状态塞进 Prompt 里。这就是为什么 Context Window 的管理是 Agent 架构的核心挑战之一——放太多历史就会超出限制,放太少就会让 LLM 做出错误判断。
Q5. 为什么说"给 System Prompt 写很详细的步骤列表"不等于实现了 Planning?
A
因为 System Prompt 太长会影响模型理解
B
因为静态步骤列表无法在运行时根据执行结果动态调整任务图
C
因为 Planning 必须用代码实现,不能用自然语言描述
Planning 的核心价值是"运行时自适应":步骤 3 失败了,Planning 模块能跳过或用备选方案替代;发现新的前置条件,能插入新子任务。而 System Prompt 里的步骤是写死的——这本质上还是没有 Planning 的"精心设计的单次调用"。
ReAct、Plan-and-Execute、Multi-Agent 不是凭空设计出来的——每种模式的诞生都是为了解决前一种模式暴露出的具体问题。理解这条演进脉络,才能真正懂"什么时候用哪个"。
三种模式的诞生背景
2022 · Google Brain
ReAct
Reasoning + Acting · 论文:《ReAct: Synergizing Reasoning and Acting in Language Models》
2022年之前,LLM 有两条平行路线:CoT(只推理,不行动)和 Tool-use(只行动,不推理)。两者都有严重缺陷——CoT 产生幻觉,Tool-use 缺乏灵活性。
把推理和行动交织在一起——每次行动前先显式推理(Thought),行动后把观察结果(Observation)喂回推理链,形成闭环。这让模型既能使用工具,又有自我纠错能力。
为什么是突破
之前的工具调用是"盲打"——模型不知道为什么调用这个工具,也不会根据结果修正行为。ReAct 第一次让模型能"看着结果继续想"。
遗留的问题
ReAct 每一步都在"摸黑走路"——缺乏全局视野,容易陷入局部最优,长任务中会累积推理偏差,而且每步都要调用 LLM,成本很高。
2023 · LangChain Labs
Plan-and-Execute
先规划再执行 · 论文:《Plan-and-Solve Prompting》+ LangGraph 工程实现
ReAct 在长任务上失控:每步只看当前情况,第10步的决策可能和第1步的规划完全矛盾;而且步骤越多,幻觉累积越严重。
分离"规划"和"执行"两个阶段:第一阶段用 LLM 生成完整任务图(只调用一次),第二阶段按任务图执行(执行时不频繁调用 LLM)。整体一致性大幅提升,成本也更低。
关键洞察
人类做复杂工作时,会先写项目计划,再按计划执行——而不是每隔10分钟问一次"我现在应该做什么"。Plan-and-Execute 把这个常识带入了 Agent 设计。
遗留的问题
单个 Agent 的能力上限受 Context Window 和专业深度限制。当任务跨越多个专业域(代码 + 搜索 + 数据分析同时需要)时,单 Agent 很难做好所有事。
2023–2024 · 社区 + 学术
Multi-Agent
AutoGPT 引爆 → CrewAI 规范化 → AutoGen / LangGraph 工程化
单 Agent 处理跨领域复杂任务时,要么 Context Window 撑不住,要么一个"全才 Agent"的 Prompt 过于复杂、表现不稳定。同时,某些任务天然可以并行处理,串行执行太慢。
把一个大任务拆给多个专职 Agent 并行处理——每个 Agent 只做自己擅长的事,一个 Orchestrator 负责协调。理论上无限扩展,实践上需要精心设计通信协议。
历史节点
2023年3月:AutoGPT 开源,Multi-Agent 概念爆炸式传播,但工程质量差,大量失控案例。
2023年下半年:CrewAI 用"角色扮演"简化了 Multi-Agent 的配置,降低了使用门槛。
2024年:AutoGen(微软)、LangGraph 提供了更成熟的工程框架,解决了早期的协调混乱问题。
至今未完全解决的问题
Agent 之间的信息同步、任务边界的划定、Orchestrator 的失控风险——这些问题在生产环境中仍然很棘手。Multi-Agent 至今仍是"最强但最难用好"的模式。
深度决策矩阵
不同维度下三种模式的表现
短任务(<5步)
✓ 最优
可以,但浪费
过度设计
长任务(10步+)
容易偏航
✓ 最优
可以,成本高
LLM 调用次数
每步都调用
主要1次规划
多 Agent × 各自调用
动态响应能力
✓ 最强
Re-Plan 才能调整
依赖 Orchestrator
调试难度
每步可见,易追踪
任务图清晰
跨 Agent 难追踪
选型口诀:任务步数少用 ReAct,步骤已知用 Plan-Execute,真正需要专业分工并行才上 Multi-Agent。90% 的移动端 Agent 场景,前两种就够了。
AI 推理能力的发展不是一蹴而就的,而是在一次次"模型做不到 X"的挫败中,研究者找到了一个又一个突破口。这条演进线索能帮你理解每个技术为什么存在。
推理能力演化时间线
2017
Transformer 出现 —— 记忆力强,但不会"推理"
Attention Is All You Need 论文发布。Transformer 架构让模型能处理长文本、做翻译、做摘要,但本质上是模式匹配——记住了大量文本中的统计规律,不是真正的步骤推理。
给它一道多步数学题,它会胡乱猜一个答案,经常错。
📄 Vaswani et al., "Attention Is All You Need"
2020
GPT-3 —— Few-shot 涌现,但推理仍弱
1750亿参数的 GPT-3 第一次展现了涌现能力(Emergent Ability)——给几个例子,它能推广到新情况。但多步推理仍然很差:问"Mary 有 3 个苹果,给了 John 1 个,再买了 2 个,现在有几个"这类题,它经常出错。
关键洞察:Scale(规模)带来了新能力,但没有自动带来推理能力。
2022 Q1
Chain-of-Thought —— 让模型"先想再说"
Google Brain 的研究者发现:在 Prompt 里加一句 "Let's think step by step",或者给出几个"先推理再给答案"的例子,模型在多步推理任务上的准确率大幅提升。
这是第一次发现:推理过程本身对模型来说就是"上下文"——把中间步骤写出来,后续生成的 token 质量会更好。
📄 Wei et al., "Chain-of-Thought Prompting Elicits Reasoning in LLMs"
本质发现:LLM 生成 token 时是"自回归"的——后面的词依赖前面的词。把推理步骤显式生成出来,等于为最终答案提供了更好的"中间跳板"。
2022 Q3
ReAct —— 推理 × 行动的第一次结合
CoT 的局限:模型只能"想",不能"做"。推理链里如果需要查一个真实数据,模型会编造一个。ReAct 把 CoT 和工具调用结合:Thought(推理)→ Action(调用工具)→ Observation(看结果)→ Thought(基于真实结果继续推理)。
第一次让推理有了真实世界的锚点,幻觉大幅减少。
📄 Yao et al., "ReAct: Synergizing Reasoning and Acting in LLMs"
2023 Q1
GPT-4 + Function Calling —— 工具调用标准化
OpenAI 在 GPT-4 API 里引入了 Function Calling:开发者可以把工具定义为结构化的 JSON Schema,模型能可靠地输出"调用哪个函数、参数是什么"的结构化指令,而不是在自然语言里夹带工具调用。
这是工具调用从"实验"走向"工程"的关键节点——准确率从约70%提升到95%+。
为什么 Function Calling 这么重要?
之前的工具调用依赖 LLM 在文本里写 [TOOL: search, query: xxx] 这样的标记,然后用正则解析——极不稳定。Function Calling 让模型直接输出结构化 JSON,可靠性质变。这才让生产级 Agent 成为可能。
2023 Q2
AutoGPT 爆红 —— Multi-Agent 的第一次大众化
AutoGPT 让 Agent 自主分解任务、调用工具、甚至创建子 Agent。GitHub star 在一周内突破10万。但随之而来的是大量失控案例:Agent 陷入死循环、创建无数无意义文件、一个任务花了几百美元 API 费用……
AutoGPT 证明了 Multi-Agent 的潜力,也暴露了缺乏 Loop Detection、成本控制、人类监督的严重后果。
这次"爆红 + 翻车"推动了整个领域对 Agent 安全性、可控性的重视。Loop Detection、Token Budget、Human-in-the-Loop 这些概念因此被写进了生产标准。
2023 下半年
LangGraph / CrewAI —— Agent 编排工程化
LangGraph 用有向图(DAG)建模 Agent 的执行流程,让 Plan-and-Execute 有了可靠的工程实现。CrewAI 用"角色扮演"简化了 Multi-Agent 的配置,让非专业工程师也能搭 Agent 团队。
这是 Agent 从"玩具"走向"可落地产品"的分水岭。
2024
OpenAI o1 —— 推理作为"内置计算"
o1 模型的核心创新:在输出最终答案前,在模型内部运行大量的"思维 token"(不对用户展示)。本质上是把 CoT 从 Prompt 层移进了模型的训练目标里——模型被强化训练来花时间推理,而不是直接猜答案。
这改变了 Agent 的设计假设:以前需要通过 ReAct 循环来增强推理,现在模型本身就能更深入地推理,单次调用的质量大幅提升。
o1 对 Agent 架构的影响
高推理质量的模型让"每步都要 Thought 节点"的 ReAct 开销下降——单步就能做出更好的判断。但也带来了新问题:推理 token 成本更高,移动端端侧部署更难。
2024–2025
端侧推理 —— Reasoning 走向移动端
Llama-3-8B、Phi-3-mini、Gemma-2B 等小模型的推理能力大幅提升,使得移动端本地运行 Agent 成为可能。苹果 Apple Intelligence、高通 AI Hub 推动端侧 LLM 成为手机标配。
这正是这个岗位要解决的核心工程问题:如何在端侧有限算力上实现完整的 Planning & Reasoning 闭环,以及何时把任务路由到云端。
技术演进的方向越来越清晰:大模型负责"深度推理",小模型负责"快速响应",Agent 框架负责"智能路由"。这就是端云协同架构的理论基础。
这个 Tab 来自真实生产踩坑。下面每个问题在论文里都找不到标准答案,但在生产 Agent 系统里是高频必踩的坑。每个问题都有具体的解决方案和代码思路。
高危问题(直接影响用户体验)
🔴 高危
上下文爆炸 —— Agent 在执行第 8 步时突然报错
一个 15 步的学习计划任务,前 7 步正常,第 8 步开始 LLM 返回错误或者质量急剧下降。原因:前面每步的结果都被塞进 Context,累积下来已经超出了 Context Window 限制。
方案 1 · 滚动摘要
每步执行后压缩历史
不把原始结果塞进 Context,而是每步执行后生成一句话摘要。例如"步骤2完成:查到用户本月有17个空闲时段",而不是把整个 API 返回塞进去。节省80%+ token。
方案 2 · 外部状态存储
只传"当前步骤需要的"进 Context
把中间结果存进本地数据库。每次 LLM 调用时,只从数据库取出当前步骤真正需要的字段。就像 SQL 查询只选需要的列,而不是 SELECT *。
方案 3 · Context Budget 预算制
提前计算 token 用量,超阈值触发压缩
在 Plan 生成阶段就预估每步的 token 消耗,设置总预算(如 80K tokens)。每步执行前检查剩余预算,不足时触发历史压缩。
🔴 高危
工具调用幻觉 —— Agent 调用了根本不存在的工具
Agent 的 Thought 里写着"我需要调用 translate_and_save 工具",但这个工具根本没有在工具列表里定义。LLM 编造了一个听起来合理的工具名,然后卡在等待这个工具的返回值。
方案 1 · 工具名白名单验证
解析 LLM 输出时做严格校验
在工具调用解析层加入白名单校验:如果 LLM 输出的工具名不在已注册的工具列表里,立即拒绝并触发 Fallback,而不是尝试执行。这比 "try/catch" 更主动。
方案 2 · Prompt 里精简工具描述
工具越少越好,描述越精准越好
每个工具的描述要极度精确——什么时候不该用它,和什么时候该用它一样重要。工具太多时,分批提供给不同步骤,而不是把所有工具一次性塞进 Prompt。
方案 3 · 使用 Structured Output
强制 LLM 从固定枚举中选择工具
用 Function Calling 的 enum 约束工具名字段,让模型只能从预定义的工具名里选,而不是自由填写字符串。这从根本上消灭了工具名幻觉。
中危问题(影响可靠性)
🟡 中危
规划不稳定 —— 同一个任务,每次生成的 Plan 差异很大
用户两次输入"帮我制定本周学习计划",第一次 Agent 生成了5步计划,第二次生成了3步,而且步骤名称和顺序都不一样。导致下游系统难以稳定处理。
方案 1 · Plan Schema 约束
用 JSON Schema 限制规划输出格式
要求 LLM 以固定的 JSON 结构输出 Plan,包括步骤 ID、步骤类型(从枚举中选)、依赖关系、预期输出格式。格式固定后,内容虽然不同,但下游能稳定处理。
方案 2 · Plan Validation 验证层
Plan 生成后自动验证合理性
生成 Plan 后,用规则引擎检查:步骤数是否在合理范围内?依赖关系有没有循环?必要的步骤(如最终输出步骤)是否存在?验证失败则重新生成,最多3次。
方案 3 · 模板 + LLM 填充
预定义任务模板,LLM 只填变量
对高频任务类型(制定学习计划、错题复习等)预定义好步骤框架,让 LLM 只填充具体参数(时间范围、词汇难度等)。稳定性从70%提升到95%+。
🟡 中危
成本失控 —— 一个用户请求花了 $2 的 API 费用
用户说"帮我分析一下我的学习情况",Agent 生成了一个20步的超详细分析计划,每步都调用大模型,加上 Context 越来越大,一个请求花了30秒、$2 的 API 费用。
方案 1 · Token Budget 硬上限
每个请求设置最大 token 预算
在 Agent 启动时设置本次任务的 token 预算(如 20K tokens)。框架层监控每次 LLM 调用的 token 消耗,接近上限时强制压缩 Context 或停止规划,确保不超限。
方案 2 · 模型分级路由
简单步骤用小模型,复杂步骤用大模型
格式化输出、简单查询 → Haiku/Gemma-2B(成本1/20)。复杂推理、最终生成 → Sonnet/GPT-4o。这一策略通常能把整体成本降低60-70%,同时保持质量。
方案 3 · 步骤数量上限
Plan 的步骤数设上限
在 Plan 生成的 Prompt 里明确约束:"计划不超过7个步骤"。同时在 Plan Validation 里拒绝超过上限的 Plan。这是最简单但非常有效的成本控制手段。
🟢 低危
Observation 解读偏差 —— 工具返回了正确数据,但 Agent 理解错了
日历 API 返回了 JSON 格式的事件列表,但 Agent 把"duration: 60"(分钟)理解成了60秒,导致后续的时间计算全部错误。数据是对的,但 Agent 的理解是错的。
方案 · 工具返回值语义化
返回值加入单位和说明
工具的返回值不只是数据,还要包含字段说明。例如不返回 "duration": 60,而是返回 "duration_minutes": 60, "_note": "duration is in minutes"。让 LLM 不需要猜测单位。
使用方法:先自己想10秒再点开答案。每道题都标注了难度和"常见失误"——失误往往比答案本身更值得记。
基础题 —— 考察概念清晰度
基础
ReAct 和普通 Chain-of-Thought 的本质区别是什么?
▾
回答框架(三点)
1
闭环 vs 开环:CoT 是一次调用内的线性推理,推理完就输出答案,无法获取外部信息;ReAct 是跨多次调用的循环,每次 Action 后会把真实的 Observation 反馈回推理链。
2
工具调用:CoT 只能推理训练数据里有的知识,遇到需要实时数据或私有数据时只能幻觉;ReAct 通过工具调用获取真实数据,从根本上减少幻觉。
3
状态维护:CoT 没有状态,推理结束就结束;ReAct 需要维护 Action 历史和 Observation 历史,让每次 Thought 都能"看到"之前发生了什么。
只说"ReAct 多了行动能力"——这只答到表面。面试官想听到的是"Observation 反馈进 Thought 这个闭环",以及"这才是减少幻觉的真正机制"。
基础
什么情况下你会选 Plan-and-Execute 而不是 ReAct?
▾
回答框架(场景判断法)
1
任务步骤可预知时:如果任务的大致步骤在开始前就能确定(比如"制定月度计划"永远是 查状态→生成方案→写入系统 这个流程),Plan-and-Execute 能在计划阶段把整体一致性保证好。
2
长任务防止累积偏差:ReAct 在10步以上的任务里,每步的小偏差会累积,到后面可能和最初目标偏离很远。Plan-and-Execute 有全局视图,更容易保持一致性。
3
成本控制:ReAct 每步都要调用 LLM 推理;Plan-and-Execute 主要在 Plan 生成时调用一次,执行阶段调用次数少很多,总成本可以低30-50%。
只说"任务复杂就用 Plan-and-Execute"——这没有说出真正的判断标准。关键词是"步骤可预知"和"需要整体一致性",不是"复杂度高"。
中级题 —— 考察深度理解
中级
Loop Detection 如果只检测"输出文字相同"会有什么问题?正确的检测方式是什么?
▾
回答框架
1
字面检测的漏洞:Agent 可能每次输出略有不同的文字("我需要再查一次用户数据" vs "让我重新查询用户信息"),但执行的是完全相同的工具调用。字面检测会认为这是两个不同操作。
2
正确方式 —— 行为指纹:提取 (tool_name + normalized_input_params) 作为行为指纹,对参数做标准化处理(去除时间戳、随机 ID 等随机变量),计算哈希值。在滑动窗口(最近N步)内检测指纹重复。
3
阈值设计:不是出现1次就报警(可能是正常的重试),而是在窗口期内出现 ≥2 次相同指纹才触发。窗口大小和阈值需要根据任务特性调整。
只说"用哈希检测"而不解释"为什么要标准化参数"——面试官会追问:如果参数里有时间戳,哈希每次都不同,怎么检测?这个追问要答到。
中级
移动端 Agent 和服务端 Agent 在架构上最重要的差异是什么?
▾
回答框架(三个维度)
1
网络不可靠性:服务器端的工具调用几乎不会因为网络失败,移动端失败率高很多。这要求每个子任务都必须有 Fallback 策略,Loop Detection 也要能识别"网络失败导致的重试死循环"。
2
端云协同路由:服务器端可以无限制调用云端大模型;移动端需要根据网络状态、任务复杂度、隐私敏感性动态决定是在端侧小模型处理还是路由到云端,这是一个设计上全新的决策层。
3
用户中断处理:服务器端的 Agent 任务一旦开始,通常会跑完;移动端用户随时可能切到别的 App、锁屏、改变需求。Plan 必须支持暂停/恢复,而不是从头重来。
只聊"算力受限"——这是表象,不是架构差异。真正的架构差异是这三点,算力只是其中一个影响因素。
高级题 —— 考察架构判断力
高级
如果 Plan-and-Execute 在执行到第4步时发现前三步的输出存在严重数据质量问题,你会怎么处理?
▾
回答框架(分层决策)
1
先分类错误类型:数据质量问题可能是工具本身返回了脏数据(工具问题),或者 Agent 的参数传错了(规划问题),或者用户的输入本身有歧义(用户问题)。不同原因对应不同处理策略,不能一刀切。
2
局部 Re-Plan vs 全局 Re-Plan:如果只是步骤3的工具返回了脏数据,只需要针对步骤3做局部修复(换数据源或清洗数据);如果根本原因是最初的 Plan 设计有缺陷,才需要全局 Re-Plan,代价更高。
3
用户介入门槛:如果问题严重到 Agent 无法自主判断(比如数据质量到底是否达标是主观判断),应该暂停执行,把情况告知用户,让用户决定是继续还是重来。这是"Human-in-the-Loop"的核心场景。
4
记录到执行历史:无论选哪种处理方式,都要把这个异常记录到任务状态里,方便后续分析和改进 Plan 的质量。
直接说"触发全局 Re-Plan"——面试官会追问:Re-Plan 的成本是多少?有没有更轻量的方式?没有分层思考的答案会暴露缺乏生产经验。
高级
设计一个端侧学习助手 Agent,要求在无网络时仍能工作,有网络时利用云端大模型增强体验。你如何设计这个架构?
▾
参考架构(Speakeasy 场景)
1
能力分层:把功能按"是否依赖大模型推理"分级。Level 0(完全离线):查词汇、看历史记录、做选择题;Level 1(端侧模型):简单语法判断、发音评分;Level 2(需要联网):复杂写作分析、个性化计划生成。
2
网络状态感知层:实时监测网络质量(不只是有/无网络,还要检测延迟和稳定性)。根据网络质量动态调整路由策略——弱网时降级到 Level 1,断网时降级到 Level 0,并给用户明确的能力提示。
3
离线缓存策略:用户常用的功能(最近学的词汇、当前学习计划)预先缓存到本地,保证核心体验离线可用。非常用的复杂分析功能降级为"联网后再看"。
4
任务队列与同步:离线期间产生的数据(练习结果、错题记录)存入本地队列;联网后自动同步到服务器,触发云端的深度分析和计划更新。
只谈"本地模型"而不谈"降级策略和用户体验"——技术上的本地模型方案不难,难的是如何让用户在不同网络状态下都有流畅体验,以及如何明确传达当前能力边界。
架构题 —— 考察系统设计能力
架构
你如何设计一个 Agent 的工具调用规范,使其在移动端高网络失败率下仍然可靠?
▾
完整规范设计(5个要素)
1
结构化错误语义:不只返回 HTTP 状态码,而是返回分类错误码(ERR_NETWORK / ERR_NOT_FOUND / ERR_PERMISSION),让 Reasoning 层能做出不同的恢复决策而不是统一重试。
2
幂等性保证:所有写操作必须幂等——使用请求唯一 ID(idempotency_key),服务端拒绝相同 key 的重复请求。确保网络重试不产生重复副作用(两个日历事件、两条练习记录)。
3
超时与重试策略:每个工具调用设置最大超时(如3秒),超时后的重试使用指数退避(1s、2s、4s),而不是立即重试(会加剧网络拥堵)。最多重试2次,超过后触发 Fallback。
4
副作用声明:每个工具在定义时声明其副作用级别(只读/可逆写/不可逆写),Agent 框架对高副作用工具自动要求用户确认,对低副作用工具允许自动执行。
5
调用日志:所有工具调用都写入本地日志(工具名、参数、结果、时间戳),支持 Loop Detection 的历史分析,也方便问题排查。日志定期上传云端用于系统优化。
只谈"重试"——重试只是可靠性的一个维度,而且不合理的重试反而会造成问题(幂等性缺失、加剧 Loop)。完整的工具调用规范需要覆盖这5个要素。
架构
请解释"幻觉控制"和"逻辑回滚"在 Agent 系统里具体指什么,以及如何实现?(来自 JD 加分项)
▾
幻觉控制
1
定义:Agent 在执行过程中产生了与实际工具返回数据不符的声明,或者引用了根本不存在的数据。比如工具返回用户上周有5次练习,但 Agent 在总结里说"您保持了每日练习习惯"。
2
控制方案:在最终输出生成之前,加入 Grounding 校验——对输出里的每个具体事实数据,对照工具调用的 Observation 做一致性检查。不一致的声明要么删除要么改为模糊表述。
3
Self-Consistency 双校验:用同一个问题调用 LLM 两次(不同随机性),比对两次输出的核心结论是否一致。不一致时触发第三次调用仲裁,或降级为更保守的表述。
逻辑回滚
4
定义:Agent 在对话中某一步产生了一个错误结论,后续的推理都建立在这个错误上。当错误被检测到时,不只是修正当前步骤,而是回到错误发生的那一步,撤销所有基于错误的后续推理。
5
实现方式:每个推理步骤维护一个"推理树",记录每个 Belief 的来源(来自哪个工具调用的哪个字段)。发现错误时,找到所有依赖这个错误 Belief 的推理节点,统一标记为失效,触发从该节点开始的局部重新推理。
把幻觉控制说成"加更多提示词"——这只是预防措施,不是检测和修复机制。面试官想听到的是"在 Observation → Thought 环节如何做事实核查",以及"逻辑回滚需要维护推理树这个数据结构"。
核心问题:拿到一个用户请求,怎么判断用该用 ReAct、Plan-and-Execute,还是 Multi-Agent?这不是凭感觉的——有可以工程化的识别框架。
任务分类的四个维度
📏 维度1:步骤数量
预估完成任务需要几次工具调用。1-3步 → ReAct;4-10步 → Plan-and-Execute;10步以上且需要并行 → 考虑 Multi-Agent。
🔮 维度2:步骤可预测性
任务开始前能否列出完整步骤?能列出 → Plan-and-Execute;步骤依赖运行时结果才能确定 → ReAct。
🔄 维度3:动态响应需求
任务执行中是否需要随时响应用户输入或环境变化?需要 → ReAct;任务是批处理型、执行中不需要互动 → Plan-and-Execute。
🎭 维度4:专业域分工
任务是否跨越多个真正不同的专业域,且这些域需要独立的 System Prompt 和工具集?是 → Multi-Agent;否 → 单 Agent 足够。
任务路由决策树
function routeTask(task) {
const estimated_steps = estimateSteps(task);
const needs_realtime = hasRealtimeRequirement(task);
const needs_parallel = hasParallelRequirement(task);
const domain_count = countDomains(task);
if (estimated_steps <= 3 || needs_realtime) {
return 'REACT';
}
if (domain_count >= 3 && needs_parallel) {
return 'MULTI_AGENT';
}
return 'PLAN_EXECUTE';
}
Speakeasy 任务路由实例
| 用户请求 | 识别信号 | 路由结果 | 原因 |
| "这句话哪里错了" | 步骤≤2,需即时回复 | ReAct | 短交互,无需规划 |
| "帮我制定本月学习计划" | 步骤5+,步骤可预知 | Plan-and-Execute | 整体一致性重要 |
| "分析我的发音并出一套练习" | 步骤4+,但有分支 | Plan-and-Execute + ReAct fallback | 混合策略 |
| "同时生成本周内容+更新课程库+发通知" | 三个独立域,可并行 | Multi-Agent | 真正的专业分工 |
| "陪我练口语对话" | 实时交互,不确定步骤 | ReAct | 每轮依赖上轮输入 |
自动路由 Prompt 模板
可以在 Agent 入口处加一个"路由 LLM 调用",让模型根据任务描述输出路由决策:
const ROUTER_PROMPT = `
你是任务路由器。分析用户请求,输出 JSON:
{
"mode": "REACT" | "PLAN_EXECUTE" | "MULTI_AGENT",
"estimated_steps": number,
"reason": string,
"requires_realtime": boolean
}
规则:
- 步骤≤3 或需要实时交互 → REACT
- 步骤>3 且步骤可预知 → PLAN_EXECUTE
- 跨3个以上专业域且需并行 → MULTI_AGENT
只输出 JSON,不要其他内容。
`;
重要:路由本身也会出错。路由 LLM 可能把复杂任务误判为简单任务。解决方案:在执行层加"步骤数监控"——如果 ReAct 模式下步骤数超过阈值(如6步),自动升级为 Plan-and-Execute。路由是初始决策,不是最终决策。
完整闭环案例:用户说"帮我制定本周英语学习计划,写进我的日历"。从接收任务到最终结果的完整流程,含核心代码。模式:Plan-and-Execute(步骤可预知,需要整体一致性)。
第一阶段:任务接入 → 路由判断
async function handleUserRequest(userInput) {
const route = await routeTask(userInput);
if (route.mode === "PLAN_EXECUTE") {
return await planAndExecute(userInput);
} else if (route.mode === "REACT") {
return await reactLoop(userInput);
}
}
第二阶段:生成 Plan(一次 LLM 调用)
async function generatePlan(goal) {
const response = await llm.call({
system: `生成 JSON 任务图。规则:
- 每个任务有 id, action, tool, params_template, depends_on, fallback
- depends_on 为空数组表示可立即执行
- 只输出 JSON,不要解释`,
user: `目标:${goal}\n可用工具:get_user_level, get_calendar_slots, generate_plan, write_calendar, verify_write`
});
const plan = JSON.parse(response);
validatePlan(plan);
return plan;
}
第三阶段:执行引擎(核心循环)
async function executeEngine(plan) {
const state = {
results: {},
actionHistory: [],
tokenUsed: 0
};
while (hasRemainingTasks(plan)) {
const readyTasks = plan.tasks.filter(t =>
t.status === 'pending' &&
t.depends_on.every(dep => state.results[dep]?.status === 'done')
);
await Promise.all(readyTasks.map(task =>
executeTask(task, state)
));
}
return state.results;
}
async function executeTask(task, state) {
const fingerprint = `${task.tool}:${JSON.stringify(task.resolved_params)}`;
if (detectLoop(state.actionHistory, fingerprint)) {
task.status = 'loop_detected';
return triggerFallback(task, state);
}
state.actionHistory.push(fingerprint);
try {
task.status = 'running';
const params = resolveParams(task.params_template, state.results);
const result = await callTool(task.tool, params);
const belief = interpretResult(result, task);
state.results[task.id] = { status: 'done', data: result, belief };
task.status = 'done';
} catch (error) {
const errType = classifyError(error);
await handleError(task, errType, state);
}
}
第四阶段:工具实现(以日历写入为例)
async function write_calendar(params) {
const { events, idempotency_key } = params;
for (const event of events) {
const existing = await calendarAPI.check({
date: event.date, title: event.title
});
if (existing) {
continue;
}
await calendarAPI.create(event);
}
return {
status: "success",
created_count: events.length,
_meta: { unit: "events", action: "calendar_write" }
};
}
第五阶段:最终输出生成
async function generateFinalResponse(state, originalGoal) {
const summary = {
user_level: state.results[1].belief,
slots_found: state.results[2].belief,
plan_created: state.results[3].belief,
calendar_status: state.results[4].belief
};
return await llm.call({
system: "用友好的语气总结任务执行结果,控制在3句话内",
user: `目标:${originalGoal}\n执行摘要:${JSON.stringify(summary)}`
});
}
完整执行流程可视化
总计:3次 LLM 调用 + 5次工具调用。如果用纯 ReAct,每步都要 LLM 推理,至少需要 8-10 次 LLM 调用。
每种 Agent 模式都有对应的成熟框架。选框架不只是看功能,还要看"工程复杂度 vs 你真正需要的能力"。
ReAct 模式框架
| 框架 | 特点 | 适合场景 | 学习曲线 |
| LangChain Agent | 最成熟,生态最大,工具集丰富 | 快速原型,工具调用为主 | 低,文档全 |
| OpenAI Assistants API | 原生 Function Calling,内置状态管理 | 纯 OpenAI 生态,快速上线 | 极低 |
| Anthropic Tool Use | Claude 原生工具调用,结构化输出稳定 | 需要高质量推理的工具调用 | 低 |
Plan-and-Execute 框架
| 框架 | 核心抽象 | 优势 | 生产就绪度 |
| LangGraph | 有向图 + 状态机 | 最灵活,支持复杂分支、循环、Human-in-the-Loop | ⭐⭐⭐⭐⭐ |
| LangChain Plan-and-Solve | Planner + Executor 两阶段 | 简单,快速上手 | ⭐⭐⭐ |
| Haystack Pipelines | 节点管道 | 适合文档处理类任务,工业级稳定 | ⭐⭐⭐⭐ |
Multi-Agent 框架
| 框架 | 协调模式 | 适合场景 | 上手难度 |
| CrewAI | 角色扮演,任务分配 | 内容生产、研究类任务 | 低(YAML 配置) |
| AutoGen(微软) | 对话驱动,Agent 互相对话 | 代码生成+审查、问题求解 | 中 |
| LangGraph Multi-Agent | 图结构,显式消息传递 | 需要精确控制通信的生产系统 | 高 |
| Autogen Studio | 可视化配置 | 快速实验,非工程师友好 | 极低 |
移动端专用框架 / 工具
| 工具 | 作用 | 和 Agent 的关系 |
| LLaMA.cpp | 端侧模型推理引擎(C++) | 提供端侧 Reasoning 能力 |
| MLC LLM | 跨平台端侧部署(iOS/Android/Web) | 端侧小模型的工程化运行时 |
| Ollama | 本地模型管理(主要用于 macOS/Linux) | 开发阶段模拟端侧环境 |
| Apple Core ML | iOS 原生 ML 推理 | Phi-3-mini / Gemma-2B 的 iOS 部署 |
| MCP(Model Context Protocol) | 工具调用协议标准 | 打通端侧工具(日历/相册/快捷指令) |
LangGraph 工程构建要点(重点,JD 要求)
import { StateGraph, END } from "@langchain/langgraph";
const graphState = {
goal: null,
plan: null,
current_task: null,
results: {},
error: null
};
const workflow = new StateGraph({ channels: graphState });
workflow.addNode("planner", generatePlan);
workflow.addNode("executor", executeTask);
workflow.addNode("validator", validateResult);
workflow.addNode("replanner", replanTask);
workflow.addEdge("planner", "executor");
workflow.addConditionalEdges("validator", (state) => {
if (state.error?.type === "ERR_CRITICAL") return "replanner";
if (hasMoreTasks(state)) return "executor";
return END;
});
workflow.addEdge("replanner", "executor");
const app = workflow.compile();
const result = await app.invoke({ goal: "制定本周学习计划" });
选型建议(Speakeasy 项目)
✅ 推荐:LangGraph
用于实现 Plan-and-Execute 的长任务(制定计划、批量练习生成)。状态机模型完美匹配任务依赖关系,Human-in-the-Loop 支持好,生产稳定。
✅ 推荐:Anthropic Tool Use
用于 ReAct 模式的短交互(语法解释、即时对话)。Claude 的工具调用质量高,结构化输出稳定,幻觉率低。
⚠️ 谨慎:CrewAI
快速实验内容生产流水线可以用,但生产环境的可控性和可观测性弱,排查问题困难。
🔬 实验:MLC LLM + MCP
端侧 Agent 的核心组合。先在 Ollama 上用 Phi-3-mini 验证工具调用质量,再迁移到端侧部署。
针对你提到的4个深层问题:为什么不能一个 Prompt 搞定、为什么不能运行时动态注册 Prompt、LLM 无状态的底层含义、Belief 是什么。每个都拆到最底层。
为什么不能把所有步骤写进一个 Prompt 让模型一次完成?
高频误区
这个问题有两个层次的答案——表层的"做不到"和深层的"即使做到了也不对"。
🚧 物理层面做不到
任务步骤 N 的输入,依赖步骤 N-1 的运行时输出结果。而步骤 N-1 的结果是工具调用后才存在的真实数据——在写 Prompt 时根本还不存在,你不可能提前把它写进去。
例:你无法在写 Prompt 时就知道"日历 API 今天会返回什么空闲时段"——这是 Prompt 写完之后才发生的事。
🧠 认知层面做不到
LLM 的生成是"一次性完成的"——它不能在生成过程中"暂停、去查个数据、再继续"。它只能基于 Prompt 里已有的信息生成输出,真实世界的反馈无法注入生成过程。
就算你把所有"假设性结果"都写进 Prompt,模型只是在对假设做推理,不是在做真实决策。
根本原因:LLM 是一个函数 f(input) → output,它在一次调用里完成。真实任务是有状态的迭代过程,需要多次 f() 调用,而且每次的 input 都依赖上一次的 output。这两者的结构不匹配,用单次调用硬撑多步任务,就像用一张照片代替一段视频——根本不是同一个东西。
为什么不能在运行时动态注册 Prompt?
进阶问题
这个问题问的比上面更深——假设我们能在执行过程中动态往 Prompt 里加内容,是否就解决问题了?
技术上,这完全可以做到,而且正在被做:每次 LLM 调用时,Agent 框架都在动态构建 Prompt,把前几步的结果拼接进去。这本身就是"运行时动态 Prompt"。
那为什么还需要 Planning 框架?有三个 Prompt 层面解决不了的问题:
📏 问题一:Context 上限
持续往 Prompt 里追加内容,Context Window 会被撑爆。Planning 框架的状态管理负责"选择性包含"——只把当前步骤需要的内容塞进 Prompt,而不是全部历史。
🔗 问题二:依赖关系管理
Prompt 是线性文本,无法表达"步骤 A 和 B 可以并行,C 必须等 A 和 B 都完成"这样的依赖关系。这需要任务图这种数据结构,不是 Prompt 能做到的。
🔄 问题三:全局一致性
动态拼接的 Prompt 容易导致"前后矛盾"——步骤 7 的指令和步骤 2 的前提假设发生冲突,模型会产生混乱。Planning 框架维护全局状态,确保每步调用时的 Prompt 上下文是自洽的。
动态 Prompt 是 Planning 框架工作的"媒介",不是 Planning 本身。Planning 的价值在于:管理状态、维护任务图、协调并行、保证全局一致——这些都在 Prompt 之上的抽象层。
深挖:LLM 无状态 + 任务有状态 = 所有复杂性的根源
底层洞察
核心命题
Planning 存在的根本原因
LLM 无状态(每次调用是全新的,没有记忆)
+ 任务有状态(步骤之间有依赖,有中间结果,有执行进度)
= 必须由外部框架在多次调用之间维护状态和协调顺序
= Planning 就是这个协调机制的设计
这个洞察能推导出 Agent 架构里所有核心设计决策:
| 由"LLM无状态"推导出 | 对应的架构组件 |
| 状态不能存在 LLM 里,需要外部维护 | 状态存储(内存 / 数据库) |
| 每次调用都要重新喂入必要上下文 | Context 管理 + 滚动摘要 |
| LLM 不知道之前发生了什么 | Action History + Observation 拼接 |
| LLM 不知道还剩多少任务 | 任务图 + 进度追踪 |
| LLM 不能"决定去执行工具"然后等待结果 | 工具调用框架 + 异步执行引擎 |
| LLM 不能主动感知到工具执行失败 | 错误捕获层 + Belief Update |
这个洞察还有更深一层:人类做事时,"我的大脑"(推理)和"我对世界的记忆"(状态)是融合在一起的。LLM 把这两者完全分离了——它只有推理,没有记忆。Agent 框架本质上是在给 LLM "装上记忆器",让它能处理有状态的任务。
Belief 是什么?为什么是 Agent 推理的核心概念?
核心概念
Belief(信念)不是"相信不相信"的"信念",而是 Agent 对"当前世界状态"的内部模型——它认为现在的情况是什么样的。
🗺️ 类比:Belief 是你脑中的地图
你去一个陌生城市,脑子里有一张"你认为的地图"——可能不完全准确,但是你做决策的依据。走到某个路口,看到实际情况和地图不符,你更新地图(Belief Update),然后基于新地图决定下一步。
🤔 Agent 的 Belief
Agent 的 Belief 是它对"用户数据、任务进度、工具状态"的内部理解。每次工具调用返回结果,Agent 都要更新自己的 Belief,然后基于更新后的 Belief 决定下一步行动。
Belief 的三种状态
| 状态 | 含义 | 对应行为 | Speakeasy 例子 |
| Confident Belief | 高置信度的确定判断 | 直接执行下一步 | "用户是 B2 级别"(来自明确的测试结果) |
| Uncertain Belief | 有证据但不确定 | 收集更多信息或给出不确定的输出 | "用户可能是 B1-B2 之间"(测试结果不一致) |
| Contradictory Belief | 不同来源的信息互相矛盾 | 触发人工确认或选择更可信的来源 | "档案显示 B2,但最近练习表现像 A2" |
Belief Update 的工作机制
function updateBelief(currentBelief, observation, task) {
if (observation.error_code === "ERR_NOT_FOUND") {
return { ...currentBelief,
[task.target]: { exists: false, confidence: "high" }
};
}
if (observation.error_code === "ERR_NETWORK") {
return { ...currentBelief,
env_status: { network: "unstable", last_check: Date.now() }
};
}
return { ...currentBelief,
[task.target]: { value: observation.data, confidence: "high", source: task.tool }
};
}
Belief 是 Reasoning 的"基底"——所有的 Thought 都是基于当前 Belief 做出的。Belief 的质量(准不准确、有没有及时更新)直接决定了 Agent 的决策质量。这就是为什么"工具调用返回结构化错误语义"如此重要——准确的错误信息才能产生准确的 Belief Update,进而产生正确的下一步行动。