如果你用 Claude Code、Codex 这类 AI 编程助手,一定遇到过这种时刻:额度用完了、模型被限流、供应商抽风、或者模型本身过载——这时候换不换模型、换哪个、重试几次,通常靠临时决定。free-claude-code 花了 10 个月,把这些决定写成了一套显式规则。
free-claude-code 是一个可以自己部署的多模型网关:把 12 种 AI 编程助手接到 61 个模型供应商上,并在失败时按写死的规则决定重试、换供应商还是换模型。它在 GitHub 上已经攒到 69,432 颗星。
这个项目到底是什么:一台给 AI 编程助手用的模型总机
它的定位是「自托管的多供应商网关 + 桌面工作台」。两件事同时发生:把各种 AI 编程助手的请求转发到各种模型供应商(付费的、免费的、订阅制的、本地跑的都行),再在转发之上叠一层可靠性机制——自动重试、可配置的限流、可配置的并发上限、自动的模型降级、自动的多 API Key 降级。
一次请求会经过哪些环节
一次调用大致是这样走的:先由路由层根据模型名解析出「主目标供应商 + 降级候选列表」,再由准入层拿到并发许可并分配尝试预算,然后才是真正的物理调用。调用失败时,错误会被归一成一个标准类型,策略层据此判断是原地重试、换一个候选,还是直接放弃。
这四层(路由、准入、调用、失败归类)之间是解耦的。换一套供应商降级策略,不需要动错误解析代码;改一个错误类型的含义,也不会牵连重试逻辑。
支持哪些 AI 编程助手
官方列出的 12 种 harness(harness 可以理解成「AI 编程助手的宿主程序」)包括:Claude Code、Codex、Pi、OpenCode、Cline、Hermes、DeepSeek Harness、Grok Build、Muse Code、Aider、Antigravity CLI、VS Code Chat。
适配层已经落地的部分值得单独看一眼:Claude Code 有集成、桌面集成、引导流程三件套;Codex 有集成、应用服务器、协议解析、模型目录四件套;DeepSeek Harness 有桌面集成、文件操作、配置三件套;此外还有 Antigravity、JetBrains(走 ACP 协议)、VS Code Chat、OpenCode,另外配有卸载回滚和模型策略两个模块。
供应商有多多
61 个供应商,覆盖付费、免费、订阅、本地四类。其中特别值得注意的是,它把 ollama、llamacpp、lmstudio、ollama_cloud 四个本地模型入口当成一等公民写在供应商目录里——也就是说,「接一个跑在自己电脑上的模型」在这套设计里不是一个 hack,而是正式支持的用法。
先看数据:6.9 万星、10 个月 200 个版本
以下数字是 2026-11-13 11:57 CST 通过 GitHub REST API 实测的快照,不是估算。
数据快照
| 指标 | 数值 | 说明 |
|---|---|---|
| 星标数 | 69,432 | 2026-11-13 11:57 CST 实测 |
| Fork 数 | 10,777 | 同一时点实测 |
| 未关闭 issue | 396 | API 的 open_issues_count 口径,含 PR |
| 未关闭纯 issue | 306 | 搜索接口 is:issue is:open 口径,不含 PR |
| 累计 issue | 1,070 | 搜索接口 is:issue 口径 |
| 主语言 | Python | 全仓 1,153 个文件里 1,028 个是 .py |
| 建仓时间 | 2026-01-28 | 距今约 10 个月 |
| 最新版本 | v6.19.11 | 2026-11-12 10:04 UTC 发布 |
| 最近一次推送 | 2026-11-12 19:36 UTC | |
| 仓库体积 | 17,035 KB | |
| 许可证 | AGPL-3.0-only | 以 LICENSE 文件正文为准 |
这个项目在 2026-11-13 当天出现在 GitHub Trending 日榜上,单日新增约 415 颗星。
许可证是 AGPL,不是 MIT
这里有个值得学的小细节:GitHub API 返回的 license.spdx_id 是 NOASSERTION,但仓库根目录的 LICENSE 文件开头明明白白写着 SPDX-License-Identifier: AGPL-3.0-only(Copyright (c) 2026 Ali Khokhar),README 的徽章也标着 AGPL v3。
结论是:以文件正文为准 = AGPL-3.0-only(强 copyleft)。API 报 NOASSERTION 只是自动识别失效,不代表没有许可证。这本身就是供应链透明度的一个反例样本——很多商业项目只信 API 字段,然后就把强 copyleft 的代码直接引进了商业产品。
迭代节奏
建仓 10 个月,已经发到 v6.19.11,中间有 200 多个 minor 版本,平均几乎每天一个小版本。好处是功能长得快,坏处是同时挂着 396 个未关闭 issue,社区反馈和修复速度都得盯。
仓库结构:1153 个文件里,490 个是测试
这份仓库结构本身就是一份工程价值观说明书。
文件分布
| 目录 | 文件数 | 占比 |
|---|---|---|
| src/free_claude_code | 515 | 44.7% |
| tests | 490 | 42.5% |
| smoke | 72 | 6.2% |
| e2e | 30 | 2.6% |
| scripts | 17 | 1.5% |
测试文件的数量和主源码几乎持平,还额外有一套 72 个文件的 smoke 套件和 30 个文件的端到端套件。
子包结构
src/free_claude_code 下面各子包的分布是:providers 120 个文件、core 102 个、api 96 个、messaging 52 个、cli 39 个、runtime 31 个、config 27 个、application 21 个、harnesses 20 个、updater 2 个。
core 里的协议适配器按上游 API 家族切得很干净:anthropic 25 个文件、openai_responses 24 个、gemini 12 个、chat_completions 6 个。也就是说它原生支持 4 种上游协议线,而不是只对接一家。
几个关键文件
runtime 目录下 integration_service.py 有 36,142 字节,provider_manager.py 35,665 字节,code_sessions_sqlite.py 30,368 字节,codex_app_server.py 30,321 字节,codex_protocol.py 28,528 字节。core 目录下 history_replay.py 50,338 字节,是全仓最大的源文件,anthropic/conversion.py 31,281 字节,openai_responses/tool_adaptation.py 30,914 字节,delivered_response.py 25,303 字节,continuation_overlap.py 18,215 字节。
还有两个体积特别显眼但特别值得一看的文件:providers/admission.py 40,793 字节,它是可靠性层的核心;core/data/cl100k_base.tiktoken 1,681,126 字节(约 1.68 MB),是把 cl100k_base 的 BPE 分词表整个内嵌进了仓库,用来离线算 token,不依赖 API 往返。
核心机制一:把五花八门的报错先归一成一类
core/failures.py 只有 1,791 字节,是全仓最小的文件之一,却撑起了整套可靠性层的语义地基。
九种协议中立的失败类型
| 类型 | 含义 | 典型处理 |
|---|---|---|
| invalid_request | 请求本身不合法 | 不重试,直接失败 |
| context_window_exceeded | 上下文超长 | 视情况裁剪后重试 |
| authentication | 鉴权失败 | 换 Key,不换供应商 |
| permission | 权限不足 | 不重试 |
| rate_limit | 被限流 | 冷却后重试 |
| overloaded | 模型过载 | 换候选或稍后重试 |
| timeout | 超时 | 可重试 |
| upstream | 上游错误 | 按可重试标记处理 |
| unavailable | 供应商不可用 | 换候选 |
「协议中立」这四个字是关键:这九种类型不带任何供应商色彩,也不带任何 HTTP 状态码色彩。无论错误来自 Anthropic、OpenAI、Gemini 还是本地推理服务,都能落到同一个枚举里。
一个被冻结的失败对象
配套的 ExecutionFailure 是一个冻结的 dataclass,字段包括 kind、status_code、message、retryable、stream_context。它用 slots 模式省内存,并额外覆写了 __setattr__ 把语义字段显式锁死——但异常机制字段(__traceback__、__cause__、__context__)仍然可写,这样 Python 的异常链机制不会被破坏。
这种「数据不可变、但异常链保持灵活」的分寸,是长期运行的重试框架里很容易踩坑的地方。
递归拆开聚合异常
find_execution_failure 会递归遍历 ExceptionGroup 树,去找出第一个被规范化过的失败。这个细节看着不起眼,但直接决定了并发场景的正确性:一次调用里并发跑了多个供应商、等它们全部失败后抛出一个聚合异常,框架依然能归一到唯一、确定的 kind,而不是丢一个 AggregateError 出去。
核心机制二:一次任务、多次尝试、一次准入,三层分开记账
providers/admission.py 的文件头有一句话概括了全部设计:Provider-owned admission, concurrency, and coordinated retry lifecycle.(供应商自己掌管准入、并发和协调重试的生命周期。)
逻辑操作与物理尝试
核心对象 ProviderExecution 的文档串是 Own one logical provider operation and its physical-attempt budget.(持有一次逻辑供应商操作,以及它的物理尝试预算。)
它维护 max_attempts、attempts_started、attempts_remaining 三个状态字段,以及 can_attempt() 判断(判据是 attempts_started 小于 max_attempts)。而 open_attempt() 的文档串是 Open the sole active physical call for this execution.(为这次执行打开唯一一个活跃的物理调用。)——同一时刻只允许一个活跃物理调用。
这两层的分离,是整个设计里最值钱的部分:
- 逻辑操作 = 你想做的那件事(一次生成、一次续写),对外表现为「一次请求」
- 物理尝试 = 为这件事实际发出的调用次数,内部可以重试多次
把两者分开之后,「重试」和「降级」就成了两件可以分别计数、分别解释的事,而不是混成一团。这也是很多自建 Agent 运行时最缺的一层。
三种操作种类各算各的预算
ProviderOperationKind 枚举把操作分成三类:MODEL_DISCOVERY(探测模型列表)、GENERATION(生成)、CONTINUATION(续写)。三类操作各自独立预算,不会互相偷吃额度。
配套还有一个 ProviderCorrectionAction 枚举,只有 RETRY 和 FINAL 两个值,用来回答「一次确定性的请求修正,是否允许再消耗一次尝试额度」。
准入之后才真正发请求
并发控制走的是先拿许可再发请求的顺序:acquire 拿到准入之后,才真正发起调用。max_concurrency 和 max_attempts 会一起打印在启动日志里,方便排查时对照。
不可变的失败裁决
ProviderFailureDecision 是一个不可变对象,记录「供应商是否还有资格继续」以及「最早什么时候可以重试」,其中 reports_cooldown 默认是 False。还有一个常量 UPSTREAM_TRANSIENT_TOTAL_ATTEMPTS,用来限制瞬态失败的总尝试预算上限。
核心机制三:模型级共享冷却,并且保留原来的候选顺序
这是整套设计里最反直觉、也最值得抄的一条。
冷却挂在模型上,不挂在供应商上
admission.py 里的注释直书:The first shared transient failure opens a recovery episode for its model.(第一个共享瞬态故障,会为它的模型开启一个恢复周期。)
关键在于:冷却键是模型,不是供应商。同一个模型挂在多个供应商下面时,模型级的瞬态故障会让所有提供这个模型的供应商一起进入冷却。
道理很直白——如果模型本身挂了,换一家供应商托管的同一个模型,大概率也挂。反过来,如果某个供应商只是自己的网络抖了一下,不应该连累它家其他正常模型。
被跳过的候选不消耗额度
配套的测试(test_shared_cooldown_skips_candidate_with_zero_calls_and_keeps_seed)断言了两件事:一是因冷却被跳过的候选消耗 0 次调用——不空转、不烧额度;二是保留种子(keeps seed)——冷却结束后候选仍然留在原有序列表的原始位置,不会因为一次故障被永久降序。
冷却结束后还能回到原位
这条语义可以叫「可回访的有序候选池」:某一家暂时出问题时跳过它,但它的排队位置不动。
很多实现的做法是一条静态有序列表,一旦在第 2 格失败就跳到第 3 格,之后整轮任务里第 2 格再也不会被想起——一次偶发抖动,等于永久除名。保留种子这个设计,把「暂时跳过」和「永久降级」区分开了。
核心机制四:中途换模型时,已经产出的内容怎么办
这是这个项目最值得抄、也最难抄的一层。
降级必须带上已经交付的前缀
测试文件的说明是 Model fallback continues the public response through real provider transports.(模型降级通过真实的供应商传输继续完成对外响应。)
关键约束是:降级目标必须能接受「已经产出的部分输出槽位」。换句话说,中途换模型时,前一个模型已经吐出来的内容不能丢——那部分内容对用户是可见的,丢掉就等于回答被截断了。
被放弃的调用绝不越界
另有一条测试(test_abandoned_calls_never_cross_model_boundary)划了一条硬边界:被放弃的调用绝对不允许跨模型边界泄漏。
这条规则解决的是一个非常具体但很容易踩的坑:中途换供应商时,旧供应商已经产生的工具调用、思考块、tool_use id 如果原样带过去,新供应商会看到不属于它的上下文——工具 id 冲突,或者带副作用的工具被执行两次。运营场景下这意味着重复下单、重复发消息。
源侧原生状态会阻止降级
还有一条相反方向的规则(test_source_native_state_prevents_model_fallback):当请求侧存在原生状态(比如某些助手自己维护的会话状态)时,禁止降级。这种时候宁可失败,也不能把状态甩给一个不懂这套状态的模型。
另外几条契约同样明确:每个模型拿到的是最新前缀加它自己的预算,预算不共享;永久性拒绝(永久拒绝)会前进到下一个候选,且不抹掉已经收到的前缀;首个降级调用不得在没有任何新输出的情况下「完成」;被释放的调用只在可重试的失败时移交;本地重试之后,托管侧残留的隐藏活动仍然算作模型边界。
核心机制五:模型路由与推理档位归属,都能显式配置
application/routing.py 里的 ModelRouter.resolve() 返回一个 ResolvedModelRoute 结构,包含 original_model、primary、fallbacks 和 reasoning_preference。
路由结果长什么样
primary 是主目标供应商与模型的组合,fallbacks 是一个降级候选元组(有序),reasoning_preference 记录推理档位的归属方式。
命中就短路
如果模型名本身就能直接解析成「供应商/模型」这种形式,走 MODEL DIRECT 分支,直接构造 primary,不再绕其他逻辑。这种短路路径对延迟敏感的场景很友好。
降级候选会去掉主目标自己
构造降级候选时,会读取配置里的降级链,并剔除等于 primary 的候选,避免把主目标重复排进降级链里自己降级自己——这类实现 bug 相当常见。
未知供应商在路由期就报错
_validate_provider_id 会对配置做校验,遇到未知供应商直接抛 UnknownProviderError。设计意图很明确:配置错误要在路由期炸掉,而不是拖到执行期变成一次静默降级。
这条对任何配置驱动的自动化系统都适用。一个配错的降级链如果只是「跳过」,你会看到任务莫名其妙用了另一个模型,而没有任何报错。
推理档位归属可以显式选择
推理档位(也就是模型思考量、effort 的那一层)的归属是一个显式枚举,可选值包括:
| 选项 | 含义 |
|---|---|
| Inherit | 沿用原请求已经解析出来的推理档位 |
| Off | 关闭推理 |
| From client | 用 coding agent 自己送来的 effort 或 token 预算,绕过全局设置和档位设置 |
| Low | 低档 |
| Medium | 中档 |
| High | 高档 |
| X-High | 超高档 |
| Max | 最高档 |
同时,模型档位本身也可以分开覆盖:MODEL 是所有请求的兜底,而 MODEL_FABLE、MODEL_OPUS、MODEL_SONNET、MODEL_HAIKU 可以单独指定给 Claude Code 的对应四档,选 None 则回落到 MODEL。
每一个降级候选还可以带各自的推理档位和 API Key 编号。降级链是可以在管理界面里拖拽排序、点垃圾桶删除的有序列表,并且对所有已连接的客户端同时生效。
核心机制六:失败结果本身是一个对外接口
失败载荷有专门的测试组
关于「降级最终失败时返回给客户端的载荷长什么样」,项目有 6 个专门的文件在测这件事:test_model_fallback_failure_payloads.py、test_model_fallback_wire_controls.py、test_model_fallback_reasoning.py、test_model_fallback_tool_projection.py、test_model_fallback_clients.py、test_model_fallback.py。
也就是说,降级的失败结果不是「碰巧返回了什么」,而是被当成一个对外接口来测、来保证稳定。
被拒绝的准入不扣配额
core/rate_limit.py 里的 StrictSlidingWindowLimiter 是一个严格滑动窗口限流器,保证任意长度的窗口区间内最多放行 rate_limit 次准入。它的 acquire_if(allowed) 有一个很精细的设计:先 await 容量,再在不让出事件循环的前提下同步完成条件判断和时间戳写入,注释里明写 so a rejected admission consumes no quota.(所以一次被拒绝的准入不消耗配额。)
这条在「限流 + 优先级」组合场景里极其关键。如果先占位、后判断资格,被拒的那批请求会白白吃掉额度,真正该放行的反而排队。
降级状态下的重试被单独建模
项目里有 test_retry_after_cooldown.py、test_hidden_retry_admission.py、test_openai_compat_5xx_retry.py、test_nvidia_nim_degraded_retry.py 几个文件。注意最后一个词:degraded_retry。降级状态下的重试,是被单独建模、单独测试的一种情况,而不是复用普通重试的逻辑。
多 API Key 降级也有对应的一整套:供应商弹窗支持编号 Key(Add key、拖拽重排),README 里写明默认用 Key 1,降级候选可以指定 API Key 编号;对应测试有 test_fallback_key_requests.py、test_fallback_key_settings.py 和端到端的 test_fallback_key_controls.py。
那些容易被忽略但很讲究的工程细节
降级会跨供应商烧额度,官方直接写明
README 里有一句很坦诚的话:A failed request may reach and consume usage from more than one provider before succeeding.(一次失败的请求,可能在成功之前就已经消耗了不止一个供应商的额度。)
不藏着掖着,而是写进产品文档。这对一个多供应商网关来说太重要了——用户必须知道账单为什么比预想的高。
本地 smoke 与常规 CI 分层
smoke/README.md 写得很清楚:smoke 是本地独占套件,可以启动子进程、调用真实供应商、访问本地模型服务器,甚至可以发送和删除机器人消息;同时 Regular CI collects only tests and e2e(常规 CI 只收集 tests 和 e2e)。
也就是说 smoke 不进常规 CI,需要显式开启一个环境变量才能跑。smoke 内部还分三类:installers 管安装器、卸载器和生命周期检查,用隔离文件和模拟下载,不会真的装到系统里;prereq 做存活检查,包括服务、路由、鉴权、CLI 脚本、供应商 ping、本地 models 接口、机器人权限;product 跑端到端产品场景,并且明确说明 Feature smoke coverage comes from these tests, not from route/header/provider pings(功能覆盖来自这些测试,而不是靠 ping 各接口来覆盖)。
一张「特性真值表」
smoke/features.py 被明确定义为 source-of-truth feature map: feature -> subfeature -> scenario -> env -> expected behavior -> failure class(源事实级的特性映射:特性 → 子特性 → 场景 → 环境 → 期望行为 → 失败类别)。
最后那一列「失败类别」把「测试挂了」变成一个可分类的事件,而不是一团 pytest 报错。你能直接统计出「本周的失败里有几次是限流引起的、几次是接口变更引起的」。
Token 成本被当成产品卖点
README 里有一个很抢眼的说法:Up to 90% lower token usage using RTK and Headroom,并给出每月 13 亿以上免费 token 的额度。配合仓库内嵌的 cl100k_base 分词表(1.68 MB,离线计量,不靠 API 往返),token 计量这件事是自闭环的。
电商和日常办公场景,它能派上什么用场
如果你是做电商运营的,或者你在用 AI 编程助手搭自动化流程,这个项目的价值不在于「给你一个更好用的聊天框」,而在于它让「模型掉链子」这件事变得可预期。
编程与自动化场景
最直接的场景是:你在本地或服务器上跑 Claude Code、Codex、OpenCode 这些工具,想让它们能按成本、可用性、额度情况自动挑模型,而不是每次手动换。
对你来说真正有影响的是这几个行为:某个模型过载时自动换个供应商继续,不会让你重跑整个任务;任务中途换模型时,已经生成的上下文和工具调用不会重复执行——对电商来说这意味着不会重复改价、不会重复提交订单、不会重复给客户发消息;被限流时是被跳过而不是把额度白烧光。
电商运营场景
把它放到电商自动化的语境里,这套机制对应的是几个很具体的问题:
- 多平台内容生成要接多个模型服务,如果只用一家,遇到限流或宕机就停摆;多供应商 + 冷却机制可以让任务继续跑,只是换一条路
- 批量生成详情页、客服话术、活动文案这类任务,最怕的是「跑了一半失败、不知道跑到哪、不知道哪些已经发出去」;逻辑操作与物理尝试分开的记账方式,能让这类任务有清晰的进度与重试语义
- 如果接入的是本地模型(比如把某个开源模型跑在自己机器上),它把本地模型当一等供应商的做法,可以作为参考;本地模型在工具调用(tool call)协议上的兼容性差异很大,需要额外加一道兼容性检查再放进降级链
不管哪种场景,官方那句「一次失败的请求可能已经消耗了多个供应商的额度」都值得贴在墙上:多供应商不是免费的。
什么时候你用不上它
许可证与合规
它是 AGPL-3.0-only,强 copyleft。个人自用、研究性使用问题不大;但如果要把它的代码并进闭源商业产品,或者做成对外提供的网络服务,务必先做一次合规评估。这一条对很多商业团队是硬门槛。
它是 coding agent 侧的网关,不是通用 Agent 运行时
它服务的是 Claude Code、Codex、Aider 这类终端里的编程助手,官方支持的 12 种 harness 里并不包含通用 Agent 运行时。想把它接到别的 Agent 框架上,得自己写适配层,工作量不小。
另外要留意:它会形成你自己的调度层之外又插一层供应商路由。如果你的系统里已经有成熟的路由与看门狗机制,两层并存需要想清楚谁说了算。
迭代面与风险面
10 个月 200 多个版本、396 个未关闭 issue、17 MB / 1,153 个文件。追新版本追得紧,接口就容易变;停在旧版本,则可能拿不到新的兼容性适配。
如果你想借鉴这套设计,优先做哪几件事
这套设计里真正可以迁移到你自己系统里的东西,和「部署它」是两回事。下面按性价比排序。
优先级最高的三条
第一,把供应商报错归一到一个封闭枚举,再由策略决定重试还是换人。判据和执行分离,以后换供应商策略不用改错误解析代码。最小可用的一组枚举至少要覆盖:限流、过载、超时、鉴权失败、不可用、协议不兼容——最后这一类最容易被错误地归进「不可用」的语义盲区,结果就是任务一路滑到一个根本不支持工具调用的本地模型上,假装干完了事。
第二,把「重试」显式化成「物理尝试」并计数。每次派发是一个逻辑操作(带一个运行 ID),其内的物理尝试是实际调用次数,计数写进任务台账。这样才能解释清楚「今天到底发了几次、每一次为什么前进」。
第三,降级链从「静态有序列表」升级为「有序候选池 + 每格冷却状态」。某一格因限流或过载被冷却时,跳过它,不消耗额度、不改它的序号;冷却结束后可以回访。这一条改动最小、收益最直接——它直接消除了「一次抖动导致某个模型被永久除名」这个很常见的缺陷。
中等优先级的四条
第四,降级必须携带已交付的前缀,且旧供应商的调用与状态不得穿越到新供应商。需要先定义清楚「派发中途换模型时,已经产生的部分产物如何处理」,并禁止两轮部分产物同时进入下游链路,否则可能重复发布。
第五,「推理档位归属」做成显式枚举,包含「交还给客户端」这一选项。任何一条多层链路,都应该能回答「本次实际生效的模型是谁、谁决定的」,并把答案写进任务台账。
第六,失败载荷结构化。回执里不能只写「已跳过」,要写清尝试了哪几档、每档失败类别是什么、最终结论是什么。
第七,未知供应商在启动期校验,不可用就响亮失败并记录,绝不静默跳过。配置错了还照跑,是所有自动化系统里最难查的一类故障。
需要先解决的前置问题
第八,把「限流 + 优先级」这类组合场景的配额语义定清楚——被拒绝的准入到底扣不扣额度?很多实现在这里是先占位后判资格,结果被拒者白白吃掉额度,真正该放行的反而排队。
第九,看门狗和探测动作走独立配额。探测本身如果也在消耗生产额度,长期看门狗就变成了持续成本。
第十,链路的每一层都要能回答「我在验什么」。可以直接套用 smoke/features.py 的形态,写一张真值表:层 → 场景 → 环境 → 期望行为 → 失败类别。这让「验证 cron 到底在验什么」从一句口号变成可枚举、可测试的清单。
第十一,把「本次派发消耗了哪些供应商的额度」如实写进汇报和台账。诚实披露成本不是自曝其短,反而是长期信任的基础。
一句话总结
free-claude-code 真正的价值不在于「能接 61 个模型」这种规模数字,而在于它把「多供应商失败处理」从一堆临时判断,变成了一套有名字、有边界、有测试、有优先级的显式规则:报错先归一,逻辑操作和物理尝试分开记账,冷却挂在模型上且保留原位,中途换模型必须带上前缀且旧状态不许越界,推理档位归属显式枚举,失败载荷当成对外接口来测。
如果你正在搭一套要长期跑、会在半夜失败、需要别人接手排查的 AI 自动化系统,这套清单几乎可以逐条照着抄。
本期博客暂未配置封面图。