news 2026/9/5 6:01:18

Harness容错与恢复设计:从故障预防到上下文修复的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Harness容错与恢复设计:从故障预防到上下文修复的完整指南

1. 为什么要单独把"容错与恢复"拎出来讲

做 Agent 系统的人应该都有同感:一个 demo 级的 Code Agent 跑通并不难,难的是让它长时间、稳定地在真实环境里干活。而一旦 Agent 从"在受控环境里跑个示例"进入到"让 Harness 去执行真实任务",最先崩溃的往往不是大模型,不是工具 API,而是整体流程的韧性——最典型的表现就是:Agent 卡在某个步骤里反复重试,或者一次小异常直接让整条执行链路报废,几小时的会话功亏一篑。

在继续这个系列之前,我在前面几篇已经拆过 Harness 的上下文管理、规划循环和工具调用框架。当时评论区有位朋友问了一句特别实际的话:"Harness 怎么保证不把自己搞崩溃?"这个问题的答案,就是这次要展开的容错与恢复设计。

需要先说明一点:容错不等于堆 try-catch。尤其在 Harness 这类作为"执行骨架"的组件里,容错的对象不只是代码异常,还包括模型输出格式漂移、工具返回超时、前置任务失败、上下文被污染、用户中途改需求等一连串"非代码层面"的故障。也就是说,Harness 面对的容错压力,比传统后端服务要高一个维度:它不仅要在进程级别不崩溃,还要在执行逻辑层面保证"即使某个环节出错了,整条任务链依然能继续推进或体面地停止"。

这篇不打算泛泛而谈"高可用""故障转移"这些宏大概念。我想聚焦在 Harness 这个特定场景里,把真正值得投入精力的容错设计拆成四层:故障预防、预算熔断、策略化恢复、上下文修复。每一层都会结合我实际搭建和反复踩坑的经验来讲,包括具体怎么设计、参数怎么定、哪里容易想当然。

这篇文章适合已经对 Code Agent 有一定了解、正在思考"怎么让 Agent 更抗造"的开发者。如果你是第一次接触 Harness 的概念,建议先看完本系列前面几篇再回来,否则直接看容错细节会有点跳。

2. 从故障谱系开始:先搞清楚 Harness 到底在防什么

谈容错设计之前,必须先建立一份清晰的故障谱系。我在设计 Harness 容错方案时,第一件事不是写代码,而是把所有已经遇到过的、能想象到的失败场景全部列出来,然后按来源分类。这个动作的价值在于:每一类故障的应对手段完全不同,混在一起处理必然顾此失彼。

2.1 Harness 执行链路中的四类典型故障来源

我在生产环境里实际跑过的 Agent 任务,故障来源基本逃不出下面四类:

第一类:工具层故障。这是最容易被预判到的一类——工具抛异常、返回非预期结构、执行超时、被外部服务限流。比如 Agent 调了一个代码搜索工具,结果那个服务恰好返回 500;或者执行 shell 命令时,因为权限问题直接 Permission denied。这类故障的特点是比较"显性",只要在工具调用边界做了异常捕获,基本能兜住。

第二类:模型层故障。这一类隐蔽得多。大模型返回的"格式不合法"在稳定版模型上已经不常见,但在长上下文中,模型经常出现"逐步偏离指令规范"的行为。典型的例子是:用户明确要求工具返回结果必须是一个 JSON 对象,前 20 轮 Agent 都遵守了,到第 47 轮突然直接输出一段自然语言描述,没有包 JSON 标记。这是 Harness 最需要防的故障之一——模型的行为漂移。严格说这不是"报错",但危害和报错一样大,因为 Harness 一旦无法解析模型输出,整个循环就会停摆。

第三类:外部环境故障。包括网络闪断、依赖下载超时、上游 API 限流、文件系统权限变化、环境变量缺失等。外部环境的诡异之处在于你无法在代码层面"修复"它,只能通过重试、降级、旁路等策略规避。处理这类故障,核心不是"消灭异常",而是"降低故障半径"。

第四类:上下文完整性故障。这一类是 Harness 架构专属的问题,传统后端开发几乎不会遇到。在执行长任务时,Harness 维护的世界状态(World Model)可能因为信息冲突、关键日志被剪掉、记忆覆盖策略过于激进而变得"不可信"。比如 Agent 以为文件已经写好了,实际上写入操作被工具层静默失败了;或者用户已经改了需求,Harness 还按旧目标在跑。这类故障最危险——不报错,但每一步的决策都建立在错误的前提上。

2.2 按"可恢复性"给故障分优先级

我列完这份清单后的第二个动作是给故障分优先级——不是按发生频率,而是按可恢复性。这是我后来处理故障时最重要的判断依据。

高可恢复性的故障:工具一次调用超时、网络瞬断、模型一次输出不合规。这类故障重试一次就能过,不需要改变整体执行策略,处置成本最低。

中等可恢复性的故障:连续多次工具调用失败(可能依赖服务挂了)、模型反复输出同一格式错误(行为漂移的前兆)、部分工具结果可用但另一些失败。这类故障需要切换到替代策略,比如换一个等价的工具查同一份数据。

低可恢复性的故障:上下文已经被污染(关键信息丢了)、用户的最终目标发生变化、执行路径依赖的某个外部服务被完全移除。这类故障重试也没用,必须停下来重新规划。

把这个优先级表画出来之后,容错设计的目标就非常清楚了:把高可恢复性故障用最小成本兜住,避免它们升级成中等或低可恢复性故障;对中等可恢复性故障提供策略切换;对低可恢复性故障做体面的降级与终止。Harness 里所有容错组件,本质上都是为这三层目标服务的。

提示:如果你正在设计自己的 Harness,我强烈建议先花一小时做故障谱系整理,再动手写代码。直接上手写重试逻辑,很容易把方案做成"一把梭"式的全链路重试,最终该失败的还是失败,不该重试的反倒被无限重试拖垮。

3. 故障预防:在容错之前先想办法不让错发生

容错的下限是"出了错能扛住",上限是"让错根本没机会发生"。在 Harness 里,绝大多数故障其实是可以靠设计规避的。这里讲三个我认为投入产出比最高的预防手段。

3.1 工具契约校验:把故障拦截在模型输出之外

之前提到模型行为漂移,一个很有效的预防手段是给每个工具定义严格的契约文件。所谓契约,就是对这个工具的输入输出做结构化定义,包括参数类型、必填字段、取值范围、输出格式模板。Harness 在拿到模型生成的工具调用请求时,不直接执行,而是先通过校验层跑一遍契约检查。

这看起来多了一层开销,但价值极大。工具执行前发现问题,成本只是"拒绝一次调用并生成修正反馈";工具执行到一半才发现传参不合法,成本是"回滚部分副作用+重试+补偿";工具全执行完了才发现结果不是预期格式,成本就变成"上下文已经混入脏数据"了。三者代价天差地别。

具体做法上,我给每个工具写一份 JSON Schema 描述文件,Harness 启动时加载到校验模块。模型每产出一个工具调用意图,校验模块先验证参数结构、必填字段、枚举值是否合法。校验不通过则直接进入"修正循环":把校验失败的具体原因反馈给模型,请它重新生成调用请求。从实际效果看,这个简单的防御动作能拦截掉大约 70% 的"看似能跑实际上必挂"的调用——尤其是文件路径写错、必填参数遗漏这一类低级错误。

3.2 预检与前置条件探测:把外部环境故障提前暴露

外部环境故障里,有一类非常讨厌:不是运行时崩溃,而是前置条件不满足,Agent 跑了一半才发现。比如 Mission 需要访问某个 API,但环境变量里没有配 API Key——如果 Harness 不做前置检查,Agent 会在执行到那一步时才发现问题,然后触发一整轮的排查和降级,浪费时间不说,还可能把已执行步骤的结果污染。

我的做法是在 Harness 的"规划阶段"结束后、进入"执行阶段"前,插入一个轻量的预检步骤:扫描当前 Mission 涉及的所有外部资源,检查凭据是否存在、服务地址是否可达、依赖文件是否就位。预检不是深度测试,而是快速探测,每个项目最多几千毫秒,把所有"一眼就能发现的缺失"暴露出来。

这个设计最初我并没有意识到它的价值,直到有一次跑一个涉及数据库迁移的 Agent 任务,预检发现目标库连接串配的是测试环境地址。如果在执行阶段才暴露,Agent 大概率会在错误的库上执行迁移——那可比超时、报错严重得多。现在预检已经是我所有 Harness Mission 的标配环节。

3.3 模型行为约束:用指令与模板减少漂移空间

模型输出格式的漂移不可能彻底消除,但可以通过约束显著降低概率。我在 Harness 的提示词体系里做了两点约束:

第一,每次调用大模型时,输出格式规范不是放在大段提示词中间,而是单独抽成一个 Fixed Instruction Block,固定在上下文的首部。这个块里用极简的 BNF 式语法描述工具调用的输出格式,不给模型自由发挥的余地。

第二,在 Harness 内部的"最近一轮输出"记忆区里,始终保留上一次工具的调用示例,作为 Few-shot 参考放在模型需要生成调用请求的位置之前。模型在生成当前响应时,旁边就有一个"照着写"的样例,漂移概率会明显下降。

这两招不能做到 100% 规整,但配合前面说的契约校验,可以把模型层故障的实际影响降到非常低——即便模型偶尔写歪了,Harness 也能在校验层就发现问题并进入修正循环,而不是让错误一路传导到工具执行层。

4. 预算熔断:当费用、轮次或耗时失控时强制叫停

容错设计里最容易忽略的一块,是"限制系统能造成的最大损失"。Agent 一旦跑起来,就是一个自主行动的进程——它会持续调用工具、消耗 token、占用执行时间。如果没有止损机制,一次错误的任务规划可能让用户在毫无察觉的情况下烧掉一大笔费用或浪费数小时。

4.1 多维预算:不只是限制 tokens

我做预算熔断时,定义了四个独立的预算维度:

Token 预算:这是最直观的。每轮模型调用消耗的 token 会累积,尤其当上下文很长时,单轮消耗可能非常惊人。我给每个 Mission 设了一个硬上限,超过即终止,避免"上下文越长、每轮越贵、任务越无限循环"的死亡螺旋。

步骤预算:限制 Agent 最多能执行多少轮"推理-调用工具-观察结果"的循环。我通常在 30~50 之间取值,具体看任务复杂度。步骤预算的真正作用是阻断"无限修正循环"——模型在处理某个工具报错时,可能陷入"尝试-失败-再尝试"的重复,步骤预算保证这个循环最多持续 N 轮。

耗时预算:墙上时钟时间超限即终止。这个维度经常被忽略,但很重要:比如用户只希望 Agent 在一个小时内完成代码审查,结果它跑了三个小时——即使 token 没超限、步骤没超限,从用户视角看依然是灾难。

费用预算:通过 token 数折算成成本,设置一个金额上限。这个维度在企业场景特别敏感,因为最终为失控执行买单的是钱。

4.2 软熔断与硬熔断:分级处置而非一刀切

预算耗尽后不是直接杀死进程就完事了。我做了两级熔断:

软熔断:当预算消耗达到阈值的 80% 时触发,Harness 停止向模型发起新的"探索性行动"(比如"再搜索一下相关资料"这类非必要调用),强制切换到收尾模式——只允许模型执行能直接推动 Mission 完成的任务,并提示模型尽快收敛。软熔断阶段,模型仍可正常推理,但不能无限延展探索范围。

硬熔断:达到 100% 时,立即终止所有工具调用和模型生成,回到"执行状态归集"流程。硬熔断触发后,Harness 会把当前已经执行的步骤、已获得的部分结果、未完成的目标整理成一份完整的"中断报告",而不是让执行痕迹散落在日志里。

长期跑下来,预算熔断最大的价值不在于"省钱"——那只是表面收益。真正的价值在于给整个系统定义了失败成本的上限,这让 Harness 更适合无人值守的长时任务:你可以放心地把一个需要跑半小时的 Agent 任务挂后台,而不必担心它因为某个 bug 变成"天价账单生成器"。

提示:预算熔断的阈值不是拍脑袋定的,而是从真实任务样本里统计出来的。初期可以先跑一批已知任务,统计 token 消耗和步骤数的 P85 值(85%的任务都低于该值),把预算上限设为 P85 的 1.5~2 倍。留出余量是为了避免正常波动触发误杀,但要坚决拒绝"怕超就调大"的惰性思维——预算熔断的边界越模糊,它的存在感就越低。

5. 策略化恢复:错误发生之后,是重试、换路还是回退

故障预防做得再好,也不可能消灭所有错误。真正的容错核心在于错误发生后怎么办。我的经验是:恢复策略必须"按场景分类",而不是用一个万能的重试机制去硬扛。

5.1 适配四类故障的恢复方案

针对前面整理的故障谱系,我在 Harness 里设计了四类恢复策略:

瞬时故障 —— 有限重试。网络闪断、服务限流、工具超时这类瞬时故障,直接重试往往能解决。关键是重试要有节奏:我采用指数退避(Exponential Backoff)+ 抖动(Jitter)策略,初始间隔 1 秒,每次翻倍,封顶 30 秒。抖动是为了避免多个 Agent 实例同时重试同一服务导致"惊群效应"。重试次数不是无限,我通常设 3~5 次上限。

持续故障 —— 替代路径。当同一个工具连续重试 3 次还是失败,基本可以判定这不是闪断,而是这个工具/服务当前不可用。此时恢复策略从"重试"切换到"找别的路"——比如代码搜索工具挂了,换用 grep 类命令;HTTP API 超时,改用对应的 SDK 本地实现。替代路径的前提是 Harness 在注册工具时就为每个高危工具登记了可替换的"兄弟工具",并按优先级排序。

状态损坏 —— 回退检查点。如果错误发生在执行链路的中间,而且当前步骤对外部环境产生了副作用(写文件、改配置、发请求),简单重试可能造成重复副作用。这时需要回退到上一个"干净检查点",从那个状态重新规划执行路径。回退检查点的设计细节会在下一节展开,这里先提一句:检查点是一个完整的任务状态快照,不是简单的步骤序号。

目标失效 —— 终止与上报。如果错误导致任务前置条件永远无法满足(比如用户要分析的数据源整个被删了),任何重试和替代路径都没有意义。这时需要的是"体面终止":Harness 输出一份清晰的失败报告,说明为什么无法继续、尝试过哪些路径、还缺什么信息,最后回到初始状态等待用户重新指示。

5.2 动态失败处理:让模型参与恢复决策

前面四种恢复策略都是规则驱动的——预设条件、预设动作。但真实场景里,还有一类情况规则覆盖不到:错误信息模棱两可,既不像瞬时故障,也不像持续故障。比如工具返回了一长串日志,其中有一个 ERROR 关键字,但从日志看任务其实已经成功了。

遇到这种"可读但难判定"的失败,我会把错误上下文(工具返回值前 50 行、退出码、已执行操作列表)打包塞给模型,请求它做一次失败分类,并把分类结果映射到上述四类恢复策略之一。模型不需要重新规划整个任务,只需要回答一个问题:"基于这些信息,你觉得这个错误属于哪一类?应该重试、换路、回退还是终止?"

我一开始对这种"让模型判断错误类型"的做法存疑,但实测下来效果比预期好。原因也简单:大模型的日志模式识别能力远强于规则匹配。人能看出来"Permission denied 意味着什么、Timeout 在什么语境下是暂时的",模型同样能,只需要给它足够清晰的分类提示词。当然,模型判断出错的情况也存在,所以 Harness 层保留了最终否决权——如果模型选择的恢复策略在执行中再次失败,就降级为规则策略兜底。

5.3 恢复策略里的"优先级"和"快速失败"设计

在恢复策略的执行顺序上,我定义了明确的优先级:有限重试 > 替代路径 > 回退检查点 > 终止上报。这个顺序不是按成功概率排的,而是按恢复成本排的——成本从低到高。低成本的策略失败后升到高成本的策略,不会跳跃。

与此配套的是"快速失败"原则:不要在低层策略上反复消耗时间。比如一个工具明明已经连续失败 4 次,如果重试上限是 5 次,就绝不上 10 次——你该做的是快速切换到替代路径,而不是在一条确定走不通的路上多试一次。快速失败意味着把时间让给更有希望成功的策略,这是我在实战中总结的效率铁律。

注意:恢复策略的"重试上限"必须区分幂等和非幂等操作。对于幂等操作(查询、只读分析),可以放心重试;对于非幂等操作(写入、删除、转账),重试前必须确认上一次调用是否已生效。如果无法确认,宁可走"人工确认"分支也不盲目重试,否则同样的副作用会被执行两遍。

6. 上下文修复:让 Agent 在出错后依然保持"清醒"

这部分是我认为整个容错设计里最核心、也最容易被忽视的环节。很多 Harness 的设计者处理完工具层异常、重试策略、预算熔断就觉得"容错做完了"——但真正让 Agent 任务从"撑住不崩"变成"恢复后还能高质量完成"的,是上下文层的修复能力。

6.1 "上下文污染"比工具报错更危险

我给上下文污染的定义是:Agent 依据的世界模型信息与真实世界状态不一致,但 Agent 自己没有感知到。最典型的案例是:Harness 在某一步调用了"写入文件"工具,工具层执行失败被重试机制拦住了,但重试前 Harness 并没有把"这次写入未确认"的标记写入上下文。模型在下一轮规划时就会以为文件已经写好了,于是接下来的所有决策都建立在幻象之上。

上下文污染不报错,但会悄悄侵蚀任务质量。你会看到 Agent 在后面的步骤里正常执行、正常回复,但你最终会发现产出的文件根本不存在,或者代码逻辑里引用了从未创建过的变量。这种故障是最难排查的——因为它不在任何错误日志里。

6.2 执行日志压缩与关键状态摘要

我当前使用的修复方案,是给 Harness 增加一个"执行日志摘要器",在每轮工具调用结束后执行:

  • 保留本轮调用的"操作类型、目标对象、返回码、关键输出片段"作为结构化执行记录;
  • 对超过长度阈值的工具原始输出执行摘要(缩到 200~300 字以内);
  • 标注本轮操作是否"已确认成功""已确认失败""未确认(结果未知)"三类状态;
  • 将摘要结果写入上下文的"执行状态区",同时把旧轮次的原始日志挪进可回收的滚动区,避免上下文膨胀。

这套机制解决了两个问题:一是压住了上下文长度(长任务的上下文不会线性膨胀);二是建立了一个"操作状态表",模型每轮决策前可以先看一眼这个表,确认当前世界状态里哪些操作是实打实成功的、哪些还是悬空的。这是对抗上下文污染的基础设施。

6.3 世界模型回摆:从"继续执行"转向"重新校准"

上下文出现偏差之后,最难的决策是继续还是停止。我的经验是:一旦检测到关键状态的"不确定性",Harness 应该进入重新校准模式——不再继续推进任务,而是先向模型提供当前已确认状态的全部摘要,并明确要求模型回答三个问题:

  1. 基于当前可确认的状态,任务还差几步可以完成?
  2. 之前哪些步骤的前提条件可能已经失效?
  3. 如果要继续,应该从哪一个环节开始重做?

这个过程我称它为"世界模型回摆"——就像开车时发现导航地图和实际路况对不上了,最优策略不是继续闷头开,而是先停到路边,重新定位,再规划新路线。

世界模型回摆的实际价值在下一条会细说。这里先给结论:它是整个容错体系里唯一能"修复"低可恢复性故障的机制。前面说的重试和换路都是绕开错误,只有回摆能修正 Agent 对世界的认知——而认知修正之后,策略失误带来的连锁错误才会被切断。

6.4 检查点快照:故障恢复的"存档点"

检查点机制是上下文修复的载体。我在 Harness 里把"任务的完整状态快照"定义为以下四件套:

  • 任务状态文件:当前目标、已完成的子任务列表、进行中但未确认的任务、待办队列;
  • 执行状态表:每步工具的调用参数、返回摘要、确认状态(成功/失败/未知);
  • 决策轨迹摘要:最近 N 轮的关键决策及其理由,方便回摆时理解"为什么走到了这一步";
  • 环境快照:当前工作目录、关键文件列表、临时文件位置、环境变量状态。

快照的保存时机不是固定时间间隔,而是在关键副作用操作前自动存档——比如写文件前、发请求前、执行破坏性命令前。这样一旦后续出错,回退的粒度不会太粗。

我在长任务中实测的效果是:加了检查点快照之后,一次典型的中途故障恢复时间从"完全从头跑"的小时级,降到"从最近确认状态继续"的分钟级。而且因为上下文里的信息始终以最近一次快照为准,模型不会被历史上已经失败的操作干扰,决策质量明显提升。

7. 真实故障复盘:一次上下文污染引发的完整恢复链路

说再多设计理念,不如看一次真实故障的处理过程。这里复盘一个我印象很深的案例,它能非常清晰地展示"容错与恢复"各层机制是如何串联运作的。

7.1 故障现场:一个"看起来正常但实际全错"的任务

有一次我让 Agent 执行一个复杂的代码迁移任务:把一个旧 Java 项目的核心模块迁移到新框架,涉及十几个文件的读写和编译验证。任务跑到第 23 步时,Agent 调用了文件替换工具,返回码为 0,看起来执行成功。但实际那次操作因为目标文件被进程锁定,替换并没有生效——这是文件替换工具的一个隐藏 bug,它在文件被锁定时会静默失败,只写日志不抛错。

问题在于,Harness 当时的工具契约校验只检查"返回码是否为 0",没有校验"目标文件的内容是否真的变成了预期值"。于是这轮操作被标记为成功,后续步骤全部基于"文件已替换"这个错误前提继续执行。Agent 在第 28 步开始编译验证,发现编译错误,它判断是"新框架代码本身有 bug",开始尝试修复代码——但实际上错误是旧代码没被替换导致的。

从第 28 步到第 40 步,Agent 一直在错误前提上做看似合理的修复。你从日志看,每一步都是"正常执行、正常得出结论",但整体已经在错误道路上狂奔了。这就是上下文污染的典型形态:不是系统崩了,是系统在用一个错误的世界模型指导行动。

7.2 触发恢复:检查点检查发现"未确认状态"

这个故障之所以没有造成不可挽回的后果,是因为检查点机制在发挥作用。Harness 在每个检查点存档时,除了执行状态表,还会对关键副作用操作做一次"确认型探测"——检查目标文件的修改时间、内容哈希、文件大小三个指标是否与预期一致。

在第 23 步的检查点保存后,确认型探测发现目标文件的内容哈希与预期替换版本不一致。Harness 立刻把第 23 步的状态从"已确认成功"改为"未确认(结果未知)",并触发了世界模型回摆模式。

模型拿到更新后的执行状态表后,很快就定位到"文件替换结果存疑"这个关键偏差。在重新校准阶段,模型没有继续推进任务,而是先请求重新执行一次文件替换,并且这次替换前主动关闭了锁定文件的进程。

7.3 恢复链路是如何串联的:一次完整的故障处置复盘

回看整个处理过程,各层机制是这样协作的:

故障没有在发生时被"预防层"拦住(工具契约校验只校验了返回码),但它被"检查点探测"发现了,避免了污染扩大。预算熔断没有发挥作用——因为故障本身不涉及超时和超限。真正起作用的,是从检查点触发、世界模型回摆定位、到重新执行修复的完整链路。

这次复盘让我后来做了一个重要改进:所有涉及写操作的工具,都在 Harness 层增加"后置验证"步骤。工具返回码为 0 只是第一个条件,更可靠的是验证目标对象的实际状态——文件写完了就验证文件内容,配置改了就验证配置是否加载,请求发出去了就验证响应是否符合预期。这个"后置验证"把很多"静默失败"变成了"显性失败",让错误在发生的当下就能被感知到,而不是等它污染到后续步骤才被发现。

7.4 教训总结:容错设计的边界在哪里

这个案例最值得反思的不是"工具返回码校验不够",而是容错设计的边界感:任何一层容错机制都不可能覆盖所有故障场景,但它们协作起来的收益远大于单点的堆叠。预防层挡掉了 70% 的低级错误;契约校验挡掉了大部分格式漂移;预算熔断限制了失控的损失;而上下文修复与检查点,则负责兜住最隐蔽、最难防的那部分污染。

说得更直白一点:容错设计的目标不是做到"永不犯错",而是做到"每条错误路径都有对应的纠正机制"。当错误最终无法被纠正时,系统要能做到有尊严地停止——不是留下一堆半成品和脏状态,而是把"已知信息、已做操作、未完成项、失败原因"完整保留下来交给用户决策。

8. Harness 容错体系里那些拿不到台面上说,但非常有用的经验

最后分享几个在实战中摸出来的细节。它们看起来很小,但往往能决定你的容错方案是"看着合理"还是"真正好用"。

第一,重试时务必保留上一次错误的完整堆栈。这不是废话——很多重试机制只记录了错误类型和错误信息,但没记录触发错误的具体输入参数。一旦要诊断"为什么重试也失败",缺失的那部分信息就是致命的。我在 Harness 的错误对象里固定保留了"触发错误时的完整工具调用参数 + 环境快照",这让事后排障的效率提升了不止一个量级。

第二,给所有恢复动作加"恢复痕迹"。Harness 在恢复时,会在上下文里明确写入一条结构化记录:"第 23 步被标记为未确认,原因为文件哈希不匹配,已触发重新执行"。这条痕迹能让模型在后续决策时感知到"当前状态是恢复后的状态",而不是"一直在顺畅执行的状态"——避免模型因为缺少历史上下文而做出与恢复动作冲突的决策。

第三,预算熔断的阈值不要做成全局静态值。不同任务的 token 消耗特征差异极大:一个简单的代码格式化任务可能 2 万 token 就够,一个跨仓库重构可能需要 30 万。按任务类型维护一组熔断参数,比一个全局值要合理得多。我是按照任务类别(代码审查/构建执行/静态分析/多文件编辑)分别统计基线,然后为每类单独设置熔断阈值。

第四,日志分级要能让"容错动作"一目了然。我在 Harness 的日志体系里给容错相关操作打了独立标签,比如[RECOVERY][RETRY-ATTEMPT][CONTEXT-REPAIR][BUDGET-LIMIT]。排障时直接 grep 这些标签,就能在几秒钟内看到"这轮任务经历了哪些故障处置"。没有这些标签,你要从密密麻麻的执行日志里徒手扒出恢复链路,那才是真的灾难。

第五,也是我个人感受最深的:容错设计永远不要在"理想环境"里验证。只跑正常路径的 Demo,重试逻辑再完美也体现不出价值。真正的验证方式是故障注入——人为地把工具返回改为超时、故意让模型输出坏格式、模拟外部服务限流,然后观察 Harness 是否按预期走完恢复链路。搭一套故障注入测试脚本虽然麻烦,但它能帮你把容错体系里的盲区一个个挖出来,这个收益怎么强调都不为过。

关于 Harness 的容错与恢复,到这里就拆完了一层。每次做完一次故障复盘,我都会对"稳定"这个词有新的理解:在 Agent 系统里,稳定不是永远不出错,而是每次出错都有对应的回应、每条恢复路径都能被验证。这种理解不是从文档里读来的,是看着一长串失败日志、反复调整恢复策略之后才真正沉淀下来的。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/5 5:59:40

为什么“学 Python”不是 Java 程序员转 AI 的第一步?

一、为什么“学 Python”不是 Java 程序员转 AI 的第一步? 1.1 市场真正缺的不是“会 Python 的人” Python 的确是目前 AI 算法领域的主流语言,但那个岗位叫算法工程师,门槛是:硕士起步、顶会论文、手推公式。绝大多数 Java 工…

作者头像 李华
网站建设 2026/9/5 5:59:29

滤波器是什么?从时域到频域,一文讲透信号降噪的底层原理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/5 5:57:28

Python零基础入门实战:从环境搭建到爬虫与Excel自动化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/5 5:57:19

【SAP】100小时学会SAP-6销售与分销SD

目录 6.1 定义销售组织 6.2 定义分销渠道 6.3 定义产品组 6.4 将销售组织分配给公司代码 6.5 将分销渠道分配给销售组织 6.6 将产品组分配给销售组织 6.7 设置销售范围 6.8 定义销售办公室 6.9 定义销售组 6.10 给销售范围分配销售办公室 6.11 将销售组分配给销售办…

作者头像 李华
网站建设 2026/9/5 5:51:20

蓝牙芯片选型实战:杰理、中科蓝讯、高通三平台对比与避坑指南

先声明一下,这篇文章不是芯片原厂的软文,也不收任何一家的推广费。纯粹是我这几年在方案公司做蓝牙音频产品,把杰理、中科蓝讯、高通三个平台的方案都从选型、试产、量产、售后完整走了一遍,烧了不少钱,也被退货率教育…

作者头像 李华