Logo
热心市民王先生

NanoClaw 核心功能与架构

NanoClaw AI Agent 架构设计 OpenClaw

介绍 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 的对比

维度OpenClawNanoClaw差异倍数
代码规模~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.tsIPC 通信:消息监控、任务处理、授权验证~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.tsAgent 执行:查询循环、会话恢复、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 默认所有操作都在容器中执行

设计理由:

  1. 安全基线 - 容器是明确的信任边界,而非应用级权限检查
  2. 一致性 - 开发/生产环境使用相同的隔离机制
  3. 简化威胁模型 - 即使 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 SDKAgent 执行框架必需
agent-browser浏览器自动化工具可选(用于 Web 操作)

1.5.2 数据存储

数据类型存储位置格式
消息/会话/任务data/sqliteSQLite
群组文件data/groups/{folder}/文件系统
Claude 会话data/sessions/{group}/.claude/JSON 转录
IPC 消息data/ipc/{group}/messages/JSON 文件
挂载白名单~/.config/nanoclaw/mount-allowlist.jsonJSON

1.5.3 通信协议

通信类型协议实现
外部渠道(WhatsApp 等)各渠道 API技能注册
内部组件通信文件系统 IPC文件监控
容器与主机stdin/stdoutJSON 协议
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-container for a lighter-weight native runtime.

深度分析:

方案隔离强度启动时间跨平台复杂度
Docker~1-2 秒
Firecracker~150ms❌ (仅 Linux)
gVisor~5-10 秒
纯应用层隔离N/A

决策合理性: Docker 在隔离强度、启动时间、跨平台支持之间提供了最佳平衡点。

1.6.2 为什么使用文件系统 IPC 而非网络 IPC?

可能原因:

  1. 简单性 - 不需要管理端口、连接池
  2. 持久化 - 消息天然持久化,不会丢失
  3. 调试友好 - 可以直接查看文件内容
  4. 权限控制 - 文件系统权限天然支持隔离

缺点:

  • 性能低于内存 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 助理框架,核心特点:

  1. 轻量级 - ~3500 行代码,远优于 OpenClaw 的 50 万行
  2. 容器化默认 - 所有操作都在 Docker 容器中执行
  3. 技能驱动 - 通过技能系统扩展功能,而非硬编码
  4. 显式安全 - 挂载白名单、IPC 授权、凭证保护都是显式的

下一章预告: 第 2 章将深入分析 NanoClaw 的容器化执行机制,包括 Docker 运行时配置、容器启动流程、Dockerfile 分析,以及 stdin 协议的详细设计。


参考资料