Genkit JS 多 Agent 编排实战:用 `agents()` 中间件构建 Orchestrator + Sub-Agent 协作系统

发布时间:2026/9/13 14:26:40
Genkit JS 多 Agent 编排实战:用 `agents()` 中间件构建 Orchestrator + Sub-Agent 协作系统 Genkit JS 多 Agent 编排实战用agents()中间件构建 Orchestrator Sub-Agent 协作系统【免费下载链接】skillsAgent Skills for Google products and technologies项目地址: https://gitcode.com/GitHub_Trending/skills29/skills导读本文基于当前仓库 genkit-js 技能集 中的核心参考文档 agents-multi-agent.md完整讲解 GenkitNode.js/TypeScript中Beta 阶段的 Multi-Agent 编排 / Sub-Agents子代理能力。你将掌握如何用genkit-ai/middleware提供的agents()中间件搭建一个「编排者orchestrator委派任务给多个专职子代理sub-agent」的典型架构如researchercoder并深入理解agents()的全部配置项、子代理间 Artifact 共享机制、retry()等配套中间件以及子代理触发中断interrupt时的行为边界。读完本文你能直接复制出一套可运行的多 Agent 协作应用并为后续排查 Beta API 变更打下基础。⚠️Beta / preview API 声明子代理委派依赖genkit-ai/middleware包中的agents()中间件Agent 服务端 API 来自genkit/beta浏览器客户端来自genkit/beta/client导入路径与函数签名未来可能变化。按仓库 agents.md 的要求Agent 相关代码必须始终使用genkit/beta而非genkit导入且要求genkit 1.39.0CLI 最低版本 1.29.0。建议先阅读 agents.md 掌握 Agent 基础。一、整体机制agents()中间件如何实现委派多 Agent 编排的核心是一个orchestrator编排者与若干sub-agent子代理。编排者负责理解用户请求、决定把任务拆给谁、再综合各方产出形成最终答案子代理则各自专注单一领域比如搜索资料、写代码。在 Genkit 中这一切通过agents()中间件一行接入完成它自动做了三件事见 agents-multi-agent.md 与 middleware.md注入委派工具为每个子代理自动生成一个名为delegate_to_name的 tool模型可以在回合中调用它来完成委派扩充系统提示词在编排者的 system prompt 末尾自动追加一个sub-agents区块列出所有可委派的子代理及其描述让模型知道「什么时候该找谁」执行委派并回填结果当模型调用某个委派工具时中间件真正运行对应子代理并把子代理的回复作为 tool result 返回给编排者。中间件的挂载方式与retry()、artifacts()完全一致——通过 Agent 的use: [...]数组该数组同样支持ai.generate/ai.generateStream与可执行 prompt见 middleware.md。如 agents.md 所述Agent 与中间件是天生一对子代理委派、Artifact、文件系统、技能加载、工具审批、重试等高级能力本质上都只是你「丢进 use 数组的中间件」。二、第一步定义专职子代理每个子代理就是一个用ai.defineAgent定义的标准 Agent基础定义方式见 agents.md。关键点是务必为每个子代理编写description——agents()中间件会自动发现该描述并展示给编排者模型据此判断何时应该委派即「auto-discovered description」机制。下面定义一个会联网搜索并保存结论的researcher和一个负责写代码的coderimport { artifacts, retry } from genkit-ai/middleware; import { ai, defaultModel } from ./genkit.js; export const researcher ai.defineAgent({ name: researcher, description: A thorough research assistant that searches the web and provides well-sourced answers., model: defaultModel, system: You are a thorough research assistant. Save findings with write_artifact., maxTurns: 10, use: [retry(), artifacts()], }); export const coder ai.defineAgent({ name: coder, description: An expert programmer that writes clean, well-commented code., system: You are an expert programmer. Save code with write_artifact., maxTurns: 10, use: [artifacts(), retry()], });代码要点说明description是委派决策的依据编排者的 system prompt 中会自动列出每个子代理的description描述写得越具体、越能说清「什么任务该找我」模型委派就越精准use: [retry(), artifacts()]给子代理叠加了「自动重试」和「Artifact 读写」能力——retry()应对瞬时模型错误artifacts()则注入write_artifact/read_artifact工具详见 agents-artifacts.md子代理可以把研究结论、代码等成果落成命名 ArtifactmaxTurns: 10限制单次会话的最大模型往返次数防止 Agent 陷入死循环该选项在defineAgent中可用参考 agents.md 的 codingAgent 示例。子代理也可以配置自己的model、tools、storeSessionStore等标准选项。是否需要store取决于你是否希望该子代理会话由服务端持久化详见下文「委派上下文」与 agents-sessions.md。三、第二步用agents()组装编排者编排者同样用ai.defineAgent定义区别在于use: [...]数组中加入了agents()import { agents, artifacts, retry } from genkit-ai/middleware; import { ai } from ./genkit.js; export const orchestratorAgent ai.defineAgent({ name: orchestratorAgent, system: You are a helpful project assistant. Analyze the request and delegate to the appropriate sub-agent. If it needs research AND code, call them sequentially, then synthesize a final answer., use: [ agents({ agents: [ researcher, // auto-discovered description { name: coder, description: Writes, debugs, and explains code. Use for programming., }, ], maxDelegations: 5, // guard rail against runaway delegation loops historyLength: 4, // forward the last N user/model messages as context artifactStrategy: session, // see Sharing artifacts below }), artifacts({ readonly: true }), // read sub-agent artifacts via read_artifact retry(), ], });agents.agents数组的两种写法researcher字符串只给名字描述从 Agent 注册表自动发现auto-discovered{ name: coder, description: ... }对象显式覆盖描述适合在编排层面补充更贴合委派决策的措辞。运行方式与普通 Agent 完全一致——agent.chat()打开会话支持流式输出const chat orchestratorAgent.chat(); const turn chat.sendStream( Research the best sorting algorithms, then write a TypeScript quicksort. ); for await (const chunk of turn.stream) process.stdout.write(chunk.text ?? ); const res await turn.response;这段流式 APIchat.sendStreamturn.streamturn.response是 Genkit Agent 的标准调用形态与 agents.md 中weatherAgent.chat()的用法一致。编排者拿到用户请求后会依据系统提示词决定先委派researcher调研排序算法再委派coder编写 quicksort 代码最后综合成最终答案。中间件顺序值得注意如 agents.md 的 codingAgent 示例所示中间件在use数组中的顺序会影响行为例如toolApproval需放在filesystem之前。在编排场景把agents()放在artifacts({ readonly: true })之前是常见且推荐的顺序。四、agents()配置项全解析配置项类型 / 默认值作用与细节agents必填Arraystring \| { name: string; description?: string }子代理引用列表。字符串形式名字描述自动从注册表发现对象形式可显式覆盖descriptiontoolPrefix默认delegate_to生成的委派工具名前缀即delegate_to_agent设为空字符串则直接使用裸 Agent 名作为工具名maxDelegations无默认建议显式设置单次generate调用内的最大委派次数防止「编排者不断委派」的失控循环runaway delegation loopshistoryLength默认0/ 省略转发给子代理的最近 N 条用户/模型消息作为上下文。0或省略时只发送任务描述本身。注意只有客户端托管状态的子代理无store才接受这种临时种子历史服务端托管状态的子代理配置了store会跳过该历史只接收任务artifactStrategyinline默认或session子代理产生的 Artifact 如何回传给编排者详见下一节其中toolPrefix与maxDelegations直接对应中间件源码的注入逻辑每子代理一个delegate_to_name工具 防循环护栏是你在生产环境中防止「委派雪崩」的关键旋钮historyLength则是控制子代理上下文成本的开关——任务简单时保持0最省 token任务依赖多轮上下文时再调大。五、子代理间共享 Artifactinline与session两种策略子代理可以通过write_artifact产出命名、带内容的成果文件、报告、代码等详见 agents-artifacts.md。artifactStrategy决定这些成果如何到达编排者inline默认Artifact 的完整内容直接包含在委派工具的结果tool result里编排者模型可以直接看到同时内容也会合并进父会话parent session。适用场景子代理产出体量小、编排者必须立即审阅全部内容。sessionArtifact只合并进父会话委派工具结果中只列出 Artifact 的名字而非内容需要与artifacts()中间件搭配编排者通过read_artifact按需读取这正是上文编排者示例artifacts({ readonly: true })的用途——编排者只读、不生产 Artifact见 agents-artifacts.md 的「Sharing artifacts across agents」命名空间规则合并进父会话的 Artifact 会按调用 ID 命名空间隔离形如agentName_rand/name避免多个子代理产出同名 Artifact 时互相覆盖。适用场景子代理产出体量大长代码、长报告把完整内容塞进 tool result 会浪费 token编排者只在需要时按名读取。这也是「研究 编码」型编排的推荐组合use: [ agents({ agents: [researcher, coder], artifactStrategy: session }), artifacts({ readonly: true }), ];需要读写 Artifact 的编程式访问例如自定义工具内部时可在 Agent 回合内通过ai.currentSession()获取当前会话再用session.getArtifacts()/session.addArtifacts([...])操作完整示例见 agents-artifacts.md。六、配套中间件retry()与其他可选能力genkit-ai/middleware包安装npm i genkit-ai/middleware共导出七个中间件工厂retry、fallback、artifacts、agents、filesystem、skills、toolApproval全部通过use: [...]挂载到 Agent 或ai.generate上完整目录见 middleware.md。其中retry()与委派是常见搭档——子代理调用的模型可能瞬时不可用自动重试能显著提升编排链路的稳定性import { retry } from genkit-ai/middleware; retry({ maxRetries: 3, // default 3 initialDelayMs: 1000, // default 1000 maxDelayMs: 60000, // default 60000 backoffFactor: 2, // default 2 (exponential backoff) // statuses defaults to UNAVAILABLE, DEADLINE_EXCEEDED, RESOURCE_EXHAUSTED, // ABORTED, INTERNAL });配置细节与 middleware.md 中retry()文档一致maxRetries最大重试次数默认3initialDelayMs首次重试前的初始延迟默认1000msmaxDelayMs重试延迟上限默认60000msbackoffFactor指数退避因子默认2每次重试延迟按该因子翻倍statuses触发重试的 RPC 状态码默认集合为UNAVAILABLE、DEADLINE_EXCEEDED、RESOURCE_EXHAUSTED、ABORTED、INTERNAL。其余可叠加的中间件能力fallback()主模型失败时按序回退其他模型、filesystem()把沙箱文件系统工具注入模型、skills()扫描技能目录并提供use_skill工具、toolApproval()限制可执行工具白名单超出抛ToolInterruptError均见 middleware.md。推荐实践通过各中间件的.plugin()方法注册到genkit()插件列表如retry.plugin()、artifacts.plugin()。不注册也能在use数组中使用但未注册的中间件不会出现在 Genkit Dev UI 中影响可视化调试见 middleware.md。七、重要边界子代理的中断Interrupt不会传播为可恢复中断human-in-the-loop / interrupts 允许 Agent 在回合中暂停等待人工批准或补充输入后再从暂停点精确恢复内部实现为「工具调用即控制流」中断工具永远不在服务端执行只用于暂停回合随后通过chat.resume({ respond: [...] })恢复。但在多 Agent 编排中有一个必须知道的边界原文档明确声明如果子代理触发了 interrupt它会被作为一条普通工具响应normal tool response回报给编排者而不会作为可恢复的中断向上传播。交互式、有状态stateful的子代理中断属于未来特性——请只委派自包含self-contained的任务给子代理。换言之当前 Beta 阶段你不应该期望「子代理暂停等待用户输入 → 用户批准 → 编排流程恢复」这条链路能够端到端工作。委派给子代理的任务应当是一次调用即可完成的封闭任务若确实需要人审请在编排者这一层而非子代理内部使用中断机制相关中断定义与chat.resume/chat.resumeStream用法见 agents-human-in-the-loop.md。八、从单机到部署多 Agent 的 HTTP 服务化编排者与子代理本质上都是标准 Agent因此可以像普通 Agent 一样通过 HTTP 对外服务。agents()中间件发生在服务端内部编排者回合内委派子代理对外暴露的仍然只是一个编排者端点。以 agents-deployment.md 中的expressHandler为例Express 适配器import { expressHandler } from genkit-ai/express; import express from express; import { orchestratorAgent } from ./orchestrator-agent.js; const app express(); app.use(express.json()); app.post(/api/orchestratorAgent, expressHandler(orchestratorAgent)); app.listen(8080);如需支持快照恢复 / 分支 / 后台执行可额外挂载两个伴生动作POST /api/name/getSnapshotagent.getSnapshotDataAction与POST /api/name/abortagent.abortAgentAction路径与remoteAgent客户端默认值${url}/getSnapshot、${url}/abort保持一致。浏览器客户端跨域调用时记得在 CORS 配置中放行并暴露X-Genkit-Stream-Id请求/响应头流式传输必需完整代码见 agents-deployment.md。除 Express 外还支持 Next.jsappRoutegenkit-ai/next、Fetch 运行时fetchHandlergenkit-ai/fetch适配 Hono/Bun/Deno/Cloudflare Workers/Edge、FastifyfastifyHandlergenkit-ai/fastify等适配器。浏览器端消费与普通 Agent 相同——remoteAgent来自genkit/beta/client返回类型化 HTTP 客户端chat.send/chat.sendStream自动携带会话状态客户端托管状态时状态 blob 每回合自动往返无需管理 snapshot id详见 agents.md。九、实战小结与推荐阅读路径一个可落地的多 Agent 编排应用通常遵循以下组装清单子代理层每个ai.defineAgent配好name、description委派决策依据、system、maxTurns并叠加artifacts()/retry()编排层ai.defineAgentuse: [agents({ agents: [...], maxDelegations, artifactStrategy }), artifacts({ readonly: true }), retry()]在 system 中明确「分析请求 → 按需委派 → 顺序调用 → 综合成稿」的协作指令防护与上下文用maxDelegations防委派循环用historyLength控制子代理上下文成本用toolPrefix自定义工具名成果共享产出大时选artifactStrategy: session 编排者read_artifact按需读取产出小且需直接可见时用默认inline边界认知不把「子代理触发中断并传播回编排者」当作可用能力只委派自包含任务部署expressHandler或 Next/Fetch/Fastify 适配器把编排者暴露为 HTTP 端点浏览器用remoteAgent消费。为帮助你在当前仓库中继续深挖推荐按此顺序阅读Agent 基础与会话状态agents.md、agents-sessions.mdArtifact 机制agents-artifacts.md中间件全览与自定义middleware.md、middleware-custom.md人类在环 / 部署 / 高级控制agents-human-in-the-loop.md、agents-deployment.md、agents-custom.md分支、后台执行、类型化状态等进阶主题agents-branching.md、agents-background.md、agents-state.md⚠️ 再次提醒Agent 相关 API 均为Beta始终以genkit/beta导入并锁定genkit 1.39.0遇到 API 报错时请优先查阅仓库中的 common-errors.md再结合genkit docs:search/genkit docs:read核实最新文档不要依赖过时的历史知识。【免费下载链接】skillsAgent Skills for Google products and technologies项目地址: https://gitcode.com/GitHub_Trending/skills29/skills创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询