主题
MistralAI
项目搭建
要将 langchain4j 安装到你的项目,添加以下依赖:
Maven 项目的 pom.xml
xml
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j</artifactId>
<version>1.22.0</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-mistral-ai</artifactId>
<version>1.22.0</version>
</dependency>Gradle 项目的 build.gradle
groovy
implementation 'dev.langchain4j:langchain4j:1.22.0'
implementation 'dev.langchain4j:langchain4j-mistral-ai:1.22.0'API 密钥设置
将你的 MistralAI API 密钥添加到项目中,你可以创建一个 ApiKeys.java 类,内容如下
java
public class ApiKeys {
public static final String MISTRALAI_API_KEY = System.getenv("MISTRAL_AI_API_KEY");
}别忘了把你的 API 密钥设置为环境变量。
shell
export MISTRAL_AI_API_KEY=your-api-key #For Unix OS based
SET MISTRAL_AI_API_KEY=your-api-key #For Windows OS关于如何获取 MistralAI API 密钥的更多细节可在这里找到
模型选择
你可以使用 MistralAiChatModelName 与 MistralAiFimModelName 这两个 Java 枚举来为你的用例找到合适的模型名。 MistralAI 依据性能与成本的权衡,更新了一套新的模型选择与分类方式。
| Model name | Deployment or available from | Description |
|---|---|---|
| open-mistral-7b | - Mistral AI La Plateforme. - Cloud platforms (Azure, AWS, GCP). - Hugging Face. - Self-hosted (On-premise, IaaS, docker, local). | OpenSource The first dense model released by Mistral AI, perfect for experimentation, customization, and quick iteration. Max tokens 32K Java Enum MistralAiChatModelName.OPEN_MISTRAL_7B |
| open-mixtral-8x7b | - Mistral AI La Plateforme. - Cloud platforms (Azure, AWS, GCP). - Hugging Face. - Self-hosted (On-premise, IaaS, docker, local). | OpenSource Ideal to handle multi-languages operations, code generationand fine-tuned. Excellent cost/performance trade-offs. Max tokens 32K Java Enum MistralAiChatModelName.OPEN_MIXTRAL_8x7B |
| open-mixtral-8x22b | - Mistral AI La Plateforme. - Cloud platforms (Azure, AWS, GCP). - Hugging Face. - Self-hosted (On-premise, IaaS, docker, local). | OpenSource It has all Mixtral-8x7B capabilities plus strong maths and coding natively capable of function calling Max tokens 64K. Java Enum MistralAiChatModelName.OPEN_MIXTRAL_8X22B |
| open-mistral-nemo | - Mistral AI La Plateforme. - Cloud platforms (Azure, AWS, GCP). - Hugging Face. - Self-hosted (On-premise, IaaS, docker, local). | OpenSource A 12B model built in collaboration with NVIDIA. Its reasoning, world knowledge, and coding accuracy are state-of-the-art in its size category. Max tokens 128K. Java Enum MistralAiChatModelName.OPEN_MISTRAL_NEMO |
| open-codestral-mamba | - Mistral AI La Plateforme. - Cloud platforms (Azure, AWS, GCP). - Hugging Face. - Self-hosted (On-premise, IaaS, docker, local). | OpenSource A Mamba2 language model specialised in code generation. It was trained with advanced code and reasoning capabilities, enabling it to perform on par with SOTA transformer-based models. Max tokens 256K. Java Enum MistralAiFimModelName.OPEN_CODESTRAL_MAMBA |
| mistral-small-latest | - Mistral AI La Plateforme. - Cloud platforms (Azure, AWS, GCP). | Commercial Suitable for simple tasks that one can do in bulk (Classification, Customer Support, or Text Generation). Max tokens 32K Java Enum MistralAiChatModelName.MISTRAL_SMALL_LATEST |
| mistral-medium-latest | - Mistral AI La Plateforme. - Cloud platforms (Azure, AWS, GCP). | Commercial Ideal for intermediate tasks that require moderate reasoning (Data extraction, Summarizing, Writing emails, Writing descriptions. Max tokens 32K Java Enum MistralAiChatModelName.MISTRAL_MEDIUM_LATEST |
| mistral-large-latest | - Mistral AI La Plateforme. - Cloud platforms (Azure, AWS, GCP). | Commercial Ideal for complex tasks that require large reasoning capabilities or are highly specialized (Text Generation, Code Generation, RAG, or Agents). Max tokens 128K Java Enum MistralAiChatModelName.MISTRAL_LARGE_LATEST |
| mistral-embed | - Mistral AI La Plateforme. - Cloud platforms (Azure, AWS, GCP). | Commercial Converts text into numerical vectors of embeddings in 1024 dimensions. Embedding models enable retrieval and RAG applications. Max tokens 8K Java Enum MistralAiEmbeddingModelName.MISTRAL_EMBED |
| codestral-latest | - Mistral AI La Plateforme. - Cloud platforms (Azure, AWS, GCP). - Hugging Face. - Self-hosted (On-premise, IaaS, docker, local). | OpenSource (Non-production license) and Commercial A cutting-edge generative model that has been specifically designed and optimized for code generation tasks, including fill-in-the-middle and code completion. Max tokens 32K Java Enum MistralAiFimModelName.CODESTRAL_LATEST |
@Deprecated 已弃用模型:
- mistral-tiny(
@Deprecated) - mistral-small(
@Deprecated) - mistral-medium(
@Deprecated)
你可以在这里找到更多细节,以及各自对应的 Mistral 模型类型与用例
聊天补全
聊天模型让你能用一个在对话数据上微调过的模型生成类人的响应。
同步
创建一个类并添加以下代码。
java
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.mistralai.MistralAiChatModel;
public class HelloWorld {
public static void main(String[] args) {
ChatModel model = MistralAiChatModel.builder()
.apiKey(ApiKeys.MISTRALAI_API_KEY)
.modelName(MistralAiChatModelName.MISTRAL_SMALL_LATEST)
.build();
String response = model.chat("Say 'Hello World'");
System.out.println(response);
}
}运行该程序会生成如下所示输出的一个变体
plaintext
Hello World! How can I assist you today?流式
创建一个类并添加以下代码。
java
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import dev.langchain4j.model.mistralai.MistralAiStreamingChatModel;
import dev.langchain4j.model.output.Response;
import java.util.concurrent.CompletableFuture;
public class HelloWorld {
public static void main(String[] args) {
MistralAiStreamingChatModel model = MistralAiStreamingChatModel.builder()
.apiKey(ApiKeys.MISTRALAI_API_KEY)
.modelName(MistralAiChatModelName.MISTRAL_SMALL_LATEST)
.build();
CompletableFuture<ChatResponse> futureResponse = new CompletableFuture<>();
model.chat("Tell me a joke about Java", new StreamingChatResponseHandler() {
@Override
public void onPartialResponse(String partialResponse) {
System.out.print(partialResponse);
}
@Override
public void onCompleteResponse(ChatResponse completeResponse) {
futureResponse.complete(completeResponse);
}
@Override
public void onError(Throwable error) {
futureResponse.completeExceptionally(error);
}
});
futureResponse.join();
}
}你会在 onPartialResponse 方法上,随着 LLM 生成逐块(词元)收到文本。
如下所示,输出是实时流式返回的。
plaintext
"Why do Java developers wear glasses? Because they can't C#"当然,你可以将 MistralAI 聊天补全与设置模型参数、聊天记忆等其他特性结合,以获得更准确的响应。
在聊天记忆中,你将学习如何传递你的聊天历史,让 LLM 知道之前说过什么。如果你不传递聊天历史(像这个简单示例那样),LLM 就不会知道之前说过什么,也就无法正确回答第二个问题("我刚才问了什么?")。
许多参数是在幕后设置的,例如超时、模型类型与模型参数。 在设置模型参数中,你将学习如何显式地设置这些参数。
函数调用
函数调用让 Mistral 聊天模型(同步与流式)能连接外部工具。例如,你可以调用一个 Tool 来获取支付交易状态,如 Mistral AI 函数调用教程所示。
支持哪些 mistral 模型?
NOTE
目前,函数调用可用于以下模型:
- Mistral Small
MistralAiChatModelName.MISTRAL_SMALL_LATEST - Mistral Large
MistralAiChatModelName.MISTRAL_LARGE_LATEST - Mixtral 8x22B
MistralAiChatModelName.OPEN_MIXTRAL_8X22B - Mistral Nemo
MistralAiChatModelName.OPEN_MISTRAL_NEMO
1. 定义一个 Tool 类,以及如何获取支付数据
假设你有这样一个支付交易数据集。在真实应用中,你应当注入一个数据库来源或 REST API 客户端来获取数据。
java
import java.util.*;
public class PaymentTransactionTool {
private final Map<String, List<String>> paymentData = Map.of(
"transaction_id", List.of("T1001", "T1002", "T1003", "T1004", "T1005"),
"customer_id", List.of("C001", "C002", "C003", "C002", "C001"),
"payment_amount", List.of("125.50", "89.99", "120.00", "54.30", "210.20"),
"payment_date", List.of("2021.22.05", "2021.22.06", "2021.22.07", "2021.22.05", "2021.22.08"),
"payment_status", List.of("Paid", "Unpaid", "Paid", "Paid", "Pending"));
...
}接下来,定义两个方法 retrievePaymentStatus 与 retrievePaymentDate,从 Tool 类获取支付状态与支付日期。
java
// Tool to be executed to get payment status
@Tool("Get payment status of a transaction") // function description
String retrievePaymentStatus(@P("Transaction id to search payment data") String transactionId) {
return getPaymentData(transactionId, "payment_status");
}
// Tool to be executed to get payment date
@Tool("Get payment date of a transaction") // function description
String retrievePaymentDate(@P("Transaction id to search payment data") String transactionId) {
return getPaymentData(transactionId, "payment_date");
}
private String getPaymentData(String transactionId, String data) {
List<String> transactionIds = paymentData.get("transaction_id");
List<String> paymentData = paymentData.get(data);
int index = transactionIds.indexOf(transactionId);
if (index != -1) {
return paymentData.get(index);
} else {
return "Transaction ID not found";
}
}它使用 @Tool 注解定义函数描述,并用 @P 注解定义来自包 dev.langchain4j.agent.tool.* 的参数描述。更多信息见这里
2. 定义一个接口作为发送聊天消息的 agent。
创建一个接口 PaymentTransactionAgent。
java
import dev.langchain4j.service.SystemMessage;
interface PaymentTransactionAgent {
@SystemMessage({
"You are a payment transaction support agent.",
"You MUST use the payment transaction tool to search the payment transaction data.",
"If there a date convert it in a human readable format."
})
String chat(String userMessage);
}3. 定义一个 main 应用类,与 MistralAI 聊天模型对话
java
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.mistralai.MistralAiChatModel;
import dev.langchain4j.model.mistralai.MistralAiChatModelName;
import dev.langchain4j.service.AiServices;
public class PaymentDataAssistantApp {
ChatModel mistralAiModel = MistralAiChatModel.builder()
.apiKey(System.getenv("MISTRAL_AI_API_KEY")) // Please use your own Mistral AI API key
.modelName(MistralAiChatModelName.MISTRAL_LARGE_LATEST) // Also you can use MistralAiChatModelName.OPEN_MIXTRAL_8X22B as open source model
.logRequests(true)
.logResponses(true)
.build();
public static void main(String[] args) {
// STEP 1: User specify tools and query
PaymentTransactionTool paymentTool = new PaymentTransactionTool();
String userMessage = "What is the status and the payment date of transaction T1005?";
// STEP 2: User asks the agent and AiServices call to the functions
PaymentTransactionAgent agent = AiServices.builder(PaymentTransactionAgent.class)
.chatModel(mistralAiModel)
.tools(paymentTool)
.chatMemory(MessageWindowChatMemory.withMaxMessages(10))
.build();
// STEP 3: User gets the final response from the agent
String answer = agent.chat(userMessage);
System.out.println(answer);
}
}并期望得到类似这样的答案:
shell
The status of transaction T1005 is Pending. The payment date is October 8, 2021.JSON 模式
你也可以使用 JSON 模式让响应以 JSON 格式返回。为此,你需要在 MistralAiChatModel builder 或 MistralAiStreamingChatModel builder 中将 responseFormat 参数设为 ResponseFormat.JSON。
同步示例:
java
ChatModel model = MistralAiChatModel.builder()
.apiKey(System.getenv("MISTRAL_AI_API_KEY")) // Please use your own Mistral AI API key
.responseFormat(ResponseFormat.JSON)
.build();
String userMessage = "Return JSON with two fields: transactionId and status with the values T123 and paid.";
String json = model.chat(userMessage);
System.out.println(json); // {"transactionId":"T123","status":"paid"}流式示例:
java
StreamingChatModel streamingModel = MistralAiStreamingChatModel.builder()
.apiKey(System.getenv("MISTRAL_AI_API_KEY")) // Please use your own Mistral AI API key
.responseFormat(MistralAiResponseFormatType.JSON_OBJECT)
.build();
String userMessage = "Return JSON with two fields: transactionId and status with the values T123 and paid.";
CompletableFuture<ChatResponse> futureResponse = new CompletableFuture<>();
streamingModel.chat(userMessage, new StreamingChatResponseHandler() {
@Override
public void onPartialResponse(String partialResponse) {
System.out.print(partialResponse);
}
@Override
public void onCompleteResponse(ChatResponse completeResponse) {
futureResponse.complete(completeResponse);
}
@Override
public void onError(Throwable error) {
futureResponse.completeExceptionally(error);
}
});
String json = futureResponse.get().content().text();
System.out.println(json); // {"transactionId":"T123","status":"paid"}结构化输出
结构化输出(Structured Outputs)确保模型的响应遵循一个 JSON schema。
NOTE
关于在 LangChain4j 中使用结构化输出的文档在这里,下节你会找到 MistralAI 专有的信息。
如有需要,模型可配置一个默认的 JSON Schema,当请求未提供 schema 时作为回退使用。
java
ChatModel model = MistralAiChatModel.builder()
.apiKey(System.getenv("MISTRAL_AI_API_KEY"))
.modelName(MISTRAL_SMALL_LATEST)
.supportedCapabilities(Set.of(Capability.RESPONSE_FORMAT_JSON_SCHEMA)) // Enable structured outputs
.responseFormat(ResponseFormat.builder() // Set the fallback JSON Schema (optional)
.type(ResponseFormatType.JSON)
.jsonSchema(JsonSchema.builder().rootElement(JsonObjectSchema.builder()
.addProperty("name", JsonStringSchema.builder().build())
.addProperty("capital", JsonStringSchema.builder().build())
.addProperty(
"languages",
JsonArraySchema.builder()
.items(JsonStringSchema.builder().build())
.build())
.required("name", "capital", "languages")
.build())
.build())
.build())
.strictJsonSchema(true)
.build();护栏(Guardrailing)
护栏是一种限制模型行为、防止它生成有害或不受欢迎内容的方式。你可以选择在 MistralAiChatModel builder 或 MistralAiStreamingChatModel builder 中设置 safePrompt 参数。
同步示例:
java
ChatModel model = MistralAiChatModel.builder()
.apiKey(System.getenv("MISTRAL_AI_API_KEY"))
.safePrompt(true)
.build();
String userMessage = "What is the best French cheese?";
String response = model.chat(userMessage);流式示例:
java
StreamingChatModel streamingModel = MistralAiStreamingChatModel.builder()
.apiKey(System.getenv("MISTRAL_AI_API_KEY"))
.safePrompt(true)
.build();
String userMessage = "What is the best French cheese?";
CompletableFuture<ChatResponse> futureResponse = new CompletableFuture<>();
streamingModel.chat(userMessage, new StreamingChatResponseHandler() {
@Override
public void onPartialResponse(String partialResponse) {
System.out.print(partialResponse);
}
@Override
public void onCompleteResponse(ChatResponse completeResponse) {
futureResponse.complete(completeResponse);
}
@Override
public void onError(Throwable error) {
futureResponse.completeExceptionally(error);
}
});
futureResponse.join();开启安全提示词后,会在你的消息前加上如下 @SystemMessage:
plaintext
Always assist with care, respect, and truth. Respond with utmost utility yet securely. Avoid harmful, unethical, prejudiced, or negative content. Ensure replies promote fairness and positivity.逐次请求参数
Mistral 专有选项(safePrompt、randomSeed、sendThinking 与 returnThinking)也可通过 MistralAiChatRequestParameters 逐次请求设置,覆盖在模型 builder 上配置的值。 这让你能用单个共享模型实例在一次次调用间变化这些选项——例如对某个请求启用 safePrompt 而对另一个不启用,或为一次可复现的补全设置 randomSeed,而无需构建第二个模型:
java
ChatModel model = MistralAiChatModel.builder()
.apiKey(System.getenv("MISTRAL_AI_API_KEY"))
.modelName("mistral-small-latest")
.build();
MistralAiChatRequestParameters parameters = MistralAiChatRequestParameters.builder()
.safePrompt(true)
.randomSeed(42)
.build();
ChatRequest chatRequest = ChatRequest.builder()
.messages(UserMessage.from("What is the best French cheese?"))
.parameters(parameters)
.build();
ChatResponse chatResponse = model.chat(chatRequest);思考 / 推理
MistralAiChatModel 与 MistralAiStreamingChatModel 都支持借助 Magistral 推理模型 进行推理。
通过以下参数配置:
returnThinking:启用时,模型产生的推理文本会从 API 响应中被解析,并存储于AiMessage.thinking()。对于流式,StreamingChatResponseHandler.onPartialThinking()与TokenStream.onPartialThinking()回调也会被调用。默认禁用。sendThinking:启用时,来自先前响应的推理文本(存储于AiMessage.thinking())会被包含到对 LLM 的后续请求中。默认禁用。
下面是一个如何配置推理的示例:
java
ChatModel model = MistralAiChatModel.builder()
.apiKey(System.getenv("MISTRAL_AI_API_KEY"))
.modelName(MistralAiChatModelName.MAGISTRAL_MEDIUM_LATEST)
.returnThinking(true)
.sendThinking(true)
.build();内容审核(Moderation)
它是一个分类器模型,可用于检测文本中的有害内容。
内容审核示例:
java
ModerationModel model = new MistralAiModerationModel.Builder()
.apiKey(System.getenv("MISTRAL_AI_API_KEY"))
.modelName(MistralAiModerationModelName.MISTRAL_MODERATION_LATEST)
.logRequests(true)
.logResponses(false)
.build();
// I want to check if the text contains harmful content
Moderation moderation = model.moderate("I want to kill them.").content();代码补全
中间填充(FIM)模型让你能生成代码补全,用户可以用一个 prompt 定义代码的起始点,并用一个可选的 suffix 和一个可选的 stop 定义代码的结束点。
FIM 同步
就像聊天补全那样,FIM 端点也能工作。你可以通过添加以下代码来测试它。
java
import dev.langchain4j.model.mistralai.MistralAiFimModel;
import dev.langchain4j.model.output.Response;
public class HelloWorld {
public static void main(String[] args) {
MistralAiFimModel codestral = MistralAiFimModel.builder()
.apiKey(System.getenv("MISTRAL_AI_API_KEY"))
.modelName(MistralAiFimModelName.CODESTRAL_LATEST)
.stop(List.of("}")) // must stop at the first occurrence of "}"
.build();
// I want to generate a code completion for a simple hello world program using MistralAI of LangChain4j framework.
String codePrompt = """
public static void main(String[] args) {
// Create a function to multiply two numbers
""";
String suffix = """
System.out.println(result);
}
""";
// Asking to Codestral model to complete the code with given prompt and suffix
Response<String> response = codestral.generate(prompt, suffix);
System.out.println(
String.format(
"%s%s%s",
prompt, // print code prompt (prefix)
response.content(), // print code filled-in-the-middle
suffix)); // print code suffix
}
}运行该程序会打印如下所示输出的一个变体
console
public static void main(String[] args) {
// Create a function to multiply two numbers
int result = multiply(5, 3);
System.out.println(result);
}FIM 流式
创建一个类并添加以下代码。
java
import dev.langchain4j.model.StreamingResponseHandler;
import dev.langchain4j.model.language.StreamingLanguageModel;
import dev.langchain4j.model.mistralai.MistralAiStreamingFimModel;
import dev.langchain4j.model.output.Response;
import java.util.concurrent.CompletableFuture;
public class HelloWorld {
public static void main(String[] args) {
StreamingLanguageModel codestralStream = MistralAiStreamingFimModel.builder()
.apiKey(ApiKeys.MISTRALAI_API_KEY)
.modelName(MistralAiFimModelName.CODESTRAL_LATEST)
.build();
// I want to generate a code completion for a simple hello world program.
String prompt = "public static void main(String[] args) {";
CompletableFuture<Response<String>> futureResponse = new CompletableFuture<>();
codestral.generate(prompt, new StreamingResponseHandler() {
@Override
public void onNext(String token) {
System.out.print(token);
}
@Override
public void onComplete(Response<String> response) {
futureResponse.complete(response);
}
@Override
public void onError(Throwable error) {
futureResponse.completeExceptionally(error);
}
});
futureResponse.join();
}
}你会在 onNext 方法上,随着 LLM 生成逐块(词元)收到文本。
如下所示,输出是实时流式返回的。
console
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
System.out.println("Sum of all elements in the array: " + sum);
}
}访问原始 HTTP 响应与服务端事件流(SSE)
使用 MistralAiChatModel 时,你可以访问原始 HTTP 响应:
java
SuccessfulHttpResponse rawHttpResponse = ((MistralAiChatResponseMetadata) chatResponse.metadata()).rawHttpResponse();
System.out.println(rawHttpResponse.body());
System.out.println(rawHttpResponse.headers());
System.out.println(rawHttpResponse.statusCode());使用 MistralAiStreamingChatModel 时,你可以访问原始 HTTP 响应(见上)以及原始服务端事件流:
java
List<ServerSentEvent> rawServerSentEvents = ((MistralAiChatResponseMetadata) chatResponse.metadata()).rawServerSentEvents();
System.out.println(rawServerSentEvents.get(0).data());
System.out.println(rawServerSentEvents.get(0).event());批处理
MistralAiBatchChatModel 实现了核心的 BatchChatModel 接口,通过 Mistral Batch API 异步处理大量聊天请求,按标准逐词元价格的 50% 计费。一批中的所有请求都针对该批处理模型上配置的单一模型运行。
提交一个批次,轮询直到它达到终态,然后读取逐次请求的结果(保持提交顺序):
java
MistralAiBatchChatModel batchModel = MistralAiBatchChatModel.builder()
.apiKey(System.getenv("MISTRAL_AI_API_KEY"))
.modelName("mistral-small-latest")
.build();
BatchResponse<ChatResponse> submitted = batchModel.submit(new BatchRequest<>(List.of(
ChatRequest.builder().messages(UserMessage.from("What is the capital of France?")).build(),
ChatRequest.builder().messages(UserMessage.from("What is the capital of Germany?")).build())));
String batchId = submitted.batchId();
// Poll until the batch reaches a terminal state (SUCCEEDED, FAILED, CANCELLED, EXPIRED).
BatchResponse<ChatResponse> batch = batchModel.retrieve(batchId);
while (!batch.state().isTerminal()) {
Thread.sleep(Duration.ofSeconds(30).toMillis());
batch = batchModel.retrieve(batchId);
}
for (BatchItemResult<ChatResponse> result : batch.results()) {
if (result.isSuccess()) {
System.out.println(result.response().aiMessage().text());
} else {
System.out.println("Failed: " + result.error().message());
}
}一个正在运行的批次可以被取消,现有批次也可以分页列出:
java
batchModel.cancel(batchId);
BatchPage<ChatResponse> page = batchModel.list(new BatchPagination(20, null));