为什么 OpenClaw 和 Claude Code 都使用 Node.js

文章目录

    • 前言
    • 一、先认识两个真实的标杆项目
      • [1. OpenClaw:周末项目长成 37 万 Star 怪兽](#1. OpenClaw:周末项目长成 37 万 Star 怪兽)
      • [2. Claude Code:Anthropic 官方的命令行 Agent](#2. Claude Code:Anthropic 官方的命令行 Agent)
    • [二、技术取舍一:事件循环和 ReAct 推理循环是结构同构的](#二、技术取舍一:事件循环和 ReAct 推理循环是结构同构的)
    • [三、技术取舍二:流式输出是 Node.js 的主场](#三、技术取舍二:流式输出是 Node.js 的主场)
    • [四、技术取舍三:npm 生态在消息平台 SDK 上是降维优势](#四、技术取舍三:npm 生态在消息平台 SDK 上是降维优势)
    • [五、技术取舍四:TypeScript 已经是 LLM 的"母语"](#五、技术取舍四:TypeScript 已经是 LLM 的"母语")
    • [六、技术取舍五:ES Modules + 动态 import = 真正的热插拔](#六、技术取舍五:ES Modules + 动态 import = 真正的热插拔)
    • [七、拆解 OpenClaw 的完整 Agent 架构](#七、拆解 OpenClaw 的完整 Agent 架构)
      • [1. Gateway 是唯一控制平面](#1. Gateway 是唯一控制平面)
      • [2. SOUL.md:人类可读的人格定义](#2. SOUL.md:人类可读的人格定义)
      • [3. Context Compaction:滑窗压缩](#3. Context Compaction:滑窗压缩)
      • [4. ACP:Agent 间通信协议](#4. ACP:Agent 间通信协议)
    • [八、Python 没有退场,是和 Node.js 分工](#八、Python 没有退场,是和 Node.js 分工)
    • [九、什么场景反而不该选 Node.js?](#九、什么场景反而不该选 Node.js?)
      • [1. 企业内部 Agent 强依赖 Java/Spring 生态](#1. 企业内部 Agent 强依赖 Java/Spring 生态)
      • [2. GPU 密集的实时推理路径](#2. GPU 密集的实时推理路径)
      • [3. 重度依赖 LangChain / LlamaIndex 生态](#3. 重度依赖 LangChain / LlamaIndex 生态)
      • [4. 团队没有任何 Node.js 储备](#4. 团队没有任何 Node.js 储备)
    • 总结

前言

最近团队里有个讨论挺有意思------做 AI Agent 平台时,到底该选什么技术栈。

会议上 Java 老兵和 Python 拥趸吵了俩小时,结果有人甩出一张图:GitHub Star 数前十的 Agent 项目,九个是 TypeScript / Node.js。这就有点反常识了------Python 不是 AI 的主场吗?

带着这个问题翻了几个标杆项目的源码,发现这不是巧合,是工程选型上的必然。

结论先抛出来:Node.js 在 AI Agent 这个细分领域成为事实标配,背后是五个跑不掉的工程取舍------而不是社区情绪。

读完这篇你能搞明白:

  • OpenClaw(37 万 Star)和 Claude Code 在用什么样的真实技术栈
  • "事件循环"和"ReAct 推理循环"为什么在结构上是同构的
  • npm 生态对 Agent 项目意味着什么------为什么 Python 的同类 SDK 反而是短板
  • TypeScript 为什么被称作 LLM 的"母语"------这不是吹牛
  • Node.js 不适合做哪些 Agent 场景------架构师视角的边界判断

不管你是带 Java 团队往 AI 转的技术负责人,还是正纠结新项目选啥栈的架构师,这篇都值得看完。开拆。

一、先认识两个真实的标杆项目

聊技术选型之前,先把背景统一。下面这两个项目是当下 AI Agent 领域最值得拆解的标杆------一个是社区现象级开源项目,一个是 LLM 厂商官方出品。

1. OpenClaw:周末项目长成 37 万 Star 怪兽

OpenClaw 由奥地利程序员 Peter Steinberger(PSPDFKit 的作者,圈内有名的老兵)在 2025 年 11 月作为周末项目发布。最初叫 Clawdbot,因为商标冲突改名 Moltbot,三天后再改成现在的 OpenClaw。

定位很简单一句话------一个能自主做事的本地 AI Agent,把消息平台(Telegram、WhatsApp、Slack、Discord 等)当作用户界面,在你的本地机器上跑任务。

截止 2026 年 6 月,仓库已经是 37 万 Star、近 8 万 Fork 的规模,社区技能仓库 ClawHub 已经收录 1.3 万+ 第三方技能。这种增长速度在开源圈里已经不是"火"能形容的了。

它的 package.json 关键字段直接揭示了选型:

json 复制代码
{
  "name": "openclaw",
  "version": "2026.3.13",
  "license": "MIT",
  "bin": {
    "openclaw": "openclaw.mjs"
  },
  "type": "module",
  "exports": {
    ".": "./dist/index.js",
    "./plugin-sdk": {
      "types": "./dist/plugin-sdk/index.d.ts",
      "default": "./dist/plugin-sdk/index.js"
    },
    "./plugin-sdk/discord": "...",
    "./plugin-sdk/memory-core": "..."
  }
}

几个信号一目了然:

  • "type": "module" ------全栈拥抱 ES Modules,是当代 Node.js 的标准姿势
  • 入口是 .mjs,原生 ESM
  • 插件系统用 npm subpath exports 实现,而不是塞成巨石
  • 版本号 2026.3.13 是 CalVer(日历版本号),意味着发布节奏极快

仓库结构也很说明问题------除了 Node.js 主程序外,还配了 iOS(Swift)、macOS(Swift)、Android(Kotlin)三个原生客户端,以及 React + Vite 写的 Control UI。也就是说,这已经不是个简单的 CLI 工具,是一套全平台的 Agent 基础设施

2. Claude Code:Anthropic 官方的命令行 Agent

Claude Code 是模型厂商 Anthropic 自己出的 CLI Agent,分发方式很 Node.js 味儿:

bash 复制代码
npm install -g @anthropic-ai/claude-code

打开它的 npm 包描述能看到:engines.node >= 18,入口是 bin/claude.exe用户拿到的就是一个跑在 Node.js 上的 CLI------这一点和 OpenClaw 是一致的。

⚠️ 一个常见误解先澄清:你去 GitHub 仓库 anthropics/claude-code 看,会发现"主语言"显示 Python。但那些 Python 代码主要是构建脚本、issue 模板、文档工具 ,不是用户实际跑的那个 CLI。"选择 Node.js"指的是分发方式 + 用户机器上的运行时,不是源码用什么写的------这两件事经常被混为一谈。

把 OpenClaw 和 Claude Code 的关键字段放在一起对比,技术栈相似度高得惊人:

维度 OpenClaw Claude Code
版本管理 CalVer:2026.3.13 npm: @anthropic-ai/claude-code
运行时 Node.js(ESM 模式) Node.js
核心语言 TypeScript(31.6 万行) TypeScript(官方称约 90% 由 AI 编写)
包管理 pnpm + monorepo npm
构建工具 tsdown(新一代 TS bundler) ---
插件机制 npm 子路径导出 + extensions/ 目录 内置工具集
技能系统 SKILL.md(Markdown + YAML frontmatter) SKILL.md(同一套规范)
分发方式 npm install -g openclaw npm install -g @anthropic-ai/claude-code

两个完全独立的团队,在不到一年内做出来的 Agent,技术栈居然高度收敛。这不是抄袭,是被同一个工程现实推到了同一个选项上。

接下来一章一章拆这背后的取舍。

二、技术取舍一:事件循环和 ReAct 推理循环是结构同构的

Node.js 的事件循环(Event Loop)和 AI Agent 的 ReAct 循环(Reason + Act),在结构上几乎是同一种东西的两种说法:

复制代码
Node.js 事件循环:       事件队列 → 回调执行 → 异步 I/O → 回到事件队列
Agent ReAct 循环:       观察 Observe → 推理 Think(LLM)→ 行动 Act(Tool)→ 回到观察

这种对应不是文字游戏,是真实的技术映射:

  • Agent 等待 LLM 响应 ≈ Node.js 等待网络 I/O(都是异步非阻塞)
  • Agent 接收 tool_use 指令 ≈ Node.js 处理事件回调
  • Agent 流式接收 LLM 输出 ≈ Node.js Stream API(天作之合)
  • Agent 同时维护多个通道连接 ≈ Node.js 事件循环本身就是为高并发长连接设计的

OpenClaw 一个进程里要同时挂着 Telegram、Discord、WhatsApp、Slack 等多条长连接,对 Python 的 asyncio 已经是不小的工程挑战,对 Node.js 是默认模式。

架构师的视角 :选型最怕的就是运行时模型和业务模型对不上。Java 的线程池模型擅长 CPU 密集型同步任务,Python 的 GIL 在多 IO 场景里要靠 asyncio 重构整个调用栈,而 Node.js 的事件循环天然契合"等 LLM 回复 → 处理回调 → 触发下一个工具调用"这种业务节奏。这是结构性优势,不是单点性能。

三、技术取舍二:流式输出是 Node.js 的主场

现代 LLM 全部支持流式返回(SSE,Server-Sent Events),用户不必等整个回答生成完才看到内容。在 Node.js 里,这事和内置的 ReadableStreampipeline 是一体的:

typescript 复制代码
import Anthropic from '@anthropic-ai/sdk'

const client = new Anthropic()

// stream() 返回一个 AsyncIterable,原生 ES 语法直接遍历
const stream = await client.messages.stream({
  model: 'claude-sonnet-4-6',
  max_tokens: 1024,
  messages: [{ role: 'user', content: '分析这段代码' }],
})

for await (const chunk of stream) {
  if (chunk.type === 'content_block_delta') {
    process.stdout.write(chunk.delta.text)
  }
}

// 如果模型决定调用工具,从最终消息里取出
const finalMessage = await stream.finalMessage()
if (finalMessage.stop_reason === 'tool_use') {
  const toolUse = finalMessage.content.find(c => c.type === 'tool_use')
  // 调用真实工具,把结果反馈给下一轮 LLM
}

for await...of 是 ES2018 的原生语法,Node.js 14+ 全面支持,前端工程师写起来零学习成本。Python 那边要用 async for + httpx.aiter_lines() 加上一堆类型转换,能写但确实没这边顺手。

架构师视角 :评估一项语言是否"适合做 X",最重要的是看核心范式有没有内置支持,而不是看能不能写出来。 能写出来不等于适合做。Java 也能用 Project Reactor 写流式,但生态、心智模型、社区案例都比不上 Node.js 在这个场景下的开箱即用。

四、技术取舍三:npm 生态在消息平台 SDK 上是降维优势

OpenClaw 能在几周内集成 50+ 消息平台,根本原因不是团队多能打,是 npm 生态里官方/社区 SDK 的覆盖度太可怕了

平台 npm 包 维护方
WhatsApp baileys 社区活跃维护
Telegram grammy 官方推荐
Discord discord.js 官方维护
Slack @slack/bolt 官方维护
Matrix matrix-js-sdk Matrix 基金会官方
飞书/Lark @larksuiteoapi/node-sdk 字节官方

Python 在这些企业通讯平台上存在明显空白------大部分官方 SDK 都优先支持 Node.js,Python 版本要么社区维护、要么功能不完整。

这件事的根本原因是这些消息平台本身是事件驱动、长连接、JSON 消息为核心的应用,和 Node.js 的核心范式完全对味,所以官方倾向于先做 Node SDK。Python 那边的 SDK 主要服务的是数据分析和 Bot 自动化场景,对长连接编排的支持是后来才补的。

架构师视角 :选型时生态成熟度的权重远高于语言性能。一个语言要在某领域成为标配,必须有官方 SDK 厚度、活跃维护节奏、社区代码案例三件套同时具备。Node.js 在消息平台这块刚好都有。

五、技术取舍四:TypeScript 已经是 LLM 的"母语"

这是个会自我强化的循环:

复制代码
互联网上 JS/TS 代码海量 → LLM 训练数据里 JS/TS 占比极高
                                ↓
LLM 写 TypeScript 准确率最高 → 用 TypeScript 构建 AI 工具和框架
                                ↑
                          更多 TypeScript 流回互联网

OpenClaw 的工具调用 Schema(Function Calling)本质上就是一段 TypeScript 类型定义的 JSON 序列化版本:

typescript 复制代码
interface ToolDefinition {
  name: string
  description: string
  input_schema: {
    type: 'object'
    properties: Record<string, {
      type: string
      description: string
    }>
    required: string[]
  }
}

const bashTool: ToolDefinition = {
  name: 'bash',
  description: 'Execute a shell command and return stdout/stderr',
  input_schema: {
    type: 'object',
    properties: {
      command: { type: 'string', description: 'The shell command to execute' },
      timeout: { type: 'number', description: 'Timeout in milliseconds (default: 30000)' }
    },
    required: ['command']
  }
}

TypeScript 的静态类型让这种 Schema 在编辑器里就能检查错误,不用等到运行时崩才发现。这对 Agent 这种"工具调用密集型"应用是雪中送炭------一个 schema 写错,LLM 就会被错误信息带偏跑出难以排查的链路。

架构师视角 :跟"生态优势"是一回事的另一面------当 LLM 自己擅长写某种语言时,你用这种语言搭工具,AI 的辅助质量会高一档。这件事会让选型逻辑出现"赢者通吃"的滑坡,未来几年值得持续观察。

六、技术取舍五:ES Modules + 动态 import = 真正的热插拔

OpenClaw 的插件系统能在不重启 Gateway 的情况下加载新扩展,靠的就是 Node.js ESM 的 import() 动态导入:

typescript 复制代码
// OpenClaw 插件加载逻辑(简化版,源码思路一致)
async function loadExtensions(extensionsDir: string) {
  const entries = await fs.readdir(extensionsDir)
  for (const entry of entries) {
    const pkgPath = path.join(extensionsDir, entry, 'package.json')
    const pkg = JSON.parse(await fs.readFile(pkgPath, 'utf-8'))

    if (pkg.openclaw?.extensions) {
      for (const entryPoint of pkg.openclaw.extensions) {
        // 动态 import:ESM 原生支持,无需重启
        const module = await import(path.join(extensionsDir, entry, entryPoint))
        module.register(gateway)
      }
    }
  }
}

Node.js 16+ 对 import() 的支持已经是生产级别。安装新技能后服务无需重启,对于面向终端用户的本地 Agent,这种"扩展即装即用"的体验是核心壁垒。

架构师视角 :Java 阵营里要做这种热插拔得搬出 OSGi 或自定义 ClassLoader 才能搞,复杂度直线飙升。Python 的 importlib 能动态加载但缺乏作用域隔离。Node.js 在这件事上是少有的默认行为就足够好的语言

七、拆解 OpenClaw 的完整 Agent 架构

把上面五个技术点的取舍放在一起看,OpenClaw 的整体架构就好理解了:

复制代码
[输入层]              [Gateway 控制平面]            [Agent 执行引擎]           [工具层]
CLI                                                 Context 构建              Bash 执行
WebChat            ┌──────────────────┐            LLM 调用                  文件操作
Telegram   ───────▶│ WebSocket RPC   │───────────▶ ReAct 循环 ──────────────▶ 浏览器自动化
WhatsApp           │  Server         │            (Observe-Think-Act)        HTTP 请求
Discord            │ Session Manager │             tool-catalog              Sub-Agent
iOS/macOS App      └──────────────────┘            tool-policy               Skills (SKILL.md)
                                                        │
                                                        ▼
                                                  [记忆层]
                                                  SOUL.md(人格 + 长期记忆)
                                                  Markdown 文件(默认存储)
                                                  LanceDB(可选向量记忆)
                                                  Context Compaction(滑窗压缩)

几个值得拆解的设计:

1. Gateway 是唯一控制平面

所有客户端------iOS/macOS 原生 App、Android、浏览器 UI、CLI------全部通过 WebSocket RPC(自定义 Protocol v3) 连到 Gateway。这种设计让业务逻辑只有一份,新增平台只需要做一个支持 WebSocket RPC 的客户端壳即可。

对企业落地的启示------多端 Agent 一定要避免把业务逻辑分散到各端,否则版本迭代会变成灾难。

2. SOUL.md:人类可读的人格定义

这是 OpenClaw 最有想法的设计之一。Agent 的"人格"不是存在向量数据库或者参数文件里,而是一个纯 Markdown 文件

markdown 复制代码
# My Assistant's Soul

## Identity
You are a personal AI assistant running locally on this machine.
Your owner is [name]. You help with coding, research, and daily tasks.

## Personality
- Concise and direct in responses
- Proactive about suggesting better approaches
- Honest about limitations

## Long-term Memory
- Owner prefers TypeScript over JavaScript
- Preferred editor: Neovim
- Current project: Building an e-commerce platform with Next.js

## Behavioral Rules
- Always ask before deleting files
- Never send messages to external services without confirmation
- Keep responses under 200 words unless asked for detail

每次对话开始时这段被注入 System Prompt。设计哲学很值------对于个人 AI 助手,人类可读性 > 技术复杂性。你随时能打开文件夹检查你的 Agent 记住了什么,避免黑盒焦虑。

3. Context Compaction:滑窗压缩

LLM 的 context window 即使 200K tokens 也是有限的。OpenClaw 在 src/agents/ 里做了上下文压缩:超过阈值时调用 LLM 把前 N 轮对话总结成摘要,注入 System Prompt 后释放旧 tokens。

架构师视角:这是 Agent 长期运行的必选项。任何 Agent 平台只要打算服务真实用户超过一周,都绕不开 context compaction 的设计。

4. ACP:Agent 间通信协议

OpenClaw 2026 版本引入了 ACP(Agent Communication Protocol),让多个 Agent 之间能协作------研究助手发现需要写文档时,把任务委托给写作助手,写作助手完成后把结果回传。

这是 Agent 系统从"单体"走向"多智能体"的标志性设计。

八、Python 没有退场,是和 Node.js 分工

澄清一个常见误解:Node.js 在 Agent 领域兴起,不代表 Python 在 AI 系统中失势。 两者在能力上是清晰互补的:

维度 Node.js 的主场 Python 的主场
多通道消息路由
实时流式响应 ⚠️ 能做但费劲
工具调用编排
插件热加载 ⚠️ 缺隔离
多平台 SDK
模型推理
Embedding 计算
RAG 管道 ⚠️ 在追赶 ✅(LangChain/LlamaIndex)
数据科学
科学计算

实际企业里两者的分工长这样:

复制代码
用户消息 ─▶ OpenClaw Gateway (Node.js)
                │
                ├─▶ Anthropic / OpenAI API(普通任务)
                ├─▶ LanceDB(Rust + Node binding,向量检索)
                ├─▶ Python FastAPI 微服务(复杂数据分析)
                └─▶ Stable Diffusion API(Python,图像生成)

OpenClaw 本身就内置了这种分工------extensions/memory-lancedb 这个扩展,TypeScript 编排上层,底下调用 Rust 编写的 LanceDB 做向量计算。三层栈协同:TypeScript 调度 → Rust 计算 → 向量存储

架构师视角 :单一语言能解决所有问题的时代已经过去了。现代 AI 系统的常态是多语言协同------Node.js 在边缘做接入和编排,Python/Rust/Go 在后端做计算。技术总监们要做的是建立明确的服务边界,而不是强求统一栈。

九、什么场景反而不该选 Node.js?

讲完了五个 Node.js 占优的理由,我得给个边界说明------架构师的本职是知道工具的边界,而不是无脑推荐。下面四个场景,我会优先考虑别的栈:

1. 企业内部 Agent 强依赖 Java/Spring 生态

如果你的 Agent 要深度集成公司内部的 Spring Boot 微服务、用现有的 OAuth/SSO 体系、复用已有的 RBAC 权限模型,直接基于 Spring AI 做 Agent 会比新搭一套 Node.js 栈成本低。Spring AI 1.0 之后对 Function Calling 和 ChatClient 流式响应都有内置支持,不至于像几年前那么割裂。

2. GPU 密集的实时推理路径

如果 Agent 的核心动作是本地调用大模型推理(比如本地 Llama / Qwen),那么 Python + vLLM / TGI 的链路会比 Node.js 调 Python 子进程更直接。Node.js 在这种场景下只适合做前置的请求路由层。

3. 重度依赖 LangChain / LlamaIndex 生态

LangChain 的 JS 版本(langchain.js)的成熟度和文档质量,跟 Python 版本差着一代。如果你的 Agent 要大量复用 LangChain 的 Chain 组合、Memory 实现、Retriever 模式,用 Python 是更务实的选择

4. 团队没有任何 Node.js 储备

技术选型不能脱离团队现实。一个全是 Java 工程师的团队,硬上 Node.js 做生产 Agent,前三个月会被 ESM / CommonJS 互操作、tsconfig 配置地狱、undefined is not a function 这类坑反复教做人。先评估 ramp-up 成本再决定要不要切栈

总结

回到开头那个问题------为什么 OpenClaw 和 Claude Code 都使用 Node.js?

不是某个团队特别有眼光,是工程现实把所有人推到了同一个选项上:

  1. 运行时模型契合业务模型 ------事件循环和 ReAct 推理循环是结构同构的
  2. 流式输出是原生主场 ------SSE / for await / ReadableStream 一体集成
  3. npm 生态在消息平台上是降维优势 ------Python 在这块是明显短板
  4. TypeScript 是 LLM 的母语 ------AI 写 TypeScript 准确率最高,自我强化
  5. ES Modules + 动态 import 等于真正的热插拔 ------其他语言要做到这点都得搬重武器

选型不是站队 ------Python 在模型推理和 RAG 管道上仍然不可替代,Java 在企业内部 Agent 集成上仍然有它的位置。正确的姿势是分清边界、做好分工:Node.js 在前端接入和编排,Python/Rust/Go 在后端计算。

时代变快了。但每一个选型背后,依然是同样朴素的工程逻辑------让运行时模型和业务模型贴近,让语言生态服务于业务需求,让团队能力决定栈的厚度。这些原则没变过。

如果你正在做 Agent 平台的选型,欢迎评论区聊聊你的判断和踩坑。

相关推荐
沉默王二2 小时前
又一个神级 Codex Skill 诞生了!
agent·ai编程
袁煦丞 cpolar内网穿透实验室2 小时前
飞书+龙虾!摄影师局域网外使用龙虾实例!
飞书·远程工作·内网穿透·cpolar·摄影师·openclaw·安全内网链接
小lan猫2 小时前
用 AI Agent 让购物更便捷:LumiGlow 电商网站实践
前端框架·llm·agent
绕过江河错落2 小时前
深度拆解 Claude Code 系列(七):可观测性与成本控制
agent
小小龙学IT2 小时前
告别 Node.js?Bun 2.0 深度解析
node.js
一条泥憨鱼2 小时前
Codex App 从0到1完整入门教程
经验分享·agent·开发·codex
Aolith3 小时前
Express + TypeScript 下写 JWT 中间件,我踩了三个坑
typescript·node.js·express
sg_knight3 小时前
Claude Code、Cursor、Copilot、openCode,到底怎么选
llm·copilot·agent·claude·code·codex·claude-code
AC赳赳老秦3 小时前
技术文章素材收集自动化:用 OpenClaw 自动爬取行业资讯、技术热点、优质文章
运维·开发语言·python·自动化·wpf·deepseek·openclaw