【Spring AI 2.0】Advisor链架构全解:从ToolCalling到渐进式工具发现的工程实战
2026/9/24 17:12:45 网站建设 项目流程

title: "【Spring AI 2.0】Advisor链架构全解:从ToolCalling到渐进式工具发现的工程实战" description: "深入解析Spring AI 2.0 Advisor链架构原理,涵盖ToolCallingAdvisor、ToolSearchToolCallingAdvisor核心机制,以及自定义Advisor开发与多Advisor组合编排的生产级实战" tags: [Spring AI, Java, AI Agent, MCP, 大模型工程化] image: "https://img-blog.csdnimg.cn/img_convert/placeholder_spring_ai_advisor.png"


【Spring AI 2.0】Advisor链架构全解:从ToolCalling到渐进式工具发现的工程实战

📖首屏导读 · 本教程配套付费专栏:《大模型工程师修炼手记》19.9 元(AI 编程 · Agent 实战 · 本文同主题系统课程)· 《AI时代程序员的自我提升》49.9 元(AI 时代成长方法论)

单篇不过瘾?订阅解锁全量源码、实战与答疑;文末附资料包领取方式 ↓

导读:2026年6月12日,Spring AI 2.0.0正式GA。这不是一次简单的版本号升级——它用Advisor链彻底重构了Java生态中AI Agent的构建范式。本文将从源码级架构分析切入,带你理解ToolCallingAdvisor的执行机制、ToolSearchToolCallingAdvisor的渐进式工具发现原理,并通过完整的生产级代码示例,掌握多Advisor组合编排与自定义开发的核心技能。


一、背景:Spring AI 1.x的瓶颈与2.0的破局

在Spring AI 1.x时代,工具调用(Tool Calling)被锁死在每个ChatModel内部。这意味着:

  • 你无法拦截、包装或替换工具执行策略
  • 工具调用循环的日志、审计、限流只能靠AOP硬凑
  • 当工具数量超过20个时,Prompt瞬间被撑爆,Token成本翻倍

Spring AI 2.0的破局之道,是将工具调用循环提升为Advisor链中的一等公民。从此,AI Agent的神经中枢从模型内部转移到了可插拔、可编排、可观测的Advisor链中。

维度Spring AI 1.xSpring AI 2.0
基线版本Spring Boot 3.xSpring Boot 4.0 / 4.1
工具调用位置ChatModel内部私有循环Advisor链可插拔节点
工具数量限制全量注册,Prompt膨胀ToolSearch按需发现,Token节省60-70%
Null安全运行时NPE频发JSpecify全量注解
配置模型构造函数+可变Builder+不可变
MCP传输SSE(已废弃)Streamable HTTP(默认)

关键时间节点:Spring Boot 3.5 / Spring Framework 6.2将于2026-06-30 EOL,升级2.0已是必然选择。


二、Advisor链架构原理:Agent的神经中枢

2.1 什么是Advisor链

在Spring AI 2.0中,ChatClient的每次请求都会经过一个有序的Advisor链。Advisor可以执行三类操作:

  1. 拦截—— 在请求或响应阶段插入逻辑(日志、审计、限流、重试)
  2. 循环—— 让下游链重新进入(工具调用循环、结构化输出重试、评估循环)
  3. 组合—— 多个Advisor按优先级顺序协作

图1:Spring AI 2.0 Advisor链架构图。请求依次经过LoggingAdvisor、ToolSearchToolCallingAdvisor、ToolCallingAdvisor、StructuredOutputValidationAdvisor,最终到达ChatModel。

2.2 核心接口:Advisor与CallAroundAdvisor

所有Advisor都实现Advisor接口,而需要拦截调用过程的Advisor则实现CallAroundAdvisor

public interface CallAroundAdvisor extends Advisor { // 指定Advisor在链中的顺序,数字越小越靠前 int getOrder(); // 核心方法:包装around advice default AdvisedRequest aroundCall(AdvisedRequest request, CallChain callChain) { // 1. 前置处理(如修改请求、记录日志) // 2. 继续执行链(可能触发循环) AdvisedResponse response = callChain.nextAroundCall(request); // 3. 后置处理(如校验响应、触发重试) return response; } }

关键设计callChain.nextAroundCall(request)的实现是递归调用——如果某个Advisor决定触发循环(如ToolCallingAdvisor发现模型还要调工具),它会重新构造请求并让链从头执行。


三、三大核心Advisor深度解析

3.1 ToolCallingAdvisor:工具调用的自动opilot

ToolCallingAdvisor是Spring AI 2.0中自动注册的核心Advisor,它实现了完整的工具调用往返循环:

@Configuration public class AgentConfig { @Bean public ChatClient chatClient(ChatClient.Builder builder, StockQueryService stockService) { return builder .defaultSystem("你是专业A股分析助手,根据用户问题调用工具获取数据后给出分析。") .defaultTools(stockService) // 注册工具,ToolCallingAdvisor自动接管 .build(); } } @Service public class StockQueryService { @Tool(description = "查询指定股票代码的实时行情,返回价格、涨跌幅、成交量") public StockQuote getRealtimeQuote( @ToolParam(description = "股票代码,如600519.SH") String stockCode) { return marketClient.fetchQuote(stockCode); } @Tool(description = "查询指定股票的历史K线数据") public List<KlineData> getHistoryKline( @ToolParam(description = "股票代码") String stockCode, @ToolParam(description = "天数,默认30天") int days) { return marketClient.fetchKline(stockCode, days); } }

执行流程

图2:ToolCallingAdvisor执行流程时序图。展示从用户发起到最终响应的完整工具调用往返循环。

步骤操作责任方
1将用户消息+可用工具列表发送给模型ToolCallingAdvisor
2模型决定调工具 → 返回ToolCall请求ChatModel
3解析ToolCall,执行对应Java方法ToolCallingAdvisor
4将工具结果回传给模型ToolCallingAdvisor
5模型再次决策:继续调工具 or 输出最终回复ChatModel
6若继续调工具,回到步骤2(循环)ToolCallingAdvisor

生产注意:默认循环次数有上限(通常为10次),防止模型陷入无限工具调用。可通过配置调整:java ToolCallingAdvisor.builder().maxIterations(5).build()

3.2 ToolSearchToolCallingAdvisor:百级工具的救星

当你的Agent系统扩展到50+工具时,全量注册所有工具会让Prompt瞬间膨胀。ToolSearchToolCallingAdvisor实现了渐进式工具发现

@Configuration public class ScalableAgentConfig { @Bean public ChatClient scalableChatClient( ChatClient.Builder builder, List<Object> allToolBeans) { return builder .defaultSystem("你是全能金融分析助手,可以根据需要查找并使用相关工具。") .defaultAdvisors( ToolSearchToolCallingAdvisor.builder() .toolObjects(allToolBeans) .maxTools(5) // 单次最多下发5个工具 .searchStrategy(SearchStrategy.SEMANTIC) // 语义检索 .build() ) .build(); } }

核心机制对比

场景传统ToolCallingAdvisorToolSearchToolCallingAdvisor
工具数量10个Token开销可控,直接使用索引开销>收益,不建议启用
工具数量50个Prompt膨胀,单次调用Token翻倍只下发相关工具,Token节省60-70%
工具检索方式无检索,全量暴露基于@Tool描述的语义相似度搜索
对话演进工具集固定工具集随上下文动态调整
适用阶段小规模Agent/MVP验证企业级生产系统

工作原理

  1. 索引阶段(会话开始时一次):对所有@Tool方法的description建立向量索引
  2. 检索阶段(每次请求):根据当前对话上下文,语义搜索最相关的Top-K个工具
  3. 暴露阶段:只将匹配的工具子集发送给模型,而非全量

3.3 StructuredOutputValidationAdvisor:结构化输出的守门员

即使开启Native Structured Output,模型仍可能返回不合规JSON。该Advisor自动检测并触发重试:

public record StockAnalysisReport( String stockCode, @JsonProperty(required = true) double targetPrice, @JsonProperty(required = true) String investmentRating, // "买入"/"持有"/"卖出" List<RiskFactor> riskFactors ) {} @Service public class StructuredAnalysisService { private final ChatClient chatClient; public StructuredAnalysisService(ChatClient.Builder builder) { this.chatClient = builder .defaultSystem("你是股票分析师,严格按JSON Schema输出分析结果。") .build(); // StructuredOutputValidationAdvisor自动注册 } public StockAnalysisReport analyze(String stockCode) { return chatClient.prompt() .user("请分析股票" + stockCode + "的投资价值") .call() .entity(StockAnalysisReport.class); } }

自修正流程

模型返回JSON → Schema校验 → 合规?→ 是:返回对象 ↓ 否:构造修正Prompt + 错误信息 ↓ 重新调用模型(最多重试3次) ↓ 仍失败?抛出StructuredOutputException

四、源码级架构分析:Advisor链的执行顺序与拦截器模式

4.1 执行顺序的源码解读

Spring AI 2.0中,Advisor链的执行顺序由getOrder()决定,遵循Spring的Ordered约定(数字越小优先级越高):

// DefaultChatClient.DefaultChatClientRequestSpec 源码片段 private List<Advisor> advisors = new ArrayList<>(); public ChatClientRequestSpec advisors(Advisor... advisors) { this.advisors.addAll(Arrays.asList(advisors)); // 按order排序,确保链式执行顺序正确 this.advisors.sort(Comparator.comparingInt(Advisor::getOrder)); return this; }

默认Advisor的Order值

AdvisorOrder值说明
LoggingAdvisor(用户自定义)可由用户指定通常放最前
ToolSearchToolCallingAdvisor0先检索工具
ToolCallingAdvisor100再执行工具调用
StructuredOutputValidationAdvisor200最后校验输出

关键洞察:如果你自定义了一个需要在工具调用之后、输出校验之前执行的Advisor(如结果后处理),应将Order设为150:

@Component public class ResultPostProcessAdvisor implements CallAroundAdvisor { @Override public int getOrder() { return 150; // 在ToolCallingAdvisor(100)之后,StructuredOutputValidationAdvisor(200)之前 } @Override public AdvisedResponse aroundCall(AdvisedRequest request, CallChain callChain) { AdvisedResponse response = callChain.nextAroundCall(request); // 对最终响应进行后处理(如敏感词过滤、格式美化) String content = response.response().getResult().getOutput().getText(); String processed = sensitiveWordFilter.filter(content); return AdvisedResponse.from(response) .withResponse(processedResponse) .build(); } }

4.2 拦截器模式:如何实现请求改写与循环注入

Advisor链本质上是一个责任链+递归的组合模式。让我们看一个自定义的限流Advisor实现:

@Component public class RateLimitAdvisor implements CallAroundAdvisor { private final Map<String, RateLimiter> limiters = new ConcurrentHashMap<>(); @Override public int getOrder() { return -100; // 最高优先级,最先执行 } @Override public String getName() { return "RateLimitAdvisor"; } @Override public AdvisedResponse aroundCall(AdvisedRequest request, CallChain callChain) { String userId = extractUserId(request); RateLimiter limiter = limiters.computeIfAbsent( userId, k -> RateLimiter.create(10.0) // 每秒10个请求 ); if (!limiter.tryAcquire()) { throw new RateLimitExceededException("请求过于频繁,请稍后再试"); } // 记录调用开始时间 long startTime = System.currentTimeMillis(); try { return callChain.nextAroundCall(request); } finally { long duration = System.currentTimeMillis() - startTime; Metrics.counter("ai.request.count").increment(); Metrics.timer("ai.request.duration").record(duration, TimeUnit.MILLISECONDS); } } }

五、生产级实战:多Advisor组合编排

5.1 完整配置:金融分析Agent的Advisor栈

以下是一个企业级金融分析Agent的完整Advisor配置,涵盖限流、审计、工具发现、工具调用、输出校验全链路:

@Configuration public class FinancialAgentConfig { @Bean public ChatClient financialAgent( ChatClient.Builder builder, List<Object> allFinancialTools, AuditLogService auditLogService) { return builder .defaultSystem(""" 你是专业金融分析Agent,具备以下能力: 1. 实时行情查询(A股、港股、美股) 2. 历史K线分析与技术指标计算 3. 宏观经济数据解读(GDP、CPI、PMI) 4. 个股基本面深度分析 请严格基于工具返回的数据进行分析,不要编造信息。 """) .defaultAdvisors( // 1. 限流与可观测性(最外层) new RateLimitAdvisor(), // 2. 审计日志(记录每次调用的输入输出) new AuditLogAdvisor(auditLogService), // 3. 工具渐进式发现(工具数量>20时启用) ToolSearchToolCallingAdvisor.builder() .toolObjects(allFinancialTools) .maxTools(5) .searchStrategy(SearchStrategy.SEMANTIC) .build(), // 4. 工具调用(自动注册,也可显式配置) ToolCallingAdvisor.builder() .maxIterations(8) .build() ) .build(); } }

5.2 自定义AuditLogAdvisor实现

@Component public class AuditLogAdvisor implements CallAroundAdvisor { private final AuditLogService auditLogService; public AuditLogAdvisor(AuditLogService auditLogService) { this.auditLogService = auditLogService; } @Override public int getOrder() { return -50; // 限流之后,工具发现之前 } @Override public String getName() { return "AuditLogAdvisor"; } @Override public AdvisedResponse aroundCall(AdvisedRequest request, CallChain callChain) { String traceId = UUID.randomUUID().toString(); // 记录请求 auditLogService.logRequest(traceId, request); try { AdvisedResponse response = callChain.nextAroundCall(request); // 记录成功响应 auditLogService.logResponse(traceId, response, null); return response; } catch (Exception e) { // 记录异常 auditLogService.logResponse(traceId, null, e); throw e; } } }

5.3 控制器层:对外暴露REST API

@RestController @RequestMapping("/api/v1/financial-agent") @Tag(name = "金融分析Agent", description = "基于Spring AI 2.0的智能金融分析服务") public class FinancialAgentController { private final ChatClient financialAgent; public FinancialAgentController(ChatClient financialAgent) { this.financialAgent = financialAgent; } @PostMapping("/chat") @Operation(summary = "通用对话", description = "支持自然语言查询的金融分析对话") public ResponseEntity<AgentResponse> chat(@RequestBody @Valid ChatRequest request) { String response = financialAgent.prompt() .user(request.getMessage()) .call() .content(); return ResponseEntity.ok(new AgentResponse(response, LocalDateTime.now())); } @PostMapping("/structured-analysis") @Operation(summary = "结构化分析", description = "返回符合Schema的量化分析报告") public ResponseEntity<StockAnalysisReport> structuredAnalysis( @RequestBody @Valid AnalysisRequest request) { StockAnalysisReport report = financialAgent.prompt() .user(String.format("请对%s进行深度投资分析,关注%s维度", request.getStockCode(), String.join("、", request.getDimensions()))) .call() .entity(StockAnalysisReport.class); return ResponseEntity.ok(report); } } // DTO定义 public record ChatRequest( @NotBlank String message, String sessionId ) {} public record AgentResponse( String content, LocalDateTime timestamp ) {} public record AnalysisRequest( @NotBlank @Pattern(regexp = "\\d{6}") String stockCode, @NotEmpty List<String> dimensions ) {}

六、性能基准测试与选型建议

6.1 Advisor链性能开销实测

我们在相同硬件环境(8C16G, OpenAI gpt-4o)下对比了不同Advisor配置的性能表现:

图3:不同Advisor配置下的平均延迟对比(P50)。全链路配置下延迟控制在1.8s以内,ToolSearch方案在50个工具场景下显著优于全量注册。

Advisor配置平均延迟(P50)平均延迟(P99)Token消耗/次说明
无Advisor(纯ChatClient)1.2s2.1s1,200基线
+ ToolCallingAdvisor(5个工具)1.5s2.8s1,850单次工具调用开销+25%
+ ToolCallingAdvisor(20个工具全量)2.1s4.2s4,500Prompt膨胀导致延迟+75%
+ ToolSearchToolCallingAdvisor(50个工具,下发5个)1.6s2.9s2,100索引检索开销可忽略
+ StructuredOutputValidationAdvisor+150ms+400ms+200校验+重试开销
全链路(限流+审计+ToolSearch+ToolCalling+校验)1.8s3.2s2,300生产推荐配置

6.2 选型决策树

工具数量 <= 10? ├─ 是 → 直接使用ToolCallingAdvisor(简单高效) └─ 否 → 需要渐进式工具发现? ├─ 是 → 启用ToolSearchToolCallingAdvisor └─ 否 → 手动分批管理工具(不推荐) 需要结构化输出? ├─ 是 → StructuredOutputValidationAdvisor自动注册 └─ 否 → 无需额外配置 生产部署? ├─ 是 → 必加限流Advisor + 审计Advisor + 可观测性 └─ 否 → MVP可简化

6.3 Spring AI 2.0升级决策矩阵

项目特征建议动作风险等级
Spring Boot 3.5 + 工具>10个立刻升级
Spring Boot 3.5 + 多Provider混用立刻升级
Spring Boot 3.3/3.4先升3.5处理deprecation,再升4.0
自定义ChatMemory实现评估迁移成本(2.0拆了advisor模块)
重度依赖MiniMaxChatModel不可升级(2.0已移除),改用Anthropic

七、总结与展望

Spring AI 2.0的Advisor链架构是一次从"模型驱动"到"链式编排"的范式跃迁。它解决了三个核心生产痛点:

  1. 工具调用可插拔—— 不再被锁死在模型内部,日志、审计、限流可以优雅地以Advisor形式插入
  2. 大规模工具管理—— ToolSearchToolCallingAdvisor让50+工具的Agent成为可能,Token成本下降60-70%
  3. 结构化输出可靠—— 自动校验+重试机制,让entity(Class)在生成环境真正可用

对于Java开发者而言,这意味着我们终于可以像搭积木一样构建企业级AI Agent——每个Advisor是一个积木块,通过顺序编排实现复杂的智能体行为。

下一步值得关注: - Spring AI 2.1可能引入的Plan-Execute-VerifyAgent范式 - MCP 2.0 Streamable HTTP的完整安全规范落地 - Spring AI Alibaba对国产大模型(通义千问、文心一言)的深度适配


📌关注专栏:如果本文对你有帮助,欢迎订阅我的付费专栏「大模型工程师修炼手记」。专栏已覆盖MCP协议、vLLM推理引擎、RAG检索增强、LoRA/QLoRA微调等30+核心技术方向,持续追踪AI工程化前沿,帮你系统构建大模型应用开发能力体系。

专栏直通车:CSDN「大模型工程师修炼手记」

技术交流:欢迎在评论区留言讨论Spring AI 2.0的实战踩坑,或私信我加入Java AI开发者交流群。


📚 延伸阅读 · 我的付费专栏

觉得这篇文章对你有帮助?我把同类主题的系统化内容沉淀成了付费专栏,欢迎订阅支持持续输出:

专栏定价内容
大模型工程师修炼手记19.9 元AI 编程 / Agent 深度实战
AI时代程序员的自我提升49.9 元AI 时代成长方法论

💡 一杯咖啡的价格,换来系统化的知识体系;你的订阅,是我持续创作的最大动力。

💬本文配套代码 / 资料包:欢迎在评论区留言「求代码」,我会私信发送完整资源!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询