文章目录

这是一份为你精心准备的 nanobot 项目完全指南。我会带你从零开始,逐步深入这个超轻量级个人 AI 助手的每一个细节。无论你是想使用它,还是想基于它进行二次开发,这里都有你需要的一切。


快速预览

nanobot 是什么?

nanobot 是一个超轻量级的个人 AI 助手,代码行数比同类项目少 99%,但功能却一点不少。它受到 OpenClaw 的启发,由香港大学数据科学实验室(HKUDS)开发维护。

核心特性

  • 🪶 超轻量 - 极简代码,易于理解和修改
  • 🔌 多平台支持 - Telegram、Discord、飞书、Slack、微信等
  • 🤖 多模型支持 - OpenAI、Claude、DeepSeek、Qwen 等
  • 🛠️ 工具丰富 - 文件操作、Shell 命令、Web 搜索、MCP 集成
  • 💾 记忆系统 - 会话历史 + 长期记忆
  • 🎯 技能系统 - 可扩展的能力模块

快速开始

# 安装
pip install nanobot-ai

# 初始化
nanobot onboard

# 配置 API Key(编辑 ~/.nanobot/config.json)

# 开始对话
nanobot agent

第一章:项目简介

本章将带你了解 nanobot 是什么,它的诞生背景、核心设计理念,以及它与其他 AI 助手项目的区别。

1.1 什么是 nanobot?

nanobot 是一个超轻量级(ultra-lightweight)的个人 AI 助手框架。它的目标是用最少的代码实现完整的 AI Agent 功能,让开发者能够轻松理解、修改和扩展。

从代码量来看,nanobot 比同类项目(如 OpenClaw)少 99% 的代码行数,但功能却毫不逊色。这是一个令人印象深刻的工程成就——用更简洁的代码实现相同的功能,意味着更好的可维护性和可理解性。

官方定义

nanobot is an ultra-lightweight personal AI assistant inspired by OpenClaw.

1.2 诞生背景

1.2.1 为什么需要另一个 AI 助手?

市面上的 AI 助手已经很多了:ChatGPT、Claude、AutoGPT、LangChain Agents 等等。那么 nanobot 存在的意义是什么呢?

答案在于 “轻量”“可理解” 这两个关键词。

1.2.2 现有方案的痛点
  1. 代码过于复杂 - 主流 Agent 框架动辄数万行代码,学习曲线陡峭
  2. 依赖过多 - 引入大量外部库,增加了维护负担
  3. 难以定制 - 想要修改某个行为往往牵一发而动全身
  4. 研究门槛高 - 对于想研究 AI Agent 的学者和学生不够友好
1.2.3 nanobot 的设计目标
  • 极简主义 - 用最少的代码实现核心功能
  • 📖 代码可读 - 每一个文件都应该能被轻松理解
  • 🔧 易于扩展 - 添加新功能不应该影响现有代码
  • 🎓 教育友好 - 适合作为学习 AI Agent 的入门项目

1.3 核心特性

1.3.1 多平台集成

nanobot 支持连接多种聊天平台:

平台 连接方式 特点
Telegram Bot API 推荐首选,稳定可靠
Discord Bot API 适合开发者社区
飞书 WebSocket 无需公网 IP
Slack Socket Mode 企业协作
WhatsApp QR 登录 国际常用
微信 HTTP Long Poll 需要第三方服务
QQ botpy SDK 仅支持私聊
钉钉 Stream Mode 企业办公
企业微信 WebSocket 企业内部
Matrix Matrix 协议 去中心化通信
Email IMAP/SMTP 最通用的异步通信
1.3.2 多模型支持

nanobot 内置支持 20+ 大语言模型提供商:

  • 国际主流: OpenAI、Anthropic (Claude)、Google (Gemini)、Mistral
  • 国内厂商: 百度 (ERNIE)、阿里 (Qwen)、字节 (豆包)、MiniMax、Moonshot (Kimi)、智谱 (GLM)、DeepSeek
  • 开源/本地: Ollama、vLLM、OpenVINO Model Server
  • 网关服务: OpenRouter、AIHubMix、SiliconFlow
1.3.3 工具系统

nanobot 内置了丰富的工具:

  • 📁 文件系统工具 - 读取、写入、编辑、列出文件
  • 🖥️ Shell 执行 - 运行终端命令
  • 🌐 Web 工具 - 搜索、获取网页内容
  • 💬 消息发送 - 向各平台发送消息
  • 定时任务 - Cron 表达式调度
  • 🔀 子代理 - 并行执行后台任务
  • 🔌 MCP 集成 - 连接 Model Context Protocol 服务器
1.3.4 记忆系统
  • 会话记忆 - 保存对话历史,支持上下文续接
  • 长期记忆 - MEMORY.md + HISTORY.md 两层结构
  • 自动摘要 - 基于 Token 计数的自动记忆 consolidation
1.3.5 技能系统
  • 内置技能目录 (GitHub、天气、TMux 等)
  • 用户自定义技能
  • 动态加载,无需重启

1.4 与其他项目的对比

1.4.1 代码量对比
项目 估计代码行数 定位
nanobot ~5,000 超轻量 Agent
OpenClaw ~500,000 完整解决方案
LangChain ~100,000+ Agent 框架
AutoGPT ~50,000 实验性 Agent
1.4.2 设计理念差异
  • nanobot: 极简优先,所有功能都是"可选插件"
  • LangChain: 模块化框架,提供大量抽象层
  • AutoGPT: 功能优先,追求自动化程度

1.5 适用场景

1.5.1 个人使用
  • 私人 AI 助手,接入你常用的聊天软件
  • 自动化日常任务(日程管理、信息收集等)
  • 个人知识管理助手
1.5.2 开发研究
  • 学习 AI Agent 的实现原理
  • 基于 nanobot 开发定制化 AI 助手
  • 进行 Agent 相关的学术研究
1.5.3 企业应用
  • 客服机器人
  • 内部知识库助手
  • 办公自动化

1.6 版本与发布

nanobot 采用语义化版本号,当前稳定版本为 v0.1.4 系列。

发布节奏非常活跃,几乎每天都有更新:

  • post1/post2/post3... - 补丁版本
  • postN 累积一定程度后发布正式小版本

1.7 社区与支持

  • GitHub: https://github.com/HKUDS/nanobot

第二章:系统架构

本章深入分析 nanobot 的整体架构设计,包括核心组件、数据流、以及各模块之间的协作方式。理解这些将帮助你把握整个项目的设计脉络。

2.1 架构概览

2.1.1 整体架构图
┌─────────────────────────────────────────────────────────────────────────┐
│                              用户 (User)                                 │
│   Telegram / Discord / 飞书 / Slack / WhatsApp / 微信 / QQ / ...       │
└─────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                         Channel Layer (通道层)                          │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐           │
│  │Telegram │ │ Discord │ │ 飞书    │ │  Slack  │ │  更多   │  ...      │
│  │ Channel │ │ Channel │ │ Channel │ │ Channel │ │Channels │           │
│  └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘           │
└───────┼───────────┼───────────┼───────────┼───────────┼─────────────────┘
        │           │           │           │           │
        └───────────┴───────────┼───────────┴───────────┘
                                ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                         Message Bus (消息总线)                          │
│                    ┌─────────────────────────┐                         │
│                    │   InboundMessage Queue  │                         │
│                    │  ←── ── ── ── ── ── ←   │                         │
│                    │   OutboundMessage Queue │                         │
│                    └─────────────────────────┘                         │
└───────────────────────────────┬─────────────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                      Agent Layer (Agent 层)                            │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │                      Agent Loop                                  │   │
│  │  ┌──────────┐   ┌──────────┐   ┌──────────┐   ┌──────────┐     │   │
│  │  │ Context  │──▶│   LLM    │──▶│  Tools   │──▶│ Response │     │   │
│  │  │ Builder  │   │ Provider │   │ Registry │   │  Writer  │     │   │
│  │  └──────────┘   └──────────┘   └──────────┘   └──────────┘     │   │
│  └─────────────────────────────────────────────────────────────────┘   │
│                                                                         │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐                │
│  │   Session    │  │   Memory     │  │   Skills     │                │
│  │   Manager    │  │   System     │  │   Loader     │                │
│  └──────────────┘  └──────────────┘  └──────────────┘                │
└───────────────────────────────┬─────────────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                    Provider Layer (模型层)                             │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐                  │
│  │ OpenAI   │ │Anthropic │ │ DeepSeek │ │  更多    │                  │
│  │Provider  │ │Provider  │ │Provider  │ │Providers │                  │
│  └──────────┘ └──────────┘ └──────────┘ └──────────┘                  │
└─────────────────────────────────────────────────────────────────────────┘
2.1.2 架构分层

nanobot 采用清晰的分层架构

  1. Channel Layer - 消息入口,对接各种聊天平台
  2. Message Bus - 消息中枢,解耦各层之间的通信
  3. Agent Layer - 核心逻辑,处理 AI 对话
  4. Provider Layer - 模型抽象,对接各种 LLM

这种分层设计的好处:

  • 松耦合 - 各层之间通过定义好的接口通信
  • 可替换 - 更换聊天平台或 LLM 提供商无需修改核心逻辑
  • 可测试 - 每个组件可以独立测试

2.2 核心组件详解

2.2.1 Channel Layer(通道层)

位置: nanobot/channels/

职责: 负责与各个聊天平台通信,接收用户消息,发送 AI 响应。

关键类:

  • BaseChannel - 所有通道的基类,定义接口规范
  • ChannelManager - 通道管理器,协调所有通道
  • 各平台特定实现: TelegramChannel, DiscordChannel, FeishuChannel
2.2.2 Message Bus(消息总线)

位置: nanobot/bus/

职责: 充当各组件之间的"消息中枢",实现发布-订阅模式。

为什么需要消息总线?

想象没有消息总线的架构:

Telegram → Agent → Telegram
Discord  → Agent → Discord
飞书    → Agent → 飞书

每个通道都要直接和 Agent 耦合。如果 Agent 升级了,所有通道都要改。

有了消息总线:

Telegram → Bus ← Agent
Discord  → Bus ← Agent
飞书     → Bus ← Agent

通道和 Agent 解耦了,可以独立开发和测试。

2.2.3 Agent Loop(Agent 循环)

位置: nanobot/agent/loop.py

职责: 这是 nanobot 的核心引擎,负责:

  1. 接收消息
  2. 构建上下文(历史对话、记忆、技能)
  3. 调用 LLM
  4. 执行工具调用
  5. 返回响应
2.2.4 Context Builder(上下文构建器)

位置: nanobot/agent/context.py

职责: 组装发送给 LLM 的完整上下文,包括:

  • 系统提示词(身份、平台策略)
  • 引导文件 (AGENTS.md, SOUL.md, USER.md, TOOLS.md)
  • 记忆内容
  • 技能摘要

引导文件说明:

文件 用途
AGENTS.md Agent 的身份定义和行为规范
SOUL.md 核心价值观和原则
USER.md 用户偏好和设置
TOOLS.md 可用工具的描述
2.2.5 Session Manager(会话管理器)

位置: nanobot/session/manager.py

职责: 管理每个对话会话的历史记录。

2.2.6 Memory System(记忆系统)

位置: nanobot/agent/memory.py

职责: 实现长期记忆功能,让 AI 记住跨会话的重要信息。

两层记忆结构:

  1. MEMORY.md - 长期记忆,存储重要事实和偏好
  2. HISTORY.md - 历史记录,可用于 grep 搜索
2.2.7 Skills System(技能系统)

位置: nanobot/agent/skills.py

职责: 动态加载和管理技能扩展。

技能类型:

  • Always Skills - 总是激活的技能
  • On-demand Skills - 按需加载的技能
2.2.8 Tool Registry(工具注册表)

位置: nanobot/agent/tools/registry.py

职责: 管理所有可用工具的注册和执行。

内置工具:

工具 功能
read_file 读取文件内容
write_file 写入文件
edit_file 编辑文件
list_dir 列出目录内容
exec 执行 Shell 命令
web_search 搜索网页
web_fetch 获取网页内容
send_message 发送消息
spawn 启动子代理
cron 定时任务

2.3 数据流分析

2.3.1 完整消息流程
用户发送消息
    │
    ▼
Channel Layer (例如 Telegram)
    │ 1. 通道收到消息
    │ 2. 验证权限 (is_allowed)
    ▼
Message Bus (Inbound)
    │ 3. 转换为 InboundMessage
    │ 4. 发布到消息队列
    ▼
Agent Loop
    │ 5. 从队列消费消息
    │ 6. 获取/创建会话
    ▼
Context Builder
    │ 7. 构建完整上下文
    │   - 历史消息
    │   - 记忆内容
    │   - 技能
    ▼
LLM Provider
    │ 8. 调用大语言模型
    │ 9. 获取响应
    ▼
    ┌────┴────┐
    │         │
有工具调用   无工具调用
    │         │
    ▼         ▼
Tool        Message Bus
Registry    (Outbound)
    │               │
    ▼               ▼
Execute     Channel Layer
 Tool        (发送回复给用户)
    │
    └─────────────▶ (回到第8步,继续循环)

2.4 配置系统

2.4.1 配置架构

位置: nanobot/config/

核心文件:

  • schema.py - Pydantic 模型定义
  • paths.py - 路径解析逻辑
2.4.2 配置文件位置
  • 默认: ~/.nanobot/config.json
  • 自定义: 通过 --config 参数指定
  • 多实例: 每个实例可有独立配置

2.5 扩展性设计

2.5.1 添加新通道

只需两步:

  1. nanobot/channels/ 下创建新通道类,继承 BaseChannel
  2. nanobot/channels/registry.py 注册
2.5.2 添加新 Provider

只需两步:

  1. providers/registry.py 添加 ProviderSpec
  2. config/schema.py 添加配置字段
2.5.3 添加新工具

nanobot/agent/tools/ 下创建新工具类,继承 BaseTool


第三章:核心概念详解

本章深入讲解 nanobot 的三个核心概念:Agent Loop(Agent 循环)、Message Bus(消息总线)和 Session(会话)。这些是理解整个系统运作的关键。

3.1 Agent Loop(Agent 循环)

位置: nanobot/agent/loop.py

Agent Loop 是 nanobot 的核心引擎,负责处理用户消息并生成响应。理解它的运作方式,就理解了 nanobot 的一半。

3.1.1 核心职责

Agent Loop 做的事情用一句话概括就是:

接收消息 → 构建上下文 → 调用 LLM → 执行工具 → 返回响应

但实际上这是一个循环,因为 LLM 可能需要多次调用工具才能完成用户的请求。

3.1.2 完整工作流程
class AgentLoop:
    async def handle_message(self, msg: InboundMessage):
        # 第1步:准备
        session = self.sessions.get_or_create(msg.session_key)
        session.add_message("user", msg.content)
        
        # 第2步:构建上下文
        context = self.context.build(
            session=session,
            skill_names=msg.requested_skills
        )
        
        # 第3步:LLM 调用循环
        for iteration in range(self.max_iterations):
            response = await self.provider.chat(
                model=self.model,
                messages=context.messages,
                tools=context.tools_schema
            )
            context.add_message(response)
            
            # 第4步:处理 LLM 响应
            if response.tool_calls:
                for tool_call in response.tool_calls:
                    result = await self.tools.execute(
                        name=tool_call.name,
                        arguments=tool_call.arguments,
                        session=session
                    )
                    context.add_tool_result(
                        tool_call_id=tool_call.id,
                        content=result
                    )
                continue
            else:
                break
        
        # 第5步:发送响应
        final_content = context.get_last_message_content()
        await self.bus.publish_outbound(OutboundMessage(
            channel=msg.channel,
            chat_id=msg.chat_id,
            content=final_content
        ))
3.1.3 关键配置参数
class AgentLoop:
    def __init__(
        self,
        bus: MessageBus,
        provider: LLMProvider,
        workspace: Path,
        model: str | None = None,
        max_iterations: int = 40,           # 最大工具调用次数
        context_window_tokens: int = 65_536, # 上下文窗口大小
        ...
    ):

3.2 Message Bus(消息总线)

位置: nanobot/bus/

Message Bus 是 nanobot 的通信中枢,采用发布-订阅模式实现组件间的松耦合通信。

3.2.1 为什么需要消息总线?

在软件设计中,我们追求松耦合。试想如果没有消息总线:

Telegram Channel 需要知道:
- 如何调用 Agent
- Agent 的接口是什么
- 如何处理 Agent 的响应

Discord Channel 也要知道同样的事情...
飞书 Channel 也要知道...

这会导致:

  1. 代码重复 - 每个通道都要写类似的调用逻辑
  2. 紧耦合 - 通道和 Agent 强绑定
  3. 难以测试 - 无法独立测试通道或 Agent

有了消息总线:

Telegram → 发送到 Bus → (谁关心这个消息就让谁处理)
Discord  → 发送到 Bus → (同上)
Agent    → 发送到 Bus → (同上)

通道只需要知道:

  • 如何接收平台消息
  • 如何发送到 Bus

Agent 只需要知道:

  • 如何从 Bus 接收消息
  • 如何发送响应到 Bus
3.2.2 核心数据结构
@dataclass
class InboundMessage:
    """从聊天平台收到的消息"""
    channel: str           # 平台标识: telegram, discord, feishu, ...
    sender_id: str         # 用户 ID
    chat_id: str           # 会话/群组 ID
    content: str           # 消息内容
    timestamp: datetime    # 时间戳
    media: list[str]       # 附件 URL 列表
    metadata: dict         # 平台特定数据
    
    @property
    def session_key(self) -> str:
        """会话唯一标识"""
        return f"{self.channel}:{self.chat_id}"
@dataclass
class OutboundMessage:
    """要发送的消息"""
    channel: str
    chat_id: str
    content: str
    reply_to: str | None = None
    media: list[str] = field(default_factory=list)
    metadata: dict = field(default_factory=dict)

3.3 Session(会话)

位置: nanobot/session/manager.py

Session 管理每个独立对话的历史记录,确保上下文连贯性。

3.3.1 会话标识

会话通过 session_key 唯一标识,格式为:

{channel}:{chat_id}

例如:

  • telegram:123456789 - Telegram 私聊
  • discord:987654321 - Discord 群组
  • feishu:ou_xxxxx - 飞书用户

这确保了:

  • 不同平台的相同用户是不同会话
  • 同一平台的不同用户是不同会话
  • 同一用户的不同群组是不同会话
3.3.2 消息存储格式
@dataclass
class Session:
    key: str                    # "telegram:123456"
    messages: list[dict]        # 消息列表
    created_at: datetime
    updated_at: datetime
    metadata: dict              # 元数据
    last_consolidated: int      # 已合并的消息数

消息格式:

{"role": "user", "content": "你好", "timestamp": "2024-01-01T12:00:00"}
{"role": "assistant", "content": "你好!有什么可以帮助你的吗?", "timestamp": "2024-01-01T12:00:00"}
3.3.3 消息持久化

消息存储在 ~/.nanobot/workspace/sessions/ 目录:

sessions/
├── telegram_123456789.jsonl
├── discord_987654321.jsonl
└── feishu_ou_xxxxx.jsonl

使用 JSONL 格式(每行一个 JSON),方便追加和读取。

3.4 三者的协作

3.4.1 消息流转
用户消息
    │
    ▼
Channel.start() 监听消息
    │
    ▼
Channel._handle_message() 权限检查
    │
    ▼
MessageBus.publish_inbound(InboundMessage)
    │
    ▼
AgentLoop.handle_message() 消费消息
    │
    ▼
SessionManager.get_or_create(session_key)
    │
    ▼
构建上下文 → 调用 LLM → 执行工具 → ...
    │
    ▼
MessageBus.publish_outbound(OutboundMessage)
    │
    ▼
ChannelManager._dispatch_outbound() 消费消息
    │
    ▼
Channel.send() 发送到平台
3.4.2 异步设计

整个系统基于 asyncio 构建:

  • Channel 启动异步任务监听消息
  • AgentLoop 异步处理每个消息
  • 工具执行是异步的
  • 消息队列使用 asyncio.Queue

这确保了系统可以同时处理多个用户的请求。


第四章:消息通道详解

本章详细介绍 nanobot 如何连接各种聊天平台。Channel(通道)是用户与 AI 交互的入口,理解通道的工作原理对于定制和扩展非常重要。

4.1 通道架构概述

4.1.1 BaseChannel 基类

所有通道都继承自 BaseChannel 抽象类,它定义了统一的接口:

class BaseChannel(ABC):
    name: str = "base"
    display_name: str = "Base"
    
    def __init__(self, config: Any, bus: MessageBus):
        self.config = config
        self.bus = bus
        self._running = False
    
    @abstractmethod
    async def start(self) -> None:
        """启动通道,开始监听消息"""
        pass
    
    @abstractmethod
    async def stop(self) -> None:
        """停止通道"""
        pass
    
    @abstractmethod
    async def send(self, msg: OutboundMessage) -> None:
        """发送消息"""
        pass
    
    def is_allowed(self, sender_id: str) -> bool:
        """权限检查"""
        allow_list = getattr(self.config, "allow_from", [])
        if not allow_list:
            return False
        if "*" in allow_list:
            return True
        return str(sender_id) in allow_list

4.2 支持的通道

4.2.1 Telegram

配置:

{
  "channels": {
    "telegram": {
      "enabled": true,
      "token": "YOUR_BOT_TOKEN",
      "allowFrom": ["YOUR_USER_ID"]
    }
  }
}

特点: 官方推荐的首选通道,稳定可靠,功能丰富。

4.2.2 Discord

配置:

{
  "channels": {
    "discord": {
      "enabled": true,
      "token": "YOUR_BOT_TOKEN",
      "allowFrom": ["YOUR_USER_ID"],
      "groupPolicy": "mention"
    }
  }
}

groupPolicy 选项:

  • "mention" - 仅当被 @ 时响应
  • "open" - 响应所有群消息
4.2.3 飞书 (Feishu)

配置:

{
  "channels": {
    "feishu": {
      "enabled": true,
      "appId": "cli_xxx",
      "appSecret": "xxx",
      "allowFrom": ["ou_YOUR_OPEN_ID"],
      "groupPolicy": "mention"
    }
  }
}

特点: 使用 WebSocket 长连接,无需公网 IP。

4.2.4 Slack

配置:

{
  "channels": {
    "slack": {
      "enabled": true,
      "botToken": "xoxb-...",
      "appToken": "xapp-...",
      "allowFrom": ["YOUR_SLACK_USER_ID"],
      "groupPolicy": "mention"
    }
  }
}
4.2.5 WhatsApp

配置:

{
  "channels": {
    "whatsapp": {
      "enabled": true,
      "allowFrom": ["+1234567890"]
    }
  }
}

使用方法:

# 登录(需要两个终端)
nanobot channels login whatsapp  # 终端1:显示 QR 码
nanobot gateway                   # 终端2:运行服务
4.2.6 微信 (WeChat/Weixin)

配置:

{
  "channels": {
    "weixin": {
      "enabled": true,
      "allowFrom": ["YOUR_WECHAT_USER_ID"]
    }
  }
}

注意: 需要安装额外依赖 pip install nanobot-ai[weixin]

4.2.7 QQ

配置:

{
  "channels": {
    "qq": {
      "enabled": true,
      "appId": "YOUR_APP_ID",
      "secret": "YOUR_APP_SECRET",
      "allowFrom": ["YOUR_OPENID"]
    }
  }
}
4.2.8 钉钉 (DingTalk)

配置:

{
  "channels": {
    "dingtalk": {
      "enabled": true,
      "clientId": "YOUR_APP_KEY",
      "clientSecret": "YOUR_APP_SECRET",
      "allowFrom": ["YOUR_STAFF_ID"]
    }
  }
}
4.2.9 企业微信 (Wecom)

配置:

{
  "channels": {
    "wecom": {
      "enabled": true,
      "botId": "your_bot_id",
      "secret": "your_bot_secret",
      "allowFrom": ["your_id"]
    }
  }
}
4.2.10 Matrix

配置:

{
  "channels": {
    "matrix": {
      "enabled": true,
      "homeserver": "https://matrix.org",
      "userId": "@nanobot:matrix.org",
      "accessToken": "syt_xxx",
      "deviceId": "NANOBOT01",
      "e2eeEnabled": true,
      "allowFrom": ["@your_user:matrix.org"]
    }
  }
}

特点: 去中心化通信协议,支持端到端加密。

4.2.11 Email

配置:

{
  "channels": {
    "email": {
      "enabled": true,
      "consentGranted": true,
      "imapHost": "imap.gmail.com",
      "imapPort": 993,
      "imapUsername": "my-nanobot@gmail.com",
      "imapPassword": "your-app-password",
      "smtpHost": "smtp.gmail.com",
      "smtpPort": 587,
      "smtpUsername": "my-nanobot@gmail.com",
      "smtpPassword": "your-app-password",
      "fromAddress": "my-nanobot@gmail.com",
      "allowFrom": ["your-real-email@gmail.com"]
    }
  }
}

注意: Gmail 需要使用应用专用密码

4.3 Channel Manager

文件: nanobot/channels/manager.py

Channel Manager 负责管理所有已启用的通道。

4.4 权限控制

allowFrom 配置

每个通道都有 allowFrom 配置项:

{
  "channels": {
    "telegram": {
      "allowFrom": ["123456789"]  // 仅允许特定用户
    }
  }
}

特殊值:

  • [] (空数组) - 拒绝所有用户(默认)
  • ["*"] - 允许所有用户

4.5 流式输出

某些通道支持流式输出,让用户可以看到 AI 逐字生成的回答。

启用:

{
  "channels": {
    "telegram": {
      "enabled": true,
      "streaming": true
    }
  }
}

第五章:LLM 提供商详解

本章详细介绍 nanobot 支持的各种大语言模型提供商,以及如何添加新的提供商。Provider 层是 AI 对话能力的来源。

5.1 Provider 架构概述

位置: nanobot/providers/base.py

所有 Provider 都继承自 LLMProvider 基类:

class LLMProvider(ABC):
    @property
    @abstractmethod
    def name(self) -> str:
        """提供商名称"""
        pass
    
    @abstractmethod
    async def chat(
        self,
        model: str,
        messages: list[dict],
        tools: list[dict] | None = None,
        **kwargs
    ) -> LLMResponse:
        """发送聊天请求"""
        pass
    
    @abstractmethod
    async def close(self):
        """关闭连接"""
        pass

5.2 Provider Registry

位置: nanobot/providers/registry.py

Provider Registry 是 nanobot 的单一真相来源,定义了所有支持的提供商。

添加新 Provider

只需两步:

Step 1: 在 providers/registry.py 添加 ProviderSpec:

ProviderSpec(
    name="myprovider",
    keywords=("myprovider", "mymodel"),
    env_key="MYPROVIDER_API_KEY",
    display_name="My Provider",
    litellm_prefix="myprovider",
    skip_prefixes=("myprovider/",),
)

Step 2: 在 config/schema.py 添加配置字段:

class ProvidersConfig(Base):
    ...
    myprovider: ProviderConfig = ProviderConfig()

完成!环境变量、模型前缀、配置匹配都会自动工作。

5.3 支持的提供商

5.3.1 国际主流
OpenAI
{
  "providers": {
    "openai": {
      "apiKey": "sk-..."
    }
  },
  "agents": {
    "defaults": {
      "model": "gpt-4o",
      "provider": "openai"
    }
  }
}
Anthropic (Claude)
{
  "providers": {
    "anthropic": {
      "apiKey": "sk-ant-..."
    }
  },
  "agents": {
    "defaults": {
      "model": "claude-sonnet-4-20250514"
    }
  }
}
Google Gemini
{
  "providers": {
    "gemini": {
      "apiKey": "AIza..."
    }
  },
  "agents": {
    "defaults": {
      "model": "gemini-2.0-flash"
    }
  }
}
5.3.2 国内厂商
阿里 Qwen (DashScope)
{
  "providers": {
    "dashscope": {
      "apiKey": "sk-..."
    }
  },
  "agents": {
    "defaults": {
      "model": "qwen-max"
    }
  }
}
智谱 GLM (Zhipu)
{
  "providers": {
    "zhipu": {
      "apiKey": "..."
    }
  },
  "agents": {
    "defaults": {
      "model": "glm-4-flash"
    }
  }
}
DeepSeek
{
  "providers": {
    "deepseek": {
      "apiKey": "sk-..."
    }
  },
  "agents": {
    "defaults": {
      "model": "deepseek-chat"
    }
  }
}
Moonshot (Kimi)
{
  "providers": {
    "moonshot": {
      "apiKey": "..."
    }
  },
  "agents": {
    "defaults": {
      "model": "moonshot-v1-8k"
    }
  }
}
MiniMax
{
  "providers": {
    "minimax": {
      "apiKey": "..."
    }
  },
  "agents": {
    "defaults": {
      "model": "abab6.5s-chat"
    }
  }
}
字节豆包 (VolcEngine/BytePlus)
{
  "providers": {
    "volcengine": {
      "apiKey": "..."
    }
  },
  "agents": {
    "defaults": {
      "model": "doubao-pro-32k"
    }
  }
}
5.3.3 网关服务
OpenRouter
{
  "providers": {
    "openrouter": {
      "apiKey": "sk-or-v1-..."
    }
  },
  "agents": {
    "defaults": {
      "model": "anthropic/claude-sonnet-4-5"
    }
  }
}
SiliconFlow (硅基流动)
{
  "providers": {
    "siliconflow": {
      "apiKey": "sk-..."
    }
  },
  "agents": {
    "defaults": {
      "model": "Qwen/Qwen2-72B-Instruct"
    }
  }
}
5.3.4 本地部署
Ollama
{
  "providers": {
    "ollama": {
      "apiBase": "http://localhost:11434"
    }
  },
  "agents": {
    "defaults": {
      "model": "llama3.2",
      "provider": "ollama"
    }
  }
}
vLLM
{
  "providers": {
    "vllm": {
      "apiKey": "dummy",
      "apiBase": "http://localhost:8000/v1"
    }
  },
  "agents": {
    "defaults": {
      "model": "meta-llama/Llama-3.1-8B-Instruct"
    }
  }
}
5.3.5 OAuth 登录
OpenAI Codex
# 登录(会打开浏览器)
nanobot provider login openai-codex
GitHub Copilot
# 登录
nanobot provider login github-copilot

5.4 自动检测机制

当配置中 provider 设为 "auto" 时,nanobot 会自动检测使用哪个 Provider:

检测优先级:

  1. API Key 前缀检测 - 如 sk-or- → OpenRouter
  2. API Base 关键词检测 - 如 URL 包含 openrouter → OpenRouter
  3. 模型名关键词检测 - 如模型名包含 gpt → OpenAI
  4. 默认 Provider - 兜底方案

第六章:工具系统详解

本章详细介绍 nanobot 内置的工具系统,以及如何通过 MCP 扩展工具能力。工具是 AI Agent 执行具体操作的关键。

6.1 工具系统架构

Tool Registry (工具注册表)
    │
    ├── Built-in Tools (内置工具)
    │   ├── 文件系统工具 (read_file, write_file, edit_file, list_dir)
    │   ├── Shell 工具 (exec)
    │   ├── Web 工具 (web_search, web_fetch)
    │   ├── 消息工具 (send_message)
    │   ├── 定时任务工具 (cron)
    │   ├── 子代理工具 (spawn)
    │   └── Cron 工具
    │
    └── MCP Tools (MCP 扩展工具)
        ├── 文件系统 MCP
        ├── Git MCP
        └── 其他 MCP 服务器

6.2 工具注册表

文件: nanobot/agent/tools/registry.py

class ToolRegistry:
    def __init__(self):
        self._tools: dict[str, BaseTool] = {}
        self._register_builtin_tools()
    
    def register(self, tool: BaseTool):
        """注册工具"""
        self._tools[tool.name] = tool
    
    async def execute(
        self,
        name: str,
        arguments: dict,
        session: Session
    ) -> str:
        """执行工具"""
        tool = self._tools.get(name)
        if not tool:
            return f"Error: Unknown tool '{name}'"
        
        try:
            return await tool.execute(arguments, session)
        except Exception as e:
            return f"Error: {str(e)}"

6.3 内置工具详解

6.3.1 文件系统工具
read_file - 读取文件
read_file(file_path="/path/to/file.txt")
read_file(file_path="/path/to/file.txt", limit=100)
read_file(file_path="/path/to/file.txt", offset=50, limit=100)
write_file - 写入文件
write_file(file_path="/path/to/file.txt", content="Hello World")
write_file(file_path="/path/to/file.txt", content="\nNew line", append=True)
edit_file - 编辑文件
edit_file(
    file_path="/path/to/file.txt",
    old_string="Hello",
    new_string="Hi"
)
edit_file(
    file_path="/path/to/file.txt",
    old_string="Hello",
    new_string="Hi",
    replace_all=True
)
list_dir - 列出目录
list_dir(directory_path="/path/to/dir")
6.3.2 Shell 执行工具
exec(command="ls -la")
exec(command="python script.py")
exec(command="cat file.txt | grep keyword")

配置选项:

{
  "tools": {
    "exec": {
      "enable": true,
      "timeout": 60,
      "path_append": "/usr/local/bin"
    }
  }
}

安全限制:

{
  "tools": {
    "restrict_to_workspace": true
  }
}

启用后,所有文件操作和 Shell 执行都限制在 workspace 目录内。

6.3.3 Web 工具
web_search - 网页搜索
web_search(query="Python async await tutorial")

支持的搜索引擎:

Provider 配置 免费
Brave apiKey
Tavily apiKey
Jina apiKey 是 (10M tokens)
SearXNG baseUrl 是 (自托管)
DuckDuckGo -
web_fetch - 获取网页
web_fetch(url="https://example.com/article")
6.3.4 消息发送工具
send_message(channel="telegram", content="Hello from agent!")
send_message(channel="discord", content="Hello from agent!")
6.3.5 子代理工具
spawn(message="搜索最新的 AI 新闻并总结")

特点:

  • 异步执行,不阻塞主对话
  • 子代理有独立的上下文
  • 结果会通过消息发送回来
6.3.6 定时任务工具
cron(action="list")
cron(action="add", task="每天早上 8 点发送天气提醒", cron="0 8 * * *")
cron(action="remove", task_id="task_123")

Cron 表达式格式:

┌───────────── 分钟 (0 - 59)
│ ┌───────────── 小时 (0 - 23)
│ │ ┌───────────── 日期 (1 - 31)
│ │ │ ┌───────────── 月份 (1 - 12)
│ │ │ │ ┌───────────── 星期 (0 - 6, 0 = 周日)
* * * * *

示例:

  • 0 8 * * * - 每天早上 8 点
  • 0 9 * * 1-5 - 工作日早上 9 点
  • */15 * * * * - 每 15 分钟

6.4 MCP 集成

文件: nanobot/agent/tools/mcp.py

MCP (Model Context Protocol) 是 Anthropic 推出的工具协议,允许 AI 连接外部服务。

6.4.1 MCP 配置
{
  "tools": {
    "mcpServers": {
      "filesystem": {
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"]
      },
      "remote-mcp": {
        "url": "https://example.com/mcp/",
        "headers": {
          "Authorization": "Bearer xxxxx"
        }
      }
    }
  }
}
6.4.2 传输模式
模式 配置 用途
Stdio command + args 本地进程
HTTP url + headers 远程服务
SSE url + headers Server-Sent Events
6.4.3 工具过滤
{
  "tools": {
    "mcpServers": {
      "filesystem": {
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
        "enabledTools": ["read_file", "list_dir"]
      }
    }
  }
}
  • ["*"] - 启用所有工具
  • [] - 不启用任何工具
  • ["tool1", "tool2"] - 只启用指定工具

6.5 安全机制

6.5.1 工作空间限制
{
  "tools": {
    "restrict_to_workspace": true
  }
}

启用后:

  • 文件操作限制在 workspace 目录
  • Shell 执行限制在 workspace 目录
  • 防止路径遍历攻击
6.5.2 Shell 执行开关
{
  "tools": {
    "exec": {
      "enable": false
    }
  }
}

完全禁用 Shell 执行功能。


第七章:记忆系统详解

本章详细介绍 nanobot 的记忆系统,包括短期会话记忆和长期记忆的实现原理。记忆系统让 AI 能够记住跨会话的重要信息。

7.1 记忆系统概述

7.1.1 两层记忆架构

nanobot 采用两层记忆架构

┌─────────────────────────────────────────────────────────────┐
│                      记忆系统                                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Layer 1: 会话记忆 (Session Memory)                         │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 存储在: ~/.nanobot/workspace/sessions/              │   │
│  │ 格式: JSONL                                          │   │
│  │ 内容: 当前会话的完整消息历史                         │   │
│  │ 生命周期: 会话期间                                   │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  Layer 2: 长期记忆 (Long-term Memory)                       │
│  ┌──────────────────────┐  ┌──────────────────────────┐    │
│  │    MEMORY.md         │  │    HISTORY.md            │    │
│  │  重要事实和偏好       │  │  历史记录(可搜索)       │    │
│  │  用户信息、设置       │  │  对话摘要                │    │
│  └──────────────────────┘  └──────────────────────────┘    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

7.2 会话记忆 (Session Memory)

位置: nanobot/session/manager.py

Session 数据结构
@dataclass
class Session:
    key: str                    # 唯一标识: "telegram:123456"
    messages: list[dict]        # 消息列表
    created_at: datetime        # 创建时间
    updated_at: datetime        # 更新时间
    metadata: dict              # 元数据
    last_consolidated: int      # 已合并的消息数
消息持久化

消息存储在 ~/.nanobot/workspace/sessions/ 目录:

sessions/
├── telegram_123456789.jsonl
├── discord_987654321.jsonl
└── feishu_ou_xxxxx.jsonl

JSONL 格式:每行一个 JSON 对象,方便追加。

7.3 长期记忆 (Long-term Memory)

位置: nanobot/agent/memory.py

MemoryStore 类
class MemoryStore:
    """两层记忆: MEMORY.md + HISTORY.md"""
    
    def __init__(self, workspace: Path):
        self.workspace = workspace
        self.memory_file = workspace / "MEMORY.md"
        self.history_file = workspace / "HISTORY.md"
    
    def get_memory_context(self) -> str:
        """获取记忆上下文"""
        if not self.memory_file.exists():
            return ""
        return self.memory_file.read_text()
MEMORY.md - 长期记忆

存储位置:~/.nanobot/workspace/MEMORY.md

内容示例

# Memory

## 用户信息
- 名字: 张三
- 位置: 北京
- 时区: Asia/Shanghai

## 偏好
- 喜欢简洁的回答
- 编程语言: Python > JavaScript

## 重要事实
- 正在开发一个 AI 项目
- 每周一三五开会
HISTORY.md - 历史记录

存储位置:~/.nanobot/workspace/HISTORY.md

内容示例

# History

## 2024-01-15
- 讨论了项目架构设计
- 用户偏好使用 Python

## 2024-01-14
- 解决了 Docker 部署问题
- 添加了新的定时任务

7.4 记忆合并 (Consolidation)

触发条件

记忆合并在以下情况触发:

  1. Token 数量阈值 - 会话消息达到一定数量
  2. 手动触发 - 用户要求保存记忆
Consolidation 流程
class MemoryConsolidator:
    async def consolidate(
        self,
        session: Session,
        provider: LLMProvider,
        model: str
    ):
        # 1. 准备合并提示
        prompt = self._build_consolidation_prompt(
            session.get_history(),
            self.memory_store.get_memory_context()
        )
        
        # 2. 调用 LLM 生成摘要
        response = await provider.chat(
            model=model,
            messages=[{"role": "user", "content": prompt}],
            tools=_SAVE_MEMORY_TOOL
        )
        
        # 3. 解析 LLM 响应
        args = _normalize_save_memory_args(response.tool_calls[0].arguments)
        
        # 4. 保存到文件
        history_entry = args["history_entry"]
        memory_update = args["memory_update"]
        
        # 追加到 HISTORY.md
        self._append_to_history(history_entry)
        
        # 更新 MEMORY.md
        self._update_memory(memory_update)
        
        # 更新会话状态
        session.last_consolidated = len(session.messages)

7.5 上下文构建中的记忆

位置: nanobot/agent/context.py

def build_system_prompt(self, skill_names: list[str] | None = None) -> str:
    parts = [self._get_identity()]
    
    # 加载引导文件
    bootstrap = self._load_bootstrap_files()
    if bootstrap:
        parts.append(bootstrap)
    
    # 添加记忆上下文
    memory = self.memory.get_memory_context()
    if memory:
        parts.append(f"# Memory\n\n{memory}")
    
    # 添加技能
    always_skills = self.skills.get_always_skills()
    if always_skills:
        always_content = self.skills.load_skills_for_context(always_skills)
        if always_content:
            parts.append(f"# Active Skills\n\n{always_content}")
    
    # 技能摘要
    skills_summary = self.skills.build_skills_summary()
    if skills_summary:
        parts.append(f"# Skills\n\n{skills_summary}")
    
    return "\n\n---\n\n".join(parts)

7.6 记忆系统设计理念

为什么不直接保存所有消息?
  1. 上下文窗口限制 - LLM 有 token 上限
  2. 成本考虑 - 更少的 token = 更低的成本
  3. 噪声过滤 - 摘要保留了重要信息
为什么用两层?
  • MEMORY.md - 结构化、可读、用于系统提示词
  • HISTORY.md - 完整记录、可搜索、用于回溯

第八章:技能系统详解

本章详细介绍 nanobot 的技能系统(Skills),如何通过技能扩展 AI 的能力,以及如何创建自定义技能。

8.1 技能系统概述

什么是技能?

技能(Skill)是 nanobot 的一种扩展机制,允许你为 AI 添加额外的能力。每个技能本质上是一个 Markdown 文件,描述了:

  • 技能的功能
  • 如何使用
  • 任何依赖或配置
技能与工具的区别
特性 工具 (Tool) 技能 (Skill)
调用方式 LLM 直接调用 LLM 读取文件后使用
复杂度 简单操作 复杂流程
实现方式 Python 代码 Markdown 描述
动态性 运行时注册 按需加载
技能类型
  1. Always Skills - 始终激活的技能
  2. On-demand Skills - 按需加载的技能

8.2 技能目录结构

内置技能目录

位置: nanobot/skills/

nanobot/skills/
├── github/
│   └── SKILL.md
├── weather/
│   └── SKILL.md
├── tmux/
│   └── SKILL.md
└── ...
工作空间技能目录

用户可以在工作空间添加自定义技能:

~/.nanobot/workspace/
├── skills/
│   ├── my_skill/
│   │   └── SKILL.md
│   └── another_skill/
│       └── SKILL.md
├── MEMORY.md
├── HISTORY.md
├── AGENTS.md
├── SOUL.md
├── USER.md
└── TOOLS.md
SKILL.md 格式
# Skill Name

## Description
简要描述这个技能做什么。

## Usage
如何使用这个技能。

## Tools
这个技能可能使用的工具。

## Examples
使用示例。

8.3 SkillsLoader 实现

位置: nanobot/agent/skills.py

class SkillsLoader:
    def __init__(self, workspace: Path):
        self.workspace = workspace
        self.skills_dir = workspace / "skills"
        self._cache: dict[str, str] = {}
    
    def get_all_skills(self) -> list[str]:
        """获取所有可用技能"""
        skills = []
        
        # 内置技能
        if BUILTIN_SKILLS_DIR.exists():
            skills.extend(
                d.name for d in BUILTIN_SKILLS_DIR.iterdir()
                if d.is_dir() and (d / "SKILL.md").exists()
            )
        
        # 工作空间技能
        if self.skills_dir.exists():
            skills.extend(
                d.name for d in self.skills_dir.iterdir()
                if d.is_dir() and (d / "SKILL.md").exists()
            )
        
        return skills
    
    def load_skill(self, skill_name: str) -> str | None:
        """加载指定技能的内容"""
        # 先检查缓存
        if skill_name in self._cache:
            return self._cache[skill_name]
        
        # 尝试从工作空间加载
        skill_file = self.skills_dir / skill_name / "SKILL.md"
        if skill_file.exists():
            content = skill_file.read_text()
            self._cache[skill_name] = content
            return content
        
        # 尝试从内置技能加载
        skill_file = BUILTIN_SKILLS_DIR / skill_name / "SKILL.md"
        if skill_file.exists():
            content = skill_file.read_text()
            self._cache[skill_name] = content
            return content
        
        return None
Always Skills
def get_always_skills(self) -> list[str]:
    """获取始终激活的技能"""
    always_file = self.skills_dir / "always.md"
    if always_file.exists():
        content = always_file.read_text()
        return [line.strip() for line in content.splitlines() if line.strip()]
    return []

always.md 格式:

github
weather
tmux

8.4 内置技能示例

GitHub 技能
# GitHub

## Description
与 GitHub 交互,管理仓库、Issue、PR 等。

## Usage
使用 GitHub CLI (gh) 命令与 GitHub 交互。

## Tools
- exec: 执行 gh 命令
- read_file: 读取仓库文件
- write_file: 创建/编辑文件

## Available Commands
- `gh repo list` - 列出仓库
- `gh issue list` - 列出 Issue
- `gh pr list` - 列出 PR
- `gh issue create` - 创建 Issue
- `gh pr create` - 创建 PR
Weather 技能
# Weather

## Description
查询天气信息。

## Usage
使用 curl 请求天气 API。

## Tools
- exec: 执行 curl 命令
- web_fetch: 获取网页内容

## Examples
查询北京天气:
curl "https://wttr.in/Beijing?format=j1"
Tmux 技能
# Tmux

## Description
管理 Tmux 会话和窗口。

## Usage
使用 tmux 命令管理终端会话。

## Tools
- exec: 执行 tmux 命令

## Commands
- `tmux ls` - 列出会话
- `tmux new -s name` - 创建会话
- `tmux attach -t name` - 连接到会话
- `tmux kill-session -t name` - 删除会话

8.5 创建自定义技能

创建技能目录
mkdir -p ~/.nanobot/workspace/skills/my_skill
编写 SKILL.md
# My Custom Skill

## Description
这是一个自定义技能,用于...

## Usage
描述如何使用这个技能。

## Tools
这个技能可能用到的工具:
- exec: 执行命令
- read_file: 读取文件

## Examples

### 示例1
描述...

执行的命令或操作


### 示例2
...
配置 Always Skills

如果希望技能始终激活,创建 ~/.nanobot/workspace/skills/always.md

my_skill
another_skill

8.6 技能系统设计理念

为什么用 Markdown?
  1. 易于编写 - 不需要编程知识
  2. 易于分享 - 可以直接复制粘贴
  3. 易于版本控制 - 纯文本文件
为什么需要读取文件?
  1. 灵活性 - 技能可能很复杂,直接传给 LLM 太长
  2. 按需加载 - 只在需要时加载
  3. 缓存 - 加载过的技能会被缓存

第九章:配置详解

本章详细介绍 nanobot 的所有配置选项,包括配置文件的结构、各个模块的配置项、以及多实例配置。

9.1 配置系统概述

配置文件位置
  • 默认位置: ~/.nanobot/config.json
  • 自定义位置: 通过 --config 参数指定
  • 多实例: 每个实例可以有独立的配置文件
配置模型层次
Config (根配置)
├── agents: AgentsConfig
│   └── defaults: AgentDefaults
│       ├── workspace: str
│       ├── model: str
│       ├── provider: str
│       ├── max_tokens: int
│       ├── context_window_tokens: int
│       ├── temperature: float
│       ├── max_tool_iterations: int
│       └── reasoning_effort: str | None
│
├── providers: ProvidersConfig
│   ├── openai: ProviderConfig
│   ├── anthropic: ProviderConfig
│   ├── openrouter: ProviderConfig
│   ├── dashscope: ProviderConfig
│   └── ... (20+ providers)
│
├── channels: ChannelsConfig
│   ├── telegram: dict
│   ├── discord: dict
│   ├── feishu: dict
│   └── ... (12+ channels)
│
├── tools: ToolsConfig
│   ├── web: WebToolsConfig
│   ├── exec: ExecToolConfig
│   ├── restrict_to_workspace: bool
│   └── mcp_servers: dict
│
└── gateway: GatewayConfig
    ├── host: str
    ├── port: int
    └── heartbeat: HeartbeatConfig

9.2 Agent 配置

AgentDefaults
{
  "agents": {
    "defaults": {
      "workspace": "~/.nanobot/workspace",
      "model": "anthropic/claude-opus-4-5",
      "provider": "auto",
      "max_tokens": 8192,
      "context_window_tokens": 65536,
      "temperature": 0.1,
      "max_tool_iterations": 40,
      "reasoning_effort": null
    }
  }
}

配置项说明:

配置项 类型 默认值 说明
workspace string ~/.nanobot/workspace 工作空间目录
model string anthropic/claude-opus-4-5 使用的模型
provider string auto LLM 提供商,auto 自动检测
max_tokens int 8192 响应最大 token 数
context_window_tokens int 65536 上下文窗口大小
temperature float 0.1 采样温度
max_tool_iterations int 40 最大工具调用次数
reasoning_effort string null 思考模式: low/medium/high

9.3 Provider 配置

ProviderConfig 通用字段
{
  "providers": {
    "openai": {
      "apiKey": "sk-...",
      "apiBase": "https://api.openai.com/v1",
      "extraHeaders": {}
    }
  }
}
配置项 类型 说明
apiKey string API 密钥
apiBase string API 基础地址(可选)
extraHeaders dict 自定义请求头(可选)

9.4 Channel 配置

通用配置项

每个通道都支持以下配置:

{
  "channels": {
    "telegram": {
      "enabled": true,
      "allowFrom": ["123456789"],
      "streaming": false
    }
  }
}
配置项 类型 说明
enabled bool 是否启用
allowFrom list 白名单用户 ID
streaming bool 是否启用流式输出

9.5 Tools 配置

Web 工具配置
{
  "tools": {
    "web": {
      "proxy": "http://127.0.0.1:7890",
      "search": {
        "provider": "brave",
        "apiKey": "",
        "baseUrl": "",
        "maxResults": 5
      }
    }
  }
}

search.provider 选项:

  • brave (默认)
  • tavily
  • jina
  • searxng
  • duckduckgo
Exec 工具配置
{
  "tools": {
    "exec": {
      "enable": true,
      "timeout": 60,
      "path_append": ""
    }
  }
}
安全配置
{
  "tools": {
    "restrict_to_workspace": false
  }
}
MCP 配置
{
  "tools": {
    "mcpServers": {
      "filesystem": {
        "command": "npx",
        "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
        "enabledTools": ["*"],
        "toolTimeout": 30
      },
      "remote": {
        "url": "https://example.com/mcp/",
        "headers": {
          "Authorization": "Bearer xxx"
        }
      }
    }
  }
}

9.6 Gateway 配置

基本配置
{
  "gateway": {
    "host": "0.0.0.0",
    "port": 18790
  }
}
Heartbeat 配置
{
  "gateway": {
    "heartbeat": {
      "enabled": true,
      "interval_s": 1800,
      "keep_recent_messages": 8
    }
  }
}
配置项 类型 默认值 说明
enabled bool true 是否启用
interval_s int 1800 检查间隔(秒)
keep_recent_messages int 8 保留的最近消息数

9.7 多实例配置

创建多实例
# 实例 A - Telegram
nanobot onboard --config ~/.nanobot-telegram/config.json --workspace ~/.nanobot-telegram/workspace

# 实例 B - Discord
nanobot onboard --config ~/.nanobot-discord/config.json --workspace ~/.nanobot-discord/workspace

# 实例 C - 飞书
nanobot onboard --config ~/.nanobot-feishu/config.json --workspace ~/.nanobot-feishu/workspace
启动多实例
# 终端 1
nanobot gateway --config ~/.nanobot-telegram/config.json

# 终端 2
nanobot gateway --config ~/.nanobot-discord/config.json

# 终端 3
nanobot gateway --config ~/.nanobot-feishu/config.json --port 18791

9.8 配置优先级

优先级顺序
  1. 命令行参数 (–config, --workspace)
  2. 配置文件 (~/.nanobot/config.json)
  3. 默认值 (Pydantic 模型定义)

第十章:命令行使用详解

本章详细介绍 nanobot 的所有命令行工具,包括快速开始、交互模式、Gateway 启动、以及各种实用命令。

10.1 命令概览

命令 说明
nanobot onboard 初始化配置和工作空间
nanobot onboard --wizard 交互式初始化向导
nanobot agent 启动交互式 CLI 对话
nanobot agent -m "..." 发送单条消息
nanobot gateway 启动 Gateway 服务
nanobot status 查看状态信息
nanobot provider login OAuth 登录
nanobot channels login 通道认证登录
nanobot channels status 查看通道状态

10.2 初始化 (onboard)

基本用法
nanobot onboard

这会创建默认配置:

  • 配置: ~/.nanobot/config.json
  • 工作空间: ~/.nanobot/workspace/
交互式向导
nanobot onboard --wizard

向导会引导你:

  1. 选择要启用的通道
  2. 配置 API Key
  3. 选择默认模型
  4. 配置工作空间
指定配置和工作空间
# 为特定实例初始化
nanobot onboard --config ~/.nanobot-telegram/config.json --workspace ~/.nanobot-telegram/workspace

# 刷新现有配置
nanobot onboard -c ~/.nanobot-telegram/config.json -w ~/.nanobot-telegram/workspace

10.3 交互式对话 (agent)

启动交互模式
nanobot agent

这会启动一个交互式命令行界面,你可以:

  • 输入消息与 AI 对话
  • 使用上下箭头查看历史
  • 支持命令补全

退出方式:

  • exit
  • quit
  • /exit
  • /quit
  • :q
  • Ctrl+D
发送单条消息
# 基本用法
nanobot agent -m "你好"

# 查看运行时日志
nanobot agent -m "你好" --logs

# 纯文本输出(无 Markdown 格式)
nanobot agent -m "你好" --no-markdown
指定工作空间和配置
# 使用特定工作空间
nanobot agent -w ~/.nanobot-telegram/workspace -m "你好"

# 使用特定配置
nanobot agent -c ~/.nanobot-telegram/config.json -m "你好"

# 同时指定两者
nanobot agent -c ~/.nanobot-telegram/config.json -w ~/.nanobot-telegram/workspace -m "你好"

10.4 Gateway 服务 (gateway)

启动 Gateway
nanobot gateway

Gateway 会:

  1. 加载配置
  2. 初始化所有启用的通道
  3. 启动消息监听
  4. 处理 AI 对话请求
指定配置和端口
# 使用特定配置
nanobot gateway --config ~/.nanobot-telegram/config.json

# 指定端口
nanobot gateway --port 18791

# 同时指定
nanobot gateway --config ~/.nanobot-telegram/config.json --port 18790
后台运行
# Linux/macOS - 使用 nohup
nohup nanobot gateway > nanobot.log 2>&1 &

# 使用 systemd
systemctl --user start nanobot-gateway

# 使用 Docker
docker compose up -d nanobot-gateway

10.5 状态查看 (status)

查看整体状态
nanobot status

输出示例:

nanobot v0.1.4.post5

Provider: openrouter (auto-detected)
Model: anthropic/claude-sonnet-4-20250514
Workspace: ~/.nanobot/workspace

Channels:
  ✓ telegram (enabled, running)

Tools:
  ✓ web_search (brave)
  ✓ web_fetch
  ✓ exec
  ✓ read_file
  ✓ write_file
  ✓ edit_file
  ✓ list_dir
  ✓ send_message
  ✓ spawn
  ✓ cron

10.6 Provider 登录

OpenAI Codex OAuth
nanobot provider login openai-codex
GitHub Copilot OAuth
nanobot provider login github-copilot

10.7 通道登录

WhatsApp 登录
# 首次登录
nanobot channels login whatsapp

# 强制重新登录
nanobot channels login whatsapp --force
查看通道状态
nanobot channels status

10.8 常用场景

快速开始流程
# 1. 安装
pip install nanobot-ai

# 2. 初始化
nanobot onboard

# 3. 配置 API Key
vim ~/.nanobot/config.json

# 4. 启动对话
nanobot agent
Telegram Bot 完整配置
# 1. 从 BotFather 获取 Token

# 2. 初始化
nanobot onboard

# 3. 编辑配置
vim ~/.nanobot/config.json
# 添加:
# {
#   "channels": {
#     "telegram": {
#       "enabled": true,
#       "token": "YOUR_TOKEN",
#       "allowFrom": ["YOUR_USER_ID"]
#     }
#   }
# }

# 4. 启动 Gateway
nanobot gateway
Docker 部署
# 首次初始化
docker compose run --rm nanobot-cli onboard

# 编辑配置
vim ~/.nanobot/config.json

# 启动 Gateway
docker compose up -d nanobot-gateway

# 运行 CLI
docker compose run --rm nanobot-cli agent -m "Hello!"

# 查看日志
docker compose logs -f nanobot-gateway

# 停止
docker compose down

第十一章:开发指南

本章介绍如何为 nanobot 贡献代码,包括项目结构、编码规范、如何添加新功能、以及提交 PR 的流程。

11.1 项目结构

目录概览
nanobot/
├── nanobot/                    # 主代码目录
│   ├── agent/                  # Agent 核心
│   │   ├── loop.py             # Agent 循环
│   │   ├── context.py          # 上下文构建
│   │   ├── memory.py           # 记忆系统
│   │   ├── skills.py           # 技能加载
│   │   ├── subagent.py         # 子代理管理
│   │   └── tools/              # 工具实现
│   ├── channels/               # 通道实现
│   │   ├── base.py             # 基类
│   │   ├── manager.py          # 管理器
│   │   ├── registry.py         # 注册机制
│   │   ├── telegram.py
│   │   ├── discord.py
│   │   ├── feishu.py
│   │   └── ...
│   ├── providers/              # LLM 提供商
│   │   ├── base.py             # 基类
│   │   ├── registry.py         # 注册机制
│   │   ├── litellm_provider.py # LiteLLM 代理
│   │   └── ...
│   ├── bus/                    # 消息总线
│   ├── session/                # 会话管理
│   ├── config/                 # 配置系统
│   ├── cli/                    # 命令行
│   ├── cron/                   # 定时任务
│   ├── heartbeat/              # 心跳服务
│   ├── skills/                 # 内置技能
│   └── utils/                  # 工具函数
│
├── docs/                       # 文档
├── tests/                      # 测试
├── pyproject.toml              # 项目配置
└── Dockerfile                  # Docker 配置

11.2 开发环境设置

克隆项目
git clone https://github.com/HKUDS/nanobot.git
cd nanobot
安装开发依赖
# 安装项目(可编辑模式)
pip install -e .

# 安装开发依赖
pip install -e ".[dev]"

# 或安装所有可选依赖
pip install -e ".[all]"
运行测试
# 运行所有测试
pytest

# 运行特定测试
pytest tests/test_agent.py

# 带覆盖率
pytest --cov=nanobot

11.3 添加新通道

创建通道类

nanobot/channels/ 下创建新文件,例如 mychannel.py

"""My Channel implementation."""

from nanobot.channels.base import BaseChannel
from nanobot.bus.events import OutboundMessage


class MyChannel(BaseChannel):
    name = "mychannel"
    display_name = "My Channel"

    async def start(self) -> None:
        """启动通道,监听消息"""
        pass

    async def stop(self) -> None:
        """停止通道"""
        pass

    async def send(self, msg: OutboundMessage) -> None:
        """发送消息"""
        pass

11.4 添加新 Provider

添加 ProviderSpec

nanobot/providers/registry.py 中添加:

ProviderSpec(
    name="myprovider",
    keywords=("myprovider", "mymodel"),
    env_key="MYPROVIDER_API_KEY",
    display_name="My Provider",
    litellm_prefix="myprovider",
    skip_prefixes=("myprovider/",),
    default_api_base="https://api.myprovider.com/v1"
),
添加配置字段

nanobot/config/schema.pyProvidersConfig 中添加:

class ProvidersConfig(Base):
    ...
    myprovider: ProviderConfig = ProviderConfig()

完成!以下功能会自动工作:

  • 环境变量检测
  • 模型前缀处理
  • nanobot status 显示

11.5 添加新工具

创建工具类

nanobot/agent/tools/ 下创建新文件,例如 mydata.py

"""My custom tool."""

from nanobot.agent.tools.base import BaseTool
from nanobot.session.manager import Session


class MyDataTool(BaseTool):
    name = "my_data"
    description = "获取自定义数据"
    
    parameters = {
        "type": "object",
        "properties": {
            "query": {
                "type": "string",
                "description": "查询内容"
            }
        },
        "required": ["query"]
    }

    async def execute(self, arguments: dict, session: Session) -> str:
        query = arguments.get("query", "")
        result = await self._fetch_data(query)
        return result

11.6 编码规范

代码风格
  • Python: 遵循 PEP 8
  • 类型注解: 使用类型提示
  • 文档字符串: 使用 Google 风格
命名规范
  • 类名: PascalCase
  • 函数/变量: snake_case
  • 常量: UPPER_SNAKE_CASE
  • 私有成员: _leading_underscore
异步编程
# 推荐:使用 async/await
async def fetch_data(url: str) -> str:
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

# 避免:不要在异步函数中使用阻塞调用
# 不好
def read_file(path: str) -> str:
    with open(path) as f:
        return f.read()

# 好
async def read_file(path: str) -> str:
    return await asyncio.to_thread(Path(path).read_text)

11.7 分支策略

分支类型
分支 用途 目标
main 稳定版本 发布 bug 修复
nightly 实验版本 新功能
提交 PR
  1. Fork 项目
  2. 创建功能分支
  3. 开发并测试
  4. 提交 PR 到 mainnightly

11.8 测试

运行测试
# 所有测试
pytest

# 特定文件
pytest tests/test_agent.py

# 特定测试
pytest tests/test_agent.py::test_something

# 带详细输出
pytest -v

# 带覆盖率
pytest --cov=nanobot --cov-report=html
编写测试
import pytest
from nanobot.agent.loop import AgentLoop

@pytest.mark.asyncio
async def test_agent_response():
    """测试 Agent 响应"""
    loop = AgentLoop(...)
    response = await loop.handle_message(...)
    assert response.content == "expected"

11.9 调试技巧

日志调试
from loguru import logger

logger.debug("Debug info: {}", value)
logger.info("Info: {}", value)
logger.warning("Warning: {}", value)
logger.error("Error: {}", value)
本地测试
# 使用本地配置测试
nanobot agent -c /path/to/config.json -m "test message"

# 查看详细日志
nanobot agent -c /path/to/config.json -m "test message" --logs

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐