Spring AI的函数调用(Function Calling),具体怎么实现?


Spring AI 的 函数调用(Function Calling) 功能允许大语言模型(LLM)在生成回答时触发预定义的外部函数,从而实现动态数据获取或业务逻辑操作(如查询数据库、调用 API 等)。以下是其核心机制和实现方式:


在这里插入图片描述

1. 函数调用的核心流程

  1. 定义函数:声明可供模型调用的函数(名称、描述、参数结构)。
  2. 模型交互:将函数信息与用户输入一起发送给模型,模型决定是否需要调用函数。
  3. 执行函数:解析模型的函数调用请求,执行对应的业务逻辑。
  4. 返回结果:将函数执行结果返回给模型,生成最终回答。

2. Spring AI 中的实现步骤

2.1 定义函数接口

使用 @Function 注解标记方法,描述函数的作用和参数:

public class WeatherService {
    
    @Function(
        name = "getCurrentWeather", 
        description = "获取指定城市的当前天气",
        inputType = @Function.Parameter(
            type = "object",
            properties = {
                @Function.ParameterProperty(name = "location", type = "string", description = "城市名称")
            }
        )
    )
    public String getWeather(@RequestParam String location) {
        // 调用真实天气 API(示例)
        return "{\"location\": \"" + location + "\", \"temperature\": 25, \"condition\": \"晴\"}";
    }
}

2.2 注册函数到模型

在 Spring 配置中将函数注册到 ChatClient

@Configuration
public class FunctionConfig {
    
    @Bean
    public FunctionCallback weatherFunctionCallback(WeatherService weatherService) {
        return new FunctionCallbackWrapper<>(
            "getCurrentWeather", 
            "获取天气信息", 
            weatherService::getWeather, 
            new WeatherRequestConverter()  // 参数解析器(将模型请求转为Java对象)
        );
    }

    @Bean
    public ChatClient chatClient(OpenAiChatClient chatClient, List<FunctionCallback> functionCallbacks) {
        // 将函数回调注册到 ChatClient
        chatClient.setFunctionCallbacks(functionCallbacks);
        return chatClient;
    }
}

2.3 触发函数调用

在对话请求中启用函数调用:

@RestController
public class ChatController {
    
    @Autowired
    private ChatClient chatClient;

    @PostMapping("/chat")
    public String chat(@RequestBody String userMessage) {
        // 构造包含函数调用选项的请求
        ChatOptions options = OpenAiChatOptions.builder()
            .withFunctionCallbacks(List.of("getCurrentWeather")) // 允许调用的函数
            .build();

        // 发送请求
        ChatResponse response = chatClient.call(
            new UserMessage(userMessage, options)
        );

        return response.getResult().getOutput().getContent();
    }
}

3. 处理函数调用结果

模型可能返回两种结果:

  1. 直接回答:无需调用函数时,直接生成文本。
  2. 函数调用请求:模型返回函数名称和参数,需手动执行并回传结果。
手动处理函数调用的示例
ChatResponse response = chatClient.call(userMessage);

if (response.getMetadata().containsKey("function_call")) {
    // 解析函数调用请求
    FunctionCallRequest functionCall = parseFunctionCall(response.getMetadata());
    
    // 执行函数
    Object result = executeFunction(functionCall.getName(), functionCall.getArguments());
    
    // 将结果回传给模型生成最终回答
    ChatResponse finalResponse = chatClient.call(
        new UserMessage(
            "函数调用结果:" + result, 
            OpenAiChatOptions.builder().build()
        )
    );
    return finalResponse.getResult().getContent();
}

4. 核心优势

  • 动态数据整合:模型可实时获取外部数据(如天气、订单状态)。
  • 业务逻辑触发:通过自然语言触发后端操作(如发送邮件、更新数据库)。
  • 精准性提升:结合函数调用与 RAG,生成更准确、实时的回答。

5. 典型应用场景

  • 客服机器人:查询用户订单、物流信息。
  • 智能助手:控制智能家居设备(“打开客厅的灯”)。
  • 数据分析:根据用户问题动态生成图表(调用图表生成服务)。

6. 注意事项

  • 模型支持:确保使用的模型支持函数调用(如 GPT-3.5-turbo、GPT-4)。
  • 参数验证:严格校验模型传入的参数,避免注入攻击。
  • 权限控制:限制敏感函数的访问权限(如仅允许管理员触发删除操作)。

7. 完整示例:天气查询

用户输入"北京现在天气怎么样?"

流程分解

  1. 模型识别需要调用 getCurrentWeather,参数 location: 北京
  2. Spring AI 触发 WeatherService.getWeather("北京")
  3. 函数返回 JSON 数据:{"temperature": 25, "condition": "晴"}
  4. 模型将结果转换为自然语言:"北京当前天气晴朗,气温 25 摄氏度。"

### 如何在Spring框架中调用AI函数 为了在Spring框架内集成并调用AI功能,开发者可以利用`spring-ai`模块来简化这一过程。通过设置特定属性如API密钥以及模型选项,应用程序能够轻松访问外部的人工智能服务。 配置文件中的相关设定如下所示: ```properties spring.ai.openai.api-key=YOUR_API_KEY spring.ai.openai.embedding.options.model=text-embedding-ada-002[^1] ``` 上述配置允许应用连接到OpenAI的服务,并指定使用名为`text-embedding-ada-002`的预训练模型来进行文本嵌入操作。这使得开发人员可以在项目里实现自然语言处理的任务,比如语义相似度计算或是基于内容的推荐系统构建等高级特性。 对于希望进一步增强解释性的AI交互体验的应用程序而言,研究也提供了有价值的见解。例如,在计算机视觉领域的工作展示了如何让机器学习模型不仅给出预测结果还能提供背后的原因说明,从而提高了系统的透明性和可信度[^2]。 当涉及到具体编码实践时,假设已经完成了必要的依赖引入和环境搭建工作,则可以通过注入相应的客户端组件实例化对象并与之互动的方式完成对AI能力的调用。下面是一个简单的Java代码片段展示怎样创建一个REST控制器方法用于触发AI任务执行: ```java @RestController @RequestMapping("/api/ai") public class AiController { private final OpenAIClient openAiClient; @Autowired public AiController(OpenAIClient openAiClient) { this.openAiClient = openAiClient; } @PostMapping("/embeddings") ResponseEntity<String> getEmbedding(@RequestBody String text){ EmbeddingRequest request = new EmbeddingRequest(text); EmbeddingResponse response = openAiClient.createEmbedding(request); return ResponseEntity.ok(response.toString()); } } ``` 这段代码定义了一个接受POST请求的端点 `/api/ai/embeddings` ,它接收一段文字作为输入参数并通过`openAiClient`发送给远程服务器获取对应的向量表示形式作为响应返回给前端使用者。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值