nanobot核心架构解析:4000行代码如何实现完整AI代理功能
nanobot核心架构解析:4000行代码如何实现完整AI代理功能
nanobot核心架构解析:4000行代码如何实现完整AI代理功能
引言
在上一篇文章中,我们介绍了 nanobot 的基本概念和快速入门。本文将深入探讨 nanobot 的核心架构设计,解析这个仅用约4000行核心代码就实现了完整AI代理功能的超轻量级系统是如何做到的。
架构概览
nanobot 采用了一个简洁而高效的分层架构:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
nanobot/
├── agent/ # 🧠 核心代理逻辑
│ ├── loop.py # 代理循环 (LLM ↔ 工具执行)
│ ├── context.py # 提示构建器
│ ├── memory.py # 持久化记忆
│ ├── skills.py # 技能加载器
│ ├── subagent.py # 后台任务执行
│ └── tools/ # 内置工具 (包括 spawn)
├── skills/ # 🎯 捆绑技能 (github, weather, tmux...)
├── channels/ # 📱 聊天渠道集成
├── bus/ # 🚌 消息路由
├── cron/ # ⏰ 定时任务
├── heartbeat/ # 💓 主动唤醒
├── providers/ # 🤖 LLM提供商 (OpenRouter, etc.)
├── session/ # 💬 对话会话
├── config/ # ⚙️ 配置管理
└── cli/ # 🖥️ 命令行接口
核心组件详解
1. Agent Loop (agent/loop.py)
这是 nanobot 的心脏,负责协调 LLM 与工具执行的整个流程:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 简化的代理循环逻辑
async def agent_loop(session_id: str, message: str):
# 1. 构建上下文
context = build_context(session_id, message)
# 2. 调用LLM
response = await call_llm(context)
# 3. 解析工具调用
tool_calls = parse_tool_calls(response)
# 4. 执行工具
for tool_call in tool_calls:
result = await execute_tool(tool_call)
# 5. 将结果反馈给LLM
context.add_tool_result(result)
response = await call_llm(context)
# 6. 返回最终响应
return response
关键设计点:
- 流式处理:支持工具调用的流式执行
- 上下文管理:智能的上下文构建和维护
- 错误处理:完善的异常处理和重试机制
2. Provider Registry (providers/registry.py)
nanobot 的提供商注册表是其灵活性的关键:
1
2
3
4
5
6
7
8
9
# ProviderSpec 定义
ProviderSpec(
name="openrouter", # 配置字段名
keywords=("openrouter",), # 模型名关键词用于自动匹配
env_key="OPENROUTER_API_KEY", # LiteLLM的环境变量
display_name="OpenRouter", # 在状态显示中的名称
litellm_prefix="openrouter", # 自动前缀:模型 → openrouter/model
skip_prefixes=("openrouter/",), # 不要重复前缀
)
这种设计使得添加新提供商变得极其简单,只需要两步:
- 在
PROVIDERS列表中添加ProviderSpec - 在
ProvidersConfig中添加配置字段
3. Channel Integration (channels/)
nanobot 支持多种聊天平台,每个平台都有专门的集成模块:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 以Telegram为例
class TelegramChannel:
def __init__(self, config: TelegramConfig):
self.bot = Bot(token=config.token)
self.allow_from = config.allow_from
async def start(self):
# 启动Telegram机器人
await self.bot.start()
async def handle_message(self, message: Message):
# 处理接收到的消息
if self._is_allowed(message.from_user.id):
await self.agent.process(message.text)
4. Memory System (agent/memory.py)
nanobot 的记忆系统设计简洁但功能完整:
1
2
3
4
5
6
7
8
9
10
11
12
13
class MemoryManager:
def __init__(self, workspace: str):
self.memory_file = Path(workspace) / "MEMORY.md"
self.daily_dir = Path(workspace) / "memory"
def get_long_term_memory(self) -> str:
# 读取长期记忆
return self.memory_file.read_text() if self.memory_file.exists() else ""
def save_daily_log(self, date: str, content: str):
# 保存每日日志
daily_file = self.daily_dir / f"{date}.md"
daily_file.write_text(content)
性能优化策略
1. 代码精简
- 避免过度抽象和复杂的继承层次
- 使用类型提示提高可读性而不增加运行时开销
- 最小化依赖项
2. 异步设计
- 全面使用 asyncio 进行异步处理
- 非阻塞的 I/O 操作
- 并发处理多个请求
3. 缓存机制
- LLM 响应缓存
- 配置缓存
- 会话状态缓存
与 OpenClaw 的架构对比
| 特性 | nanobot | OpenClaw |
|---|---|---|
| 代码复杂度 | ~4000行核心代码 | 数万行代码 |
| 架构风格 | 简单分层 | 复杂微服务 |
| 通信协议 | 基础WebSocket | 类型化WebSocket协议 |
| 安全模型 | 基础访问控制 | 企业级安全体系 |
| 部署复杂度 | pip install 即可 | 需要完整安装流程 |
总结
nanobot 通过精心的设计和严格的代码约束,在保持极简的同时实现了完整的AI代理功能。其核心思想是”少即是多”——通过减少不必要的复杂性,提高系统的可维护性和可理解性。
在下一篇文章中,我们将深入探讨 nanobot 的模块设计和关键代码实现细节。
本文由作者按照 CC BY 4.0 进行授权