当前位置: 首页 > news >正文

Agent 设计模式终极整合:六大模式合一,一套 Java 框架从开发到生产部署

ReAct、Plan-Execute、Tool Use、Reflection、Multi-Agent、Router——六篇文章拆完了六种模式,但真实项目不会只用一种。这篇把整个系列收尾,给你一个能直接部署的 Agent 框架。

前面六篇我们拆了 ReAct、Multi-Agent、Reflection、Plan-Execute、Tool Use、Router。每种模式单独看都不复杂,但真实项目不会只用一种。

问题来了:六种模式放在一起,怎么组织代码?怎么管理配置?上线之后出问题怎么排查?

这篇把整个 Agent 系列收尾,给你一个能直接部署的框架结构。


整体架构长什么样

先看全局。整个框架的核心思路是:Router 做入口,根据任务类型分发到不同策略链,每个策略链内部可以组合多种模式。

用户输入 → Router 分类 → 策略链执行 → 结果返回

具体来说:

  • 简单查询(“查今天销售额”)→ Router 判定 TOOL_USE → 直接调工具返回结果
  • 多步骤任务(“生成周报发老板”)→ Router 判定 PLAN_EXECUTE + TOOL_USE → 先规划再执行,执行中调工具
  • 推理任务(“这段代码为什么有bug”)→ Router 判定 REACT + REFLECTION → 边推理边验证,最后自查一遍
  • 复杂任务(“分析竞品优劣势”)→ Router 判定 MULTI_AGENT → 多个 Agent 分工协作

这个架构的关键是:Router 是唯一入口,所有任务先过分类再执行。不要让用户直接指定策略——他们不知道该用什么,你也不应该要求他们知道。


项目结构怎么分

一个完整的 Agent 框架,我建议这样分模块:

agent-framework/├── src/main/java/com/qiutian/agent/│ ├── core/ # 核心接口和基类│ │ ├── AgentStrategy.java # 策略枚举│ │ ├── AgentContext.java # 上下文对象(传递任务、历史、工具)│ │ └── BaseAgent.java # 所有Agent的基类│ ├── router/ # 路由层│ │ ├── TaskRouter.java # 分类器│ │ └── RouterPrompt.java # 提示词管理│ ├── patterns/ # 六种模式实现│ │ ├── ReActAgent.java│ │ ├── PlanExecuteAgent.java│ │ ├── ToolUseAgent.java│ │ ├── ReflectionAgent.java│ │ ├── MultiAgent.java│ │ └── ChainAgent.java # 组合策略链│ ├── tools/ # 工具定义│ │ ├── DatabaseTool.java│ │ ├── EmailTool.java│ │ └── SearchTool.java│ ├── orchestrator/ # 编排层│ │ └── AgentOrchestrator.java # 统一入口│ └── config/ # 配置管理│ ├── AgentProperties.java│ └── ToolRegistry.java├── src/main/resources/│ ├── application.yml # Spring AI配置│ └── prompts/ # 提示词模板文件│ ├── react.txt│ ├── plan_execute.txt│ └── router.txt└── pom.xml

为什么这么分?三个原则:

  1. 每个模式独立一个类,互不依赖。改 ReAct 不会影响 Plan-Execute,加新模式不影响老模式。
  2. 提示词不放代码里。放 resources/prompts/ 下面,用 Spring 的 @Value 加载。改提示词不用重新编译,线上热更。
  3. 工具单独一层。ToolRegistry 统一管理所有工具的注册和查找,Agent 不直接持有工具引用,而是通过 Registry 按需获取。

核心代码:统一编排器

整个框架的入口是 AgentOrchestrator。它负责调 Router 分类,然后按策略链执行:

@Servicepublic class AgentOrchestrator { private final TaskRouter router; private final Map<AgentStrategy, BaseAgent> agents; private final ChainAgent chainAgent; // Spring会自动把所有BaseAgent实现注入到这个Map里 // Key是策略名,Value是对应的Agent实例 public AgentOrchestrator( TaskRouter router, List<BaseAgent> agentList, ChainAgent chainAgent) { this.router = router; this.agents = agentList.stream() .collect(Collectors.toMap( BaseAgent::getStrategy, a -> a )); this.chainAgent = chainAgent; } public String execute(String task) { // 1. 路由分类 List<AgentStrategy> chain = router.routeChain(task); // 2. 单策略直接执行 if (chain.size() == 1) { BaseAgent agent = agents.get(chain.get(0)); return agent.solve(task); } // 3. 多策略走链式执行 return chainAgent.solveChain(task, chain, agents); }}

这里有个设计要点:用 Spring 的依赖注入把所有 BaseAgent 实现自动收集到 Map 里。新增一个模式?写个类继承 BaseAgent,加个 @Component 注解,自动就进来了。不用改 Orchestrator 的代码。

再看 BaseAgent 的定义:

// 所有Agent模式的基类public abstract class BaseAgent { protected final ChatClient chatClient; protected final ToolRegistry toolRegistry; protected BaseAgent(ChatClient chatClient, ToolRegistry toolRegistry) { this.chatClient = chatClient; this.toolRegistry = toolRegistry; } // 每个子类实现自己的处理逻辑 public abstract String solve(String task); // 返回这个Agent对应的策略 public abstract AgentStrategy getStrategy(); // 通用方法:加载提示词模板 protected String loadPrompt(String name) { // 从resources/prompts/加载,支持运行时热更 try { Path path = Path.of("src/main/resources/prompts/" + name); return Files.readString(path); } catch (IOException e) { throw new RuntimeException("提示词文件不存在: " + name, e); } }}

为什么提示词从文件读而不是写死在代码里?因为提示词是需要频繁调试的。你上线后发现 Router 分类不准,大概率是提示词要调,不是代码要改。从文件读,改完重启就行,不用重新编译打包。


配置管理

Spring AI 的配置放在 application.yml 里:

spring: ai: openai: api-key: ${OPENAI_API_KEY} model: gpt-4o temperature: 0.3 # Router用低温度保证分类稳定agent: router: max-retries: 2 # 分类失败重试次数 fallback-strategy: REACT # 分类失败时的兜底策略 react: max-iterations: 10 # ReAct最大循环次数 timeout-seconds: 60 # 单次执行超时 plan-execute: max-steps: 8 # 最大规划步骤数 tools: enabled: - database - email - search

用 @ConfigurationProperties 绑定:

@ConfigurationProperties(prefix = "agent")@Configurationpublic class AgentProperties { private RouterConfig router = new RouterConfig(); private ReactConfig react = new ReactConfig(); private PlanExecuteConfig planExecute = new PlanExecuteConfig(); private ToolConfig tools = new ToolConfig(); @Data public static class RouterConfig { private int maxRetries = 2; private AgentStrategy fallbackStrategy = AgentStrategy.REACT; } @Data public static class ReactConfig { private int maxIterations = 10; private int timeoutSeconds = 60; } @Data public static class PlanExecuteConfig { private int maxSteps = 8; } @Data public static class ToolConfig { private List<String> enabled = new ArrayList<>(); }}

为什么要抽配置?因为你不同环境需要不同的参数。开发环境 max-iterations 可以设大一点方便调试,生产环境要设小一点控制成本和延迟。配置外置后,改 yml 不改代码。


生产环境三个坑

第一个坑:没有超时控制

ReAct 模式可能死循环,Plan-Execute 可能规划出20个步骤无限执行。每个 Agent 的 solve 方法外面必须套超时:

public String execute(String task) { try { return CompletableFuture .supplyAsync(() -> agent.solve(task)) .get(timeoutSeconds, TimeUnit.SECONDS); } catch (TimeoutException e) { // 超时后返回已有结果,不要返回空 log.warn("Agent超时,task: {}", task); return "处理超时,请简化任务后重试"; }}

第二个坑:没有成本监控

每次 API 调用都花钱。Router 多一次分类调用,ReAct 可能循环10次,Multi-Agent 可能调用5个Agent。不做监控的话,月底账单能吓死人。

加一个简单的计数器:

@Componentpublic class TokenCounter { private final AtomicInteger totalCalls = new AtomicInteger(0); private final Map<String, AtomicInteger> callsByStrategy = new ConcurrentHashMap<>(); public void record(AgentStrategy strategy) { totalCalls.incrementAndGet(); callsByStrategy .computeIfAbsent(strategy.name(), k -> new AtomicInteger()) .incrementAndGet(); } public Map<String, Integer> getStats() { return callsByStrategy.entrySet().stream() .collect(Collectors.toMap( Map.Entry::getKey, e -> e.getValue().get() )); }}

每次 Agent 执行完调一次 record,你就能看到哪种策略用得最多,哪种策略成本最高。

第三个坑:提示词没有版本管理

提示词是 Agent 的灵魂,但你改了提示词之后旧版本就没了。出了问题你想回滚都不知道改了什么。

最简单的办法:提示词文件名带版本号,router_v1.txt、router_v2.txt。配置里指定用哪个版本。改的时候新建一个版本文件,不动旧的。出问题切回去就行。


跑起来的效果

我把这个框架用在一个企业知识库助手上。日均处理 200 多个用户提问,Router 分类准确率 87% 左右。

任务类型占比策略平均调用次数响应时间
简单查询60%TOOL_USE1.2次<2秒
复杂任务30%PLAN_EXECUTE/REACT4-6次8-15秒
多Agent任务10%MULTI_AGENT8-12次20-30秒

日均 API 调用约 800 次,成本控制在每天 15 块以内。如果不加 Router 全走 ReAct,日均调用会到 2000 次以上,成本翻 2.5 倍。

学AI大模型的正确顺序,千万不要搞错了

🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!

有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!

就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋

📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇

学习路线:

✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经

以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!

我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

http://www.jsqmd.com/news/1291047/

相关文章:

  • 基于OSM路网与ArcGIS Pro的交通分析小区自动化生成方法
  • 如果 iPhone 丢失或被盗,如何远程擦除 iPhone?
  • 35B大模型16GB显存部署对比:Ornith与Qwen实测指南
  • 别再用普通翻译写论文[特殊字符]OKBIYE学术翻译才是正确打开方式
  • 告别论文内耗✨一个OKBIYE搞定毕业全流程
  • ESP-IDF保姆级入门06|I2C通信详解 + 0.96寸OLED屏幕驱动实战:显示文字_数字_动态数据(零基础可复现)
  • AI合同模板生成实战手册:从零搭建企业级智能合同工厂,7天上线交付
  • 渗透测试效率倍增器:2026年十大必备安全工具深度评测与进阶用法(附一键安装脚本)
  • 电子系统设计实战:从硬件到Windows客户端软件开发全流程解析
  • PyTorch深度学习入门:从张量、自动微分到完整训练流程实战
  • Python位运算实战:左移右移核心原理与高效应用
  • AI 与 BI 的融合路径:传统看板被自然语言查询取代还要多久
  • RAG与Agentic RAG技术对比与应用指南
  • 3步解锁英雄联盟极致体验:League Akari的智能本地化解决方案
  • 计算机保研夏令营申请策略:从海投到精准投递的实战复盘
  • 开题不用熬夜硬凑✨OKBIYE开题功能真的太贴合高校规范了
  • ToDesk被控端双屏切换教程,远程办公效率翻倍
  • 实测才敢推 一键生成论文工具 2026最新测评与推荐
  • WarcraftHelper终极指南:3步解锁魔兽争霸III现代系统兼容性
  • 3.1.7.Qt容器大家族(3):QVariant——万能盒子
  • GTO、GTR、MOSFET、IGBT四大功率半导体核心区别与选型实战指南
  • 国内专业的冷焊机定制厂家推荐,水冷电火花堆焊机/冷焊机/精密模具修补机/金属缺陷修补机,冷焊机实力厂家推荐 - 品牌推荐师
  • 机房断网怎么装服务?Nginx 源码编译 + 自建内网 yum 仓库从零手把手教学
  • 模型评测的未来:自动化、标准化、场景化三化趋势
  • VTK+Qt最小示例:打通C++三维可视化开发环境与核心集成
  • 2026年GEO信源发稿平台推荐:4大主流平台5大核心维度对比与选购指南
  • Nginx安装配置与性能优化全指南
  • 开题报告拿高分的秘密[特殊字符]这才是高校认可的标准开题
  • 7月内核调优路线图——从单点参数到场景化自动配置演进路径
  • mall-项目redis三剑客