Goose Recipes 实战:用可复用的"菜谱"把 Agent 工作流规模化
本指南以 Goose 官方博客《A Recipe for Success》中的思想为骨架,系统讲解 Goose 如何借助 Model Context Protocol(MCP)把大模型从"提建议的顾问"升级为"能动手的编排者",并通过 Recipe(菜谱)机制将一次成功的会话固化为可重跑、可混搭、可分享的可复用工作流。读完你将掌握 Recipe 的 YAML 结构、参数化、扩展装配、校验、分享与自动重试等完整实操能力,并能在真实场景中一键复现同一套 Agent 工作流。
从《料理鼠王》说起:传统 AI Agent 的"三层角色"
原文档用电影《料理鼠王》里 Remy 与 Linguini 的关系类比 AI Agent:Remy 满腹厨艺却没有厨房使用权,Linguini 能在厨房自由行动却缺乏烹饪判断。二者合体后,Remy 观察厨房里有什么工具、给出一步步指令("拿起刀和砧板,把土豆切片"),Linguini 负责执行。
对应到智能体系统,就是三个核心角色:
| 角色 | 电影类比 | 职责 |
|---|---|---|
| Large Language Model(LLM) | Remy | 拥有知识与推理能力,负责规划(用什么工具、按什么顺序) |
| Agent | Linguini | 能调用工具采取行动,但需要 LLM 的指导 |
| Tools | 厨房里的刀、灶台、食材 | 完成具体动作的能力入口,如 file.write() |
典型流程是:用户说"写一些单元测试",LLM 分析代码后回复"这是 JavaScript,用 Jest,创建测试文件并导入模块",Agent 随后调用 file.write() 等工具落地执行。这是"LLM 规划、Agent 执行"的基础形态。
MCP:让 Agent 从被动执行者变成主动编排者
电影后半段,Linguini 不再需要每一道菜都依赖指令——搭档 Colette 教会他工具放在哪里、工位如何组织、如何在厨房里高效移动、缺东西时如何变通。此时的 Linguini 已经理解"厨房是一个系统"。
Goose 的思路与此一致:遵循 Model Context Protocol(MCP)的 AI Agent,会把智能体从被动执行者推向主动编排者——少依赖 LLM 的临场发挥,多感知自己运行所在的上下文。MCP 为 Agent 与外部数据、服务之间的交互提供了标准化协议,其三大核心组件是:
- MCP Host:接收计划并协调任务的核心 Agent;
- MCP Client:Host 用来连接外部服务的本地连接器;
- MCP Servers:以结构化格式封装的工具、数据或提示词包——在 Goose 生态中,MCP Server 被称为扩展(Extension)。
这套架构让 Goose 能动态发现工具、理解工具用法,并跨多个系统编排复杂工作流。Goose 本身就是一个本地运行的开源 AI Agent,其编排与扩展能力的实际使用方式见 Goose 扩展文档,MCP Host/Client/Server 的分层实现在 crates/goose/src/mcp_utils.rs 等源码中均有对应。
Goose 的编排与临场应变
当用户让 Goose"收集上周关于认证 bug 的所有讨论"时,Goose 会主动协调工具、管理执行、动态调整:
- 识别该用哪些 MCP Server:Slack、GitHub、PostgreSQL;
- 察觉某个工具运行异常(如 Slack 搜索没有返回上周消息);
- 寻找替代路径("试试不同日期范围""PR 评论里也许有要点")。
"出错了不慌、先换方案"正是 Recipe 诞生前,Agent 单次会话中体现出的编排能力。
为什么需要 Recipe:把一次成功"烹饪"封装成可复用的菜谱
原文档指出了一个关键痛点:单纯分享 prompt 无法复现体验。AI 是非确定性的,不同人的扩展与上下文配置也不一致。Recipe 的解法是把整个 Goose 工作流打包:扩展、设置、目标、示例活动一并交付。一个 Recipe 相当于一张完整的烹饪菜谱——别人拿到手就知道开哪些火、放哪些料、最终端出什么菜。
Recipe 的三大核心组成
一个 Recipe 至少要围绕以下内容组织(详见 Recipes 文档):
- Instructions(指令):定义 Agent 行为与能力边界,相当于 Agent 的"使命宣言",让 Agent 能胜任任何相关任务;若未提供 prompt 则必填;
- Prompt(提示词,可选):自动开启会话的首条消息,适合"特定即时任务";若未提供 instructions 则必填;
- Activities(活动,可选):以可点击气泡展示的示例任务,帮用户快速理解这个 Recipe 能做什么、从哪里开始。
动手示例:一个"404 风格个人主页"Recipe
原文档给出的示例 Recipe 会先询问用户选择 GitHub、Bluesky 还是 Dev.to,然后用该平台的公开内容,生成一个故事化的 404 错误页微站点。它可以借助桌面端 Recipe 链接一键启动——该链接本质上是 goose://recipe?config= 后跟一段 URL-safe Base64 编码的 Recipe JSON(Goose 桌面端安装方式见 installation.md,DeepLink 的解析逻辑可参考 crates/goose/src/recipe_deeplink.rs)。
把该链接中的 Base64 解码后,得到的正是如下 JSON(原文以 YAML 呈现,二者等价):
version: 1.0.0
title: "404Portfolio"
description: "Create personalized, creative 404 pages using public profile data"
instructions: |
Create an engaging 404 error page that tells a creative story using a user's recent public content from **one** of the following platforms: **GitHub**, **Dev.to**, or **Bluesky**. You do not need to use all three—just the one selected by the user.
The page should be fully built with **HTML, CSS, and JavaScript**, featuring:
* Responsive design
* Personal branding elements (e.g., name, handle, avatar)
* Narrative-driven layout that turns the error into an opportunity for discovery
Use platform-specific methods to fetch recent user content:
* For **Dev.to**, use the public Dev.to API to retrieve recent articles, reactions, and profile information.
* For **GitHub**, use the GitHub REST or GraphQL API to access recent repos, commits, and contributions.
* For **Bluesky**, use public feed endpoints from the AppView API (e.g., `app.bsky.feed.getAuthorFeed`) to pull posts, replies, or likes.
Incorporate the fetched data into a compelling narrative (e.g., "Looks like this page is missing, but \[username\] has been busy!"), and display it using engaging visuals like cards, timelines, or media embeds.
Wrap the user's activity into a story — for example:
"This page may be lost, but @username is building something amazing. Their latest open source journey involves a new repo that's gaining stars fast…"
"You won't find what you're looking for here, but you will find @username's hot take on async/await in their latest Dev.to post."
The result should be a small narrative-driven microsite that dynamically celebrates the user's presence online—even when the destination is missing.
Ask the user:
1. Which platform to use: GitHub, Dev.to, or Bluesky
2. Their username on that platform
Then generate the complete code in a folder called 404-story.
activities:
- "Build error page from GitHub repos"
- "Generate error page from dev.to blog posts"
- "Create a 404 page featuring Bluesky bio"
extensions:
- type: builtin
name: developer
- type: builtin
name: computercontroller
这个例子清晰地展示了一个"真菜谱"长什么样:目标(instructions)告诉 Agent 要做什么、按什么平台逻辑取数、产出物放哪里;activities 给用户三个可点的入手任务;extensions 预先声明需要 developer(开发扩展)与 computercontroller(电脑控制扩展)两个内置工具。共享者只需把文件或链接发给对方,接收方就能在独立、私有的会话中复现完全一致的环境与目标。
Recipe 的文件结构与字段语义
Recipe 可以使用 .yaml(官方推荐,以及 .yml)或 .json 编写;注意 Goose CLI 不直接支持 .yml 后缀。完整字段对照表见 Recipe Reference Guide,核心字段如下:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
title |
String | ✅ | 简短的 Recipe 标题 |
description |
String | ✅ | 详细描述该 Recipe 做什么 |
instructions |
String | ✅* | 模板化指令,可含参数替换 |
prompt |
String | ✅* | 模板化首条提示词;headless(非交互)模式必须提供 |
activities |
Array | - | 示例提示词列表,桌面端以可点击气泡呈现 |
extensions |
Array | - | Recipe 所需的扩展(MCP Server)配置列表 |
parameters |
Array | - | 动态 Recipe 的参数定义 |
response |
Object | - | 自动化场景的结构化输出 schema |
retry |
Object | - | 带成功校验的自动重试配置 |
settings |
Object | - | 指定 provider、model 等运行时设置 |
sub_recipes |
Array | - | 子 Recipe 列表 |
version |
String | - | Recipe 格式版本,缺省为 1.0.0 |
(*instructions 与 prompt 至少提供一个。)
该结构在源码中有精确对应:crates/goose/src/recipe/mod.rs 中的 Recipe 结构体定义了上述全部字段;RecipeBuilder(mod.rs)在 build() 时强制校验:title、description 必填,且"prompt 或 instructions 至少其一"。桌面端保存的 Recipe 还会包裹 recipe: 字段并附加 name、isGlobal、lastModified、isArchived 等元数据(这些元数据仅服务于桌面端的库管理,CLI 运行时会忽略)。
用参数让一个 Recipe 适配多种场景
Recipe 的复用价值很大程度上来自参数化:在内容中以 {{ variable_name }} 占位,并在 parameters 段定义每个参数。每个参数包含 key、input_type、requirement、description,可选 default 与 options:
input_type:string(默认)、number、boolean、date、file、select;requirement:required(必填)、optional(可选,必须提供 default)、user_prompt(未提供时即使非交互模式也会提示用户输入);file类型的参数会把文件内容(而非路径)代入模板,且无论何种 requirement 都不允许默认值,以防无意导入敏感文件;select类型必须提供options候选列表。
一个带参数的典型 Recipe:
version: 1.0.0
title: "{{ project_name }} Code Review"
description: Automated code review for {{ project_name }} with {{ language }} focus
instructions: You are a code reviewer specialized in {{ language }} development.
prompt: |
Apply the following standards:
- Complexity threshold: {{ complexity_threshold }}
- Required test coverage: {{ test_coverage }}%
- Style guide: {{ style_guide }}
parameters:
- key: project_name
input_type: string
requirement: required
description: name of the project
- key: language
input_type: string
requirement: required
description: language of the code
- key: complexity_threshold
input_type: number
requirement: optional
default: 20
description: a threshold that defines the maximum allowed complexity
- key: test_coverage
input_type: number
requirement: optional
default: 80
description: the minimum test coverage threshold in percentage
- key: style_guide
input_type: string
requirement: user_prompt
description: style guide name
标题若以模板语法开头,务必用引号包裹以避免 YAML 解析错误。参数替换底层由 MiniJinja 模板引擎实现,渲染逻辑见 crates/goose/src/recipe/template_recipe.rs:它会把合法变量代入参数、把不可解析的 {{...}}(如含空格的占位)自动按字面量保留,从而避免破坏 YAML。模板系统还支持:
- 转义:用
{{'{{example_variable}}'}}输出字面量花括号语法,适合生成含占位符的模板文件; - 模板继承:
{% extends "parent.yaml" %}+{% block ... %}{% endblock %}; indent()过滤器:{{ raw_data | indent(2) }}让多行参数值缩进正确,可被当作合法 JSON/YAML 解析;- 内置参数
recipe_dir:自动指向 Recipe 所在目录,用于引用同目录伴生文件,例如{{ recipe_dir }}/style-guide.md。注意其模板加载器会拒绝绝对路径与../目录穿越,防止模板越权读取文件(见 template_recipe.rs)。
为 Recipe 装配扩展:声明工具栈
Recipe 的 extensions 段声明运行所需的 MCP Server 等工具。每种扩展的子字段包括 type、name、cmd、args、env_keys、timeout、bundled、description、available_tools。扩展类型有 stdio、builtin(内置扩展)、platform(在 Agent 进程内运行)与 streamable_http。
env_keys 用于声明扩展所需的(秘密或非秘密)环境变量,goose 会依次从环境变量与 goose 密钥存储中解析;Recipe 加载时不会弹出补录,缺失则扩展报初始化错误。典型 stdio 扩展声明:
extensions:
- type: stdio
name: github-mcp
cmd: github-mcp-server
args: []
env_keys:
- GITHUB_PERSONAL_ACCESS_TOKEN
timeout: 60
description: "GitHub MCP extension for repository operations"
需要 subagent 委派(delegate/load 工具)时须显式加入 summon platform 扩展——因为一旦写了 extensions 段,默认平台扩展不会自动带入。而定义 sub_recipes 的 Recipe 会被自动注入 summon;从源码看,加载时还会对含旧版 developer 内置扩展的 Recipe 自动补齐 analyze 平台扩展(见 crates/goose/src/recipe/mod.rs)。前面的 404 Recipe 声明了 developer 与 computercontroller 两个 builtin 扩展,二者都属于 Goose 自带的本地 MCP Server 工具集,保证收到 Recipe 的人不必额外安装任何第三方 MCP 服务。
创建、运行与校验 Recipe
创建
- Goose Desktop:在会话中点击底部的厨师帽按钮,把当前会话保存为 Recipe(支持从"当前会话"或"模板"新建);编辑字段后可选择
Create Recipe(存入 Recipe 库)或Create & Run Recipe(保存并立即在新会话运行)。注意:不能从"运行中的 Recipe 会话"再创建 Recipe,只能查看或编辑它。 - Goose CLI:在会话内执行斜杠命令生成
recipe.yaml:
/recipe # 在当前目录生成 recipe.yaml
/recipe my-custom-recipe.yaml
Goose 如何把对话转成 Recipe 字段,由 crates/goose/src/prompts/recipe.md 这个提示词模板决定——它要求模型产出 title、description、instructions(更高层、可泛化的措辞)与 3~5 个 activities 的合法 JSON;你可以编辑该模板自定义生成行为。
运行
Recipe 可放在本地文件系统(当前目录或 GOOSE_RECIPE_PATH 指定目录),也可配置 GitHub 仓库统一拉取(配置项 GOOSE_RECIPE_GITHUB_REPO,要求安装并认证 GitHub CLI gh)。仓库中每个 Recipe 应独占一个目录,目录名即命令中使用的 Recipe 名,文件名为 recipe.yaml 或 recipe.json。
# 本地文件
goose run --recipe recipe.yaml
goose run --recipe ./recipes/my-recipe.yaml
goose run --recipe recipe.yaml --interactive # 交互模式,逐个提示必填参数
goose run --recipe recipe.yaml --params language=Python
# GitHub 仓库按名运行(目录名即 recipe 名)
goose run --recipe code-review
桌面端则通过 Recipe 库、手动输入链接或自定义斜杠命令启动;首次运行会弹出信任确认(展示标题、描述与指令),确认 Trust and Execute 后同版本 Recipe 不再重复询问;含参数时在 Recipe Parameters 弹窗中填写(必填项带红色星号,可选项展示可改默认值)。无论桌面还是 CLI,每次运行都是彼此隔离的私有会话——数据不跨用户共享,也不影响创建者原会话。
校验
CLI 提供了 goose recipe validate 命令,用于排障、验证手工修改、接入 CI/CD 自动化:
goose recipe validate recipe.yaml
校验器会检查必填字段、参数格式、扩展是否存在有效、YAML/JSON 语法。源码实现见 crates/goose/src/recipe/validate_recipe.rs,其校验规则包括:instructions/prompt 至少其一、response.json_schema 合法、可选参数必须有默认值、文件参数禁止默认值、模板变量与参数定义一一对应(无未定义变量、无未使用参数)、retry 配置合法等。
分享与定时
- 分享链接:桌面端 Recipe 库点复制链接;CLI 用
goose recipe deeplink <FILE>生成,也可用--param key=value预填参数;接收者点击后会用该配置打开 Goose Desktop,并可导入为可复用的本地 Recipe(详见 storing-recipes.md)。 - 分享文件:桌面端可
Export to File导出.yaml或Copy YAML;CLI 用户可直接发送文件,接收方用goose run --recipe <FILE>运行。 - 定时调度:桌面端 Scheduler 视图可创建/暂停/编辑/立即运行定时 Recipe;CLI 用
goose schedule add --schedule-id daily-report --cron "0 0 9 * * *" --recipe-source ./recipes/daily-report.yaml,支持 5/6/7 位 cron 表达式。
让 Recipe 更可靠:自动重试与结构化输出
针对无人值守场景,Recipe 提供两个"高级武器":
retry:自动重试 + shell 成功校验
retry:
max_retries: 3
timeout_seconds: 30
on_failure_timeout_seconds: 60
checks:
- type: shell
command: "curl -f http://localhost:8080/health"
- type: shell
command: "pgrep -f 'web-service' > /dev/null"
on_failure: "systemctl stop web-service || killall web-service"
执行流程为:Recipe 正常运行 → 结束后按序执行所有 checks(shell 命令退出码 0 才算成功)→ 若失败且重试次数未耗尽,执行可选的 on_failure 清理、将 Agent 消息历史重置为初始状态并重新执行 → 直到全部校验通过或达到 max_retries。全局超时可用环境变量 GOOSE_RECIPE_RETRY_TIMEOUT_SECONDS 与 GOOSE_RECIPE_ON_FAILURE_TIMEOUT_SECONDS 配置(Recipe 内配置优先)。
response:强制结构化 JSON 输出
在 Recipe 中声明 response.json_schema 后,Goose 会通过一个 final_output 工具要求 Agent 产出与 schema 匹配的 JSON,经校验后作为最后一行输出,方便脚本直接提取:
response:
json_schema:
type: object
properties:
build_status:
type: string
enum: ["success", "failed", "warning"]
tests_passed:
type: number
deployment_ready:
type: boolean
required: [build_status, tests_passed, deployment_ready]
配合 CLI 即可管道化消费:
goose run --recipe analysis.yaml --params project_path=./src > output.log
RESULT=$(tail -n 1 output.log)
echo "Analysis Status: $(echo $RESULT | jq -r '.build_status')"
注意:该功能在 CLI 与 Desktop 运行均支持,但 json_schema 目前需要手动在 Recipe 文件中创建与编辑。
Recipe 打包了什么,又刻意排除了什么
打包范围(详见 session-recipes.md):
- AI 指令(目标/目的);
- 建议活动(用户可点击的示例);
- 启用的扩展及其配置;
- 项目文件夹或文件上下文;
- 初始设置(不含完整对话历史);
- 运行所用模型与 provider(可选);
- 重试逻辑与成功校验配置(如配置)。
隐私与安全边界——Recipe 会主动排除:全局与本地记忆、API 密钥与个人凭证、系统级 goose 设置。因此如果 Recipe 依赖个人凭证,接收者需要自行提供。源码中还有一道防线:加载时会扫描 instructions/prompt/activities 中的 Unicode 私用区标签,检出有害内容即告警(mod.rs)。
规模化使用场景
- 新同事入职:与其花几小时解释环境搭建、平台选型与团队潜规则,不如直接发一个 Recipe——自动完成本地配置、呈现相关文档、带他走一遍团队工作流,全程无需屏幕共享;
- 办工作坊:不同机器、不同环境最容易翻车。丢一个 Recipe 链接,每个参会者都能拉起相同的环境、相同的工具、相同的目标与示例,把时间省给教学而不是排障;
- 放大团队产出:有人做好了内部仪表盘、有人摸熟了工单分级、有人自动化了 changelog 生成——用 Recipe 把这些"孤品"转成团队共享的复用资产,沉淀成 Goose 流程库。仓库中的 workflow_recipes/release_risk_check/recipe.yaml 与 scripts/test-subrecipes-examples 就是真实存在的 Recipe 与子 Recipe 范例,可当作阅读参照。
小结
正如 Colette 教会 Linguini"把厨房当系统来理解",MCP 让 Goose 从被动的执行者成长为能动态发现工具、编排多系统、遇错即换路的编排者;而 Recipe 则更进一步——把某一次成功的"烹饪"固化成包含工具栈、设置、目标与示例活动的完整菜谱,用 DeepLink、文件或共享仓库一键分发。想要编写或调试自己的 Recipe,可从 Recipe Reference Guide 的完整字段规范入手,配合 goose recipe validate 迭代;想进一步拆解子任务、并行执行,可阅读 subrecipes.md。从你的下一次成功会话开始,把它存成一张菜谱——未来的你和团队都会感谢现在的你。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
