<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>容错恢复 on Last Stand</title><link>https://amatsuzero.github.io/LastStand/tags/%E5%AE%B9%E9%94%99%E6%81%A2%E5%A4%8D/</link><description>Recent content in 容错恢复 on Last Stand</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Tue, 09 Jun 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://amatsuzero.github.io/LastStand/tags/%E5%AE%B9%E9%94%99%E6%81%A2%E5%A4%8D/index.xml" rel="self" type="application/rss+xml"/><item><title>第13章 容错与恢复算法</title><link>https://amatsuzero.github.io/LastStand/posts/aiagentalgorithm/chapter-13/</link><pubDate>Tue, 09 Jun 2026 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/aiagentalgorithm/chapter-13/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;真正的韧性不在于永不失败，而在于每次失败后都能优雅地站起来。&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="131-问题引入"&gt;13.1 问题引入&lt;/h2&gt;
&lt;p&gt;想象这样一个场景：用户正在使用 Claude Code 进行一个复杂的代码重构任务。Agent 已经分析了数十个文件，制定了修改计划，正在逐步执行。此时 API 突然返回 HTTP 529（Overloaded）错误。&lt;/p&gt;
&lt;p&gt;这个看似简单的场景引发了一系列深刻的工程决策：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;立即失败？&lt;/strong&gt; 用户等待了几分钟的上下文将全部丢失，体验极差。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;无限重试？&lt;/strong&gt; 如果服务器已过载，盲目重试只会加剧雪崩，使所有用户的体验都恶化。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;等待后重试？&lt;/strong&gt; 等多久？如果所有客户端都在同一时刻重试呢？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;降级到备用模型？&lt;/strong&gt; 什么条件下降级？如何在质量和可用性之间取舍？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;更复杂的场景还包括：网络在 SSH 会话中断开，进程收到 SIGTERM 信号，OAuth Token 在请求中途过期，SSL 证书验证失败……每一种故障都需要不同的处理策略。&lt;/p&gt;
&lt;p&gt;Claude Code 作为一个长时间运行的交互式 Agent 系统，面临的容错挑战远比普通 Web 应用复杂。它必须在&amp;quot;永不放弃&amp;quot;和&amp;quot;适时认输&amp;quot;之间找到精确的平衡点。本章将深入分析 Claude Code 源码中的容错与恢复算法，揭示一个生产级 Agent 系统如何在真实世界的混乱中保持韧性。&lt;/p&gt;
&lt;h2 id="132-错误分类状态机"&gt;13.2 错误分类状态机&lt;/h2&gt;
&lt;p&gt;容错系统的第一步是&lt;strong&gt;正确分类错误&lt;/strong&gt;。不同类型的错误需要截然不同的处理策略。Claude Code 构建了一个精密的错误分类体系，将错误分为可重试、不可重试、可降级等多个类别。&lt;/p&gt;
&lt;h3 id="1321-分类的核心逻辑"&gt;13.2.1 分类的核心逻辑&lt;/h3&gt;
&lt;p&gt;错误分类是一棵决策树。Claude Code 的 &lt;code&gt;shouldRetry&lt;/code&gt; 函数体现了这棵树的结构：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-gdscript3" data-lang="gdscript3"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;错误发生&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;├──&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;是否为模拟错误？&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;不重试（测试用）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;├──&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;是否为持久模式下的瞬态容量错误（&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;429&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;529&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;）？&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;始终重试&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;├──&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;远程模式下的&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;401&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;403&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;？&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;重试（基础设施令牌刷新）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;├──&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;包含&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;overloaded_error&amp;#34;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;？&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;重试（流式&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;529&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;的变体）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;├──&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;上下文溢出&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;400&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;？&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;重试（自动调整&lt;/span&gt; max_tokens&lt;span style="color:#960050;background-color:#1e0010"&gt;）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;├──&lt;/span&gt; x&lt;span style="color:#f92672"&gt;-&lt;/span&gt;should&lt;span style="color:#f92672"&gt;-&lt;/span&gt;retry &lt;span style="color:#960050;background-color:#1e0010"&gt;响应头&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;├──&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;企业用户&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;重试&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;│&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;└──&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;false&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;非&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;xx &lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;不重试&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;├──&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;连接错误（&lt;/span&gt;APIConnectionError&lt;span style="color:#960050;background-color:#1e0010"&gt;）？&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;重试&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;├──&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;408&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;请求超时&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;重试&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;├──&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;409&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;锁超时&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;重试&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;├──&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;429&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;速率限制&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;条件重试（非订阅用户或企业用户）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;├──&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;401&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;认证失败&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;清除缓存后重试&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;├──&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;403&lt;/span&gt; Token &lt;span style="color:#960050;background-color:#1e0010"&gt;撤销&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;重试&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;├──&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;xx &lt;span style="color:#960050;background-color:#1e0010"&gt;服务端错误&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;重试&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;└──&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;其他&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;→&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;不重试&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这棵决策树的设计体现了几个关键原则：&lt;/p&gt;</description></item></channel></rss>