nanobot 项目完全指南:从入门到精通

该文章已生成可运行项目,

AI 时代程序员必备技能

Codex、Claude Code、Cursor、Hermes Agent、OpenClaw等工程化实战专栏 ,讲透 AI 如何接管脏活累活

文章目录

这是一份为你精心准备的 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 支持连接多种聊天平台:

平台连接方式特点
TelegramBot API推荐首选,稳定可靠
DiscordBot API适合开发者社区
飞书WebSocket无需公网 IP
SlackSocket Mode企业协作
WhatsAppQR 登录国际常用
微信HTTP Long Poll需要第三方服务
QQbotpy SDK仅支持私聊
钉钉Stream Mode企业办公
企业微信WebSocket企业内部
MatrixMatrix 协议去中心化通信
EmailIMAP/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.mdAgent 的身份定义和行为规范
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配置免费
BraveapiKey
TavilyapiKey
JinaapiKey是 (10M tokens)
SearXNGbaseUrl是 (自托管)
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 传输模式
模式配置用途
Stdiocommand + args本地进程
HTTPurl + headers远程服务
SSEurl + headersServer-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
    }
  }
}

配置项说明:

配置项类型默认值说明
workspacestring~/.nanobot/workspace工作空间目录
modelstringanthropic/claude-opus-4-5使用的模型
providerstringautoLLM 提供商,auto 自动检测
max_tokensint8192响应最大 token 数
context_window_tokensint65536上下文窗口大小
temperaturefloat0.1采样温度
max_tool_iterationsint40最大工具调用次数
reasoning_effortstringnull思考模式: low/medium/high

9.3 Provider 配置

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

9.4 Channel 配置

通用配置项

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

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

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
    }
  }
}
配置项类型默认值说明
enabledbooltrue是否启用
interval_sint1800检查间隔(秒)
keep_recent_messagesint8保留的最近消息数

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 loginOAuth 登录
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

本文章已经生成可运行项目

AI 时代程序员必备技能

Codex、Claude Code、Cursor、Hermes Agent、OpenClaw等工程化实战专栏 ,讲透 AI 如何接管脏活累活

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ToTensor

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值