Skip to content
Back to skills

Cloud Api Recipe Authoring

BSecurity

Author or revise a cloud-api-operations recipe (config/source/skills/cloud-api-operations/references/recipes/). Encodes why the long tail of control-plane capabilities is deliberately NOT wrapped as MCP/CLI tools, the API-first admission test for whether a capability deserves a recipe, the negative and positive lists, the fixed recipe structure, the writing rules distilled from writing-for-agents, the user-facing copy red lines, and the product regeneration/verification pipeline. Also routes ...

  • 1,130 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 1, 2026
ai-agentspythongojavashellbashnodegitapi

Works with

  • cli
  • api
  • mcp

Security analysis

B85/100
  • highPerforms destructive filesystem operations

Pro scans all 3 files and shows the line behind each finding

Scanned October 1, 2026

npx -y skills add TencentCloudBase/CloudBase-MCP --skill cloud-api-recipe-authoring --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Cloud Api Recipe Authoring?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Cloud Api Recipe Authoring
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/tencentcloudbase-cloud-api-recipe-authoring-cloudbase-ai-toolkit/badge)](https://www.skillsdirectory.com/skills/tencentcloudbase-cloud-api-recipe-authoring-cloudbase-ai-toolkit)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: cloud-api-recipe-authoring
description: "Author or revise a cloud-api-operations recipe (config/source/skills/cloud-api-operations/references/recipes/). Encodes why the long tail of control-plane capabilities is deliberately NOT wrapped as MCP/CLI tools, the API-first admission test for whether a capability deserves a recipe, the negative and positive lists, the fixed recipe structure, the writing rules distilled from writing-for-agents, the user-facing copy red lines, and the product regeneration/verification pipeline. Also routes contributors (and their agents) to the contribution flow and the pre-PR self-test protocol in references/contributing.md. Use when adding a recipe, judging whether a scenario belongs in the recipe set, updating the recipes index, re-checking existing recipes against the admission test, or onboarding someone who wants to submit one."
alwaysApply: false
---

# Cloud API Recipe Authoring

目标:让**「AI 可以 100% 操作云开发」**可验证 —— 每个高频管控面场景都有一篇能照着跑通的 recipe,且每篇都建立在**公开 API** 之上。

## When to use

- 新增一篇 recipe,或修改现有一篇
- 判断某个能力**该不该**进 recipe 集(准入)
- 更新 `config/source/skills/cloud-api-operations/references/recipes/README.md` 的目录表与状态列
- 复核已有 recipe 是否仍满足准入(Action 是否已公开、是否已被专用 MCP 工具覆盖)
- 有人(或他的 Agent)要提交一篇 recipe —— 把 `./references/contributing.md` 给他

## 为什么不全部封装进 MCP / CLI(分工原则)

产品排期里「对外开放 API」通常不优先,于是有一个固定落差:**控制台上了功能,AI 却操作不了**。因果链是单向的 —— 没有公开 API,CLI / MCP 就无从封装,AI 只能用鼠标。

补齐落差有两条路,我们不走「全都封装」那条:

| 做法 | 代价 |
| --- | --- |
| 把能力都补成 API、再全部封装成工具 | 工具面持续膨胀:模型选错工具的概率上升,工具描述吃掉上下文预算,每个工具都要跟 API 变更一起维护 |
| **只封装核心,长尾走 recipe** | 要多维护一份文档,但工具面稳定,长尾能力照样能被 AI 操作 |

**核心能力已经封装过了**(`query*` / `manage*` 工具家族 + CLI),剩下的大量接口**不需要**封装。一个能力该去哪:

| 能力形态 | 归属 |
| --- | --- |
| 有公开 API + 高频核心 | 已在 MCP / CLI 工具里 —— 直接用,不要另写 recipe |
| 有公开 API + 长尾(串联多 Action、有非平凡前置、有踩坑或回查义务) | **写 recipe**(本 skill) |
| 有公开 API + 单接口、读文档即可调 | 既不封装也不写 recipe —— agent 现场查索引 |
| **没有公开 API**(只在控制台可见) | 谁也封装不了 —— **产品缺口**,推产品先开放 API;这里也没有 recipe 可写 |

最后一行是硬约束:**没有公开 API,能力对 AI 的可用性就是 0**,这不是「我们封装得不够」的问题。

## 准入:API first(硬门槛,先过这一关再动笔)

三条必须同时满足:

1. **有公开云 API**:目标 Action 已列入公开 API 概览 / 接口文档(`https://docs.cloudbase.net/ai/cloudbase-ai-toolkit/api-reference.md` 或产品官方文档)。
2. **语言无关可调用**:云 API 直调 / 官方 SDK / CLI / MCP 任一条通路都行 —— 但必须是**公开 API 的封装**,不能反过来「只有某个语言的 SDK 封装、没有公开 Action」。
3. **写操作能由使用者独立完成**:含签名、必要的前置查询与加解密。若关键步骤依赖客户端拿不到的内部配置,就不合格。

不满足时的处理:

- **不要**写进 `config/source/skills/`(那是对外发布面)
- 同时当**产品缺口**反馈:请官方把这些 Action 列入公开概览,或给出语言无关的调用路径
- 归档:维护者放 `specs/cloud-api-skill/pending-recipes/`(内部目录,不进版本控制),正文顶部写清「为什么未通过 + 解封条件」;外部贡献者不提 PR,按 `./references/contributing.md` 开 Issue 说明

踩过的实例见下文「反面 case」—— 驳回后不进公开集,也不要把归档内容抄回来。

## 负向清单(不该写 recipe)

- 读公开 API 概览 + 单个接口文档就能直接调的(单个 Action、参数可查、无需串联)→ 让 agent 走 `SKILL.md §1` 的发现流程现场查
- 已有专用 MCP 工具覆盖的(`query*` / `manage*` 家族)→ 路由到工具,不写文档
- 纯参数含义 / 概念说明 → 属于官方文档,路由过去
- 只对某个 SDK 语言成立的用法(除该 SDK 外没有语言无关通路)

## 正向清单(必须写 recipe)

- 需要**串联多个 Action 或多个产品**(例:monitor 策略族 + postgres `DescribeDBInstances`)
- 有**非平凡前置**:CAM 授权升级、临时密钥、环境绑定、签名或加密
- 有**实测踩坑**:报错信息 → 正确做法,靠读文档推不出来
- 调用后有**回查 / 清理义务**:幂等查重、解绑、残留维度清理

## 反面 case(准入驳回长什么样)

**集成中心 UserKey 密钥对管理** —— 全文在内部归档 `specs/cloud-api-skill/pending-recipes/integration-userkey.md`(不进版本控制,外部读者看不到内容,按下文「驳回后归档页写三样」自行落笔)。

它当时**过了正向清单的两条**:有非平凡前置(password 字段加密)、有实测踩坑(脱离 SDK 会明文落库)。但三条硬门槛一条都不过:

| 硬门槛 | 实际 |
| --- | --- |
| 有公开云 API | 6 个 Action(`GetUserKeyList` / `CreateUserKey` / …)在公开概览 **0 命中** |
| 语言无关可调用 | 唯一通路是 `@cloudbase/manager-node` 的封装;Python / Go / Java 用户没有对应入口 |
| 写操作能独立完成 | password 的加密密钥由 SDK 内部从七彩石取(`QueryRainbowConfig`),公开面没有入口 → 裸调云 API 无法加密,写路径走不通 |

**要记住的是漏判机制,不是这条结论**:把「官方 SDK 文档里写全了、本地跑得通」当成了「能力在公开 API 契约内」。**SDK 文档公开 ≠ Action 公开**。

**写前自检**:动笔前拿目标 Action 名去公开概览 / 官方接口文档搜一次(入口见上文准入 §1)。0 命中就停手,不进公开集。

**驳回后归档页写三样**(照 `pending-recipes/` 那份抄):① 为什么未通过,逐条对到上面三条门槛;② 解封条件——满足其一即可移回公开集;③ 显式禁止「复制回公开 skill」。

## 权限模型(维护者视角:这一步要不要预置掉)

使用者看到的是「点一下授权链接」;我们要判断的是**要不要让这一步消失**。三种处置:

| 处置 | 什么情况 | 怎么做 |
| --- | --- | --- |
| 预置进角色族 | 能力通用、高频、且在 TCB 产品语义内(TCR 拉镜像、CloudBase Run 访问 VPC/CVM 属这类) | 推产品给 `TCB_QcsRole` 挂预设策略,命名沿 `QcloudAccessForTCBRoleIn<X>` → 用户零操作 |
| 让用户按需追加 | 长尾能力、跨产品,或预设策略粒度太粗(`QcloudMonitorFullAccess` 是全读写) | 给一键授权链接,写进 recipe 的 `前置权限`。**默认走这条** —— 把大权限挂在默认角色上,等于替所有用户扩大默认授权范围 |
| 都不做 | 能力没有公开 API(准入驳回那一类) | 到此为止,不写 recipe 也不预置;当产品缺口反馈 |

判断顺序:先过准入(没有公开 API 就停),再看值不值得进角色族;两条都不过就只留一键授权链接。

**动笔预置前先做一次身份校验**:确认这条通路的凭据真的以该角色发起。`auth get_temp_credentials` 导出的是 Web / device 登录的**同一份**临时密钥(不是另起一次角色假定),所以只有用「权限收窄到刚好没这个 Action」的身份实测报出 `UnauthorizedOperation`,才能判定角色策略在这条通路上生效。判不出来就给一键授权链接、不预置。

一个已观察到的线索:账号级 device 登录的凭据能过 `cam:CreateRole`、`cdn:DescribeDomains`,而同一账号 `TCB_QcsRole` 的挂载策略里都没有这两条 —— 倾向说明它取的**不是**该角色。但这个结果用主账号登录也会得到,必须换窄权子账号复测才算数;没复测前,对外只写「按凭据身份判断」,不要对外断言 CLI / MCP 走角色。

**已落定的归属**(按能力族,不按产品):

| 能力 | 处置 | 依据 |
| --- | --- | --- |
| 云开发自己的域名(静态托管、网关自定义域名的绑定 / 解绑 / 查任务) | 预置——已在角色族 | 走 `tcb:*` 与 `cdn:Tcb*`,属 TCB 产品语义内 |
| 证书只读(列证书 / 详情 / 校验链) | 预置——已在角色族 | 绑自定义域名要在证书列表里挑一张,是必要读权限 |
| 云监控告警族 | 预置——已在角色族 | 随基座策略下发 `monitor:*`,不单独挂 `QcloudMonitorFullAccess` |
| 通用 CDN 加速域名(`AddCdnDomain` 等) | 让用户按需追加 | 跨产品长尾;`QcloudCDNFullAccess` 粒度太粗 |
| DNS 解析(DNSPod) | 让用户按需追加 | 跨产品长尾:解析记录操作与云开发无产品语义绑定 |
| 证书写(申请 / 续期 / 删除 / 部署) | 让用户按需追加 | 同上;`QcloudSSLFullAccess` 是全读写,粒度偏粗 |

角色挂载策略会随产品迭代变动,上面这张表可能过期 —— **以 `ListAttachedRolePolicies` + `GetPolicy` 读到的实际策略内容为准**,不要拿历史结论当事实。

## 用到的 service 必须在 MCP 白名单里

recipe 里出现的 service 要能在 `callCloudApi` 直接调通。白名单是 `mcp/src/tools/capi.ts` 的 `SERVICE_VERSIONS`(枚举 + 官方版本映射)。写 recipe 时若发现目标产品不在表里,**先补表再写 recipe**:单版本产品写 `service: ["YYYY-MM-DD"]`,多版本产品把官方在用版本都列进数组(缺省时调用方必须显式传 version)。版本号取自官方 SDK 目录 `tencentcloud/<service>/v<YYYYMMDD>`,不要凭记忆填。

改完 `SERVICE_VERSIONS` 要同步**两处**再跑产物链:使用者侧的完整索引 `config/source/skills/cloud-api-operations/references/service-versions.md`(按产品线分组的分组表),以及 `references/calling-methods.md` §1 的「最常用的几个」小表(只在核心产品变动时动这张)。

链接拼法、角色载体读法、策略覆盖范围见对外 skill 的 `config/source/skills/cloud-api-operations/references/calling-methods.md` §3 —— 维护者视角的内容**只写在本 skill**(对外 skill 只写「怎么点一下授权」,不写这一节)。

## 动笔前先自己跑通一遍(实测口径)

准入过了不等于能写 —— 先拿真账号把**只读**路径跑通,再决定哪些进主序列、哪些进「踩坑清单」。

- **目标 service 不在 `SERVICE_VERSIONS` 时先补表**(`mcp/src/tools/capi.ts`),再重建本地产物:跑 `build:webpack`,**不要跑 `npm run build`** —— 它的 `prebuild = rm -rf dist` 会被 safe-delete 钩子拦下,整条链断在第一步。版本号取自官方接口文档页或 SDK 目录 `tencentcloud/<service>/v<YYYYMMDD>`,两处对得上才填。
- **`callCloudApi` 有环境绑定门禁**:账号级登录后首个调用仍会返回 `ENV_REQUIRED`(「已登录,但尚未绑定环境」)。先 `auth(set_env, envId=…)` 绑一个正常环境即可 —— 备案这类账号级业务与环境无关,绑定只是为了过门禁。
- **用 stdio 探针直接驱动本地 `mcp/dist/cli.cjs`**(`initialize` → `tools/call`),比挂进客户端快得多;本地 MCP 起法与探针脚本见 skill `cloudbase-mcp-local-probe`。
- **只跑 `Describe*` / `Check*` / `Validate*`**,写操作一律留给使用者手动执行。写路径如果必须靠订单流程内的参数才能发起,正好说明它不进主序列。
- **但有自己可自由支配的测试环境时,写操作要真跑,跑完还原** —— 否则写操作之后的回查步骤永远停在「文档核对」,整篇也只好标 `🟡 部分实证`。挑按量计费、可重建、不影响他人的环境,走完整条序列(提交 → 轮询进度 → 回查结果 → **改回原值并再次确认**);**两个方向都要跑**,升与降常走不同分支、耗时也不同(实测升 174 s / 降 67 s,同规格同地域)。真跑还会暴露只读永远看不到的东西:任务步骤表会边跑边长、入参与任务详情对同一个字段用两套枚举。
- **写接口自带「只校验」开关时(`DryRun` / `预检`),可以按只读口径实测** —— 但两个条件都要满足:(1) 官方文档或控制台自己的实现明确说明它**不产生订单、不发起变更**;(2) 参数挑「目标值 = 当前值」,万一开关没生效,也只会命中幂等分支、不会真改。跑完必须再读一次现状确认没变(例:变配预检后重读实例属性,比对规格与 `UpdateTime`)。
- **控制台的真实路由与「它在调哪个 Action」都是可查的**,不用靠猜:前端仓库里 `src/framework/routes/groups/**` 是路由真源(拿到页面 hash 路径),`src/services/capi-action-definitions/**` 是「控制台调哪个云 API、每个字段什么语义、返回体的空值约定」的真源;页面自己的 hook / utils 还能看到数据来源与**单位换算**(字段名相同但单位不同,多半只有这里写着)。写 recipe 前先读这三处,比只读官方文档多拿到「真实调用序列 + 字段语义 + 踩坑」三样东西。
- **先看专用工具有没有覆盖,再决定这一段写不写云 API**:recipe 的读者手里有 MCP 工具,能用专用工具就别教他走裸云 API —— 专用工具已经替他把开通状态归一化、异步任务轮询、错误文案不一致这些麻烦事处理掉了。`queryCloudRun` / `manageCloudRun` 这类工具的 **action 列表就是它的能力边界**(列表里没有的才轮到 `callCloudApi`)。一个能力同时有专用工具和云 API 时,recipe 里只写专用工具;只有专用工具没接的那一段才写裸云 API,并在文中说清为什么绕开(例:云托管固定 IP 在 `tcbr` 有 Action,但两个云托管工具的 action 列表里都没有)。
- **同一个环境可以横跨多个 service,别默认它们属于同一个产品,也别默认能力已开通**:云开发环境 ID 同时就是云托管(`tcbr`)的 `EnvId`,但云托管要单独开通。写「前置权限」表时按能力分 service,正文里点明「这个能力可能还没开通、怎么判、怎么开」,否则读者会把空值当成「已开通且未开启」。
- **空值判据要追一层**:同一个空值往往对应两种以上状态(云托管没开通 vs 开通了但固定 IP 关着,`Status` 都是空串)。拿它当判据前,先找到能把状态区分开的那个调用,把它排进序列的前面,否则读者拿到空值也不知道下一步该干什么。**判据字段有取值域时按取值域写全,别用「空值 = 关闭」这种近似**:类型定义里带枚举注释的字段(例 `status: string; // normal | isolate`)就写成「`normal` = 已开启,其余值含空串 = 未开启」,否则读到第三个值的人不知道该怎么判。
- ⚠️ **实测前先确认凭据能看到目标**:读接口对「不属于当前凭据的目标」往往**静默返回成功 + 空值**,而不是报错 —— 很容易把「查了个空」当成「验证通过」。实测一个不属于当前账号的 envId:`tcb/DescribeICPResourcesInfo` 返回 `success` + 空数组(像「够格」)、`tcbr/DescribeStableIP` 返回 `success` + 空 `Status`、`queryCloudRun(action="envStatus")` 返回 `unopened`,同一批探测里**只有** `tcb/DescribeEnvInfo` 报 `env not found`。动手验证前先用一个「一定会报错」的接口探目标可达性,否则整轮实测的结论都建在空值上。
- ⚠️ **区分「未开通」与「不可达」的归因**:同一个空值可能来自「能力没开通」,也可能来自「目标根本不在当前凭据下」。要坐实是前者,必须有一个**确实属于当前凭据、且该能力未开通**的样本;拿不可达目标测出来的空值只能支撑「不可达时静默返回空」,不能写成「未开通时返回空」—— 这是已经犯过一次的错(把不属于当前账号的环境当成「云托管未开通」的样本)。
- ⚠️ **账号级登录 ≠ 有该产品的操作权限;但「被拒」先归因到账号,不要归因到产品**:`ba` 这类操作级授权产品,账号级凭据确实可能整族被拒(九个只读接口全部 `UnauthorizedOperation`,action 名被正常识别、卡在策略层)。但**同一批接口在业务主体所属账号的凭据下是正常返回数据的** —— 两边都实测过,所以真正的变量是**凭据与目标是否同账号**。「前置权限」里既不要写「账号读自己的数据一般不需要额外策略」这种没验证过的乐观断言,也不要把一次被拒写成「该产品要额外策略」;写清账号这个变量,并给出换对账号后的预期。验证前先确认凭据与目标同账号,否则整轮结论都是「账号不对」造成的假象。
- **把「缺哪个必填参数」当成判据**,不是当成障碍:返回 `missing the required parameter Skey / IcpOrderID / Uin` 这类只能从内部流程拿到的参数,就等于宣告该接口无法独立使用 —— 它该写进「踩坑清单」的反面做法,而不是主序列。
- 跑完把每个 Action 的**真实返回形状**记下来(字段名、空值表现),主序列里「取什么」一列才有据可依;只读为空是正常结果,不能据此判断接口没通。
- **判据落在控制台时,要把它变成可点击的链接,不要只写「去控制台看」**。实测时顺手记下页面 hash 路径,写进 recipe 用 `https://tcb.cloud.tencent.com/dev?envId=<envId>#/<path>` 拼。**控制台路径的唯一真源是 `config/source/skills/cloudbase-platform/SKILL.md` 的 `Entry points` 清单** —— 那里没有的路径先补那一份,再在 recipe 里引用,否则两处各写一份必然漂移。同一条判据往往有「看起来该在这儿」的错页(例:备案准入的固定 IP 开关在备案管理页,环境设置页没有卡片),把这类对照写进「踩坑清单」,比只给一条正确链接更省使用者的时间。

## 结构(固定五节,入口特殊才加第六节)

顺序固定:`When to use → 前置权限 → 接口序列 → 踩坑清单 → 验证步骤`(+ 可选 `入口`)。对外发布的是这套顺序本身,别增删标题。

| 节 | 写什么 | 完成条件(可判定) |
| --- | --- | --- |
| `When to use` | 出现什么症状就该翻这篇(可判定的触发条件,不是主题概括);末尾一句划界:本篇不管什么、该转哪去 | 触发条件能对上用户手里的报错/现象 |
| `前置权限` | 需要的 service / version、凭据身份(账号级 / 环境级 / 服务角色)、需要哪几个 CAM 策略;能直接用的官方文档入口 | 权限不足时能直接给出一条**可点击的一键授权链接**(角色名 + 策略名 + `principal`),而不是"去 CAM 控制台追加策略" |
| `接口序列` | 最小可跑序列(代码块或步骤表),每步带返回要点;方法/参数只在**一处**写全 | 每步的返回值都能对应到下一步的入参;**表格每一步都带 service 列**(表头写 `service` 或 `service / version`),用到多个 service 时分节写、每节表头都要有该列 —— 漏掉这列,读者只能靠猜这一步是谁的 API |
| `踩坑清单` | 表格:坑 / 现象(贴真实报错原文)/ 正确做法 | 每行都能对上一条真实报错或可复现现象 |
| `验证步骤` | 调用后怎么自查(只读自检、写后回查、幂等查重) | 每条都有明确通过判据(字段有值 / 计数一致),不用「合理」这类词 |

## 写作规则(从 writing-for-agents 提取,逐条给落地方式)

| 杠杆 | 本仓库的落地 | 反例 |
| --- | --- | --- |
| 单一可信源 | 序列只在代码块或表里写一次;索引表不重复它的内容 | 同一序列「表里一遍、代码里一遍」 |
| context pointer | 标题与首句写**症状**,让 agent 能判断「要不要翻这篇」 | 标题写成主题词(「关于告警」) |
| 信息层级 + progressive disclosure | in-file step > in-file reference > disclosed reference:只有**某一支**才需要的细节,下沉到分支里或指向可查处,不要塞进主序列 | 把 AES/IV/base64 全套写进正文,而只有「脱离 SDK 自己实现加密」才用得到 |
| co-location | 相关的东西放同一节,少造标题 | 「因为这篇要解决什么」+「能力入口」两个标题讲同一件事 |
| 完成条件 | 每节给可判定判据;要求 legwork 就明说读什么 | 「`TotalCount` 合理」无法判定,会诱发提前收工 |
| leading word | 复用现成紧凑词,别自造 | 把「SDK 取不到密钥时静默明文写入」起名 **明文落库**,与「密文落库自检」构成同一词汇对 |
| 正面表述 | 写「改查 X」「走 Y」,别写一串「不要…」(禁用词会把行为拖进上下文) | 「不要猜 Action 名、不要用索引、不要…」 |
| 环境即真源 | 命令与路径写成能在当前环境直接执行的;能本地查到的不要缓存 | 缓存 `node_modules` 里就能读到的实现细节 |
| 剪枝 | 删 no-op、删沉渣、删与别处重复的内容 | 同一事实在 SKILL.md / README / recipe 三处各写一遍 |

## 文案红线(对外文件,使用者视角)

- **不写**:出处与验证过程(取自哪份文档/源码、比对过哪些版本、我们怎么核对的)、测试状态叙述、维护者待办
- **不写**:内部标识(AppId / Uin / 内部环境名 / 仓内路径)
- **「实测」是值级标记**:贴在具体参数、接口或返回值上,最多一个;**不要**给整节或整表贴「(全部实测)」——它没有逐行分辨率,后来补进的未验证内容会继承这个标签,正好让 AI 高置信采信未验证的东西
- **可信度只记一处**:`recipes/README.md` 目录表的「状态」列(`✅ 生产实证(日期)` / `🟡 部分实证(日期)` / `🟡 文档核对,未实跑`),SKILL.md 条目与 recipe 正文都不重复
- **状态按实际跑到的范围分档,不要整篇贴 `✅`**:一篇里「跑过」与「没跑过」混着是常态 —— 写操作要真实破坏、权限或计费限制都可能挡住。`✅` 要求整条接口序列端到端跑过;只跑到一部分(只跑通其中一条路径、或只跑了只读步骤)就用 `🟡 部分实证`,**并把没跑到的部分写在状态列里**,使用者才知道该对哪几条保持谨慎。整篇贴 `✅` 的代价与给整节贴「(全部实测)」相同:后来补进的未验证内容会继承它没挣到的置信度。(2026-09-24 教训:两篇 recipe 都只有部分路径真跑过,先误贴 `✅`,自查时才发现 —— 写完状态列要回头拿「这条序列里哪几步真的执行过」核一遍。)
- **界面口径既不是「实测」也不是「官方文档」,要单独标**:控制台给用户看的提示语可以原文转述;用量估算里的单价常量写成「控制台提交页的用量推算就按这个口径给」,让使用者能在界面上自己复核。别贴「实测」标签(那不是跑出来的),也别当官方文档契约引用 —— 两类都会让使用者按错误的前提去依赖它。这一类新增内容同样要写进状态列点名未实跑,免得跟着接口序列的 `✅` 一起被高置信采信。(2026-09-25:往 PG recipe 里补「无需升级套餐」时带进了控制台的资源点单价常量,正文标明是界面口径、状态列另点一条未实跑。)
- 以上对外规则的权威副本在 `config/source/skills/cloud-api-operations/references/recipes/README.md`,改结构/红线时两处一起看

## 索引维护

- 新 recipe 登记到 `recipes/README.md` 目录表:序号 + 场景名 + 文档链接 + 状态
- **一个场景一篇**;一个 recipe 长到两段独立序列时按 invocation 或 sequence 拆分,而不是继续加节
- 暂不写独立 recipe 的场景,写进「没有独立 recipe 的场景」,并指明复用哪篇、换什么参数

## 贡献与自测(给外部贡献者)

要加一篇 recipe 的完整流程、PR 该写什么、以及提 PR 前必须做的三层自测(机器校验 / 端到端实跑 / 多模型冷启动)见 `./references/contributing.md`。

**从 raw 链接直接读本文件时**:相对路径接在 `https://raw.githubusercontent.com/TencentCloudBase/CloudBase-AI-Toolkit/main/` 之后即可取到对应文件。

## 产物链与校验(改完必跑)

```bash
export PATH=/usr/local/bin:$PATH   # 缺它 → git-lfs 钩子报错,&& 链会静默断掉
NODE=/Users/bookerzhao/.workbuddy/binaries/node/versions/22.22.2-3/bin/node
$NODE scripts/generate-prompts-data.mjs && $NODE scripts/generate-prompts.mjs
$NODE scripts/sync-claude-skills-mirror.mjs && $NODE scripts/build-compat-config.mjs
$NODE scripts/check-prompts-sync.mjs && $NODE scripts/sync-claude-skills-mirror.mjs --check
$NODE scripts/diff-compat-config.mjs     # Has blocking diff: NO
$NODE skills/cloud-api-recipe-authoring/scripts/check-recipes.mjs   # 表格结构 + 编号交叉引用
```

- **动过接口序列的结构(删节、加节、重排步骤号)之后,必跑 `check-recipes.mjs`。** 步骤号在两个互不相干的位置各写一遍 ——「步」列的单元格、正文里的「步骤 N」句子 —— 改一处不会让另一处报错,只会让读者照着一个不存在(或指向别的步骤)的编号去找。脚本还会检查表格列数(含 `\|` 转义、分隔行、表格后空行)与反引号配对,退出码非 0 即有问题。**不要用眼睛代替它**:编号差一位看起来完全正常。

- **新增或删除**文本面都会让 compat-diff 报 blocking,必须刷 `config/source/editor-config/compat-baseline.json`
- **新写一篇 recipe = 新增文件,只能用全量刷新。** `update-compat-baseline.mjs --only <skill>` 只改**已存在**的 key;匹配到新文件时会把它记进 `unseen` 并提示走全量 —— 不会替你加进去(existence 级变更只能整体重算)。所以:
  - 改现有 recipe 的正文 → 定向刷新够用(`--only cloud-api-operations`),也避免顺手洗白别人的漂移
  - 新增 / 删除 recipe → 全量 `npm run update:compat-baseline`
- **全量刷新后先看 diff 范围再提交**,别默认它吞了别人的漂移。实测(2026-09-24,新增一篇 recipe 后全量刷新):baseline diff 的改动路径全部落在本次动过的两个 skill 上,无一条落在别的 skill —— 因为分叉点上的 baseline 与源是一致的。判据是可机械检查的:把 diff 里的路径去重,只应出现你改过的 skill 名;出现第三个就停下查那个 skill 的源与 baseline 谁过期。
- 新 recipe 还要带上两份派生产物:`config/.claude/skills/**` 镜像与 `doc/prompts/cloud-api-operations.mdx`。跑测试时注意 `/usr/local/bin/node` 会让 vitest 直接起不来,绕法见 skill `cloudbase-mcp-artifact-pipeline`
- 校验完成前不要宣称改完:三项预检全过 + `git diff` 里非目标改动行为空

## 常见坑

- 中文核对**不要用 shell `grep`**:本会话实测会静默返回空且 exit 0(假阴性),用内置检索工具
- 授权指引必须落到「角色名 + 策略名 + 可点击链接」;写"去 CAM 控制台追加策略"等于把找路成本丢回用户
- 沙箱 PATH 不含 `/usr/local/bin`(git-lfs 在那里),`git checkout <file>` 会返回非零并断掉 `&&` 链
- ⚠️ **「我现在复现不出来」不等于「当初没测过」—— 撤标注和改结论一样要有证据**:复核既有 recipe 时,先查这条标注是谁、什么时候、用什么条件加的(`git log -S"<原句>"` 找引入提交,再翻当日的实测记录)。实测条件会变(账号不同、区域不同、构建版本不同),把「条件不同导致复现不了」写成「标注无证据」,等于自己造一次回退。本轮就发生过:一条值级「实测」标注差点被当成无证据撤掉,实际在当轮探针记录里能查到真实返回。
- 删除 recipe 时,除源文件与 `config/.claude/` 镜像,还要清掉 SKILL.md 与 README 里的引用,再跑产物链
- **删节或重排编号后,表格的「步」列要单独再改一遍**:正文里的「步骤 N」和表格单元格是两套独立文本,只改一处不会有任何报错。实测(2026-09-25)删掉一整节后正文已重排成 8/9/10,表格仍停在 9/10/11 —— 差一位,读者按 8 去表格里找会落到别的步骤上。跑 `scripts/check-recipes.mjs` 检出,别靠复查时"看着没问题"

Files in this skill

  • SKILL.md28.9 KB
  • references/contributing.md6.4 KB
  • scripts/check-recipes.mjs4.9 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…