诊断 OpenClaw 的模型路由、fallback 使用情况与 CLI 中断原因
name: "diagnose-openclaw-model-routing-and-fallback-usage"
by can4hou6joeng4 · published 2026-04-01
$ claw add gh:can4hou6joeng4/can4hou6joeng4-diagnose-openclaw-model-routing-and-fallback-usage---
name: "diagnose-openclaw-model-routing-and-fallback-usage"
description: "用于分析 OpenClaw 中“某个 provider/模型为什么看起来没被用上”、主模型与 fallback 实际是否生效、以及 ClaudeCodeCLI 协作任务为何中断。遇到这些情况就应触发:用户提到“没请求打到 local-router”“明明注册了模型却没流量”“Agent 到底在用哪个模型”“fallback 有没有发生”“为什么日志里看不到候选切换”“code 143 / SIGTERM / Exec failed”“需要结合当前配置和日志做严谨归因”。也适用于区分“provider 被调用”与“provider 下某个特定模型被调用”这两类常见混淆。"
metadata: { "openclaw": { "emoji": "🧭" } }
---
# 诊断 OpenClaw 的模型路由、fallback 使用情况与 CLI 中断原因
这个技能帮助你把 OpenClaw 的 Agent 配置、provider 注册信息和运行日志串起来,判断“请求到底发到了哪里、为什么某个模型没有被实际使用、fallback 是否真的发生过”,并补充分析 ClaudeCodeCLI 协作执行中断的根因。
When to use this skill
Steps
1. **先区分用户到底在问“provider 没被调用”,还是“provider 下某个模型没被调用”**
- 要做什么:先把问题拆成两层再分析:
- `local-router` 这个 provider 是否被请求命中
- `local-router/claude-opus-4-6-thinking` 这个具体模型是否被 Agent 主链或 fallback 链使用
- 为什么:这两件事最容易被混为一谈;provider 有流量,不代表 provider 里的每个模型都有流量。
2. **读取当前各 Agent 的主模型配置**
- 要做什么:核对 `main`、`coder`、`writer` 当前绑定的模型。
- 已验证结论:
- `main` → `local-router/gpt-5.4`
- `coder` → `local-router/gpt-5.4`
- `writer` → `local-router/gpt-5.4`
- 为什么:用户的体感常来自“回答风格不像预期模型”,而主模型配置是最直接的证据链起点。
3. **读取默认 fallback 链,而不是只看 provider 的 models 列表**
- 要做什么:核对 `agents.defaults.model` 的 primary 和 fallbacks。
- 已验证结论:
- primary: `local-router/gpt-5.4`
- fallbacks:
1. `aigocode-gpt/gpt-5.4-codex`
2. `openai-codex/gpt-5.4`
3. `local-router/gpt-5.3-codex`
4. `aigocode-gpt/gpt-5.3-codex`
- 为什么:模型是否“会自然切到某个候选”,取决于 fallback 链有没有引用它,而不是 provider 是否声明过它可用。
4. **检查目标模型只是“已注册”,还是“已绑定”**
- 要做什么:确认 `local-router/claude-opus-4-6-thinking` 所在位置。
- 已验证结论:
- 它存在于 `models.providers.local-router.models[]`
- 但当前没有任何 Agent 主模型引用它
- 默认 fallback 链也没有引用它
- 为什么:`provider 中存在` 只表示“可选”,不表示“当前执行链会使用”。
5. **给出第一层诊断结论:为什么用户感觉没请求发到某个模型**
- 要做什么:明确输出这类结论:
- 如果用户特指 `local-router/claude-opus-4-6-thinking`,那“感觉没流量”是正确的
- 因为它当前既不是主模型,也不在默认 fallback 链里
- 为什么:这能把“错觉”变成“配置导致的必然结果”,降低误判。
6. **同时纠正另一种常见误解:不能把“没打到目标模型”误说成“没打到 provider”**
- 要做什么:说明当前主模型本身就是 `local-router/gpt-5.4`,所以请求确实在打 `local-router` provider。
- 已验证线索:
- 日志中大量出现:`OpenClaw fallback model: gpt-5.4 via http://localhost:8317/v1`
- 为什么:用户往往观察的是模型风格或某个具体模型名,而不是 provider 维度的流量。
7. **补充历史与当前状态的区别,避免把旧日志当成当前事实**
- 要做什么:如果系统里有历史上目标模型被调用的痕迹,要明确说明“曾经用过”不等于“现在还在用”。
- 已验证历史线索:
- 曾出现过 `requested=local-router/claude-opus-4-6-thinking`
- 曾出现 `candidate_failed... reason=rate_limit`
- 然后 fallback 到 `aigocode-gpt/gpt-5.4-codex`
- 为什么:日志回看很容易把旧配置时期的调用轨迹误判为当前链路。
8. **检查辅助链路,避免只盯主 Agent**
- 要做什么:同时看 memory/plugin 等辅助组件的模型。
- 已验证线索:
- `memos-local-openclaw-plugin` 的 summarizer 使用 `claude-sonnet-4-6`
- endpoint 为 `http://localhost:8317/v1`
- 为什么:系统可能“用了 local-router”,但用在插件辅助链路,而不是主 Agent;这会影响用户体感。
9. **针对“是否所有请求到 local-router/gpt-5.4 都成功”做日志核验**
- 要做什么:不要只依据配置;要找失败证据。
- 已验证失败日志:
- `2026-03-14T05:32:22.073+08:00`
- `embedded run agent end`
- `isError=true`
- `model=gpt-5.4`
- `provider=local-router`
- `error=500 Post "https://chatgpt.com/backend-api/codex/responses": EOF`
- 为什么:只要存在一条明确失败记录,就足以否定“全部成功”这个命题。
10. **区分“没有看到 fallback 证据”与“没有发生 fallback”**
- 要做什么:检查是否存在标准化 fallback 决策日志。
- 已验证精确结果:
- `requested=local-router/gpt-5.4` → `0` 条
- `candidate_failed requested=local-router/gpt-5.4` → `0` 条
- `candidate_succeeded requested=local-router/gpt-5.4` → `0` 条
- 为什么:日志中缺少标准字段,只能说明“证据不完整”,不能直接推出“绝对没有 fallback”。
11. **解释为什么 `OpenClaw fallback model: gpt-5.4 via http://localhost:8317/v1` 不能直接当作 fallback 发生证据**
- 要做什么:把这类日志视为“配置/调试打印”的高可能信号,而不是逐请求 fallback 决策记录。
- 为什么:否则会把“当前 fallback 配置值”误读成“本次请求确实从主模型掉进 fallback 候选”。
12. **给出严谨结论,而不是过度下判断**
- 要做什么:按证据强度输出:
- 可以确定:`local-router/gpt-5.4` 是当前主模型
- 可以确定:并非所有请求都成功
- 不能确定:所有失败后都没有进入 fallback
- 只能说:当前看不到清晰完整的标准 fallback 决策链
- 为什么:这种问题最怕把“没查到”说成“没有发生”。
13. **当用户追问 ClaudeCodeCLI 中断原因时,先解读退出码**
- 要做什么:对 `Exec failed (..., code 143)` 进行归因。
- 已验证解释:
- `143 = 128 + 15`
- 通常对应 `SIGTERM`
- 表现为“被外部终止”
- 为什么:退出码是判断“CLI 自己报错”还是“外层执行环境杀进程”的关键证据。
14. **结合执行现象判断是外层 exec/调度问题,而非 Claude 本身逻辑错误**
- 要做什么:结合这些现象给结论:
- 会话:`mild-breeze`
- 状态:`failed`
- 持续约 3 分钟 1 秒
- 没留下有效 stdout
- 结论:高概率不是 Claude 自己正常报错退出,而是外层执行容器/调度把进程终止了。
- 为什么:如果是参数、权限、认证、网络等 CLI 级错误,通常更容易留下 stderr 或非 143 退出码。
15. **给出高概率原因排序**
- 要做什么:按优先级解释中断来源:
1. 外层 exec 会话超时或被回收
2. `stdin` / heredoc / pipeline 方式不稳
3. Claude CLI 等待某些外部资源,导致上层误判并终止
- 已验证调用方式线索:
- 先写 `/tmp/claude_review_prompt.txt`
- 再 `claude -p < /tmp/claude_review_prompt.txt`
- 为什么:用户不仅要知道“发生了什么”,还要知道后续流程该避免什么。
16. **在后续流程中改用结果落盘,而不是只依赖 stdout**
- 要做什么:用输出文件保存结果与错误。
- 已验证建议命令:
```bash
claude -p... > /tmp/claude_review_output.txt 2>/tmp/claude_review_error.txt
```
- 为什么:即使 session 输出流断掉,也更有机会保住最终产物,方便补救和审计。
17. **改用后台任务 + 轮询方式管理长任务**
- 要做什么:后续流程改为:
1. 后台启动 Claude Code review
2. 记录 session id / pid
3. 轮询进程状态
4. 检查结果文件是否生成
5. 超时则显式判定失败并回收
- 为什么:这比“前台阻塞等待 stdout”更稳,更适合 OpenClaw 编排外部 CLI。
18. **在正式大任务前加最小健康探针**
- 要做什么:先运行极小命令,例如:
```bash
claude -p "reply with OK"
```
- 验证点:
- 命令是否可返回
- 当前认证是否正常
- print 模式是否正常
- 当前工作目录是否会触发异常
- 为什么:先发现环境问题,能避免把长任务直接送进不稳定链路。
19. **区分多层超时并单独处理**
- 要做什么:将超时拆成:
- CLI 内部超时
- OpenClaw exec 外层超时
- 结果文件未生成超时
- 为什么:这样才能知道究竟是模型慢、CLI 卡住,还是 orchestrator 把子进程回收了。
20. **输出时直接闭环,不把“继续捞结果”再抛回给用户**
- 要做什么:在这种协作流程里,直接输出:
- 配置分析结果
- 日志证据
- 失败归因
- 后续规避方案
- 为什么:用户要求的是完成后的结果整理,而不是让用户再决定是否继续补救链路。
Pitfalls and solutions
❌ **看到 provider 里注册了某模型,就认定它在被使用**
→ 失败原因:`models.providers.local-router.models[]` 只能证明“可用”,不能证明“某个 Agent 正在引用它”
✅ **先查 Agent 主模型和 fallback 链,再判断模型是否真在执行链路中**
❌ **把“没打到 local-router/claude-opus-4-6-thinking”理解成“没打到 local-router provider”**
→ 失败原因:provider 命中和具体模型命中是两层概念
✅ **分别判断 provider 流量和模型流量;当前确实在打 `local-router`,但主走的是 `local-router/gpt-5.4`**
❌ **只看当前 provider 声明,不看 fallback 链**
→ 失败原因:某模型不在 fallback 链里,就算主模型失败也不会自然切过去
✅ **核对 `agents.defaults.model` 的完整 fallback 列表**
❌ **看到 `OpenClaw fallback model: gpt-5.4 via http://localhost:8317/v1` 就断言“本次请求发生了 fallback”**
→ 失败原因:这类日志更像配置/调试打印,不一定是逐请求决策日志
✅ **以 `requested=...`、`candidate_failed`、`candidate_succeeded` 这类更强证据为准**
❌ **因为没查到标准 fallback 日志,就断言“完全没有 fallback”**
→ 失败原因:日志打点可能不完整,错误也可能发生在 provider 适配器层
✅ **表述为“当前没有看到清晰完整的 fallback 决策证据”,避免过度结论**
❌ **把一次 `500 EOF` 失败忽略掉,继续说“所有请求都成功”**
→ 失败原因:只要存在一条明确失败日志,就足以推翻“全成功”
✅ **先确认是否有任意失败样本,再谈成功率和 fallback 概率**
❌ **把 `code 143` 当作 ClaudeCodeCLI 自身功能错误**
→ 失败原因:`143` 通常是 `SIGTERM`,更像外层调度/会话终止
✅ **优先从 exec 包装层、会话回收、超时策略和 stdin 生命周期分析**
❌ **直接前台等待长任务 stdout 作为唯一结果来源**
→ 失败原因:会话被回收时,stdout 常常拿不到,导致“任务做了但结果丢了”
✅ **把 stdout/stderr 都落盘,并用后台轮询接回结果**
❌ **用 heredoc / stdin 重定向跑长时间 CLI,而不做探针**
→ 失败原因:包装层对子进程树和输入流生命周期不稳定
✅ **先跑 `claude -p "reply with OK"` 探针,再启动正式任务**
Key code and configuration
当前 Agent 主模型与默认 fallback(已验证)
agents:
main:
model: local-router/gpt-5.4
coder:
model: local-router/gpt-5.4
writer:
model: local-router/gpt-5.4
defaults:
model:
primary: local-router/gpt-5.4
fallbacks:
- aigocode-gpt/gpt-5.4-codex
- openai-codex/gpt-5.4
- local-router/gpt-5.3-codex
- aigocode-gpt/gpt-5.3-codex目标模型当前所处位置(已验证语义)
models:
providers:
local-router:
models:
- local-router/gpt-5.4
- local-router/gpt-5.3-codex
- local-router/claude-opus-4-6-thinking
- claude-sonnet-4-6关键失败日志样例:证明 `local-router/gpt-5.4` 并非全成功
2026-03-14T05:32:22.073+08:00
embedded run agent end
isError=true
model=gpt-5.4
provider=local-router
error=500 Post "https://chatgpt.com/backend-api/codex/responses": EOF历史上目标 Claude 模型曾被请求的证据样式
requested=local-router/claude-opus-4-6-thinking
candidate_failed... reason=rate_limit
fallback -> aigocode-gpt/gpt-5.4-codex当前缺失的标准 fallback 决策证据
requested=local-router/gpt-5.4 -> 0
candidate_failed requested=local-router/gpt-5.4 -> 0
candidate_succeeded requested=local-router/gpt-5.4 -> 0辅助链路使用的模型线索
memos-local-openclaw-plugin summarizer:
model = claude-sonnet-4-6
endpoint = http://localhost:8317/v1ClaudeCodeCLI 中断的关键状态
session = mild-breeze
status = failed
duration ≈ 3m1s
Exec failed (..., code 143)不稳定的调用方式线索
claude -p < /tmp/claude_review_prompt.txt更稳的结果落盘方式
claude -p... > /tmp/claude_review_output.txt 2>/tmp/claude_review_error.txt最小健康探针
claude -p "reply with OK"Environment and prerequisites
- `agents.main`
- `agents.coder`
- `agents.writer`
- `agents.defaults.model`
- `models.providers.local-router.models[]`
Companion files
More tools from the same signal band
Order food/drinks (点餐) on an Android device paired as an OpenClaw node. Uses in-app menu and cart; add goods, view cart, submit order (demo, no real payment).
Sign plugins, rotate agent credentials without losing identity, and publicly attest to plugin behavior with verifiable claims and authenticated transfers.
The philosophical layer for AI agents. Maps behavior to Spinoza's 48 affects, calculates persistence scores, and generates geometric self-reports. Give your...