一步步用 TypeScript 构建一个轻量版 OpenClaw Agent —— 从最小链路到完整工具调用。
Build a lightweight OpenClaw agent step by step in TypeScript — from minimal chat to full tool-calling capabilities.
LiteClaw 是一个面向学习和实践的 Agent 项目。它不是对 OpenClaw 的完整复刻,而是一个可以跟着做的、从零到一的 Agent 构建教程:
- Phase 1 — 先打通最短链路:飞书消息 → 本地模型 → 回复
- Phase 2 — 补齐基础设施:持久化、日志、错误处理、限流
- Phase 3 — 实现 Agent 核心:模型自主调用工具 + 多轮 Agent Loop
- Phase 4 — 记忆管理:会话摘要 + 用户事实提取 + 动态 Prompt
- Phase 5 — 任务编排:多步任务分解 + 顺序执行 + 进度反馈 + 结果合成 ← 当前已完成
每个 Phase 都是可运行的,你可以从任意阶段开始理解和实验。
- 飞书接入层:长连接(默认)+ Webhook 备用
- 消息处理编排:Command Router 处理命令,普通消息进入 Memory Pipeline → 编排门控 → Agent Loop
- Memory Pipeline:获取历史 → 条件摘要 → 动态 Prompt 构建 → 事实提取(异步)
- 任务编排:Task Planner 判断是否多步 → Orchestrator 顺序执行子任务 → 进度反馈 → 合成汇总
- Agent Loop:Vercel AI SDK 的
generateText+stopWhen自动管理多轮工具调用 - Tool Registry:
toAISDKTools桥接层,6 个内置工具 - Conversation Store:Memory / Redis 可切换,支持消息、摘要、用户事实
- Infrastructure:日志、错误分类、超时重试、限流等基础设施
- 飞书接入:长连接模式(无需公网域名)+ webhook 备用
- 模型调用:任意 OpenAI-compatible 本地/私有模型
- Agent Loop:模型自主选择工具 → 执行 → 结果回传 → 多轮循环
- 6 个内置工具:
local_status— 查看运行时状态current_time— 获取当前时间(支持时区)http_fetch— 受控 HTTP GET(支持域名白名单)weather— 查询城市天气(和风天气 API)code_exec— 在沙箱中执行 JS / Shell 代码feishu_doc_search— 搜索飞书云文档
- 记忆管理:
- 会话摘要 — 消息超阈值时 LLM 自动生成增量摘要
- 用户事实 — 异步提取姓名、偏好等,跨会话保留
- 动态 Prompt — base + summary + facts 自动拼装
- 多步任务编排:
- Task Planner — LLM 自动判断是否需要拆分多个子任务
- Task Orchestrator — 顺序执行子任务,失败不中断(Graceful Degradation)
- 进度反馈 — 每个子任务执行时发送飞书进度消息
- 结果合成 — LLM 自动汇总所有子任务结果为连贯回复
- 单元测试:Vitest 测试框架,96 个用例覆盖核心模块
- 会话管理:按 chat_id 维护上下文,支持 Memory / Redis 切换
- 命令路由:
/help、/reset、/forget、/status、/tools - 基础设施:结构化日志、错误分类、超时重试、限流、事件去重
- 卡片消息 / 文件处理 / 流式回复
- 并行子任务执行
- 飞书加密事件解密
- Node.js
20+ pnpm- 已开通机器人和事件订阅的飞书应用
- 一个本地或私有部署的 OpenAI-compatible 模型服务(需支持 function calling)
pnpm installcp .env.example .env.local将你自己的本地配置写入 .env.local,不要提交该文件。
核心配置项:
# 飞书
FEISHU_APP_ID=your-feishu-app-id
FEISHU_APP_SECRET=your-feishu-app-secret
FEISHU_CONNECTION_MODE=long-connection
# 模型(需支持 function calling)
MODEL_BASE_URL=http://localhost:8000/v1
MODEL_API_KEY=your-local-model-api-key
MODEL_ID=your-model-id
# Agent Loop
MAX_TOOL_ROUNDS=5 # 单次对话最大工具调用轮次
TOOL_EXECUTION_TIMEOUT_MS=10000 # 单个工具执行超时
HTTP_FETCH_ALLOWED_DOMAINS= # http_fetch 域名白名单(空=允许所有)
# 可选工具
QWEATHER_API_KEY= # 和风天气 API Key(为空则不注册)
CODE_EXEC_ENABLED=false # 代码执行(默认关闭)
FEISHU_DOC_SEARCH_ENABLED=false # 飞书文档搜索(默认关闭)
# 记忆管理
MEMORY_SUMMARIZE_THRESHOLD=24 # 触发摘要的消息数阈值
MEMORY_RECENT_WINDOW=16 # 保留最近消息原文数
MEMORY_MAX_FACTS=10 # 每 chatId 最大事实数
MEMORY_FACTS_ENABLED=false # 事实提取(默认关闭)
# 任务编排
ORCHESTRATION_ENABLED=false # 多步任务编排(默认关闭)
ORCHESTRATION_MAX_SUBTASKS=5 # 最大子任务数
ORCHESTRATION_PROGRESS_ENABLED=true # 发送进度消息
# 存储(默认内存,可选 Redis)
STORAGE_BACKEND=memory
# STORAGE_BACKEND=redis
# REDIS_URL=redis://127.0.0.1:6379完整配置说明见 .env.example。
pnpm dev在飞书中给机器人发消息:
- "现在几点了?" → 模型调用
current_time工具,返回当前时间 - "/status" → 查看运行时状态
- "/tools" → 查看已注册工具列表
- "/help" → 查看帮助
LiteClaw 默认使用飞书长连接模式,本地开发无需公网域名或 tunnel。
基本步骤:
- 在飞书开放平台创建企业自建应用
- 为应用开启机器人能力
- 开启事件订阅,选择长连接模式
- 订阅
im.message.receive_v1 - 发布应用并开始本地联调
详细配置见 飞书配置指南。
Phase 3 的 Agent Loop 依赖模型的 function calling / tool calling 能力。以下模型已验证或理论兼容:
- Qwen 2.5+(推荐)
- DeepSeek V3 / R1
- LLaMA 3.1+(需要支持 tool use 的版本)
- 任何支持 OpenAI function calling 协议的模型
如果你的模型不支持 function calling,LiteClaw 仍可正常作为普通聊天机器人运行(工具不会被调用)。
只需 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) {
const query = context.arguments?.query as string;
// ... 你的逻辑
return { text: "工具返回结果" };
}
};2. 注册到 registry — 在 src/services/tools.ts 中导入并添加到 toolRegistry
3. 完成 — 模型会自动发现并使用新工具
src/
├── index.ts # 启动入口
├── config.ts # 配置管理(.env.local)
├── routes/
│ └── feishu.ts # Webhook 路由
├── types/
│ └── feishu.ts # 飞书事件类型定义
└── services/
├── feishu.ts # 飞书长连接 & API 客户端
├── feishu-message-handler.ts # 消息处理编排(Agent Loop 入口)
├── llm.ts # LLM 适配器(generateAgentReply)
├── commands.ts # 命令路由
├── tools.ts # Tool Registry + AI SDK 桥接
├── tools/
│ ├── local-status.ts # 内置工具:运行时状态
│ ├── current-time.ts # 内置工具:当前时间
│ ├── http-fetch.ts # 内置工具:受控 HTTP 请求
│ ├── weather.ts # 内置工具:天气查询(和风天气)
│ ├── code-exec.ts # 内置工具:代码执行(沙箱)
│ └── feishu-doc-search.ts # 内置工具:飞书文档搜索
├── summarizer.ts # 会话摘要服务
├── facts-extractor.ts # 用户事实提取
├── prompt-builder.ts # 动态 System Prompt 构建
├── task-types.ts # 任务编排类型定义
├── task-planner.ts # 任务规划器(LLM 分解子任务)
├── task-orchestrator.ts # 任务编排器(顺序执行 + 合成)
├── task-progress.ts # 进度格式化
├── store.ts # Store 接口定义
├── conversation-store.ts # Store 后端选择器
├── memory.ts # 内存 Store 实现
├── redis-store.ts # Redis Store 实现
├── runtime-status.ts # 运行时状态快照
├── logger.ts # 结构化 JSON 日志
├── errors.ts # 错误分类系统
├── resilience.ts # 超时 & 重试
└── rate-limit.ts # 滑动窗口限流
docs/
├── phase1-minimal-chain.md # Phase 1 技术方案
├── phase2-infrastructure.md # Phase 2 技术方案
├── phase3-tool-calling.md # Phase 3 技术方案
├── phase4-memory.md # Phase 4 技术方案
├── phase5-task-orchestration.md # Phase 5 技术方案
├── phases-implementation-guide.md # 各阶段实现说明
├── feishu-config.md # 飞书配置指南
└── assets/ # 架构图(SVG + PNG)
飞书消息接入 → 本地模型调用 → 会话上下文 → 事件去重
Redis 持久化 → 结构化日志 → 错误分类 → 超时重试 → 限流 → 命令路由
Tool Registry → 模型自主选工具 → 多轮 Agent Loop → 6 个内置工具 → Vitest 单测
会话摘要(增量式)→ 用户事实提取 → 动态 System Prompt → /forget 命令
Task Planner → 子任务顺序执行 → 进度反馈 → LLM 结果合成 → Graceful Degradation
完整 Agent 编排 → 工具生态 → 权限审计 → 丰富消息形式
- 路线图
- Phase 1 技术方案 — 最小可运行链路
- Phase 2 技术方案 — Agent 基础设施
- Phase 3 技术方案 — 工具调用
- Phase 4 技术方案 — 记忆管理
- Phase 5 技术方案 — 任务编排
- 阶段实现说明
- 飞书配置指南
- 贡献指南
- 真实凭据仅放在
.env.local中 - 不要提交模型服务地址、密钥或任何内网信息
.gitignore已忽略.env.local、.env、.npmrc、dist和node_moduleshttp_fetch工具支持域名白名单(HTTP_FETCH_ALLOWED_DOMAINS),生产环境建议开启
