自己实现一个 OpenClaw - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
biubiu3000
V2EX    程序员

自己实现一个 OpenClaw

  •   biubiu3000
    WarrenJones 3 小时 24 分钟前 577 次点击

    大家都在装 OpenClaw ,我选择自己实现一个

    与其 clone 一个跑不起来的庞然大物,不如从零造一个真正理解的 Agent 。


    背景:为什么不直接用 OpenClaw ?

    最近 OpenClaw (开源 Agent 框架)在圈子里火了。不少人 clone 下来,配好环境变量,跑起来然后呢?

    说实话,大部分人(包括我)的体验是这样的:

    • clone → 安装依赖 → 配置一堆环境变量 → 跑起来了
    • 然后……不知道改哪里,不知道每个模块在干什么
    • 想加个工具?不知道从何下手
    • 出了 bug ?日志看不懂,架构理不清

    装了一个 Agent ,但并没有理解 Agent 。

    所以我换了个思路:不装 OpenClaw ,而是自己从零实现一个轻量版。

    我给它取名 LiteClaw一个用 TypeScript 从零构建的 Agent ,目标是一步步复刻 OpenClaw 的核心能力,每一步都可运行、可理解。


    LiteClaw 是什么

    LiteClaw 不是 OpenClaw 的 fork ,也不是它的简化版。它是一个面向学习的 Agent 构建教程

    • 完全用 TypeScript 编写
    • 通过飞书机器人作为交互入口(不需要搭前端)
    • 接入本地 OpenAI-compatible 模型( Qwen 、DeepSeek 等)
    • 按 Phase 分阶段递进,每个阶段都是完整可运行的

    最终目标是:走完所有 Phase 之后,你手上会有一个自己理解每一行代码的 Agent 。


    架构总览

    先看一张 Phase 3 完成后的整体架构图:

    LiteClaw Phase 3 Architecture

    整个系统由几个核心层组成:

    • 飞书接入层:长连接模式,本地开发不需要公网域名
    • 消息处理编排:命令路由 + Agent Loop 分发
    • Agent Loop:模型自主选择工具 → 执行 → 结果回传 → 多轮循环
    • Tool Registry:可扩展的工具注册体系
    • Conversation Store:Memory / Redis 可切换
    • Infrastructure:日志、错误分类、超时重试、限流

    分阶段实现路线

    这是 LiteClaw 最核心的设计理念:不一口气做完,而是分 Phase 递进。每个 Phase 解决一个核心问题,每个 Phase 都是可运行的。

    Phase 1:最小可运行链路

    目标:验证"消息能进来、模型能调用、结果能回去"。

    这一步只做最核心的事:

    1. 飞书长连接接收消息
    2. 调用本地模型生成回复
    3. 通过飞书 API 发送回复
    4. 按 chat_id 维护多轮上下文

    Phase 1 Architecture

    关键技术决策:

    • 飞书长连接而非 Webhook:本地开发不需要 ngrok 或公网域名
    • Vercel AI SDK + @ai-sdk/openai-compatible:统一的模型调用接口,适配任何 OpenAI-compatible 模型
    • 进程内 Map 做会话存储:最快启动,后续再换 Redis

    完成 Phase 1 之后,你已经有了一个能聊天的飞书机器人。

    Phase 2:Agent 基础设施

    目标:从"能跑的 demo"升级成"可持续迭代的服务底座"。

    一个真正的 Agent 不只是"能回复消息"。你还需要:

    • 持久化:重启不丢对话 → Redis Store
    • 可观测:出问题能定位 → 结构化 JSON 日志
    • 稳定性:外部调用有保护 → 超时 + 重试 + 限流
    • 可扩展:存储后端可替换 → 统一 Store 接口

    Phase 2 Architecture

    这一步的核心设计是 Store 抽象

    interface ConversationStore { getConversation(chatId: string): Promise<ConversationMessage[]>; appendExchange(chatId: string, userText: string, assistantText: string): Promise<void>; resetConversation(chatId: string): Promise<void>; // ... } 

    业务代码只依赖接口,底层是 Map 还是 Redis 完全透明。这个设计在 OpenClaw 中也是一样的依赖抽象,不依赖实现。

    Phase 3:工具调用 + Agent Loop ← 当前完成

    目标:让 Agent 从"会聊天"升级到"会做事"。

    这是 Agent 最关键的一步跃迁。Phase 3 之后,LiteClaw 不再只是一个聊天机器人,而是一个能自主决策并执行动作的 Agent 。

    核心能力:

    • 模型自主选择工具:LLM 通过 function calling 决定是否调用工具
    • 多轮 Agent Loop:工具执行 → 结果回传 → 模型再决策 → 循环
    • 3 个内置工具current_timelocal_statushttp_fetch

    Agent Loop Flow

    Agent Loop 是怎么工作的?

    用户: "现在北京几点了?" ↓ LLM 判断: 需要调用 current_time 工具 ↓ Runtime 执行: current_time({ timezone: "Asia/Shanghai" }) ↓ 工具返回: "2026/03/17 18:30:00" ↓ LLM 基于结果回复: "现在是北京时间 18:30 。" 

    我使用了 Vercel AI SDK 的 generateText + stopWhen(stepCountIs(N)) 来实现多轮循环,不需要手写 while loop 。同时保留了 LiteClaw 自己的 Tool Registry ,通过 toAISDKTools() 桥接层转换格式。

    新增工具只需 3 步:

    // 1. 创建工具文件 src/services/tools/my-tool.ts import { z } from "zod"; import type { LiteClawTool } from "../tools.js"; export const myTool: LiteClawTool = { name: "my_tool", description: "工具描述(给模型看的)", parameters: z.object({ query: z.string().describe("参数描述") }), async run(context) { // 你的逻辑 return { text: "结果" }; } }; // 2. 在 tools.ts 中注册 // 3. 完成。模型会自动发现并使用新工具 

    技术栈选择

    技术 选择 为什么
    Language TypeScript 类型安全,前后端统一
    Runtime Node.js 20+ 成熟稳定
    HTTP Hono 极轻量,适合做 Agent runtime
    AI SDK Vercel AI SDK (ai v6) 内置 tool calling + agent loop
    模型 OpenAI-compatible 适配 Qwen 、DeepSeek 等本地模型
    Schema Zod 工具参数验证,AI SDK 原生支持
    接入 飞书长连接 零公网依赖,本地即可联调
    存储 Memory / Redis 可切换,渐进式引入

    快速上手

    # 1. clone git clone https://github.com/WarrenJones/liteClaw.git cd liteClaw # 2. 安装依赖 pnpm install # 3. 配置 cp .env.example .env.local # 填入飞书 App ID/Secret + 本地模型地址 # 4. 启动 pnpm dev # 5. 飞书中给机器人发消息测试 # "现在几点了?" → 模型自动调用 current_time 工具 # "/status" → 查看运行时状态 # "/tools" → 查看已注册工具列表 

    后续路线

    Phase 3 完成后,LiteClaw 已经具备了 Agent 的核心骨架。后续还有三个大方向:

    Phase 4:记忆与状态管理

    当前的"记忆"只是最近 N 轮对话。真正的 Agent 需要:

    • 短期记忆:当前会话上下文(已有)
    • 长期记忆:跨会话的用户偏好、重要信息
    • 摘要机制:对话太长时自动压缩
    • 记忆裁剪:过期信息的回收策略

    Phase 5:任务执行与编排

    从"单轮对话"升级到"多步任务":

    • 任务拆解:把复杂请求拆成子步骤
    • 状态机:跟踪任务执行进度
    • 进度反馈:让用户知道当前在做什么
    • 任务恢复:中断后可以继续

    Phase 6:向 OpenClaw 能力对齐

    最终目标补齐完整 Agent 能力:

    • 完整的 Agent 编排系统
    • 更丰富的工具生态
    • 权限与审计机制
    • 卡片消息、文件处理、流式回复
    • 生产级部署与可观测性

    为什么我建议你也试试

    装 OpenClaw 当然没问题。但如果你想真正理解 Agent 是怎么工作的,我建议你也试试从零搭一个。

    你会发现:

    1. Agent 的核心并不复杂:本质就是 LLM + Tool Calling + Loop
    2. 基础设施比想象中重要:日志、超时、重试、限流这些"无聊的事"决定了你的 Agent 能不能稳定运行
    3. 分阶段构建是最好的学习路径:每个 Phase 都有明确目标,做完就有成就感
    4. 你对代码有完全的掌控力:想改就改,想加就加,不用在别人的代码里翻来翻去

    LiteClaw 的所有代码都在 GitHub 上,每个 Phase 都有独立的技术文档。欢迎 star 、fork 、提 issue 。

    GitHub: github.com/WarrenJones/liteClaw


    总结

    装 OpenClaw 自己实现 LiteClaw
    上手速度 快(如果环境配得对) 慢一些,但每一步都清楚
    理解深度 停留在使用层 深入到实现层
    可定制性 受框架约束 完全自由
    学习价值 学会了"怎么用" 学会了"怎么造"

    大家都在装 OpenClaw ,我选择自己实现一个。不是因为 OpenClaw 不好,而是因为造过一遍之后,你才真正拥有它。

    1 条回复    2026-03-17 13:36:34 +08:00
    kylehuangyu
        1
    kylehuangyu  
       2 小时 42 分钟前
    可以考虑加上一个运行沙箱的 phase
    https://github.com/algopian/chromeclaw // 贴个我的,欢迎交流
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5512 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 22ms UTC 08:18 PVG 16:18 LAX 01:18 JFK 04:18
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86