Paperclip 接 OpenClaw 当执行层:邀请提示词、网关 preflight 与两次批准

2026-08-17

想让 Paperclip 负责派活、OpenClaw 负责真正动手,卡住人的往往不是「要不要这么干」,而是这条链路中间藏了几道批准、几个必须核对的字段。你在 Paperclip 里点了同意,任务发过去还是回一句 pairing required;或者 agent 建出来了,但适配器类型不对,怎么试都跑不通。

Paperclip 仓库里有两份文档专门讲这件事:一份是 OPENCLAW_ONBOARDING.md,开头就写「按这份检查表逐条来」,从启动到验收共十一步;另一份是 guides/openclaw-docker-setup.md,讲怎么在本地 Docker 里把 OpenClaw 跑起来配合调试。两份合起来就是官方给出的完整对接口径。

先说清楚边界:本文只依据 Paperclip 官方文档。OpenClaw 自己那侧的能力、配置项含义、设备配对内部是怎么实现的,这两份文档没展开,本文也不替它补。凡是文档没写的,下面一律标成「官方文档未说明」。另外我们没有实际安装运行过这套东西,所有步骤都是文档原文的转述,不是操作体验。

两份文档各管哪一段

分工其实很清楚,混着读容易串。

文档管什么典型产出
doc/OPENCLAW_ONBOARDING.md从启动到验收的十一步检查表,含权限、preflight、三个测试用例、通过标准一个能接活的 OpenClaw agent
docs/guides/openclaw-docker-setup.md本地 Docker 怎么把 OpenClaw 跑起来、环境变量有哪些、已知坑怎么绕一个可访问的 gateway 与 dashboard URL

openclaw-docker-setup.md 里还提到一条更省事的路:Paperclip 自带一套端到端的 join 冒烟脚本。

pnpm smoke:openclaw-join

文档说这套 harness 自动做完这几件事:创建邀请(allowedJoinTypes=agent)、发起 OpenClaw agent 的 join 请求(adapterType=openclaw)、board 批准、一次性 API key 领取(包含无效领取与重放领取的检查)、以及把 wakeup 回调投递到一个容器化的 OpenClaw 风格 webhook 接收端。默认用的是预置的 docker/openclaw-smoke 接收端镜像,好处是这一跑是确定性的,不需要手改 OpenClaw 配置。

有个权限前提别漏:这套 harness 做的是 board 治理级别的动作(建邀请、批准 join、唤醒新 agent)。文档写明,如果你的部署跑在 authenticated 模式,必须提供 board/operator 身份,否则脚本会提前退出并给出明确的权限错误。提供方式是两个环境变量之一:

PAPERCLIP_AUTH_HEADER="Bearer <token>" pnpm smoke:openclaw-join
# 或
PAPERCLIP_COOKIE="your_session_cookie=..." pnpm smoke:openclaw-join

部署模式本身怎么选,可以看 Paperclip 三种部署模式怎么选

手动流的头两步:3100 与 18789

检查表的第 1 步是以 auth 模式启动 Paperclip,给的命令和验活方式是:

cd <paperclip-repo-root>
pnpm dev --bind lan
curl -sS http://127.0.0.1:3100/api/health | jq

第 2 步是起一个干净的 OpenClaw Docker:

OPENCLAW_RESET_STATE=1 OPENCLAW_BUILD=1 ./scripts/smoke/openclaw-docker-ui.sh

然后在浏览器里打开脚本打印出来的 Dashboard URL——文档特意说明这个 URL 里带 #token=...。同样的能力在 Docker 指南里对应的是 pnpm smoke:openclaw-docker-ui,文档强调它是「零参数」的,不用先设任何配对相关的环境变量就能直接跑。它背后做的事列得很细:拉取或更新 openclaw/openclaw/tmp/openclaw-docker、构建 openclaw:local 镜像(除非 OPENCLAW_BUILD=0)、把隔离的冒烟配置写到 ~/.openclaw-paperclip-smoke/openclaw.json 和 Docker 的 .env、把 agent 默认模型钉到 OpenAI、通过 Compose 启动 openclaw-gateway(带一个必需的 /tmp tmpfs 覆盖)、探测并打印一个「从 OpenClaw 容器内部能访问到」的 Paperclip 主机地址,最后等健康检查通过、打印 http://127.0.0.1:18789/#token=...

常用的环境变量开关,文档给了一整张:

变量默认值 / 作用
OPENAI_API_KEY必需,从环境或 ~/.secrets
OPENCLAW_DOCKER_DIR默认 /tmp/openclaw-docker
OPENCLAW_GATEWAY_PORT默认 18789
OPENCLAW_GATEWAY_TOKEN默认随机
OPENCLAW_BUILD=0跳过重新构建镜像
OPENCLAW_RESET_STATE=1默认开,每次重置冒烟 agent 状态,避免陈旧鉴权/会话漂移
PAPERCLIP_HOST_PORT默认 3100
PAPERCLIP_HOST_FROM_CONTAINER默认 host.docker.internal

关于 disableDeviceAuth 这个词,两份文档说的不是同一处开关,读的时候最容易串:Docker 指南里的 OPENCLAW_DISABLE_DEVICE_AUTH(默认为 1)作用对象写的是 Control UI 的设备配对,目的是本地冒烟时省事,设成 0 则保持配对启用、之后用 devices 系列 CLI 命令批准浏览器;而检查表里要核对的 adapterConfig.disableDeviceAuthPaperclip 这一侧 agent 适配器配置上的字段,要求恰恰相反。别拿其中一处的默认值去推另一处该是什么样。

邀请提示词流:为什么是「生成一段 prompt 粘过去」

检查表第 3、4 步的做法有点特别:不是在 OpenClaw 里填 Paperclip 的地址,而是在 Paperclip 里生成一段提示词,整段粘进 OpenClaw 的主聊天,由 OpenClaw 自己走完加入流程。

文档给的路径是 http://127.0.0.1:3100/CLA/company/settings,在 Invites 区域点 Generate OpenClaw Invite Prompt,把生成出来的 OpenClaw Invite Prompt 复制走,作为一条消息整段粘进 OpenClaw 主聊天。如果它卡住不动,文档给了一句标准的追问:How is onboarding going? Continue setup now.——只发这一条。路径里的 CLA 在同一份文档后面的「CLA agents」里也出现过,指的是那家公司,官方文档没有解释这个缩写本身。

这一步看着像「复制粘贴大法」,但生成侧是有管控的。文档专门写了安全说明:邀请提示词由一个受控端点产出。

POST /api/companies/{companyId}/openclaw/invite-prompt

调用权限分两类:board 用户需要具备 invite 权限;agent 身份的调用方则被限制为该公司的 CEO agent。也就是说不是任意 agent 都能给外部发一张入场券。公司与角色这层怎么建,见 Paperclip 建第一家公司的完整步骤

第 5 步回到 Paperclip:批准 join 请求,然后确认这个 OpenClaw agent 确实出现在 CLA 的 agents 列表里。审批环节本身卡住怎么排查,另见 Paperclip 审批卡住怎么办

preflight:跑任务之前必须核对的四件事

第 6 步是整份检查表里最值得停下来看的一段,文档把它标成「跑任务测试之前必需」。核对项如下:

  • 新建出来的 agent 用的适配器必须是 openclaw_gateway不是 openclaw
  • 网关 URL 必须是 ws://wss://
  • 网关 token 不能是敷衍值(不能为空、不能是一个字符的占位符);
  • 配对方式要显式:默认要求设备鉴权开启(adapterConfig.disableDeviceAuth 为 false 或不存在),并且持久化了 adapterConfig.devicePrivateKeyPem

文档还补了两句约束:OpenClaw Gateway 适配器的配置界面在正常 onboarding 场景下不该暴露 disableDeviceAuth;正常 onboarding 也不要靠 disableDeviceAuth 走通。

如果你手上有 board 身份,可以直接查接口核对:

AGENT_ID="<newly-created-agent-id>"
curl -sS -H "Cookie: $PAPERCLIP_COOKIE" "http://127.0.0.1:3100/api/agents/$AGENT_ID" | jq '{adapterType,adapterConfig:{url:.adapterConfig.url,tokenLen:(.adapterConfig.headers["x-openclaw-token"] // .adapterConfig.headers["x-openclaw-auth"] // "" | length),disableDeviceAuth:(.adapterConfig.disableDeviceAuth // false),hasDeviceKey:(.adapterConfig.devicePrivateKeyPem // "" | length > 0)}}'

期望值文档写得很死:

字段期望
adapterTypeopenclaw_gateway
tokenLen≥ 16
hasDeviceKeytrue
disableDeviceAuthfalse

注意 token 是从请求头里取的,jq 那段先看 x-openclaw-token,取不到再退到 x-openclaw-auth。适配器这一层整体有哪几类、各自怎么接,可以对照 Paperclip 五类适配器怎么选 一起看。

pairing required 不是坏了,是第二次批准

这是最容易误判的一处。文档把预期讲得很直白:干净跑一遍的期望是第一个任务不需要任何手动配对命令就能成。适配器在首次遇到 pairing required 时,会尝试一次自动配对批准并重试——前提是共享的网关鉴权 token 或密码是有效的。

但自动配对也会完不成,文档举了两种情形:token 不匹配,或者根本没有待处理的配对请求。这时候首次网关运行仍然会返回 pairing required。关键的一句是:这是与 Paperclip 邀请批准彼此独立的另一次批准,必须在 OpenClaw 里自己去批。批完再重试任务。

本地 Docker 冒烟场景下,文档给了从宿主机批准的办法:

docker exec openclaw-docker-openclaw-gateway-1 sh -lc 'openclaw devices approve --latest --json --url "ws://127.0.0.1:18789" --token "$(node -p \"require(process.env.HOME+\\\"/.openclaw/openclaw.json\\\").gateway.auth.token\")"'

想先看清楚现在有哪些待批、哪些已配对,把命令换成 openclaw devices list --json,token 同样从容器里的 openclaw.json 读。这些命令本身属于 OpenClaw 一侧,Paperclip 文档只是把它当作可用的批准手段列出来,更多参数含义官方这两份文档未说明。

容器里的 127.0.0.1 不是你的主机

回调打不通,多半栽在这条上。Docker 指南写得很清楚:本地同主机冒烟时,默认回调用的是 http://127.0.0.1:<port>/webhook;但在 OpenClaw 容器内部,127.0.0.1 指向的是容器自己,不是你宿主机上的 Paperclip。

所以给容器里 OpenClaw 用的邀请/onboarding 地址,要用脚本打印出来的那个 Paperclip URL,通常是 http://host.docker.internal:3100。如果 Paperclip 以主机名错误拒绝了这个容器可见的地址,在宿主机上放行:

npx paperclipai allowed-hostname host.docker.internal

然后重启 Paperclip、重跑冒烟脚本。远程 OpenClaw 的情形,文档建议用一个真正可达的主机名——Docker 主机别名、Tailscale 主机名或公网域名都行;在 authenticated / private 模式下,还要确认这些主机名在允许列表里,同样用 npx paperclipai allowed-hostname <host> 加。

A/B/C 三个用例与通过标准

第 7 到 9 步是三个递进的验收用例,用「标记字符串」来判定,不用靠观察:

  • Case A(手动 issue):建一个 issue 指派给 OpenClaw agent,指令写成「发一条评论 OPENCLAW_CASE_A_OK_<timestamp> 然后标记完成」,验证 issue 状态变成 done 且评论存在。
  • Case B(消息工具):再建一个 issue,指令是通过 message tool 把 OPENCLAW_CASE_B_OK_<timestamp> 发到主 webchat,再把同样的标记评论到 issue 上,然后标完成。两处都要验:issue 上的标记评论,以及主聊天里出现的标记文本。
  • Case C(新会话的记忆/技能):在 OpenClaw 里开一个 /new 会话,让它在 Paperclip 建一个标题唯一的新 issue OPENCLAW_CASE_C_CREATED_<timestamp>,再回 Paperclip 确认这个 issue 真的建出来了。

排查期间可以跟日志,文档给的命令带两个 compose 文件,第二个是脚本生成的覆盖文件:

docker compose -f /tmp/openclaw-docker/docker-compose.yml -f /tmp/openclaw-docker/.paperclip-openclaw.override.yml logs -f openclaw-gateway

最后文档把通过标准又复述了一遍:preflight 是 openclaw_gateway 加非占位 token(tokenLen >= 16);配对方式是配置了稳定的 devicePrivateKeyPem 且设备鉴权开启的默认路径;Case A 要 done 加标记评论;Case B 在此之上还要主聊天里能看到消息;Case C 是原任务完成且 /new 会话确实建出了新 issue。这三个用例覆盖的是「接单」「往外发消息」「跨新会话还记得怎么调 Paperclip」三种不同能力,前两个过了第三个不过,是另一类问题。

什么时候不适用,以及还没解决的部分

这条链路的文档定位要认清楚:openclaw-docker-setup.md 标题里写的就是 Local Development,前置条件列的是 Docker Desktop v29+、构建镜像可用内存 2 GB 以上、~/.secrets 里至少有 OPENAI_API_KEY。它给的两个方案里,Option A 是 Docker Sandbox(文档标为推荐,理由写的是基于 microVM 的隔离更好、设置更简单),Option B 是 Docker Compose 兜底,供 Docker Desktop 低于 v29 时用。生产部署要怎么落,这两份文档没讲,只能另找部署侧文档。

几个已知坑文档也直说了:容器起不来报 no space left on device,是 Docker Desktop 虚拟磁盘满了,用 docker system df 看用量、docker system prune -fdocker image prune -f 清;报 Unable to create fallback OpenClaw temp dir: /tmp/openclaw-1000 是容器写不了 /tmp,只在 Compose 方案上出现,要给 openclaw-gatewayopenclaw-cli 两个服务都加 tmpfs: - /tmp:exec,size=512M,Sandbox 方案不受影响;社区构建的沙箱模板镜像有的还是 Node 20,而 OpenClaw 要求 Node >= 22.12.0,文档建议改用自建的 openclaw:local;网关启动后大约要 15 秒才响应,别急着打 http://127.0.0.1:18789/;Compose 打出的 CLAUDE_AI_SESSION_KEY 未设置告警是无害的。

还有几件事这两份文档没给答案:openclawopenclaw_gateway 两种适配器类型的差别到底在哪(join 冒烟里发起请求用的是前者,preflight 又要求最终是后者),文档只给了要核对成什么样、没解释为什么;自动配对失败时 token 具体在哪一环对不上,也没有更细的定位步骤;生产环境下这条链路的鉴权与网络怎么收口,同样没写。真要照着做,最稳的顺序还是先跑一遍 pnpm smoke:openclaw-join 确认基础链路通,再上手动流,出问题时先用 preflight 那条 curl 把四个字段核一遍——检查表把它排在任务测试之前,本身就是在说这四个字段错了后面全白测。

延伸阅读


本文依据 Paperclip 官方仓库(github.com/paperclipai/paperclip,MIT 协议)的 docs/ 用户文档 与 doc/ 下的规范、运维与连接器手册整理,核对日 2026-08-17。 我们没有部署或运行过 Paperclip,因此不涉及界面外观与操作手感; 部分规范文档描述的是目标架构而非当前实现,文中已就地标注,不构成对实际行为的保证。 请以仓库最新内容为准。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。