nanobot 故障定位表

对应源码

故障边界源码
入口和配置nanobot/cli/commands.py、nanobot/config/loader.py、nanobot/config/paths.py
Agent Loop 和 Runnernanobot/agent/loop.py、nanobot/agent/runner.py
Provider retry/fallbacknanobot/providers/base.py、nanobot/providers/fallback_provider.py
Tool discovery/validationnanobot/agent/tools/loader.py、nanobot/agent/tools/registry.py
Session 和原子保存nanobot/session/manager.py
Channel/API/WebUInanobot/channels/、nanobot/api/server.py、nanobot/webui/、webui/src/

五问法

遇到问题先回答五个问题:

  1. 入口到了吗? CLI/API/Channel 是否真的构造了请求?
  2. Session 对吗? 实际 session key 与 workspace 是否符合预期?
  3. 停在哪层? AgentLoop state、Runner、Provider、Tool、Channel 还是 UI?
  4. 证据是什么? 日志、state trace、Runtime Event、Session 文件和 wire frame 分别说明什么?
  5. 最小复现是什么? 能否去掉 WebUI、真实 Channel 或非必要 Tool?
flowchart LR
    A["入口"] --> B["AgentLoop"]
    B --> C["AgentRunner"]
    C --> D["Provider / Tool"]
    B --> E["Session"]
    B --> F["Outbound / Event"]
    F --> G["Channel / API / SDK / WebUI"]

常见症状

症状第一检查边界看什么证据常见原因下一步
命令无法启动CLI 与配置加载traceback、实际配置路径、Python 环境依赖未安装、配置解析失败、${VAR} 缺失、端口占用运行最小 nanobot --help/status,再查 nanobot/config/loader.py
DeepSeek 返回 401/403Provider 凭据HTTP 状态、active provider;不打印 key环境变量不在当前进程、key 无效、Provider 选错只验证 DEEPSEEK_API_KEY 是否存在,再核对 preset/provider
Provider 返回 429/5xxProvider retry/fallbackretry 日志、_retry_wait、最终 error限流、暂时服务故障、重试策略不合适区分 retry 与 fallback,读 providers/base.py、fallback_provider.py
请求一直不结束Runner 与超时层state trace、最后一次 delta、超时名称Tool 未返回、流空闲、持续目标、外层 LLM 超时区分 API timeout、LLM timeout、stream idle timeout
Tool 没出现在模型 schemaTool discovery/registry注册工具列表、loader 日志未发现模块/entry point、名称冲突、实例无效、作用域不匹配查 loader.py 和 test_tool_loader_*
Tool 被调用但参数报错Tool schemaarguments、validation errorparameters 与执行签名不一致、required/类型/额外字段错误用 ToolRegistry.prepare_call() 或 Tool.validate_params() 的相邻测试复现
Tool 执行成功但模型不知道结果Runner 回填tool result message、call id、截断信息结果未序列化、call id 不匹配、超过字符上限查 AgentRunner 的 Tool result 组装
MCP 启动失败transport 建连command/url、stderr、连接日志Windows 命令归一化、cwd/env 错、服务未启动、SSRF 阻断分开验证 stdio 进程或 HTTP endpoint,再读 mcp.py
MCP 有连接但没有工具enabledTools/注册server 工具清单、包装后名称enabledTools=[]、名称 allowlist 不匹配、初始化未完成对照 raw 名与 mcp_<server>_<tool> 包装名
新消息读不到旧上下文Session key 与回放实际 key、Session JSONL、loaded messagesChannel/chat 改变、override、unified session、历史压缩/上限查 session/keys.py 和 SessionManager
Session 文件损坏或内容缺失SAVE临时文件、原文件、保存异常日志进程异常、磁盘错误、非原子写入路径、并发误用先保留现场,不手工覆盖;查 atomic save tests
/stop 后上下文异常取消/checkpointcancellation 日志、checkpoint、Session 尾部取消发生在 Tool/Provider 边界、恢复失败查 test_task_cancel.py 与 test_stop_preserves_context.py
CLI 正常但 Channel 无回复出站投递OutboundMessage、ChannelManager 重试日志Channel 配置/凭据、路由错、平台 API 失败用直接调用或 fake Channel 隔离核心
有最终回复但没有流式进度hook/Channel 配置callback 是否传入、metadata_wants_stream 缺失、sendProgress=false、Channel 不实现 delta查 progress_hook.py 与 Channel 的 send_delta()
流式内容重复或拼错segment/合并_stream_id、_stream_end、sequence不同 segment 被合并、delta 重放、UI reducer 错从 WebSocket frame 到 React state 逐层核对
WebUI 显示一直运行中Runtime Event/WebSocketTurnRunStatusChanged、TurnCompleted、framecompletion 未发布、订阅器异常、断线/replay 状态错先确认核心已结束,再查 coordinator/adapter
配置改了却没生效config → runtime snapshot实际加载路径、active preset/model改错配置、preset 覆盖、进程未刷新/重启、别名错误查 配置索引
文件 Tool 拒绝 workspace 外路径workspace policyresolved path、access moderestrictToWorkspace、路径逃逸或 symlink 检查不绕过限制;确认任务是否应在 workspace 内完成
Windows 配了 sandbox 但命令仍未隔离OS sandbox启动 warning、sandbox provider/enforced 标志bwrap 路径依赖 Linux/container,Windows 不支持该执行边界把它视为未隔离,改用外部容器/VM 或更低权限环境
Web 抓取被拒绝SSRFURL、解析 IP、redirect 链localhost/内网/保留地址、DNS 结果或重定向被阻断不关闭全局保护;仅审查后添加最小可信 CIDR
Memory 没变化Memory/触发条件Memory 文件、工具调用、Dream/Cron 日志未调用记忆工具、Dream 未启用/未触发、workspace 错区分 Session 历史与 Memory
Cron 没触发调度/时区job store、next run、timezone、statusjob disabled、时区错误、Gateway 未常驻、保护规则单独检查 CronService,不要先改 AgentRunner

最小隔离顺序

WebUI 问题
  → 先用 SDK/direct call 验证核心
  → 再看 Runtime Event 或 progress callback
  → 再看 WebSocket frame
  → 最后看 React state
 
Channel 问题
  → 先用 CLI/direct call 验证 Provider 和 Agent
  → 再构造一条 InboundMessage
  → 再看 OutboundMessage
  → 最后调用真实平台
 
Tool 问题
  → 直接实例化 Tool
  → 验证 schema
  → 通过 ToolRegistry 执行
  → 用 fake Provider 触发 Tool Call
  → 最后做真实模型 smoke test

不要这样排障

  • 不要把 key、完整配置或带凭据的 URL 粘进日志;
  • 不要一开始同时启用 WebUI、真实 Channel、MCP 和多个 Tool;
  • 不要仅因错误在 UI 出现,就从前端组件开始改;
  • 不要用无限重试掩盖认证、schema 或确定性逻辑错误;
  • 不要为了通过测试关闭 workspace 或 SSRF 保护;
  • 不要直接改 Session 文件后继续判断原始故障。

证据仍不足时

明确记录:

  • 最小输入;
  • 使用的入口和 session key(不含敏感值);
  • AgentLoop 最后状态;
  • active Provider/model;
  • 是否发生 Tool Call;
  • 最后一个可观察事件;
  • 是否能用 fake Provider 或 direct call 复现。

然后回到 日志、RuntimeEvent 与测试策略 选择下一层证据。

返回:速查参考