Java 写 Agent:模型只是组件

摘要:Spring AI 2.0 把工具调用循环从模型黑盒搬进 Advisor 链,模型不再是主角。审批、海量工具、存量升级三个落点,讲清 Java 写 Agent 的设计思路。

给后端项目接 Agent,第一版代码通常天真得像 Hello World:

java 复制代码
String answer = ChatClient.create(chatModel)
        .prompt("查一下供应商 A 的付款状态")
        .call()
        .content();

demo 跑得很顺。等要上线,产品提了三个要求:调"发送付款指令"这个工具前,必须过一道人工审批;每次工具调用要留审计日志;同一个问题不能让模型反复烧钱,要能设上限。

这时候你会发现问题不在模型,在这几行代码上------没有一处能插进这些逻辑。工具调用发生在哪、循环了几次、什么时候停,全埋在 ChatClient 背后的 ChatModel 里。你调得到工具,却够不着循环。

Agent 不是"带系统提示词的聊天端点"。Spring AI 官方文档把界线划得很清楚:只能生成文本的是聊天机器人,能发现信息、采取行动、循环到目标才算 Agent(官方文档)。那个"选工具、执行、看结果、再决定"的循环,才是工程化真正要管的东西。模型只是循环里最聪明、也最不可控的一个组件。

1.x:循环锁在模型黑盒里

Spring AI 1.x 里,每个 ChatModel 实现都维护着自己的一套私有工具循环:模型说"我要调 getWeather",框架执行、把结果塞回对话、再问一次,直到模型不再请求工具。

功能是通的,问题在它埋在模型实现内部。看不到中间步骤,组合不了日志、校验、重试,也没法在工具调用前后插入自定义逻辑,工具请求和响应对上层 Advisor 链完全不透明。用一句话概括:你能调用工具,但无法在工具之上构建任何东西。

这句话对 Java 后端尤其扎心。Spring 最值钱的工程能力------事务、安全、审计、限流------全都够不着这个循环。模型封装得越干净,工程化越无从下手。

2.0:循环搬进 Advisor 链

Spring AI 2.0 在 2026 年 6 月 12 日 GA,基线切到 Spring Boot 4 / Framework 7,Java 17 起步、推荐 21(2.0.1 发布说明)。它做的最核心的一件事,是把工具循环从各 ChatModel 实现里抽出来,变成 Advisor 链上的标准组件 ToolCallingAdvisor。

ChatClient 把每次请求丢进一条有序的 Advisor 链,链本身支持循环------Advisor 可以重新进入下游链。同一套机制,同时驱动工具调用循环、结构化输出重试循环、评估循环。

这套设计里最值得注意的,是循环的位置:它不再是模型实现里没法碰的私有逻辑,而是应用代码里的标准部件。

循环本身还是那个循环:注入工具定义(名称、描述、JSON Schema),发请求;模型要求调工具就执行、结果并回对话、再来一轮,直到模型不再请求工具。

变化的只是位置------它长在你代码够得着的地方,阻塞的 .call() 和流式的 .stream() 都走同一条链。

实战一:把审批装进循环

产品要的"付款前过审批",在 2.0 里有清晰的落点。

一个办法是全局开关:关掉自动执行。工具定义照常发给模型,但它只输出"我想调哪个工具、参数是什么",执行权交回你的代码。

另一个是细粒度检查:ToolExecutionEligibilityChecker 让你在每次执行前问一句"这次允许吗"。权限逻辑写在一个地方,循环里的每一步都会来问你。

比事后审计更狠的一招是工具参数增强:给工具动态附加一层参数,比如 reason(为什么调)、approver(谁批准)。模型执行前必须先把这些字段填出来------调用还没发生,它就得先交代动机,出了事也追得到是谁批的。

审批、审计、重试上限,全都能挂在这个循环上,而不是散落在各家模型 SDK 里。这正是"模型只是组件"的工程含义。

实战二:工具一多,循环先崩

Java 后端接 Agent 有个独有场景:企业内部系统批量通过 MCP 暴露成工具,单次会话聚合上百个工具定义是常态。每次请求把所有工具的 JSON Schema 全塞给模型,上下文迅速膨胀,模型开始选错工具,token 成本翻着倍走。

2.0 的答案是 ToolSearchToolCallingAdvisor------渐进式工具发现:会话开始时把全部工具建一次索引,每轮只按需检索最相关的几个注入上下文,能显著压缩 token 开销(官方基准覆盖三家主流模型)。

索引有轻量 regex、关键词、向量语义几种策略,工具规模越大,越值得上向量那档。

代价同样要写清楚:索引按会话隔离,调用方必须传 session ID;检索质量本身要单独验证------"找不到该用的工具"和"工具太多选错"是两种死法,后者只是换了种死法。省下的 token,要拿一部分去建评测集、验证检索,这笔账得算进去。

升级不是换版本号

2.0 不是 1.x 的小版本。核心模块拆成按需引入的多个 starter,Options 全面改成不可变对象,改配置要用 .mutate() 重建。

1.x 项目迁过去,是一个小型升级工程:编译期修复之外,工具循环、记忆、流式行为都要回归测试。

1.1.x 还在维护,给留在 Spring Boot 3.x 的项目兜底。

判断要给就给出边界:新项目直接上 2.0。存量项目还没碰海量工具、MCP 2.0 这些 2.0 的主场的话,留在 1.1.x 等一个稳定窗口不丢人。

急着升,容易把 Agent 本身没验证清楚的行为问题,和新基线的问题搅在一起,到时候分不清是谁的锅。

循环在谁手里,Java 才算数

把循环从模型手里拿出来,带来的不只是几个新 API。模型适配层开始向厂商官方 SDK 收敛,各家模型对工具调用的支持差异被框架抹平------评估一个新模型,只看质量就行,不用连带评估它绑定的那套工具执行逻辑。

这也解释了为什么"企业 Java 做 AI"和"Python 原型"是两种物种。原型比的是模型聪明不聪明;生产比的是循环能不能被审计、被限流、被审批。

至少在这套体系里,Java 多年攒的工程能力终于能完整罩在 Agent 上。不是模型让 Java 重新伟大,是循环把 Java 的老本行还给了 Java。

下次有人问 Java 能不能写 Agent,别急着比模型。先问一句:你的循环在谁手里?在模型黑盒里,你能做的只有换模型;在自己代码里,你才能加审批、留日志、定上限。这才是 Java 写 Agent 真正的开始。

参考资料

  1. Spring AI 官方文档 · Tool Calling,https://docs.spring.io/spring-ai/reference/api/tools.html
  2. Spring AI 2.0.1 发布说明,Christian Tzolov,2026-08-21,https://spring.io/blog/2026/08/21/spring-ai-2-0-1-available-now
  3. spring-projects/spring-ai(GitHub),https://github.com/spring-projects/spring-ai

作者:唐悦玮 | 从后端出发,用 AI 拓展到全栈的工程师。

相关推荐
小玮看世界1 小时前
[Python]从合并区间到传感器融合区:合并区间在传感器区域融合的实际落地
开发语言·python
彧azz2 小时前
Java学习语法篇:变量
java·学习
繁星蓝雨2 小时前
C++的设计与演进大纲(如何从C语言一步步成长为C++)
c语言·开发语言·c++·c++历史·c++演进
Evand J2 小时前
【MATLAB例程,图像降噪滤波9】自适应维纳滑动窗口滤波(Wiener)图像降噪、方法对比,有中文注释
开发语言·图像处理·计算机视觉·matlab·滑动窗口·滤波·降噪
杜大哥3 小时前
python程序:如何查看电脑【电池电量的剩余百分比】 和 【是否插入连接着充电器】?
开发语言·python
wuyk5553 小时前
Python网络爬虫入门到实战 第01章:爬虫到底是什么?原理、流程、合法性、风险全解析(零基础必看)
开发语言·爬虫·python
信誓旦旦的程序猿3 小时前
【量化系统从零构建 #04】存储设计:选型·建库·交易日历
java·人工智能·python·股票数据api·股票数据·股票数据api接口·股票api数据接口
yurenpai(27届找实习中)3 小时前
Java 10 的 var 为什么不能随便用?从订单汇总看懂类型推断与泛型陷阱
java·开发语言·java18
shmily麻瓜小菜鸡3 小时前
JS/TS 易踩坑知识点 — 模块化与工程化类
开发语言·javascript·ecmascript