项目概述
什么是 Nanobot?
Nanobot 是一个轻量级的 AI 代理框架,让你能够轻松构建自己的 AI 助手!
简单来说
想象一下,你可以拥有一个像 ChatGPT 一样的 AI 助手,但它不仅能聊天,还能:
- 📱 在 Telegram、WhatsApp、Discord 等平台上与你对话
- 🔧 执行各种任务(读写文件、搜索网页、运行命令)
- ⏰ 定时提醒你重要事项
- 🧠 记住你们之前的对话内容
核心价值
简单易用
只需几行配置,就能启动你的 AI 助手
多平台支持
支持 10+ 种聊天平台,随时随地使用
可扩展
轻松添加新功能,打造专属助手
成本低
支持多种 AI 模型,选择最适合你的
适合谁使用?
编程新手
想学习 AI 应用开发,从实际项目入手
效率工具爱好者
希望自动化日常任务,提高工作效率
AI 探索者
想深入了解 AI Agent 的工作原理
核心功能
功能清单
Nanobot 包含以下核心功能模块,每个模块都有特定的职责:
这是 Nanobot 的"大脑",负责:
- 理解用户意图:分析用户说的话,理解想要做什么
- 决策执行:决定需要调用哪些工具来完成任务
- 生成回复:将执行结果转化为自然语言回复
💡 例子
用户说:"帮我查一下今天北京的天气"
代理引擎会:理解意图 → 调用天气查询工具 → 返回结果
工具是 AI 的"手",让它能执行实际操作:
读取、写入、搜索文件
运行 Shell 命令
搜索互联网获取信息
主动发送消息给用户
设置提醒和定时执行
连接外部工具服务
支持多种聊天平台,让你在任何地方使用:
让 AI 能够"记住"之前的对话:
- 短期记忆:当前对话的上下文
- 长期记忆:重要信息的持久化存储
- 记忆整合:自动总结和归档历史对话
支持三种定时方式:
🕐 一次性任务
在指定时间执行一次
例如:明天早上 9 点提醒我开会
🔄 周期性任务
每隔一段时间执行
例如:每小时检查一次邮件
📅 Cron 表达式
使用专业定时语法
例如:每天早上 8 点(0 8 * * *)
系统架构
架构概览
下面是 Nanobot 的整体架构图,展示了各个组件之间的关系:
数据流向
当用户发送一条消息时,系统是如何处理的?
接收消息
渠道(如 Telegram)接收到用户消息
消息路由
通过消息总线传递到代理引擎
构建上下文
加载历史对话和记忆信息
AI 处理
调用 LLM 进行理解和决策
执行工具
如果需要,调用相应工具执行任务
返回结果
生成回复并发送给用户
核心模块关系
文件夹结构
项目目录概览
点击文件夹可以展开查看详细说明:
代码解析
核心处理流程
让我们从最重要的 loop.py 开始,理解 AI 代理是如何工作的:
async def process_message(self, message: str, session_key: str) -> str:
"""
处理用户消息的核心方法
这是 AI 代理的"大脑",负责:
1. 构建上下文(加载历史对话)
2. 调用 LLM 获取响应
3. 执行工具调用(如果需要)
4. 返回最终结果
"""
# 第一步:构建上下文
# 把历史对话、记忆信息组合成 LLM 能理解的格式
messages = await self._build_context(session_key)
# 添加用户消息
messages.append({"role": "user", "content": message})
# 第二步:调用 LLM
# 让 AI 理解用户意图并决定如何响应
response = await self.provider.chat(
messages=messages,
tools=self._get_tool_definitions(),
model=self.model
)
# 第三步:处理工具调用
# 如果 AI 决定要使用工具(比如查天气),执行它
while response.has_tool_calls:
# 执行所有工具调用
tool_results = await self._execute_tools(response.tool_calls)
# 把工具结果发回给 AI
messages.append(response.message)
messages.extend(tool_results)
# 让 AI 根据工具结果生成最终回复
response = await self.provider.chat(
messages=messages,
tools=self._get_tool_definitions(),
model=self.model
)
# 第四步:保存对话并返回结果
await self._save_message(session_key, "assistant", response.content)
return response.content
代码解读
就像人需要记忆一样,AI 也需要知道之前的对话内容。这一步把历史消息加载进来。
把用户消息发给 AI 模型(如 GPT-4),让它理解并决定如何响应。
如果 AI 决定使用工具(比如"查天气"),就执行相应的工具并获取结果。
保存对话记录,把 AI 的回复返回给用户。
工具系统解析
看看工具是如何定义和注册的:
class BaseTool:
"""
所有工具的基类
每个工具都需要:
1. name: 工具名称(AI 用这个名字调用工具)
2. description: 工具描述(告诉 AI 这个工具能做什么)
3. parameters: 参数定义(告诉 AI 需要传什么参数)
4. execute: 执行方法(实际干活的代码)
"""
@property
def name(self) -> str:
"""工具名称"""
raise NotImplementedError
@property
def description(self) -> str:
"""工具描述"""
raise NotImplementedError
@property
def parameters(self) -> dict:
"""
参数定义(JSON Schema 格式)
例如:
{
"type": "object",
"properties": {
"file_path": {
"type": "string",
"description": "要读取的文件路径"
}
},
"required": ["file_path"]
}
"""
return {}
async def execute(self, **kwargs) -> str:
"""
执行工具
参数:kwargs - AI 传递的参数
返回:工具执行结果(字符串形式)
"""
raise NotImplementedError
class ReadFileTool(BaseTool):
"""读取文件内容的工具"""
@property
def name(self) -> str:
return "read_file"
@property
def description(self) -> str:
return "读取指定文件的内容"
@property
def parameters(self) -> dict:
return {
"type": "object",
"properties": {
"file_path": {
"type": "string",
"description": "要读取的文件路径"
}
},
"required": ["file_path"]
}
async def execute(self, file_path: str) -> str:
"""执行文件读取"""
try:
# 安全检查:确保路径在工作区内
if not self._is_safe_path(file_path):
return "错误:不能访问工作区外的文件"
# 读取文件内容
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
return f"文件内容:\n{content}"
except Exception as e:
return f"读取失败:{str(e)}"
消息总线解析
消息如何在系统中流转:
class MessageBus:
"""
消息总线:连接各个组件的"邮局"
工作原理:
1. 渠道(如 Telegram)收到用户消息 → 发布到入站队列
2. 代理引擎从入站队列取消息 → 处理 → 发布到出站队列
3. 渠道从出站队列取消息 → 发送给用户
"""
def __init__(self):
# 入站消息队列(用户 → AI)
self._inbound = asyncio.Queue()
# 出站消息队列(AI → 用户)
self._outbound = asyncio.Queue()
async def publish_inbound(self, message: InboundMessage):
"""发布入站消息(用户发给 AI)"""
await self._inbound.put(message)
async def consume_inbound(self) -> InboundMessage:
"""消费入站消息(AI 接收用户消息)"""
return await self._inbound.get()
async def publish_outbound(self, message: OutboundMessage):
"""发布出站消息(AI 发给用户)"""
await self._outbound.put(message)
async def consume_outbound(self) -> OutboundMessage:
"""消费出站消息(渠道发送给用户)"""
return await self._outbound.get()
方法介绍
方法金字塔结构
理解方法的层级关系,从顶层入口到底层基础,层层递进:
方法关系知识图谱
可视化展示方法之间的调用关系,帮助理解系统工作流程:
方法关系模式
调用链(Call Chain)
A → B → C,像多米诺骨牌一样依次调用
循环调用(Loop)
A 调用 B,B 又调用 A,形成循环
配对使用(Pair)
两个方法配合使用,完成完整操作
层级调用(Hierarchy)
上层调用下层,形成金字塔结构
核心方法详解
运行演示
快速开始
安装步骤
安装 Python
确保你的电脑已安装 Python 3.10 或更高版本
python --version
安装 Nanobot
使用 pip 安装
pip install nanobot
初始化配置
运行初始化命令
nanobot onboard
配置 API Key
编辑配置文件,添加你的 API Key
~/.nanobot/config.json
{
"providers": {
"openrouter": {
"api_key": "your-api-key-here"
}
}
}
开始对话
启动交互式对话
nanobot agent
学习路径建议
第一步:理解概念
你已经完成了项目概述和核心功能的学习
第二步:了解架构
你已经了解了系统架构和数据流向
第三步:动手实践
尝试运行项目,体验基本功能
第四步:阅读代码
从 loop.py 开始,深入理解核心逻辑
第五步:定制开发
尝试添加自己的工具或功能
常见问题
A: Nanobot 支持多种 AI 模型:
- 推荐:OpenRouter(支持多种模型,价格透明)
- Anthropic Claude(智能但价格较高)
- DeepSeek(性价比高,中文支持好)
- 本地模型(如 Ollama,免费但需要硬件)
A: 需要实现 BaseChannel 类:
- 在
channels/目录创建新文件 - 继承
BaseChannel类 - 实现
start()和stop()方法 - 在配置文件中添加相应配置
A: 创建工具很简单:
- 在
agent/tools/创建新文件 - 继承
BaseTool类 - 定义 name、description、parameters
- 实现
execute()方法 - 在
__init__.py中注册工具