7e87a3336b
📋 SDD:workflow-discovery task 3.8(3.7 的 suggestion 指 skill write_recipe, 之前是空地——指路會指到不存在的 skill)。 - registry/skills/write_recipe.md:從真 code 反推,不是憑空教學—— schema=routes/recipes.ts RecipeDefinition(canonical_id/endpoint/method/auth_service…); 真範例=api-recipe-seeds.ts 的 telegram_send(URL path 注入)+gmail_send(service account); auth recipe 必填欄位(required_secrets 的 help_url 必填)照 POST /auth-recipes 驗證邏輯; 常犯錯收錄實錄(sheets append PUT→POST、telegram auth recipe 漏種、金鑰只准名字 D36) - INDEX.md 補 write_recipe 入口;「/cypher/search 假 found」坑改標已修(2026-07-31) - write_intent_workflow.md §6 status 表改 not_found 契約+suggestion/similar_* 欄說明 安裝器 seed:registry/skills/*.md 由 sync-registry-to-kbdb.py 自動收,新檔即納入。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
6.1 KiB
6.1 KiB
Skill: Write Recipe(寫 recipe)
何時用這個 skill
/cypher/search 回 not_found 且 suggestion 指「寫 recipe」時,讀這支。
- 要打某個外部 API(Google Slides / Slack / 任何有 HTTP API 的服務),但
arcrun_recipe_list()沒有 acr recipe search <關鍵字>落空,回「公庫無符合的 recipe」- 你想把一條常用的 API 呼叫封裝成可重用、可投稿的配方
🔴 不要因為沒有 recipe 就改寫成
code節點——那是「腹語術」。 recipe 不用改平台、不用部署 Worker、不用寫程式,幾行 YAML 就能自己補上。
recipe 是什麼
「http_request + 參數模板」的具名封裝(真身存在 cypher-executor 的 RECIPES KV)。 執行時 cypher-executor 直接 fetch 該 endpoint——不 deploy Worker、不寫 WASM。
| 你缺的是… | 走哪條路 |
|---|---|
| 打外部 API(服務有 HTTP API) | recipe(本 skill) |
| 計算能力(加解密/壓縮這類純運算) | 零件 PR → arcrun_get_skill('add_new_wasm_component') |
1. Recipe 的欄位(schema)
canonical_id: google_slides_create # 必填。小寫底線,全庫唯一的可讀名
endpoint: https://slides.googleapis.com/v1/presentations # 必填。要打的 URL
method: POST # 選填,預設 POST(GET/PUT/PATCH/DELETE 皆可)
display_name: Google Slides Create # 選填,人看的名字
description: 建立一份新簡報。POST presentations,body 帶 title。auth: google service_account。
auth_service: google_slides_sa # 選填。指向 auth recipe(見第 3 節)
headers: {} # 選填。額外固定 header
body: {} # 選填。固定 body 欄位(會與節點 payload 合併)
hash_id(rec_xxxxxxxx)與uuid由系統自動生成,不用寫。- description 認真寫:AI(包括未來的你)靠它決定要不要用這個 recipe。 照庫裡的慣例寫「做什麼。怎麼打。auth 用什麼。」三段。
2. 真範例(從實際 seed 且實跑過的 recipe 照抄)
A. token 在 URL path(telegram_send)
canonical_id: telegram_send
display_name: Telegram Send
description: Telegram sendMessage。token 在 URL path({{auth.bot_token}}),body 帶 chat_id+text。auth: static_key path 注入。
endpoint: https://api.telegram.org/bot{{auth.bot_token}}/sendMessage
method: POST
auth_service: telegram
B. Bearer/service account(gmail_send)
canonical_id: gmail_send
display_name: Gmail Send
description: 寄 Gmail。POST messages/send,body 帶 raw(base64url MIME)。auth: google service_account。
endpoint: https://gmail.googleapis.com/gmail/v1/users/me/messages/send
method: POST
auth_service: google_gmail_sa
模板變數(endpoint 裡可用)
| 變數 | 來源 | 例 |
|---|---|---|
{{auth.X}} |
auth recipe 的 inject.path 注入 |
bot{{auth.bot_token}}/sendMessage |
{{_path}} |
節點 payload 的 _path 欄位(路徑由工作流決定時用) |
https://sheets.googleapis.com{{_path}} |
🔴 金鑰只准名字,不准真身:endpoint/headers 裡絕不寫死 token。
真值走 credential 中心(acr creds push),recipe 只留 {{auth.X}} 這種名字引用。
3. auth 怎麼接(多數 recipe 需要)
auth_service: telegram 表示執行時去拿 auth_recipe:telegram 做認證注入。
先查有沒有:acr auth-recipe list 或 GET /auth-recipes/<service>。
沒有就要一併建(POST /auth-recipes,缺這步 recipe 會注入空值打不通):
service: telegram # 必填
primitive: static_key # 必填:static_key | oauth2 | service_account
base_url: https://api.telegram.org # 必填
required_secrets: # 必填,每個 secret 的 help_url 也必填(官方文件連結)
- key: telegram_bot_token
label: Bot Token(從 @BotFather 取得)
help_url: https://core.telegram.org/bots/features#botfather
inject: # 必填:secret 注入到哪(header / query / body / path)
path:
bot_token: "{{secret.telegram_bot_token}}"
然後用戶端上傳真值:acr creds push(存進 credential 中心,AI 拿不到真身)。
4. 裝上(三個介面同一個 API)
acr recipe push my_recipe.yaml # CLI:push 時會實打 endpoint 做打通檢查
- MCP:
arcrun_recipe_push(...) - HTTP:
POST /recipes(JSON,欄位同上)
裝好後 workflow 直接引用(節點名=canonical_id,或 config 指定):
config:
notify:
component: telegram_send # 或穩定引用 rec_xxxxxxxx
payload(如 chat_id、text)由上游節點或 context 給——這正是「AI 只填 payload」。
5. 驗收(誠實原則)
- push 時的打通檢查只是提醒級——真驗收=跑一次 workflow、
verdict=success(2xx) - 缺 credential 打不到 2xx → 誠實標「未驗收:缺 X」,不 mock 充綠燈
- 打通後可投稿公庫讓別人用:
acr recipe submit-p <canonical_id>(成為該 recipe 的作者版本)
6. 常犯的錯
- token 寫死在 endpoint/headers → 金鑰鐵律違規。只准
{{auth.X}}名字引用 - method 用猜的 → 查官方文件。實錄:Sheets append 被猜成 PUT(官方是 POST
:append), seed 到壞 recipe 每個新用戶都打 400 - 只建 recipe 忘了 auth recipe →
{{auth.X}}注入空值打不通。實錄:telegram auth recipe 漏進種子,所有新實例的 telegram 發訊全斷 - 落空就寫 code 節點 → 腹語術。recipe 是正路,且寫好可投稿讓全生態重用
- canonical_id 用大寫/空白 → 一律小寫底線(系統會 trim+lowercase,但別靠它救)
7. 相關
- 寫意圖工作流(上游,先寫意圖再查缺什麼):
arcrun_get_skill('write_intent_workflow') - 缺的是計算零件不是 API:
arcrun_get_skill('add_new_wasm_component') - 查公庫現貨:
acr recipe search <關鍵字>/arcrun_recipe_search(...) - 拉別人寫好的:
acr recipe pull <canonical_id> [--author=<name>]