news 2026/9/24 14:35:31

《AI Agent 脚手架》第2-13节:增强装配 AgentWorkflowNode——把流转决策收拢为统一分发中心

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
《AI Agent 脚手架》第2-13节:增强装配 AgentWorkflowNode——把流转决策收拢为统一分发中心
  • 文档
  • 教程
  • 后端

【免费下载链接】CodeGuide

:books: 本代码库是作者小傅哥多年从事一线互联网 Java 开发的学习历程技术汇总,旨在为大家提供一个清晰详细的学习教程,侧重点更倾向编写Java核心内容。如果本仓库能为您提供帮助,请给予支持(关注、点赞、分享)!

项目地址:https://gitcode.com/gh_mirrors/code/CodeGuide
点击查看免费下载

导读

本篇技术指南围绕《AI Agent 脚手架》第2-13节「增强装配-AgentWorkflowNode」展开,讲解如何把 LoopAgentNode、ParallelAgentNode、SequentialAgentNode 三个智能体节点的"流转判断"职责收拢到 AgentWorkflowNode 一个节点上,让三个功能 Agent 节点只负责业务处理、不再负责"下一个该流转到谁"。读完本文,你将掌握:如何用currentStepIndex原子步骤指针 +currentAgentWorkflow当前值重构工作流上下文,如何让每个节点处理完都回环到 AgentWorkflowNode 进行统一分发决策,从而编排出"并行研究 + 串行汇总"这类复杂嵌套智能体,并通过 YML 配置与单测完成验证。

一、本章诉求:为什么要把流转决策收拢

在 第2-8节:装配域节点-AgentWorkflowNode 和 第2-9节:装配域节点-Loop、Parallel、Sequential 中,工作流编排由 AgentWorkflowNode 向 LoopAgentNode、ParallelAgentNode、SequentialAgentNode 三个节点流转,节点之间存在交叉流转:例如 LoopAgent 处理完要自己判断是否进入 SequentialAgent,SequentialAgent 又要决定是否回到 LoopAgent。

这种"每个节点各自判断下一个是谁"的设计,在组合变多后会带来两个问题:

  1. 职责不清晰:功能 Agent 节点既要处理自己的业务,又要背负流程流转的判断逻辑;
  2. 扩展不灵活:每新增一种流程编排方式,都要在多个节点里同步修改流转逻辑。

因此,本章换一种设计方式:增强 AgentWorkflowNode 的流转能力,让 LoopAgentNode、ParallelAgentNode、SequentialAgentNode 不再负责判断流转,而是每个流程处理完毕后都回到 AgentWorkflowNode 中进行流转决策。这样,三个功能 Agent 节点的职责更加单一清晰,AgentWorkflowNode 成为唯一的分发中心,我们可以组合出更为复杂的智能体编排。

旧版流程:AgentWorkflowNode <-> Loop/Parallel/Sequential 各节点交叉流转(每个节点各自判断下一个) 新版流程:AgentWorkflowNode(分发中心)-> Loop/Parallel/Sequential 处理业务 -> 回到 AgentWorkflowNode 决策 -> ... -> RunnerNode

用一句话概括:AgentWorkflowNode 是"分发中心",三个智能体节点处理完业务后都回到 AgentWorkflowNode 即可,下一个节点是谁,永远由 AgentWorkflowNode 说了算。

二、流程设计:单点决策、回环流转

新版流程的核心思想是"每个节点流转完都重新回到 AgentWorkflowNode 节点进行决策":

  • 左侧是旧版流程:LoopAgentNode、ParallelAgentNode、SequentialAgentNode 每个节点交叉流转;
  • 右侧是本次的新版流程:所有的流转都由 AgentWorkflowNode 负责,三个功能 Agent 节点的职责更清晰;
  • 由此,AgentWorkflowNode 成为分发中心,三个智能体节点处理完业务后都回到 AgentWorkflowNode 即可。

与此同时,在 第2-12节:增强装配-RunnerNode 中已经实现了 RunnerNode 的增强:用户如果只配置一个基础 Agent,不配置 loop、parallel、sequential 流程,则 AgentWorkflowNode 判断agentWorkflows为空后直接流转到 RunnerNode;RunnerNode 再根据配置中runner声明的 agentName 从上下文按名称取智能体构建 InMemoryRunner。本节则是在此基础上,把"AgentWorkflowNode 什么时候流转、按什么规则流转"补完整,形成闭环。

整体装配链路(结合 第2-11节:智能体加载使用验证 的启动加载):

程序启动 -> 读取 yml 智能体配置 -> AiApiNode -> ChatModelNode -> AgentNode -> AgentWorkflowNode(统一分发)-> Loop/Parallel/Sequential 子节点处理 -> 回环 AgentWorkflowNode -> 配置遍历完毕(currentAgentWorkflow 为 null)-> RunnerNode 构建 InMemoryRunner -> 注册进 Spring 容器 -> 会话对话

三、功能实现

1. 工程结构与改造要点

本章的工程改动聚焦在四个节点类上:

  • 修改LoopAgentNodeParallelAgentNodeSequentialAgentNode,三个节点中的流转操作都转移到AgentWorkflowNode处理;
  • AgentWorkflowNode中,要拿到当前agentWorkflows配置的列表中第 N 个步骤,把拿到的值作为当前信息存储到上下文,之后流转到任何一个节点,该节点只负责从上下文取到当前值即可。

从源码结构看(参见 notes.md 的面试归档),整套装配域采用"组合模式 + 责任链思维"构建了节点(Node)处理管道:定义统一的IArmoryService接口和AbstractArmorySupport抽象类,所有节点遵循相同规范,通过上下文对象DynamicContext在节点间传递配置数据。本节正是对这条责任链上"流转判断"环节的重构。

2. 核心模块

2.1 定义上下文 DynamicContext

AgentWorkflowNode中定义静态内部类DynamicContext(即DefaultArmoryFactory.DynamicContext的演进),代码如下:

@Data @Builder @AllArgsConstructor @NoArgsConstructor public static class DynamicContext { /** * LLM API */ private OpenAiApi openAiApi; /** * 对话模型 */ private ChatModel chatModel; /** * 原子安全的递进步骤 */ private AtomicInteger currentStepIndex = new AtomicInteger(0); /** * 当前的智能体 */ private AiAgentConfigTableVO.Module.AgentWorkflow currentAgentWorkflow; /** * 智能体组 */ private Map<String, BaseAgent> agentGroup = new HashMap<>(); private Map<String, Object> dataObjects = new HashMap<>(); }

与旧版上下文相比,本次改动有两点:

  • 去掉agentWorkflows列表值,增加currentAgentWorkflow当前值:上下文不再持有整个流程列表,只持有"当前正在处理的那一个步骤对象",职责更聚焦;
  • 增加currentStepIndex原子步骤指针:每完成一个步骤则迭代 +1,从agentWorkflows渠道取到的当前对象存储到currentAgentWorkflow,这样判断流转会更方便。

其中currentStepIndex使用AtomicInteger实现"原子安全的递进步骤",在多线程访问装配上下文时保证步骤计数线程安全。这一步设计是项目中"演进式迭代"的体现:先按直觉把整个列表放进上下文,再演进为"指针 + 当前值"的轻量方案,方便读者积累多种设计积累。

2.2 增强流转:AgentWorkflowNode 的 doApply 与 get

增强后的AgentWorkflowNode完整代码如下:

@Slf4j @Service public class AgentWorkflowNode extends AbstractArmorySupport { @Resource private LoopAgentNode loopAgentNode; @Resource private ParallelAgentNode parallelAgentNode; @Resource private SequentialAgentNode sequentialAgentNode; @Resource private RunnerNode runnerNode; @Override protected AiAgentRegisterVO doApply(ArmoryCommandEntity requestParameter, DefaultArmoryFactory.DynamicContext dynamicContext) throws Exception { log.info("Ai Agent 装配操作 - AgentWorkflowNode"); AiAgentConfigTableVO aiAgentConfigTableVO = requestParameter.getAiAgentConfigTableVO(); List<AiAgentConfigTableVO.Module.AgentWorkflow> agentWorkflows = aiAgentConfigTableVO.getModule().getAgentWorkflows(); // 如果未配置 agentWorkflows 则直接流转到 RunnerNode if (null == agentWorkflows || agentWorkflows.isEmpty() || dynamicContext.getCurrentStepIndex() >= agentWorkflows.size()) { // 设置结果值 dynamicContext.setCurrentAgentWorkflow(null); // 路由下节点 return router(requestParameter, dynamicContext); } // 设置当前判断流程对象 dynamicContext.setCurrentAgentWorkflow(agentWorkflows.get(dynamicContext.getCurrentStepIndex())); // 步骤值增加 dynamicContext.addCurrentStepIndex(); return router(requestParameter, dynamicContext); } @Override public StrategyHandler<ArmoryCommandEntity, DefaultArmoryFactory.DynamicContext, AiAgentRegisterVO> get(ArmoryCommandEntity requestParameter, DefaultArmoryFactory.DynamicContext dynamicContext) throws Exception { AiAgentConfigTableVO.Module.AgentWorkflow currentAgentWorkflow = dynamicContext.getCurrentAgentWorkflow(); // 没有下一个节点,流转到结束节点 if (null == currentAgentWorkflow) { return runnerNode; } String type = currentAgentWorkflow.getType(); AgentTypeEnum agentTypeEnum = AgentTypeEnum.fromType(type); if (null == agentTypeEnum) { throw new RuntimeException("agentWorkflow type is error!"); } String node = agentTypeEnum.getNode(); return switch (node) { case "loopAgentNode" -> loopAgentNode; case "parallelAgentNode" -> parallelAgentNode; case "sequentialAgentNode" -> sequentialAgentNode; default -> runnerNode; }; } }

两个方法各司其职,构成"取值 + 分发"的完整闭环:

  • doApply:核心是"取步骤值",类似一个 for 循环。逻辑分三步:

    1. 判断是否配置了agentWorkflows,或步骤指针是否已经走完列表(currentStepIndex >= agentWorkflows.size()),如果是,则dynamicContext.setCurrentAgentWorkflow(null)并路由走——置空表示"流程已经全部处理完毕";
    2. 否则,从agentWorkflows中取出currentStepIndex对应的当前步骤对象,设置到上下文currentAgentWorkflow
    3. 步骤指针 +1(addCurrentStepIndex()),然后router路由到下一节点。
  • get:核心是"节点分发"。逻辑分三步:

    1. 从上下文取出currentAgentWorkflow
    2. 判断是否为 null,为 null 表示没有要处理的节点了,直接进入runnerNode(结束节点);
    3. 非 null 时,读取type,通过AgentTypeEnum.fromType(type)转为枚举,再从枚举拿到节点名称node,用switch表达式分发到loopAgentNodeparallelAgentNodesequentialAgentNode,默认走runnerNode。若type无法解析为合法枚举,则抛出RuntimeException("agentWorkflow type is error!")及时暴露配置错误。

从源码结构可以推断:AgentTypeEnum承担了"配置类型 -> 节点标识"的映射职责,switch分发后,无论走哪个子节点,子节点处理完都会再次路由回agentWorkflowNode,从而形成"AgentWorkflowNode 取值分发 -> 子节点执行 -> 回环 AgentWorkflowNode 再取值分发"的循环,直到currentAgentWorkflow为 null 落入 RunnerNode。

2.3 子智能体节点:只处理业务,不负责流转

三个子节点的改造思路完全一致:从上下文取当前值构建 Agent,处理完路由回agentWorkflowNode

LoopAgentNode
@Service public class LoopAgentNode extends AbstractArmorySupport { @Override protected AiAgentRegisterVO doApply(ArmoryCommandEntity requestParameter, DefaultArmoryFactory.DynamicContext dynamicContext) throws Exception { log.info("Ai Agent 装配操作 - LoopAgentNode"); AiAgentConfigTableVO.Module.AgentWorkflow currentAgentWorkflow = dynamicContext.getCurrentAgentWorkflow(); List<BaseAgent> subAgents = dynamicContext.queryAgentList(currentAgentWorkflow.getSubAgents()); LoopAgent loopAgent = LoopAgent.builder() .name(currentAgentWorkflow.getName()) .description(currentAgentWorkflow.getDescription()) .subAgents(subAgents) .maxIterations(currentAgentWorkflow.getMaxIterations()) .build(); dynamicContext.getAgentGroup().put(currentAgentWorkflow.getName(), loopAgent); return router(requestParameter, dynamicContext); } @Override public StrategyHandler<ArmoryCommandEntity, DefaultArmoryFactory.DynamicContext, AiAgentRegisterVO> get(ArmoryCommandEntity requestParameter, DefaultArmoryFactory.DynamicContext dynamicContext) throws Exception { return getBean("agentWorkflowNode"); } }

改动要点:

  • doApply修改为从上下文的dynamicContext.getCurrentAgentWorkflow()获取当前节点数据(名称、描述、子智能体列表、最大迭代次数maxIterations),通过LoopAgent.builder()构建循环智能体,并放入dynamicContext.getAgentGroup(),随后router路由;
  • get则负责流转回getBean("agentWorkflowNode"),把节点流转的判断权交还给 AgentWorkflowNode。
ParallelAgentNode
@Service public class ParallelAgentNode extends AbstractArmorySupport { @Override protected AiAgentRegisterVO doApply(ArmoryCommandEntity requestParameter, DefaultArmoryFactory.DynamicContext dynamicContext) throws Exception { log.info("Ai Agent 装配操作 - ParallelAgentNode"); AiAgentConfigTableVO.Module.AgentWorkflow currentAgentWorkflow = dynamicContext.getCurrentAgentWorkflow(); List<BaseAgent> subAgents = dynamicContext.queryAgentList(currentAgentWorkflow.getSubAgents()); ParallelAgent parallelAgent = ParallelAgent.builder() .name(currentAgentWorkflow.getName()) .subAgents(subAgents) .description(currentAgentWorkflow.getDescription()) .build(); dynamicContext.getAgentGroup().put(currentAgentWorkflow.getName(), parallelAgent); return router(requestParameter, dynamicContext); } @Override public StrategyHandler<ArmoryCommandEntity, DefaultArmoryFactory.DynamicContext, AiAgentRegisterVO> get(ArmoryCommandEntity requestParameter, DefaultArmoryFactory.DynamicContext dynamicContext) throws Exception { return getBean("agentWorkflowNode"); } }

代码修改方式同LoopAgentNode:从上下文取currentAgentWorkflow,构建ParallelAgent并放入agentGroupget回环agentWorkflowNode

SequentialAgentNode
@Service public class SequentialAgentNode extends AbstractArmorySupport { @Override protected AiAgentRegisterVO doApply(ArmoryCommandEntity requestParameter, DefaultArmoryFactory.DynamicContext dynamicContext) throws Exception { log.info("Ai Agent 装配操作 - SequentialAgentNode"); AiAgentConfigTableVO.Module.AgentWorkflow currentAgentWorkflow = dynamicContext.getCurrentAgentWorkflow(); List<BaseAgent> subAgents = dynamicContext.queryAgentList(currentAgentWorkflow.getSubAgents()); SequentialAgent sequentialAgent = SequentialAgent.builder() .name(currentAgentWorkflow.getName()) .description(currentAgentWorkflow.getDescription()) .subAgents(subAgents) .build(); dynamicContext.getAgentGroup().put(currentAgentWorkflow.getName(), sequentialAgent); return router(requestParameter, dynamicContext); } @Override public StrategyHandler<ArmoryCommandEntity, DefaultArmoryFactory.DynamicContext, AiAgentRegisterVO> get(ArmoryCommandEntity requestParameter, DefaultArmoryFactory.DynamicContext dynamicContext) throws Exception { return getBean("agentWorkflowNode"); } }

代码修改方式同LoopAgentNode

三个节点改造后的共同形态doApply只做"从上下文取当前值 -> 构建对应 Agent -> 写入 agentGroup -> 路由",get统一返回agentWorkflowNode。这正是"每个节点都回到 AgentWorkflowNode 决策"的回环设计,让 AgentWorkflowNode 成为唯一的流转分发中心。

3. 设计要点小结

  • 单一职责:Loop/Parallel/Sequential 三种智能体节点的职责收敛为"构建对应类型的 Agent",流转判断从三个节点中彻底移除;
  • 单点决策:所有"下一步是谁"的决策集中在 AgentWorkflowNode 的get方法中,通过AgentTypeEnum映射type -> node,新增编排类型只需扩展枚举与 switch 分支;
  • 上下文轻量化DynamicContext从持有整个agentWorkflows列表改为持有currentStepIndex + currentAgentWorkflow,配合AtomicInteger保证步骤推进的原子性。

四、测试验证

1. 修改配置文件

测试使用parallel_research_app.yml,完整配置如下:

ai: agent: config: tables: testAgent02: app-name: ResearchAndSynthesisPipeline agent: agent-id: 100002 agent-name: 测试智能体02 agent-desc: 并行研究并汇总的智能体管道 module: ai-api: base-url: https://apis.itedus.cn api-key: sk-Sp2jx3yeq7x7HJ663bDc9bF0D34b4f609f833840271519B1 completions-path: v1/chat/completions embeddings-path: v1/embeddings chat-model: model: gpt-4.1 tool-mcp-list: - sse: name: baidu-search base-uri: https://appbuilder.baidu.com/v2/ai_search/mcp/ sse-endpoint: sse?api_key=bce-v3/ALTAK-3zODLb9qHozIftQlGwez5/2696e92781f5bf1ba1870e2958f239fd6dc822a4 request-timeout: 5000 agents: - name: RenewableEnergyResearcher description: Researches renewable energy sources. instruction: | You are an AI Research Assistant specializing in energy. Research the latest advancements in 'renewable energy sources'. Use the Google Search tool provided. Summarize your key findings concisely (1-2 sentences). Output *only* the summary. output-key: renewable_energy_result - name: EVResearcher description: Researches electric vehicle technology. instruction: | You are an AI Research Assistant specializing in transportation. Research the latest developments in 'electric vehicle technology'. Use the Google Search tool provided. Summarize your key findings concisely (1-2 sentences). Output *only* the summary. output-key: ev_technology_result - name: CarbonCaptureResearcher description: Researches carbon capture methods. instruction: | You are an AI Research Assistant specializing in climate solutions. Research the current state of 'carbon capture methods'. Use the Google Search tool provided. Summarize your key findings concisely (1-2 sentences). Output *only* the summary. output-key: carbon_capture_result - name: SynthesisAgent description: Combines research findings into a structured report. instruction: | You are an AI Assistant responsible for combining research findings into a structured report. Your primary task is to synthesize the following research summaries, clearly attributing findings to their source areas. Structure your response using headings for each topic. Ensure the report is coherent and integrates the key points smoothly. **Crucially: Your entire response MUST be grounded *exclusively* on the information provided in the 'Input Summaries' below. Do NOT add any external knowledge, facts, or details not present in these specific summaries.** **Input Summaries:** * **Renewable Energy:** {renewable_energy_result} * **Electric Vehicles:** {ev_technology_result} * **Carbon Capture:** {carbon_capture_result} **Output Format:** ## Summary of Recent Sustainable Technology Advancements ### Renewable Energy Findings (Based on RenewableEnergyResearcher's findings) [Synthesize and elaborate *only* on the renewable energy input summary provided above.] ### Electric Vehicle Findings (Based on EVResearcher's findings) [Synthesize and elaborate *only* on the EV input summary provided above.] ### Carbon Capture Findings (Based on CarbonCaptureResearcher's findings) [Synthesize and elaborate *only* on the carbon capture input summary provided above.] ### Overall Conclusion [Provide a brief (1-2 sentence) concluding statement that connects *only* the findings presented above.] Output *only* the structured report following this format. Do not include introductory or concluding phrases outside this structure, and strictly adhere to using only the provided input summary content. agent-workflows: - type: parallel name: ParallelWebResearchAgent description: Runs multiple research agents in parallel to gather information. sub-agents: - RenewableEnergyResearcher - EVResearcher - CarbonCaptureResearcher - type: sequential name: ResearchAndSynthesisPipeline description: Coordinates parallel research and synthesizes the results. sub-agents: - ParallelWebResearchAgent - SynthesisAgent runner: agent-name: ResearchAndSynthesisPipeline

这份配置是验证"增强装配"效果的关键,需要理解几个字段的设计意图:

  • agent-workflows配置了ParallelWebResearchAgentResearchAndSynthesisPipeline两个流程步骤:第一个是type: parallel(并行),把三个 Researcher 智能体并行编排;第二个是type: sequential(串行),把ParallelWebResearchAgentSynthesisAgent串行编排。两个步骤依次被 AgentWorkflowNode 的currentStepIndex指针逐个取出,可以测试循环(回环)处理逻辑;
  • runner配置agent-name: ResearchAndSynthesisPipeline:指定装配到 InMemoryRunner 的智能体名称,这正是 第2-12节:增强装配-RunnerNode 中 RunnerNode 按名称从上下文取智能体的设计,在此处落地;
  • agents中四个智能体通过output-key定义输出键:三个 Researcher 的结果(renewable_energy_resultev_technology_resultcarbon_capture_result)通过{...}占位符注入 SynthesisAgent 的 instruction,形成"并行研究 -> 串行汇总"的数据链路;
  • chat-model.tool-mcp-list以 sse 方式挂载了baidu-search搜索工具:让 Researcher 智能体具备实时联网检索能力,request-timeout: 5000控制请求超时。

整个配置对应的执行链路:AgentWorkflowNode 取出ParallelWebResearchAgent-> ParallelAgentNode 并行构建三个研究智能体 -> 回环 AgentWorkflowNode -> 取出ResearchAndSynthesisPipeline-> SequentialAgentNode 串行构建"并行研究 + 汇总" -> 回环 AgentWorkflowNode -> 步骤指针走完,置空后流转 RunnerNode -> 按agent-name装配 InMemoryRunner。

2. 测试方法

@Test public void test_handlerMessage_03(){ AiAgentRegisterVO aiAgentRegisterVO = applicationContext.getBean("100002", AiAgentRegisterVO.class); String appName = aiAgentRegisterVO.getAppName(); InMemoryRunner runner = aiAgentRegisterVO.getRunner(); Session session = runner.sessionService() .createSession(appName, "xiaofuge") .blockingGet(); Content userMsg = Content.fromParts(Part.fromText("你具备哪些能力")); Flowable<Event> events = runner.runAsync("xiaofuge", session.id(), userMsg); List<String> outputs = new ArrayList<>(); events.blockingForEach(event -> outputs.add(event.stringifyContent())); log.info("测试结果:{}", JSON.toJSONString(outputs)); }

测试执行结果(节选):

26-01-01.13:20:04.106 [main ] INFO test_handlerMessage_03 - 测试结果:["我可以帮助你查询和分析可再生能源领域的最新进展,包括太阳能、风能、生物能、地热能、海洋能等各类新能源技术的发展趋势、创新成果及政策动态。同时,我可以利用互联网搜索功能,快速获取最新科研成果、行业动态和相关数据,并将关键信息进行简明总结。","我是专注于电动汽车技术(electric vehicle technology)研究的AI助理,具备以下能力:\n\n1. **新技术检索与总结**:我能利用Google搜索等工具,快速检索最新的电动汽车技术发展、行业动态和科研突破,并进行简洁明了的总结。\n2. **趋势与前沿分析**:能够获取并分析行业趋势,例如电池创新、驱动系统进展、智能网联、电驱动新材料等领域的最新动向。\n3. **政策与市场信息搜集**:可查询全球各地与电动汽车相关的政策、市场增长、补贴政策等信息。\n4. **参考文献和数据追溯**:能帮助定位权威期刊、会议论文、专利等技术文档,提供学术研究支持。\n5. **技术对比与评估**:可对比不同品牌、技术路径或产品,分析其优劣及市场应用前景。\n6. **简明交流和摘要能力**:围绕"电动汽车技术",可将复杂技术信息压缩为1-2句话的核心摘要,便于快速理解。\n\n如果你有特定方向的需求(如电池、驱动控制、充电技术等),我也能定向进行最新信息搜索和研究。","我具备以下能力,专注于碳捕集(carbon capture)相关的研究与信息获取:\n\n1. 实时网络检索:我可以通过专业搜索工具实时获取最新关于碳捕集方法、技术进展、应用案例、政策法规等公开信息。\n2. 资料梳理与总结:对检索到的信息快速提炼要点,进行结构化、简明扼要的总结,便于决策与参考。\n3. 技术分类与比较:能够对比不同类型的碳捕集技术(如直接空气捕集、点源捕集、碳矿化、生物碳捕集等)的原理、优缺点和应用现状。\n4. 最新动态追踪:跟踪全球范围内碳捕集领域的最新动态、前沿研究和重大项目进展。\n5. FAQ解答:针对碳捕集相关的常见问题(如成本、能效、行业难点等)进行专业、准确回答。\n\n如需获取某一具体问题或领域的最新信息,请直接告诉我!","## Summary of Recent Sustainable Technology ..."]

运行后可以看到:三个并行研究的 Researcher 智能体分别返回各自的领域能力介绍,随后 SynthesisAgent 输出结构化汇总报告。测试结果验证了增强后的装配方式是没问题的——并行节点与串行节点在 AgentWorkflowNode 的统一分发下被正确装配并执行

五、读者作业

  • 简单作业:完成本节功能的编写,理解此处的架构设计。对于节点的流转,打开思路,之后活学活用。可以对照 第2-8节:装配域节点-AgentWorkflowNode 与 第2-9节:装配域节点-Loop、Parallel、Sequential 的旧版设计,体会"交叉流转"与"回环分发"两种方案的差异与演进动机;
  • 复杂作业:尝试配置一个多层嵌套的智能体(例如"并行 -> 串行 -> 再并行"的三层结构),来验证这样的装配。配置时注意agent-workflows中每一步的typesub-agents的引用关系,以及runner.agent-name最终指向的汇总智能体名称。

六、总结

本节通过把流转决策收拢到 AgentWorkflowNode,完成了对智能体装配域的一次关键演进:

  1. 上下文重构DynamicContextcurrentStepIndex(AtomicInteger 原子步骤指针)+currentAgentWorkflow(当前流程对象)替代原先持有整个agentWorkflows列表的设计;
  2. 回环分发AgentWorkflowNode.doApply负责"按步骤取值 + 步骤推进",get负责"按 type 分发到具体节点",子节点处理完统一回环agentWorkflowNode
  3. 职责清晰:LoopAgentNode、ParallelAgentNode、SequentialAgentNode 只负责从上下文取值构建对应 Agent,不再各自判断流转;
  4. 配置驱动:通过agent-workflows编排步骤、runner.agent-name指定入口智能体,即可组合出"并行研究 + 串行汇总"这类复杂嵌套智能体,并借助单测完成端到端验证。

配合 第2-12节:增强装配-RunnerNode 的 RunnerNode 增强,整套智能体装配链路(Api -> ChatModel -> Agent -> Workflow -> Runner -> Spring 容器)在"配置即编排"的思路下变得完整且可扩展,为后续 第2-14节:增强装配-本地mcp、第2-15节:增强装配-回调plugin、第2-20节:增强装配-skills 等更多能力扩展奠定了流转基础。

  • 文档
  • 教程
  • 后端

【免费下载链接】CodeGuide

:books: 本代码库是作者小傅哥多年从事一线互联网 Java 开发的学习历程技术汇总,旨在为大家提供一个清晰详细的学习教程,侧重点更倾向编写Java核心内容。如果本仓库能为您提供帮助,请给予支持(关注、点赞、分享)!

项目地址:https://gitcode.com/gh_mirrors/code/CodeGuide
点击查看免费下载
上一篇:终极网页表格提取指南:用requests-html轻松获取数据
下一篇:CNNDetection实战教程:5分钟学会识别AI生成的假图片

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 14:31:30

Docker实战 | 使用Docker部署OtterWiki知识管理工具

【Docker项目实战】使用Docker部署OtterWiki知识管理工具一、OtterWiki介绍1.1 OtterWiki项目简介1.2 OtterWiki主要特点二、本次实践规划2.1 本地环境规划2.2 本次实践介绍三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本四、拉取Otter…

作者头像 李华
网站建设 2026/9/24 14:28:48

WinUtil:装软件做优化修系统,一个窗口搞定

WinUtil&#xff1a;装软件做优化修系统&#xff0c;一个窗口搞定 【免费下载链接】winutil Chris Titus Techs Windows Utility - Install Programs, Tweaks, Fixes, and Updates 项目地址: https://gitcode.com/GitHub_Trending/wi/winutil 新机装系统那天&#xff0c…

作者头像 李华
网站建设 2026/9/24 14:26:13

Jackett错误报告系统:用户反馈与自动提交

Jackett错误报告系统&#xff1a;用户反馈与自动提交 在使用Jackett的过程中&#xff0c;用户可能会遇到各种错误和问题。Jackett提供了完善的错误报告系统&#xff0c;帮助用户收集、分析和提交错误信息&#xff0c;以便开发团队及时解决问题。本文将详细介绍Jackett错误报告…

作者头像 李华
网站建设 2026/9/24 14:25:15

fq 解码 STL:用 jq 解析二进制立体光刻(Stereolithography)模型文件

开发工具CLI 【免费下载链接】fq fq - jq for binary formats. Tool, language and decoders for working with binary formats. 项目地址&#xff1a; https://gitcode.com/gh_mirrors/fq/fq 点击查看 免费下载 fq 是一个面向二进制格式的 jq 风格工具、脚本语言与解码器集合…

作者头像 李华