第 8 章:Recipe、Skill 与 Scheduler——把 Agent 变成工作流
8.1 是什么:从一次 prompt 到可复用执行单元
Recipe 是带 title、description、prompt、parameters、extensions、settings、sub-recipes、retry config 和 success checks 的声明式工作流。Skill 更像可发现的能力说明和参数入口;Scheduler 则把 recipe 或 prompt 绑定到 cron/定时触发器,创建 Scheduled session 执行。
flowchart LR YAML[Recipe YAML / deeplink] --> Parse[parse + validate] Parse --> Params[参数收集与替换] Params --> Session[创建带 recipe 的 Session] Session --> Agent[Agent::reply] Agent --> Checks[success checks / retry config] Checks -->|失败且可重试| Agent Checks -->|成功| Done[结果 + usage ledger] Cron[Scheduler] --> Session Skill[Skill / slash command] --> Params
8.2 源码怎么做:Recipe 的生命周期
recipe/manifest.rs描述可序列化格式和版本语义。validate_recipe.rs检查必需字段、扩展和参数合法性。template_recipe.rs/yaml_format_utils.rs处理模板和 YAML。recipe_extension_adapter.rs把 recipe 里的 extension 声明接入 ExtensionManager。local_recipes.rs负责本地 recipe 发现、保存、删除和列表。recipe_deeplink.rs负责把 recipe 编码为可分享入口。
参数不是简单字符串替换:SDK types 中定义了参数输入类型、必需性、默认值以及前端交互 DTO;桌面端用 RecipeParamsModal 收集值,再通过 ACP/custom request 交回 runtime。
8.3 Retry 与成功检查
Recipe retry config 把“模型说完成了”与“任务真的完成了”分开。成功检查可以基于输出内容或其他约束;失败时 RetryManager 让 Agent 继续同一个 workflow,而不是让宿主重新发一条用户消息。max_retries 到达后,失败消息照常写入 session 并终止,避免 silent exit。
8.4 Skill:把领域指令做成可发现资源
skills/ 负责内置/外部技能的加载、参数和客户端调用。技能内容会进入 prompt manager 或以 slash command 暴露给宿主。它的价值不在于替代工具,而在于把“何时用哪些工具、遵循什么步骤、输出要满足什么格式”变成可版本化的 instruction。
8.5 Scheduler:同一 runtime 的非交互入口
scheduler.rs 与 scheduler_trait.rs 把时间触发和 Agent 执行解耦。调度运行会带 schedule_id,使用单独 session type 和 usage 统计;桌面端通过 custom requests 暴露列表、创建、暂停、立即运行、终止和检查运行中任务等操作。
8.6 为什么这样做:让工作流复用安全边界
Recipe、Skill、Scheduler 都不直接调用模型或工具,而是创建带上下文的 session,再走同一套 Agent Loop、Provider、MCP、permission、security 和 compaction。这样自动化任务不会因为“后台执行”而绕过前台安全策略;同时 session 记录使得失败、重试、成本和结果都可追踪。
源码定位
crates/goose/src/recipe/:Recipe 解析、验证、模板和本地存储。crates/goose/src/skills/:技能加载和参数处理。crates/goose/src/scheduler.rs、scheduler_trait.rs:调度服务。crates/goose/src/agents/retry.rs:重试状态机。crates/goose-sdk-types/src/custom_requests/recipe.rs、schedule.rs:跨宿主 DTO。