LangChain4j integration for Mistral AI providing chat completion, streaming, embedding, moderation, and code completion capabilities
Mistral AI chat completion capabilities with synchronous and streaming modes. Supports multi-turn conversations, tool/function calling, multimodal inputs (text and images), thinking/reasoning output, JSON schema responses, and extensive Configuration Options options.
Generates complete chat responses in a single API call. Blocks until the full response is received. Suitable for scenarios where you need the complete response before proceeding.
public class MistralAiChatModel implements ChatModel {
/**
* Create a new builder for configuring MistralAiChatModel.
*
* @return MistralAiChatModelBuilder instance
*/
public static MistralAiChatModelBuilder builder() { ... }
/**
* Generate a chat response from a chat request.
* Main API method that handles all chat interactions.
*
* @param chatRequest ChatRequest (non-null) containing messages and parameters
* @return ChatResponse with generated message and metadata
*/
public ChatResponse chat(ChatRequest chatRequest) { ... }
/**
* Generate a chat response from a user message string.
* Convenience method for simple text interactions.
*
* @param userMessage Simple (non-null) string message from user
* @return String response from the AI
*/
public String chat(String userMessage) { ... }
/**
* Generate a chat response from variable number of messages.
* Convenience method for multi-message conversations.
*
* @param messages Variable (non-null) number of ChatMessage arguments
* @return ChatResponse with generated message and metadata
*/
public ChatResponse chat(ChatMessage... messages) { ... }
/**
* Generate a chat response from a list of messages.
* Convenience method for multi-message conversations.
*
* @param messages List (non-null) of ChatMessage objects (UserMessage, AiMessage, SystemMessage)
* @return ChatResponse with generated message and metadata
*/
public ChatResponse chat(List<ChatMessage> messages) { ... }
/**
* Core interface method for chat request processing.
*
* @param chatRequest ChatRequest (non-null) containing messages and parameters
* @return ChatResponse with generated message
*/
public ChatResponse doChat(ChatRequest chatRequest) { ... }
/**
* Get the default request parameters configured for this model.
*
* @return ChatRequestParameters with default settings
*/
public ChatRequestParameters defaultRequestParameters() { ... }
/**
* Get the list of chat model listeners attached to this model.
*
* @return List of ChatModelListener instances for observability
*/
public List<ChatModelListener> listeners() { ... }
/**
* Get the model provider identifier.
*
* @return ModelProvider (MISTRAL_AI)
*/
public ModelProvider provider() { ... }
/**
* Get the set of capabilities supported by this model.
*
* @return Set of Capability enums (e.g., TOOL_CALLING, MULTIMODAL, etc.)
*/
public Set<Capability> supportedCapabilities() { ... }
}Simple conversation:
import dev.langchain4j.model.mistralai.MistralAiChatModel;
import dev.langchain4j.model.mistralai.MistralAiChatModelName;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.SystemMessage;
import dev.langchain4j.model.output.Response;
import java.util.Arrays;
import java.util.List;
MistralAiChatModel chatModel = MistralAiChatModel.builder()
.apiKey(System.getenv("MISTRAL_API_KEY"))
.modelName(MistralAiChatModelName.MISTRAL_LARGE_LATEST)
.temperature(0.7)
.build();
List<ChatMessage> messages = Arrays.asList(
SystemMessage.from("You are a helpful assistant."),
UserMessage.from("What is the speed of light?")
);
ChatResponse response = chatModel.chat(messages);
System.out.println(response.aiMessage().text());Multi-turn conversation:
List<ChatMessage> conversation = new ArrayList<>();
conversation.add(SystemMessage.from("You are a helpful math tutor."));
conversation.add(UserMessage.from("What is 15 * 24?"));
ChatResponse response1 = chatModel.chat(conversation);
conversation.add(response1.aiMessage());
conversation.add(UserMessage.from("Now add 100 to that result."));
ChatResponse response2 = chatModel.chat(conversation);
System.out.println(response2.aiMessage().text());Tool/function calling:
import dev.langchain4j.agent.tool.ToolSpecification;
// Note: JsonSchemaProperty is not available in this library.
// Refer to LangChain4j core documentation for ToolSpecification.builder() methods
ToolSpecification weatherTool = ToolSpecification.builder()
.name("get_current_weather")
.description("Get the current weather for a location")
// Use appropriate ToolSpecification.builder() methods for parameters
.build();
// Note: Tool specifications must be added to ChatRequest.parameters()
// using ChatRequestParameters, not passed directly to chat()
ChatRequestParameters params = ChatRequestParameters.builder()
.toolSpecifications(weatherTool)
.build();
ChatRequest chatRequest = ChatRequest.builder()
.messages(UserMessage.from("What's the weather in Paris?"))
.parameters(params)
.build();
ChatResponse response = chatModel.chat(chatRequest);
if (response.aiMessage().hasToolExecutionRequests()) {
for (ToolExecutionRequest request : response.aiMessage().toolExecutionRequests()) {
System.out.println("Tool: " + request.name());
System.out.println("Arguments: " + request.arguments());
}
}Multimodal inputs (text and images):
import dev.langchain4j.data.message.ImageContent;
import dev.langchain4j.data.message.TextContent;
import dev.langchain4j.data.image.Image;
import java.net.URI;
Image image = Image.builder()
.url(URI.create("https://example.com/image.jpg"))
.build();
UserMessage userMessage = UserMessage.from(
TextContent.from("What do you see in this image?"),
ImageContent.from(image)
);
ChatResponse response = chatModel.chat(List.of(userMessage));JSON schema response:
import dev.langchain4j.model.chat.request.ResponseFormat;
import dev.langchain4j.model.chat.request.json.JsonSchema;
import java.util.Map;
// Define JSON schema structure
Map<String, Object> schema = Map.of(
"type", "object",
"properties", Map.of(
"name", Map.of("type", "string"),
"age", Map.of("type", "number"),
"city", Map.of("type", "string")
),
"required", List.of("name", "age")
);
ResponseFormat responseFormat = ResponseFormat.builder()
.type(ResponseFormat.JSON)
.jsonSchema(JsonSchema.builder()
.name("person_info")
.schema(schema)
.strict(true)
.build())
.build();
MistralAiChatModel chatModel = MistralAiChatModel.builder()
.apiKey(apiKey)
.modelName(MistralAiChatModelName.MISTRAL_LARGE_LATEST)
.responseFormat(responseFormat)
.build();
ChatResponse response = chatModel.chat(
List.of(UserMessage.from("Tell me about John who is 30 years old from Paris"))
);Generates chat responses token-by-token in real-time via streaming. Provides immediate feedback and enables progressive UI updates. Uses server-sent events (SSE) for streaming responses.
public class MistralAiStreamingChatModel implements StreamingChatModel {
/**
* Create a new builder for configuring MistralAiStreamingChatModel.
*
* @return MistralAiStreamingChatModelBuilder instance
*/
public static MistralAiStreamingChatModelBuilder builder() { ... }
/**
* Generate a streaming chat response from a chat request.
* Main API method for streaming interactions.
*
* @param chatRequest ChatRequest (non-null) containing messages and parameters
* @param handler StreamingChatResponseHandler (non-null) to receive streaming response
*/
public void chat(ChatRequest chatRequest, StreamingChatResponseHandler handler) { ... }
/**
* Core interface method for streaming chat request processing.
*
* @param chatRequest ChatRequest (non-null) containing messages and parameters
* @param handler StreamingChatResponseHandler (non-null) to receive streaming response
*/
public void doChat(ChatRequest chatRequest, StreamingChatResponseHandler handler) { ... }
/**
* Get the default request parameters configured for this model.
*
* @return ChatRequestParameters with default settings
*/
public ChatRequestParameters defaultRequestParameters() { ... }
/**
* Get the list of chat model listeners attached to this model.
*
* @return List of ChatModelListener instances for observability
*/
public List<ChatModelListener> listeners() { ... }
/**
* Get the model provider identifier.
*
* @return ModelProvider (MISTRAL_AI)
*/
public ModelProvider provider() { ... }
/**
* Get the set of capabilities supported by this model.
*
* @return Set of Capability enums (e.g., TOOL_CALLING, MULTIMODAL, etc.)
*/
public Set<Capability> supportedCapabilities() { ... }
}Basic streaming:
import dev.langchain4j.model.mistralai.MistralAiStreamingChatModel;
import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
import dev.langchain4j.model.chat.request.ChatRequest;
MistralAiStreamingChatModel streamingModel = MistralAiStreamingChatModel.builder()
.apiKey(System.getenv("MISTRAL_API_KEY"))
.modelName(MistralAiChatModelName.MISTRAL_LARGE_LATEST)
.temperature(0.7)
.build();
ChatRequest chatRequest = ChatRequest.builder()
.messages(UserMessage.from("Write a short poem about Java"))
.build();
streamingModel.chat(chatRequest, new StreamingChatResponseHandler() {
@Override
public void onPartialResponse(String token) {
System.out.print(token);
}
@Override
public void onCompleteResponse(ChatResponse response) {
System.out.println("\n\nStreaming completed.");
System.out.println("Tokens used: " + response.metadata().tokenUsage().totalTokenCount());
}
@Override
public void onError(Throwable error) {
System.err.println("Error: " + error.getMessage());
}
});Streaming with accumulation:
StringBuilder fullResponse = new StringBuilder();
ChatRequest chatRequest = ChatRequest.builder()
.messages(messages)
.build();
streamingModel.chat(chatRequest, new StreamingChatResponseHandler() {
@Override
public void onPartialResponse(String token) {
fullResponse.append(token);
updateUI(token); // Update UI progressively
}
@Override
public void onCompleteResponse(ChatResponse response) {
String complete = fullResponse.toString();
saveResponse(complete);
}
@Override
public void onError(Throwable error) {
handleError(error);
}
});Both MistralAiChatModel and MistralAiStreamingChatModel share similar builder configuration options, with one exception: MistralAiStreamingChatModel does NOT have a maxRetries() method (only the synchronous MistralAiChatModel supports retries).
public static class MistralAiChatModelBuilder {
/**
* Set the Mistral AI API key (required).
*
* @param apiKey Your (non-null) Mistral AI API key
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder apiKey(String apiKey) { ... }
/**
* Set the base URL for the Mistral AI API.
* Default: https://api.mistral.ai/v1
*
* @param baseUrl Custom (non-null) API endpoint URL
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder baseUrl(String baseUrl) { ... }
/**
* Set the model name using enum.
*
* @param modelName MistralAiChatModelName (non-null) enum value
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder modelName(MistralAiChatModelName modelName) { ... }
/**
* Set the model name using string.
*
* @param modelName Model (non-null) identifier string
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder modelName(String modelName) { ... }
/**
* Set sampling temperature (0.0 to 1.0).
* Higher values make output more random, lower values more deterministic.
* Default: 0.7
*
* @param temperature Temperature (non-null) value
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder temperature(Double temperature) { ... }
/**
* Set top-p sampling parameter (0.0 to 1.0).
* Controls nucleus sampling.
*
* @param topP Top (non-null)-p value
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder topP(Double topP) { ... }
/**
* Set maximum number of tokens to generate.
*
* @param maxTokens Maximum (non-null) tokens
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder maxTokens(Integer maxTokens) { ... }
/**
* Enable safe prompt mode for additional content safety.
*
* @param safePrompt True (non-null) to enable safe prompt mode
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder safePrompt(Boolean safePrompt) { ... }
/**
* Set random seed for reproducible outputs.
*
* @param randomSeed Random (non-null) seed value
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder randomSeed(Integer randomSeed) { ... }
/**
* Include thinking/reasoning content in the response.
*
* @param returnThinking True (non-null) to return thinking content
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder returnThinking(Boolean returnThinking) { ... }
/**
* Send thinking/reasoning content to the model.
*
* @param sendThinking True (non-null) to send thinking content
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder sendThinking(Boolean sendThinking) { ... }
/**
* Set response format (text or JSON object).
* Note: Uses LangChain4j's public ResponseFormat from dev.langchain4j.model.chat.request
*
* @param responseFormat ResponseFormat (non-null) configuration
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder responseFormat(ResponseFormat responseFormat) { ... }
/**
* Set custom stop sequences to terminate generation.
*
* @param stopSequences List (non-null) of stop sequence strings
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder stopSequences(List<String> stopSequences) { ... }
/**
* Set frequency penalty (-2.0 to 2.0).
* Reduces repetition of token sequences.
*
* @param frequencyPenalty Frequency (non-null) penalty value
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder frequencyPenalty(Double frequencyPenalty) { ... }
/**
* Set presence penalty (-2.0 to 2.0).
* Encourages new topics.
*
* @param presencePenalty Presence (non-null) penalty value
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder presencePenalty(Double presencePenalty) { ... }
/**
* Set request timeout.
* Default: 60 seconds
*
* @param timeout Duration (non-null) for request timeout
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder timeout(Duration timeout) { ... }
/**
* Enable request logging.
*
* @param logRequests True (non-null) to log requests
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder logRequests(Boolean logRequests) { ... }
/**
* Enable response logging.
*
* @param logResponses True (non-null) to log responses
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder logResponses(Boolean logResponses) { ... }
/**
* Set custom SLF4J logger for logging.
*
* @param logger SLF (non-null)4J Logger instance
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder logger(Logger logger) { ... }
/**
* Set maximum retry attempts on failure.
* Default: 2
*
* @param maxRetries Maximum (non-null) number of retries
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder maxRetries(Integer maxRetries) { ... }
/**
* Set chat model listeners for observability.
*
* @param listeners List (non-null) of ChatModelListener instances
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder listeners(List<ChatModelListener> listeners) { ... }
/**
* Set default request parameters.
*
* @param defaultRequestParameters ChatRequestParameters (non-null) with default settings
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder defaultRequestParameters(ChatRequestParameters defaultRequestParameters) { ... }
/**
* Set custom HTTP client builder.
*
* @param httpClientBuilder HttpClientBuilder (non-null) instance
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder httpClientBuilder(HttpClientBuilder httpClientBuilder) { ... }
/**
* Set supported capabilities using varargs.
*
* @param supportedCapabilities Variable (non-null) number of Capability values
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder supportedCapabilities(Capability... supportedCapabilities) { ... }
/**
* Set supported capabilities using a Set.
*
* @param supportedCapabilities Set (non-null) of Capability values
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public MistralAiChatModelBuilder supportedCapabilities(Set<Capability> supportedCapabilities) { ... }
/**
* Build the MistralAiChatModel instance.
*
* @return Configured MistralAiChatModel
*/
public MistralAiChatModel build() { ... }
}Chat responses include additional Mistral AI-specific metadata.
public class MistralAiChatResponseMetadata extends ChatResponseMetadata {
/**
* Get raw HTTP response for debugging.
* Note: Returns SuccessfulHttpResponse object, not String.
*
* @return SuccessfulHttpResponse object containing response details
*/
public SuccessfulHttpResponse rawHttpResponse() { ... }
/**
* Get raw server-sent events (for streaming responses).
* Note: Returns List of ServerSentEvent objects, not Strings.
*
* @return List of ServerSentEvent objects
*/
public List<ServerSentEvent> rawServerSentEvents() { ... }
/**
* Create a builder from this instance.
*
* @return Builder for creating modified copies
*/
public Builder toBuilder() { ... }
/**
* Check equality with another object.
*
* @param o Object (non-null) to compare with
* @return True if equal
*/
public boolean equals(Object o) { ... }
/**
* Get hash code.
*
* @return Hash code value
*/
public int hashCode() { ... }
/**
* Get string representation.
*
* @return String representation
*/
public String toString() { ... }
}Access metadata from responses:
ChatResponse response = chatModel.chat(messages);
// Standard metadata (from ChatResponseMetadata)
TokenUsage tokenUsage = response.metadata().tokenUsage();
System.out.println("Prompt tokens: " + tokenUsage.inputTokenCount());
System.out.println("Completion tokens: " + tokenUsage.outputTokenCount());
System.out.println("Total tokens: " + tokenUsage.totalTokenCount());
FinishReason finishReason = response.metadata().finishReason();
System.out.println("Finish reason: " + finishReason);
// Mistral AI-specific metadata
if (response.metadata() instanceof MistralAiChatResponseMetadata) {
MistralAiChatResponseMetadata metadata = (MistralAiChatResponseMetadata) response.metadata();
SuccessfulHttpResponse rawResponse = metadata.rawHttpResponse();
// Use for debugging or logging
}Enable the model to show its reasoning process:
MistralAiChatModel chatModel = MistralAiChatModel.builder()
.apiKey(apiKey)
.modelName(MistralAiChatModelName.MISTRAL_LARGE_LATEST)
.returnThinking(true) // Include thinking in response
.build();
ChatResponse response = chatModel.chat(
List.of(UserMessage.from("Solve: 2x + 5 = 13"))
);Control when the model should use tools:
// AUTO: Model decides when to call tools (default)
// ANY: Model must call at least one tool
// NONE: Model cannot call tools
// Note: Tool choice is controlled via LangChain4j's ToolSpecification
// and the model's behavior, not via a direct API parameterEnable additional content safety measures:
MistralAiChatModel chatModel = MistralAiChatModel.builder()
.apiKey(apiKey)
.safePrompt(true) // Enable safe prompt mode
.build();Define custom sequences that stop generation:
MistralAiChatModel chatModel = MistralAiChatModel.builder()
.apiKey(apiKey)
.stopSequences(Arrays.asList("\n\n", "END", "###"))
.build();Monitor token usage to control costs:
ChatResponse response = chatModel.chat(messages);
TokenUsage usage = response.metadata().tokenUsage();
System.out.println("Cost estimate: " + estimateCost(usage));Set max tokens to limit response length:
MistralAiChatModel chatModel = MistralAiChatModel.builder()
.apiKey(apiKey)
.maxTokens(500) // Limit to 500 tokens
.build();Handle different finish reasons:
ChatResponse response = chatModel.chat(messages);
switch (response.metadata().finishReason()) {
case STOP:
// Normal completion
processResponse(response.aiMessage().text());
break;
case LENGTH:
// Hit token limit, response may be incomplete
handleIncompleteResponse(response.aiMessage().text());
break;
case TOOL_CALLS:
// Model wants to call tools
executeTools(response.aiMessage().toolExecutionRequests());
break;
case CONTENT_FILTER:
// Content was filtered
handleContentFilter();
break;
}Manage conversation history to stay within context limits:
List<ChatMessage> conversation = new ArrayList<>();
conversation.add(SystemMessage.from("You are a helpful assistant."));
// Add messages
conversation.add(UserMessage.from("Hello"));
conversation.add(aiResponse1);
conversation.add(UserMessage.from("Tell me more"));
conversation.add(aiResponse2);
// Prune old messages if context gets too large
if (estimateTokens(conversation) > 8000) {
conversation = pruneOldMessages(conversation);
}Install with Tessl CLI
npx tessl i tessl/maven-dev-langchain4j--langchain4j-mistral-ai