Bootstrap

SpringAI 搭建智能体(一):让模型执行客户端操作

在现代 AI 应用中,仅仅通过模型生成文本并不能满足复杂场景的需求。许多情况下,模型需要调用客户端的工具或函数来完成某些特定任务,例如查询数据库、访问第三方 API、执行系统命令等。Spring AI 提供了工具调用功能,使开发者可以将客户端操作集成到 AI 模型中,让模型通过工具调用来扩展其功能。

本文将介绍如何使用 Spring AI 实现工具调用功能,允许模型请求并执行客户端工具或函数,并结合实际应用场景进行演示。
有了本篇的基础,下一篇中,将会介绍智能体概念,及 SpringAI 搭建智能体实战。


1. 工具调用的原理与流程

工具调用的核心思想是将一组预定义的客户端函数暴露给 AI 模型,允许模型根据上下文请求执行这些函数。整个流程包括以下步骤:

  1. 注册工具或函数:开发者在应用中定义一组可供调用的工具或函数。
  2. AI 模型请求工具调用:模型在生成输出时,通过特定的格式(如 JSON)请求调用某个工具。
  3. 执行工具并返回结果:工具层解析模型的请求,执行相应的函数,并将结果返回给模型继续处理。

2. Spring AI 工具调用的实现步骤

2.1 定义工具接口

Spring AI 允许我们将工具注册为 Spring 的 Bean。首先,我们需要定义一个通用的工具接口。

public interface Tool {
    String getName(); // 返回工具的名称
    String execute(String input); // 执行工具逻辑
}
2.2 实现具体工具

根据业务需求实现不同的工具。例如,以下是两个工具:

  1. 查询天气的工具;
  2. 查询数据库的工具。
查询天气工具
import org.springframework.stereotype.Component;

@Component
public class WeatherTool implements Tool {

    @Override
    public String getName() {
        return "weather";
    }

    @Override
    public String execute(String input) {
        // 模拟调用第三方天气 API
        return "The weather in " + input + " is sunny and 25°C.";
    }
}
数据库查询工具
import org.springframework.stereotype.Component;

@Component
public class DatabaseTool implements Tool {

    @Override
    public String getName() {
        return "database";
    }

    @Override
    public String execute(String input) {
        // 模拟从数据库中查询数据
        return "Query result for input [" + input + "]: {id: 1, name: 'Spring AI'}";
    }
}
2.3 工具管理器

为了方便管理多个工具,可以创建一个工具管理器来动态解析和执行工具调用。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
public class ToolManager {

    private final Map<String, Tool> tools;

    @Autowired
    public ToolManager(List<Tool> toolList) {
        this.tools = toolList.stream()
                .collect(Collectors.toMap(Tool::getName, tool -> tool));
    }

    public String executeTool(String toolName, String input) {
        Tool tool = tools.get(toolName);
        if (tool == null) {
            throw new IllegalArgumentException("Tool not found: " + toolName);
        }
        return tool.execute(input);
    }
}
2.4 集成到 Spring AI 中

在模型的生成逻辑中,解析工具调用请求并执行对应工具的逻辑。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class AiService {

    private final ToolManager toolManager;

    @Autowired
    public AiService(ToolManager toolManager) {
        this.toolManager = toolManager;
    }

    public String processRequest(String prompt) {
        // 简单解析工具调用格式
        if (prompt.startsWith("tool:")) {
            String[] parts = prompt.split(":", 3);
            String toolName = parts[1];
            String toolInput = parts[2];
            return toolManager.executeTool(toolName, toolInput);
        }
        // 默认返回提示信息
        return "Unknown request format.";
    }
}

3. 实际应用场景

场景 1:智能客服系统

在智能客服系统中,客户提出的问题可能需要调用特定工具来获取答案。例如:

  • 用户询问天气:What is the weather in New York?
  • 系统解析后调用 WeatherTool 并返回结果。
示例代码
@RestController
public class AiController {

    private final AiService aiService;

    @Autowired
    public AiController(AiService aiService) {
        this.aiService = aiService;
    }

    @GetMapping("/ai-request")
    public String handleRequest(@RequestParam String prompt) {
        return aiService.processRequest(prompt);
    }
}

请求示例:

GET /ai-request?prompt=tool:weather:New York

返回结果:

The weather in New York is sunny and 25°C.

场景 2:自动化数据处理

在数据处理平台中,用户可能需要执行某些复杂的查询操作。例如:

  • 用户提交数据查询请求:Query the database for customer 12345.
  • 系统通过工具层调用数据库查询逻辑,并返回结果。
请求示例
GET /ai-request?prompt=tool:database:customer 12345

返回结果:

Query result for input [customer 12345]: {id: 12345, name: 'John Doe', balance: 1000.0}

场景 3:多工具联合调用

在某些场景下,模型可能需要同时调用多个工具。例如:

  1. 获取天气;
  2. 查询与天气相关的数据库记录。

可以通过工具层管理多个工具的调用顺序,实现工具的联合调用。

public String processComplexRequest(String input) {
    String weatherInfo = toolManager.executeTool("weather", input);
    String dbInfo = toolManager.executeTool("database", "weather:" + input);
    return weatherInfo + "\n" + dbInfo;
}

4. 总结

通过 Spring AI 的工具调用功能,我们可以让模型在生成内容的同时执行客户端工具或函数,极大地增强了系统的灵活性和扩展性。无论是智能客服、自动化数据处理,还是更复杂的多工具联合调用,Spring AI 都能够通过其强大的依赖注入和工具管理机制简化实现过程。

在构建 AI 应用时,工具调用为开发者提供了一种高效且模块化的方式来扩展模型的能力,为用户提供更加丰富的功能和体验。

;