当前位置: 首页 > news >正文

Spring AI系列之使用 Mistral AI API 实现函数调用

1. 概述

利用大型语言模型(LLM),我们可以检索大量有用的信息。我们可以学习关于任何事物的许多新知识,并基于互联网上已有的数据获得答案。我们可以让它们处理输入数据并执行各种操作。但如果我们让模型调用API来准备输出呢?

为此,我们可以使用函数调用(Function Calling)。函数调用使大型语言模型能够交互并操作数据,执行计算,或获取超出其固有文本能力的信息。

本文将探讨函数调用是什么,以及如何利用它将大型语言模型与我们内部的业务逻辑集成。作为模型提供方,我们将使用 Mistral AI 的 API。


2. Mistral AI API

Mistral AI 致力于为开发者和企业提供开放且可移植的生成式 AI 模型。我们既可以用它来处理简单的提示,也可以用来实现函数调用集成。

2.1 获取 API 密钥

要开始使用 Mistral API,首先需要获取 API 密钥。这一步读者自行去网上搜索。

2.2 使用示例

我们先从一个简单的提示开始。我们将请求 Mistral API 返回一个患者状态列表。下面来实现这样一个调用:

@Test
void givenHttpClient_whenSendTheRequestToChatAPI_thenShouldBeExpectedWordInResponse() throws IOException, InterruptedException {String apiKey = System.getenv("MISTRAL_API_KEY");String apiUrl = "https://api.mistral.ai/v1/chat/completions";String requestBody = "{"+ "\"model\": \"mistral-large-latest\","+ "\"messages\": [{\"role\": \"user\", "+ "\"content\": \"What the patient health statuses can be?\"}]"+ "}";HttpClient client = HttpClient.newHttpClient();HttpRequest request = HttpRequest.newBuilder().uri(URI.create(apiUrl)).header("Content-Type", "application/json").header("Accept", "application/json").header("Authorization", "Bearer " + apiKey).POST(HttpRequest.BodyPublishers.ofString(requestBody)).build();HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());String responseBody = response.body();logger.info("Model response: " + responseBody);Assertions.assertThat(responseBody).containsIgnoringCase("healthy");
}

我们创建了一个 HTTP 请求并发送到/chat/completions端点。然后,我们使用API密钥作为授权头的值。正如预期的那样,响应中包含了元数据和内容本身:

Model response: {"id":"585e3599275545c588cb0a502d1ab9e0","object":"chat.completion",
"created":1718308692,"model":"mistral-large-latest",
"choices":[{"index":0,"message":{"role":"assistant","content":"Patient health statuses can be
categorized in various ways, depending on the specific context or medical system being used.
However, some common health statuses include:
1.Healthy: The patient is in good health with no known medical issues.
...
10.Palliative: The patient is receiving care that is focused on relieving symptoms and improving quality of life, rather than curing the underlying disease.",
"tool_calls":null},"finish_reason":"stop","logprobs":null}],
"usage":{"prompt_tokens":12,"total_tokens":291,"completion_tokens":279}}

函数调用的示例为复杂,且在调用之前需要做大量准备工作。我们将在后面部分中详细了解。

3. Spring AI 集成

下面来看几个使用 Mistral API 进行函数调用的示例。借助 Spring AI,我们可以省去很多准备工作,让框架帮我们完成。

3.1 依赖项

所需的依赖项位于 Spring 里程碑版本仓库中。我们将其添加到 pom.xml 文件中:

<repositories><repository><id>spring-milestones</id><name>Spring milestones</name><url>https://repo.spring.io/milestone</url></repository>
</repositories>

添加Mistral API的集成依赖

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

3.2 配置

把上面获取到的key配置到属性文件

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

3.3 仅使用一个调用函数的用例

在我们的演示示例中,我们将创建一个函数,根据患者的 ID 返回患者的健康状态。

让我们先创建患者记录:

public record Patient(String patientId) {
}

再创建一个健康状态记录

public record HealthStatus(String status) {
}

然后,创建一个配置类

@Configuration
public class MistralAIFunctionConfiguration {public static final Map<Patient, HealthStatus> HEALTH_DATA = Map.of(new Patient("P001"), new HealthStatus("Healthy"),new Patient("P002"), new HealthStatus("Has cough"),new Patient("P003"), new HealthStatus("Healthy"),new Patient("P004"), new HealthStatus("Has increased blood pressure"),new Patient("P005"), new HealthStatus("Healthy"));@Bean@Description("Get patient health status")public Function<Patient, HealthStatus> retrievePatientHealthStatus() {return (patient) -> new HealthStatus(HEALTH_DATA.get(patient).status());}
}

此处,我们已定义了包含患者健康数据的数据集。此外,我们还创建了

retrievePatientHealthStatus()函数,该函数可根据给定的患者 ID 返回其健康状态。

现在,让我们通过在集成环境中调用该函数来进行测试:

@Import(MistralAIFunctionConfiguration.class)
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class MistralAIFunctionCallingManualTest {@Autowiredprivate MistralAiChatModel chatClient;@Testvoid givenMistralAiChatClient_whenAskChatAPIAboutPatientHealthStatus_thenExpectedHealthStatusIsPresentInResponse() {var options = MistralAiChatOptions.builder().withFunction("retrievePatientHealthStatus").build();ChatResponse paymentStatusResponse = chatClient.call(new Prompt("What's the health status of the patient with id P004?",  options));String responseContent = paymentStatusResponse.getResult().getOutput().getContent();logger.info(responseContent);Assertions.assertThat(responseContent).containsIgnoringCase("has increased blood pressure");}
}

我们导入了MistralAIFunctionConfiguration类,将retrievePatientHealthStatus()函数添加到测试的Spring上下文中。同时,我们注入了MistralAiChatClient,该客户端会由 Spring AI Starter 自动实例化。

在请求聊天 API 时,我们指定了包含某个患者 ID 的提示文本,以及用于获取健康状态的函数名称。随后调用了 API,并验证响应中包含了预期的健康状态。

此外,我们还记录了整个响应文本,内容如下:

The patient with id P004 has increased blood pressure.

3.4 多函数用例

我们还可以指定多个函数,AI 会根据我们发送的提示决定使用哪个函数。

为了演示这一点,让我们扩展一下 HealthStatus 记录:

public record HealthStatus(String status, LocalDate changeDate) {
}

我们添加了状态上次变更的日期。

现在,让我们修改配置类:

@Configuration
public class MistralAIFunctionConfiguration {public static final Map<Patient, HealthStatus> HEALTH_DATA = Map.of(new Patient("P001"), new HealthStatus("Healthy",LocalDate.of(2024,1, 20)),new Patient("P002"), new HealthStatus("Has cough",LocalDate.of(2024,3, 15)),new Patient("P003"), new HealthStatus("Healthy",LocalDate.of(2024,4, 12)),new Patient("P004"), new HealthStatus("Has increased blood pressure",LocalDate.of(2024,5, 19)),new Patient("P005"), new HealthStatus("Healthy",LocalDate.of(2024,6, 1)));@Bean@Description("Get patient health status")public Function<Patient, String> retrievePatientHealthStatus() {return (patient) -> HEALTH_DATA.get(patient).status();}@Bean@Description("Get when patient health status was updated")public Function<Patient, LocalDate> retrievePatientHealthStatusChangeDate() {return (patient) -> HEALTH_DATA.get(patient).changeDate();}
}

我们为每个状态项填写了变更日期。同时,我们还创建了 retrievePatientHealthStatusChangeDate() 函数,用于返回状态变更日期的信息。

下面来看如何使用这两个新函数与 Mistral API 进行交互:

@Test
void givenMistralAiChatClient_whenAskChatAPIAboutPatientHealthStatusAndWhenThisStatusWasChanged_thenExpectedInformationInResponse() {var options = MistralAiChatOptions.builder().withFunctions(Set.of("retrievePatientHealthStatus","retrievePatientHealthStatusChangeDate")).build();ChatResponse paymentStatusResponse = chatClient.call(new Prompt("What's the health status of the patient with id P005",options));String paymentStatusResponseContent = paymentStatusResponse.getResult().getOutput().getContent();logger.info(paymentStatusResponseContent);Assertions.assertThat(paymentStatusResponseContent).containsIgnoringCase("healthy");ChatResponse changeDateResponse = chatClient.call(new Prompt("When health status of the patient with id P005 was changed?",options));String changeDateResponseContent = changeDateResponse.getResult().getOutput().getContent();logger.info(changeDateResponseContent);Assertions.assertThat(paymentStatusResponseContent).containsIgnoringCase("June 1, 2024");
}

在这种情况下,我们指定了两个函数名称并发送了两个提示。首先,我们询问了患者的健康状态;然后,我们询问了该状态的变更时间。我们确认返回的结果包含了预期的信息。除此之外,我们还记录了所有响应,内容如下:

The patient with id P005 is currently healthy.
The health status of the patient with id P005 was changed on June 1, 2024.

4. 结论

函数调用是扩展大型语言模型功能的绝佳工具。我们还可以利用它将大型语言模型与我们的业务逻辑进行集成。

在本教程中,我们探讨了如何通过调用一个或多个自定义函数来实现基于大型语言模型的流程。通过这种方法,我们能够开发与AI API深度集成的现代应用程

 关注我不迷路,系列化的给您提供当代程序员需要掌握的现代AI工具和框架

相关文章:

  • 使用LSTM进行时间序列分析
  • MCU - SPI总线介绍 + W25Qx驱动设计
  • 基于深度学习的三维图像生成项目开发方案
  • SpringAI+MCPServer+MCPClient快速入门
  • 如何优化Elasticsearch的搜索性能?
  • adb查看、设置cpu相关信息
  • failed to bind host port for 0.0.0.0:3306
  • 【 Docker系列】 Docker部署kafka
  • 深度解读漏洞扫描:原理、类型与应用实践
  • 虚拟机中创建虚拟机-window10为例
  • 2025.05.28【Parallel】Parallel绘图:拟时序分析专用图
  • TestStand API编程:在SequenceFile中操作Sequence和Step
  • Vue 3 的 <script setup> 语法糖(持续更新)
  • 零基础设计模式——结构型模式 - 享元模式
  • Conda更换镜像源教程:加速Python包下载
  • 双因子COX 交互 共线性 -spss
  • Windows SMB压缩在低速或者高延迟环境可以帮助提供性能增益
  • UDP数据报
  • 设计模式24——访问者模式
  • Flutter 与 Android 原生布局组件对照表(完整版)
  • 简易做网站/南京seo全网营销
  • 前端 国外 网站/百度推广400客服电话
  • 做美食网站的目的意义/石嘴山网站seo
  • 电子商务网站建设教程pdf/互联网广告投放代理公司
  • 武汉市建设厅官方网站/百度竞价关键词怎么优化
  • 北京网站制作培训学校/网站优化排名首页