goose Summon 扩展深度指南加载任务源并把工作委派给子代理【免费下载链接】goosean open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM项目地址: https://gitcode.com/GitHub_Trending/goose3/goose本文围绕 goosegoose3/goose 仓库内置的Summon 平台扩展展开讲解如何把可复用的任务源Recipes、Agents、Subrecipes加载进 goose 的上下文以及如何用delegate把任务委派给独立运行的子代理subagent包括同步执行、后台异步执行与结果回收的完整闭环。读完本文你将掌握 Summon 的启用方式、两个核心工具load()/delegate()的完整参数语义、任务源的目录发现规则以及并行研究/分工执行的最佳实践。正文中的原理部分结合了仓库内 Summon 源码 与 扩展注册表可直接对照查看。Summon 是什么一处「加载」、一处「委派」Summon 是 goose 的一个内置平台扩展官方定位为Load sources and delegate tasks to subagents见 summon-mcp.md。它提供两类核心能力load加载把可复用的任务源内容读入当前 goose 会话的上下文作为「知识」直接使用delegate委派基于某个任务源启动一个拥有独立上下文与独立会话的子代理去执行任务并把最终结果交回主代理。它面向三类任务源source来源类型含义落地位置Recipes带 prompt 与参数的可复用任务定义recipe 文件.yaml所在目录见下方发现规则Agents存储在 agent 目录中、可复用的 agent 定义agent 目录内的.md文件Subrecipes当前 recipe 上下文内、recipe 局部的任务由当前 session 的 recipe 声明这种能力典型用于让 goose 复用一个既定任务定义、把工作交给另一个 agent 处理、或并行运行多个只读研究型子任务。需要注意的是Skills技能并不由 Summon 加载它由独立的 Skills 平台扩展 负责。该扩展自v1.25.0起可用官方文档明确标注见文档头部:::info提示。从源码结构看Summon 是作为内置平台扩展实现的而非常规 MCP server在 扩展注册表 中summon被注册为display_name: Summon、default_enabled: true默认启用且unprefixed_tools: true工具名不带summon_前缀直接以load/delegate暴露给模型。其真实载体是一个会话内的工具客户端底层通过goose_sdk_types::custom_requests中的SourceEntry/SourceType模型描述任务源实现位于 summon.rs 的SummonClient。启用 Summon 扩展虽然 Summon 默认启用但你仍可以在配置界面中确认或调整其开关。官方文档给出了 goose CLI 下的标准操作流程运行配置命令goose configure选择Toggle Extensions在扩展列表中确保summon处于选中状态用空格切换、回车提交┌ goose-configure │ ◇ What would you like to configure? │ Toggle Extensions │ ◆ Enable extensions: (use space to toggle and enter to submit) │ ● summon └ Extension settings updated successfully对于goose Desktop用户扩展通常在设置中的扩展管理界面里以 Summon 名称展示并默认开启由于注册表中default_enabled: true见 mod.rs多数场景下无需额外操作即可使用load/delegate。端到端示例创建一个 Recipe 并委派给子代理官方文档用一个「生成 release notes」的完整例子串起了 Summon 的典型工作流。第一步写一个可复用 Recipe将下述内容保存为.agents/recipes/release-notes.yaml注意仓库内的 recipe 目录约定见下一节title: Release Notes description: Draft release notes from recent git changes instructions: | Review the recent git history and changed files. Write concise release notes with: - user-facing changes - fixes - migration notes, if any prompt: Draft release notes for the current branch.这个 YAML 遵循 goose 的 recipe 结构title与description用于展示与检索instructions是对子代理的行为约束任务怎么干prompt是触发该 recipe 时注入的具体任务描述。仓库中 recipe 的解析与构建逻辑位于 recipe 模块Summon 在委派时通过build_recipe_from_template/Recipe::from_content将其还原为可执行 recipe。第二步用自然语言指示 gooseUse summon to delegate the release-notes recipe for this branch.第三步观察 goose 的输出─── delegate | summon ─────────────────────────────────────── source: release-notes The release-notes subagent reviewed the branch and drafted release notes: ## User-facing changes - Added support for configuring project-specific extensions. - Improved error messages when extension startup fails. ## Fixes - Fixed stale extension state after disabling an extension.可以看到delegate被调用后主会话以─── delegate | summon ───标注了委派过程子代理独立审查分支并返回了结构化草稿。核心工具与命令手册官方文档建议既可以用自然语言让 goose 自行决定何时调用 Summon也可以直接调用工具。文档给出的常用形式如下load() load(source: release-notes) delegate(source: release-notes) delegate(instructions: Review these docs and report stale links) delegate(source: release-notes, async: true) load(source: 20260219_1, peek: true) load(source: 20260219_1)这些调用对应源码中的两个工具 schema下面逐参数展开。load()把知识载入当前上下文从 create_load_tool 的实现 可以看出其完整语义不带参数调用load()等价于“源发现”列出当前可用的所有 sourceSubrecipes / Recipes / Agents以及仍可回收结果的已完成后台任务若没有任何源会给出提示并说明源可能出现的目录。它由handle_load_discovery实现输出中会给出使用指引Use load(source: name) to load into context.与Use delegate(source: name) to run as subagent.。load(source: 名称)把该 source 的正文内容如 recipe 的instructions读取进当前上下文返回以# Loaded: name (type)开头的文本块末尾明确提示 This knowledge is now available in your context.。load(source: 任务id)当传入的是一个后台任务 id形如20260219_1时会阻塞等待该后台任务完成并返回其最终结果、状态、耗时与轮次等待有5 分钟上限超时后任务会保留运行并提示你可再次load(source: ...)等待或用cancel: true停止。load(source: 任务id, peek: true)对运行中的后台任务做非阻塞探活返回已运行时长、轮次turns、空闲时间与缓冲的 tool call 数量不等待完成。该行为由源码中handle_load_task_result的peek分支实现。load(source: 任务id, cancel: true)取消一个正在运行的后台任务并回收其已产生的输出。此外当source名称不存在时handle_load_source会做模糊匹配建议返回形如Source xxx not found. Did you mean: ...?的错误最多给 3 个候选而不是简单失败。delegate()把任务交给独立子代理从 create_delegate_tool 的实现 及DelegateParams结构同文件 L52-L66可见其完整参数表参数类型/默认值说明instructionsstring任务说明。临时任务ad-hoc下为必填也可与source组合作为追加在源 prompt 之后的额外指令sourcestring要执行的 recipe / agent / subrecipe 名称。instructions与source至少要提供一个parametersobject传给 source 的参数仅配合source使用否则参数校验会报错extensionsarraystring子代理要启用的扩展。省略继承父会话全部空数组不启用任何扩展providerstring覆盖 LLM providermodelstring覆盖模型temperaturenumber覆盖采样温度max_turnsinteger≥1该次委派的最大轮次覆盖 recipe 的settings.max_turns与GOOSE_SUBAGENT_MAX_TURNScontextstring注入子代理系统提示词中的“参考上下文”适合放背景资料、文件内容或约束与任务指令分离working_dirstring子代理工作目录必须位于父会话工作目录之内缺省继承父会话工作目录asyncboolean默认 falsetrue 表示后台运行立即返回任务 id稍后用load(source: task_id)回收结果关于委派方式工具描述与源码注释总结出三种模式与若干纪律Ad-hoc临时模式只给instructionsgoose 会以Recipe::builder()现场构造一个 Delegated Task recipe 来执行Source 模式只给source按 recipe/agent/subrecipe 的既有定义执行组合模式sourceinstructions同时给例如「用 deploy recipe 部署到 staging」。委派纪律源码工具描述中的明确提示被委派的子代理只知道「指令 源内容」且子代理之间无法互相协调因此同一文件上的并发写入会冲突。官方给出的分工建议是——研究只读型任务可以放心并行子代理各自探索后汇报写文件的任务则要严格切分文件避免两个子代理触碰同一文件。并行路径是拆解Decompose→async: true派发多个 → 逐个load(taskId)等待 → 汇总synthesize。同时源码还有一个重要的嵌套限制如果当前 session 本身是子代理SessionType::SubAgenthandle_delegate会直接返回错误 Delegated tasks cannot spawn further delegationssummon.rs#L1349-L1351相应地list_tools在子代理会话中不会暴露delegate工具只保留loadsummon.rs#L2064-L2076。委派的下游子代理如何被真正执行当delegate被调用时SummonClient 的底层链路是summon.rs#L1325-L1429校验参数必须提供instructions或sourceparameters只能配合sourcemax_turns ≥ 1依据 source 类型构建可执行 reciperecipe/subrecipe 走模板构建agent 走build_recipe_from_agent会把 agent frontmatter 中的model提升为 recipe 的settings构建子代理任务配置TaskConfig——包括扩展过滤、provider/model 解析、工作目录解析与max_turns确定通过 session_manager 创建一个SessionType::SubAgent会话并记录parent_session_id关联到父会话以run_subagent_task在独立会话中运行return_last_only: true表示只回收最终文本结果期间子代理的 tool call 通知通过NotificationSink实时流回父会话因此你在主会话能看到子代理的一举一动CLI 中常显示为[subagent:...]前缀详见 Subagents 指南。后台任务async的运行机制delegate(source: ..., async: true)对应源码中的handle_async_delegatesummon.rs#L1940-L2051关键机制如下任务 id后台任务复用子代理 session id 作为任务 id形如文档示例中的20260219_18 位日期 下划线 序号。load通过is_session_id判断传入的是任务 id 还是 source 名因此task id 与 source 名天然不会冲突。立即返回派发后不阻塞主代理返回文本 Task started in background: ... Continue with other work. When you need the result, use load(source: ).元数据中带subagent_session_id主代理可继续做其他事。结果回收load(source: task_id)阻塞等待直至完成已完成的任务会暂存在completed_tasks中供后续取回TTL 由环境变量GOOSE_COMPLETED_TASK_TTL_SECS控制默认 600 秒见 summon.rs#L525-L530。并发上限同一会话内并行后台任务数由GOOSE_MAX_BACKGROUND_TASKS控制默认 5见 summon.rs#L518-L523达到上限后继续async: true会报错提示改用同步模式或等待完成。轮次与空闲统计后台任务通过on_message回调累加 turn 数并记录last_activitypeek: true时这些数字会展示出来若轮次与缓冲的 tool call 均为 0会提示 Task is initialising (no tool activity yet).生命周期清理SummonClient::drop会在扩展关闭时尽力取消所有仍在运行的后台任务cancel token避免泄漏。max_turns的最终取值优先级为delegate参数max_turns recipesettings.max_turns 环境变量/配置GOOSE_SUBAGENT_MAX_TURNS 编译期默认值DEFAULT_SUBAGENT_MAX_TURNS定义于 subagent_task_config.rs这保证了逐次委派时的临时性覆盖不会污染后续任务。任务源从哪里来目录发现规则理解了load()的空参数列表输出后你可能想知道 goose 究竟去哪里找这些 recipe 与 agent 文件。源码discover_filesystem_sourcessummon.rs#L328-L399给出了完整答案。Recipe 目录.yaml等扩展名由RECIPE_FILE_EXTENSIONS决定项目级local相对于当前工作目录工作目录本身working_dir仅以“非 recipe 即忽略”的宽松模式扫描避免把package.json等误报为错误.goose/recipes.agents/recipes全局级globalGOOSE_RECIPE_PATH环境变量中列出的所有目录Windows 下以;分隔其他平台以:分隔~/.goose/recipes配置文件目录下的recipes~/.agents/recipesAgent 目录.md文件解析 YAML frontmatter项目级.goose/agents.claude/agents.agents/agents全局级~/.goose/agents~/.agents/agents配置目录下的agents~/.claude/agents注意上述两个列表均来自 summon.rs 中discover_filesystem_sources的局部目录数组你可以直接打开源码核对。Agent 文件需包含合法的 YAML frontmatter如name、可选description与model正文作为 agent 的 instructions解析失败且缺失字段的文件会被静默跳过只有真正 YAML 语法错误才会告警parse_agent_content。Recipe 目录的扫描结果做了60 秒缓存source_cache同目录下频繁调用不会反复扫盘。当前 recipe 上下文中的 Subrecipes如果当前会话是由某个 recipe 启动的该 recipe 声明的sub_recipes也会被注册为 Summon 的 sourceSourceType::Subrecipe其内容会按需从本地 recipe 文件加载并在返回前把parameters键、类型、必填/可选、默认值与可选项追加到 instructions 之后format_subrecipe_content/format_parameters确保委派出去的子代理知道如何与参数交互。关于 subrecipe 的编写方式可参考 recipes/subrecipes.md 与 recipes 指南。委派时的模型与扩展控制delegate最实用的特性之一是按任务隔离运行环境Provider / 模型覆盖除参数provider/model外还可以通过环境变量GOOSE_SUBAGENT_PROVIDER与GOOSE_SUBAGENT_MODEL全局指定子代理默认使用哪个 provider/model。源码resolve_provider/resolve_model_config中的解析优先级为环境变量 delegate参数 recipesettingsagent frontmatter 中的model也会提升到这里 全局配置 父会话模型 provider 默认模型。模型未被匹配到时会给出明确错误 No model configured for provider ...; set GOOSE_SUBAGENT_MODEL。扩展过滤默认情况下子代理继承父会话的扩展EnabledExtensionsState::extensions_or_default传入extensions: []表示不加载任何扩展传入名单时只保留名单内且父会话确实可用的扩展未匹配项会产生 warning 而非硬失败。这使你可以实现「只给它 developer 扩展去重构代码」「只给它 fetch 扩展去做网页调研」之类的精细权限隔离。限制与注意事项小结不能无限嵌套子代理会话内不暴露delegate无法再派生孙代理这是设计上的递归深度保护。同步等待有 5 分钟上限load(task_id)阻塞等待超时后返回错误文案提示可再次等待或 cancel任务本身仍在后台继续不会丢失。working_dir有边界必须位于父会话工作目录之内防止委派越权访问无关目录。写任务请勿并行触碰同一文件子代理间无法协调写冲突需要主代理在拆解阶段就用参数/说明把文件切分清楚。Skills 不属于 Summon加载技能请使用独立的 Skills 平台扩展见 using-skills.md。扩展阅读官方 Summon 文档本文所依据的原始页面summon-mcp.mdSubagents 概念与使用subagents.mdxRecipe 编写与存储recipes 指南、Subrecipes自定义 Agent 定义custom-agents.md源码入口平台扩展注册表 mod.rs、Summon 实现 summon.rs【免费下载链接】goosean open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM项目地址: https://gitcode.com/GitHub_Trending/goose3/goose创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考