跳到主要内容
TypeScript Node.js AI
NanoClaw 深度剖析:AI 原生个人助手的架构设计 综述由AI生成 NanoClaw 是一个运行在本地机器的个人 AI 助手框架。其核心架构基于 SQLite 存储消息状态,通过容器化隔离执行 AI 代理任务,确保安全性。独特的 Skills Engine 允许 AI 直接重写源码实现功能扩展,采用三路合并机制处理冲突并支持自动回滚。系统利用游标机制实现断点续传,结合定时任务与 IPC 辅助通信。这种设计体现了 AI 即操作者、隔离第一公民及可组合胜过全能的工程哲学,展示了软件通过 AI 自我演化的可能性。
接口猎人 发布于 2026/3/16 更新于 2026/4/29 4 浏览NanoClaw 是一个运行在本地机器的个人 AI 助手框架。它做的事情可以用三句话概括:
监听 :把来自 WhatsApp(以及通过技能扩展的 Telegram 等)的消息写入一个本地 SQLite 数据库。
判断 :轮询数据库,判断哪些消息需要 AI 处理。
执行 :把任务丢进一个隔离容器(Docker/Apple Container)里运行 AI 代理,再把结果回传。
听起来很简单?但魔鬼藏在细节里。
一、整体架构:一张图看懂数据流
┌──────────────────────────────────────────────────────────┐
│ 宿主机 (Host) │
│ │
│ WhatsApp/Telegram │
│ ▼ │
│ ┌─────────────┐ 轮询 ┌──────────────────────┐ │
│ │ SQLite DB │ ◄──────►│ src /index.ts │ │
│ │ (消息队列) │ │ (指挥中心 / 调度员) │ │
│ └─────────────┘ └──────────┬───────────┘ │
│ │ │
│ │ 按群组分发 │
│ ▼ │
│ ┌──────────────────┐ │
│ │ GroupQueue │ │
│ │ (并发控制) │ │
│ └────────┬─────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 隔离容器 (Container) │ │
│ │ container /agent-runner/src /index.ts │ │
│ │ ├── Anthropic API (Claude 模型) │ │
│ │ ├── read_file / write_file 工具 │ │
│ │ └── bash 工具 │ │
│ │ │ │
│ │ 挂载:groups/<group_folder>/ │ │
│ └──────────────────────────────────────────────────────────┘ │
这个架构的核心理念是职责分离:宿主机只管派单,容器只管干活,两者之间通过文件系统挂载和 stdin/stdout 管道通信,互不干扰。
二、数据层:SQLite 才是真相的唯一来源
1. 为什么选 SQLite?
很多人第一反应会问:为什么不用 Redis?不用消息队列?答案很简单——零依赖,零运维。
NanoClaw 用 better-sqlite3 管理一个单文件数据库,涵盖以下表:
messages 存储所有收到的消息,作为 AI 上下文
scheduled_tasks 定时任务配置和下次运行时间
registered_groups 已激活的群组信息(触发词、文件夹路径等)
2. 游标机制:如何做到断点续传 这是 src/index.ts 里一个非常精妙的设计。系统维护两个关键时间戳:
lastTimestamp :消息循环扫描到哪里了(已读线)
lastAgentTimestamp :AI 已经处理到哪条消息了(处理线)
消息时间轴: ─────────────────────────────────────────────────────►
msg1 msg2 msg3 msg4 msg5 msg6 msg7
▲ ▲
lastAgentTimestamp lastTimestamp
(AI 处理到这里) (已读到这里)
中间这段 = 已读但 AI 还没处理 = 待处理消息
当程序崩溃重启时,recoverPendingMessages() 会从这两个游标之间找到漏网的消息,重新入队处理。这就是所谓的故障恢复机制。
三、消息循环:一颗永不停跳的心脏 startMessageLoop() 是整个系统的主循环,每隔几百毫秒(POLL_INTERVAL)就询问一次数据库:有没有新消息?
SELECT 出所有时间戳 > lastTimestamp 的新消息
按 chatJid (群组 ID) 分组
对每个群组判断:是否包含触发词(如 @Andy)?如果是主群组,无需触发词
更新 lastTimestamp(标记已读)
派单:
该群组容器已在运行?YES:直接 pipe 消息到容器 stdin
容器不存在?NO:enqueueMessageCheck(chatJid),等待 GroupQueue 分配资源后启动新容器
这个设计的精髓在于热容器和冷启动的区分。如果用户在持续对话,消息会直接喂给已有容器,响应极快;如果容器已因空闲超时(10 分钟)被销毁,才会触发一次完整的冷启动流程。
四、容器化执行:安全隔离的艺术
1. 为什么要用容器? 这是 NanoClaw 最关键的安全决策。AI 代理可以执行 bash 命令、读写文件——这些能力如果不加约束,一条错误的指令就可能删光你的硬盘。
文件系统隔离 :容器只能看到挂载进来的 groups/<folder_name>/目录,宿主机的其他文件完全不可见。
网络隔离 :可配置容器的出口网络权限,防止数据泄露。
进程隔离 :容器崩溃不会波及宿主机进程。
2. 容器内的 AI 代理是如何工作的? 在容器内部运行的是 container/agent-runner/src/index.ts。它的本质是一个工具调用循环(Tool Use Loop):
接收 prompt(消息上下文)
▼
调用 Anthropic API(Claude 模型)
▼
模型返回 tool_use 或 text ?
▼ ▼
执行工具 流式输出文字 (bash/read_file/write_file)
发回宿主机 (通过 stdout)
└────── 把 tool_result 返回给模型,继续对话
注意其中有一个特殊设计:AI 输出中的 <internal>...</internal> 标签会被过滤掉,不发送给用户。这让 AI 可以进行内部思考而不打扰用户体验。
五、Skills Engine:最令人拍案叫绝的设计 如果说容器化是 NanoClaw 的安全基石,那 Skills Engine 就是它的灵魂。
1. 传统插件 vs. NanoClaw 技能 维度 传统插件系统 NanoClaw Skills 扩展方式 加载独立 DLL/JS 模块 直接重写源码 学习成本 需要学习宿主 API 理解意图文件即可 死代码 不需要的功能依然存在 最终代码只含你用到的功能 底层访问 受宿主 API 限制 可触及任意文件(db.ts、index.ts…) 回滚能力 通常没有 有完整事务 + 自动回滚
2. 三路合并的核心原理 当你运行 npx tsx scripts/apply-skill.ts .claude/skills/add-telegram 时,实际上是在执行一次自动化 Git 手术。
Base(原始基线) ──┐
├─► git merge - file ──► 合并结果
Current (你的修改) ─┤
Skill(技能修改) ──┘
这和 git merge 的三路合并是完全相同的原理:
Base → Current 的差异 = 你做的修改
Base → Skill 的差异 = 技能要做的修改
如果两者修改的位置不重叠 → 自动合并成功
如果同一行都被修改了 → 产生冲突,暂停安装
底层直接调用 git merge-file 命令执行,这是一个极其务实的工程决策——不重复造轮子。
3. applySkill 的完整生命周期 skills-engine/apply.ts 的 applySkill() 函数是整个引擎的核心,它的执行流程是一个标准的数据库事务模型:
[版本检查] 技能版本 vs 引擎版本是否兼容?
[依赖/冲突检查] 依赖的技能是否已安装?有无互斥技能?
[漂移检测] 你是否手动改过即将被修改的文件?
[加锁] 创建 .lock 文件,防止并发安装
[备份] 把所有受影响文件拷贝到 .nanoclaw/backups/
[文件添加] 把 add/目录下的新文件复制到项目
[三路合并] 对 modify/目录下每个文件执行 git merge-file
[结构化操作] 修改 package.json 安装 npm 依赖,更新 .env.example 注入环境变量,修改 docker-compose.yml
[运行 npm install]
[执行后置命令] 运行 post_apply 脚本(如 tsc 编译)
[运行测试] 如果测试失败 → 从 backups/完整回滚
[提交状态] 写入 .nanoclaw/state.yaml 记录安装成功
[清理] 删除备份,释放锁
失败时的回滚路径:任何一步出错,都会调用 restoreBackup() 把所有文件还原到安装前的状态,真正做到了幂等性。
4. Intent 文件:写给 AI 看的手术说明书 这是 NanoClaw 最有远见的设计之一。每个需要合并的文件旁边,都配有一个 *.intent.md:
modify/
src/index.ts ← 要合并的目标文件
src/index.ts.intent.md ← 用自然语言描述为什么要这么改
当三路合并产生冲突时,意图文件会告诉 Claude Code:
'我要在消息路由逻辑里加一个 Telegram 分支,这个分支的不变量是:必须在 WhatsApp 分支之后注册,且必须复用 findChannel() 工厂函数…'
这让 AI 能够像一名理解需求的开发者一样,而不是机械的代码替换器,来解决合并冲突。代码变更的意图被显式编码进了代码库——这本身就是一种先进的软件工程实践。
六、状态追踪:.nanoclaw/state.yaml engine_version: "1.2.0"
installed_skills:
- name: add-telegram
version: "1.0.0"
installed_at: "2025-01-15T10:30:00Z"
file_hashes:
src/index.ts: "a3f8b2c1..."
src/config.ts: "d9e4f7a0..."
path_remaps:
old/path/file.ts: new/path/file.ts
其中 file_hashes 是漂移检测的关键:如果你手动修改了 src/index.ts,下次安装技能时哈希值不匹配,系统会给出警告——它知道你动过刀。
七、路径重映射:抵抗重构的能力 skills-engine/path-remap.ts 解决了一个实际工程问题:如果你把 src/channels/whatsapp.ts 重命名为 src/channels/whatsapp-bridge.ts,下次安装 add-telegram 技能时,它还能找到正确的注入位置吗?
答案是可以。重命名操作会被记录在 state.yaml 的 path_remaps 字段里,技能引擎在执行合并前会先做一次路径翻译。这让代码库在经过重构后,依然能正确应用技能。
八、定时任务与 IPC:被忽视的辅助系统 src/index.ts 的 main() 函数在启动消息循环之前,还会初始化两个子系统:
定时任务调度器(Scheduler) :读取数据库中的 scheduled_tasks 表,按时触发 AI 执行任务(如每天早上 8 点发送天气播报)。
IPC 监视器(Inter-Process Communication) :监听容器与宿主机之间的消息通道,处理诸如容器请求注册新群组这类跨边界的操作请求。
九、从源码里读出的设计哲学 读完整个代码库,我总结出 NanoClaw 的三个核心设计哲学:
所有 AI 执行都在容器里发生。这不是可选的优化,而是架构的基础假设。任何能力的扩展都不能绕过这道隔离墙。
整个系统的使用姿势不是用户配置,而是 AI 编程。想改触发词?让 AI 改代码。想加新功能?给 AI 提供意图文件,让它运行安装脚本。代码是配置,AI 是操作员。
NanoClaw 的核心代码出奇地精简。它不预装任何你不需要的功能。Telegram 支持、定时任务高级功能、语音识别——所有这些都是可选的技能,你用到了再装,装了就织入代码,不装就不存在。这与大而全框架的思路截然相反。
结语:它预示了什么? NanoClaw 目前还是一个相对小众的项目,但它展示了一种可能性:未来的软件可以不依赖传统的插件系统,而是直接通过 AI 来改造自身。
这种 AI 原生(AI-Native)的设计模式——让 AI 参与软件自身的演化——或许才是下一代开发工具真正的形态。
Skills Engine 里那个调用 git merge-file 的小函数,承载的是比它看起来大得多的野心。
相关免费在线工具 RSA密钥对生成器 生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
Mermaid 预览与可视化编辑 基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
随机西班牙地址生成器 随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online