技能最佳实践:提示词写得好不算完事儿
📌 温馨提示:本章是第 10 章的进阶篇。第 10 章教会你”怎么把 Skill 写出来”,本章教你”怎么让写出来的 Skill 不会在生产环境掉链子”。两个章节是亲兄弟,建议一起服用。
同样一个 Skill,有人越写越稳,有人越写越乱,差别通常不在提示词有多花哨,而在规则有没有写清楚、边界有没有收紧。本章就是帮你擦屁股的——不对,是帮你提前避开坑。
本章你将学会什么
Section titled “本章你将学会什么”- 把输入输出固定成可测试、可追溯的结构(就像给 Skill 穿上防弹衣)
- 用”重复执行不乱套 + 复盘重现”让问题可定位,而不是靠猜
- 建立重试、超时、兜底方案(降级)三层保护(就像给 Skill 买保险)
- 用工具策略、审批与循环检测控制成本和风险(别让 Skill 偷偷帮你烧钱)
- 让失败提示对小白读者友好且可执行(别让用户对着报错信息发呆)
- 你已经完成第 10 章示例 Skill(知道怎么写一个能跑的东西)
- 你能使用以下两个命令:
# 查看 Skill 信息openclaw skills info <name>
# 实时看日志openclaw logs --follow如果这两个命令还不熟,先去第 10 章练练手,别急着往下走。
11.1 结构化输入输出
Section titled “11.1 结构化输入输出”💡 一句话解释:结构化就是给数据穿制服——格式统一了,机器好处理,人也看得懂。
11.1.1 输入先标准化,再交给模型
Section titled “11.1.1 输入先标准化,再交给模型”很多新手会犯的错:一上来就把用户的原始输入直接塞给模型。结果模型很困惑,输出很随机,排错很痛苦。
正确姿势:先把输入字段收紧,再让 Skill 执行。
以”写日报”这个 Skill 为例,入参最少保持这样:
| 字段名 | 类型 | 必须? | 什么意思 |
|---|---|---|---|
date | 字符串 | 必须 | 日期,比如 “2026-02-17” |
highlights | 字符串数组 | 必须 | 今天完成的重要事项 |
blockers | 字符串数组 | 可选 | 遇到的阻碍,没阻碍就不填 |
为什么要这么严格?好处很直接:
- 排障时你能快速判断是”输入有问题”,还是”执行流程有问题”
- 模型收到的数据格式统一,输出也更稳定
- 将来写自动化测试的时候,有东西可断言
11.1.2 输出要同时服务”人”和”机器”
Section titled “11.1.2 输出要同时服务”人”和”机器””输出不能只让人类看得爽,也要让机器能解析。推荐统一返回骨架:
{ "status": "ok", "summary": "已生成日报草稿", "data": { "file": "reports/2026-02-17-daily-report.md" }, "nextAction": "请检查"阻塞与风险"是否完整"}这四个字段各有各的用处:
status:机器判断成功还是失败summary:人类一眼看懂刚才发生了什么data:具体产出物(文件路径、计算结果等)nextAction:告诉用户接下来该干嘛
这样前端展示、日志检索、自动化回归都能直接用,一鱼三吃。
11.1.3 命名与字段稳定性
Section titled “11.1.3 命名与字段稳定性”重要提醒:字段名一旦发布,尽量别随手改。
比如把 summary 改成 message,看起来只是个小改动,但会导致:
- 下游脚本解析失败
- 自动化测试全部报错
- 监控告警可能误报或漏报
实操建议(抄作业版):
- 字段名尽量短且语义稳定(
summary就比overallSummaryText好记) - 新字段只新增,不轻易删除旧字段
- 删除字段前先给过渡期版本(比如 v1 用
summary,v2 同时支持summary和message,v3 再废弃summary)
11.2 重复执行不乱套与复盘重现
Section titled “11.2 重复执行不乱套与复盘重现”💡 一句话解释:幂等就是”同一件事做两次跟做一次结果一样”,不会越跑越乱。
11.2.1 防重复键(幂等键):给每次执行一个”身份标签”
Section titled “11.2.1 防重复键(幂等键):给每次执行一个”身份标签””幂等的核心是:同一输入重复执行,不应该越跑越乱。
常见做法是生成一个”防重复键”,比如:
# 用日期 + 项目名当唯一标识IDEMPOTENT_KEY="daily-report-2026-02-17-张三的项目"这个键可以写入输出文件名:
reports/2026-02-17-daily-report.md或者写入元数据里。下次再跑同样的输入,系统一看”哦,这个已经处理过了”,就直接返回已有结果,不会重复生成。
11.2.2 写入策略:先读后写
Section titled “11.2.2 写入策略:先读后写”建议把”先读后写”直接写进 Skill 规则,流程如下:
- 先检查:目标文件是否存在?
- 再决定:根据策略覆盖(直接替换)还是追加(后面接着写)
- 返回动作:告诉用户实际采取了什么操作
这样读者就能理解”为什么这次覆盖、不是新建”,不会觉得系统在抽风。
11.2.3 可复盘重现:为排障留证据
Section titled “11.2.3 可复盘重现:为排障留证据”最低要求(必须做到):
- 保留输入快照(敏感信息脱敏后)
- 保留关键决策点(例如”为什么走了降级分支”)
- 保留输出路径
配合日志命令:
# 实时看 Skill 跑的过程openclaw logs --follow你就能把”偶现 bug”变成”可定位问题”。下次出问题直接翻日志,不用抓耳挠腮猜原因。
11.3 重试、超时与兜底方案
Section titled “11.3 重试、超时与兜底方案”💡 一句话解释:重试是”再试一次”,超时是”等太久就放弃”,兜底是”实在不行给个保底结果”。
11.3.1 错误分类:先判定,再处理
Section titled “11.3.1 错误分类:先判定,再处理”遇到错误先别急着重试,先分清楚是哪一类:
| 错误类型 | 例子 | 怎么处理 |
|---|---|---|
| 不可恢复 | 参数缺失、权限明确不足、配置错误 | 别重试,直接报错告诉用户 |
| 可恢复 | 短时网络抖动、临时 I/O 阻塞 | 可以重试 |
简单说:不可恢复的错误重试也没用,可恢复的错误才值得重试。
11.2.2 重试与超时的推荐值
Section titled “11.2.2 重试与超时的推荐值”对初学者最稳的默认值(直接抄):
| 参数 | 推荐值 | 什么意思 |
|---|---|---|
| 重试次数 | 1~2 次 | 试太多次没用,还浪费时间 |
| 超时时间 | 每步 10~30 秒 | 超过这个时间还没动静,就算了 |
| 退避间隔 | 1s → 2s | 第一次等 1 秒,第二次等 2 秒(指数退避最简版) |
超过这个强度,读者通常会感觉”它卡死了”——别问我是怎么知道的。
11.3.3 兜底方案(降级):失败时也要有可交付结果
Section titled “11.3.3 兜底方案(降级):失败时也要有可交付结果”兜底策略示例(从好到差):
- 首选:写入完整结构化内容(正常完成任务)
- 兜底:只写”摘要 + 待补充项”(部分完成,告诉用户还缺什么)
- 最终:返回失败说明与可执行修复动作(没完成但给了下一步指引)
核心原则:就算失败,也要给用户一个”下一步还能继续做”的状态。
11.4 限流与成本边界
Section titled “11.4 限流与成本边界”💡 一句话解释:限流就是”别让 Skill 放飞自我疯狂调用工具”,成本边界就是”别让它偷偷帮你烧钱”。
11.4.1 先收工具,再谈智能
Section titled “11.4.1 先收工具,再谈智能”用 tools.profile + allow/deny 先缩小工具集合:
{ tools: { profile: "coding", // 基础工具集选 "coding" deny: ["group:runtime", "group:web"], // 禁用这两类工具 },}对大多数内容生产 Skill,profile: "coding" + 禁用 group:runtime 和 group:web 就够用了。意思是说:“你就老实写代码,别想去跑服务器、别想去调网页。“
11.4.2 高风险执行必须走审批
Section titled “11.4.2 高风险执行必须走审批”一旦 Skill 涉及 exec(执行主机命令),建议开启审批与白名单策略。
先解释几个概念:
- allowlist(白名单):只有名单上的命令才能跑
- ask(询问):遇到不在名单的命令,问用户同不同意
- askFallback: deny:问了也不给面子,不同意就是不同意
- autoAllowSkills:把 Skill 声明的 CLI 自动放进白名单(只在你信任这个 Skill 来源时打开)
推荐最小策略(按 agent 粒度):
{ "defaults": { "security": "deny", // 默认拒绝所有 "ask": "on-miss", // 不在名单就问用户 "askFallback": "deny", // 问也不给通过 "autoAllowSkills": false // 不自动放行任何 Skill }, "agents": { "main": { "security": "allowlist", // main agent 用白名单模式 "ask": "on-miss", "askFallback": "deny", "autoAllowSkills": true // 信任来源,可以自动放行 } }}再配一层 safeBins,把无需落盘、仅处理 stdin 的低风险命令放行:
{ "tools": { "exec": { "safeBins": ["jq", "grep", "cut", "sort", "uniq", "head", "tail", "tr", "wc"] } }}默认思路:宁可多一次确认,也不要让系统悄悄做错一次危险动作。
⚠️ 特别注意:
exec相关配置是生产环境的命门,配错了轻则浪费钱,重则安全事故。请务必理解每个字段的含义再动手。
11.4.3 识别”空转循环”
Section titled “11.4.3 识别”空转循环””官方提供 tools.loopDetection(默认关闭)。当你发现 Skill 在”重复调用同类工具但没有进展”时,可以启用:
{ tools: { loopDetection: { enabled: true, // 开启循环检测 repeatThreshold: 3, // 同一类工具调用 3 次就警告 criticalThreshold: 6, // 调用 6 次还没进展就强制停止 }, },}这个功能就像”防沉迷系统”——检测到 Skill 在做无用功,及时止损。
11.5 失败可解释与用户体验
Section titled “11.5 失败可解释与用户体验”💡 一句话解释:好的错误信息就像好的老师——不骂你笨,而是告诉你下一步怎么做。
11.5.1 对小白读者的错误文案模板
Section titled “11.5.1 对小白读者的错误文案模板”推荐固定模板(照抄就能用):
- 发生了什么(一句话说清楚)
- 系统已尝试什么(让用户知道不是平白无故失败)
- 你下一步怎么做(带具体命令或操作路径)
示例:
❌ 错误示范(看了等于没看):
Error: File write failed✅ 正确示范(看完就知道下一步):
生成日报失败:目标目录没有写权限。我已尝试写入 reports/,但操作系统拒绝。请先执行 ls -ld ~/.openclaw/workspace/reports 检查权限,再重试。
11.5.2 把”人工可理解”放在”技术细节”前面
Section titled “11.5.2 把”人工可理解”放在”技术细节”前面”错误信息顺序建议:
- 第一行:人话总结(初中生能看懂)
- 第二行:关键字段(文件路径、命令、状态码)
- 第三行:详细诊断(必要时折叠,技术人员才看)
这样既照顾小白,也不会丢掉工程排障需要的信息。
11.5.3 发布前质量门禁(实操版)
Section titled “11.5.3 发布前质量门禁(实操版)”发布前至少跑一轮清单。复制下面这个清单,每项都打勾:
[ ] 正常输入能成功[ ] 缺参数能给明确提示[ ] 非法输入不会卡死[ ] 同一输入重复执行结果稳定[ ] 日志能还原关键步骤[ ] exec approvals 已配置 allowlist + on-miss + askFallback: deny[ ] safeBins 仅保留最小集合,未误放高危命令[ ] 无需读者猜测"下一步"全部打勾再发布,别偷懒。
- 结构化 I/O 是 Skill 可维护性的地基,不是”可有可无”。输入收紧、输出统一、日志可查,这三样缺一不可。
- 重复执行不乱套(幂等)+ 可复盘重现 + 重试兜底是一个整体,少一项都容易在真实环境翻车。它们就像 Skill 的防弹衣、记录仪和保险丝。
- 成本与风险管理要前置到工具策略层,不能只靠模型”自觉”。该关的工具关掉,该审批的命令审批,别等出事了再后悔。
- 好的失败提示能显著降低读者挫败感,这本身就是工程质量。错误信息写得烂,读者流失;写得好,读者信任。
🎯 下一章预告:第 12 章会讲 Skill 的测试与迭代——怎么从”能跑”变成”敢让用户跑”。敬请期待。