Java 和 Spring AI 中使用最新 Mistral AI API 的函数调用

工程 | Christian Tzolov | 2024 年 3 月 6 日 | ...

更新:截至 2024 年 3 月 13 日,Mistral AI 已在其大型模型中集成了对并行函数调用的支持,此功能在此博客最初发布时不存在。

Mistral AI 是开源大型语言模型的领先开发商,发布了在其尖端模型中添加**函数调用**支持的消息。

**函数调用**是一项功能,它促进了 LLM 与外部工具和 API 的集成。它使语言模型能够请求执行客户端函数,从而使其能够访问必要的运行时信息或动态执行任务。

在这里,我将讨论如何将 Mistral AI 的新函数调用功能与 Java 以及特别是与Spring AI一起使用。

如果您不想深入了解低级 Java 客户端的详细信息,并希望充分利用您的投资,可以跳过下一段,直接跳到使用 Spring AI 进行函数调用

1. Java 中的函数调用

如果您想使用 Java 和Spring AI测试最新的 Mistral AI 功能,您会发现 Mistral 不支持 Java 客户端,并且尚未发布函数调用 API。

因此,我不得不求助于探索它们的 JavaScript/Python 客户端来弄清楚。下面是一个类图,说明了 API 的各个组件及其相互连接。

Mistral AI Class Diagram 1

熟悉 OpenAI API 的人会注意到 Mistral AI 的新 API 几乎相同,只有几个细微的差别。

我扩展了由 Ricken Bazolo 最初创建的MistralAiApi Java 客户端,以包含缺少的函数调用功能。更新后的客户端运行良好,如付款状态演示所示。

由于我的重点是 Spring AI,因此我不会在这里深入探讨客户端的技术细节。但是,如果您有兴趣,可以探索我包含在下面的演示代码和备忘单图。

Mistral AI Function Calling Flow 3

需要注意的是,模型不会直接调用函数;相反,它会为您生成 JSON,以便您在代码中调用函数并将结果返回给模型以继续对话。

2. 使用 Spring AI 进行函数调用

Spring AI 通过允许您定义一个返回用户定义的java.util.Function@Bean来简化函数调用。它会自动推断函数的输入类型并相应地生成 JSON(或 OpenAPI)模式。此外,Spring AI 通过使用必要的适配器代码包装您的 POJO(函数)来处理与 AI 模型的复杂交互,从而无需您编写重复的代码。

此外,Spring AI 简化了代码的可移植性到支持函数调用的其他 AI 模型,并允许开发高效的原生(GraalVM)可执行文件。

2.1 它如何工作?

假设我们希望 AI 模型以它没有的信息进行响应。例如,您最近的支付交易的状态,如 Mistral AI 的此教程所示。

让我们使用 Spring AI 重新实现该教程。

使用Initializr引导一个新的 Boot 应用程序,并将 MistralAI boot starter 依赖项添加到 POM 中

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-mistral-ai-spring-boot-starter</artifactId>
    <version>0.8.1</version>
</dependency>

使用application.properties配置它

spring.ai.mistralai.api-key=${MISTRAL_AI_API_KEY}
spring.ai.mistralai.chat.options.model=mistral-small-latest

这将为您提供完全功能的MistralAiChatClient

@Autowired
MistralAiChatClient chatClient;

接下来,假设我们有一个包含支付交易的数据集

public record Transaction(String transactionId) {}

public record Status(String status) {}

public static final Map<Transaction, Status> PAYMENT_DATA = Map.of(
            new Transaction("T1001"), new Status("Paid"),
            new Transaction("T1002"), new Status("Unpaid"),
            new Transaction("T1003"), new Status("Paid"),
            new Transaction("T1004"), new Status("Paid"),
            new Transaction("T1005"), new Status("Pending"));

用户可以询问有关此数据集的问题,并使用函数调用来回答它们。例如,让我们考虑一个根据交易检索付款状态的函数

@Bean
@Description("Get payment status of a transaction")
public Function<Transaction, Status> retrievePaymentStatus() {
        return (transaction) -> new Status(PAYMENT_DATA.get(transaction).status());
}

它使用一个简单的java.util.Function,该函数将Transaction作为输入并返回该交易的Status。该函数注册为@Bean,并使用@Description注释定义函数描述。Spring AI 极大地简化了您需要编写的支持函数调用的代码。它为您代理函数调用对话。您还可以参考提示中的多个函数 bean 名称。

var options = MistralAiChatOptions.builder()
   .withFunction("retrievePaymentStatus")
   .build();

ChatResponse paymentStatusResponse = chatClient.call(
      new Prompt("What's the status of my transaction with id T1005?",  options);

我们在提示中制定问题,包括提示选项中的相关函数名称。函数名称应与 Bean 名称匹配。

提示:为了避免在每次请求的提示选项中重复指定函数名称,您可以考虑在application.properties文件中对其进行一次配置,例如:spring.ai.mistralai.chat.options.functions=retrievePaymentStatus。这种方法确保该函数始终启用并可用于所有提示问题。但是,需要注意的是,此方法可能会导致为不需要该函数的请求传输不必要的上下文标记。

就是这样。Spring AI 将代表您促进函数调用的对话。您可以打印响应内容

System.out.println(paymentStatusResponse.getResult().getOutput().getContent());

并期望如下结果

The status of your transaction T1005 is "Pending".

提示:查看**MistralAi-AOT-Demo**,这是一个简单的 Spring Boot 应用程序,展示了 Mistral AI 与 Spring AI 的集成。它包含各种功能,例如聊天完成、流式聊天完成、嵌入和函数调用。此外,还包含了原生构建的说明。

在参考文档中探索有关 Spring AI 与 Mistral AI 集成的更多详细信息

2.2 动态提示选项

使用**MistralAiChatOptions**,我们可以自定义每个提示请求的默认设置。例如,我们可以根据需要将模型切换到 LARGE 并调整特定请求的温度。

ChatResponse paymentStatusResponse = chatClient
   .call(new Prompt("What's the status of my transaction with id T1005?",
            MistralAiChatOptions.builder()
               .withModel(MistralAiApi.ChatModel.LARGE.getValue())
               .withTemperature(0.6f)
               .withFunction("retrievePaymentStatus")
               .build()));

查看MistralAiChatOptions javadocs 以了解可用的选项。

2.3 代码可移植性

将代码移植到其他支持函数调用的模型非常简单。例如,要将代码从使用 Mistral AI 转换为 Azure OpenAI,请执行以下步骤

  1. spring-ai-mistral-ai-spring-boot-starter依赖项替换为spring-ai-azure-openai-spring-boot-starter
  2. 调整application.properties文件
    spring.ai.azure.openai.api-key=${AZURE_OPENAI_API_KEY}
    spring.ai.azure.openai.endpoint=${AZURE_OPENAI_ENDPOINT}
    spring.ai.azure.openai.chat.options.model=gpt-35-turbo
    
  3. MistralAiChatOptions类重命名为AzureOpenAiChatOptions(此重命名在将来的 Spring AI 版本中可能会变得不必要)。

目前,Spring AI 在以下平台之间提供了函数调用代码的可移植性

Spring-AI-Function-Calling-Portability示例应用程序演示了如何在多个 AI 模型中重用相同的代码和相同的函数。

3. 构建原生 (GraalVM) 执行

要构建原生镜像,您需要安装GrallVM 21 JDK并运行以下 Maven 命令

./mvnw clean install -Pnative native:compile

这可能需要几分钟才能完成。然后您可以运行原生可执行文件

./target/mistralai-aot-demo

4. 结论

在本篇博文中,我们将探讨 Mistral AI 的函数调用功能,并结合 Java 和 Spring AI 进行演示。

重点在于利用 Spring AI 中的函数调用功能,该框架通过处理与 AI 模型交互的复杂性来简化集成过程,促进代码可移植性,并开发高效的原生 (GraalVM) 可执行文件。

涵盖的关键要点包括:

  • Spring AI 中函数调用的概述,包括演示和代码示例。
  • 解释动态提示选项和 Spring AI 支持的不同 AI 模型之间的代码可移植性。
  • 构建原生 (GraalVM) 执行以提高性能。

该博文提供了相关文档和演示的链接,让读者可以进一步探索函数调用的功能以及跨不同语言模型提供商的代码可移植性。

获取 Spring 新闻通讯

与 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,帮助您加速进步。

了解更多

获取支持

Tanzu Spring 通过一个简单的订阅提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区中所有即将举行的活动。

查看全部