nanobot 项目完全指南:从入门到精通
文章目录
这是一份为你精心准备的 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 现有方案的痛点
- 代码过于复杂 - 主流 Agent 框架动辄数万行代码,学习曲线陡峭
- 依赖过多 - 引入大量外部库,增加了维护负担
- 难以定制 - 想要修改某个行为往往牵一发而动全身
- 研究门槛高 - 对于想研究 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 | 企业协作 |
| QR 登录 | 国际常用 | |
| 微信 | HTTP Long Poll | 需要第三方服务 |
| botpy SDK | 仅支持私聊 | |
| 钉钉 | Stream Mode | 企业办公 |
| 企业微信 | WebSocket | 企业内部 |
| Matrix | Matrix 协议 | 去中心化通信 |
| 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 采用清晰的分层架构:
- Channel Layer - 消息入口,对接各种聊天平台
- Message Bus - 消息中枢,解耦各层之间的通信
- Agent Layer - 核心逻辑,处理 AI 对话
- 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 的核心引擎,负责:
- 接收消息
- 构建上下文(历史对话、记忆、技能)
- 调用 LLM
- 执行工具调用
- 返回响应
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 记住跨会话的重要信息。
两层记忆结构:
- MEMORY.md - 长期记忆,存储重要事实和偏好
- 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 添加新通道
只需两步:
- 在
nanobot/channels/下创建新通道类,继承BaseChannel - 在
nanobot/channels/registry.py注册
2.5.2 添加新 Provider
只需两步:
- 在
providers/registry.py添加ProviderSpec - 在
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 也要知道...
这会导致:
- 代码重复 - 每个通道都要写类似的调用逻辑
- 紧耦合 - 通道和 Agent 强绑定
- 难以测试 - 无法独立测试通道或 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:
检测优先级:
- API Key 前缀检测 - 如
sk-or-→ OpenRouter - API Base 关键词检测 - 如 URL 包含
openrouter→ OpenRouter - 模型名关键词检测 - 如模型名包含
gpt→ OpenAI - 默认 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)
触发条件
记忆合并在以下情况触发:
- Token 数量阈值 - 会话消息达到一定数量
- 手动触发 - 用户要求保存记忆
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 记忆系统设计理念
为什么不直接保存所有消息?
- 上下文窗口限制 - LLM 有 token 上限
- 成本考虑 - 更少的 token = 更低的成本
- 噪声过滤 - 摘要保留了重要信息
为什么用两层?
- MEMORY.md - 结构化、可读、用于系统提示词
- HISTORY.md - 完整记录、可搜索、用于回溯
第八章:技能系统详解
本章详细介绍 nanobot 的技能系统(Skills),如何通过技能扩展 AI 的能力,以及如何创建自定义技能。
8.1 技能系统概述
什么是技能?
技能(Skill)是 nanobot 的一种扩展机制,允许你为 AI 添加额外的能力。每个技能本质上是一个 Markdown 文件,描述了:
- 技能的功能
- 如何使用
- 任何依赖或配置
技能与工具的区别
| 特性 | 工具 (Tool) | 技能 (Skill) |
|---|---|---|
| 调用方式 | LLM 直接调用 | LLM 读取文件后使用 |
| 复杂度 | 简单操作 | 复杂流程 |
| 实现方式 | Python 代码 | Markdown 描述 |
| 动态性 | 运行时注册 | 按需加载 |
技能类型
- Always Skills - 始终激活的技能
- 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?
- 易于编写 - 不需要编程知识
- 易于分享 - 可以直接复制粘贴
- 易于版本控制 - 纯文本文件
为什么需要读取文件?
- 灵活性 - 技能可能很复杂,直接传给 LLM 太长
- 按需加载 - 只在需要时加载
- 缓存 - 加载过的技能会被缓存
第九章:配置详解
本章详细介绍 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(默认)tavilyjinasearxngduckduckgo
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 配置优先级
优先级顺序
- 命令行参数 (–config, --workspace)
- 配置文件 (~/.nanobot/config.json)
- 默认值 (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
向导会引导你:
- 选择要启用的通道
- 配置 API Key
- 选择默认模型
- 配置工作空间
指定配置和工作空间
# 为特定实例初始化
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 对话
- 使用上下箭头查看历史
- 支持命令补全
退出方式:
exitquit/exit/quit:qCtrl+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 会:
- 加载配置
- 初始化所有启用的通道
- 启动消息监听
- 处理 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.py 的 ProvidersConfig 中添加:
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
- Fork 项目
- 创建功能分支
- 开发并测试
- 提交 PR 到
main或nightly
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
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)