技术原理核心
技术研究 AI Agent 架构设计
nanobot 的技术架构深度分析,包括核心组件、设计模式和实现原理
整体架构概览
nanobot 采用清晰的分层架构设计,将系统划分为四个核心层次:
graph TB
subgraph "Channels 层"
TG[Telegram]
DC[Discord]
WA[WhatsApp]
SL[Slack]
FS[Feishu]
DT[DingTalk]
EM[Email]
QQ[QQ]
end
subgraph "Gateway 层"
GW[Gateway<br/>消息路由]
end
subgraph "Agent 核心"
AG[Agent Loop<br/>工具调用循环]
MM[Memory<br/>会话记忆]
TK[Tools<br/>内置工具]
end
subgraph "Providers 层"
OR[OpenRouter]
OA[OpenAI]
AN[Anthropic]
DS[DeepSeek]
GM[Gemini]
VL[vLLM/Local]
end
TG --> GW
DC --> GW
WA --> GW
SL --> GW
FS --> GW
DT --> GW
EM --> GW
QQ --> GW
GW --> AG
AG --> MM
AG --> TK
AG --> OR
AG --> OA
AG --> AN
AG --> DS
AG --> GM
AG --> VL
核心代码量分析
nanobot 的核心代码分布(截至 v0.1.4.post3):
| 模块 | 文件 | 主要职责 | 预估行数 |
|---|---|---|---|
| Agent 核心 | nanobot/agent/ | 工具调用循环、消息处理 | ~800 |
| Providers | nanobot/providers/ | LLM API 统一封装 | ~400 |
| Channels | nanobot/channels/ | 多平台消息接入 | ~1500 |
| Memory | nanobot/memory/ | 会话记忆管理 | ~200 |
| Tools | nanobot/tools/ | 内置工具实现 | ~500 |
| Config | nanobot/config/ | 配置解析与验证 | ~300 |
| Utils | nanobot/utils/ | 工具函数 | ~235 |
总计约 3,935 行(可通过 bash core_agent_lines.sh 实时验证)
核心组件详解
1. Provider 注册机制
nanobot 使用 Provider Registry 模式统一管理 LLM 提供商,新增 Provider 仅需两步:
步骤一:在 nanobot/providers/registry.py 添加 ProviderSpec
ProviderSpec(
name="myprovider", # 配置字段名
keywords=("myprovider", "mymodel"), # 模型名关键词自动匹配
env_key="MYPROVIDER_API_KEY", # LiteLLM 环境变量
display_name="My Provider", # 显示名称
litellm_prefix="myprovider", # 自动前缀:model → myprovider/model
skip_prefixes=("myprovider/",), # 避免重复前缀
)
步骤二:在 nanobot/config/schema.py 添加配置字段
class ProvidersConfig(BaseModel):
myprovider: ProviderConfig = ProviderConfig()
这种设计的关键优势:
- 自动模型匹配:根据模型名关键词自动选择 Provider
- 统一 API 调用:通过 LiteLLM 统一不同 Provider 的 API 差异
- 配置驱动:无需硬编码,配置文件即可启用新 Provider
2. Channel 抽象层
每个 Channel 实现统一的接口协议:
class BaseChannel(ABC):
@abstractmethod
async def start(self): ...
@abstractmethod
async def send_message(self, session_id: str, content: str): ...
@abstractmethod
async def handle_message(self, message: Message): ...
WebSocket 长连接 vs Webhook
nanobot 针对不同平台采用最优接入方式:
| 平台 | 连接方式 | 优势 |
|---|---|---|
| Telegram | Webhook / Polling | 灵活部署 |
| Discord | WebSocket | 实时性好 |
| Feishu | WebSocket 长连接 | 无需公网 IP |
| DingTalk | Stream Mode | 企业内网友好 |
| 本地 Bridge + QR | 用户自主控制 |
3. Agent 核心循环
Agent 的核心是一个简洁的工具调用循环:
async def run_agent_loop(self, messages: List[Message]):
while True:
# 1. 调用 LLM
response = await self.provider.chat(messages)
# 2. 检查是否需要工具调用
if not response.tool_calls:
return response.content
# 3. 执行工具
tool_results = await self.execute_tools(response.tool_calls)
# 4. 将结果加入上下文,继续循环
messages.extend(tool_results)
设计亮点:
- 循环终止条件明确:无工具调用时返回
- 工具执行并行化:多个工具可并发执行
- 上下文自动管理:工具结果自动追加到消息历史
4. Memory 系统(重新设计)
v0.1.3.post7 版本对 Memory 系统进行了彻底重构:
旧方案:向量数据库 + RAG(复杂、依赖重)
新方案:两个纯文本文件 + grep
~/.nanobot/
├── memory.jsonl # 长期记忆(追加写入)
└── context.json # 当前会话上下文
这种设计的哲学:
“对于个人助手场景,grep 足够好。RAG 增加了复杂度,但收益有限。”
记忆检索流程:
- 用户消息触发关键词提取
grep在memory.jsonl中搜索相关条目- 匹配的记忆片段注入到当前上下文
5. MCP 集成
nanobot 支持 Model Context Protocol (MCP) 工具扩展:
{
"mcp": {
"servers": {
"brave-search": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-brave-search"],
"env": {
"BRAVE_API_KEY": "your-key"
}
}
}
}
}
MCP 工具被自动发现并注册到 Agent 的工具列表中,与内置工具统一调用。
设计哲学
极简主义原则
nanobot 的设计遵循以下原则:
1. 能不写就不写
每个功能在添加前都要经过严格审视:
- 这是核心功能吗?
- 能否通过更简单的方式实现?
- 是否增加了不必要的抽象?
2. 组合优于继承
避免深层继承链,多用组合和简单函数:
- Channel 使用 ABC 定义接口
- Provider 使用 Registry 模式
- Tools 使用函数式定义
3. 配置优于代码
将可变部分外置到配置文件:
- Provider 配置
- Channel 启用/禁用
- Agent 模型选择
与 OpenClaw 的对比
| 方面 | OpenClaw | nanobot |
|---|---|---|
| 语言 | TypeScript | Python |
| 代码量 | 430,000+ 行 | ~4,000 行 |
| 插件系统 | 完整的插件生态 | MCP 工具 |
| 多 Agent | 支持 | 单 Agent |
| Web UI | 功能完善 | 无 |
| 部署复杂度 | 高 | 低(pip install) |
| 安全审计 | 困难 | 容易 |