五个入口与运行边界
对应源码
| 入口 | 源码 |
|---|---|
| CLI 与 Gateway 命令 | nanobot/cli/commands.py::agent、_run_gateway |
| Gateway runtime | nanobot/gateway/runtime.py、nanobot/gateway/service.py |
| HTTP API | nanobot/api/server.py |
| Python facade 与 SDK | nanobot/nanobot.py::Nanobot、nanobot/sdk/ |
| Channel | nanobot/channels/base.py、nanobot/channels/manager.py、nanobot/channels/ |
| WebUI Turn 协调 | nanobot/session/webui_turns.py |
学习目标
读完后,你应当能够:
- 区分 CLI、Gateway、HTTP API、Python SDK 和 WebUI;
- 知道哪些路径使用 MessageBus,哪些直接调用
process_direct(); - 根据问题选择正确的调试入口;
- 理解“入口不同”不等于“存在五套 Agent 实现”。
前置知识
- 已完成 第一次 DeepSeek 请求;
- 理解异步函数和消息队列的基本用途。
先建立一个直觉
nanobot 的多个入口共享核心 runtime,但组装方式和输出协议不同:
flowchart TD CLI1["CLI 单次消息"] --> PD["AgentLoop.process_direct"] SDK["Python SDK"] --> PD API["HTTP API"] --> PD CLI2["交互式 CLI"] --> BUS["MessageBus"] CH["Chat Channel"] --> BUS WS["WebSocket Channel / WebUI"] --> BUS BUS --> LOOP["AgentLoop.run / _dispatch"] PD --> TURN["AgentLoop._process_message"] LOOP --> TURN TURN --> RUNNER["AgentRunner"]
共同核心是:
AgentLoop;AgentRunner;- Provider;
- ToolRegistry;
- ContextBuilder;
- SessionManager。
区别主要在:
- 谁创建这些对象;
- 消息是否经过 MessageBus;
- session key 如何生成;
- stream 如何展示;
- 谁负责长期保持进程运行。
1. CLI 单次消息
命令:
nanobot agent -m "Hello"主要路径:
nanobot/cli/commands.py::agent
→ AgentLoop.from_config
→ AgentLoop.process_direct
→ AgentLoop._process_message特点:
- 路径短;
- 不要求 Gateway 常驻;
- 适合验证配置、Provider 和核心 Turn;
- 通过回调显示 stream/progress;
- 默认 session ID 为
cli:direct。
如果“单次 CLI 也失败”,先不要调试 Channel 或 WebUI。
2. 交互式 CLI
命令:
nanobot agent交互式模式创建 MessageBus,并运行:
- AgentLoop 消息消费任务;
- CLI 输入循环;
- outbound 消费任务;
- stream/progress 展示。
它更接近 Channel 模式,但仍然没有外部聊天平台的鉴权、网络和消息格式转换。
3. Gateway
命令:
nanobot gatewayGateway 是长期运行的组装入口。nanobot/cli/commands.py::_run_gateway 创建并连接:
MessageBus;RuntimeEventBus;- Provider snapshot;
SessionManager;- workspace-scoped
CronService; AgentLoop;WebuiTurnCoordinator;ChannelManager;- 可选 health server。
flowchart TD GW["_run_gateway"] --> MB["MessageBus"] GW --> RE["RuntimeEventBus"] GW --> SM["SessionManager"] GW --> CR["CronService"] GW --> AL["AgentLoop"] GW --> WC["WebuiTurnCoordinator"] GW --> CM["ChannelManager"] CM --> MB MB --> AL AL --> RE RE --> WC
Gateway 主要用于:
- Chat Channel;
- WebUI;
- WebSocket;
- Cron;
- Heartbeat;
- Dream;
- 长期后台任务。
nanobot/gateway/runtime.py不等于核心组装流程当前核心 Gateway 组装主要位于
cli/commands.py::_run_gateway。nanobot/gateway/runtime.py还承担进程或服务运行控制。不要仅凭目录名猜调用入口。
4. OpenAI-compatible HTTP API
命令:
nanobot serve主要接口:
POST /v1/chat/completionsGET /v1/modelsGET /health
实现位于 nanobot/api/server.py,使用 aiohttp.web,不是 FastAPI。
请求处理特点:
- JSON 或 multipart 输入;
- session key 为
api:<session_id>,未提供时使用api:default; - 每个 API session 使用独立
asyncio.Lock; - 调用
AgentLoop.process_direct(); - stream 模式使用 SSE;
- SSE 关闭需要等待
process_direct()完成。
因此 API 问题可以分为两层:
HTTP 解析 / SSE / session lock
→ process_direct
→ 通用 Agent 问题5. Python SDK
入口类:
from nanobot import Nanobot主要源码:
nanobot/nanobot.py::Nanobotnanobot/sdk/streaming.pynanobot/sdk/types.py
Nanobot.from_config() 内部创建 AgentLoop。run()、run_streamed() 和 stream() 最终复用 process_direct(),同时提供:
- Python 类型;
- hooks;
- stream event;
- session、memory 和 runtime 客户端;
- 单次运行覆盖项。
SDK 适合嵌入 Python 程序,不负责长期 Channel 连接。
6. WebSocket 与 WebUI
WebUI 不是独立的 Agent runtime。主要关系是:
React/TypeScript WebUI
↔ WebSocket Channel
↔ MessageBus
↔ AgentLoopGateway 中的 WebuiTurnCoordinator 订阅通用 RuntimeEventBus,将 Turn、Goal 和运行状态转换为 WebUI 所需的协调行为。按照项目设计约束:
- AgentLoop 可以发布通用 runtime event;
_turn_end、_goal_status等具体 wire/UI 行为不应塞入核心 AgentLoop;- WebUI/WebSocket 细节留在 coordinator 或 Channel adapter。
五种入口对照
| 入口 | 是否常驻 | 进入核心方式 | 主要输出 | 最适合 |
|---|---|---|---|---|
CLI -m | 否 | process_direct | 终端文本/stream | 最小验证 |
| 交互式 CLI | 会话期间 | MessageBus | 终端交互 | 多轮调试 |
| Gateway/Channel | 是 | MessageBus | 各 Channel 消息 | 聊天平台、自动化 |
| HTTP API | 服务期间 | process_direct | JSON/SSE | 外部程序调用 |
| Python SDK | 由宿主管理 | process_direct | Python 对象/event | 应用内嵌 |
| WebUI | Gateway 常驻 | WebSocket Channel + MessageBus | WebSocket/UI | 浏览器交互 |
调试起点
| 现象 | 首先查看 |
|---|---|
| 所有入口都失败 | Config、Provider factory、AgentLoop/Runner |
| CLI 成功但 API 失败 | api/server.py 的解析、session 和 SSE |
| CLI 成功但 Channel 不回复 | Channel、allowFrom/Pairing、ChannelManager |
| CLI 成功但 WebUI 不更新 | WebSocket、RuntimeEventBus、WebuiTurnCoordinator |
| 普通消息成功但 Cron 不运行 | Gateway、CronService、workspace cron store |
| SDK 返回事件不完整 | SDK streaming adapter 和 process_direct callbacks |
源码与测试
| 主题 | 源码 | 测试 |
|---|---|---|
| CLI | nanobot/cli/commands.py | tests/cli/ |
| Gateway | nanobot/cli/commands.py::_run_gateway | tests/cli/test_gateway_commands.py |
| API | nanobot/api/server.py | tests/test_openai_api.py 或当前 API 测试文件 |
| SDK | nanobot/nanobot.py、nanobot/sdk/ | 搜索 tests 中的 Nanobot 和 streaming |
| Channel | nanobot/channels/ | tests/channels/ |
| Runtime UI 协调 | nanobot/session/webui_turns.py | tests/webui/ 和相关 session 测试 |
测试文件名以当前仓库为准
API 和 SDK 测试可能按功能而不是源码目录命名。运行前使用
rg --files tests | rg "api|sdk|stream"核对。
自检
- 为什么
nanobot serve不需要先把消息发到 MessageBus? - 为什么 Gateway 需要同时创建 MessageBus 和 RuntimeEventBus?
- CLI 成功而 WebUI 失败时,为什么不应该首先修改 AgentRunner?
- WebUI 为什么不能被描述为另一套 Agent?
下一步
阅读 源码目录与阅读顺序。