外挂集成 Cookbook
5 类常见外部系统的集成对话模板——数据库 / 内部 API / SaaS / 消息队列 / 对象存储。每类都给一段直接复制的对话,让龙虾帮你把龙虾接到你的系统上。
使用方法
- 先读 指挥中枢模式 理解为什么龙虾不该直接连数据库
- 再读 带 API 的 Skill 开发 掌握 skill 基本写法
- 然后从下面挑你需要的集成类型,复制对话模板,改
〈...〉占位符
通用铁律
所有集成对话模板都遵守三条铁律(参考指挥中枢模式):
- 龙虾决策、外挂执行、不可逆操作必须人工确认
- 敏感数据不进龙虾上下文,脱敏后再给
- 凭证在环境变量,永远不硬编码、不打印
一、数据库(PostgreSQL / MySQL)
集成模式
绝不让龙虾直接连数据库执行 SQL。中间隔一层 skill:
| 层 | 职责 |
|---|---|
| 龙虾 | 理解"查用户最近订单",决定调 get_user_orders skill |
| Skill(外挂) | 把"用户"翻译成 user_id,执行预定义的 SQL,脱敏后返回 |
| 数据库 | 实际存数据 |
对话模板:查询类
帮我写一个数据库查询 skill:
目标:让龙虾能帮我查用户的最近订单,但**不直接暴露数据库**。
需求:
- skill 名:db_query_orders
- 输入:user_id(字符串)、limit(整数,默认 10)
- 数据源:我们的 PostgreSQL(连接信息我会加到 ~/.openclaw/.env,变量名 DB_HOST / DB_NAME / DB_USER / DB_PASSWORD)
- 查询 SQL:SELECT order_id, created_at, total_amount FROM orders WHERE user_id = %(user_id)s ORDER BY created_at DESC LIMIT %(limit)s
- 返回:JSON 格式,orders 数组(每条含 order_id、created_at、amount)
- **脱敏**:不要返回客户的手机号、地址、邮箱(即使表里有也不返回)
- 错误处理:连接超时 5 秒;查询失败返回 {"ok": false, "error": "..."}
- 安全:用参数化查询,绝不要拼字符串(防 SQL 注入)
写完后测一次 user_id="test_user",把返回贴给我看。对话模板:写入类(必须人工确认)
帮我写一个数据库写入 skill,但有特殊要求:
目标:让龙虾能起草"标记订单为已发货"的 SQL,但**不能自动执行**。
流程:
1. 龙虾收到"把订单 ORDER_X 标记为已发货"的指令
2. skill 生成对应的 UPDATE SQL,但**不执行**
3. skill 返回 {"ok": true, "needs_confirmation": true, "proposed_sql": "...", "warning": "..."}
4. 龙虾看到 needs_confirmation=true,会主动问我"确认执行吗"
5. 我回复"确认"后,龙虾才调另一个 db_execute_confirmed skill 真正跑
理由:写入数据库是不可逆操作,必须人工二次确认。安全要点(对话里强调)
所有数据库 skill 必须遵守:
1. DB 用户用最小权限——查询 skill 只给 SELECT 权限,更新走另一个受限账号
2. 敏感字段(手机号、身份证、邮箱)在 skill 层脱敏,龙虾永远看不到原文
3. 慢查询加 statement_timeout(PostgreSQL)或 max_execution_time(MySQL)
4. 所有 SQL 用参数化,不拼字符串二、内部 REST API
对话模板
帮我写一个调内部 API 的 skill:
目标:让龙虾能查询我们的内部 〈客户管理 / 订单 / 库存〉 系统。
需求:
- skill 名:internal_api_call
- 输入:endpoint(路径,如 /api/customers/123)、method(默认 GET)
- API 基地址:从环境变量 INTERNAL_API_BASE 读(如 http://internal-api.local)
- 认证:Bearer Token,从环境变量 INTERNAL_API_TOKEN 读
- 超时:10 秒
- 返回:JSON,{"ok": true, "data": ...} 或 {"ok": false, "error": "...", "status": ...}
特别注意:
1. 内网域名解析——龙虾容器看不到我们 LAN 的 DNS,可能要用 IP 而不是域名,请帮我判断
2. 如果内部 API 用 mTLS(客户端证书),证书文件路径告诉我,我挂载到容器里
3. 错误响应 body 截断到 500 字符,避免长 body 撑爆龙虾上下文
4. 不要把 Authorization header 的值打印到日志里
写完后测一次 endpoint="/health",把返回贴给我看。常见坑(对话里让龙虾预防)
| 坑 | 症状 | 怎么提 |
|---|---|---|
| 内网域名解析不了 | "connection refused" | "如果 INTERNAL_API_BASE 是内网域名,请确认龙虾容器能解析;如果不能,给我改成 IP 的建议" |
| mTLS 客户端证书 | "SSL verification failed" | "如果 API 需要 mTLS,告诉我证书挂载路径,代码里加 cert_file 参数" |
| 服务要特定 User-Agent | 403 | "有些 API 会挡默认 Python UA,必要时加 User-Agent: Mozilla/5.0" |
| 超时层级 | 龙虾报"skill timeout" | "skill 内部超时(10s)要比龙虾默认(60s)小" |
三、SaaS(Stripe / Notion / Linear / GitHub / Slack)
每个 SaaS 都有自己的 SDK,但用 REST API + Bearer token 更通用。
对话模板(以 Linear 为例)
帮我写一个 Linear 集成 skill:
目标:让龙虾能查我分配给我的 Linear 任务。
需求:
- skill 名:linear_my_issues
- 输入:team_id(字符串,可选,不传则查所有团队)
- 数据源:Linear GraphQL API(https://api.linear.app/graphql)
- 认证:LINEAR_API_KEY 从环境变量读
- 查询:用 GraphQL,filter assignee.isMe=true,按 status 分组
- 返回:JSON,按 status 分组的 issue 列表(identifier、title、state)
- 超时:10 秒
- **脱敏**:不返回 assignee 的邮箱、内部 UUID
写完后测一次,把我的 Linear 当前任务列出来。各家 SaaS 的特点(对话里提醒龙虾)
我后面可能还要集成其他 SaaS,记一下各家注意事项:
- Stripe:强烈建议用 test mode key 调试,避免真扣钱
- Notion:数据库查询要分页,默认 100 条
- Linear:GraphQL 一个请求可以拿很多字段,注意别拿太多
- GitHub:速率限制严格,要处理 403 + Retry-After header
- Slack:发消息和读消息是不同 scope,token 要分开申请共性安全要点
所有 SaaS 集成必须:
1. API key 加权限范围(scope)——能只读就别给读写
2. Webhook 验签——如果龙虾接收 SaaS 的 webhook,必须验签(防伪造)
3. 不要让龙虾自动调"删除/扣款"类 API——同数据库写入,走"起草+人工确认+执行"四、消息队列(Redis / RabbitMQ)
用途
龙虾跟外部系统异步通信——龙虾把任务推到队列,外部 worker 消费后回写结果。
对话模板
帮我写两个 skill 配合消息队列:
目标:让龙虾把长任务(爬虫、批处理)推到 Redis 队列异步执行。
Skill 1 - enqueue_task:
- 输入:task_type(字符串)、payload(任意 JSON)
- 动作:把 {"type": ..., "payload": ...} 推到 Redis list "openclaw:tasks"
- 返回:{"ok": true, "queued": true, "msg_id": ...}
- Redis 连接:从环境变量 REDIS_URL 读,socket_timeout=5
Skill 2 - poll_results:
- 输入:msg_id(要查的任务 ID)
- 动作:从 Redis hash "openclaw:results" 查这个 msg_id 的结果
- 返回:{"ok": true, "status": "pending|done|failed", "result": ...}
- 说明:这个 skill 用于龙虾 cron 定期检查任务状态
外部 worker(不归龙虾管)会从 openclaw:tasks 拉消息处理,把结果写到 openclaw:results。什么时候用队列,什么时候直接 API
我以后判断一个任务该用队列还是直接 API:
- 秒级返回 → 直接 REST API
- 分钟级返回(爬虫、批处理)→ 消息队列
- 可能失败需要重试 → 消息队列
- 多 worker 并发消费 → 消息队列
请记住这个判断规则,下次我让你集成时主动建议。五、对象存储(S3 / MinIO)
用途
大文件交换——龙虾生成报告保存到 S3,外部系统按需取。避免把大文件塞进对话上下文。
对话模板
帮我写一个对象存储 skill:
目标:让龙虾把生成的报告(markdown / PDF)上传到 S3 / MinIO,返回 key 而不是内容。
需求:
- skill 名:upload_report
- 输入:content(bytes 或文件路径)、key_prefix(默认 "reports")
- 动作:
1. 生成 key:〈key_prefix〉/YYYY/MM/DD/HHMMSS.〈ext〉
2. 上传到 S3 / MinIO(endpoint 从环境变量 S3_ENDPOINT 读,S3 留空)
3. Bucket 从环境变量 S3_BUCKET 读
4. 凭证:S3_ACCESS_KEY / S3_SECRET_KEY 从环境变量读
- 返回:{"ok": true, "key": "...", "size": 〈字节数〉}
- **关键**:不返回文件内容本身(避免撑爆上下文),只返回 key
配套再写一个 download_report skill:
- 输入:key、byte_range(可选,如 "0-1024" 只取前 1KB)
- 返回:内容片段(如果文件大,默认只取前 4KB 给龙虾预览)常见坑
S3 集成的几个注意点:
1. 不要让龙虾直接读大文件进上下文——skill 返回 key 即可,龙虾按需让另一个 skill 读片段
2. 分享文件给别人时,生成 1 小时有效的 presigned URL,别把 object 设成 public read
3. 生命周期策略:reports/ 下的对象设 30 天自动删除,避免成本失控六、安全清单(所有集成都要过一遍)
让龙虾在每个集成完成后自检:
请对我刚写的所有 skill 做安全审计,逐项检查:
- [ ] 凭证都在环境变量,不硬编码
- [ ] 凭证不打印到 stdout 或日志
- [ ] 网络请求都有超时(建议 5-10s)
- [ ] 敏感字段在 skill 层脱敏
- [ ] 不可逆操作(写入、删除、扣款)走"起草+人工确认"流程
- [ ] DB 用户用最小权限
- [ ] API token 用最小 scope
- [ ] Webhook 入口做验签
- [ ] 大文件不进龙虾上下文,存对象存储返回 key
有不符合的,列出来给我修复建议。七、下一步
- 主 agent + 多 skill + 外挂的协同:多 Agent + 外挂协同
- 把这一切稳定跑在生产环境:生产部署实战
