FDE W5 Day 1 学习手册 · Agent Loop 企业扩展
W5 Day1 · A 级(必须掌握,面试核心)· 4h · 学完能讲透"从原型 Agent Loop 到生产级企业 Loop 的四项关键演进"
本日定位:W4 跑通了"感知—决策—行动"的最小 Agent Loop。Day1 把它从 Demo 推向企业级:补上 Context 裁剪、Tool Runtime 抽象、多轮状态持久这三块,否则上生产会爆上下文、串数据、不可恢复。
学完能回答:① 原型 Loop 为什么不能直接上生产(无裁剪/无隔离/无状态持久);② Context 怎么裁剪与摘要、和 KV Cache 的关系;③ Tool Runtime 与业务解耦怎么落地;④ 多轮状态存哪、怎么恢复。
使用方法:通读原理 → 重点看「工程含义」「面试话术」「易错点」→ 做自测清单 → 配合《FDE-W5D1-评测题.md》。选中不熟的词可标注(左下★重要 / 右下📌待查)。候选人背景:36岁,Java+大数据+医疗保险行业,示例围绕特药理赔/保险知识库。
一、从原型 Loop 到企业 Loop:为什么不能直接上生产
W4 的原型 Agent Loop 通常长这样:把整段对话历史 + 工具结果直接塞进 prompt,循环调 LLM 直到给出最终答案。它能跑通 Demo,但有三道硬伤:
| 维度 | 原型 Loop | 企业级 Loop |
| 上下文 | 全量历史无裁剪,越聊越长直到溢出窗口 | Context 裁剪 + 摘要,按预算控制长度 |
| 工具执行 | 直接调业务函数,异常会拖垮整个 Loop | Tool Runtime 抽象层,隔离/调度/限流 |
| 状态 | 状态只在内存变量里,进程一挂全丢 | Checkpointer / 外部存储持久化,可恢复 |
| 可观测 | 无 Trace,出问题靠猜 | 每步留痕,可回放审计 |
企业级 Agent 的本质不是"更聪明的模型",而是把工程基础设施补齐:裁剪控成本、Runtime 控故障、持久化控可用性。模型能力只是其中一环,真正决定能不能上生产的是这三块。
原型 Loop 上生产会出三件事:上下文爆窗、工具异常拖垮主流程、进程重启状态全丢。企业级要补 Context 裁剪、Tool Runtime 抽象、状态持久化三块。
① 很多人以为"上生产就是调更贵的模型",错——模型不对,基础设施不对照样崩。② 这三块(裁剪/Runtime/状态)是正交的,可以分别演进,不要等"全都做好"才上线,先按最大痛点补。③ 不要为了"企业级"把架构做得过度复杂,LangGraph 这类框架的价值正是把这三块开箱即用,避免重复造轮子。
二、原型 Agent Loop 的构成(W4 回顾)
最小 Agent Loop 是一个"感知—决策—行动—观察"的闭环:
system + history + tools_desc → LLM → 决定调工具 or 结束 → 执行工具 → observation 回填 → 再喂回 LLM → … → 输出最终答案
- 感知:把用户问题、历史、工具描述拼成 prompt。
- 决策:LLM 输出"下一步动作"——是调用某个工具,还是给出最终答案。
- 行动:解析 LLM 输出,执行工具调用(如查知识库、算理赔金额)。
- 观察:把工具返回结果回填进上下文,进入下一轮。
特药理赔示例:用户问"我这个肺癌靶向药能报多少?" → 模型决定先调"查询保单"工具 → 拿到保单与特药目录 → 再调"计算报销比例"工具 → 得出金额 → 输出最终理赔结论。
原型 Loop = 不断把"工具结果"回填进上下文再问模型"下一步干啥",直到模型说"我答完了"。核心是循环 + 工具回填。
① 原型里"回填"往往直接把原始工具结果(可能几千字)整段塞回去,这是后面上下文爆炸的根源。② 循环没有"最大步数"护栏,模型一旦陷入"调工具 A→发现缺 B→调 B→又缺 A"就会无限循环烧 token。③ 模型输出解析(从文本里抠出工具名和参数)在原型里常是脆弱的字符串匹配,生产要换成结构化 tool_call。
三、Context 裁剪与摘要:为什么必须做
3.1 问题
每一轮推理,模型都要重新读整个上下文窗口。当对话多轮、工具结果巨大(如一份几十页的保险条款 PDF 抽取结果)时,上下文会:
- 超窗口:超出模型 max_tokens,直接报错或截断,丢失关键信息。
- 变贵变慢:输入 token 越多,每次调用成本越高、延迟越大。
- 注意力稀释:无关信息太多,模型反而不聚焦关键证据,准确率下降。
3.2 裁剪的两条思路
| 思路 | 做法 | 适用 |
| 丢弃(Eviction) | 按策略丢掉最不重要的旧消息/旧工具结果 | 历史很长、近期才重要 |
| 压缩(Compression) | 把多轮对话/长工具结果摘要成短文本保留 | 旧信息仍有价值但不能全留 |
对医疗保险场景尤其关键:一个理赔案件可能涉及历史沟通记录、多份医疗文书、知识库检索结果,原始拼起来轻松几万字。不裁剪,单次调用 token 成本与延迟都不可接受,且容易把"关键拒赔条款"淹没在噪声里。
Context 裁剪是"在有限窗口里塞下最有用的信息"。两种手段:直接丢不重要的(eviction),或把长内容压成摘要(compression)。不裁剪会超窗、烧钱、还稀释注意力。
① 裁剪不是"越短越好"——把关键拒赔条款摘要没了,模型会给出错误理赔结论,这是业务事故。② 摘要本身由 LLM 或规则做,摘要也可能丢失/歪曲信息,需要评估摘要保真度。③ 裁剪策略要"可解释":为什么丢这条、为什么留那条,企业里要能审计,不能黑盒随机丢。
四、Context 摘要策略:按轮摘要 / 按 token 预算裁剪
4.1 按轮摘要(Summary per turn)
当对话超过 N 轮后,把最早的若干轮压缩成一段"到目前为止的进展摘要",替换掉原始多轮消息。例如:
# 会话摘要(前 8 轮已压缩)
用户为肺癌患者,持有尊享特药险(保单号 PX-2024-8832),询问奥希替尼报销比例。
已确认:该药在目录内、适应症匹配。待确认:年度报销上限与自付比例。
尚未调用:计算报销金额工具。
4.2 按 token 预算裁剪(Token-budget trimming)
设定一个"上下文预算"(如 8k token)。每轮把消息按重要性打分,超出预算时从最低分开始丢弃或摘要,直到回到预算内。重要性可参考:系统提示最高、最新用户消息高、工具错误结果高、陈旧摘要低。
if (estimated_tokens(messages) > BUDGET) {
sort by importance desc;
keep high-importance;
summarize / drop low-importance until fits BUDGET;
}
4.3 工具结果裁剪
长工具结果(知识库 top-k 文档)单独处理:只保留与当前问题最相关的片段(按相关性重排后取 top-N),或先 RAG 截断再进上下文。
工程中常组合用:对话历史用"按轮摘要",工具结果用"截断/top-k",再加全局"token 预算"兜底。LangGraph 的 pre_model_hook / trim_messages 就是干这个的。
两种主流策略:按轮摘要(把老轮压成一段进展摘要)和按 token 预算裁剪(设上限、按重要性丢/压低优先级的)。工具长结果单独 top-k 截断。可组合用。
① 摘要和裁剪都会丢信息,要设"保底白名单"——比如保单号、当前决策阶段这类字段永远不丢。② 每轮都重新摘要很贵,建议"阈值触发"(超轮数或超预算才摘要),不要每轮都做。③ token 估算用粗略计数(1 token≈0.6 中文字)即可,不必精确,但要留安全余量防溢出。
五、Context 裁剪与 KV Cache 的关系
5.1 KV Cache 是什么
自回归生成时,模型对"已读过的 token"算出的 Key/Value 向量会缓存(KV Cache),下一轮推理直接复用,避免重算前缀,大幅降低延迟和成本。前缀不变 → 缓存命中 → 快且省。
5.2 裁剪如何影响 KV Cache
| 做法 | 对 KV Cache 的影响 |
| 只在尾部追加新消息 | 前缀不变,缓存高命中(最优) |
| 把最早几轮"替换成摘要" | 前缀变了,旧缓存失效,需重算(有代价但可控) |
| 每轮都重排/截断中间内容 | 前缀频繁变动,缓存几乎每次失效(最差,慢且贵) |
因此裁剪策略要尽量保持前缀稳定:摘要放在最前面(旧端),新消息永远追加在尾部,避免动中间。这样前面"系统提示+摘要"虽偶尔变,但尾部大量轮次仍可命中缓存。
KV Cache 命中率直接决定成本和延迟。裁剪时优先"改旧端(摘要化老轮)、保尾端(新消息追加)",让不变的前缀尽量长,缓存命中高。反之频繁重排中间内容会打散缓存,得不偿失。
KV Cache 缓存前缀,前缀不变就快就省。裁剪要尽量"动旧端、保尾端"——把老轮摘要化放前面,新消息追加在后面,避免每轮重排中间内容打散缓存。
① 很多人裁剪时"智能重排"把重要消息挪到前面,结果每轮前缀都变,KV Cache 全废,反而更慢更贵。② 摘要操作本身也要成本,要和"缓存失效重算"成本权衡——不是裁剪越勤越好。③ 不同厂商对 KV Cache 计费和命中规则不同(有的跨请求复用、有的同会话复用),要查对应文档。
六、Tool Runtime:工具执行的抽象层
6.1 为什么需要抽象
原型里 Agent 直接 import 业务函数调用。企业里这不行:工具要鉴权、要限流、要超时、要隔离、要可观测。把"调工具"这件事抽象成Tool Runtime层,Agent 只说"我要调 X",Runtime 负责安全地把它跑完。
Agent ──(意图: tool=查保单, args=...)──▶ Tool Runtime ──▶ 实际业务系统
▲ │
调度/鉴权/隔离/限流/超时 结果 or 受控错误
6.2 Tool Runtime 的职责
- 注册:工具以统一元数据结构登记(名称、描述、入参 schema、权限标签)。
- 调度:决定调用顺序、并发、重试、超时。
- 隔离:工具在沙箱/独立线程/独立服务里跑,异常不污染主流程。
- 可观测:每次调用的入参、耗时、结果、错误全记 Trace。
对 Java 背景很自然:Tool Runtime 类似"工具调用的中间件层 / 防腐层(ACL)"。它把 LLM 的"意图"翻译成对核心业务系统的安全调用,业务代码零改动即可被 Agent 复用,符合"与业务解耦"。
Tool Runtime 是"工具调用的中间件层":Agent 只发意图,Runtime 负责注册/调度/隔离/可观测。它把 LLM 意图转成对业务系统的安全调用,业务代码不用改。
① Runtime 不是"又包一层函数"这么简单,它的价值在统一治理(鉴权/限流/超时/审计)一次搞定,否则每个工具自己写一遍。② 隔离要到位:工具里的 NPE、OOM 不能把 Agent 进程拖死。③ 不要为了"可观测"在每个工具里手写日志,应统一在 Runtime 拦截记 Trace,否则日志散落难审计。
七、工具注册与调度(注册 / 调度 / 隔离)
7.1 注册:统一工具描述
ToolSpec(
name="query_policy",
description="按保单号查询保险保单与已购特药目录",
input_schema={ "policy_no": "string", "holder_id": "string" },
annotations={ "read_only": true, "risk": "low" },
permissions=["tool:policy:read"]
)
7.2 调度:并发与依赖
- 独立工具:可并行调用(如"查保单"和"查药品目录"无依赖,一起发)。
- 有依赖:必须等前置结果(如先得保单号才能算报销)。
- 最大并发 / 队列:防止瞬间打爆下游业务系统。
7.3 隔离:故障不扩散
工具在独立线程池/协程/微服务执行。单个工具超时或抛错,Runtime 捕获后返回"受控错误"(供 Agent 决定重试或换策略),主 Loop 不崩。
注册=统一元数据结构(名/描述/入参/权限标签);调度=处理并发与依赖、限流;隔离=工具在独立执行单元跑,异常被 Runtime 捕获成受控错误返回,主流程不挂。
① 工具"并行"很诱人但要小心下游:查保单和查目录并行没事,但若都打同一个核心库,并发反而把它压垮——限流在 Runtime 层做。② 注册的 annotations(如 read_only/risk)只是"提示",不是安全边界,真正鉴权另做(见 W5D2)。③ 隔离粒度别太粗也别太细:一个工具一个线程池太碎,全共用一个池又互相影响,按业务域分组更合理。
八、多轮状态管理:Agent 中间状态存哪
8.1 状态有哪些
- 对话历史:用户/助手消息。
- Agent 内部状态:当前步骤、已收集到的字段(如已确认保单号)、中间工具结果。
- 业务状态:理赔单状态、审批状态(注意:这部分属于业务系统,见 W5D4)。
8.2 存储位置对比
| 位置 | 优点 | 缺点 | 适用 |
| 内存变量 | 最快 | 进程重启全丢、无法多实例共享 | 原型 / 单次会话内 |
| Checkpointer | 每步快照、可暂停/恢复/回溯 | 需配套存储 | 企业级多轮 Agent |
| 外部存储(DB/Redis) | 持久、跨进程、可审计 | 需自己管序列化与一致性 | 长周期业务(跨天理赔) |
特药理赔可能跨多个工作日(等医院发票、等人工审批),状态必须落外部存储,不能靠内存。
"状态存哪"决定可用性。企业 Agent 普遍用 Checkpointer(框架级,每一步落快照)做"可恢复",再对长周期业务把关键状态同步到业务 DB。内存只用于单次请求的临时变量。
Agent 状态三处可放:内存(快但一挂就丢)、Checkpointer(每步快照可恢复,框架级)、外部存储(持久跨进程可审计)。长周期业务如理赔必须落外部存储。
① "状态"和"业务状态"是两回事:Agent 内部的中间变量可以 Checkpoint,但理赔单状态属于业务系统(W5D4),Agent 不能自己当 owner。② Checkpointer 快照要轻量,别把整个大上下文每步都序列化,会爆存储——只存"恢复所需的最小状态 + 裁剪后的上下文指针"。③ 多实例部署时内存态不共享,必须用外部存储或带共享后端的 Checkpointer,否则用户第二次请求打到另一台机器状态全无。
九、Checkpointer 设计与可恢复性
9.1 原理
Checkpointer 在 Agent 每执行一步(一次 LLM 调用 / 一次工具调用后)把"当前状态快照"写进存储。崩溃或主动暂停后,可用 session_id + 步号恢复,从断点继续,不必从头重跑(避免重复烧 token、重复调工具副作用)。
step_n: { messages(裁剪后), agent_state, next_action } ──save──▶ store[session_id][n]
recover(session_id, n): load snapshot → resume from step_{n+1}
9.2 设计要点
- 幂等:恢复后重跑要安全——工具调用若有副作用(提交审批),需幂等键防重复提交。
- 版本兼容:Agent 代码升级后,旧快照能否反序列化,要有迁移策略。
- 过期清理:长周期会话快照保留多久、何时归档。
Checkpointer 是企业 Agent "可恢复性"的核心。它让"暂停等人审批""半夜进程重启""主动 human-in-loop 打断"都变成可能——这正是 W4 HITL 能落地的底座。
Checkpointer 每步落快照,崩溃/暂停后能从断点恢复,不重跑。关键是工具副作用要幂等,否则恢复重跑会重复提交审批。
① 没有幂等保障就去"恢复重跑",会把"提交理赔审批"执行两遍——这是生产事故。② 快照里若存了敏感信息(患者身份证号)要加密,存储合规要管。③ 不要 Checkpoint 得太碎(每 token 都存)也别太粗(只在开头存),"每步"是平衡点。
十、资源与监控:Trace / 可观测
企业级必须能回答"这次回答是怎么来的":调了哪些工具、每步耗时、花了多少 token、哪步出错。靠 Trace 系统(如 Langfuse、LangSmith)把每次 Loop 的步骤串成树状记录。
| 要记录 | 用途 |
| 每步 LLM 输入/输出 | 复现、评测、调试 |
| 工具调用入参/结果/耗时/错误 | 定位慢/错的工具 |
| token 与成本 | 成本核算、预算预警 |
| 裁剪/摘要动作 | 审计"为什么丢了某信息" |
企业级要可观测:把每次 Loop 的步骤(LLM 输入输出、工具调用、token、裁剪动作)串成 Trace,出问题能回放、能审计、能算成本。
① Trace 别只记成功不管失败——恰恰失败路径(工具异常、超时)最该记全,否则线上事故无法复盘。② 记 Trace 本身有开销,生产要采样或分级(关键业务全记、普通对话抽样)。③ Trace 含患者隐私,存储与访问要脱敏和权限控制。
十一、面试达标线①:能讲清从原型 Loop 到企业 Loop 的演进
| 演进维度 | 原型 | 企业级 | 解决什么 |
| Context | 全量历史无裁剪 | 裁剪 + 摘要 + token 预算 | 超窗、成本、注意力稀释 |
| 工具执行 | 直接调业务函数 | Tool Runtime 抽象(鉴权/隔离/限流) | 故障扩散、无治理 |
| 状态 | 内存变量 | Checkpointer + 外部存储 | 重启丢失、不可恢复 |
| 可观测 | 无 | Trace 全链路 | 不可复盘、不可审计 |
核心:企业级 Agent 不是"更聪明模型",而是补齐 Context 裁剪、Tool Runtime、状态持久化、可观测四块基础设施。三者正交、可分别演进、不必一步到位。
十二、面试达标线②:Context 裁剪为什么必要、有哪些策略、和 KV Cache 的关系
必要性:超窗 + 成本 + 注意力稀释 │ 策略:按轮摘要 / 按 token 预算裁剪 / 工具结果 top-k │ KV Cache:动旧端保尾端,保前缀稳定以高命中缓存
- 为什么必要:不裁剪会超上下文窗口、每次调用更贵更慢、无关信息稀释关键证据(如拒赔条款)。
- 有哪些策略:丢弃低重要消息(eviction)、按轮摘要老轮、按 token 预算裁剪、工具长结果 top-k 截断,可组合。
- 和 KV Cache 关系:KV Cache 缓存前缀,前缀不变则命中高、快且省。裁剪要"改旧端(摘要)、保尾端(追加)"以维持前缀稳定;频繁重排中间内容会打散缓存,反而更慢更贵。
- 代价权衡:摘要本身有成本、且可能丢信息,需保底白名单 + 摘要保真度评估。
十三、W5D1 自测清单
- 能说出原型 Agent Loop 的"感知—决策—行动—观察"闭环,并指出它上生产的三道硬伤(无裁剪/无隔离/无状态持久)。
- 能解释 Context 不裁剪的三类后果(超窗/成本/注意力稀释),举出医疗保险场景的例子。
- 能区分"丢弃(eviction)"和"压缩(compression)"两种裁剪思路。
- 能讲清两种摘要策略:按轮摘要、按 token 预算裁剪,以及工具结果如何单独 top-k 截断。
- 能说清 KV Cache 原理,以及裁剪为什么"动旧端、保尾端"才能维持高缓存命中。
- 能画出 Tool Runtime 在 Agent 与业务系统之间的位置,并说出它的四个职责(注册/调度/隔离/可观测)。
- 能解释工具"注册"统一元数据结构里哪些字段只是提示、哪些才是真鉴权依据(D2 展开)。
- 能对比内存 / Checkpointer / 外部存储三种状态存放位置的优劣与适用。
- 能讲清 Checkpointer 的可恢复性原理,以及为什么工具副作用必须幂等。
- 能讲清从原型到企业 Loop 的四项演进(裁剪/Runtime/状态/可观测),并区分"Agent 内部状态"与"业务状态"(后者归 W5D4)。
十四、高频面试题速记卡
Q:原型 Agent Loop 为什么不能直接上生产?
三道硬伤:无 Context 裁剪(超窗/烧钱)、无 Tool 隔离(一处异常拖垮全流)、无状态持久(重启全丢、不可恢复)。
Q:Context 裁剪有哪两类思路?
丢弃(eviction,丢低重要消息)和压缩(compression,把长内容/多轮摘要成短文本)。可组合。
Q:按轮摘要和按 token 预算裁剪分别怎么用?
按轮摘要把最早 N 轮压成"进展摘要";按 token 预算设上限、按重要性丢/压低优先级内容回到预算内。工具长结果单独 top-k。
Q:Context 裁剪和 KV Cache 什么关系?
KV Cache 缓存前缀,前缀不变则命中高、省且快。裁剪应"动旧端(摘要老轮)、保尾端(新消息追加)",避免频繁重排中间内容打散缓存。
Q:Tool Runtime 是干什么的?
工具调用的中间件/防腐层:Agent 发意图,Runtime 负责注册、调度、隔离、可观测,把 LLM 意图转成对业务系统的安全调用,业务代码零改。
Q:Agent 状态存哪?
内存(快但一挂就丢)、Checkpointer(每步快照可恢复,框架级)、外部存储(持久跨进程可审计)。长周期业务如理赔必须落外部存储。
Q:Checkpointer 恢复为什么要幂等?
恢复会重跑后续步骤,若工具(如提交审批)无幂等键,会重复执行造成生产事故。
Q:工具并行调用要注意什么?
只并行无依赖工具;有依赖的必须等前置结果;在 Runtime 层限流,防止瞬间打爆下游核心系统。
Q:企业级可观测要记什么?
每步 LLM 输入输出、工具入参/结果/耗时/错误、token 成本、裁剪动作——尤其失败路径最该记全。
Q:Agent 状态和业务状态是一回事吗?
不是。Agent 内部中间变量可 Checkpoint;理赔单/审批状态属于业务系统(W5D4),Agent 不拥有,只驱动。
FDE W5D1 学习手册 · Agent Loop 企业扩展(面试级)· 配合《FDE-W5D1-评测题.md》自测 · 资源:李宏毅 Agent 原理 BV1aiADewEBC、LangGraph 多智能体/工具 BV1zKx4zWEZP
📌 待查★ 重要