告别臃肿:nanobot,一个更轻、更纯粹的 AI Agent 的实践和原理解析
告别臃肿:nanobot,一个更轻、更纯粹的 AI Agent 的实践和原理解析
本地clawbot功能虽然强大,但整体较为复杂,这边香港大学开源了nanobot,仅4k多行,实现了clawbot的核心功能核心功能,相对于clawbot有代码少,易扩展的优点,而且还支持本地的vllm模型,能充分使用本地的模型节省成本,这边整理一下我的使用体验和代码具体原理分析。
实践:
首先使用
nanobot onboard
初始化配置文件后,在用户目录的.nanobot 下回有个config配置文件
##agent配置 包含使用模型,记忆窗口大小,最大工具调用次数等
"agents": {
"defaults": {
"workspace": "~/.nanobot/workspace",
"model": "cyankiwi/Qwen3-VL-8B-Instruct-AWQ-4bit",
"maxTokens": 8192,
"temperature": 0.7,
"maxToolIterations": 20,
"memoryWindow": 1
}
},
我的场景主要想bot能帮我批量搜索总结信息 这边bot 原有的是使用,这边接入了免费的搜索工具ddgstool,
感兴趣可以看这个 https://github.com/nightli110/nanobot_prove库
"tools": {
"web": {
"search": {
"provider":"duckduckgo",
"max_results":10
}
},
nanobot 有两种方式gateway和agent, 这边主要介绍agent方式, agent方式符合我使用的场景
agent方式,通过
nanobot agent --help
可以看到一些options选项

这边bot会以markdown的方式,保存在workspace中
通过添加 —no-markdown 和–logs 可以打印
这边以查询以chatdev的论文查询chatdev对应github项目库为例
先通过 启动agent对话模式nanobot agent --no-markdown -logs
通过简单对话模型 调用websearch搜索,搜索到了对应的github项目地址,并且按我需要的格式返回搁我了,这个没有建立复杂的workflow
这边我使用模型本地vllm部署的cyankiwi/Qwen3-VL-8B-Instruct-AWQ-4bit, 由于bot会调用工具,在部署vllm时需要添加–enable-auto-tool-choice –tool-call-parser hermes,让模型能动态决定何时使用工具
可以用下面启动
python -m vllm.entrypoints.openai.api_server --model cyankiwi/Qwen3-VL-8B-Instruct-AWQ-4bit --gpu-memory-utilization 0.85 --max-model-len 32384 --dtype half --host 0.0.0.0 --port 8000 --enable-auto-tool-choice --tool-call-parser hermes
下面来看看整个项目的结构,流程以及一些核心模块
2. 项目结构
nanobot/
├── nanobot/ # 核心 Python 包
│ ├── cli/ # 命令行接口
│ │ └── commands.py # CLI 命令实现
│ ├── agent/ # 代理核心
│ │ ├── loop.py # 主循环
│ │ ├── context.py # 上下文构建
│ │ ├── subagent.py # 子代理管理
│ │ ├── memory.py # 记忆管理
│ │ ├── skills.py # 技能加载
│ │ ├── session.py # 会话管理
│ │ └── tools/ # 工具实现
│ │ ├── base.py # 工具基类
│ │ ├── registry.py # 工具注册表
│ │ ├── filesystem.py
│ │ ├── shell.py
│ │ ├── web.py
│ │ ├── message.py
│ │ ├── spawn.py
│ │ └── cron.py
│ ├── bus/ # 消息总线
│ │ └── queue.py # 异步消息队列
│ ├── channels/ # 聊天渠道
│ │ ├── manager.py # 渠道管理器
│ │ ├── whatsapp.py
│ │ ├── telegram.py
│ │ ├── feishu.py
│ │ ├── dingtalk.py
│ │ ├── discord.py
│ │ ├── email.py
│ │ ├── slack.py
│ │ ├── qq.py
│ │ └── mochat.py
│ ├── config/ # 配置系统
│ │ ├── schema.py # Pydantic 配置模型
│ │ └── loader.py # 配置加载
│ ├── providers/ # LLM 提供者
│ │ ├── base.py # 提供者基类
│ │ ├── litellm_provider.py
│ │ └── registry.py
│ ├── cron/ # 定时任务
│ │ └── service.py
│ ├── heartbeat/ # 心跳服务
│ ├── session/ # 会话管理
│ │ └── manager.py
│ └── skills/ # 内置技能
│ ├── cron/
│ ├── github/
│ ├── memory/
│ ├── skill-creator/
│ ├── summarize/
│ ├── tmux/
│ └── weather/
├── bridge/ # Node.js 桥接服务
├── tests/ # 测试
├── doc/ # 文档
├── workspace/ # 默认工作区模板
├── case/ # 使用案例
├── pyproject.toml # 项目配置
└── README.md
3. 主流程架构
3.1 系统架构图
┌─────────────────────────────────────────────────────────────────┐
│ CLI / Channels │
│ (WhatsApp, Telegram, Discord, Email, Feishu, DingTalk, Slack) │
└────────────┬────────────────────────────────────────────────────┘
│
┌────────▼────────┐
│ MessageBus │ (Inbound/Outbound queues)
└────────┬────────┘
│
┌────────▼──────────┐
│ AgentLoop │ (Core processing engine)
│ - ContextBuilder │ (System prompt + messages)
│ - SessionManager │ (Conversation history)
│ - ToolRegistry │ (All available tools)
│ - SubagentManager│ (Background task execution)
└────────┬──────────┘
│
┌────────▼──────────┐
│ LLM Provider │ (LiteLLM wrapper)
│ (Claude, GPT-4, │ supported)
│ DeepSeek, etc.) │
└────────┬──────────┘
│
┌────────▼──────────┐
│ Tool Execution │ (Read, Write, Exec, Search, etc.)
└────────────────────┘
3.2 消息处理流程
用户发送消息
│
▼
[聊天渠道] ──解析消息──▶ Message {
channel: "telegram",
chat_id: "123456",
content: "你好",
...
}
│
▼
[MessageBus.inbound.put(message)]
│
▼
[AgentLoop.run()] ◀────轮询获取消息
│
▼
[AgentLoop._process_message(message)]
│
├─▶ 会话管理
│ SessionManager.get_or_create(
│ channel, chat_id
│ )
│
├─▶ 命令处理 (如 /reset)
│
├─▶ 记忆整合 (如需要)
│ MemoryStore.consolidate()
│
├─▶ 构建上下文
│ ContextBuilder.build(
│ system_prompt, # 系统提示
│ messages, # 历史消息
│ tools # 可用工具
│ )
│
├─▶ 调用 LLM
│ LLMProvider.call(
│ messages,
│ tools
│ )
│
├─▶ 处理响应
│ ├─ 普通消息 ──▶ 直接返回
│ └─ 工具调用 ──▶ 执行工具
│ │
│ ▼
│ [Tool.execute()]
│ │
│ ▼
│ 继续调用 LLM (带工具结果)
│ (循环直到无新工具调用)
│
└─▶ 发送响应
MessageBus.outbound.put(response)
│
▼
[聊天渠道] ──▶ 用户
3.3 上下文构建流程
ContextBuilder.build()
│
├─▶ 构建系统提示
│ build_system_prompt()
│ │
│ ├─▶ 核心身份
│ │ "You are an AI assistant..."
│ │ "Time: 2025-01-20 10:30:00"
│ │ "Workspace: /path/to/workspace"
│ │
│ ├─▶ 引导文件 (如存在)
│ │ AGENTS.md ──读取──▶ 代理指令
│ │ SOUL.md ────读取──▶ 个性定义
│ │ USER.md ────读取──▶ 用户信息
│ │ TOOLS.md ───读取──▶ 工具说明
│ │ IDENTITY.md ──读取──▶ 身份定义
│ │
│ ├─▶ 内存上下文 (如存在)
│ │ MEMORY.md ──读取──▶ 长期记忆
│ │
│ └─▶ 技能信息
│ 列出所有可用技能
│
├─▶ 构建消息列表
│ build_messages()
│ │
│ ├─▶ 历史消息
│ │ 从 Session 加载历史 (限制 memory_window)
│ │
│ ├─▶ 当前用户消息
│ │ 处理文本 + 媒体附件 (图片等)
│ │
│ └─▶ 工具结果 (如有)
│ 添加工具执行结果到消息列表
│
└─▶ 构建工具定义
build_tools()
│
└─▶ 从 ToolRegistry 获取所有工具定义
转换为 OpenAI 函数调用格式
4. 核心类详解
4.1 AgentLoop
文件: nanobot/agent/loop.py
职责: 核心处理引擎,负责消息处理、上下文构建、LLM 调用、工具执行。这个时主要关注方法
主要方法:
- _run_agent_loop,是Agent 的核心迭代循环,其是 ReAct(Reasoning + Acting) 模式的简化版本:LLM 可以交替进行推理(生成内容)和行动(调用工具),直到完成任务或达到最大迭代次数。
核心流程:开始 │ ▼ ┌─────────────────┐ │ 调用 LLM │◄─────────────────┐ │ (带工具定义) │ │ └────────┬────────┘ │ │ │ ▼ │ ┌─────────┐ │ │有工具调用?│ │ └────┬────┘ │ 是 / \ 否 │ / \ │ ▼ ▼ │ ┌─────────┐ ┌──────────┐ │ │执行工具 │ │返回最终 │ │ │并添加结果│ │结果 │ │ └────┬────┘ └──────────┘ │ │ │ └──────────────────────────────┘
关键设计:
┌──────────┬──────────────────────────────────────────────────────────────────────┐
│ 步骤 │ 说明 │
├──────────┼──────────────────────────────────────────────────────────────────────┤
│ 迭代控制 │ 最大迭代次数由 max_iterations 控制(默认 20),防止无限循环 │
├──────────┼──────────────────────────────────────────────────────────────────────┤
│ 工具调用 │ LLM 可以同时请求多个工具调用,按顺序执行 │
├──────────┼──────────────────────────────────────────────────────────────────────┤
│ 消息历史 │ 每次工具调用结果都会添加到消息上下文,供后续迭代使用 │
├──────────┼──────────────────────────────────────────────────────────────────────┤
│ 反思提示 │ 工具执行后添加 "Reflect on the results..." 提示,引导 LLM 决定下一步 │
├──────────┼──────────────────────────────────────────────────────────────────────┤
│ 工具记录 │ 所有使用的工具名称被记录到 tools_used 列表,用于后续保存到会话 │
└──────────┴──────────────────────────────────────────────────────────────────────┘
- _consolidate_memory 是记忆整合的核心方法,负责将旧对话归档到 HISTORY.md 并更新 MEMORY.md,同时实现了增量式记忆管理:只处理新增的旧消息,避免重复处理已归档的内容。。
主要流程
触发条件开始 │ ▼ ┌─────────────────┐ 是 ┌─────────────────────────┐ │ archive_all? │───────────►│ 处理所有消息 │ │ (来自 /new 命令)│ │ keep_count = 0 │ └─────────────────┘ │ old_messages = all │ │ 否 └─────────────────────────┘ ▼ │ ┌─────────────────┐ │ │ 检查是否需要整合 │ │ │ │◄───────────┘ │ messages > │ │ memory_window/2?│ └─────────────────┘ │ 否 ▼ 返回 (无需整合) 是 │ ▼ │ ┌─────────────────┐ │ │ 取中间部分消息 │ │ │ last_consolidated │ │ │ 到 -keep_count │ │ └─────────────────┘ │ │ └──────────────────┘ ▼ ┌─────────────────┐ │ 格式化对话文本 │ │ [时间] 角色: 内容│ │ + tools_used │ └─────────────────┘ ▼ ┌─────────────────┐ │ 构建 LLM Prompt │ │ 要求返回 JSON: │ │ - history_entry │ │ - memory_update │ └─────────────────┘ ▼ ┌─────────────────┐ │ 调用 LLM 处理 │ └─────────────────┘ ▼ ┌─────────────────┐ │ 解析 JSON 响应 │ │ 提取 entry & │ │ update │ └─────────────────┘ ▼ ┌─────────────────┐ │ 写入文件 │ │ - append_history│ │ - write_long_term│ └─────────────────┘ ▼ ┌─────────────────┐ │ 更新标记 │ │ last_consolidated│ │ = 新位置 │ └─────────────────┘ ▼ 结束 - 消息数超过 memory_window:在 _process_message 中检查,异步触发
- /new 命令:用户主动触发,归档所有消息并重置会话
压缩的promt:You are a memory consolidation agent. Process this conversation and return a JSON object with exactly two keys: 1. "history_entry": A paragraph (2-5 sentences) summarizing the key events/decisions/topics. Start with a timestamp like [YYYY-MM-DD HH:MM]. Include enough detail to be useful when found by grep search later. 2. "memory_update": The updated long-term memory content. Add any new facts: user location, preferences, personal info, habits, project context, technical decisions, tools/services used. If nothing new, return the existing content unchanged. ## Current Long-term Memory {current_memory or "(empty)"} ## Conversation to Process {conversation} Respond with ONLY valid JSON, no markdown fences.您是记忆整合代理。请处理此对话并返回一个包含两个键的 JSON 对象: 1. "history_entry":一段总结关键事件/决策/主题的段落(2-5 句话)。以时间戳开头,例如 [YYYY-MM-DD HH:MM]。包含足够的细节,以便稍后通过 grep 搜索找到。 2. "memory_update":更新后的长期记忆内容。添加任何新信息:用户位置、偏好、个人信息、习惯、项目背景、技术决策、使用的工具/服务。如果没有新内容,则返回现有内容,保持不变。 ## 当前长期记忆 {current_memory 或 "(empty)"} ## 待处理的对话 {conversation} 请仅返回有效的 JSON 格式,不要使用 Markdown 代码块。
其他方法:
| 方法 | 说明 |
|---|---|
run() |
启动主循环,持续消费消息总线中的消息 |
_process_message() |
处理单个消息,包括会话管理、命令处理、内存整合 |
_process_system_message() |
处理系统消息(如子代理完成通知) |
process_direct() |
直接处理消息(用于 CLI 和 cron 任务) |
工具注册 (_register_default_tools()):
- 文件系统工具:
ReadFileTool,WriteFileTool,EditFileTool,ListDirTool - Shell 工具:
ExecTool - 网络工具:
WebSearchTool,WebFetchTool - 消息工具:
MessageTool - 子代理工具:
SpawnTool - 定时任务工具:
CronTool
4.2 ContextBuilder
文件: nanobot/agent/context.py
职责: 构建 LLM 的完整上下文,包括系统提示、历史消息、工具定义。
核心流程:
┌─────────────────────────────────────────────────────────┐
│ build_system_prompt │
└─────────────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────┐
│ _get_identity() │
│ - 核心身份 (nanobot 🐈) │
│ - 当前时间/时区 │
│ - 运行时信息 (OS, Python) │
│ - 工作区路径 │
└────────────────┬───────────────┘
│
▼
┌────────────────────────────────┐
│ _load_bootstrap_files() │
│ 按顺序读取: │
│ 1. AGENTS.md │
│ 2. SOUL.md │
│ 3. USER.md │
│ 4. TOOLS.md │
│ 5. IDENTITY.md │
└────────────────┬───────────────┘
│
▼
┌────────────────────────────────┐
│ memory.get_memory_context() │
│ 长期记忆内容 (MEMORY.md) │
└────────────────┬───────────────┘
│
▼
┌────────────────────────────────┐
│ 技能加载 (渐进式) │
│ ├─ Always Skills: 完整内容 │
│ │ (始终加载的技能) │
│ └─ Available Skills: 摘要列表 │
│ (需要时主动读取) │
└────────────────────────────────┘
│
▼
┌────────────────────────┐
│ 用 "---" 连接各部分 │
│ 返回完整 system prompt │
└────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ build_messages │
│ ┌─────────────────────────────┐ │
│ │ 1. system prompt │ │
│ │ (+ channel/chat_id 信息) │ │
│ └─────────────────────────────┘ │
│ ┌─────────────────────────────┐ │
│ │ 2. history (历史消息) │ │
│ └─────────────────────────────┘ │
│ ┌─────────────────────────────┐ │
│ │ 3. current message │ │
│ │ (+ 可选图片媒体) │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
│
▼
┌────────────────────────┐
│ 返回 messages 列表 │
│ 用于 LLM API 调用 │
└────────────────────────┘
主要方法:
1.build_system_prompt(),构建完整的系统提示,包含以下部分(按顺序):
┌─────────────────┬───────────────────────────────┬────────────────────────────────────────────────────┐
│ 部分 │ 来源 │ 说明 │
├─────────────────┼───────────────────────────────┼────────────────────────────────────────────────────┤
│ Identity │ _get_identity() │ 核心身份定义,包含时间、运行时、工作区路径 │
├─────────────────┼───────────────────────────────┼────────────────────────────────────────────────────┤
│ Bootstrap Files │ workspace/*.md │ AGENTS.md, SOUL.md, USER.md, TOOLS.md, IDENTITY.md │
├─────────────────┼───────────────────────────────┼────────────────────────────────────────────────────┤
│ Memory Context │ memory.get_memory_context() │ 长期记忆内容 │
├─────────────────┼───────────────────────────────┼────────────────────────────────────────────────────┤
│ Always Skills │ skills.get_always_skills() │ 始终加载的技能 │
├─────────────────┼───────────────────────────────┼────────────────────────────────────────────────────┤
│ Skills Summary │ skills.build_skills_summary() │ 可用技能列表(agent 需要主动读取) │
└─────────────────┴───────────────────────────────┴────────────────────────────────────────────────────┘
- build_messages() - 构建完整消息列表
请求大模型的消息主要由:系统提示+历史消息+当前用户消息组成
其中用户消息中的图片信息,主要由 _build_user_content方法处理:
- 将图片文件转为 base64 编码
- 返回 OpenAI 格式的 image_url 消息块
引导文件 (按优先级排序):
AGENTS.md- 代理指令SOUL.md- 个性定义USER.md- 用户信息TOOLS.md- 工具说明IDENTITY.md- 身份定义
4.3 MemoryStore
MemoryStore 是 Nanobot 的记忆系统,实现了一个简单的双层记忆架构:
核心架构
┌─────────────────────────────────────┐ │ MemoryStore │
├─────────────────────────────────────┤
│ Layer 1: MEMORY.md │
│ - 长期事实记忆(关键信息提取) │
│ - 每次覆盖写入 │
│ - 注入到 System Prompt │
├─────────────────────────────────────┤
│ Layer 2: HISTORY.md │
│ - 对话历史日志(grep-searchable) │
│ - 追加写入 │
│ - 用于回溯查找 │
└─────────────────────────────────────┘
工作流程
1. 对话进行 → 消息积累在 Session 中
│
▼
2. 触发记忆整合 (当消息数 > memory_window)
- 在 loop.py 的 _consolidate_memory() 中
│
▼
3. LLM 处理对话,生成:
├─ history_entry → append_history() → HISTORY.md
└─ memory_update → write_long_term() → MEMORY.md
│
▼
4. 下次对话时
- MEMORY.md 内容注入 System Prompt
- 作为长期记忆上下文
4.5 SkillsLoader
文件: nanobot/agent/skills.py
主要的技能加载器,负责加载和管理 agent 技能。
- 技能来源 (优先级从高到低)
- Workspace skills: workspace/skills/ 目录下的技能(最高优先级)
- Built-in skills: nanobot/skills/ 目录下的内置技能
- 核心方法
│ 方法 │ 功能 │
├───────────────────────────┼──────────────────────────────────┤
│ list_skills() │ 列出所有可用技能,支持按需求过滤 │
├───────────────────────────┼──────────────────────────────────┤
│ load_skill(name) │ 加载指定技能的 SKILL.md 内容 │
├───────────────────────────┼──────────────────────────────────┤
│ load_skills_for_context() │ 加载特定技能用于 agent 上下文 │
├───────────────────────────┼──────────────────────────────────┤
│ build_skills_summary() │ 构建 XML 格式的技能摘要 │
├───────────────────────────┼──────────────────────────────────┤
│ get_skill_metadata() │ 从 frontmatter 获取技能元数据 │
├───────────────────────────┼──────────────────────────────────┤
│ get_always_skills() │ 获取标记为 always=true 的技能 │
└───────────────────────────┴──────────────────────────────────┘
- 技能文件格式
技能是 markdown 文件 (SKILL.md),包含:
- YAML frontmatter: 元数据(名称、描述、要求等)
- Markdown 内容: 技能说明和用法
- 依赖检查
_check_requirements() 方法检查:
- bins: 需要的 CLI 工具是否存在 (shutil.which)
- env: 需要的环境变量是否设置
- 元数据解析
- _parse_nanobot_metadata(): 解析 frontmatter 中的 JSON 元数据(支持 nanobot 或 openclaw 键)
这个技能系统允许动态加载和过滤能力,使 agent 能够根据环境和需求使用不同的技能。
4.4 SubagentManager
文件: nanobot/agent/subagent.py
职责: 管理后台子代理执行,用于处理复杂任务。
特点:
- 轻量级代理实例,后台运行
- 共享 LLM 提供者,独立上下文
- 专注特定任务的系统提示
- 最大迭代次数限制(默认 15 次)
主要方法:
| 方法 | 说明 |
|---|---|
spawn() |
生成新的子代理任务,返回任务ID |
_run_subagent() |
执行子代理循环,包括工具调用和结果收集 |
_announce_result() |
通过消息总线向主代理宣布结果 |
_build_subagent_prompt() |
构建子代理特定的系统提示 |
工具限制: 子代理只能访问有限工具集(无消息工具和生成子代理工具)
4.4 ToolRegistry
文件: nanobot/agent/tools/registry.py
职责: 动态注册和管理工具,支持参数验证和执行。
主要方法:
| 方法 | 说明 |
|---|---|
register() |
注册工具实例 |
get_tool() |
获取工具实例 |
get_tool_definitions() |
获取所有工具定义(OpenAI 格式) |
validate_params() |
验证工具参数 |
execute() |
执行工具调用 |
4.5 SessionManager
文件: nanobot/session/manager.py
职责: 管理用户会话,支持持久化和多会话隔离。
主要方法:
| 方法 | 说明 |
|---|---|
get_or_create() |
获取或创建会话 |
load() |
从磁盘加载会话 |
save() |
保存会话到磁盘 |
reset() |
重置会话历史 |
会话键格式: {channel}:{chat_id}
5. 启动流程详解
5.1 Gateway 模式启动流程
nanobot gateway
│
▼
[commands.gateway()]
│
├─▶ 加载配置
│ ConfigLoader.load()
│ ├─ 读取 ~/.nanobot/config.json
│ └─ 合并环境变量
│
├─▶ 初始化消息总线
│ MessageBus()
│ ├─ inbound queue
│ └─ outbound queue
│
├─▶ 创建 LLM 提供者
│ ProviderRegistry.create(config)
│ └─ 根据配置实例化提供者
│
├─▶ 初始化会话管理器
│ SessionManager(workspace)
│
├─▶ 初始化定时任务服务
│ CronService(bus, config)
│
├─▶ 创建 AgentLoop 实例
│ AgentLoop(config, bus, provider, session_manager)
│ ├─ 初始化 ToolRegistry
│ │ └─ _register_default_tools()
│ └─ 初始化 SubagentManager
│
├─▶ 初始化心跳服务
│ HeartbeatService()
│
├─▶ 初始化渠道管理器
│ ChannelManager(config, bus)
│ └─ 初始化所有启用的渠道
│
└─▶ 启动所有服务
├─ cron_service.start()
├─ heartbeat_service.start()
├─ agent.run() (后台任务)
└─ channels.start_all() (阻塞)
5.2 Agent 模式启动流程
nanobot agent
│
▼
[commands.agent()]
│
├─▶ 加载配置
│
├─▶ 创建 LLM 提供者
│
├─▶ 创建 AgentLoop 实例 (direct_mode=True)
│
└─▶ 进入交互循环
while True:
├─▶ 读取用户输入
├─▶ 检查退出命令 (exit/quit)
├─▶ 调用 AgentLoop.process_direct()
└─▶ 显示响应
6. 关键设计模式
6.1 消息驱动架构
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Source │────▶│ MessageBus │────▶│ Handler │
│ (Channels) │ │ (Queues) │ │(AgentLoop) │
└─────────────┘ └──────────────┘ └─────────────┘
│
▼
┌──────────────┐
│ Subscribers │
│(Outbound Msgs)│
└──────────────┘
优点:
- 解耦消息生产者和消费者
- 支持异步处理
- 便于扩展和测试
6.2 会话隔离
Session Key: {channel}:{chat_id}
Example Sessions:
- telegram:123456
- whatsapp:654321
- discord:999888
每个会话独立存储:
- 会话历史 (JSON)
- 工作区目录
- 记忆文件 (MEMORY.md)
6.3 内存整合机制
当会话历史超过阈值 (默认 50 条):
│
▼
调用 LLM 总结对话:
Prompt: "Summarize this conversation..."
│
▼
更新 MEMORY.md:
追加总结内容
│
▼
更新 HISTORY.md:
记录整合历史
│
▼
重置会话历史:
保留最近 N 条
6.4 工具系统架构
┌──────────────────────────────────────┐
│ ToolRegistry │
│ ┌──────────────────────────────┐ │
│ │ Tool Definitions │ │
│ │ (OpenAI Function Schema) │ │
│ └──────────────────────────────┘ │
│ ┌──────────────────────────────┐ │
│ │ Tool Instances │ │
│ │ (ReadFile, WriteFile, etc.) │ │
│ └──────────────────────────────┘ │
└──────────────────────────────────────┘
│
▼
┌─────────────────────┐
│ BaseTool │
│ (Abstract Class) │
│ - name: str │
│ - description: str │
│ - parameters: dict │
│ - execute() │
└─────────────────────┘
│
┌─────────┼─────────┐
▼ ▼ ▼
┌───────┐ ┌───────┐ ┌───────┐
│ Read │ │ Write │ │ Exec │
└───────┘ └───────┘ └───────┘
7. 扩展开发指南
7.1 添加新工具
# nanobot/agent/tools/my_tool.py
from .base import Tool
class MyTool(Tool):
name = "my_tool"
description = "Description of what my tool does"
parameters = {
"type": "object",
"properties": {
"param1": {
"type": "string",
"description": "Description of param1"
}
},
"required": ["param1"]
}
async def execute(self, param1: str) -> dict:
# 实现工具逻辑
result = do_something(param1)
return {
"content": result,
"is_error": False
}
在 AgentLoop._register_default_tools() 中注册:
self.tools.register(MyTool())
7.2 添加新渠道
# nanobot/channels/my_channel.py
from .base import Channel
class MyChannel(Channel):
def __init__(self, config: dict, bus: MessageBus):
self.config = config
self.bus = bus
async def start(self):
# 启动渠道连接
# 监听消息并转发到总线
async def stop(self):
# 停止渠道连接
async def send(self, message: Message):
# 发送消息到用户
在配置中启用:
{
"channels": {
"my_channel": {
"enabled": true,
"api_key": "..."
}
}
}
7.3 添加新 LLM 提供者
# nanobot/providers/my_provider.py
from .base import LLMProvider
class MyProvider(LLMProvider):
def __init__(self, config: dict):
self.api_key = config.get("api_key")
async def call(self, messages: list, tools: list = None, **kwargs):
# 调用 LLM API
response = await call_llm_api(
messages=messages,
tools=tools,
api_key=self.api_key
)
return parse_response(response)
在 ProviderRegistry 中注册:
registry.register("my_provider", MyProvider)
8. 总结
Nanobot 代码功能比较简短,也比较合适用来了解一个agent主要的原理,有极强的拓展性,现在作者在逐步完善代码库,功能会逐步复杂起来,部分功能可以参考比如更好支持mcp及openclawhub,我也会逐步把我需要的工具合入到自己的分支中。