ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Paperclip:基于React+Node.js+OpenClaw的轻量AI智能体开发范式

Paperclip:基于React+Node.js+OpenClaw的轻量AI智能体开发范式 1. 项目概述Paperclip 不是回形针而是一个正在成型的 AI 智能体开发范式“Paperclip”这个词在当前技术社区里已经彻底脱离了办公文具的原始语义。它不再指代那个弯折金属丝就能夹住纸张的小物件而是悄然演变为一个代号——指向一类以轻量、可组合、强交互为特征的新型 AI 智能体AI Agent构建框架或实践模式。你搜“paperclip”十有八九会撞上 Node.js、React、OpenClaw 这三个词的密集共现再往下翻全是“openclaw 部署失败”、“react state 怎么和 agent 同步”、“node.js v24.21.0 不存在”这类真实到扎心的操作现场。这说明什么说明 Paperclip 已经不是某个公司发布的闭源产品而是一群开发者在 OpenClaw 基础上自发摸索出的一套工作流共识用 React 做前端壳子用 Node.js 做后端胶水把大模型能力像搭积木一样嵌进真实业务动作里。我第一次接触 Paperclip 是在帮一家做 SaaS 客服系统的客户做智能体 PoC。他们原本想直接套用 LangChain 的标准模板结果发现流程太重、调试太慢、前端状态和 agent 决策完全脱节。后来团队里一个前端老哥甩出个 repo就叫paperclip-core里面只有 3 个核心文件一个基于 Express 的极简 agent runtime、一个 React Hook 封装的useAgent、以及一份用 Markdown 写的 action schema 定义规范。我们用它三天内跑通了一个“自动查订单生成话术触发工单”的闭环比原计划快了一周。关键在于它不试图替代 OpenClaw而是站在 OpenClaw 肩膀上解决 OpenClaw 自身没打算解决的问题怎么让 AI agent 真正活在用户界面里而不是躲在 API 后面当个黑盒。所以 Paperclip 的本质是 React 开发者对 AI agent 落地的最后一公里发起的务实反击——它不谈 AGI只问“这个按钮点下去agent 能不能在 800ms 内给出带操作按钮的响应”。它适合谁第一类是 React 中高级开发者已经写过 3 个以上复杂表单或实时协作应用对useReducer和useEffect的边界了如指掌但面对 AI agent 时总卡在“state 怎么同步”“loading 状态怎么粒度控制”这种细节上第二类是 Node.js 后端习惯用 Express/Koa 快速搭 API但不想被 LangChain 的抽象层绕晕需要一个能直接塞进现有服务的轻量 agent 执行器第三类是技术决策者正在评估 OpenClaw 是否值得投入但被“无法安全验证”“sl2 环境报错”这类问题劝退Paperclip 提供了一条绕过 OpenClaw 复杂部署、直奔核心能力验证的捷径。它不是银弹但它是把 AI agent 从 PPT 拉进真实代码仓库的第一把扳手。2. 核心设计思路为什么放弃“全栈 AI 框架”选择“React Node.js OpenClaw”三角组合2.1 放弃大一统框架拥抱分层解耦的现实主义当前市面上的 AI agent 框架要么像 LangChain 那样追求“一次定义到处运行”结果是抽象层叠了七层debug 时得从Runnable一路 trace 到BaseLLM要么像 OpenClaw 那样主打“开箱即用”但代价是强绑定特定环境比如必须 WSL2 Ubuntu、特定认证体系“无法安全验证”报错根源在此。Paperclip 的设计起点非常朴素开发者最熟悉的工具链就是最好的 AI agent 工具链。React 是事实上的前端标准Node.js 是 JS 全栈的默认后端OpenClaw 是目前中文社区最活跃、插件最丰富的开源 agent runtime。三者不是拼凑而是按职责严格切分React 层负责“人机交互契约”定义用户能看到什么、能点什么、状态如何反馈。这里不写任何 LLM 调用逻辑只暴露useAgent({ schema })这样的 Hook把 agent 当成一个“智能的 useState”来用。Node.js 层负责“执行契约”接收 React 发来的结构化请求比如{ action: search_order, params: { order_id: ORD-789 } }调用 OpenClaw 的 REST API 或直接加载其本地 SDK把结果清洗成 React 能消费的 JSON。OpenClaw 层负责“能力供给”专注做好两件事——解析自然语言指令、调度工具API/数据库/文件系统其他一概不管。它的“无法安全验证”问题在 Paperclip 架构里被降级为“后端配置项”前端完全无感。这种分层不是为了炫技而是为了解决一个血泪教训在客户现场90% 的 agent 项目失败不是因为模型不够强而是因为前端 loading 状态卡死、后端超时重试逻辑混乱、agent 返回的 JSON 字段名和 React 组件期望的对不上。Paperclip 把这些“胶水问题”全部显性化、标准化让每个角色各司其职。2.2 为什么选 OpenClaw 而非 LangChain 或 LlamaIndexOpenClaw 在 Paperclip 架构里的不可替代性源于它对“工具调用”这一环节的极致聚焦。LangChain 的Tool概念很优雅但实际落地时你要写tool装饰器、要注册到ToolRegistry、要处理ToolResult的序列化反序列化最后发现 70% 的代码都在和框架的类型系统打架。LlamaIndex 更侧重 RAG对“调用外部 API 修改状态”这种动作支持薄弱。而 OpenClaw 的action定义极其直白{ name: create_ticket, description: 创建客服工单需提供用户ID和问题摘要, parameters: { type: object, properties: { user_id: { type: string }, summary: { type: string } }, required: [user_id, summary] } }这份 JSON 直接对应一个 HTTP POST 请求的 bodyNode.js 层拿到后连 schema validation 都不用额外写直接axios.post(/openclaw/actions, payload)即可。更关键的是OpenClaw 的 action 可以是任意 HTTP endpoint这意味着你可以把 legacy 系统的 SOAP 接口、内部 Java 微服务的 REST API、甚至 Excel 导出脚本统统包装成 agent 能调用的“工具”。Paperclip 的 Node.js 层只需要做一件事把 React 的用户操作翻译成 OpenClaw 能懂的 action 调用格式。这种“协议级简单”是 LangChain 那种面向对象抽象永远做不到的。2.3 React 层的轻量化设计Hooks 是唯一入口拒绝组件库绑架Paperclip 对 React 的使用刻意回避了所有“智能组件库”的诱惑。没有PaperclipProvider没有AgentChat /这种黑盒组件只有一个核心 HookuseAgent。它的签名长这样const { run, status, result, error, reset } useAgent({ // schema 定义 agent 能做什么直接来自 OpenClaw action JSON schema: orderActionsSchema, // backendUrl 指向你的 Node.js agent server backendUrl: /api/agent, // 可选自定义错误处理比如把 OpenClaw 的 400 错误转成用户友好的提示 onError: (err) toast.error(操作失败${err.message}) });这个设计背后有三个硬性约束第一状态必须可预测。status只有idle | running | success | error四种绝不出现loading_data | waiting_for_llm | parsing_response这种过度细分的状态避免前端状态机爆炸。第二数据流必须单向。result是纯对象不包含任何函数或 Promise确保能安全地JSON.stringify()存入 Redux 或 localStorage。第三错误必须可恢复。reset()不是简单清空 state而是重置整个 agent session包括清除 OpenClaw backend 缓存的对话历史保证下一次run()是干净的起点。我见过太多项目因为没实现reset导致用户连续点两次“重试”agent 把同一份订单创建了两遍——Paperclip 把这种坑直接焊死在 API 设计里。3. 核心实现细节从零搭建 Paperclip 开发环境的实操指南3.1 环境准备绕过 OpenClaw 官方安装陷阱的实战方案OpenClaw 官方文档推荐的 WSL2 Ubuntu 安装路径对 Windows 开发者来说就是一场灾难。“sl2 环境报错”、“wsl --status 返回 Not Installed”、“Ubuntu 安装后找不到 /dev/ttyUSB0”……这些不是你的问题是 OpenClaw 默认配置和 Windows 子系统兼容性的真实写照。Paperclip 的解决方案非常粗暴在 Windows 主机上用 Docker Desktop 运行 OpenClawNode.js 和 React 全部走 Windows 原生环境。这样既避开 WSL2 的权限地狱又保留 OpenClaw 的完整功能。具体步骤如下安装 Docker Desktop for Windows必须开启 WSL2 backend这是 Docker Desktop 的要求但不是 OpenClaw 的要求拉取并运行 OpenClaw 官方镜像# 创建专用网络隔离 OpenClaw 流量 docker network create paperclip-net # 运行 OpenClaw映射端口 3000Web UI和 8000API docker run -d \ --name openclaw-paperclip \ --network paperclip-net \ -p 3000:3000 \ -p 8000:8000 \ -v $(pwd)/openclaw-config:/app/config \ -v $(pwd)/openclaw-tools:/app/tools \ ghcr.io/openclaw/openclaw:latest提示$(pwd)在 PowerShell 里要写成${PWD}否则路径会错。openclaw-config目录下放config.yamlopenclaw-tools放你自定义的 action 脚本Python/JS/Shell这是 OpenClaw 加载工具的约定路径。验证 OpenClaw 是否就绪# 在 PowerShell 中执行检查容器状态 docker ps | Select-String openclaw-paperclip # 访问 http://localhost:3000看到 OpenClaw Web UI 即成功 # 测试 API 连通性 curl -X GET http://localhost:8000/health # 应返回 {status:healthy}这个方案的优势在于Docker Desktop 的 WSL2 是微软官方维护的稳定版本不会出现wsl --status报错OpenClaw 运行在 Linux 容器里完美支持其依赖的 Python 包如pydantic、fastapi而你的 Node.js 和 React 代码完全在 Windows 上开发npm start、npx create-react-app等命令照常运行毫无割裂感。我实测下来这套组合在 i5-1135G7 笔记本上OpenClaw 启动时间 15 秒比原生 Ubuntu WSL2 快 3 倍。3.2 Node.js Agent Server50 行代码搞定的胶水层Paperclip 的 Node.js 层不是微服务而是一个“智能代理”。它不做业务逻辑只做三件事接收 React 请求、转发给 OpenClaw、清洗响应。用 Express 实现代码不到 50 行// server.js const express require(express); const axios require(axios); const app express(); const PORT 3001; // 解析 JSON body app.use(express.json({ limit: 10mb })); // 核心代理路由 app.post(/api/agent, async (req, res) { try { const { action, params, context } req.body; // 1. 构造 OpenClaw action 调用 payload const openclawPayload { action_name: action, parameters: params, // context 透传给 OpenClaw用于跨 action 状态保持 context: context || {} }; // 2. 调用 OpenClaw API注意这里是容器内地址 const openclawResponse await axios.post( http://openclaw-paperclip:8000/actions/execute, openclawPayload, { timeout: 30000 } // 设置超时避免前端无限等待 ); // 3. 清洗响应只返回业务数据剥离 OpenClaw 内部字段 const cleanedResult { success: true, data: openclawResponse.data.result, // 保留 context 用于下一次调用 context: openclawResponse.data.context }; res.json(cleanedResult); } catch (error) { // 统一错误格式便于前端处理 res.status(500).json({ success: false, error: error.response?.data?.message || Agent 执行失败, code: error.response?.status || 500 }); } }); app.listen(PORT, () { console.log(Paperclip Agent Server running on http://localhost:${PORT}); });注意http://openclaw-paperclip:8000是 Docker 容器间通信的地址不是localhost:8000。因为 Node.js 服务也在 Windows 上运行它通过 Docker 的paperclip-net网络直接访问 OpenClaw 容器无需走宿主机端口映射性能更高、更可靠。这个 server 的精妙之处在于context字段的设计。OpenClaw 本身支持对话上下文但 Paperclip 把它显性化为一个可由前端控制的参数。比如用户先查订单search_order再基于结果创建工单create_ticketReact 层可以把第一次返回的order_id和customer_name存进context第二次调用时直接传过去避免重复提问。这比依赖 OpenClaw 的隐式 session 机制更可控、更易 debug。3.3 React Agent Hook让 AI 能力像 useState 一样简单useAgentHook 是 Paperclip 的灵魂它的实现必须兼顾 React 的并发渲染特性和 agent 的异步不确定性。以下是经过生产环境验证的 TypeScript 版本// hooks/useAgent.ts import { useState, useCallback, useRef } from react; interface AgentStateT { status: idle | running | success | error; result: T | null; error: string | null; } export function useAgentT({ schema, backendUrl /api/agent, onError }: { schema: { name: string; parameters: Recordstring, any }; backendUrl?: string; onError?: (error: Error) void; }) { const [state, setState] useStateAgentStateT({ status: idle, result: null, error: null }); const abortControllerRef useRefAbortController | null(null); const run useCallback(async (params: Recordstring, any, context?: Recordstring, any) { // 1. 取消前一次请求 if (abortControllerRef.current) { abortControllerRef.current.abort(); } abortControllerRef.current new AbortController(); try { setState(prev ({ ...prev, status: running, error: null })); const response await fetch(backendUrl, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ action: schema.name, params, context }), signal: abortControllerRef.current.signal }); if (!response.ok) { throw new Error(HTTP ${response.status}: ${response.statusText}); } const data await response.json(); if (!data.success) { throw new Error(data.error || Agent 执行失败); } setState({ status: success, result: data.data as T, error: null }); return data.data as T; } catch (error) { if (error.name AbortError) return; const errorMessage error instanceof Error ? error.message : 未知错误; setState(prev ({ ...prev, status: error, error: errorMessage })); onError?.(error as Error); } }, [schema.name, backendUrl, onError]); const reset useCallback(() { setState({ status: idle, result: null, error: null }); if (abortControllerRef.current) { abortControllerRef.current.abort(); abortControllerRef.current null; } }, []); return { run, status: state.status, result: state.result, error: state.error, reset }; }这段代码的关键细节AbortController 防止内存泄漏每次run都创建新 controllerreset时主动 abort避免组件卸载后 Promise 还在 resolve 导致setState on unmounted component警告。状态更新原子性setState用函数式更新确保status切换和error清除同步发生不会出现status: running但error还残留的中间态。错误分类处理网络错误、HTTP 错误、业务错误全部归一为Error对象onError回调统一处理前端可以自由决定是toast还是Modal。3.4 实战案例用 Paperclip 构建“智能客服助手”我们以一个真实需求为例客服后台需要一个按钮点击后自动完成“查询用户最新订单 → 提取订单状态和商品信息 → 生成标准化回复话术 → 如果订单异常则触发工单”。传统做法是写 4 个独立 API前端串行调用出错就得重来。用 Paperclip只需定义 3 个 OpenClaw action 并组合调用OpenClaw action 定义openclaw-tools/search_order.pydef search_order(user_id: str): # 调用公司订单微服务 orders call_internal_api(GET, f/orders?user_id{user_id}, timeout5) return { latest_order: orders[0] if orders else None, order_count: len(orders) }React 组件调用function CustomerSupportPanel({ userId }: { userId: string }) { const { run: searchOrder, status: searchStatus, result: orderData } useAgent({ schema: searchOrderSchema }); const { run: generateReply, status: replyStatus, result: replyText } useAgent({ schema: generateReplySchema }); const { run: createTicket, status: ticketStatus } useAgent({ schema: createTicketSchema }); const handleAssist async () { // Step 1: 查询订单 const order await searchOrder({ user_id: userId }); if (!order?.latest_order) { toast.error(未找到该用户的订单); return; } // Step 2: 生成话术传入订单数据作为 context const reply await generateReply( {}, { order: order.latest_order } // context 透传 ); // Step 3: 检查状态异常则建工单 if (order.latest_order.status failed) { await createTicket({ user_id: userId, summary: 订单 ${order.latest_order.id} 支付失败 }); } // 更新 UI 显示话术 setGeneratedReply(reply); }; return ( div button onClick{handleAssist} disabled{isProcessing()} 智能辅助 /button {replyText div classNamereply{replyText}/div} /div ); }这个案例展示了 Paperclip 的核心价值把复杂的 AI workflow拆解成可测试、可复用、可单独 debug 的原子 action。每个 action 都可以独立单元测试search_order.py用 pytest每个useAgentHook 都可以单独 Storybook 演示整个流程的错误定位精准到某一行await而不是在 LangChain 的RunnableSequence里大海捞针。4. 常见问题与排查技巧实录那些踩过的坑都写在日志里了4.1 “OpenClaw 无法安全验证”报错的根因与绕过方案这个报错几乎出现在所有 Windows WSL2 的 OpenClaw 部署教程评论区本质是 OpenClaw 的 TLS 证书验证机制和 WSL2 的网络栈不兼容。WSL2 使用虚拟网卡其localhost指向的是 WSL2 内部 loopback而 Windows 主机的localhost指向的是 Windows loopback两者不通。当 OpenClaw 尝试用https://localhost:3000验证自身时WSL2 环境根本连不上 Windows 的 3000 端口于是报“无法安全验证”。Paperclip 的绕过方案极其简单禁用 OpenClaw 的安全验证改用 Docker 网络直连。修改openclaw-config/config.yaml# 关键配置关闭 TLS 验证启用 HTTP server: host: 0.0.0.0 port: 8000 https: false # 强制 HTTP cors: allow_origins: [*] # 开发阶段允许所有来源 # 关闭安全验证模块 security: enable_verification: false # 核心开关然后重启容器docker restart openclaw-paperclip提示生产环境必须重新启用 HTTPS 和验证但开发阶段enable_verification: false是最快落地的方案。Paperclip 的 Node.js 层运行在 Windows它通过 Docker 网络http://openclaw-paperclip:8000直接访问容器完全绕过localhost解析问题因此前端看不到任何报错。4.2 Node.js 版本冲突“v24.21.0 is not yet released” 的真相搜索“error installing 24.21.0: node.js v24.21.0 is not yet released”你会发现大量开发者被误导去安装根本不存在的 Node.js 版本。真相是OpenClaw 的某些插件或文档示例错误地将 Node.js 的预发布版本号如 v24.0.0-alpha.1当作稳定版引用。Node.js 官网的 LTS 版本目前是 v20.xCurrent 版本是 v22.xv24 还在规划中。Paperclip 的解决方案是锁定 Node.js 版本忽略 OpenClaw 文档的错误指引。在项目根目录创建.nvmrc文件20.18.0然后用 nvm 切换nvm install 20.18.0 nvm use 20.18.0验证node -v # 输出 v20.18.0 npm -v # 输出 10.5.0匹配 Node.js 20 的 npm 版本注意OpenClaw 本身是 Python 项目对 Node.js 版本无依赖。Paperclip 的 Node.js 层只用到fetch、axios等基础能力Node.js 18 完全满足。强行升级到不存在的 v24.x只会浪费你 2 小时在 GitHub issue 里找答案。4.3 React 白屏与 State 同步失效的典型场景“react native 启动白屏”、“react state 与 hooks 不同步”这类问题在 Paperclip 项目中往往源于一个被忽视的细节agent 返回的数据结构和 React 组件期望的不一致。例如OpenClaw 的search_orderaction 返回{ result: { order_id: ORD-123, items: [...] } }而你的 React 组件却直接解构const { order_id, items } result; // ❌ result 是 { result: { ... } }Paperclip 的 Node.js 层已做清洗但如果你跳过它直接调用 OpenClaw API就会遇到这个问题。排查步骤打开浏览器 Network 面板过滤/api/agent请求查看 Response Body对比useAgent的result类型定义和实际返回值在useAgent的then回调里加console.log(result)确认数据形态。修复方案在useAgent的响应处理中增加类型守卫// 在 server.js 的响应清洗部分 if (openclawResponse.data.result) { cleanedResult.data openclawResponse.data.result; } else if (openclawResponse.data.output) { // 兼容 OpenClaw 旧版返回格式 cleanedResult.data openclawResponse.data.output; } else { cleanedResult.data openclawResponse.data; }4.4 性能瓶颈定位当 agent 响应慢于 3 秒时该怎么办Paperclip 的响应延迟90% 来自 OpenClaw 的工具执行而非网络传输。快速定位方法在 OpenClaw 容器内启用日志docker exec -it openclaw-paperclip bash tail -f /app/logs/action_execution.log观察search_order这类 action 的执行耗时。检查工具代码中的阻塞操作比如search_order.py里用了time.sleep(2)模拟延迟或调用外部 API 时没设 timeout。优化策略为所有外部 API 调用添加timeout参数如requests.get(url, timeout3)把耗时操作如 PDF 生成改为异步任务OpenClaw 返回task_id前端轮询对高频查询如用户信息加 Redis 缓存OpenClaw action 优先读缓存。我遇到过最典型的性能坑一个get_user_profileaction每次都要调用公司 LDAP 服务平均耗时 2.8 秒。加了 Redis 缓存后P95 降到 120ms。Paperclip 的优势在于这种优化完全在 OpenClaw 层完成React 和 Node.js 层代码零改动。5. 工具链与生态扩展Paperclip 如何融入现有技术栈5.1 与 Obsidian 的深度集成把 AI agent 变成你的第二大脑OpenClaw 社区有个热门插件叫openclaw-obsidian它让 Obsidian 笔记本具备调用 agent 的能力。Paperclip 的 Node.js 层可以无缝对接这个插件原理是Obsidian 插件通过fetch调用你的/api/agent端点和 React 组件调用方式完全一致。配置步骤在 Obsidian 的community-plugins目录安装openclaw-obsidian在插件设置中将Agent Endpoint指向http://localhost:3001/api/agent在笔记中写agent action: search_order params: user_id: U-789Obsidian 会自动发送请求把返回的 order_id 插入当前笔记。这个集成的价值在于把 AI agent 的能力从 Web 应用延伸到知识管理场景。销售团队可以用它一键生成客户背景报告产品经理可以用它把会议录音转成待办事项。Paperclip 不需要为 Obsidian 写任何特殊代码因为它遵循的是标准 HTTP 协议。5.2 Qwen2.5-3B 模型接入小模型也能跑出大效果“qwen2.5-3b 关联到 openclaw” 是近期热点因为 3B 参数的 Qwen2.5 在消费级 GPU如 RTX 4090上能跑出接近 7B 模型的效果且推理速度快 3 倍。Paperclip 的 Node.js 层支持无缝切换模型只需修改 OpenClaw 的config.yamlllm: provider: qwen model: Qwen2.5-3B-Instruct api_base: http://localhost:8001/v1 # Ollama 或 vLLM 服务地址 api_key: sk-xxx # 如果需要然后启动 Ollamaollama pull qwen2.5:3b-instruct ollama run qwen2.5:3b-instructPaperclip 的优势在于模型切换对前端完全透明。React 组件还是调用useAgentNode.js 层还是转发请求OpenClaw 负责把请求路由到不同的 LLM backend。你甚至可以配置 A/B 测试50% 流量走 Qwen2.5-3B50% 走 Qwen2.5-7B用 Paperclip 的context字段记录模型版本方便效果分析。5.3 企业级扩展如何把 Paperclip 接入现有微服务架构Paperclip 的轻量设计让它极易融入企业级架构。假设你已有 Spring Cloud 微服务订单服务地址是http://order-service:8080用户服务是http://user-service:8081。OpenClaw 的 action 可以直接调用这些服务# openclaw-tools/get_order_with_user.py import requests def get_order_with_user(order_id: str): # 调用订单服务 order_resp requests.get(fhttp://order-service:8080/orders/{order_id}) order order_resp.json() # 调用用户服务 user_resp requests.get(fhttp://user-service:8081/users/{order[user_id]}) user user_resp.json() return { order: order, user: user }Paperclip 的 Node.js 层不需要知道这些内部服务的存在它只认 OpenClaw 的get_order_with_useraction。这种设计让 AI agent 成为企业服务网格Service Mesh里的一个普通 consumer享受 Istio 的熔断、限流、追踪能力而无需 Paperclip 自己实现。我在某金融客户项目中就是用这套方案把 Paperclip 接入他们的 Dubbo 服务集群。OpenClaw action 用 PyDubbo 调用 Java 服务Paperclip Node.js 层零修改上线后监控显示 agent 平均响应时间 420msP99 1.2s完全满足客服系统 SLA。6. 实操心得与避坑指南一个资深开发者掏心窝的话Paperclip 不是魔法它是一套经过反复打磨的工程实践。以下是我踩过最深的五个坑现在写出来省得你再花三天时间 debug第一坑别在useAgent里做副作用很多新手喜欢在run().then()里直接navigate(/success)或dispatch(action)。这会导致两个问题一是run可能被多次调用比如用户连点导航或 dispatch 会触发多次二是run的 Promise 可能被reset()中断then里的代码却还在执行。正确做法是run只负责获取数据数据拿到后用useEffect监听result变化再做导航或 dispatch。这是 React 的基本哲学Paperclip 不能破戒。第二坑OpenClaw 的context不是万能状态桶context字段设计初衷是传递跨 action 的必要数据如order_id但有人把它当成全局状态管理器塞进用户偏好、UI 主题、甚至整个 Redux store。后果是 OpenClaw 的内存占用飙升GC 频繁响应变慢。我的建议context里只放字符串、数字、布尔值复杂对象一律序列化后存 Rediscontext只存 key。第三坑Node.js 层的timeout必须小于前端 timeout前端fetch默认 timeout 是 0无限等待但 Paperclip 的useAgent设了 30s。如果 Node.js 层axiostimeout 设成 60s那么前端 30s 后报错Node.js 还在等 OpenClaw 响应造成连接堆积。规则很简单Node.js timeout 前端 timeout × 0.8比如前端 30sNode.js 设 24s。第四坑Docker 容器名必须和--network匹配docker run --name openclaw-paperclip --network paperclip-net这个openclaw-paperclip就是容器内 DNS 名称。Node.js 代码里http://openclaw-paperclip:8000的openclaw-paperclip必须和--name一致少一个字符都不行。Windows 的大小写
返回列表