1. 刚克隆完 OpenClaw,我盯着 src 目录愣了十分钟
你刚把 OpenClaw 仓库拉到本地,cd进去,ls一下,看到src/下面躺着gateway、agents、channels、memory、skills、plugins、routing、security、ui这一串目录,每个目录里又是十几二十个文件。这时候最想干的事其实不是读代码,而是先搞清楚:OpenClaw 的目录结构到底怎么划分的,哪个目录是入口,哪个目录是核心,模块之间谁调谁。没有这张“地图”,你打开server.ts看两百行就会开始怀疑人生。
这篇就是给刚接触 OpenClaw 的开发者准备的源码起步指南。我会从仓库根目录出发,把src/核心目录逐个拆开讲清楚职责边界,给出一份可以直接对照的目录速查表,再补上模块依赖关系和本地验证命令。同时,源码阅读过程中你一定会想跑起来验证某个模块的行为,这时候如果每个模型调用都要单独配一套 Key,调试节奏会被打断。所以我会顺带说明怎么用 TaoToken 统一 Key 和 API 通道,让后续的调试与验证有一个稳定入口,不用在多个配置之间来回切换。
整篇内容基于 OpenClaw 2026.3.2 源码结构整理,目录名和关键文件名都是真实存在的,你可以直接对着自己的仓库跟读。读完之后,你至少能做到:看到任意一个文件路径,能判断它属于哪个模块层;想改某个功能,知道该去哪个目录找;想跑验证,知道命令怎么写、Key 从哪里统一出。
2. 先把 TaoToken 的 Key 和通道准备好,再进源码
源码阅读和调试是两件事。读代码可以纯静态看,但一旦你想验证某个模块的实际行为,比如让agents/里的执行引擎真的跑一次工具调用,或者让channels/里的适配器收一条消息,就需要一个能用的模型 API 通道。OpenClaw 本身是模型无关的架构,它不绑定某一家模型服务,所以你完全可以用统一的 Key 来对接。
TaoToken 在这里的角色就是一个统一入口:你拿到一个 Key,配好 API 地址,OpenClaw 里所有需要模型调用的模块都走这个通道。这样你在读agents/和skills/的时候,不用因为换模型而改一堆配置。
具体操作分三步。第一步,打开官网https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=注册账号,然后在控制台里创建一个 API Key。第二步,进入 API Keys 管理页面https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite,复制你刚创建的 Key。第三步,如果你后面要跑编码类 Agent 或者长时间挂着的调试任务,可以看一下 Coding Plan 页面https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite,选一个适合自己使用强度的方案。
API 的基础地址是https://taotoken.net/api,这个地址不加 UTM 参数,直接用在配置文件里。你可以在 OpenClaw 的环境变量或者配置文件中这样写:
# .env 或 shell 配置 TAOTOKEN_API_KEY=sk-你的实际Key TAOTOKEN_BASE_URL=https://taotoken.net/api配好之后,OpenClaw 里所有走模型调用的模块都会通过这个通道出去。你在读agents/pi-embedded-runner/run.ts的时候,看到它调用模型的地方,实际请求就是发往这个地址。这样你在源码里追踪一条消息从进入到返回的完整链路时,模型调用这一段是可控、可复现的。
注意:Key 不要硬编码在源码文件里,用环境变量或者独立的配置文件管理,避免提交到仓库。
3. OpenClaw 目录结构速查表与模块边界
现在进入正题。我把src/下面的核心目录整理成一张速查表,你可以直接对照自己的仓库看。每个目录我只讲职责边界和关键文件,不逐行展开,目的是让你先建立“哪个目录管什么”的认知。
3.1 src/ 核心目录逐层拆解
先看整体结构。OpenClaw 的src/采用单一职责划分,每个目录对应一个明确的模块层:
src/ ├── gateway/ # 控制平面:服务启动、连接管理、全局路由 ├── agents/ # 核心执行引擎:AI 逻辑、工具调用、沙箱 ├── channels/ # 平台适配器:各外部平台的消息收发 ├── cli/ # 命令行工具:启动、初始化、更新 ├── memory/ # 记忆存储:向量数据库、长期记忆 ├── skills/ # 内置技能:原生工具能力 ├── plugins/ # 插件系统:扩展 SDK 与第三方集成 ├── routing/ # 消息路由:模块间转发与分发 ├── security/ # 安全工具:加解密、权限校验 ├── ui/ # Web UI:可视化界面组件 └── index.ts # 主入口:模块统一导出这张表就是你读源码时的第一层导航。下面逐个说关键文件。
gateway/是控制平面,你可以理解成项目的大脑。server.ts是 WS 和 HTTP 双协议的主服务器入口,server-startup.ts负责服务启动时的配置加载和模块初始化,server-channels.ts做 20 多个平台通道的统一注册。auth/目录放的是挑战-应答式身份认证逻辑,sessions/用 SQLite 做会话持久化。你读启动流程,就从server-startup.ts开始追。
agents/是核心执行引擎,项目灵魂所在。pi-embedded-runner/run.ts里的runEmbeddedPiAgent()是运行时主入口,subscribe.ts处理流式数据订阅。tool-policy-pipeline.ts是工具调用的安全策略管道,做权限和风险校验。subagent-spawn.ts负责子 Agent 的动态生成,sandbox/封装隔离执行环境。你读 AI 业务逻辑,重点就在这个目录。
channels/是多平台适配器层。每个平台一个子目录,比如telegram/、whatsapp/、slack/、discord/,里面各自实现消息收发和事件解析。这一层的特点是“可插拔”,新增平台只需要新建一个目录,不用动核心代码。
cli/是命令行工具集。commands/放子命令实现,比如 gateway 启动、onboard 初始化、update 更新;wizard/是交互式配置向导。你平时敲的命令,最终都落到这里。
memory/是向量记忆存储。sqlite-vec/是基于 SQLite 的向量数据库实现,轻量、本地化。AI 的长期记忆能力就靠这一层支撑。
skills/是内置技能库。time.ts、weather.ts这类文件就是原生工具技能的实现,每个技能封装一个能力,提供给 AI 调用。
plugins/是插件系统。plugin-sdk/里是插件开发 SDK,包含开发规范和 API。你想做二次开发,从这里入手。
routing/是消息路由核心逻辑,负责模块间的消息转发和分发。security/是安全工具集,ui/是 Web UI 前端组件,canvas-host/是画布宿主组件。
3.2 顶级非 src 目录与文件
除了src/,根目录还有几个关键文件你需要知道。openclaw.mjs是 CLI 工具的全局入口,所有命令行操作的总调度。apps/放跨平台伴侣 App 源码,Swift/iOS 和 Kotlin/Android 各一套。Dockerfile.sandbox*是沙箱运行环境的镜像定义。docs/是官方文档,VISION.md讲设计哲学和发展规划,SECURITY.md讲安全规范和漏洞上报方式。
读源码之前先翻VISION.md,这一步能帮你理解项目为什么这样划分模块,避免“为了看源码而看源码”。
3.3 模块依赖关系:谁调谁
把目录职责搞清楚之后,下一步是理解模块之间的调用关系。OpenClaw 的依赖方向大致是这样的:
openclaw.mjs (CLI 入口) └── cli/commands/ (命令解析) └── gateway/server.ts (主服务启动) ├── gateway/server-startup.ts (配置与模块加载) │ ├── gateway/auth/ (身份认证) │ ├── gateway/sessions/ (会话管理) │ └── gateway/server-channels.ts (通道注册) ├── channels/ (平台适配器) │ └── 各平台子目录 ├── routing/ (消息路由) │ └── agents/ (执行引擎) │ ├── pi-embedded-runner/run.ts │ ├── tool-policy-pipeline.ts │ └── sandbox/ ├── memory/ (记忆存储) │ └── sqlite-vec/ ├── skills/ (内置技能) └── plugins/ (插件系统) └── plugin-sdk/这张图的关键信息是:入口在 CLI,调度在 gateway,执行在 agents,适配在 channels,存储在 memory,扩展在 skills 和 plugins。你读代码时,顺着这个方向追,就不会迷路。
4. 可复制的本地验证命令与配置
光看目录不够,你得能跑起来验证。这一节给你可以直接复制的命令和配置,让你在本地把 OpenClaw 跑起来,并且确认模型通道走的是你配好的 TaoToken 地址。
4.1 克隆与依赖安装
# 克隆仓库 git clone https://github.com/openclaw/openclaw.git cd openclaw # 查看当前版本,确认与本文结构一致 cat package.json | grep version # 安装依赖(根据项目实际包管理器选择) npm install # 或 pnpm install安装完成后,先别急着启动。把上一节配好的环境变量确认一遍:
# 确认环境变量已生效 echo $TAOTOKEN_API_KEY echo $TAOTOKEN_BASE_URL如果输出为空,说明你的 shell 没有加载配置文件。可以临时 export 一下:
export TAOTOKEN_API_KEY=sk-你的实际Key export TAOTOKEN_BASE_URL=https://taotoken.net/api4.2 启动 Gateway 并验证模块加载
OpenClaw 的启动入口是openclaw.mjs,你可以直接用它启动 gateway:
# 启动 gateway 服务 node openclaw.mjs gateway start # 或者用项目提供的脚本 npm run gateway:start启动过程中,server-startup.ts会依次加载配置、初始化模块、注册通道。你可以在终端看到加载日志,重点观察这几行:
[gateway] loading config... [gateway] initializing auth module... [gateway] initializing sessions module... [gateway] registering channels... [gateway] server listening on port 3000如果卡在某个模块,说明那个模块的配置有问题。比如卡在registering channels,就去检查channels/下你启用的平台配置。
4.3 验证模型通道是否走通
启动成功后,你可以用一个简单的请求验证模型通道。OpenClaw 的agents/模块会通过你配置的 API 地址调用模型。你可以直接对 TaoToken 的 API 地址发一个测试请求:
curl -X POST https://taotoken.net/api/v1/chat/completions \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "claude-sonnet-4-20250514", "messages": [{"role": "user", "content": "ping"}], "max_tokens": 10 }'如果返回正常的 JSON 响应,说明 Key 和通道都没问题。这时候你再回到 OpenClaw 里跑 Agent 任务,模型调用就会走这个通道。
如果你想在 OpenClaw 内部验证,可以找到agents/pi-embedded-runner/run.ts,在runEmbeddedPiAgent()的调用处加一行日志,确认它请求的 base URL 是你配置的地址。这样你在读源码的时候,能直观看到模型调用发生在哪一行。
4.4 目录速查命令
读源码时经常需要快速定位文件。这几个命令可以帮你:
# 查看 src 下所有目录 ls -d src/*/ # 查看 gateway 模块所有文件 find src/gateway -type f -name "*.ts" | head -30 # 搜索某个函数的定义位置 grep -rn "runEmbeddedPiAgent" src/ # 查看模块间的 import 关系 grep -rn "from '../agents" src/gateway/这几个命令配合前面的目录速查表,基本能覆盖你起步阶段的定位需求。
5. 读源码时最容易卡住的几个报错
这一节整理几个新手读 OpenClaw 源码和跑验证时常见的卡点。每个都给出原因和排查方向。
5.1 启动时报 “Cannot find module”
这个报错通常出现在你直接node src/gateway/server.ts的时候。原因是 OpenClaw 的模块路径依赖项目根目录的构建配置,直接跑单个文件会找不到相对路径。正确做法是从openclaw.mjs入口启动,或者用项目提供的 npm script。如果你确实想单独调试某个模块,先确认tsconfig.json里的paths配置,再用ts-node加-r tsconfig-paths/register跑。
5.2 模型调用返回 401 或 403
如果你在验证模型通道时收到 401,先检查TAOTOKEN_API_KEY是否复制完整,有没有多余空格。403 通常是 Key 权限问题,去控制台确认这个 Key 有没有被禁用或者额度耗尽。还有一种情况是 base URL 写错了,注意 API 地址是https://taotoken.net/api,不要多加/v1后缀,具体路径由请求本身决定。
5.3 通道注册失败 “channel already registered”
这个报错出现在server-channels.ts注册通道的时候。原因是你可能在配置里重复启用了同一个平台,或者上一次启动的进程没有完全退出,端口还被占用。排查方法:先lsof -i :3000看端口占用,杀掉残留进程;再检查配置文件里channels列表有没有重复项。
5.4 读 agents 模块时找不到执行入口
很多人打开src/agents/之后,看到一堆文件不知道从哪读起。记住一个入口:pi-embedded-runner/run.ts里的runEmbeddedPiAgent()。这是 Agent 执行的主入口,你从这里往下追,能看到它怎么调tool-policy-pipeline.ts做安全校验,怎么调sandbox/做隔离执行。不要一上来就逐个文件读,先抓住主入口。
5.5 会话数据找不到或 SQLite 报错
gateway/sessions/用 SQLite 做持久化。如果你在验证时发现会话数据读不出来,先确认 SQLite 文件路径。默认情况下它会在项目的数据目录下生成.db文件。检查这个文件是否存在、是否有写权限。如果报 “database is locked”,说明有另一个进程在占用,关掉其他 OpenClaw 实例再试。
6. 把地图用起来,从读目录到改模块
到这里,OpenClaw 的目录结构和模块边界你应该有了一张清晰的图。回顾一下核心路径:从openclaw.mjs入口进,经cli/commands/解析,到gateway/server.ts启动,由server-startup.ts加载auth/、sessions/、server-channels.ts,再往下分发到channels/、routing/、agents/、memory/、skills/、plugins/。每个目录职责单一,依赖方向明确。
接下来你可以按需求深入。想做平台适配,重点看channels/和gateway/server-channels.ts;想扩展 AI 能力,看skills/和agents/;想做本地化部署,看memory/和Dockerfile.sandbox*。读的时候用第 4 节的命令快速定位,用第 5 节的排查思路解决卡点。
如果你在调试过程中需要频繁验证模型调用,记得把 TaoToken 的 Key 和 API 地址配好,统一通道能省掉很多切换配置的时间。模型对话验证可以直接用https://taotoken.net/api/v1/chat/completions测通,接入文档在https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite可以查到更细的参数说明。长期跑编码类 Agent 的话,Coding Plan 页面https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite里有适合持续调试的方案。
源码地图的价值在于,你下次打开 OpenClaw 的任何文件,都能立刻判断它在整个项目里的位置和职责。这比逐行读代码的效率高得多。