Yoda
参考Agent 设计指南Runtime 生命周期

配置自诊断

CC /doctor 是 Ink 界面化体检(安装/更新/设置/上下文),Codex doctor 是带 JSON 输出与退出码的 18 项 CI 友好诊断;harness 预检 = 二进制 + 认证 + 版本兼容三件套

配置自诊断

结论

两家都有 doctor,但面向的消费者不同。CC 的 /doctor(也可 shell 直跑 claude doctor)是给人看的 Ink 界面:核心是安装健康(安装方式六分类、多重安装冲突检测、ripgrep 可用性)、更新健康(自更新状态/权限/渠道/远端版本)、设置合法性(zod 校验)、再加 CC 特色的上下文体检(CLAUDE.md/agents/MCP 的 token 占用警告、不可达权限规则),但没有机器可读输出。Codex 的 codex doctor给人也给脚本的诊断器:18 项检查(system/installation/runtime/search/config/auth/updates/network/websocket/MCP/sandbox/terminal/git/terminal title/state/thread inventory/app-server/provider reachability)并发执行,--json 输出脱敏的扁平 schema(每项带 category/status/issues/remediation/duration_ms),整体 fail 时退出码 1——明确设计为「只报告不修复」,CI 可直接消费。harness 的预检不应照抄任何一家,而是三件套:二进制存在与版本(which + --version)、认证有效(官方 API probe 或 login status)、版本兼容(与已验证 flag 语义比对);对 Codex 还可以直接吃 codex doctor --json

研究问题

  • CC 的 /doctor 覆盖哪些检查项?如何检测多重安装?
  • Codex 有无对等机制?输出能否被程序消费?
  • harness 应该预检什么?Yoda 现状与机会点?

各 Agent 设计与实现

Claude Code

入口:斜杠命令 /doctorcommands/doctor/index.ts:4-10,描述 "Diagnose and verify your Claude Code installation and settings",可被 DISABLE_DOCTOR_COMMAND 环境变量禁用)[一手源码];CLI 起不来时从 shell 跑 claude doctor(docs troubleshooting.md:22)[一手文档]。

诊断数据层utils/doctorDiagnostic.ts)[一手源码]:

  • DiagnosticInfo 字段:installationTypeversioninstallationPathinvokedBinaryconfigInstallMethodautoUpdateshasUpdatePermissionsmultipleInstallations[]warnings[](issue+fix 成对)、recommendationpackageManagerripgrepStatus(working / system|builtin|embedded)(doctorDiagnostic.ts:54-71);
  • 安装方式六分类:npm-global | npm-local | native | package-manager | development | unknown。检测顺序:NODE_ENV=development → bundled 模式下探测 8 种包管理器(homebrew/winget/mise/asdf/pacman/deb/rpm/apk)→ npm-local → npm 全局路径启发式(含 nvm 路径与 npm config get prefix 前缀比对)(doctorDiagnostic.ts:86-148);
  • 多重安装检测是亮点:同时检查 ~/.claude/local(npm-local)、npm 全局前缀的 bin/claude(并 realpath 解析 symlink——若指向 Homebrew /Caskroom/ 且当前就是 brew 安装则不算重复)、无 bin 入口的「孤儿」全局包、原生安装 ~/.local/bin/claude~/.local/share/claudedoctorDiagnostic.ts:205-315)[一手源码]。claude update 复用同一诊断,更新前先警告多重安装与 PATH 指向问题(cli/update.ts:40-75)[一手源码]。

渲染层screens/Doctor.tsx)的区块结构 [一手源码]:

区块内容位置
Diagnostics当前运行的安装类型+版本、包管理器、路径、invoked binary、config install method、Search(ripgrep 状态与来源)Doctor.tsx:268-318
多重安装/警告multipleInstallations 列表(标注 currently running)、warnings 的 issue+fixDoctor.tsx:334-343
Invalid Settingssettings zod 校验错误(MCP 除外单列)Doctor.tsx:351
Updates自更新开关(含禁用原因)、更新权限(No 时提示 sudo)、渠道、npm/GCS dist-tags(stable+latest 远端版本)Doctor.tsx:66-83, 376-400
Environment Variablesenv 校验错误(capped/error 状态)Doctor.tsx:429, 525
Version Locks版本锁列表(PID 是否存活、清理 stale 锁数量)Doctor.tsx:442, 522
Agent/Plugin Errorsagent 文件解析失败、插件错误Doctor.tsx:450-458
Unreachable Permission Rules永远不会命中的权限规则Doctor.tsx:466
Context Usage WarningsCLAUDE.md / agents / MCP servers 的上下文占用警告(CC 独有)Doctor.tsx:474
SandboxSandboxDoctorSection 组件Doctor.tsx:14, 426

macOS 上 claude doctor 还检查 Keychain 可访问性(登录失败排查路径,docs troubleshooting.md:779)[一手文档]。没有 --json 之类的机器可读输出——doctor 是 Ink 组件,结论只进终端 [一手源码+推断:未发现任何结构化输出路径]。

Codex CLI

入口:一等子命令 codex doctor,帮助文案 "Diagnose local Codex installation, config, auth, and runtime health"(cli/src/main.rs:159-160)[一手源码]。

输出契约(这是与 CC 最大的差异)[一手源码]:

  • flag:--json(脱敏机器可读报告)、--summary(紧凑行)、--all--no-color--asciicli/src/doctor.rs:149-170);
  • 报告 schema 刻意扁平:DoctorReport { schema_version, generated_at, overall_status, codex_version, checks[] },每个 DoctorCheckid/category/status/summary/details/issues/remediation/duration_msDoctorIssue 再细分 severity/cause/measured/expected/remedy——注释明说是为了支持工具能逐行过滤/脱敏(doctor.rs:180-226);
  • 「不修复,只报告」:整体 fail 时退出码 1,让脚本能区分干净环境(doctor.rs:301-331)。

检查项build_reportdoctor.rs:333-429):先同步跑 systeminstallationruntimesearch 四项,然后加载 config,成功则 tokio::join! 并发跑 14 项:configauthupdatesnetworkwebsocketMCPsandboxterminalgitterminal titlestatethread inventoryapp-serverprovider reachability;config 加载失败也有降级路径继续跑子集(doctor.rs:431-439)[一手源码]。几个值得抄的细节:

  • updates 检查会验证「npm install -g 将更新的包根 = 当前运行进程的包根」,提前抓出 PATH/prefix 错位导致的「更新了却没生效」(doctor/updates.rs:1-7 模块注释、50-86);
  • terminal 检查覆盖 dumb terminal、窄于 80x24、非 UTF-8 locale、terminfo 不可读、SSH/WSL/VSCode 等远程指示变量、tmux 关键选项(doctor.rs:107-143 常量表 + terminal_check)——这正是 harness 嵌入 PTY 时最常踩的雷区清单;
  • 网络探测统一走 curl -fsSL --max-time 5,失败只降级为 warning 不掩盖本地问题(doctor/updates.rs:28-32, 174-180)。

差异矩阵

维度Claude CodeCodex CLI
入口/doctor(会话内)+ claude doctor(shell)codex doctor(shell 子命令)
机器可读--json(脱敏、schema_version 化)
退出码语义无明确契约overall fail → exit 1
检查并发React effect 逐块异步渲染tokio::join! 并发 + 每项 duration_ms
安装健康六分类 + 多重安装冲突检测(强项)InstallContext 五分类 + npm 包根错位检测(强项)
更新健康自更新状态/权限/渠道/远端双渠道版本缓存版本 + 远端 latest + npm root match
配置校验settings zod 错误、env 校验config 加载 + strict 检查
认证检查Keychain(macOS)、/status 配合auth + provider 专项 + provider reachability + websocket
上下文体检CLAUDE.md/agents/MCP token 占用警告(独有)
终端体检dumb/窄屏/locale/terminfo/远程/tmux(独有)
MCP 体检配置校验 + 上下文占用server 可达性(disabled 跳过、optional 降 warning)
修复行为claude update/claude install 附带清理动作doctor 纯只读,remediation 给命令建议

最小复现

# CC:会话内 /doctor;或 shell:
claude doctor          # Ink 界面,人读

# Codex:CI 友好
codex doctor --json | jq '.overallStatus, [.checks[] | {id, status}]'
codex doctor --summary; echo "exit=$?"   # fail 时 exit=1

# harness 最小预检(不依赖任一家 doctor)
which claude && claude --version && claude auth status >/dev/null; echo "cc-auth=$?"
which codex && codex --version && codex login status; echo "codex-auth=$?"

Harness 接入建议(Yoda 实践)

Yoda 当前没有「doctor」命名的功能,但已分层实现了预检三件套的前两件 [一手源码]:

  1. 二进制 + 版本DependencyManager 两阶段探测(见版本章),结果含 status/version/path/checkedAt/error,启动即后台跑全量并流式推给 UI(core/dependencies/dependency-manager.ts:104-169);
  2. 认证有效性:注册表为每个 runtime 声明 OfficialApiProbeSpec——用对应 env key 对官方 API 发一个最便宜的认证请求(如 Anthropic GET /v1/modelsx-api-key + anthropic-version 头,OpenAI GET /models 带 bearer;src/shared/runtime-registry.ts:99-110, 682-711),产出 AgentApiProbeResult{ok,status,endpoint,error};订阅态登录则读 CLI 本地登录状态(AgentSubscriptionAccountruntime-registry.ts:176-187);
  3. 本地用量侧写:直接读各 CLI 的本地会话日志聚合 token/成本(AgentLocalUsageruntime-registry.ts:156-174)——这其实是 doctor 没有的「健康 + 消耗」视角。

机会点(按性价比排序):

  • 直接消费 codex doctor --json:Yoda 对 Codex 的深度体检不必自建,spawn 一次解析 overallStatus 与逐项 remediation 即可;注意它有网络探测,应放后台并设超时 [推断];
  • CC 侧补齐多重安装检测:CC doctor 不可机读,但其检查逻辑(~/.claude/local、npm prefix bin/claude~/.local/bin/claude 三处 stat + realpath)足够简单,Yoda 可复刻——Yoda 现在 which 只取第一个命中,正是 CC doctor 要抓的「PATH 指向另一个安装」盲区 [推断];
  • 版本兼容预检:在 probe 之后比对「Yoda 已验证的 flag 语义版本区间」(如 CC --session-id、Codex resume 子命令),不符则降级相应功能并提示升级——这是两家 doctor 都不会替 harness 做的事 [推断];
  • 终端预检清单照抄 Codex:Yoda 的 PTY 尺寸(≥80x24)、TERM、locale 设置可对照 doctor.rs 的 terminal 检查项做自检,提前规避 TUI 渲染劣化。

失效条件

  • CC /doctor 增加机器可读输出(届时 Yoda 应改为直接消费;源为 v2.1.88 重构源,滞后线上约 2 个月)
  • CC 安装六分类或多重安装检测路径变化(doctorDiagnostic.ts 重构)
  • Codex doctor 检查项集合或 --json schema_version 升版(cli/src/doctor.rs
  • Codex doctor 退出码契约变化(当前 fail=1)
  • Yoda 接入 codex doctor --json 后,Codex 把网络探测改为默认跳过/必选(影响超时策略)

参考资料

  • CC docs:claude-code-docs/docs/troubleshooting.md(/doctor 用法、Keychain)、setup.md(claude doctor 验证安装)、troubleshoot-install.md
  • CC 重构源:src_2026-03-31/commands/doctor/index.tsutils/doctorDiagnostic.tsscreens/Doctor.tsxcli/update.ts
  • Codex 源(b89ce9a):codex-rs/cli/src/doctor.rscli/src/doctor/{updates,runtime,system,thread_inventory,background}.rscli/src/main.rs:159-160, 1319
  • Yoda 源:src/main/core/dependencies/dependency-manager.tssrc/shared/runtime-registry.ts(OfficialApiProbeSpec / AgentApiProbeResult / AgentLocalUsage / AgentSubscriptionAccount)

On this page