源码目录与阅读顺序

对应源码

阅读层级对应目录或文件
Python 产品代码nanobot/
Agent 核心nanobot/agent/loop.py、runner.py、context.py、tools/
运行表面nanobot/cli/、api/、sdk/、channels/、gateway/、webui/
前端与 Bridgewebui/、bridge/
可执行行为说明tests/
官方用法说明docs/
打包入口pyproject.toml、hatch_build.py

学习目标

读完后,你应当能够:

  • 说出主要目录的职责;
  • 从用户可见行为定位到负责模块;
  • 按调用链阅读,而不是机械遍历文件;
  • 识别核心层、接入层和展示层。

前置知识

项目顶层

路径职责初学优先级
nanobot/Python runtime高
tests/Python 行为和回归测试高
docs/当前仓库官方使用和开发文档高
webui/React/TypeScript WebUI后学
bridge/需要独立桥接服务的集成选学
pyproject.toml包、依赖、CLI entry point、插件入口说明中
.agent/设计、安全和常见陷阱高

nanobot/ 内部地图

目录主要职责先看什么
agent/Turn、Runner、Context、Memory、Tools、Subagentloop.py、runner.py、context.py
bus/Inbound/Outbound 消息队列和 runtime eventsevents.py、queue.py、runtime_events.py
session/Session JSONL、key、goal、continuation、WebUI turn 协调manager.py、keys.py
providers/LLM Provider 契约、注册、创建、fallback 和适配base.py、registry.py、factory.py
channels/外部聊天平台和 WebSocket adapterbase.py、registry.py、manager.py
config/Pydantic schema、加载、路径schema.py、loader.py
cli/Typer CLI 和主要 runtime 组装入口commands.py
api/OpenAI-compatible HTTP APIserver.py
sdk/SDK 类型、stream 和 runtime helper先从 nanobot/nanobot.py 进入
cron/workspace-scoped 调度、绑定 Turn 和投递service.py、bound_runner.py
command/slash command 路由和内置命令router.py、builtin.py
pairing/未授权私聊发送者的配对审批store.py
security/workspace 和网络边界workspace_policy.py、network.py
webui/Python 侧 WebUI API、token、thread 和媒体协调按问题选文件
apps/App 协议和 CLI app 服务不要与 Skill/Tool 混为一谈
audio/转录 Provider 注册和调度选学
skills/内置 Skill 文件先读 README.md
templates/system prompt、bootstrap、Dream、Heartbeat 模板理解上下文时阅读

核心层与边缘层

项目设计约束强调“核心保持小,能力放在边缘”:

flowchart TD
    CORE["核心路径<br/>AgentLoop + AgentRunner"]
    CTX["Context / Session / Provider 契约"] --> CORE
    CORE --> TOOLS["Tools"]
    CORE --> EVENTS["通用 Runtime Events"]
    CH["Channels"] --> CORE
    MCP["MCP"] --> TOOLS
    SK["Skills"] --> CTX
    EVENTS --> UI["WebUI / WebSocket 协调"]
    CRON["Cron / Heartbeat"] --> CORE

设计含义:

  • 新能力优先放在 Tool、Skill、MCP 或 Channel;
  • 只有无法在边缘表达的通用 Turn 行为才进入 AgentLoop/Runner;
  • UI wire 细节不应进入 AgentLoop;
  • Provider 和 Channel 允许少量重复,避免建立难懂的万能基类。

源码依据:

  • .agent/design.md

推荐阅读顺序

第 1 轮:只看骨架

  1. nanobot/bus/events.py
  2. nanobot/bus/queue.py
  3. nanobot/agent/loop.py::TurnState
  4. AgentLoop.process_direct
  5. AgentLoop._process_message
  6. AgentRunner.run
  7. AgentRunner._run_core

目标:只画出主调用链,不进入每个 helper。

第 2 轮:补上下文和状态

  1. nanobot/agent/context.py
  2. nanobot/session/manager.py
  3. nanobot/session/keys.py
  4. nanobot/agent/memory.py
  5. nanobot/bus/runtime_events.py

目标:回答“本轮模型看到了什么、磁盘保存了什么、UI收到了什么”。

第 3 轮:补 Provider 和 Tool

  1. nanobot/providers/base.py
  2. nanobot/providers/factory.py
  3. nanobot/providers/registry.py
  4. nanobot/agent/tools/base.py
  5. nanobot/agent/tools/registry.py
  6. nanobot/agent/tools/loader.py

目标:回答“模型怎么选、工具怎么发现、参数怎么校验、结果怎么回填”。

第 4 轮:选择一个运行表面

根据需要选一条:

  • CLI:nanobot/cli/commands.py
  • API:nanobot/api/server.py
  • SDK:nanobot/nanobot.py
  • Channel:nanobot/channels/base.py → manager.py → 一个具体 Channel
  • WebUI:nanobot/channels/websocket.py → session/webui_turns.py → Python WebUI API → React

第 5 轮:高级机制

  • agent/autocompact.py
  • agent/memory.py
  • session/turn_continuation.py
  • session/goal_state.py
  • agent/subagent.py
  • cron/
  • security/

测试阅读顺序

不要先运行全部测试。按主题选择最接近的文件:

主题测试起点
Loop/Runner 主链tests/agent/test_loop_runner_integration.py
Runner 基本分支tests/agent/test_runner_core.py
工具执行tests/agent/test_runner_tool_execution.py
错误和安全tests/agent/test_runner_errors.py、test_runner_safety.py
Contexttests/agent/test_context_builder.py
Sessiontests/agent/test_session_manager_history.py、test_session_atomic.py
Runtime eventstests/bus/test_runtime_events.py
Providertests/providers/
Channeltests/channels/test_base_channel.py、test_channel_plugins.py
Subagenttests/agent/test_subagent_lifecycle.py

从现象定位目录

现象优先目录
模型选错、key 取错config/、providers/
Tool schema 或参数错误agent/tools/、agent/runner.py
同一对话历史错乱agent/loop.py、session/
Channel 不收或不发channels/、pairing/
UI 状态不刷新bus/runtime_events.py、session/webui_turns.py、channels/websocket.py
Cron 没运行cron/、Gateway 组装、workspace cron store
文件越权agent/tools/filesystem.py、security/
HTTP 工具访问内网security/network.py、Web/MCP 调用方
Prompt 行为变化agent/context.py、templates/、Skills、Session history

常见错误阅读方式

错误一:按文件名猜职责

例如 gateway/runtime.py 名字看起来像 Gateway 的全部 runtime,但主要服务组装路径在 cli/commands.py::_run_gateway。

错误二:把测试当实现替代品

测试证明受保护的行为,但不能替代阅读实际调用链。先确认测试覆盖的入口和边界。

错误三:看到共享代码就假设所有入口一致

API、SDK 和 CLI 都可调用 process_direct(),但它们的 session key、stream adapter、锁和错误格式不同。

错误四:深入单个 Provider 后忘记统一契约

先理解 LLMProvider 和 LLMResponse,再看 DeepSeek 使用的 OpenAI-compatible adapter。

自检

  1. 如果 WebUI 的 _turn_end 不正确,应先检查哪些模块?
  2. 如果一个新能力只是“教模型如何完成某项任务”,为什么应先考虑 Skill?
  3. 如果 API 返回 400,但 CLI 正常,为什么先看 api/server.py?
  4. 为什么 AgentLoop/Runner 的修改门槛应高于 Tool?

下一步

阅读 最小故障定位流程,然后进入“一次 Turn”。