故障排查
大多数团队问题都可归入以下四类之一:运行时设置、启动确认、任务解析以及提供方限制。
快速证据准备
对于任何团队生命周期问题,请先定义以下变量,并复用同一个 shell:
TEAM="<team-name>"
TEAM_DIR="$HOME/.claude/teams/$TEAM"
TASKS_DIR="$HOME/.claude/tasks/$TEAM"然后在解读 UI 状态之前,先确认预期的文件确实存在:
test -d "$TEAM_DIR" && find "$TEAM_DIR" -maxdepth 2 -type f | sort | sed -n '1,80p'
test -d "$TASKS_DIR" && find "$TASKS_DIR" -maxdepth 1 -name '*.json' | sort | sed -n '1,40p'证据优先
不要仅凭一个卡住的徽章就去修改 prompt、提供方设置或清理进程。请先将 UI 与持久化文件、启动产物以及运行时证据相互印证。
团队无法启动
按顺序逐项检查:
- 运行时可用 —— 所选 CLI(
claude、codex、opencode)已安装 - PATH 可达 —— 二进制文件在环境
PATH中可用 - 模型访问 —— 提供方有权访问所请求的模型字符串(尤其对于 OpenCode,精确的提供方/模型名称至关重要)
- 项目路径 —— 项目目录存在且可读
- 网络 / VPN —— 某些提供方会在 VPN 处于激活状态时丢弃流量
TIP
在终端中运行运行时二进制文件以验证 PATH 和认证。例如:claude --version 或 opencode --version。
OpenCode:已注册但引导未确认
如果 OpenCode 显示 registered 但引导未确认,请先检查产物,然后再更改团队 prompt。
贡献者/调试细节见贡献者架构,其中链接到权威的智能体团队调试操作手册。
查看最新的启动失败产物:
LATEST_FAILURE="$TEAM_DIR/launch-failure-artifacts/latest.json"
MANIFEST_PATH="$(jq -r '.manifestPath' "$LATEST_FAILURE")"
jq '.classification, .bootstrapTransportBreadcrumb, .memberSpawnStatuses' "$MANIFEST_PATH"latest.json 指向最新打包的产物目录及其 manifest.json。该 manifest 包含:
classification—— 此次启动被判定为失败的原因bootstrapTransportBreadcrumb—— 所使用的投递路径- 成员 spawn 状态
- 已脱敏的日志和追踪
同时检查通道(lane)manifest:
jq '.lanes' "$TEAM_DIR/.opencode-runtime/lanes.json" 2>/dev/null
find "$TEAM_DIR/.opencode-runtime/lanes" -maxdepth 2 -name manifest.json -print -exec jq '.activeRunId, .entries' {} \; 2>/dev/null不要凭 UI 猜测
始终将 UI 诊断与持久化文件(launch-state.json、bootstrap-journal.jsonl)以及运行时专有证据相互印证。
通用诊断
从磁盘上的持久化文件开始,而不是仅看 UI。
团队根目录
printf '%s\n' "$TEAM_DIR"关键文件及其所能告诉你的信息:
launch-state.json—— 成员启动/存活状态(.teamLaunchState、.summary、.members)bootstrap-journal.jsonl—— 来自 CLI/运行时的有序引导事件(tail -80)bootstrap-state.json—— 引导阶段摘要config.json—— 提供方、模型和项目配置inboxes/*.json和sentMessages.json—— 消息投递状态
jq '.teamLaunchState, .summary, .members' "$TEAM_DIR/launch-state.json"
tail -80 "$TEAM_DIR/bootstrap-journal.jsonl" 2>/dev/nullOpenCode 运行时证据
对于 OpenCode 队友,会话证据位于通道(lane)运行时存储中:
.opencode-runtime/lanes.json—— 带状态的通道索引.opencode-runtime/lanes/<lane>/manifest.json——activeRunId和证据条目.opencode-runtime/lanes/<lane>/opencode-sessions.json—— 已提交的会话记录
预期的健康状态:通道状态为 active,manifest 带有 activeRunId 且至少有一个证据条目,成员的 bootstrapConfirmed: true。
jq '.lanes' "$TEAM_DIR/.opencode-runtime/lanes.json" 2>/dev/null
find "$TEAM_DIR/.opencode-runtime" -maxdepth 3 -type f | sort启动失败产物
当一次启动被标记为失败时,检查 latest.json:
LATEST_FAILURE="$TEAM_DIR/launch-failure-artifacts/latest.json"
jq '.' "$LATEST_FAILURE"
jq '.' "$(jq -r '.manifestPath' "$LATEST_FAILURE")"该 manifest 包含:
classification—— 此次启动被判定为失败的原因bootstrapTransportBreadcrumb—— 所使用的投递路径- 成员 spawn 状态以及已脱敏的日志/追踪
智能体回复缺失
打开任务日志和队友消息。回复缺失常常源于:
- 运行时投递重试 —— 智能体可能已经作答,但消息未投递到应用。请检查投递账本(ledger)。
- 解析或过滤 —— 智能体输出未包含预期的标记或任务引用。
- 任务归属 —— 工作确实在会话期间发生,但因为输出中缺少正确的任务 id 而未与任务关联。
不要把沉默当成忽略
在日志确认之前,不要假定模型忽略了消息。
使用持久化的消息状态来区分“未发送”和“已发送但未渲染”:
jq '.' "$TEAM_DIR/inboxes/user.json" 2>/dev/null
jq '.' "$TEAM_DIR/sentMessages.json" 2>/dev/null检查 from、to、messageId、relayOfMessageId 和 taskRefs。对于 OpenCode 队友,在假定模型忽略了 prompt 之前,还要检查运行时投递证据。
任务未关联到变更
使用任务专属日志和代码审查链接。如果某个 diff 看起来是脱离关联的:
- 检查智能体输出中是否包含了任务 id 或任务引用。
- 验证智能体在进行编辑之前是否调用了
task_add_comment。 - 确保智能体调用了
task_start,以便看板知道工作已开始。
对于 OpenCode 队友,证明某个会话属于某个任务的权威证据位于 opencode-sessions.json 和通道(lane)manifest 条目中,而不仅仅是 UI 消息流。
任务日志分诊
当任务日志看起来不完整时,按任务 id 在任务 JSON、收件箱(inboxes)和引导事件中进行搜索:
TASK="<short-or-full-task-id>"
rg -n "$TASK" "$TASKS_DIR" "$TEAM_DIR/inboxes" "$TEAM_DIR/bootstrap-journal.jsonl" 2>/dev/null仔细解读结果:
| 证据 | 它能证明什么 | 它不能证明什么 |
|---|---|---|
| 消息已投递 | 应用写入或转发了一条 prompt | 智能体取得了进展 |
| 任务评论 | 智能体发布了看板可见的文本 | 该评论是有意义的进展 |
| 原生工具行 | 运行时在某个会话中做了工作 | 除非归属匹配,否则该工作属于此任务 |
| 变更账本条目 | 应用记录了文件变更 | 实现是正确的 |
对于 OpenCode,健康的任务日志通常包含原生运行时行,如 read、bash、edit 或 write,外加 Agent Teams MCP 行。如果你只看到 agent-teams_* 行,请在扩大日志匹配范围之前先确认任务归属和会话边界。
速率限制
如果提供方报告了一个已知的重置时间,Agent Teams 可以在冷却结束后提醒 lead 继续。如果重置时间未知,则等待或切换提供方/运行时路径。
| 提供方行为 | 建议操作 |
|---|---|
| 显示了已知的重置时间 | 等待冷却后继续 |
| 未显示重置时间 | 切换提供方或运行时路径 |
| 反复出现 429 | 降低并发或使用不同的模型通道(lane) |
CLI 认证问题
claude login 未持久化
如果 CLI 在某个终端中已认证,但应用却说未认证,请验证认证是否已保存到预期的配置路径,以及应用进程是否看到相同的 $HOME。
OpenCode 提供方密钥被拒绝
- 仔细核对
config.json中的提供方名称是否与模型字符串中的提供方前缀匹配 - 确保密钥未在提供方控制台中过期或被吊销
认证诊断日志
每次调用 CliInstallerService.getStatus() 都会向 Electron 日志文件夹中的 claude-cli-auth-diag.ndjson 追加一行(在 macOS 上通常为 ~/Library/Logs/<product-name>/)。如果该文件超过 512 KiB,则会在下一次写入之前被截断为空。
如果你在打包后的应用中看到 “Not logged in” 或认证错误,请检查此文件。
通道(lane)引导卡住
对于 OpenCode 次级通道(secondary lane):
- 缺少
inboxes/<member>.json并不自动意味着这是 bug。OpenCode 通道在启动之前不必先由主收件箱创建。 - 如果 UI 显示团队仍在启动,而主成员已经可用,那么“所有队友已加入”正在等待次级通道。
- 如果
Prepared communication channels for X/Y members卡住,请验证Y是否错误地把次级 OpenCode 成员计算在内。
通道(lane)manifest 条目为空
如果桥接(bridge)声称引导成功,但 manifest.json 显示 entries: [],问题在于证据提交,而不是模型行为。在 opencode-sessions.json 及其 manifest 条目存在之前,不得将该成员视为可投递。
常见成员状态
| 状态 | 含义 |
|---|---|
confirmed_alive + bootstrapConfirmed | 健康且就绪 |
registered / runtime_pending_bootstrap | 进程或通道存在,但引导证据尚未提交 |
failed_to_start + runtime_process | 进程存在,但启动门控失败。请检查诊断 |
failed_to_start + stale_metadata | 已保存的 pid/session 已过期或已失效 |
WARNING
member_briefing 本身并不是运行时证据。对于 OpenCode,权威证据是已提交的运行时证据,例如 opencode-sessions.json 和 manifest 条目。
运行时调试模式
对于本地调试,你可以强制队友在 tmux 窗格中运行:
# Launch from a terminal
CLAUDE_TEAM_TEAMMATE_MODE=tmux pnpm dev
# Or add to custom CLI args
--teammate-mode tmux用它来检查交互式 CLI 行为。不要将其视为与进程后端完全等价。
冒烟检查
正常验证请使用桌面 Electron 应用。浏览器/Web 开发模式不包含完整的桌面运行时、IPC、提供方认证、终端或团队生命周期行为。
仅文档的变更
从仓库根目录:
pnpm --dir landing docs:build
git diff --check -- landing/product-docs团队生命周期变更
先收窄范围,再逐步扩展:
pnpm test -- test/main/services/team/TeamProvisioningService.test.ts
pnpm test -- test/main/services/team/TeamAgentLaunchMatrix.safe-e2e.test.ts
pnpm typecheck
git diff --check实时团队冒烟测试
使用一个小型团队和一个受 Git 跟踪的一次性项目:
- 用
pnpm dev启动桌面应用。 - 创建一个 lead 加一个 builder。
- 请求一个带有明确验证命令的微小变更。
- 确认任务从
pending->in_progress->completed移动。 - 打开任务日志,验证工具行、任务评论和文件变更相互对应。
- 清理时只停止冒烟测试自有的团队/进程。
仅做收窄清理
在清理一次冒烟运行时,不要杀掉所有 OpenCode 主机、无关的 tmux 窗格或用户团队。
安全清理
清理过期进程时:
- 识别 pid 并确认它属于当前团队 / 通道。
- 只停止明确属于冒烟测试或你正在调试的那次启动的进程。
- 不要为了图省事而杀掉所有 OpenCode 或共享主机进程。
何时收集证据
在寻求帮助之前,收集:
- 任务 id(短的或完整的)
- 团队名称
- 运行时路径(
claude、codex或opencode) - 启动日志摘录(来自
latest.json或bootstrap-journal.jsonl) - 提供方 / 模型字符串
- 问题发生的确切时间窗口
这些数据通常足以调试启动和任务生命周期问题。
TIP
如果问题仍然存在,打开团队位于 ~/.claude/teams/<teamName>/ 下的持久化文件,并在更改代码之前将 UI 诊断与实时进程状态相互印证。
