﻿---
title: "OpenClaw 的龙虾故事"
description: "从 511 行 TypeScript 到 21.8 万 Star，一个 AI 助手项目的九十天蜕壳记录。翻了 15,579 个 commit、11,058 个 Issue 和 11,991 个 PR，这是我找到的故事。"
pubDate: 2026-02-23
tags: ["开源", "AI", "架构"]
clc: "TP18"
hero: "./hero.svg"
refs:
  - id: "1"
    title: "Initial commit with LICENSE"
    url: "https://github.com/openclaw/openclaw/commit/f6dd362d"
    site: "openclaw/openclaw@f6dd362d"
  - id: "2"
    title: "First working prototype (511 lines)"
    url: "https://github.com/openclaw/openclaw/commit/16dfc1a5"
    site: "openclaw/openclaw@16dfc1a5"
  - id: "3"
    title: "Add Clawd system prompt"
    url: "https://github.com/openclaw/openclaw/commit/0adc0ed"
    site: "openclaw/openclaw@0adc0ed"
  - id: "4"
    title: "Drop Twilio and go web-only"
    url: "https://github.com/openclaw/openclaw/commit/7c7314f6"
    site: "openclaw/openclaw@7c7314f6"
  - id: "5"
    title: "Fix WhatsApp Linked ID format"
    url: "https://github.com/openclaw/openclaw/pull/1"
    site: "PR #1"
  - id: "6"
    title: "Path traversal vulnerability in media endpoint"
    url: "https://github.com/openclaw/openclaw/pull/10"
    site: "PR #10"
  - id: "7"
    title: "Embed pi-mono runtime"
    url: "https://github.com/openclaw/openclaw/commit/fb3fae43"
    site: "openclaw/openclaw@fb3fae43"
  - id: "8"
    title: "Support custom models"
    url: "https://github.com/openclaw/openclaw/issues/46"
    site: "Issue #46"
  - id: "9"
    title: "Run sessions in Docker containers"
    url: "https://github.com/openclaw/openclaw/issues/81"
    site: "Issue #81"
  - id: "10"
    title: "Pi SDK ignores sandbox tools"
    url: "https://github.com/openclaw/openclaw/issues/243"
    site: "Issue #243"
  - id: "11"
    title: "Pi commit breaks pnpm patches"
    url: "https://github.com/openclaw/openclaw/issues/118"
    site: "Issue #118"
  - id: "12"
    title: "Gemini 3 bug requires Pi-side fix"
    url: "https://github.com/openclaw/openclaw/issues/922"
    site: "Issue #922"
  - id: "13"
    title: "Sandbox security model limitations"
    url: "https://github.com/openclaw/openclaw/issues/513"
    site: "Issue #513"
  - id: "14"
    title: "Interactive setup wizard rejected"
    url: "https://github.com/openclaw/openclaw/pull/55"
    site: "PR #55"
  - id: "15"
    title: "Gemini onboarding integration rejected"
    url: "https://github.com/openclaw/openclaw/pull/86"
    site: "PR #86"
  - id: "16"
    title: "Dangerous features: user decides"
    url: "https://github.com/openclaw/openclaw/issues/6"
    site: "Issue #6"
  - id: "17"
    title: "Claude Max burned in 20 minutes"
    url: "https://github.com/openclaw/openclaw/issues/22151"
    site: "Issue #22151"
  - id: "18"
    title: "Stabilisation Mode"
    url: "https://github.com/openclaw/openclaw/issues/5799"
    site: "Issue #5799"
  - id: "19"
    title: "i18n support discussion"
    url: "https://github.com/openclaw/openclaw/issues/3460"
    site: "Issue #3460"
---


2025 年 11 月 24 日上午 11:16，Peter Steinberger 推送了一个只有 LICENSE 文件的 commit[^1]。三个月后，这个项目有 21.8 万颗 Star、847 位贡献者，每两分钟收到一个 Pull Request——然后不得不按下暂停键。

我翻了 15,579 个 commit、11,058 个 Issue 和 11,991 个 PR。下面是我找到的故事。

先说名字。Clawd = Claude + Claw，一个谐音梗，把 AI 的名字和龙虾的钳子焊在了一起。项目吉祥物是一只太空龙虾，叫 Molty，官方口号是 "EXFOLIATE!"——对标 Dalek 的 "EXTERMINATE!"，只不过把"消灭"换成了"去角质"。

龙虾靠蜕壳才能长大。旧壳太紧了，撑不下新长出来的肉，只能脱掉重来。这个项目在九十天里蜕了四次壳——Warelay、Clawdbot、Moltbot、OpenClaw——每次改名都是一次蜕壳，每次蜕壳都意味着旧的架构撑不住了。`docs/start/lore.md` 里有一句话："The claw is the law 🦞"。读完这篇你就知道为什么。


## 511 行


七分钟后，第二个 commit 到了[^2]。511 行 TypeScript，一个 `src/index.ts`。

Peter Steinberger 不是新手。他创建过 PSPDFKit——一家被广泛使用的 PDF SDK 公司——后来退出、退休。GitHub 签名写的是 "Came back from retirement to mess with AI." 退休的人回来折腾 AI 了。

那 511 行代码做的事情简单到可以用一句话说清楚：收到 WhatsApp 消息，启动一个 Claude CLI 子进程，把消息当参数传进去，解析输出的 JSON，把回复发回 WhatsApp。消息通道用的是 Twilio——一种无状态的 Webhook 模型，消息进来触发一次 HTTP 请求，处理完就断开。

没有 API 调用，没有 SDK，没有抽象层。就是 `child_process.spawn('claude')`——启动一个子进程，消息进去，JSON 出来。项目叫 Warelay，WhatsApp Relay 的意思。名字说明了一切：它只是一个中转站。

这样的设计有一个致命的优点：十分钟内就能跑起来。Claude CLI 已经装在他的 Mac 上了，不需要申请 API key，不需要搞 SDK 集成，直接拿来用。代价是每条消息都要冷启动一个新进程，没有会话保持，没有工具调用，没有流式输出——用户发一条消息，等 30 秒，收到一整段回复。

但 steipete 显然不在乎这些。接下来的 18 个小时里他提交了 139 个 commit，版本号从 0.1 随手跳到 1.1。心跳系统、语音转录、媒体压缩、群聊支持，想到什么加什么。凌晨三点还在改代码，那种创客特有的、不计后果的兴奋。

第二天，一行代码悄悄定义了这个项目的性格。commit `0adc0ed`[^3]，steipete 写了一段系统提示词："You are Clawd (Claude) running on the user's Mac via warelay." 子进程不再只是一个中转站——它有了名字、有了人格、有了身份。龙虾的第一层壳，就是在这一天长出来的。

同一天还发生了一个更深层的架构转折。steipete 引入了 Baileys，一个直接实现 WhatsApp Web 协议的库。Twilio 是外卖电话，响一次挂一次；Baileys 是住家厨师，一直在线等着。Twilio 用 Webhook，无状态的；Baileys 用 WebSocket，有状态的。

这个切换意味着项目不再是一个可以随用随弃的脚本，而是一个需要持续运行的守护进程。项目在诞生后的第二天就完成了第一次蜕皮。12 月 5 日，Twilio 被彻底移除，commit 信息写着 "drop twilio and go web-only"[^4]。

第一个外部贡献者在 PR #1[^5] 出现——@mneves75 修复了 WhatsApp Linked ID 的格式问题。紧接着是第一道裂缝：PR #10[^6]，一个叫 @joaohlisboa 的开发者发现暴露在公网的媒体端口存在路径遍历漏洞，可以读取服务器上的任意文件。

从"我的工具"到"别人也在用"，中间只隔了四天。从"别人也在用"到"别人发现了安全漏洞"，又是四天。一个创客的周末项目，开始不得不认真对待了。



## 选择 Pi 的那一天


12 月 2 日，steipete 做了第一次抽象尝试——把 Claude CLI 从硬编码变成可配置，除了 Claude 还能调用 Pi CLI、Codex CLI、Opencode CLI。本质没变，还是子进程管道。就像一家只做外卖的餐厅，从只接美团扩展到了同时接饿了么和大众点评，厨房还是那个厨房。

但在同一时期，一个叫 Tau RPC 的中间层悄悄出现了。与其每条消息都冷启动一个新子进程，Tau 让 Pi 作为一个持久的后台进程运行，通过 RPC 管道通信——不再是每条消息新建一个进程，而是一个常驻进程接收所有请求。从"每次叫外卖"变成了"请了一个驻场厨师"，虽然厨师还是外面请来的，但至少不用每顿饭重新招聘。

真正的转折发生在 12 月 19 日。

那天有两件事同时发生。项目从 Warelay 改名 Clawdis，发布了 2.0.0-beta1。更重要的是，一个叫 pi-mono 的外部项目第一次被嵌入到代码库里——commit `fb3fae43`[^7]，文件 `src/agents/skills.ts`，只有 15 行代码。

pi-mono 是 Mario Zechner 的项目，不是一个简单的 API 封装，而是一整套 LLM Agent 运行时——工具调用、上下文管理、会话历史、多模型支持，全部打包在一起。三步走完了：`spawn('claude')` 冷启动，到 Tau RPC 持久进程，再到 Pi 嵌入式运行时。每一步都把 LLM 拉得离宿主更近一点，直到它变成了宿主身体的一部分。

三天后的 Issue #46[^8]，一个用户问能不能支持自定义模型。steipete 回了一句话：

> "Absolutely, one of the reasons I went with pi are local models. Fixing that rn, will land in main in a few minutes."

两个关键信息。第一，选 Pi 是因为它支持本地模型——不用被锁死在 Claude 一个供应商上面。第二，"fixing that rn, will land in main in a few minutes"——现在改，几分钟后上线。这就是 steipete 的节奏。不讨论，不排期，不开会。

引入 Pi 之后，Agent 架构变成了双轨制。旧路径还在，仍然可以启动外部 CLI 作为子进程，留给那些只有命令行工具的 Agent 用。新路径是 Pi 运行时直接嵌入在进程里——工具调用、上下文管理、流式输出，全在进程内完成。新架构是默认，旧架构降级为后备。

这 15 行代码还带来了一个当时看不出来的东西：Skills 系统的雏形。那个 `skills.ts` 文件从 Pi 导入了一个函数，作用是从本地目录加载 SKILL.md 文件，注入到 Agent 的系统提示里。从第一天起，Skills 就不是核心代码的一部分——它们是外部的、可插拔的、用户自己可以添加的模块。

两个月后，当成千上万的贡献者想往核心加功能时，这个泄压阀会变得至关重要。但那是后话了。



## 沙箱是坏的


用别人的运行时，意味着命运部分掌握在别人手里。这件事的代价比预想来得快。

2026 年 1 月 2 日，steipete 提了 Issue #81[^9]，全文十二个英文单词：

> "Sessions that are semi-public (e.g. Discord guilds) should run in a Docker container. Security."

没有讨论。两天后关闭，标记完成。

但三天之后的 Issue #243[^10] 暴露了一个致命的设计缺陷：OpenClaw 精心构建的 Docker 沙箱工具被传给了 Pi Agent 运行时，但 Pi SDK 完全忽略了这些工具，用自己内置的版本替换掉了。OpenClaw 说"用我的沙箱化 bash"，Pi 说"不，我用我自己的"。

沙箱从第一天起就是摆设。你以为你在开车，但方向盘连的是另一套转向系统。

同一时期，上游依赖接连爆破。Issue #118[^11]，Pi 的一个 commit 破坏了 OpenClaw 的 pnpm patch 文件，导致 29 个 TypeScript 编译错误。Issue #922[^12]，Gemini 3 的一个 bug 需要在 Pi 的代码库里改。你自己项目的 bug，要排队等别人来修。速度换控制，这个 trade-off 从来都不免费。

不过，沙箱事件也催生了更成熟的安全思维。Issue #513[^13] 的讨论里有一句话：

> "This is a policy boundary, not a security sandbox."

然后它列举了自己无法防御的攻击：编码路径绕过、解释器绕过、多步攻击。大多数项目会告诉你他们的安全模型"足够了"，OpenClaw 直接告诉你——不够。这种对自身局限的坦诚在开源项目中非常少见。



## 调度中心


12 月 8 日，一个 WebSocket 守护进程上线了，监听端口 18789。它有一个朴素的名字：Gateway。

Gateway 的角色不难理解——它是所有消息的十字路口。WhatsApp、Telegram、Discord、Signal、Slack、iMessage，所有消息平台的消息先汇入 Gateway，由 Gateway 分发给 Agent 处理，再把回复发回对应的平台。但它的意义远不止消息中转。

当 Gateway 成为系统的中枢之后，所有东西都可以接进来了。接下来一周发生的事情近乎荒诞：12 月 8 日 macOS 菜单栏应用出现，12 月 10 日 iOS 伴侣应用开始开发，12 月 14 日 Android 客户端上线。一个星期，三个原生平台。iOS 的 README 至今写着 "Super Alpha"——但它能拍照、能录屏、能读日历、能发通知，因为它不需要自己实现 AI 的部分，它只是 Gateway 的一个终端节点。

这就是 Gateway 架构最精妙的地方。每一个客户端——无论是 macOS 菜单栏、iPhone、Android 手机、CLI、还是 Web UI——都只是一个连到端口 18789 的节点。它们共享同一个会话密钥 `main`，你在手机上说的话，Mac 上能接着聊。Gateway 甚至支持 Bonjour 自动发现——同一局域网里的设备不需要手动配置，它们会自己找到彼此。

一个月后，消息平台的膨胀催生了一个 232 个文件的 PR。所有消息平台从散落的代码被重构成了插件架构，每个平台变成一个自包含的模块，实现统一的接口。两天后 "Provider" 被重命名为 "Channel"——因为 Provider 同时也是"AI 模型提供商"的意思，两个概念撞车了。名字很小，但命名即思考。

从 CLI 脚本到分布式系统，从一个消息平台到十三个，从命令行到三个原生客户端——Gateway 是这一切的枢纽。没有它，OpenClaw 还是一个聊天机器人。有了它，OpenClaw 变成了一个操作系统的雏形。



## 记忆


一个能聊天的 AI 助手和一个真正有用的 AI 助手之间，隔着一层记忆。

1 月 12 日前后，OpenClaw 的记忆系统开始成形。设计哲学用一句话就能概括：Markdown 是真相之源，其他一切都是可重建的衍生品。

记忆的存储形式是 `~/.openclaw/workspace/memory/` 目录下的纯 Markdown 文件。每天一个 `YYYY-MM-DD.md`，追加写入，不做修改。还有一个可选的 `MEMORY.md` 用于长期记忆。没有专有格式，没有二进制数据库，用任何文本编辑器都能打开。如果你想知道 AI 助手"记得"什么，打开文件夹看就行了。

但纯文本搜不动。你不能指望 grep "Mac Studio" 能找到"运行 Gateway 的那台机器"。所以 OpenClaw 在 Markdown 之上建了一层索引——每个 Agent 一个 SQLite 数据库，存在 `~/.openclaw/memory/` 下面。文本被切成大约 400 token 的碎片，每个碎片生成一个向量嵌入，存进 SQLite。搜索的时候，向量相似度占七成权重，BM25 关键词匹配占三成，两条路径交叉验证。

嵌入模型的选择暴露了这个项目一贯的自托管执念。默认选项不是 OpenAI 的 API，而是一个 3 亿参数的本地 GGUF 模型——`embeddinggemma-300m`，大约 0.6 GB，用 `node-llama-cpp` 在你自己的机器上运行。你的记忆向量不需要离开你的电脑。如果你有 OpenAI 或 Gemini 的 API key，也可以用远程嵌入——但那是退路，不是默认。

记忆还有时间衰减。30 天半衰期——今天的记忆权重 100%，一周前 84%，一个月前 50%，三个月前只剩 12.5%。但有些文件永远不衰减：`MEMORY.md` 和非日期命名的文件被标记为 "evergreen"，像长期记忆一样常驻。短期记忆会褪色，核心记忆不会。

最重要的设计决策藏在一个看不见的地方：所有的索引都是可以重建的。删掉 SQLite 文件，重新跑一遍 `openclaw memory index`，一切恢复如初。真相永远在 Markdown 里。你可以换嵌入模型、换搜索算法、甚至换整个检索后端，只要那些 `.md` 文件还在，记忆就还在。数据和视图分离——这是最古老也最可靠的架构原则之一。



## 洪水


1 月 5 日，项目改名 Clawdbot。然后一切加速了。

一周内，Issue 编号从 #75 跳到 #485。知名开发者 @swyxio 跑来报了一个 Discord Gateway Error 4014。消息平台像潮水涌入——Telegram 和 Discord 之后，Signal、iMessage、Slack、MS Teams、Matrix、LINE、Nostr、Zalo 排着队来。

发布节奏变成了每周两到三个版本。steipete 一个人贡献了超过一万个 commit，占总数的三分之二。

也有些东西被拒绝了。PR #55[^14]，一个贡献者提交了完整的交互式安装向导，steipete 否了——"pnpm is not something we should enforce. That's a user choice." PR #86[^15]，Gemini 集成被拒——"I don't think Gemini is a good option for this agent, so don't wanna offer it in the onboarding flow." 技术上 Pi 运行时是支持 Gemini 的，他拒绝的不是技术能力，而是默认体验的品质门控。

这些拒绝背后藏着一种哲学。Issue #6[^16]，项目诞生的第四天，steipete 说过一句话：

> "This is a dangerous feature, so you decide. I don't set defaults here."

不替用户做决定。不设默认值。你想让 AI 在半夜自动检查电池电量，行。你想让它有 root 权限，行，但后果自负。这套哲学在用户从 1 涨到 100 的时候完美运作。但当 21.8 万人涌入时，它就绷不住了。



## 学会说"不"


1 月 29 日，项目第四次改名，定名 OpenClaw。之前是 Warelay、Clawdis、Clawdbot，中间还有一个只存在了三天的 Moltbot——德语 "molt"，蜕壳的意思。名字终于稳定了。但比名字更需要稳定的，是项目本身。

Issue #22151[^17]，一个用户的 Claude Max 5 小时套餐在 20 分钟内被烧光了。292 次 API 调用，1010 万 token 写入缓存，只有 440 万被读取，估计消耗超过 100 美元。用户没有做错任何事，是系统的缓存行为导致了资源浪费。在"你决定"的哲学下，没有保护性默认值，没有消费上限，没有"你确定要继续？"的提示。

2 月 1 日，核心维护者 sebslight——不是 steipete 本人——发布了 Issue #5799[^18]，标题是 "OpenClaw: Stabilisation Mode"：

> "We love the energy, but no human team can review at that pace and maintain quality. So we're locking down the core to make it rock solid."

> "The project is receiving approximately one pull request every two minutes."

每两分钟一个 PR。每小时三十个新 Issue。政策变化是剧烈的：新功能请求直接关闭，贡献者被引导去做 Skills。Discord 上有一个频道叫 `#pr-thunderdome-dangerzone`。

i18n 是压力最集中的战场。Issue #3460[^19]，64 条评论，社区渴望中文、日文、韩文支持。维护者的回应很诚实：

> "We don't currently have the bandwidth to properly support multiple languages."

但后面还跟了一句更深层的理由——"We cannot verify them and this project carries too much of a security risk." 一个能控制你电脑执行命令的 AI 助手，无法验证社区提交的翻译是否安全。万一有人在翻译里注入了恶意提示呢？

这时候，12 月 19 日种下的那颗种子终于发挥了作用。还记得那 15 行 `skills.ts` 吗？Skills 系统成了项目的减压阀。维护者反复说同一句话：

> "Most 'features' are really just skills. Write one, drop it in, done."

不需要改核心代码，不需要等 PR review，自己写一个 Skill 放进去就能用。当功能压力无法通过 review 流程消化时，这个架构层面的泄压阀就显得异常精妙——它把"拒绝贡献"变成了"换一种方式贡献"。



## 尾声


steipete 的哲学从 "you decide, I don't set defaults here" 变成了 "we're locking down the core to make it rock solid"。中间隔了九十天。

从一个人到八百多个贡献者。从 `spawn('claude')` 到 Tau RPC 到嵌入式多模型运行时。从 Twilio Webhook 到 Baileys 守护进程到 Gateway 调度中心。从没有记忆到 Markdown 日志到向量搜索。从一个消息平台到十三个，从命令行到三个原生客户端。四个名字，五十多个 Skills。

这不是背叛。这是长大。好比一个人开了一家路边摊，菜单上写着"你想吃什么我就做什么"。三个月后店门口排队排到了街尾，他不得不把菜单换成了固定的六道菜。不是他不想做了，是客人太多了。

但 `cli-runner.ts` 还在代码库里。那个原始的子进程调用——`spawn('claude', args)`——还在作为 fallback 路径存在着。

15,579 个 commit 的繁华之下，那 511 行代码的幽灵仍在呼吸。

---

*数据来源：OpenClaw Git 仓库（15,579 commits, 847 contributors）、GitHub Issues（11,058）、GitHub PRs（11,991）、CHANGELOG.md、源码。所有引用均来自公开的 GitHub 讨论和 commit 记录。*

## 参考资料
