Skip to main content
Agent 能不能上线,最后都落在稳定性上。上下文、状态、重试和失败放大,这四件事我一般会一起考虑,单加重试和超时解决不了。

Q1: 如何让 Agent 长时间稳定工作?

1

Agent 的长时间运行困境

LLM 的上下文窗口有限(128K/200K tokens),长时间运行会填满。Agent 会忘记最初的目标(上下文漂移),小错误逐步放大(错误累积),进程可能中断(网络、OOM、超时)。
2

致命痛点: 上下文窗口溢出

当 Agent 长时间连续工作,上下文窗口终会被填满。如果直接截断,Agent 会丢失关键信息。如果从头开始,之前的工作全部白费。
3

方案 1: 上下文压缩 (Context Compression)

定期压缩上下文,保留关键信息,丢弃噪音。用小模型(如 Haiku)总结历史对话,只保留事实和决策,丢弃中间推理过程。
4

方案 2: Session 分段 + 自动接续

把长时间任务拆成多个 session,每个 session 结束时保存”交接笔记”(Brief),下一个 session 开始时自动加载。
5

方案 3: 检查点 + 恢复

用 Checkpoint 保存执行状态,中断后从最近的 checkpoint 恢复,而不是从头开始。
Agent 长时间稳定解决的核心问题:
Agent 长时间运行的核心问题:
Agent 长时间稳定的核心是”分段 + 压缩 + 检查点”——把长任务拆成短 session,定期压缩上下文,用 checkpoint 保存状态。

没有稳定性方案

你让 Agent 连续工作 8 小时写一个项目。3 小时后上下文溢出,Agent 忘记了之前的设计决策,开始重复劳动。6 小时后进程 OOM 崩溃,所有进度丢失,从头再来。

引入稳定性方案

你把任务拆成 10 个 session,每个 session 结束时保存交接笔记和 checkpoint。第 5 个 session 中断了,从 checkpoint 恢复继续。上下文用 Haiku 定期压缩,只保留关键决策和事实。
回答时先说”为什么”(上下文窗口溢出 + 状态丢失),再说”怎么解决”(上下文压缩 + session 分段 + 检查点恢复)。想听的是你实际处理过这些问题,而不只是理论。

Q2: 上下文压缩和 Session 分段怎么实现?

上下文压缩的本质是保留关键信息,丢弃噪音。核心逻辑只有 3 步:
压缩时保留什么、丢弃什么,决定了 Agent 能否正确接续工作。
  • 必须保留:技术决策(“用 Zustand 不用 Redux”)、任务目标(“实现用户登录模块”)、关键约束(“不要修改 API 层”)
  • 可以丢弃:中间推理过程、工具调用的原始输出、已验证的中间结果
  • 判断标准:如果这条信息对下一步工作有直接影响,保留;否则丢弃
Agent 长时间运行就像一个人连续加班 8 小时。到了第 4 小时,他需要把前 4 小时的工作整理成交接笔记(上下文压缩),然后休息一下(新建 session),醒来后看交接笔记继续工作(自动接续)。交接笔记不能太长(压缩),也不能太短(保留关键信息),要让”下一个自己”能无缝接续。

Agent 稳定性的五大挑战

Agent 长时间运行面临五个核心挑战,每个都需要专门的应对策略:

上下文漂移的检测与预防

上下文漂移是指 Agent 在长时间运行中逐渐偏离最初的目标。检测方法:定期把当前状态和最初的目标做语义相似度比较,如果相似度低于阈值,强制 Agent 回顾目标。

Q3: 多 Agent 如何共享记忆?

基础梳理

专家视角深度剖析

记忆冲突怎么解决?

记忆分层架构

Agent 的记忆不是扁平的——它有层次结构,不同层次有不同的保留策略和访问频率:

记忆的遗忘曲线

不是所有记忆都应该永久保留。频繁访问的记忆应该强化,长期未访问的记忆应该自动淘汰。这和人类的记忆机制类似——你记得住上周的会议内容,但记不住去年的。

Q4: 检查点(Checkpoint)机制怎么实现?

Checkpoint 的三个核心能力:
Checkpoint 的存储后端选择:开发环境用 MemorySaver(内存,重启丢失),生产环境用 PostgreSQL(持久化、多实例共享)。关键配置:thread_id 用于区分不同的任务,checkpoint_ns 用于区分同一个任务的不同阶段。

Q5: Token 消耗怎么优化?

1

Token 消耗的核心问题

Agent 长时间运行的 token 消耗是最大的成本痛点。一个 5 小时的任务,如果每轮对话都带上完整历史(100K tokens),总消耗可能达到数百万 tokens,费用上百美元。优化的核心是”减少不必要的 token”。
2

上下文压缩(Context Compression)

定期用小模型(Haiku)压缩历史对话。把 100 条对话记录压缩为 10 条结构化事实,只保留关键决策和约束,丢弃中间推理过程。压缩比可以达到 20:1(100K → 5K tokens)。
3

摘要链(Summary Chain)

多 Agent 系统中,Agent 之间传递信息时用摘要替代全文。Agent A 的输出有 1000 tokens,传给 Agent B 前先用小模型压缩为 100 tokens 的摘要。这样 Agent 间的通信开销降低 90%。
4

选择性记忆(Selective Memory)

不是所有信息都需要记住。用重要性评分决定保留什么:技术决策(必须保留)、关键约束(必须保留)、中间推理过程(可以丢弃)、工具调用的原始输出(可以丢弃)。频繁访问的记忆强化,长期未访问的记忆自动淘汰(遗忘曲线)。
5

Token 预算管理(Token Budget Management)

设置每个 Agent 的 token 预算上限和整个工作流的总预算。超出预算时降级到更简单的处理方式(强模型→弱模型,完整分析→摘要分析)。这是成本控制的最后防线。
Token 消耗优化的核心策略:
Token 优化的核心是”只保留必要的”——压缩历史、摘要传递、选择性记忆、预算控制。

模型分级策略

不同复杂度的任务用不同模型,是 token 优化最有效的手段:
Token 优化就像家庭记账。上下文压缩是把一个月的消费小票整理成一张汇总表(100 张→1 张)。摘要链是妻子告诉丈夫”今天花了 200 块买菜”,而不是把每张小票都念一遍。选择性记忆是只记大额支出(房租、工资),日常零钱不记。模型分级是买菜用普通袋子(便宜),装贵重物品用好袋子(贵)。Token 预算是每月设定消费上限,超了就降低生活标准(降级到弱模型)。

Q6: Agent 的错误处理怎么做?

1

Agent 错误的特殊性

Agent 的错误和传统软件不同。传统软件的错误是确定性的(同一输入必然产生同一错误),Agent 的错误是概率性的(同一输入可能成功也可能失败,因为 LLM 的输出是不确定的)。这意味着 Agent 的错误处理需要更灵活的策略。
2

重试策略(指数退避)

对于临时性错误(网络超时、API 限流),用指数退避重试。第 1 次等 1 秒,第 2 次等 2 秒,第 3 次等 4 秒。加随机抖动(Jitter)防止多个 Agent 同时重试导致雪崩。区分临时性错误(可重试)和永久性错误(不可重试)。
3

降级策略(Fallback)

重试仍然失败时,降级到更简单的处理方式:强模型降级为弱模型(gpt-4o → gpt-4o-mini)、完整分析降级为摘要分析、自动处理降级为人工处理。降级的目标是”保证系统不中断”。
4

死循环检测与超时控制

Multi-Agent 系统中最危险的错误是死循环——Agent A 认为应该让 B 处理,B 认为应该让 A 处理。解决方案:设置最大循环次数(maxIterations)、状态变化检测(连续两轮输出相同则强制终止)、全局超时控制(整个工作流的最长执行时间)。
Agent 错误处理的核心策略:
Agent 错误处理的核心是”重试 + 降级 + 防死循环”——临时性错误重试,重试失败降级,死循环检测 + 超时兜底。

重试策略:指数退避 + 随机抖动

降级策略:多层 Fallback

死循环检测与超时控制

错误处理的决策树

Agent 错误处理就像快递配送。重试策略是快递员第一次送没人签收,等 1 小时后再来,再等 2 小时再来(指数退避)。多个快递员同时来会导致门口拥堵(随机抖动防止雪崩)。降级策略是快递送不到就放驿站(强模型→弱模型),驿站也放不了就退回发件人(降级到规则引擎)。死循环检测是快递员在两个地址之间来回跑(A 说送到 B,B 说送到 A),系统检测到后强制送到最近的代收点(强制终止)。超时控制是包裹必须在 3 天内送达,超时就自动退回(全局超时兜底)。

底层源码:Agent 记忆系统的实现

agentmemory 用 REST API 提供记忆服务(详见 agentmemory GitHub):

及格回答 vs 满分回答

问题:“Agent 长时间运行怎么保持稳定?”

及格回答(60-70分):
“分段 session、定期总结上下文、用 checkpoint 保存状态。”
问题出在:知道方案但不理解细节。 满分回答(90-100分):
“Agent 长时间运行的核心问题是上下文窗口溢出和状态一致性。上下文窗口溢出:LLM 的上下文窗口是有限的(如 200K tokens),长时间运行会填满。解决方案是上下文压缩——用 4 层记忆模型(working → episodic → semantic → procedural),定期用小模型(Haiku)压缩原始记录为结构化事实,丢弃中间推理过程,保留关键决策和约束。[1]”
“状态一致性:多个 Agent 并行运行时需要共享状态。方案有三种:MCP Server(所有 Agent 连接同一个记忆服务器,共享 SQLite 数据库,最推荐)、REST API(集中式记忆服务,支持远程访问)、共享文件系统(最简单,所有 Agent 读写同一个 markdown 文件)。记忆冲突用时间戳优先或写入锁解决。[2]”
“容错设计:Agent 中断后用 checkpoint 恢复(LangGraph 的 Checkpoint 机制,每个节点执行后自动保存状态快照)。Session 分段把长任务拆成多个短 session,每个 session 结束时保存交接笔记(Brief),下一个 session 开始时自动加载。quest 完成后自动 cascade-unblock 依赖它的其他任务。[3]“

常见追问

答题要点: 说出信息保留的判断标准和压缩策略。高分回答: “用重要性评分决定保留什么:
  1. 必须保留:技术决策(‘用 Zustand 不用 Redux’)、任务目标(‘实现用户登录模块’)、关键约束(‘不要修改 API 层’)。这些信息对下一步工作有直接影响。
  2. 可以丢弃:中间推理过程、工具调用的原始输出、已验证的中间结果。这些信息已经完成了使命,不影响后续工作。
  3. 压缩策略:用小模型(Haiku)做压缩,把 100 条对话记录压缩为 10 条结构化事实。压缩时保留事实和决策,丢弃推理过程。频繁访问的记忆强化,陈旧记忆自动淘汰(遗忘曲线)。”
答题要点: 说出三种冲突解决策略。高分回答: “记忆冲突有三种解决策略:
  1. 时间戳优先:最新的信息覆盖旧的。简单有效,但可能丢失旧信息中的有效部分。
  2. 写入锁:同一时间只有一个 Agent 可以写入。避免冲突,但降低并行度。
  3. 人工审核:关键决策需要人类确认。Agent A 记录’用 Redux’,Agent B 记录’用 Zustand’,冲突时交给人类决定。
实际项目中通常组合使用:普通信息用时间戳优先,关键决策用人工审核。MCP Server 的 SQLite 支持事务,可以实现原子写入,避免部分写入导致的不一致。”
答题要点: 说出三个关键策略。高分回答: “token 成本控制有三个关键:
  1. 模型分级:80% 的简单任务用 gpt-4o-mini(便宜 10 倍),20% 的决策用 gpt-4o。不同 Agent 用不同模型——格式化用弱模型,决策用强模型。
  2. 上下文压缩:定期压缩历史对话,只保留关键信息。100K tokens 的历史压缩为 5K tokens 的摘要,节省 95% 的 token。
  3. Prompt Cache:Anthropic 的 Prompt Cache 可以节省 90% 的输入 token 费用。把稳定的 System Prompt 放在前面,变化的用户输入放在后面,相同前缀的请求直接复用缓存。”
答题要点: 说出 checkpoint 恢复和 session 接续两种方案。高分回答: “Agent 中断恢复有两种方案:
  1. Checkpoint 恢复(LangGraph):每个节点执行后自动保存状态快照。中断后从最近成功的 checkpoint 恢复,不需要从头开始。配置 retry_policy 可以自动重试失败的节点。
  2. Session 接续(Guild):把长任务拆成多个 session,每个 session 结束时保存交接笔记(Brief)。中断后新建 session,加载交接笔记继续工作。关键是交接笔记要包含:已完成的任务、未完成的任务、关键决策、当前约束。
选择标准:短任务(1 小时以内)用 checkpoint,长任务(超过 1 小时)用 session 分段 + checkpoint。两者可以组合使用——session 内用 checkpoint,session 间用交接笔记。”
答题要点: 说出目标漂移的检测方法和预防措施。高分回答: “目标漂移(Goal Drift)是 Agent 长时间运行的常见问题。检测方法:
  1. 语义相似度检测:定期把当前状态的摘要和最初的目标做 Embedding 相似度比较。如果相似度低于 0.7,说明 Agent 偏离了目标。在每个 session 结束时自动检测。
  2. 里程碑检查:把大目标拆成多个里程碑,每个 session 结束时检查是否完成了当前里程碑。如果连续两个 session 没有推进里程碑,说明可能偏离了。
  3. 定期回溯:在每个 session 开始时,强制 Agent 回顾最初的目标和已完成的工作。这就像项目经理每天早上开站会——回顾昨天做了什么、今天计划做什么、有什么阻碍。
预防措施:在 session 的 Brief 中明确写上’当前目标’和’已完成的里程碑’,Agent 加载 Brief 时会自动回顾。”
答题要点: 说出错误累积的原因和三种应对策略。高分回答: “错误累积是指小错误在 Agent 长时间运行中逐步放大。例如 Agent 选了一个不合适的库,后续所有代码都基于这个库,最后整个项目都要推翻重来。应对策略:
  1. Reviewer 节点:在关键决策点加 Reviewer Agent,检查前一个 Agent 的输出是否合理。Reviewer 发现问题时,回滚到上一个 checkpoint 重新执行。这是’代码审查’的 AI 版本。
  2. 里程碑验证:每个里程碑完成后,用独立的 Agent 验证成果。如果验证失败,回滚到里程碑开始前的 checkpoint。这比等到最后才发现问题要好得多。
  3. 人工检查点:对于高风险决策(技术选型、架构设计),在 Agent 执行前加 interrupt 节点,等待人类审批。人类可以修改 Agent 的建议,或直接否决。”
答题要点: 从错误分类、退避策略、降级方案三个维度回答。高分回答: “重试和降级策略的设计:
  1. 错误分类:区分临时性错误(网络超时、API 限流,可重试)和永久性错误(参数错误、权限不足,不可重试)。只有临时性错误才重试。
  2. 退避策略:用指数退避(Exponential Backoff)+ 随机抖动(Jitter)。第 1 次等 1 秒,第 2 次等 2 秒,第 3 次等 4 秒。随机抖动防止多个 Agent 同时重试导致雪崩。
  3. 降级方案:重试 3 次仍然失败时,降级到更简单的处理方式:强模型降级为弱模型(gpt-4o → gpt-4o-mini)、完整分析降级为摘要分析、自动处理降级为人工处理。
  4. 熔断机制:如果某个 Agent 连续失败 5 次,暂时禁用它,避免浪费 tokens。5 分钟后自动恢复。这和微服务的 Circuit Breaker 模式一样。”
答题要点: 从压缩、缓存、模型分级三个维度回答成本控制。高分回答: “Agent 长时间运行的 Token 成本控制有三个关键:
  1. 上下文压缩:定期压缩历史对话,只保留关键信息。100K tokens 的历史压缩为 5K tokens 的摘要,节省 95% 的 token。用小模型(Haiku)做压缩,成本极低。
  2. Prompt Cache:Anthropic 的 Prompt Cache 可以节省 90% 的输入 token 费用。把稳定的 System Prompt 放在前面,变化的用户输入放在后面。相同前缀的请求直接复用缓存的 KV Cache。
  3. 模型分级:80% 的简单任务用 gpt-4o-mini(便宜 10 倍),20% 的决策用 gpt-4o。在 LangGraph 中,不同节点可以用不同的模型。格式化用弱模型,决策用强模型。
  4. 预算控制:设置每个 Agent 的 token 预算上限。超出预算时降级到更简单的处理方式,或暂停执行等待人类审批。LangGraph 的 maxTokens 配置可以限制单次调用的 token 数。”
答题要点: 从压缩对象、压缩时机、压缩目标三个维度对比。高分回答: “上下文压缩和摘要链都是减少 token 的技术,但应用场景不同:
  1. 上下文压缩(Context Compression):压缩的是 Agent 自身的历史对话。在每个 session 结束时,用小模型(Haiku)把 100K tokens 的历史压缩为 5K tokens 的结构化事实。目标是让 Agent 在下一个 session 中不会因为上下文溢出而丢失关键信息。
  2. 摘要链(Summary Chain):压缩的是 Agent 之间传递的信息。Agent A 的输出有 1000 tokens,传给 Agent B 前先压缩为 100 tokens 的摘要。目标是减少 Multi-Agent 系统中 Agent 间的通信开销。
简单说:上下文压缩是压缩自己的记忆,摘要链是压缩传给别人的消息。两者可以同时使用——Agent 自身的历史用上下文压缩,传给其他 Agent 的信息用摘要链。”
答题要点: 说出三种超预算策略:降级、暂停、告警。高分回答: “Token 预算超了有三种应对策略:
  1. 降级到弱模型:最常用的策略。gpt-4o 降级为 gpt-4o-mini,成本降低 10 倍。虽然输出质量下降,但系统不会中断。在 LangGraph 中,不同节点可以动态切换模型。
  2. 暂停执行等待审批:对于非紧急任务,暂停 Agent 执行,通知用户 token 预算已用完,等待用户决定是否追加预算。这适合成本敏感的场景。
  3. 压缩后继续:如果上下文太大导致 token 消耗高,先压缩上下文(100K → 5K tokens),然后继续执行。这可以释放大量 token 预算。
实际项目中通常组合使用:先压缩上下文,如果仍然超预算就降级到弱模型,如果还是超就暂停等待审批。”
答题要点: 说出三种死循环检测机制。高分回答: “死循环是 Multi-Agent 系统最危险的错误,有三种检测机制:
  1. 最大循环次数(maxIterations):设置 Supervisor 的最大轮转次数(如 10 次)。超过次数强制终止,返回当前最佳结果。这是最简单也最有效的兜底。
  2. 状态变化检测(Stale Rounds):如果连续 N 轮(如 2 轮)的状态没有变化(Agent 的输出和上一轮相同),说明陷入了死循环,强制终止。用 hash 比较输出内容。
  3. 全局超时(Global Timeout):整个工作流的最长执行时间(如 10 分钟)。超时后强制终止。这防止了 Agent 在某些节点卡住的情况。
预防措施:在 Supervisor 的 prompt 中明确写’如果 Agent A 和 Agent B 互相推诿,直接交给人工处理’。LLM 会理解这个指令,从源头避免死循环。”
答题要点: 说出重试→降级的优先级链。高分回答: “重试和降级是两个不同层次的容错机制,配合使用:
  1. 先重试:临时性错误(网络超时、API 限流)用指数退避重试 3 次。第 1 次等 1 秒,第 2 次等 2 秒,第 3 次等 4 秒。大部分临时性错误在重试后能成功。
  2. 重试失败再降级:重试 3 次仍然失败时,降级到更简单的处理方式。降级链是:强模型→弱模型→规则引擎→人工处理。
  3. 永久性错误直接降级:参数错误、认证失败等永久性错误,不需要重试(重试也不会成功),直接进入降级链。
  4. 上下文溢出特殊处理:上下文溢出不是简单的重试——需要先压缩上下文,然后再调用。这是’压缩后重试’,不是’原样重试’。
优先级:重试(临时性错误)→ 降级(重试失败或永久性错误)→ 人工兜底(所有自动策略都失败)。”
答题要点: 从事务、锁、冲突解决三个维度回答。高分回答: “多 Agent 共享记忆的一致性保证:
  1. 事务写入:MCP Server 的 SQLite 支持事务。Agent 写入记忆时,用事务确保原子性——要么全部写入成功,要么全部回滚。避免部分写入导致的不一致。
  2. 乐观锁:每个记忆记录带版本号。Agent 读取时记录版本号,写入时检查版本号是否变化。如果版本号变了,说明其他 Agent 已经修改了,需要重新读取后再写入。
  3. 冲突解决策略:
    • 普通信息:时间戳优先(最新的覆盖旧的)
    • 关键决策:人工审核(冲突时交给人类决定)
    • 结构化数据:CRDT(Conflict-free Replicated Data Type)自动合并
  4. 最终一致性:不需要强一致性——允许短暂的不一致,最终所有 Agent 会看到相同的数据。这和分布式系统的 CAP 定理一样——在分区容错和一致性之间做权衡。“

Q7: 上下文压缩策略有哪些?

Agent 长时间运行时,上下文窗口必然溢出。上下文压缩不是”随便删掉历史”,而是有策略地保留关键信息、丢弃噪音。四种核心策略各有适用场景,通常需要组合使用。

策略 1:滑动窗口(Sliding Window)

只保留最近 N 轮对话,丢弃早期历史。最简单但最粗暴——可能丢失关键决策。

策略 2:摘要链(Summary Chain)

定期用 LLM 把长对话历史压缩为结构化摘要。压缩比可达 20:1(100K tokens 压缩为 5K tokens)。

策略 3:选择性注入(Selective Context Injection)

不是把所有代码文件都塞进上下文,而是用语义搜索只注入与当前任务相关的文件。

策略 4:Token 预算管理(Token Budget Management)

限制每次请求和整体工作流的 Token 数量,超出时触发降级策略。

四种策略的组合使用

实际项目中,四种策略通常组合使用,按优先级依次触发:
上下文压缩不是”随便删历史”,而是四种策略的组合:滑动窗口(简单粗暴)、摘要链(保留关键决策)、选择性注入(只给相关信息)、Token 预算管理(成本兜底)。实际项目中按优先级依次触发。

没有上下文压缩

Agent 运行 2 小时后上下文溢出,忘记之前的代码设计决策,开始重复修改已经完成的文件。Token 消耗失控,一天烧掉 $200。

引入上下文压缩

Agent 运行 2 小时后自动触发摘要压缩,100K tokens 历史压缩为 5K tokens 的结构化摘要。选择性注入只加载当前任务相关的 5 个文件。Token 消耗可预测,一天控制在 $30 以内。
回答时重点说四种策略的适用场景和组合方式,而不是只罗列策略名称。想听的是”我在项目中用选择性注入把 10 万行项目的上下文从 200K tokens 压缩到 10K tokens,再用摘要链每 30 分钟压缩历史,Token 成本从 $200/天降到 $30/天”。

Q8: 重试为什么要分层?哪些错误能重试、哪些绝对不能?

“出错就重试”是新手最危险的本能。重试用错地方,会把一次瞬时故障放大成雪崩。

四层重试,职责不同

分层的意义在于:不同层能承受的重试代价不同。工具层重试最便宜,编排层重试最贵(可能重复副作用),所以越往上越谨慎。

可重试 vs 不可重试

把”Schema 不合法”拿去重试,只会浪费 token 并稳定复现同一个错误。正确做法是带错误信息打回,让模型修正,而不是原样重跑。

指数退避 + 抖动

抖动不是可有可无:没有抖动时,一批同时失败的请求会在同一时刻重试,形成新的尖峰。
重试必须有全局预算,否则”每个请求重试 3 次”在故障时会把流量放大 4 倍。按任务记录剩余重试次数,并设总时间上限,超限直接进入降级或死信。

Q9: 熔断、死信队列、补偿事务分别解决什么问题?

这三个机制经常被混为一谈,其实它们处理的是故障的不同阶段:

熔断器三态

熔断的关键参数是失败阈值、冷却时间、半开探测数量。阈值太低会误伤正常抖动,太高则失去保护意义。多 Agent 场景里,熔断要按 Agent 或工具粒度做,而不是全局一个开关。

死信队列

死信的要点是保留完整上下文。只存一个错误码,等于把问题丢了。

补偿事务 vs 回滚

  • 回滚通常指数据库事务层面的原子撤销。
  • 补偿针对已经对外产生副作用的操作(发消息、调用第三方、上传文件),只能再发一个反向操作去抵消。
补偿必须满足:幂等、可重入、有 trace、有失败兜底(补偿失败要告警,不能静默)。

Q10: Checkpoint / Resume、Canary、混沌测试怎么做才不是形式主义?

Checkpoint 存什么

checkpoint 不是”存一下 state”这么简单,要明确三件事: 恢复时最容易犯错的是重复执行已完成节点。所以恢复逻辑要先读 checkpoint 判断节点状态,而不是从头再跑一遍。

Canary 不是”发 5% 流量”就完事

Canary 的核心是对照与回滚条件:
  • 必须和基线同口径对比:成功率、P95 延迟、单位任务成本、重派率。
  • 必须有自动回滚阈值,而不是靠人盯。
  • 灰度维度要合理:按用户、按任务类型,而不是纯随机。

混沌测试测什么

多 Agent 系统最该注入的故障: 混沌测试的价值在于验证失败路径,而不是证明正常路径能跑。只测 happy path 的系统,等于没测。

Q11: 多 Agent 为什么会把一次小错误放大成系统性故障?

单 Agent 的失败通常是”这一步错了”;多 Agent 的失败往往是”一个错误被结构放大”。三类典型放大:

防线顺序

稳定性不是”让错误不发生”,而是”让错误发生时影响可控、可定位、可恢复”。多 Agent 的每一步都要能回答:错了会怎样?谁来兜底?

八道深度追问:及格 vs 满分

八题覆盖”重试分层 / 错误分类 / 退避抖动 / 熔断 / 死信 / 补偿 / checkpoint / 混沌测试”。

追问 1:重试为什么要分层,不能统一在一个地方重试吗?

及格回答: 分层是为了代码清晰,在哪一层重试都行。 满分回答: 分层的本质是不同层能承受的重试代价不同。工具层重试最便宜,只影响一次调用;模型层重试要重新消耗 token;任务层重试可能重复执行整段逻辑;编排层重派可能重复副作用。如果统一在最外层重试,一次抖动就会被放大成整条链路重跑。所以我按工具、模型、任务、编排四层分别设退避和上限,越往上越谨慎,并在任务维度设全局重试预算。

追问 2:哪些错误可以重试,哪些绝对不能?

及格回答: 网络错误可以重试,其他看情况。 满分回答: 判断标准是”重试能不能改变结果”。瞬时错误可以重试:超时、连接重置、429、503、临时锁冲突。确定性错误不能重试:参数不合法、Schema 校验失败、鉴权失败、业务规则拒绝,以及提示词导致的稳定幻觉——这些原样重跑只会稳定复现。对确定性错误正确做法是带错误信息打回让模型修正,或直接走降级和人工,而不是浪费 token。

追问 3:指数退避为什么一定要加抖动?

及格回答: 加抖动是为了看起来更随机一点。 满分回答: 抖动是为了打散重试的同步性。如果一批请求同时失败、又用同样的指数退避,它们会在同一时刻集中重试,形成新的流量尖峰,把刚恢复的依赖再次打垮。加随机抖动后,重试时间被摊开,削平尖峰。工程上通常取指数部分的一半作为抖动范围,并配合全局重试预算,防止总流量被放大。

追问 4:熔断器和重试是什么关系?

及格回答: 都是处理错误的手段,可以一起用。 满分回答: 它们方向相反:重试是”再试一次”,熔断是”先别试了”。正确组合是先重试、再熔断:瞬时错误靠重试消化,连续失败达到阈值后熔断快速失败,保护下游不被持续打。熔断要有三态——关闭、打开、半开,半开时放少量探测请求决定是否恢复。多 Agent 场景里熔断应按 Agent 或工具粒度做,避免一个依赖挂了拖垮全局。

追问 5:死信队列到底解决什么问题?

及格回答: 存失败的消息,以后再看。 满分回答: 死信解决的是”失败任务不能凭空消失”。重试耗尽的任务进入死信,并保留完整上下文:输入、错误、trace、重试次数、当时的 prompt 和模型版本。没有这些,事后根本无法复现。死信还承载两个动作:告警通知人工介入,以及修复后的延迟重放。只存一个错误码的死信,等于把问题丢掉。

追问 6:补偿事务和回滚有什么区别?

及格回答: 补偿就是回滚,把之前的操作撤销掉。 满分回答: 回滚通常是数据库事务层面的原子撤销,而补偿针对的是已经对外产生副作用的操作,比如发了消息、调了第三方、上传了文件,这些没法真正”撤销”,只能再发一个反向操作去抵消。补偿必须幂等、可重入、有 trace,并且要处理补偿本身失败的情况——补偿失败必须告警,不能静默,否则回滚会变成二次事故。

追问 7:Checkpoint 应该存什么,怎么保证恢复时幂等?

及格回答: 存当前状态,恢复时从断点继续跑。 满分回答: 要存四类东西:任务状态和当前节点、关键产物的版本引用(不存大对象本身)、已执行副作用的 idempotencyKey、以及代码和 prompt 的版本信息。恢复时先读 checkpoint 拿到已完成集合,跳过已完成节点;对”已执行但未确认”的副作用先查真实状态再决定是否重做。很多人恢复时从头重跑,结果重复执行了已完成节点,这就是没有把幂等上下文存进去。

追问 8:多 Agent 系统怎么做混沌测试和 canary?

及格回答: 灰度发一点流量,出问题就回滚。 满分回答: Canary 的关键是对照和自动回滚:和基线同口径比较成功率、P95 延迟、单位任务成本、重派率,并设自动回滚阈值,而不是靠人盯。混沌测试要注入真实故障:工具超时、429 限流、子 Agent 卡死、消息重复投递、对象存储不可用、上下文被截断,重点验证失败路径是否按设计降级、熔断、进死信。只测正常路径等于没测。灰度维度也要合理,按用户或任务类型切,而不是纯随机。

延伸阅读与引用参考