课前:先自学,再做 15 道题
上课前,先花点时间自己看一页材料,就三样:
- 弄懂 3 个词:超时/重试/退避/降级(四个不同动作)、幂等(同一请求重复到达,不重复执行)、成本(按"一次任务"算)。
- 记住 1 个比方:它会坏——让它能自己恢复,而且别重复干同一件事。
- 记住 1 条红线:别为了省几分钱砍用户体验;省成本的顺序:先减无效调用 → 换小模型 → 最后砍功能。
看完做 15 道自测题。哪几道大家错得多,直播时老师就重点讲哪几道。
直播 0–30|把核心快速过一遍
- 重试是好事,但对"写操作"重试是灾难。 查库存失败可以重试;创建工单失败再重试,可能建出两条 → 用幂等键(同一请求带同一键,只执行一次)。
- 超时/重试/退避/降级四个词要分清。 超时=等太久放弃;重试=再试一次;退避=越失败等越久;降级=换简单方案(模型挂了→模板回复+转人工)。
- 成本按"一次任务"算。 一次任务可能要调 3 次模型 + 2 次工具,算总账,别按"一次对话"。
直播 30–75|挑大家做错的题讲
- 无限重试,失败一次重试一次,越重试越堵。
- 重试写操作,没幂等键,重试就是复制。
- 日志没有任务 ID,出了事连"哪一次"都说不清。
直播 75–120|拆一个真实案例:启衡精密,重复建单与长链路
启衡精密(制造企业)的报销预审 Agent 自动建任务,网络卡了一下,用户点了两次"提交",就建出两条重复任务;讲师点评"你没有做客户端幂等"。材料是两次运行日志(第二次 source_meeting: null,系统没法判断"已经建过")。
修复分四步:①用 会议ID + 行动项序号 生成幂等键 M-1021-A03;②建之前先查,键存在就跳过;③写入时把幂等键一起存;④补一条测试"同一输入连跑 3 次只建 1 组"。容易踩的坑有三个:只在应用层去重、没在数据层加唯一约束;用"标题"当去重键;重试时重新生成 ID。
再说长链路:10 个独立步骤各 95% 成功率,整条链路一次走通只有约 60%;企业 Agent 上线的硬门槛是"整链准确率稳定在 90% 以上"。
这一讲想让你记住的就一句:"任务成功"和"消息送达"是两件事,日志里分开记 task_status / result_saved / human_seen。
当堂练一个(8 分钟):挑一件你平时真会让 AI 做的事——比如"读一份 10 页材料、写 300 字摘要"。先猜:做这一次大概要花多少钱?然后真做一遍,看它到底消耗了多少额度/积分,按当期的积分价格把单次成本算出来;再算一笔账:如果每天用 20 次,一个月要花多少。最后从你常用的两三个 AI 里,指出哪一个做这件事最划算。
判断标准:能报出"这件事做一次的真实成本",并说清"一次任务里可能调了 3 次模型 + 2 次工具,都要算进总账",而不是只按"一次对话"——把成本看小了。
课后:答疑 + 陪跑,交一份作业
加幂等键 + 超时有限重试 + 分状态日志 + 降级;演练 3 次(重复提交/超时/返回丢失);做 5 类故障演练修 2 类,重跑第 12 讲测试集。
这节课你该会的:
- 能说清"幂等"是什么,并保证同一请求重复提交只执行一次;
- 能分清超时、重试、退避、降级四个动作,出错时给出用户能看懂的提示;
- 能按"一次任务"算成本,并能从日志还原一次失败"卡在哪一步、花了多久、花了多少"。
三个翻车:
- 无限重试——失败一次重试一次,越重试越堵,把下游打挂;
- 重试"写操作"却没用幂等键——重试就是在复制,一份变两份;
- 日志不记任务 ID——出了事,你连"哪一次"都说不清。
延伸自读:《原理讲义》§13
展开查看
一句话定义
可靠性不是"不出错",而是"出错之后系统能自己恢复、并且不重复做同一件事"——当模型慢、工具挂、网络断、返回丢时,它是变成事故,还是退到一条可恢复、可追溯的路径。一句话:让它会坏,但坏得起。
核心原理
1. 超时 / 重试 / 退避 / 降级是四种药,治四种病,不能混成一句"加了重试"。
- 超时治"卡住":Agent 每一步都在等别人——模型生成、工具调用、下游接口,任一环节不回应就会永远卡死、拖垮整条链路。超时把"无限等待"变成"有界失败"。
- 重试治"暂时性错误":网络抖动、限流、对方恰好重启,再试一次往往就好了。但前提是——失败是暂时的、而且操作是安全的。
- 退避治"重试本身造成的拥堵":下游已经过载才超时,你立刻重试等于再踩一脚油门,所以越失败等越久(指数退避),再加随机抖动让大量客户端错峰。
- 降级治"核心依赖彻底断了":模型挂了就不回答吗?不——换简单方案,用模板回复 + 转人工,先保住"用户得到回应"这条底线。
举个例子:某零售企业的商品问答,查库存接口 500ms 无响应就超时;超时后再试 2 次、间隔 1s/2s/4s;连续失败则降级为"库存信息暂不可用,已为您转人工",而不是让用户干等或收到一句"系统错误"。
2. 幂等:让"重试"从灾难变成安全网。 查库存失败重试没关系(读是幂等的),但"创建订单""扣库存"这类写操作重试就是复制——第一次的响应丢了,客户端再发一次,就产生两张单。幂等说白了,就是给"这一次请求"一张身份证:客户端在发起前生成唯一幂等键,同一请求无论到达多少次,服务端按键去重、只执行一次。举个例子:会议 Agent 用"会议 ID + 行动项序号"生成键 M-1021-A03,建任务前先查键、存在即跳过、写入时把键一起存。三个细节——客户端生成键、重试不换键、数据层加唯一约束——缺一不可(见下方边界)。
3. 成本按"一次任务"算,不按"一次对话"算。 一次任务是一条多步流水线:可能调 3 次模型、2 次工具、1 次检索;重试和退避再把每个环节的调用次数翻几倍——一次失败的任务可能调 9 次模型才放弃。按"一次对话"记账会严重低估真实成本。优化顺序是:先减无效调用(砍重复检索、缩短上下文、少重试)→ 换小模型(只在必须精度的环节用大模型)→ 最后才砍功能,因为功能是用户价值,不该从它开刀。
4. 长链路可靠性是"乘积",不是"平均"。 10 个步骤各自 95% 成功率,听起来很高,但整条链路一次走完的成功率是 0.95¹⁰ ≈ 60%——单步再可靠,链路一长就塌方。所以企业 Agent 上线要的是"整条链路稳定达标",不是"每一步看着都还行"。应对之道不是把每步做到 100%(做不到),而是三层:用重试/降级压低每步失败率、用幂等消灭"重试带来的次生事故"、再用人工兜底接住最后 40% 里最危险的部分。
常见误区 / 边界
- 别无限重试、别对写操作裸重试:失败一次重试一次、越重试越堵,还会复制单据;重试必须有上限,写操作必须先幂等。
- 别把"重试"当通用开关:参数错误、权限不足是确定性错误,重试一百次也没用,直接报错;只重试暂时性错误。
- 别用"标题/内容"当幂等键、别在重试时重新生成 ID:业务值会变、会撞车;键一变,幂等就失效,重试变成复制——用客户端生成的稳定唯一键,且数据层加唯一约束。
- 别按"一次对话"算成本:按"一次任务的完整调用链 × 重试放大系数"算总账。
- 别为省几分钱砍体验:优化顺序是"先减无效调用 → 换小模型 → 最后砍功能",不能反过来。
- 别把"任务成功"和"消息送达"当一回事:一个"状态"背后常藏着三个状态(任务执行完 / 结果已保存 / 人已看到),日志要分开记,否则"完成了但没人知道"。
一句可带走的话
让它会坏,但坏得起:出错了自己恢复、重复了不重复干、成本按一次任务算——可靠性不是消灭错误,而是让错误变得便宜、可控、可追溯。
案例包 · 15 题自测
展开查看
15 道题分三块,各约 5 道:第 1–5 题讲重试对写操作是灾难、幂等键、日志任务 ID;第 6–10 题讲超时/重试/退避/降级四个词分清、分状态日志;第 11–15 题讲成本按"一次任务"算。
每题都有解析,容易错的地方标了出来。大家错得多的题,就是直播时要重点讲的。
- (单选)下面哪个操作失败后,可以直接无脑重试,不用担心重复?
- A. 创建工单
- B. 扣减余额
- C. 查询库存
- D. 发送下单成功短信
答案:C | 解析:查询库存是读操作,重复执行不改变结果;创建、扣减、发送都是写操作,重试可能重复执行。
- (单选)幂等键的作用是?
- A. 让请求更快
- B. 同一请求重复到达时,只执行一次
- C. 加密请求
- D. 压缩请求体
答案:B | 解析:幂等 = 同一输入重复执行结果不变;幂等键让系统能识别"这已经是同一次请求"。
- (判断)查库存失败可以重试,创建工单失败也可以直接重试,两者一样安全。
答案:错 | 解析:读操作重试安全;创建工单是写操作,重试可能建出两个,必须先带幂等键。 容易错:很多人以为"重试 = 保险",对写操作也直接重试,结果复制出重复单据。
- (单选)重试时,每次重试都"重新生成一个随机 ID"当作幂等键,会导致?
- A. 更安全
- B. 幂等键失效,每次重试被当成新请求,重复建单
- C. 响应更快
- D. 日志更全
答案:B | 解析:幂等键必须在"同一次业务请求"内保持不变,重试要沿用第一次生成的键,否则去重失效。 容易错:很多人以为"每次随机更安全",其实恰恰破坏了幂等。
- (单选)日志里没有"任务 ID / 幂等键",出了事故最大的问题是?
- A. 查不到花了多少钱
- B. 连"是哪一次请求"都说不清,没法复现
- C. 看不到用了哪个模型
- D. 不能统计耗时
答案:B | 解析:没有任务 ID,日志就是一堆孤立事件,出事时定位不到具体哪次运行。 容易错:很多人只关心"记没记",不关心"能不能定位到哪一次"。
- (单选)"设一个等待上限,到点就放弃,不再等"是哪个动作?
- A. 重试
- B. 退避
- C. 超时
- D. 降级
答案:C | 解析:超时 = 等太久就放弃,避免无限挂起。
- (单选)"越失败,等得越久再试下一次"是哪个动作?
- A. 超时
- B. 退避
- C. 降级
- D. 幂等
答案:B | 解析:退避(backoff)= 失败后把重试间隔拉长,避免把下游越打越堵。
- (单选)模型挂了,系统自动改用"模板回复 + 转人工",这是?
- A. 重试
- B. 退避
- C. 降级
- D. 超时
答案:C | 解析:降级 = 换一个更简单但可用的方案兜底,保证用户仍拿到出口。
- (判断)"重试 3 次"和"退避"是同一个意思。
答案:错 | 解析:重试管"试几次"(次数),退避管"两次之间等多久"(间隔),要搭配使用。
- (单选)日志里只有一条
task_status: 完成,你查不出什么?- A. 用了哪个模型
- B. 结果有没有保存、人有没有看到
- C. 花了多少钱
- D. 谁发的请求
答案:B | 解析:一个"状态"背后其实是三个状态——task_status(跑完没有)/ result_saved(存了没有)/ human_seen(人看到没有),要分开记。 容易错:很多人以为 task_status=完成 就万事大吉,忘了"任务成功"和"消息送达"是两件事。
- (单选)"成本按一次任务算"指的是?
- A. 只看一次对话的最后一条回复
- B. 一次任务里所有模型调用 + 工具调用的总账
- C. 只看模型调用,不算工具调用
- D. 按月均摊
答案:B | 解析:一次任务可能调 3 次模型 + 2 次工具,要算总账,不能按"一次对话"或"最后一次回复"算。
- (判断)一次任务调了 3 次模型 + 2 次工具,算成本时只算最后一次模型调用就够了。
答案:错 | 解析:3 次模型 + 2 次工具都要算,漏算工具调用会严重低估真实成本。
- (单选)想降成本,正确的优化顺序是?
- A. 先砍功能 → 换小模型 → 最后减无效调用
- B. 先减无效调用 → 换小模型 → 最后砍功能
- C. 直接砍功能
- D. 换最便宜的模型
答案:B | 解析:先减无效调用(不花钱)→ 换小模型(同任务用小模型)→ 最后才砍功能(伤体验)。
- (判断)为了省几分钱,把"转人工"去掉、让用户干等,是可以接受的成本优化。
答案:错 | 解析:不要为省几分钱砍用户体验;降级要给出口(转人工),不能让用户卡死。
- (单选)无限重试(失败一次就立刻重试一次,不限次数)最直接的后果是?
- A. 响应变快
- B. 失败一次重试一次,越重试越堵,把下游打挂
- C. 省钱
- D. 更安全
答案:B | 解析:无上限、无间隔地重试,等于在故障点上不断加压,越堵越死;正确做法是"有限次数 + 退避"。 容易错:很多人以为"重试越多越稳",其实无限重试本身就是新故障。
案例包 · 案例拆解素材
对应:第 13 讲「可靠性工程」
课堂用时:案例拆解 45 分钟(直播 75–120)
材料与提示词思路:全部写在这个文件里
1. 客户与场景
启衡精密(制造企业)的报销预审 Agent 会自动建任务。一次网络卡顿,用户点了两次"提交",系统建出两条重复任务;两周累计 200 多条重复。
讲师点评直接点破:"你没有做客户端幂等。"
2. 为什么这个案例值得教
- 真实数字讲清"长链路不可靠":10 个独立步骤各 95% 成功率,整条链路一次走通的理论成功率只有约 60%;
- 企业 Agent 上线硬门槛:整条链路准确率稳定在 90% 以上,其余风险靠人工兜底;
- 它把"超时 / 重试 / 幂等 / 降级 / 成本"五个词串进一个真实故障里。
3. 原始材料(真实故障)
故障:两次运行日志,第二次 source_meeting = null,系统无法判断"这条已经建过了",于是重复建单。
修复:
- 用
会议ID + 行动项序号生成幂等键(如M-1021-A03); - 建任务前先查"这个键存在吗",存在就跳过;
- 写入时把幂等键一起存;
- 补一条测试:同一输入连跑 3 次,只允许建 1 组。
4. 故意埋的三个坑
坑 1:只在应用层去重,没在数据层加唯一约束
并发时还是重复。正确:应用层 + 数据层双保险。
坑 2:用"任务标题"做去重键
两个不同会议有同名任务,会被误删。正确:用稳定的业务 ID,不用会变的标题。
坑 3:重试时重新生成了 ID
幂等键失效。正确:同一个请求始终带同一个键。
5. 两版提示词思路(内联)
- v1(故意有缺陷):无幂等键、无重试上限、日志不分状态。
- v2(修复后):幂等键 + 有限重试 + 日志分开记
task_status / result_saved / human_seen+ 失败转人工。
6. 验收样例(3 条)
| # | 场景 | 期望 | 判定 |
|---|---|---|---|
| 1 | 同一输入连跑 3 次 | 只建 1 组任务 | 通过 |
| 2 | 接口超时后重试 | 有限重试,不无限重试 | 通过 |
| 3 | 任务"成功"但没写进约定表 | 日志能区分"执行成功 / 结果保存 / 人看到" | 通过 |
7. 案例拆解 45 分钟流程
| 分钟 | 做什么 |
|---|---|
| 0–5 | 抛"连点两次提交,重复付款"的真实后果 |
| 5–15 | 找坑:应用层才去重 / 标题做去重键 / 重试重新生成 ID |
| 15–30 | 判对错:用 v1 检查这段日志,看它能不能发现重复 |
| 30–40 | 给修复:幂等键 + 唯一约束 + 分状态日志,重跑 |
| 40–45 | 收口:重试对"写操作"是灾难;"任务成功"和"消息送达"是两件事 |
8. 一句话总结
10 个步骤各 95% 成功,整条链路只有 60%——生产系统必须在关键节点校验、恢复、兜底;写操作必须幂等。
案例包 · 课后操作单
目标:给你的项目加"幂等 + 有限重试 + 分状态日志 + 降级"这四样,做 5 类故障演练修 2 类,重跑第 12 讲测试集。
时间:课后 90 分钟。
你要交的东西
- 一份故障演练记录:重复提交 / 超时 / 返回丢失 3 次演练,每次记下现象和修复;
- 一张延迟 / 成本表:按"一次任务"算总账(3 次模型 + 2 次工具各多少,不是按"一次对话");
- 项目里加上的这四样:幂等键 + 有限重试(≤3 次、退避)+ 分状态日志 + 降级。
步骤
第 1 步:找出最危险的写操作,定幂等键(15 分钟)
- 在你的项目里列一个"会写库/发通知/扣减"的操作清单。
- 挑最危险的一个,定幂等键规则(如"会议ID + 行动项序号"),写清格式和样例。
- 确认:幂等键在同一次业务请求内保持不变,重试沿用,不重新生成。
第 2 步:加有限重试 + 退避(15 分钟)
- 把"失败就重试"改成:最多重试 3 次,间隔指数退避(如 1s → 2s → 4s)。
- 读操作可重试,写操作重试前先查幂等键。
- 把"无限重试"删掉,写一句说明为什么。
第 3 步:分状态日志(15 分钟)
- 找到只记一个"完成/失败"的地方,拆成三个状态:task_status / result_saved / human_seen。
- 每条日志带上任务 ID / 幂等键,出事能定位到"哪一次"。
第 4 步:加降级(15 分钟)
- 给模型调用加一个降级出口:模型挂了 → 模板回复 + 转人工(或缓存结果),不让用户卡死。
- 给下游慢/超时加超时上限,到点走降级。
第 5 步:故障演练 + 延迟成本表(30 分钟)
- 做 3 次演练:①重复提交同一请求 → 只执行一次;②模拟超时 → 触发有限重试不复制;③模拟返回丢失 → 日志能看到"结果没送达人"。
- 做一张延迟 / 成本表:一次任务里每个模型调用、每个工具调用的延迟和成本,算总账。
- 做 5 类故障演练(重复提交 / 超时 / 返回丢失 / 模型挂 / 下游慢),修其中 2 类。
课后作业
- 把 5 类故障演练做完,至少修 2 类,写进演练记录。
- 重跑第 12 讲的测试集,确认可靠性改造没有破坏原有功能(回归不倒退)。
- 写 100 字:你的项目里,哪个"写操作"最危险?幂等键怎么定、为什么不能用标题?
达标标准(这节课你该会的)
- 能说清"幂等"是什么,并保证同一请求重复提交只执行一次;
- 能分清超时、重试、退避、降级四个动作,出错时给出用户能看懂的提示;
- 能按"一次任务"算成本,并能从日志还原一次失败"卡在哪一步、花了多久、花了多少"。
常见错误
- 只做应用层去重,没加数据层唯一约束 → 并发重复。
- 用"标题/名称"做幂等键 → 撞名误删。
- 重试时重新生成 ID → 幂等键失效。
- 日志只记一个"完成" → 出问题查不出是哪一次。
- 成本只看"一次对话",漏掉工具调用 → 低估真实成本。
- 无限重试 → 越堵越死,把下游打挂。
案例包 · 教师脚本(教师用)
展开查看
课前准备
- 把启衡精密重复建单日志 + 幂等键修复方案准备好(见 case_card.md)。
- 自己先跑 v1,确认它无幂等、无重试上限。
- 开课前看一眼 quiz 的错误率,圈出大家错得多的题。
0–30|把核心快速过一遍(3 个点)
- 重试是好事,但对"写操作"重试是灾难(10 分钟)— 用幂等键。
- 超时/重试/退避/降级四个词分清(10 分钟)。
- 成本按"一次任务"算(10 分钟)。
30–75|挑大家做错的题讲
- 无限重试 → 越重试越堵。
- 重试写操作 → 没幂等键,重试就是复制。
- 日志没有任务 ID → 出事了连"哪一次"都说不清。
75–120|拆一个真实案例:启衡精密,重复建单与长链路
抛故障(5 分钟):启衡精密报销预审 Agent 自动建任务,网络卡了一下,用户点了两次"提交",建出两条重复任务。讲师点评:"你没有做客户端幂等。"
找坑(12 分钟):三组分别暴露①只在应用层去重、没在数据层加唯一约束;②用"任务标题"做去重键;③重试时重新生成了 ID。
判对错(10 分钟):看两次运行日志(第二次 source_meeting = null),问"系统能判断这条已经建过了吗?"——不能。
给修复(13 分钟):①用 会议ID+行动项序号 生成幂等键;②建前先查;③写入存键;④补测试"同一输入连跑 3 次只建 1 组"。
长链路(5 分钟):10 个独立步骤各 95% 成功率,整条链路一次走通只有约 60%;企业 Agent 上线硬门槛是"整链准确率稳定在 90% 以上"。
标准答案
- 幂等键:
M-1021-A03(会议ID + 行动项序号)。 - 同一输入连跑 3 次 → 只建 1 组。
- 日志分开记 task_status / result_saved / human_seen。
学生会错在哪
- 无限重试。
- 重试写操作。
- 只在应用层去重。
- 用标题做去重键。
- 日志没任务 ID。
评分点(每条 1 分,共 5 分)
- [ ] 幂等键生成正确(业务 ID,不是随机数);
- [ ] 建前先查 + 数据层唯一约束;
- [ ] 有限重试 + 失败转人工;
- [ ] 日志分状态(task_status/result_saved/human_seen);
- [ ] 能说清"10 步×95% = 60%"这个长链路道理。
如果学生问"重试两次是不是太保守"
回答:写操作宁可少重试、多重试前先查幂等键;读操作可以多试几次。关键是"重试会不会产生副作用"——有副作用就上幂等 + 人工兜底。