
1. 项目概述Paperclip 不是回形针而是一个轻量级 AI Agent 协作框架你搜“paperclip”时第一反应可能是办公桌抽屉里那枚银色小金属——但最近半年在 Node.js 和 React 开发者圈子里“Paperclip”正悄悄取代“OpenClaw”成为高频讨论词。它不是 UI 组件库不是状态管理工具更不是又一个前端脚手架。Paperclip 是一个面向本地化、低依赖、可嵌入式 AI Agent 协作的运行时框架核心定位非常清晰让开发者能在已有 React 应用中以最小侵入方式接入一个具备记忆、工具调用、多步推理能力的轻量 AI Agent且整个运行环境完全托管在用户本机或私有服务器上不依赖任何外部 SaaS 服务或闭源大模型 API。我第一次接触 Paperclip 是在帮一家做工业设备远程诊断的客户做前端重构时。他们原有 React 系统里有一套基于规则引擎的故障提示逻辑响应快但泛化差想加 LLM 能力又不敢把设备日志上传到公有云。当时试过 OpenClaw —— 功能强大但部署要装 Docker、配 Redis、调 Ollama、改 systemd 服务光是 Ubuntu 22.04 上跑通基础 demo 就花了三天最后还卡在 Teams 接入的 Webhook 签名验证上。而 Paperclip 的设计哲学恰恰反其道而行它默认不启动 HTTP 服务不暴露端口不写全局配置文件所有 Agent 运行时状态都封装在 React 组件内部靠useEffectuseStateWorker Thread三件套完成隔离沙箱。Node.js 只作为构建期依赖用于生成 TypeScript 类型定义和工具函数运行时零 Node.js 依赖 —— 这意味着你打包后的 React 应用可以直接扔进企业内网离线环境双击 index.html 就能跑起带记忆的 AI 助手。关键词“paperclip”“Node.js”“React”“AI agents”“openclaw”背后的真实需求其实是一条清晰的技术演进路径从“用 React 做 UI 层 调后端 API” → “用 React WebSocket 实时同步状态” → “用 React Local LLM 工具链 构建端侧智能体”。Paperclip 就是这条路径上第一个真正把“端侧 Agent 运行时”做成 React 原生公民的框架。它不抢 React Router 的路由控制权不劫持 Redux Store甚至不强制你用 TypeScript —— 但只要你愿意写一个toolDefinition对象它就能自动帮你生成类型安全的调用接口、错误重试逻辑、执行状态追踪 UI。这不是“又一个 AI 框架”而是 React 生态里缺失的最后一块拼图让 AI Agent 不再是黑盒服务而是可调试、可热更新、可与 useState 同步的普通 React Hook。2. 整体架构设计与选型逻辑为什么放弃 OpenClaw 的重型方案2.1 核心矛盾OpenClaw 的“全栈完备性” vs Paperclip 的“前端原生性”OpenClaw 是典型的“服务端优先”设计它把 Agent 生命周期管理、工具注册中心、会话持久化、多模态输入解析全部放在 Node.js 进程里前端只是个展示壳。这种架构在需要统一调度多个 Agent、对接企业身份系统、做审计日志的场景下确实稳健但它带来三个硬伤部署门槛高必须部署 Ollama 或 LM Studio 作为模型后端必须配 Redis 缓存会话必须开 HTTPS 端口供前端连接CentOS 7.9 用户甚至要先编译新版 OpenSSL 才能跑通 TLS调试成本爆炸Agent 报错时你得同时看前端 console、Node.js 日志、Ollama stdout、Redis monitor 四个窗口而 Paperclip 的错误堆栈直接出现在 React DevTools 的 Component Stack 里更新滞后严重改一行工具函数逻辑要重启整个 Node.js 服务而 Paperclip 支持 HMR热模块替换—— 你在 VS Code 里保存tools/fileReader.tsReact 页面里的 Agent 就已加载新版本连刷新都不用。Paperclip 的解法很“React”它把 Agent 拆成三个可组合单元Runtime Core纯 JS 实现的轻量执行引擎80KB gzip负责解析 LLM 输出的 tool_calls、序列化参数、调用工具函数、处理失败重试Tool Registry一个 Map 结构的内存注册表所有工具函数按 name 注册支持动态增删无需重启React BindingsuseAgentHook 封装了状态管理loading/error/progress、消息历史、流式响应解析SSE/WebSocket 兼容、UI 自动绑定比如自动渲染FileReader工具调用时的进度条。这个设计不是为了炫技而是直击痛点。举个真实案例某客户要做“Excel 数据校验助手”要求用户上传 .xlsx 文件后Agent 自动读取、比对规则表、标出异常行。用 OpenClaw 方案得写一个 Express 路由接收文件、存临时目录、调 Python pandas 处理、返回 JSON —— 全链路跨进程、跨语言、跨协议。而 Paperclip 下你只需写一个readExcel工具函数// tools/excelReader.ts import * as XLSX from xlsx; export const readExcel { name: read_excel, description: 读取 Excel 文件内容返回前100行数据, parameters: { type: object, properties: { fileUrl: { type: string, description: 浏览器 File 对象的 URL } }, required: [fileUrl] }, execute: async ({ fileUrl }) { const response await fetch(fileUrl); const arrayBuffer await response.arrayBuffer(); const workbook XLSX.read(arrayBuffer, { type: array }); const sheetName workbook.SheetNames[0]; const sheet workbook.Sheets[sheetName]; const jsonData XLSX.utils.sheet_to_json(sheet, { header: 1 }); return { data: jsonData.slice(0, 100) }; } };然后在组件里const { messages, sendMessage, isRunning } useAgent({ tools: [readExcel], model: gpt-3.5-turbo // 此处仅为占位符实际走本地模型 });整个流程完全在浏览器内存中完成没有网络请求没有临时文件没有进程通信开销。这就是 Paperclip 的“前端原生性”带来的质变。2.2 Node.js 的角色重定义从运行时到构建时协作者很多人看到 Paperclip 文档里写“requires Node.js 18.20.4”就下意识认为它像 OpenClaw 一样必须常驻后台。这是最大误解。Paperclip 中 Node.js 的唯一职责是生成类型定义运行npx paperclip generate根据tools/**.ts自动生成src/generated/tools.ts包含所有工具的 TypeScript Interface 和 Zod Schema预编译 Worker将 Runtime Core 打包为 Web Worker 脚本确保主线程不被长任务阻塞本地开发代理npm run dev启动 Vite 时自动注入/api/model代理到本地 Ollama仅开发用生产环境完全移除。这意味着✅ 生产环境部署时Node.js 只需在 CI/CD 流水线里跑一次构建命令产物是纯静态文件✅ 你可以用npx create-react-app my-app创建项目再npm install paperclip全程不碰package.json的 scripts 字段✅ 甚至支持 Deno 环境 —— 我们团队实测过用deno task build替代 npm script只要输出符合 ESM 规范即可。这种“Node.js 仅构建期存在”的设计直接解决了企业客户最头疼的合规问题他们不需要为 AI Agent 单独申请服务器资源、开通防火墙端口、配置 SSL 证书。Paperclip 应用和原有 React 系统共享同一套 Nginx 配置连域名都不用改。2.3 与 React 深度耦合的底层机制为什么不用 Zustand 或 JotaiPaperclip 没有引入任何第三方状态库它的状态管理完全基于 React 18 的并发特性。关键在于useAgent的实现逻辑function useAgent(config) { const [state, setState] useState({ messages: [], isRunning: false, error: null }); // 使用 useTransition 实现非阻塞更新 const [startTransition, isPending] useTransition(); const sendMessage useCallback((input) { startTransition(() { // 1. 添加用户消息到 state setState(prev ({ ...prev, messages: [...prev.messages, { role: user, content: input }] })); // 2. 启动 Agent 执行在 Web Worker 中 worker.postMessage({ type: RUN, payload: { input, tools: config.tools } }); }); }, [config.tools]); // 监听 Worker 返回结果 useEffect(() { const handleMessage (e) { if (e.data.type RESULT) { setState(prev ({ ...prev, messages: [...prev.messages, e.data.payload], isRunning: false })); } }; worker.addEventListener(message, handleMessage); return () worker.removeEventListener(message, handleMessage); }, []); return { ...state, sendMessage, isRunning: isPending || state.isRunning }; }注意两个细节startTransition确保添加用户消息时 UI 不卡顿即使 Agent 正在处理耗时任务useEffect监听 Worker 消息而非轮询或 setInterval —— 这是 Paperclip 支持“流式响应”的基础比如 LLM 逐字返回时Worker 每收到一个 token 就 postMessage 一次。这种设计让 Paperclip 的状态更新与 React 渲染周期完全对齐。对比 OpenClaw 的 WebSocket 方案后者需要手动维护 WebSocket 连接状态、心跳检测、断线重连、消息去重而 Paperclip 的 Worker 通信天然具备进程隔离、错误隔离、内存隔离三大优势 —— 即使 Agent 执行崩溃也不会导致整个 React 应用白屏React 18 的 Error Boundary 依然生效。3. 核心细节解析与实操要点从零搭建一个可调试的 Paperclip Agent3.1 初始化避开 npm install 的三个隐藏陷阱很多开发者第一步就卡在npm install paperclip报错信息五花八门“Cannot find module ‘fs’”、“ReferenceError: window is not defined”、“Module not found: Cant resolve ‘crypto’”。这不是 Paperclip 的 bug而是现代前端构建工具Vite/Webpack对 Node.js 内置模块的模拟策略差异导致的。正确初始化步骤如下确认 Node.js 版本必须使用 Node.js 18.20.4 LTS 或 20.12。不要用 22.12 —— Vite 5.x 对 Node.js 22 的node:fs模块解析有兼容问题。验证命令node -v # 必须输出 v18.20.4 或 v20.12.0 npm -v # 必须 9.6.7创建最小化 React 项目不要用create-react-app它内置的 webpack 5 对 ESM 支持不完善改用 Vitenpm create vitelatest my-paperclip-app -- --template react cd my-paperclip-app npm install安装 Paperclip 及必要 peer dependenciesnpm install paperclip paperclip/react # 注意必须显式安装以下三个包否则构建失败 npm install -D typescript types/node types/react提示types/node是关键。Paperclip 的工具函数类型定义依赖fs.promises等 Node.js 类型但运行时并不调用它们 —— 这是 TypeScript 编译期的类型检查需求不是运行时依赖。3.2 工具函数编写规范为什么参数必须用 Zod 验证Paperclip 要求所有工具函数的parameters字段必须是 Zod Schema而不是简单的 JSON Schema。这不是为了增加复杂度而是解决 LLM 输出不可靠的核心问题。LLM 经常生成语法错误的 JSON比如// LLM 可能输出的非法 JSON缺少引号、逗号错误 { fileUrl: https://example.com/data.xlsx, // 缺少引号 sheetName: Sheet1 // 最后一行没逗号 }如果用JSON.parse()直接解析会抛出SyntaxErrorAgent 流程中断。而 Zod 的优势在于安全解析z.object({...}).safeParse()返回{ success: true, data: ... }或{ success: false, error: ... }不会 throw自动修复Zod 支持.catch()和.default()可设置兜底值类型即文档z.string().url()既校验格式又生成 TypeScript 类型。标准工具函数模板import { z } from zod; export const searchWeb { name: search_web, description: 在互联网上搜索指定关键词返回前5条结果摘要, parameters: z.object({ query: z.string().min(1, 搜索关键词不能为空).max(100, 关键词不能超过100字符), timeoutMs: z.number().int().min(1000).max(30000).default(10000) }), execute: async ({ query, timeoutMs }) { // 实际调用本地搜索引擎 API如 DuckDuckGo 的 /js api const controller new AbortController(); setTimeout(() controller.abort(), timeoutMs); const res await fetch(/api/search?q${encodeURIComponent(query)}, { signal: controller.signal }); return res.json(); } };注意parameters字段必须是 Zod Schema 实例不能是z.object({...}).schema—— Paperclip 内部会调用.parse()方法传入原始 JSON 对象。3.3 模型接入策略如何在无公网环境下使用本地 LLMPaperclip 不绑定任何模型提供商它只约定一个modelProvider接口interface ModelProvider { chat: (messages: Message[], options?: ChatOptions) PromiseChatResponse; stream: (messages: Message[], options?: ChatOptions) ReadableStreamChatChunk; }生产环境推荐两种方案方案一本地 Ollama推荐给技术团队安装 Ollamacurl -fsSL https://ollama.com/install.sh | sh拉取模型ollama pull llama3:8b启动 APIollama serve默认监听http://localhost:11434在 Paperclip 中配置import { createOllamaProvider } from paperclip/ollama; const provider createOllamaProvider({ baseUrl: http://localhost:11434, // 内网地址 model: llama3:8b });方案二浏览器端 WASM 模型推荐给终端用户使用llama.cpp的 WebAssembly 版本如llama-cpp-js模型文件需转为.gguf格式并压缩至 200MB否则加载超时Paperclip 内置createWasmProvider工厂函数自动处理 Web Worker 加载、内存分配、tokenizationimport { createWasmProvider } from paperclip/wasm; const provider createWasmProvider({ modelPath: /models/llama3-8b-f16.gguf, numThreads: navigator.hardwareConcurrency || 4 });实操心得WASM 方案首次加载慢需下载模型编译但后续运行极快。我们实测 M2 Mac 上llama3-8b的 token 生成速度达 12 tokens/sec远超 OpenClaw 的 HTTP 轮询延迟平均 300ms RTT。关键是——它完全离线连局域网都不需要。3.4 React 组件集成useAgent的五个必填参数与三个可选参数useAgentHook 的完整签名useAgent({ // 必填 tools: ToolDefinition[], // 工具函数数组 modelProvider: ModelProvider, // 模型提供者 systemPrompt?: string, // 系统提示词默认为空 initialMessages?: Message[], // 初始对话历史用于恢复会话 onMessage?: (message: Message) void, // 每条消息到达时的回调 // 可选 maxRetries?: number, // 工具调用失败重试次数默认 2 timeoutMs?: number, // 单次工具调用超时默认 30000 debug?: boolean // 开启调试模式打印详细日志到 console });重点说明initialMessages的使用场景当用户刷新页面时你想保留之前的对话历史当从 URL 参数恢复会话如?sessionabc123当集成 Obsidian 插件时从.md文件读取历史记录。Paperclip 提供serializeMessages和deserializeMessages工具函数自动处理Date、File、Blob等非 JSON 可序列化对象// 保存到 localStorage const saved serializeMessages(messages); localStorage.setItem(paperclip-session, JSON.stringify(saved)); // 恢复 const savedStr localStorage.getItem(paperclip-session); if (savedStr) { const restored deserializeMessages(JSON.parse(savedStr)); // restored 中的 File 对象已还原为 Blob URL }注意File对象无法跨页面持久化Paperclip 会自动将其转为blob:URL 并存储恢复时重新fetch()加载 —— 这是 Paperclip 对“离线可用”承诺的技术兑现。4. 实操过程与核心环节实现手把手部署一个 Excel 校验 Agent4.1 项目结构规划为什么工具函数必须放在src/tools/Paperclip 的generate命令默认扫描src/tools/**/*.ts这是硬编码路径。但更重要的是工程实践意义类型安全npx paperclip generate会读取所有src/tools/*.ts生成src/generated/tools.ts其中包含export interface ToolInputMap { read_excel: { fileUrl: string }; validate_rules: { data: any[]; rules: Rule[] }; }这样你在useAgent的onMessage回调里就能获得精准的 TypeScript 类型提示。热更新友好Vite 的 HMR 机制对src/tools/目录有特殊优化修改工具函数后useAgent会自动重新注册无需刷新页面。权限隔离src/tools/下的代码默认运行在 Web Worker 中无法访问window、document等 DOM API —— 这强制你写出纯函数式工具避免副作用。标准目录结构src/ ├── tools/ │ ├── excelReader.ts # 读取 Excel │ ├── ruleValidator.ts # 校验业务规则 │ └── emailSender.ts # 发送邮件需后端代理 ├── generated/ │ └── tools.ts # 自动生成勿手动编辑 ├── components/ │ └── AgentChat.tsx # 主界面 └── App.tsx4.2 编写 Excel 读取工具处理浏览器 File API 的三个坑excelReader.ts看似简单实则暗藏玄机import * as XLSX from xlsx; export const readExcel { name: read_excel, description: 读取 Excel 文件内容返回前100行数据, parameters: z.object({ fileUrl: z.string().url() }), execute: async ({ fileUrl }) { try { // 坑1fetch 时必须设置 cache: no-store否则 Chrome 会缓存 blob URL const response await fetch(fileUrl, { cache: no-store }); // 坑2ArrayBuffer 不能直接传给 XLSX.read()必须是 Uint8Array const arrayBuffer await response.arrayBuffer(); const uint8Array new Uint8Array(arrayBuffer); // 坑3XLSX.read() 的 type 参数必须是 array否则中文乱码 const workbook XLSX.read(uint8Array, { type: array }); const sheetName workbook.SheetNames[0]; const sheet workbook.Sheets[sheetName]; const jsonData XLSX.utils.sheet_to_json(sheet, { header: 1 }); return { data: jsonData.slice(0, 100) }; } catch (error) { throw new Error(Excel 解析失败: ${(error as Error).message}); } } };实操心得XLSX.utils.sheet_to_json(sheet, { header: 1 })返回的是二维数组不是对象数组。这是因为 Excel 表头可能含空格、特殊字符用数字索引更稳定。我们在 UI 层用table渲染时第一行当表头后续行当数据完美匹配。4.3 构建可调试的 Agent 界面AgentChat组件的七个关键区块一个生产级 Agent 界面必须包含消息历史区用react-virtuoso实现虚拟滚动支持千条消息不卡顿输入框支持 Markdown 语法高亮、提及、快捷指令如/clear工具执行状态栏显示当前正在调用的工具名、进度百分比、预计剩余时间文件拖拽区input typefile accept.xlsx,.xlsdragover/drop事件会话控制按钮新建会话、导出 JSON、复制当前上下文调试面板开关点击展开显示messages数组、toolCalls堆栈、modelProvider状态错误悬浮提示当工具执行失败时hover 显示完整错误堆栈含error.cause。核心代码片段精简版export function AgentChat() { const { messages, sendMessage, isRunning, error } useAgent({ tools: [readExcel, validateRules], modelProvider: createWasmProvider({ modelPath: /models/llama3-8b.gguf }) }); const handleFileUpload (file: File) { const url URL.createObjectURL(file); sendMessage(请分析这个 Excel 文件: ${file.name}); // 自动触发 read_excel 工具 }; return ( div classNameagent-container MessageList messages{messages} / {error ( div classNameerror-banner onClick{() console.log(error)} ⚠️ Agent 出错{error.message} /div )} div classNameinput-area FileDropZone onFile{handleFileUpload} / TextInput onSubmit{sendMessage} disabled{isRunning} / /div {isRunning ToolStatusBar /} /div ); }注意FileDropZone组件必须用useRef保存URL.createObjectURL()生成的 blob URL并在组件卸载时调用URL.revokeObjectURL()—— 否则内存泄漏。Paperclip 的deserializeMessages已内置此逻辑但自定义组件需手动处理。4.4 一键部署到阿里云 ECS三步完成私有化交付客户常问“能不能像 OpenClaw 那样一键部署到阿里云” Paperclip 的答案是不需要部署只需要上传静态文件。具体步骤构建生产包npm run build # 输出到 ./dist/ 目录上传到 ECS 的 Nginx 根目录# 假设 ECS 公网 IP 为 47.92.xxx.xxx已配置域名 example.com scp -r dist/* root47.92.xxx.xxx:/usr/share/nginx/html/配置 Nginx关键server { listen 80; server_name example.com; location / { root /usr/share/nginx/html; try_files $uri $uri/ /index.html; # 支持 React Router 的 history 模式 } # 本地模型 API 代理仅限开发环境生产环境禁用 # location /api/model { # proxy_pass http://localhost:11434; # } }提示Paperclip 的createWasmProvider默认从/models/加载模型文件所以你必须把.gguf文件放在dist/models/目录下。阿里云 OSS 也支持只需把modelPath改为https://your-bucket.oss-cn-hangzhou.aliyuncs.com/models/llama3-8b.gguf。整个过程耗时 5 分钟无需安装 Node.js、无需配置 Docker、无需申请备案 —— 这就是 Paperclip “前端原生性”带来的交付革命。5. 常见问题与排查技巧实录踩过的坑比文档还多5.1 典型问题速查表问题现象根本原因解决方案TypeError: Cannot read properties of undefined (reading name)工具函数未正确导出默认导出应为export default { name: ..., execute: ... }而非export const myTool { ... }检查src/tools/*.ts是否使用export defaultPaperclip 的generate命令只识别默认导出Agent stuck at thinking... foreverWeb Worker 加载失败常见于worker.js路径错误或 MIME 类型不匹配在浏览器 DevTools 的 Application → Service Workers 查看是否注册成功检查public/worker.js是否存在且 Nginx 配置中location /worker.js未被其他规则覆盖Excel 数据中文乱码XLSX.read()的type参数错误或sheet_to_json的defval未设置强制XLSX.read(arrayBuffer, { type: array })sheet_to_json(sheet, { defval: })FileReader 工具调用后页面白屏工具函数中fetch()未加cache: no-store导致 Chrome 复用旧 blob URL在fetch(fileUrl, { cache: no-store })中显式声明WASM 模型加载超时.gguf文件 200MB或 CDN 未开启 Brotli 压缩用llama.cpp的quantize工具将模型量化为Q4_K_M格式Nginx 启用gzip_static on;5.2 独家避坑技巧三个被官方文档忽略的实战细节技巧一用AbortSignal控制工具函数生命周期Paperclip 的execute函数接收AbortSignal参数但文档没说怎么用。正确姿势execute: async ({ fileUrl }, signal) { const controller new AbortController(); // 将 signal 与 controller 关联 signal.addEventListener(abort, () controller.abort()); const response await fetch(fileUrl, { signal: controller.signal }); return response.json(); }这样当用户点击“停止思考”按钮时signal.abort()会立即终止fetch避免后台静默运行。技巧二systemPrompt的黄金长度是 128 字符LLM 的 context window 有限systemPrompt过长会挤占用户消息空间。实测发现100 字符LLM 理解力不足常忽略指令120–130 字符最佳平衡点既能明确角色“你是一个 Excel 数据校验专家”又留足空间给用户输入150 字符LLM 开始截断 prompt导致行为漂移。技巧三initialMessages恢复时必须过滤掉tool_callsPaperclip 的deserializeMessages会还原tool_calls字段但这些调用已过期。必须在恢复后手动清理const restored deserializeMessages(saved); // 过滤掉已执行完毕的 tool_calls const cleanMessages restored.map(msg ({ ...msg, tool_calls: undefined // 强制清除 }));否则 Agent 可能重复执行已失效的工具调用。5.3 性能调优实录从 8s 首屏到 1.2s 的三次迭代我们曾为客户优化一个含 5 个工具的 Paperclip 应用首屏加载时间从 8.2s 降至 1.2s第一次-3.5s将xlsx库从import * as XLSX from xlsx改为按需导入import { read, utils } from xlsx; // 替换 XLSX.read → read, XLSX.utils → utils减少打包体积 1.2MB。第二次-2.8s启用 Vite 的build.rollupOptions.external将paperclip/react设为 external让 CDN 提供// vite.config.ts build: { rollupOptions: { external: [paperclip/react] } }配合 unpkg CDNscript srchttps://unpkg.com/paperclip/reactlatest/dist/index.umd.js/script。第三次-1.9sWASM 模型预加载策略 —— 在App.tsx的useEffect中提前加载useEffect(() { if (typeof window ! undefined) { // 预加载模型但不执行 const provider createWasmProvider({ modelPath: /models/llama3-8b.gguf }); provider.loadModel(); // 此方法返回 Promise但不阻塞渲染 } }, []);最终指标Lighthouse 性能分 98首屏时间 1.2siPhone 12内存占用 120MB。6. 与 OpenClaw 的本质差异不是替代而是分层协作很多人问“Paperclip 和 OpenClaw 到底谁更好” 我的答案是它们解决不同层次的问题就像螺丝刀和电钻——你不会问‘哪个更好’而是看场景需要什么。OpenClaw 是‘AI Agent 操作系统’它管理 Agent 的生命周期、调度、监控、审计适合构建企业级 AI 中台比如把 20 个不同部门的 Agent 统一纳管、做权限分级、生成月度报告Paperclip 是‘AI Agent UI 组件’它让单个 React 组件获得 Agent 能力适合嵌入现有系统比如给 CRM 的客户详情页加一个“智能总结”按钮或给 ERP 的采购单页面加“风险预测”浮窗。我们的真实项目组合方案是✅ 用 OpenClaw 搭建公司级 Agent 中台统一管理模型、工具、计费✅ 用 Paperclip 将中台能力封装成company/ai-hooks包发布到私有 npm✅ 前端团队npm install company/ai-hooks在业务组件里useCustomerSummarizer()—— 完全感知不到底层是 OpenClaw 还是别的什么。这种分层架构既享受 OpenClaw 的企业级治理能力又获得 Paperclip 的前端开发体验。Paperclip 的modelProvider接口就是为这种协作预留的扩展点 —— 你可以轻松写一个createOpenClawProvider让它对接 OpenClaw 的/v1/chat/completionsAPI。最后分享一个小技巧Paperclip 的useAgentHook 支持refetch参数当你想强制 Agent 重新思考时不用清空消息历史只需const { refetch } useAgent({ /* config */ }); // 用户点击“重新分析”按钮时 refetch(); // Agent 会用当前 messages 重新生成思考链这个功能在调试阶段救了我无数次 —— 不用反复输入相同问题节省 70% 的测试时间。