最小故障定位流程
对应源码
| 排障层 | 首先检查的源码 |
|---|---|
| 安装和命令 | pyproject.toml、nanobot/cli/commands.py |
| 配置路径和解析 | nanobot/config/paths.py、nanobot/config/loader.py、nanobot/config/schema.py |
| Provider 和模型 | nanobot/providers/registry.py、nanobot/providers/factory.py、nanobot/providers/base.py |
| Agent 主链 | nanobot/agent/loop.py、nanobot/agent/runner.py |
| 日志目录 | nanobot/config/paths.py::get_logs_dir、nanobot/utils/logging_bridge.py |
| 外围运行表面 | nanobot/channels/、nanobot/api/server.py、nanobot/gateway/、nanobot/webui/ |
学习目标
遇到“nanobot 不工作”时,不从所有模块同时排查,而是用最短路径确定失败层级。
前置知识
- 已完成一次 DeepSeek 配置;
- 能运行带
--logs的 CLI; - 能使用
rg。
总体定位顺序
flowchart TD A["命令能否启动?"] -->|否| I["安装 / Python / entry point"] A -->|是| B["配置能否加载?"] B -->|否| C["JSON / 环境变量 / Pydantic 校验"] B -->|是| D["Provider 能否创建?"] D -->|否| E["preset / provider / model / apiBase"] D -->|是| F["最小 CLI 请求能否回复?"] F -->|否| G["认证 / 上游错误 / timeout / AgentRunner"] F -->|是| H["只排查出错的入口或子系统"]
第 1 层:安装和命令
python --version
python -m pip show nanobot-ai
nanobot --version
python -m nanobot --version如果模块形式有效而 nanobot 无效,问题通常在虚拟环境或命令 entry point,不在 AgentLoop。
第 2 层:配置解析
检查:
- JSON 是否有效;
- 使用的是哪个
--config; - 使用的是哪个
--workspace; ${DEEPSEEK_API_KEY}是否存在;- preset 名称是否与
agents.defaults.modelPreset一致; - camelCase 或 snake_case 字段是否被当前 schema 接受。
PowerShell 中只检查是否存在,不输出 key:
if ([string]::IsNullOrWhiteSpace($env:DEEPSEEK_API_KEY)) {
"DEEPSEEK_API_KEY 未设置"
} else {
"DEEPSEEK_API_KEY 已设置"
}第 3 层:Provider 解析
相关源码:
Config.resolve_preset
→ providers/factory.py::_make_provider_core
→ providers/registry.py::ProviderSpec
→ OpenAICompatProvider检查:
- preset 是否显式选择
deepseek; - 模型名是否为当前可用名称;
- DeepSeek 配置块是否存在;
- apiKey 是否解析;
- 是否意外配置了错误
apiBase。
第 4 层:最小 CLI Turn
使用最少外围组件:
nanobot agent `
--config $nanobotConfig `
--workspace $nanobotWorkspace `
--logs `
--message "回复 OK"如果这里失败,暂时不要启动:
- Gateway;
- Channel;
- WebUI;
- Cron;
- MCP。
第 5 层:模型请求和 Runner
按错误类型判断:
| 错误 | 可能层级 |
|---|---|
| 401/403 | key、权限、Provider endpoint |
| 402 | 账户余额 |
| 422 | 模型名或请求参数 |
| 429 | 限流 |
| 500/503 | Provider 服务 |
| LLM timeout | 网络、上游响应、NANOBOT_LLM_TIMEOUT_S |
| stream idle timeout | 流长时间无事件、NANOBOT_STREAM_IDLE_TIMEOUT_S |
| empty final response | 模型空响应、finalization 分支 |
| tool_error | Tool 查找、校验、执行或安全边界 |
| max iterations | 模型—工具循环没有正常终止 |
第 6 层:只排查新增的外围
最小 CLI 成功后:
API 失败
检查:
- HTTP body;
- multipart;
session_id;- API session lock;
- SSE;
api/server.py。
Channel 失败
检查:
- Channel 是否启用;
allowFrom;- Pairing;
- ChannelManager 是否成功启动;
- 入站消息是否发布;
- outbound 是否被 dispatcher 发送。
WebUI 失败
检查:
- WebSocket Channel;
- Gateway 是否运行;
- RuntimeEventBus;
- WebuiTurnCoordinator;
- 浏览器连接和 token;
- UI 展示,而不是先改 AgentRunner。
Cron 或 Heartbeat 失败
检查:
- Gateway 是否持续运行;
- workspace 是否正确;
<workspace>/cron/jobs.json;- Heartbeat 配置和模板;
- 任务是否因活跃 session 被延后。
日志路径
nanobot/config/paths.py::get_logs_dir() 将日志目录解析到当前 config 所在实例目录下的 logs/。但并非所有启动方式都必然写同一种日志文件;CLI 的 --logs 主要控制运行日志是否显示。
因此应区分:
- 控制台日志;
- 实例
logs/目录; - Channel/WebUI 自身日志;
- 第三方 Provider 返回的错误。
用测试缩小范围
Set-Location "example\nanobot\code-EN"
pytest tests/agent/test_loop_runner_integration.py -q
pytest tests/agent/test_runner_errors.py -q
pytest tests/providers -q不要把“测试通过”直接等同于真实 key 和网络一定正常。它只能证明被测试的本地契约没有失败。
一页式检查表
- Python 3.11+
- 当前虚拟环境中安装的是本地 editable 源码
- 明确使用
--config - 明确使用
--workspace - 环境变量存在,但未打印值
- preset、Provider 和 model 一致
- 最小 CLI 请求已测试
-
--logs已开启 - 已记录完整错误类型和发生层级
- 只在核心成功后排查 API、Channel、WebUI 或 Cron
下一步
进入 一次 Turn 学习导航。