跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
JavaScriptNode.jsAI大前端

Clawdbot(Moltbot)源码部署实战:从环境搭建到 WebChat 验证

综述由AI生成记录了 Clawdbot(Moltbot)的源码部署全过程。主要涵盖在 Windows 环境下使用 WSL2 进行环境准备,安装 Node.js 及依赖,解决 node-llama-cpp 构建报错问题,通过自定义脚本完成项目构建。随后配置智谱 AI 模型及 WebChat 通道,处理 API 限额导致的无响应问题,并验证了工具调用及文件操作能力。提供了常用运维命令供参考。

孤勇者发布于 2026/4/6更新于 2026/5/2023 浏览
Clawdbot(Moltbot)源码部署实战:从环境搭建到 WebChat 验证

Clawdbot(Moltbot)源码部署实战

一、背景

最近技术圈关注较多的是 Clawdbot(后更名为 Moltbot),支持 WhatsApp、Telegram 等通道,可私有化部署。本文记录从源码拉取到环境搭建的完整过程及踩坑经验。

二、环境准备

Windows 环境下推荐优先使用 WSL2(Ubuntu/Debian 镜像)进行部署,原生 CMD 易报依赖错误。

  1. 启用 WSL2:在 Windows 功能中勾选'适用于 Linux 的 Windows 子系统'和'虚拟机平台',重启后安装 Ubuntu 22.04。
  2. 配置 WSL2:打开终端更新系统源(建议换阿里源),执行 sudo apt update && sudo apt upgrade -y。
  3. 安装 Git:执行 sudo apt install git,验证 git --version。

三、Node.js 安装与依赖

仓库文档要求 Node.js ≥ 22,建议使用 nvm 管理环境并切换至最新版本。

注意:版本低于 22 时 pnpm install 可能报错。

1. 拉取源码 & 装依赖

git clone https://github.com/openclaw/openclaw.git
cd openclaw
pnpm install

常见问题:安装时 node-llama-cpp 的 postinstall 脚本可能失败(错误码 3221225477)。该依赖仅用于本地嵌入,若使用远程模型(如 OpenAI)可忽略。解决方案是注释掉 package.json 中的 node-llama-cpp 依赖后重新运行 pnpm install。

2. 构建项目

先构建 UI:

pnpm ui:build

再构建主项目:

pnpm build

若在原生 Windows 上构建需 Bash 环境。检查是否有 Git Bash 可用,或在项目 /script 目录下创建 Node.js 版本的构建脚本 bundle-a2ui.mjs:

#!/usr/bin/env node
import { createHash } from "node:crypto";
import { promises as fs } from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { spawn } from "node:child_process";
import { promisify } from "node:util";

const spawnAsync = promisify(spawn);
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const ROOT_DIR = path.resolve(__dirname, "..");
const HASH_FILE = path.join(ROOT_DIR, "src/canvas-host/a2ui/.bundle.hash");
const OUTPUT_FILE = path.join(ROOT_DIR, "src/canvas-host/a2ui/a2ui.bundle.js");
const A2UI_RENDERER_DIR = path.join(ROOT_DIR, "vendor/a2ui/renderers/lit");
const A2UI_APP_DIR = path.join(ROOT_DIR, "apps/shared/OpenClawKit/Tools/CanvasA2UI");

async function checkDirExists(dir) {
    try {
        const stat = await fs.stat(dir);
        return stat.isDirectory();
    } catch {
        return false;
    }
}

async function walk(entryPath, files = []) {
    const st = await fs.stat(entryPath);
    if (st.isDirectory()) {
        const entries = await fs.readdir(entryPath);
        for (const entry of entries) {
            await walk(path.join(entryPath, entry), files);
        }
        return files;
    }
    files.push(entryPath);
    return files;
}

function normalize(p) {
    return p.split(path.sep).join("/");
}

async function computeHash() {
    const inputPaths = [
        path.join(ROOT_DIR, "package.json"),
        path.join(ROOT_DIR, "pnpm-lock.yaml"),
        A2UI_RENDERER_DIR,
        A2UI_APP_DIR,
    ];
    const files = [];
    for (const inputPath of inputPaths) {
        try {
            const stat = await fs.stat(inputPath);
            if (stat.isDirectory() || stat.isFile()) {
                await walk(inputPath, files);
            }
        } catch {
            // Path doesn't exist, skip
        }
    }
    files.sort((a, b) => normalize(a).localeCompare(normalize(b)));
    const hash = createHash("sha256");
    for (const filePath of files) {
        const rel = normalize(path.relative(ROOT_DIR, filePath));
        hash.update(rel);
        hash.update("\0");
        const content = await fs.readFile(filePath);
        hash.update(content);
        hash.update("\0");
    }
    return hash.digest("hex");
}

async function runCommand(command, args, options = {}) {
    return new Promise((resolve, reject) => {
        const proc = spawn(command, args, {
            ...options,
            stdio: "inherit",
            shell: false,
        });
        proc.on("close", (code) => {
            if (code === 0) {
                resolve();
            } else {
                reject(new Error(`Command failed with exit code ${code}`));
            }
        });
        proc.on("error", reject);
    });
}

async function main() {
    try {
        if (!(await checkDirExists(A2UI_RENDERER_DIR)) || !(await checkDirExists(A2UI_APP_DIR))) {
            console.log("A2UI sources missing; keeping prebuilt bundle.");
            process.exit(0);
        }
        const currentHash = await computeHash();
        let shouldBuild = true;
        try {
            const previousHash = await fs.readFile(HASH_FILE, "utf-8");
            const outputExists = await fs.access(OUTPUT_FILE).then(() => true).catch(() => false);
            if (previousHash.trim() === currentHash && outputExists) {
                console.log("A2UI bundle up to date; skipping.");
                shouldBuild = false;
            }
        } catch {
            // Hash file doesn't exist, need to build
        }
        if (shouldBuild) {
            console.log("Building A2UI bundle...");
            await runCommand("pnpm", ["-s", "exec", "tsc", "-p", path.join(A2UI_RENDERER_DIR, "tsconfig.json")]);
            await runCommand("pnpm", ["-s", "exec", "rolldown", "-c", path.join(A2UI_APP_DIR, "rolldown.config.mjs")]);
            await fs.writeFile(HASH_FILE, currentHash, "utf-8");
            console.log("A2UI bundle built successfully.");
        }
    } catch (error) {
        console.error("A2UI bundling failed. Re-run with: pnpm canvas:a2ui:bundle");
        console.error("If this persists, verify pnpm deps and try again.");
        console.error(error);
        process.exit(1);
    }
}
main();

重新构建项目:pnpm build。

四、配置 OpenClaw

直接运行向导:pnpm openclaw onboard --install-daemon。

  1. 快速配置:按提示选择 yes 和 quickstart。
  2. 配置模型:选择智谱 AI 等支持的模型。
  3. 配置 API Key:输入对应模型的 API Key。
  4. 配置 Channel:支持接入不同 App,国内微信暂不支持,可跳过并使用 WebChat 测试。
  5. 配置 Skills:可选内置技能,按空格选中,回车保存。部分技能需额外申请 Key。
  6. 配置 Hooks:暂时可跳过。

启动 Gateway Service 后,UI 应用也会自动启动。

五、问题排查

若发送消息无响应且控制台无报错,可能是模型限额导致。修改 openclaw.json 配置文件,将模型改为 Flash 版本或其他可用模型。

注意:修改后需重启 Gateway Service 生效。

pnpm openclaw gateway restart --allow-unconfigured

可使用 openclaw status 查看网关状态。

六、常用命令

  1. 查看状态:openclaw status
  2. 发送测试消息:openclaw message send --to +86xxxxxxxxx --message "测试 Clawdbot"
  3. 重置会话:openclaw agent --reset
  4. 检查问题:openclaw doctor
  5. 更新版本:openclaw update --channel stable

七、WebChat 测试

通过原生 UI WebChat 进行测试,验证工具调用能力。

  1. 读取文件能力:测试 Agent 调用工具读取系统文件。
  2. Computer Use 能力:测试 Agent 直接向系统写入文件。

可见其调用工具及 Computer Use 能力较强。

目录

  1. Clawdbot(Moltbot)源码部署实战
  2. 一、背景
  3. 二、环境准备
  4. 三、Node.js 安装与依赖
  5. 1. 拉取源码 & 装依赖
  6. 2. 构建项目
  7. 四、配置 OpenClaw
  8. 五、问题排查
  9. 六、常用命令
  10. 七、WebChat 测试
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 深入理解 Git 工作流程:从概念到实战选择
  • 行星减速器原理、计算与 C++ 实现
  • 分库分表无法解决无限扩容?聊聊单元化架构
  • 构建与 GitHub 深度集成的自动化工作流实战指南
  • Web 聊天室消息加解密方案详解
  • FFT 与 DFT 原理及算法解析
  • ROS 2 机器人运行与命令解析:海龟仿真器及 rqt 工具
  • OpenClaw 飞书机器人配置指南:聊天下达 AI 指令
  • Java核心语法:从变量到流程控制
  • Web 聊天室消息加解密方案详解
  • 理解 RAG 真实边界:Spring AI 三种架构落地实践
  • Web 聊天室消息加解密方案详解
  • Java 8 新特性:Stream API 使用指南
  • Web 聊天室消息加解密方案详解
  • 飞书 CLI 开源实战:AI 接管办公协作全流程
  • 机器人日志系统十年演进:从故障排查到核心数据资产
  • Spring Boot 药品进销存信息管理系统设计与实现
  • Web 聊天室消息加解密方案详解
  • Java 部署:滚动更新(K8s RollingUpdate 策略)
  • ROS 机器人仿真环境搭建与任务控制脚本实现

相关免费在线工具

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online