NanoClaw 核心功能与架构
介绍 NanoClaw 的产品定位、核心功能、架构设计和技术选型,解析其作为 OpenClaw 轻量级替代方案的设计哲学和关键决策。
1.1 产品定位
1.1.1 设计目标
NanoClaw 是一个”个人 AI 助理框架”,设计目标是作为 OpenClaw 的轻量级替代方案。
核心设计哲学 (NanoClaw REQUIREMENTS.md):
## Philosophy
### Small Enough to Understand
The entire codebase should be something you can read and understand.
One Node.js process. A handful of source files.
### Security Through True Isolation
Instead of application-level permission systems trying to prevent agents
from accessing things, agents run in actual Linux containers.
### Built for One User
This isn't a framework or a platform. It's working software for my specific needs.
1.1.2 与 OpenClaw 的对比
| 维度 | OpenClaw | NanoClaw | 差异倍数 |
|---|---|---|---|
| 代码规模 | ~500,000 行 | ~3,500 行 | 143:1 |
| 配置文件 | 53+ | 0 (代码即配置) | - |
| 依赖数量 | 70+ npm 包 | ~20 npm 包 | 3.5:1 |
| 进程模型 | 多进程架构 | 单 Node 进程 + 容器 | - |
| 隔离方式 | 应用层权限检查 | 操作系统级容器 | - |
| 目标用户 | 企业/团队 | 个人用户 | - |
关键洞察: NanoClaw 不是 OpenClaw 的”简化版”,而是重新设计的轻量级替代方案,核心差异在于:
- OpenClaw 试图通过复杂的配置系统满足各种场景
- NanoClaw 专注于个人用户的单一场景,通过容器化提供默认安全基线
1.2 核心功能
1.2.1 功能矩阵
| 功能类别 | 具体功能 | 实现方式 |
|---|---|---|
| 多渠道消息 | WhatsApp, Telegram, Slack, Discord, Gmail | 技能系统自注册,通过 MCP 协议通信 |
| 会话隔离 | 每个群组独立的 CLAUDE.md 记忆和文件系统 | 每群组独立容器 + 独立挂载目录 |
| 定时任务 | cron, interval, once 三种调度类型 | 基于 node-cron 的轻量调度器 |
| 容器隔离 | Docker (默认) 或 Apple Container (macOS) | 容器运行时抽象层 (src/container-runtime.ts) |
| Agent Swarms | 多 agent 协作 | Claude Agent SDK 的 Team API |
| IPC 通信 | 跨群组消息传递(受控) | 基于文件系统的 IPC 命名空间 |
1.2.2 群组类型系统
NanoClaw 将聊天会话分为两种类型:
Main Group(主群组):
- 可以访问项目根目录(只读)
- 可以访问所有群组的 IPC 消息
- 可以为其他群组创建任务
- 默认为第一个配置的群组
Non-Main Group(非主群组):
- 只能访问自己的群组目录(读写)
- 只能访问全局记忆目录(只读)
- 只能与自己通信
- 无法为其他群组创建任务
// 群组类型决定挂载策略
if (isMain) {
mounts.push({ hostPath: projectRoot, containerPath: '/workspace/project', readonly: true });
mounts.push({ hostPath: groupDir, containerPath: '/workspace/group', readonly: false });
} else {
mounts.push({ hostPath: groupDir, containerPath: '/workspace/group', readonly: false });
mounts.push({ hostPath: globalDir, containerPath: '/workspace/global', readonly: true });
}
1.3 架构概览
1.3.1 核心组件
┌─────────────────────────────────────────────────────────────┐
│ Channels Layer │
│ WhatsApp │ Telegram │ Slack │ Discord │ Gmail │
└────────────────────┬────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ SQLite Database │
│ Messages │ Sessions │ Tasks │ Groups │
└────────────────────┬────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Polling Loop │
│ 每 2-5 秒轮询新消息 → 会话恢复 → 触发 Agent │
└────────────────────┬────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Container Runtime Layer │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ Docker Container (ephemeral, --rm) ││
│ │ ┌─────────────────────────────────────────────────────┐││
│ │ │ Claude Agent SDK + agent-browser │││
│ │ │ /workspace/project (ro) │││
│ │ │ /workspace/group (rw) │││
│ │ │ /workspace/ipc (rw) - isolated per group │││
│ │ │ /home/node/.claude (rw) - session data │││
│ │ └─────────────────────────────────────────────────────┘││
│ └─────────────────────────────────────────────────────────┘│
└────────────────────┬────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Response Layer │
│ 消息发送 → IPC 任务创建 → 转录存储 │
└─────────────────────────────────────────────────────────────┘
1.3.2 关键文件
| 文件路径 | 职责 | 行数 |
|---|---|---|
src/index.ts | 编排器:状态管理、消息循环、agent 调用 | ~800 |
src/container-runner.ts | 容器执行:生成流式 agent 容器、挂载管理 | ~400 |
src/ipc.ts | IPC 通信:消息监控、任务处理、授权验证 | ~350 |
src/mount-security.ts | 挂载安全:白名单加载、路径验证、阻止模式 | ~200 |
src/container-runtime.ts | 运行时抽象:Docker CLI 封装、挂载参数生成 | ~150 |
container/Dockerfile | 容器镜像:Node.js 22 + agent-browser + claude-code | ~50 |
container/agent-runner/src/index.ts | Agent 执行:查询循环、会话恢复、Hook 注册 | ~500 |
总代码规模: ~3,500 行(不包括测试和技能)
1.4 设计哲学
1.4.1 Skills over Features
NanoClaw 采用”技能优先”的架构决策:
Don’t add features. Add skills.
If you want to add Telegram support, don’t create a PR that adds Telegram alongside WhatsApp. Instead, contribute a skill file (
.claude/skills/add-telegram/SKILL.md) that teaches Claude Code how to transform a NanoClaw installation to use Telegram.
优点:
- 用户 fork 后只保留自己需要的功能
- 避免配置膨胀(OpenClaw 有 53+ 配置文件)
- 代码库保持精简
缺点:
- 依赖 Claude Code 的正确执行
- 技能质量参差不齐
- 功能发现性差(需要知道技能存在)
1.4.2 默认容器化
与 OpenClaw 的”可选容器化”不同,NanoClaw 默认所有操作都在容器中执行。
设计理由:
- 安全基线 - 容器是明确的信任边界,而非应用级权限检查
- 一致性 - 开发/生产环境使用相同的隔离机制
- 简化威胁模型 - 即使 agent 发现漏洞,也无法突破容器边界
实现方式:
// 每次消息触发都会创建临时容器
const containerArgs = [
'run', '-i', '--rm', // --rm 确保容器执行后销毁
'--name', `nanoclaw-${group}-${Date.now()}`,
'--user', `${hostUid}:${hostGid}`, // 非 root 执行
...mountArgs, // 显式挂载点
'nanoclaw-agent:latest'
];
1.4.3 代码可读性优先
NanoClaw 明确表示”代码应该小到可以完全理解”:
- 单进程模型 - 所有逻辑在一个 Node.js 进程中
- 少量源文件 - 核心逻辑不超过 10 个文件
- 零配置 - 没有复杂的配置文件,代码即配置
- 显式优于隐式 - 挂载、授权、凭证处理都是显式的
1.5 技术选型
1.5.1 运行时依赖
| 依赖 | 用途 | 必需性 |
|---|---|---|
| Docker / Apple Container | 容器运行时 | 必需 |
| Node.js 22 | 主进程运行时 | 必需 |
| Claude Agent SDK | Agent 执行框架 | 必需 |
| agent-browser | 浏览器自动化工具 | 可选(用于 Web 操作) |
1.5.2 数据存储
| 数据类型 | 存储位置 | 格式 |
|---|---|---|
| 消息/会话/任务 | data/sqlite | SQLite |
| 群组文件 | data/groups/{folder}/ | 文件系统 |
| Claude 会话 | data/sessions/{group}/.claude/ | JSON 转录 |
| IPC 消息 | data/ipc/{group}/messages/ | JSON 文件 |
| 挂载白名单 | ~/.config/nanoclaw/mount-allowlist.json | JSON |
1.5.3 通信协议
| 通信类型 | 协议 | 实现 |
|---|---|---|
| 外部渠道(WhatsApp 等) | 各渠道 API | 技能注册 |
| 内部组件通信 | 文件系统 IPC | 文件监控 |
| 容器与主机 | stdin/stdout | JSON 协议 |
| Agent 工具调用 | MCP (Model Context Protocol) | 自定义 MCP 服务器 |
1.6 架构决策分析
1.6.1 为什么选择 Docker 而非其他沙箱方案?
官方解释:
Docker provides cross-platform support (macOS, Linux and even Windows via WSL2) and a mature ecosystem. On macOS, you can optionally switch to Apple Container via
/convert-to-apple-containerfor a lighter-weight native runtime.
深度分析:
| 方案 | 隔离强度 | 启动时间 | 跨平台 | 复杂度 |
|---|---|---|---|---|
| Docker | 中 | ~1-2 秒 | ✅ | 低 |
| Firecracker | 高 | ~150ms | ❌ (仅 Linux) | 中 |
| gVisor | 高 | ~5-10 秒 | ✅ | 高 |
| 纯应用层隔离 | 低 | N/A | ✅ | 低 |
决策合理性: Docker 在隔离强度、启动时间、跨平台支持之间提供了最佳平衡点。
1.6.2 为什么使用文件系统 IPC 而非网络 IPC?
可能原因:
- 简单性 - 不需要管理端口、连接池
- 持久化 - 消息天然持久化,不会丢失
- 调试友好 - 可以直接查看文件内容
- 权限控制 - 文件系统权限天然支持隔离
缺点:
- 性能低于内存 IPC
- 需要定期清理旧文件
- 并发控制需要额外处理(文件锁)
1.6.3 为什么凭证通过 stdin 传递而非环境变量?
安全考虑:
// 通过 stdin 传递配置(包括 secrets)
container.stdin.write(JSON.stringify(input));
container.stdin.end();
delete input.secrets; // 从日志中移除
优势:
- 不会出现在
ps aux输出中 - 不会泄露给子进程(除非显式传递)
- 容器销毁后无残留
劣势:
- 仍然可以被容器内 agent 读取(通过 SDK 状态)
- 需要额外的序列化/反序列化逻辑
1.7 小结
NanoClaw 是一个设计精良的个人 AI 助理框架,核心特点:
- 轻量级 - ~3500 行代码,远优于 OpenClaw 的 50 万行
- 容器化默认 - 所有操作都在 Docker 容器中执行
- 技能驱动 - 通过技能系统扩展功能,而非硬编码
- 显式安全 - 挂载白名单、IPC 授权、凭证保护都是显式的
下一章预告: 第 2 章将深入分析 NanoClaw 的容器化执行机制,包括 Docker 运行时配置、容器启动流程、Dockerfile 分析,以及 stdin 协议的详细设计。