
前面的学习已经完成了Memory → RAG → Tool → MCP → Structured Output。这些组件解决了 Agent 能知道什么、能够调用什么以及怎样把结果交给 Java 的问题。当 Tool 数量越来越多、任务越来越长时下一个问题会变成谁来决定程序下一步执行什么有些业务流程可以由 Java 提前确定有些任务需要 LLM 根据实际情况动态选择。Spring AI 的Agent Workflow正是在处理这一层问题。一、先理解 Agent 中的两种控制方式传统 Java 程序具有非常明确的控制路径if 条件成立 ↓ 调用 Service A ↓ 调用 Service B ↓ 返回结果相同输入和状态通常会进入相同的代码路径。LLM 的输出具有概率性。模型面对同一个问题时受到 Prompt、上下文、模型版本和采样参数影响可能产生不同判断。因此一个实际 Agent 通常同时存在两种控制力量Java / Workflow → 决定必须遵守的业务流程 LLM → 处理语义理解和无法提前写死的决策例如退款流程可以固定为识别退款意图 ↓ 查询订单 ↓ 检查退款资格 ↓ 满足条件后申请退款其中“用户到底想退款、咨询退款规则还是查询退款进度”很适合交给 LLM 判断。而if (refundAmount 5000) { requireManualApproval(); }这种业务规则更适合继续由 Java 控制。Spring AI 官方将这两类 Agentic System 分别称为 Workflow 和 Agent。Workflow 使用预定义代码路径组织模型与工具【Workflow静态】Agent 允许模型动态决定自己的执行过程【Agent动态都类似于工作的模式或者说智能系统Agentic System】。对于规则明确的企业任务Workflow 往往具有更稳定的可预测性。二、Workflow把 LLM 放进确定的业务步骤最简单的是 Chain Workflow即多个步骤顺序执行。例如用户输入 ↓ 提取需求 ↓ 生成方案 ↓ 检查方案 ↓ 生成最终结果代码本质仍然是普通 JavaString requirement chatClient.prompt() .user(提取需求 input) .call() .content(); String plan chatClient.prompt() .user(根据需求生成方案 requirement) .call() .content(); String result chatClient.prompt() .user(检查并完善方案 plan) .call() .content();LLM 负责每一步内部的智能处理Java 负责规定步骤顺序。Spring AI 官方的 Chain Workflow 示例采用同样的结构前一步输出作为后一步输入非常适合具有明确顺序的复杂任务。三、Routing先判断意图再进入不同流程很多 Agent 的第一步其实是 Routing也就是意图路由。例如客服系统收到“为什么昨天扣了我两次钱”模型可以先输出billing然后 Java 将它路由到对应业务用户请求 ↓ LLM 意图识别 ↓ billing / technical / general ↓ 不同 Workflow实际开发时最好让模型返回结构化结果public record RouteDecision( String route, String reason ) {}然后RouteDecision decision chatClient .prompt() .user( 判断下面问题属于 billing、technical 或 general message) .call() .entity(RouteDecision.class);Java 再根据结果执行return switch (decision.route()) { case billing - billingService.handle(message); case technical - technicalService.handle(message); default - generalService.handle(message); };这里体现了 Structured Output 的一个重要价值自然语言决策可以转换成 Java 能够稳定读取的控制信号。Routing 也是 Spring AI 官方列出的基础 Agent Workflow 模式。四、长任务还需要 Task State学习过ChatMemory后很容易把所有“记忆”都放到 Memory 中。实际 Agent 还需要区分 Conversation Memory 和 Task State。【对于长任务需要补充State】ChatMemory 主要保存用户之前说过什么 模型之前回答过什么 当前对话需要哪些上下文Task State 保存的是任务执行状态例如任务目标完成退款 当前步骤检查退款资格 orderIdA1024 订单状态PAID 资格检查PASSED 下一步申请退款它可以直接使用普通 Java 对象public record RefundState( String orderId, String currentStep, boolean eligible, String status ) {}复杂 Agent 的运行过程因此更适合理解成ChatMemory → 对话上下文 Task State → 当前任务执行到了哪里 Database / Tool → 外部业务世界现在是什么状态Task State 可以存入 Redis、数据库或者工作流引擎。它属于普通软件系统状态管理并不要求全部塞进 Prompt。五、任务复杂以后Planning 与 Orchestrator-Workers有些任务无法提前知道具体步骤。例如“分析这个项目代码并给出性能优化方案。”系统可能需要读取项目结构 分析数据库代码 分析缓存 分析接口 运行性能测试 汇总问题不同项目产生的子任务还可能完全不同。这时可以让 LLM 承担 Orchestrator复杂目标 ↓ LLM 分解任务 ↓ Task A Task B Task C ↓ ↓ ↓ Worker Worker Worker └───────┬───────┘ ↓ 汇总结果Spring AI 将这种模式称为Orchestrator-Workers。Orchestrator 动态产生子任务Worker 分别执行再汇总结果。官方建议将它用于无法提前预测子任务的复杂任务【比较简单、模糊的复杂任务口令】。如果多个任务彼此独立还可以并行执行任务 ↓ ├── 分析代码质量 ├── 分析性能 └── 分析安全风险 ↓ 汇总这对应Parallelization Workflow可以降低多个独立 LLM 任务串行执行带来的延迟。【Workflow有点像是代码预定义的一种工作模式chain/分布式拆解/并行执行等】六、Evaluator-Optimizer让一次任务内部自我修正还有一类模式非常重要生成结果 ↓ Evaluator ↓ 达到标准 ↓否 给出修改意见 ↓ 再次生成 ↓ 重新评价例如生成 Java 代码后可以让另一个步骤检查是否线程安全 是否满足接口要求 是否遗漏异常处理没有达到要求就重新生成。Spring AI 官方称其为Evaluator-OptimizerWorkflow适合具有明确评价标准并且多轮修改能够稳定提高结果质量的任务。Spring AI 2.0 中已经存在类似思想。例如.entity( Result.class, spec - spec.validateSchema() )如果模型输出不符合 JSON SchemaStructuredOutputValidationAdvisor会获得具体验证错误再请求模型修正默认最多执行多次尝试。Tool Calling 本身也是一种递归循环LLM ↓ Tool ↓ Tool Result ↓ LLM ↓ 继续判断Spring AI 2.0 的ToolCallingAdvisor正是一个 Recursive Advisor。七、运行时 Evaluator-Optimizer 与 Eval 需要区分这里需要区分两个很容易混淆的概念Evaluator-Optimizer 是 Agent 的运行时优化模式Eval 是评价 AI 输出质量的方法和工程过程。Evaluator-Optimizer 工作在当前任务内部生成 ↓ 评价 ↓ 发现问题 ↓ 提供反馈 ↓ 重新生成 ↓ 再次评价它的目标是利用评价结果继续修改当前输出。例如模型生成代码以后Evaluator 检查是否满足接口要求如果缺少异常处理就把问题反馈给模型让模型继续修改。而 Eval 的核心目标是衡量结果好不好。它既可以评价一个案例也可以批量运行整个测试集。例如单个案例用户问题 RAG Context 模型回答 ↓ RelevancyEvaluator ↓ Pass / Fail如果进一步准备 100 个测试案例100个 Eval Case ↓ 分别执行 Evaluator ↓ 聚合评价结果 ↓ 得到当前版本质量指标于是可以比较v1 Prompt87 / 100 v2 Prompt93 / 100因此更准确的关系是Evaluator-Optimizer → 评价之后继续修改当前任务结果 → 属于运行时 Agent Workflow Eval → 评价结果质量 → 可以作用于单个 Case、整个 Dataset、 RAG、Tool Calling 或完整 Agent Regression Test → 把一批固定 Eval Case 在系统修改以后重新运行 → 比较不同版本有没有提升或退化还有一个很重要的细节两者可以使用相似的评价技术。例如都可以使用 LLM-as-a-JudgeEvaluator-Optimizer 回答 ↓ Judge LLM ↓ “不完整需要补充来源” ↓ 重新生成而离线 Eval 中回答 ↓ Judge LLM ↓ 得分3 / 4 ↓ 记录到测试结果Spring AI 官方现在甚至已经给出了基于 Recursive Advisor 构建 LLM-as-a-Judge 自我修正循环的示例这说明“评价”本身既可以用于测试也可以进入运行时优化循环。区别主要在评价结果是否继续驱动当前任务重新生成。因此以后最好统一记成一句Evaluator 是“怎么评价”Eval 是“建立评价过程”Evaluator-Optimizer 是“评价以后根据反馈继续优化当前结果”回归测试是“把一组 Eval Case 在新版本上重新跑一遍”。八、Agent 出错时先判断错误发生在哪一层到这里一个 Agent 已经包含很多组件用户 ↓ Routing ↓ Memory / Context ↓ RAG ↓ LLM ↓ Workflow / Planning ↓ Tool ↓ 外部系统 ↓ Structured Output因此用户最终看到一句错误回答时原因可能完全不同。例如知识库根本没有退款规则 → Knowledge 问题 知识库有规则但 RAG 找错文档 → Retrieval 问题 正确文档已经进入 Prompt模型理解错误 → Prompt / Model 问题 模型判断正确但调用错 Tool → Tool Calling 问题 Tool 正确但数据库数据错误 → Business Data 问题 答案正确但 JSON 格式错误 → Output 问题这就是后续模型效果优化最重要的前置认识大模型应用的最终效果来自多个组件共同作用所以优化工作首先需要定位错误发生在哪个环节。Spring AI 的Observability也围绕这种思想设计。当前框架能够记录ChatClient、Advisor、ChatModel、Tool Calling、EmbeddingModel 和 VectorStore 等组件的 metrics(性能指标) 与 traces为后续问题定位提供基础。九、当前阶段的完整心智模型现在可以把 Spring AI Agent 理解成三个层次第一层信息 Memory RAG Context Business Data ↓ 第二层决策与编排 LLM Routing Planning Workflow Evaluator ↓ 第三层执行 Tool MCP Java Service Database / API外围还有一层工程保障Structured Output Validation Observability Eval Error Handling因此成熟的 Agent 开发已经越来越接近普通软件工程模型只是其中一个概率性组件。Java 继续负责状态、权限、事务、流程和可靠执行LLM 负责语言理解以及适合动态处理的决策。下一篇就可以正式回答一个更加实际的问题当大模型应用效果不好时到底应该改 RAG、Prompt、Tool、Workflow建立 Eval还是进一步进行 SFT、LoRA、量化和蒸馏届时可以按照“知识缺失 → 检索错误 → 上下文利用错误 → 工具执行问题 → 偶发 Badcase → 稳定能力缺陷 → 成本与延迟”的顺序建立一套完整的模型效果优化判断路径。