跳到主要内容

nanobot — 架构与原理

30 秒导读: nanobot 是一个超轻量、可自己拥有的个人 AI agent。你给它配一个大模型,它就能在终端、网页 UI、或 Telegram/Slack/飞书等聊天软件里和你对话,期间调用文件、shell、网页搜索等工具帮你干活,并把对话与学到的东西记进本地工作区。它的卖点不是功能多,而是核心那条主线代码足够小、足够可读——你能真正看懂、改它、自托管。

本项目较大(nanobot/ 下二十多个子包),所以拆成多文件。先读本页建立全景,再按下面的阅读地图下钻。

1. 这是什么(零基础也能懂)

一句话定义: nanobot 是一个用 Python 写的、围绕「小 agent 循环」展开的个人 AI 助手框架。

解决什么问题 / 给谁用? 假设你想要一个属于自己的 AI 助手:它能记住你的偏好、能帮你跑命令改代码、能定时提醒你、能在你常用的聊天软件里随叫随到——但你又不想把这一切交给某个大平台托管。nanobot 就是给这种「想自己拥有一个 agent」的人用的:一条命令装上,配一个模型 API key,就能在终端里跟它说话;打开内置网页 UI 就有一个完整的工作台;接上 Telegram/飞书 等就能在手机上用。

它能做什么(功能):

  • 多渠道接入:CLI、内置 WebUI、Telegram、Discord、Slack、飞书、企业微信、邮件等十几个平台。
  • 工具能力:读写/编辑文件、跑 shell(可沙箱)、网页搜索/抓取、MCP、定时任务(cron)、生成图片、派生子 agent。
  • 记忆:近期会话自动压缩;长期记忆靠「Dream」反思沉淀进 MEMORY.md
  • 长任务:/goal 维持一个跨多轮的持续目标,直到完成。
  • 模型自由:OpenAI 兼容 API、本地模型、Anthropic、Azure、Bedrock、Codex 等;支持 fallback 备用模型。

用起来什么样: 装完后,最小的一次交互就是终端里一句:

nanobot agent -m "Hello!"

它会带着你的工作区上下文,调一次模型,把回答打印出来。要长期常驻、用网页 UI,就 nanobot gateway 起一个网关进程,浏览器开 http://127.0.0.1:8765(见 README.md:292-430)。

一句话直觉/类比: 把 nanobot 想成一个很小的事件循环 + 一根传送带。聊天软件把你的话放上传送带(消息总线),循环引擎取下来、塞进上下文、问大模型「要不要用工具」,用完工具再问一遍,直到模型给出最终答复,再把答复放回传送带送回你眼前。框架的全部复杂度,都是在为这条朴素主线加可靠性、加渠道、加记忆、加安全

2. 顶层全景(它大概怎么转)

nanobot 的运行时是一条异步消息流水线:渠道与 agent 核心通过 MessageBus 解耦,中间没有重型编排层。

怎么读这张图: 控制流是顺时针一圈。最关键的拆分是中间那两个框——AgentLoop 管「面向渠道的一整轮」(会话键、工作区、存盘、出站),AgentRunner 管「面向模型的内循环」(发请求、收工具调用、跑工具、再发)。这条分界线是理解整个项目的钥匙(docs/architecture.md:36-54)。

部件一句话职责:

部件干什么主文件
MessageBus入站/出站两个异步队列,解耦渠道与核心nanobot/bus/queue.pyevents.py
AgentLoop一轮对话的编排:7 态状态机,管会话/上下文/存盘nanobot/agent/loop.py
AgentRunner模型对话循环:发消息、执行工具、喂回结果、判停nanobot/agent/runner.py
ContextBuilder拼系统提示(身份+记忆+技能+近期历史)nanobot/agent/context.py
ContextGovernor发给模型前修复/压缩消息(只改副本)nanobot/agent/context_governance.py
ToolRegistry / ToolLoader工具注册表 + 包扫描自动发现nanobot/agent/tools/registry.pyloader.py
Provider 体系各家大模型实现 + 注册表 + 工厂nanobot/providers/
MemoryStore / Consolidator长期记忆(Dream)+ 近期压缩nanobot/agent/memory.py
安全工作区沙箱、SSRF、shell 沙箱nanobot/security/tools/shell.pytools/sandbox.py

主线走一遍(高层,不进代码):

  1. 你在某渠道发一句话 → 渠道把它包成 InboundMessage 投到总线入站队列。
  2. AgentLoop 的主消费循环取出它,算出会话键(如 telegram:12345),进入 7 态状态机。
  3. 状态机依次:恢复会话 → 必要时压缩历史 → 判断是不是斜杠命令构建初始消息(系统提示 + 历史 + 你这句) → 运行 AgentRunner存盘 → 组装 出站 消息。
  4. AgentRunner 在「运行」这步里转它自己的内循环:问模型;模型若要调工具就执行、把结果喂回去、再问;直到模型给最终答复或撞上迭代上限。
  5. 出站消息回到总线 → 渠道发回给你。

3. 阅读地图(建议顺序)

  1. 01-agent-loop.md — 主线引擎。 先把这条主线吃透:AgentLoop 的状态机 + AgentRunner 的内循环、判停逻辑、注入(mid-turn 追问)。这是项目名所指的那个「小核心」。
  2. 02-tools-context.md — 工具与上下文治理。 工具怎么被自动发现、参数怎么被校验、并发怎么分批;以及发给模型前消息怎么被「治理」(修复畸形工具调用、压缩超长结果)。
  3. 03-providers-channels-bus.md — 总线/渠道/Provider。 想加一个新模型或新聊天平台时看这一章:注册表驱动、两步加 provider。
  4. 04-memory-dream.md — 两层记忆。 近期靠 token 预算触发压缩,长期靠 Dream 异步反思把对话沉淀成可复用的记忆与技能。
  5. 05-safety-boundaries.md — 安全边界。 workspace 限制、bwrap 沙箱、SSRF 守卫,以及它独特的「硬拦截但对话式软恢复」哲学。

4. 巧妙之处(先放在这,细节见各章)

  • Loop / Runner 二分。 把「渠道事务」和「模型事务」彻底分开,调试时一眼知道去哪个文件(01)。
  • 「持久副本 vs 模型副本」分离。 历史消息存盘是一份,发给模型前会被 ContextGovernor 复制一份并修复/压缩;修复绝不污染存盘,于是一条被脏数据卡死的会话能在下一轮自愈(02context_governance.py:176-191)。
  • mid-turn 注入。 agent 干活到一半,你又补了一句,框架能把它「注入」进当前这一轮,而不是开新一轮(01runner.py:233-281)。
  • 硬拦截 + 软恢复。 SSRF/越界是不可绕过的安全墙,但不会让 agent 崩溃——而是把拒绝原因当成「工具错误」喂回模型,让它换思路(05runner.py:1356-1399)。
  • 注册表即真相源。 加一个 provider 只要在 registry.py 加一条 ProviderSpec + schema 加一个字段(03providers/registry.py:1-11)。

5. 边界与局限(诚实)

  • bwrap 沙箱仅限 Linux/容器。 sandbox.py 只实现了 bwrap 后端;不配 sandbox 时 shell 就是直接在工作区里跑,隔离靠的是 workspace 路径策略而非 OS 级隔离(05)。
  • 核心小,外围大。 「小核心」是真的(loop+runner 约 3000 行),但渠道/provider/工具加起来体量不小;README 的「ultra-lightweight」指的是主线,不是整个仓库。
  • 记忆是文件,不是向量库。 长期记忆就是工作区里的 MEMORY.md 等 Markdown 文件 + history.jsonl,靠 Dream 用 LLM 维护;没有语义检索(04)。

6. 代码地图(导航索引)

主题文件关键符号
主消费循环nanobot/agent/loop.pyAgentLoop.runAgentLoop._process_message
一轮的状态机nanobot/agent/loop.pyTurnState_TRANSITIONS_state_build/_state_run/_state_save
模型/工具内循环nanobot/agent/runner.pyAgentRunner.runAgentRunner._run_core_execute_tools
消息事件nanobot/bus/events.pyInboundMessageOutboundMessage
上下文拼装nanobot/agent/context.pyContextBuilder.build_system_promptbuild_messages
上下文治理nanobot/agent/context_governance.pyContextGovernor.prepare_for_model
工具基类/注册nanobot/agent/tools/base.pyregistry.pyloader.pyToolToolRegistryToolLoader
Provider 注册表nanobot/providers/registry.pyProviderSpecPROVIDERS
记忆与 Dreamnanobot/agent/memory.pyMemoryStoreConsolidatorbuild_dream_prompt
安全nanobot/security/network.pytools/sandbox.pyvalidate_url_targetwrap_command