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

工程 | 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(或 Open API)模式。此外,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 社区所有即将举行的活动。

查看所有