Spring AI工具调用深度解析:实现AI实时信息获取

【免费下载链接】spring-ai An Application Framework for AI Engineering 【免费下载链接】spring-ai 项目地址: https://gitcode.com/GitHub_Trending/spr/spring-ai

引言:AI应用的数据实时性痛点与解决方案

你是否还在为AI应用无法获取实时数据而困扰?当用户询问"今天上海的天气如何"或"最新的股票行情"时,传统大模型只能依赖训练数据给出过时答案。Spring AI的工具调用(Tool Calling)能力彻底解决了这一痛点,通过将AI模型与外部API无缝集成,实现实时数据获取与处理。本文将系统拆解Spring AI工具调用的核心机制,从注解定义到执行流程,从异常处理到性能优化,带你掌握企业级AI应用的实时数据接入方案。

读完本文你将获得:

  • 工具调用的完整技术架构与核心组件解析
  • 3种工具注册方式的实战代码(注解驱动/函数注册/配置类)
  • 实时天气查询/股票数据获取的端到端实现
  • 工具调用的性能调优与可观测性配置指南
  • 复杂场景下的多工具协同与流式调用方案

一、Spring AI工具调用核心架构

1.1 技术架构概览

Spring AI工具调用采用分层架构设计,主要包含四个核心层次:

mermaid

核心组件职责:

  • 注解层:通过@Tool@ToolParam定义工具元数据
  • 管理层ToolCallingManager协调工具解析、调用与结果处理
  • 执行层:处理实际工具调用,包括参数绑定、执行与结果转换

1.2 核心API解析

1.2.1 @Tool注解

@Tool注解是标记工具方法的核心注解,定义于spring-ai-model模块:

@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Tool {
    String name() default "";                  // 工具名称,默认使用方法名
    String description() default "";           // 工具描述,用于模型判断是否调用
    boolean returnDirect() default false;      // 是否直接返回结果给用户
    Class<? extends ToolCallResultConverter> resultConverter() default DefaultToolCallResultConverter.class;
}

最佳实践

  • 名称使用小写蛇形命名(如get_current_weather),避免特殊字符
  • 描述需包含工具用途、参数含义和返回值格式,帮助模型正确调用
  • 复杂返回结果需自定义ToolCallResultConverter
1.2.2 ToolCallingManager接口

ToolCallingManager是工具调用的协调中心,定义了两大核心方法:

public interface ToolCallingManager {
    // 解析工具定义
    List<ToolDefinition> resolveToolDefinitions(ToolCallingChatOptions chatOptions);
    // 执行工具调用并返回结果
    ToolExecutionResult executeToolCalls(Prompt prompt, ChatResponse chatResponse);
}

默认实现DefaultToolCallingManager处理:

  • 工具回调解析与注册
  • 工具调用的参数绑定
  • 执行过程的观测与监控
  • 异常处理与结果转换

二、工具定义与注册实战

2.1 注解驱动的工具定义

以天气查询工具为例,使用@Tool@ToolParam定义工具:

@Service
public class WeatherService {

    @Tool(
        name = "get_current_weather",
        description = "获取指定城市的当前天气信息,返回温度、湿度等数据",
        returnDirect = false
    )
    public WeatherResponse getCurrentWeather(
        @ToolParam(description = "城市名称,格式为'城市, 省份',如'上海, 华东'", required = true) String location,
        @ToolParam(description = "温度单位,C表示摄氏度,F表示华氏度", required = true) String unit
    ) {
        // 调用外部天气API获取数据
        return weatherApiClient.fetchWeather(location, unit);
    }
    
    public record WeatherResponse(
        double temperature, 
        int humidity, 
        String condition, 
        String unit
    ) {}
}

2.2 函数式工具注册

对于第三方库或无源码的工具类,可通过FunctionToolCallback注册:

@Configuration
public class ToolConfig {

    @Bean
    public FunctionToolCallback stockToolCallback() {
        return FunctionToolCallback.builder("get_stock_price", new StockService()::getPrice)
            .description("获取指定股票代码的当前价格")
            .inputType(StockRequest.class)
            .outputType(StockResponse.class)
            .build();
    }
    
    public record StockRequest(
        @JsonProperty(required = true) String symbol,
        @JsonProperty(required = true) String exchange
    ) {}
    
    public record StockResponse(
        String symbol, 
        double price, 
        LocalDateTime timestamp
    ) {}
}

2.3 配置文件驱动注册

application.yml中配置工具:

spring:
  ai:
    tools:
      callbacks:
        - name: "get_news_headlines"
          description: "获取指定类别的新闻头条"
          function-bean: newsService
          method: "getHeadlines"
          input-type: com.example.NewsRequest
          output-type: com.example.NewsResponse

三、工具调用执行流程深度解析

3.1 端到端执行序列

mermaid

3.2 核心执行步骤解析

步骤1:工具定义解析

DefaultToolCallingManager通过resolveToolDefinitions方法解析工具:

// 简化代码
public List<ToolDefinition> resolveToolDefinitions(ToolCallingChatOptions options) {
    List<ToolCallback> callbacks = new ArrayList<>(options.getToolCallbacks());
    
    // 解析工具名称并注册回调
    for (String toolName : options.getToolNames()) {
        ToolCallback callback = toolCallbackResolver.resolve(toolName);
        callbacks.add(callback);
    }
    
    return callbacks.stream()
        .map(ToolCallback::getToolDefinition)
        .collect(Collectors.toList());
}
步骤2:工具调用执行

executeToolCalls方法处理实际调用:

public ToolExecutionResult executeToolCalls(Prompt prompt, ChatResponse response) {
    // 提取模型返回的工具调用请求
    List<ToolCall> toolCalls = response.getResult().getOutput().getToolCalls();
    
    List<ToolResponse> responses = new ArrayList<>();
    for (ToolCall call : toolCalls) {
        // 查找对应的工具回调
        ToolCallback callback = findToolCallback(call.name());
        
        // 执行工具调用
        String result = callback.call(call.arguments(), buildToolContext(prompt));
        
        // 收集结果
        responses.add(new ToolResponse(call.id(), call.name(), result));
    }
    
    return ToolExecutionResult.builder()
        .conversationHistory(buildConversationHistory(prompt, responses))
        .returnDirect(shouldReturnDirect(responses))
        .build();
}

四、实时信息获取完整案例

4.1 项目配置

Maven依赖

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-spring-boot-starter-model-openai</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-spring-boot-starter-vector-store-redis</artifactId>
</dependency>

应用配置

spring:
  ai:
    openai:
      api-key: ${OPENAI_API_KEY}
      chat:
        options:
          model: gpt-4o
          temperature: 0.7
          tools:
            - name: get_current_weather
            - name: get_stock_price

4.2 多工具协同调用

实现一个能够根据用户问题自动选择工具的AI助手:

@RestController
@RequestMapping("/ai/assistant")
public class AiAssistantController {

    private final ChatModel chatModel;
    
    public AiAssistantController(ChatModel chatModel) {
        this.chatModel = chatModel;
    }
    
    @PostMapping("/query")
    public String query(@RequestBody String question) {
        // 1. 创建系统提示,定义工具使用规则
        SystemMessage systemMessage = new SystemMessage("""
            你是一个智能助手,可以使用工具获取实时信息。
            当需要天气信息时调用get_current_weather工具,
            需要股票数据时调用get_stock_price工具。
            工具返回结果后,整理成自然语言回答用户。
        """);
        
        // 2. 创建用户消息
        UserMessage userMessage = new UserMessage(question);
        
        // 3. 创建工具调用选项
        var options = OpenAiChatOptions.builder()
            .toolChoice("auto") // 让模型自动决定是否调用工具
            .build();
        
        // 4. 发送请求并处理响应
        Prompt prompt = new Prompt(List.of(systemMessage, userMessage), options);
        ChatResponse response = chatModel.call(prompt);
        
        // 5. 处理工具调用结果
        if (response.getResult().getOutput().getToolCalls() != null) {
            return processToolCalls(prompt, response);
        } else {
            return response.getResult().getOutput().getText();
        }
    }
    
    private String processToolCalls(Prompt prompt, ChatResponse response) {
        // 执行工具调用并获取结果
        ToolExecutionResult result = toolCallingManager.executeToolCalls(prompt, response);
        
        // 将工具结果送回模型生成最终回答
        Prompt newPrompt = new Prompt(result.conversationHistory(), prompt.getOptions());
        return chatModel.call(newPrompt).getResult().getOutput().getText();
    }
}

4.3 测试与验证

使用Postman测试:

POST /ai/assistant/query
Content-Type: application/json

{
  "question": "上海现在天气怎么样?另外帮我查一下上证指数的实时行情。"
}

预期响应:

上海当前天气:温度22°C,湿度65%,多云转晴。
上证指数当前点数:3285.42,较昨日上涨0.83%,成交量2.1亿手。

五、高级特性与性能优化

5.1 工具调用的异常处理

配置全局异常处理器:

@Configuration
public class ToolExceptionConfig {

    @Bean
    public ToolExecutionExceptionProcessor toolExceptionProcessor() {
        return DefaultToolExecutionExceptionProcessor.builder()
            .retryPolicy(retryPolicy())
            .fallbackHandler((call, ex) -> {
                log.error("工具调用失败: {}", call.name(), ex);
                return new ToolResponse(call.id(), call.name(), 
                    "{\"error\":\"服务暂时不可用,请稍后重试\"}");
            })
            .build();
    }
    
    private RetryPolicy retryPolicy() {
        return RetryPolicy.builder()
            .maxAttempts(3)
            .backoff(Backoff.exponential(1000))
            .retryOn(IOException.class, TimeoutException.class)
            .build();
    }
}

5.2 流式工具调用

实现实时响应的流式工具调用:

@GetMapping(value = "/stream/query", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamQuery(@RequestParam String question) {
    // 创建流式请求
    Flux<ChatResponse> responseFlux = chatModel.stream(new Prompt(
        List.of(new UserMessage(question)),
        OpenAiChatOptions.builder()
            .stream(true)
            .toolCallbacks(List.of(weatherToolCallback, stockToolCallback))
            .build()
    ));
    
    // 处理流式响应
    return responseFlux.flatMap(response -> {
        Generation generation = response.getResult();
        if (generation.getOutput().getToolCalls() != null) {
            // 处理工具调用
            return Flux.just("正在查询实时数据...\n");
        } else {
            // 返回生成的文本
            return Flux.just(generation.getOutput().getText());
        }
    });
}

5.3 性能优化策略

优化策略 实现方式 性能提升
工具调用缓存 使用Caffeine缓存频繁调用结果 降低80%重复API调用
异步工具执行 使用CompletableFuture并行调用多工具 减少60%响应时间
批处理工具调用 合并多个同类工具请求 降低40%网络开销
工具结果压缩 对大结果进行JSON压缩 减少50%传输数据量

六、可观测性与监控

6.1 工具调用指标监控

Spring AI自动集成Micrometer,提供工具调用指标:

@Configuration
public class MetricsConfig {

    @Bean
    MeterRegistryCustomizer<MeterRegistry> toolMetrics() {
        return registry -> registry.config()
            .meterFilter(MeterFilter.deny(id -> 
                id.getName().startsWith("spring.ai.tool") && 
                id.getTag("tool.name") == null
            ));
    }
}

关键监控指标:

  • spring.ai.tool.calls.count:工具调用次数
  • spring.ai.tool.calls.duration:工具调用耗时
  • spring.ai.tool.errors.count:工具调用错误数

6.2 分布式追踪

集成Sleuth和Zipkin实现工具调用的分布式追踪:

spring:
  sleuth:
    sampler:
      probability: 1.0
  zipkin:
    base-url: http://zipkin:9411

七、总结与未来展望

Spring AI工具调用框架通过标准化的注解、灵活的注册方式和强大的执行管理,为AI应用接入实时数据提供了完整解决方案。本文从架构设计、代码实现到性能优化,全面解析了工具调用的核心技术,并通过实战案例展示了多工具协同的应用场景。

随着AI技术的发展,未来Spring AI可能会引入更多高级特性:

  • 工具调用的智能路由与负载均衡
  • 基于RAG的工具推荐系统
  • 多模态工具调用能力
  • 工具调用的安全沙箱机制

掌握Spring AI工具调用,将帮助你构建更智能、更实用的企业级AI应用,让AI真正具备实时获取和处理信息的能力。

收藏本文,关注Spring AI最新动态,持续探索AI应用开发的无限可能!


下期预告:《Spring AI RAG技术全景:构建企业知识库问答系统》

【免费下载链接】spring-ai An Application Framework for AI Engineering 【免费下载链接】spring-ai 项目地址: https://gitcode.com/GitHub_Trending/spr/spring-ai

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐