LangChain4j integration for Mistral AI providing chat completion, streaming, embedding, moderation, and code completion capabilities
Comprehensive guide to builder configuration options shared across all Mistral AI models. All model classes use fluent builder patterns for configuration with common options for authentication, networking, logging, and error handling.
These configuration options are available for all model types (chat, embedding, FIM, Moderation Model, and Model Discovery).
/**
* Set the Mistral AI API key (required for all models).
*
* @param apiKey Your (non-null) Mistral AI API key from https://console.mistral.ai/
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public Builder apiKey(String apiKey) { ... }Usage:
// Hardcoded (not recommended for production)
.apiKey("your-api-key-here")
// From environment variable (recommended)
.apiKey(System.getenv("MISTRAL_API_KEY"))
// From configuration file
.apiKey(config.getString("mistral.api.key"))
// From secrets management system
.apiKey(secretsManager.getSecret("mistral-api-key"))/**
* 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 Builder baseUrl(String baseUrl) { ... }Usage:
// Default (no need to set)
// Uses: https://api.mistral.ai/v1
// Custom endpoint
.baseUrl("https://custom-endpoint.example.com/v1")
// Proxy or gateway
.baseUrl("https://api-gateway.company.com/mistral/v1")
// Local development
.baseUrl("http://localhost:8080/v1")/**
* Set request timeout duration.
* Default: 60 seconds
*
* @param timeout Duration (non-null) for request timeout
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public Builder timeout(Duration timeout) { ... }Usage:
import java.time.Duration;
// Short timeout for fast responses
.timeout(Duration.ofSeconds(30))
// Standard timeout (default)
.timeout(Duration.ofSeconds(60))
// Long timeout for complex tasks
.timeout(Duration.ofMinutes(5))
// Very long timeout for batch processing
.timeout(Duration.ofMinutes(10))/**
* Enable request logging for debugging and auditing.
*
* @param logRequests True (non-null) to log all HTTP requests
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public Builder logRequests(Boolean logRequests) { ... }
/**
* Enable response logging for debugging and auditing.
*
* @param logResponses True (non-null) to log all HTTP responses
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public Builder logResponses(Boolean logResponses) { ... }
/**
* Set custom SLF4J logger instance.
*
* @param logger SLF (non-null)4J Logger to use for logging
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public Builder logger(Logger logger) { ... }Usage:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// Enable logging for development
.logRequests(true)
.logResponses(true)
// Custom logger
.logger(LoggerFactory.getLogger("mistral.api"))
// Complete example
MistralAiChatModel chatModel = MistralAiChatModel.builder()
.apiKey(apiKey)
.logRequests(true)
.logResponses(true)
.logger(LoggerFactory.getLogger(MyClass.class))
.build();/**
* Set maximum number of retry attempts on transient failures.
* Default: 2 retries
*
* @param maxRetries Maximum (non-null) retry count (uses exponential backoff)
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public Builder maxRetries(Integer maxRetries) { ... }Usage:
// No retries (fail fast)
.maxRetries(0)
// Default retries
.maxRetries(2)
// More aggressive retries for unstable networks
.maxRetries(5)
// Maximum resilience
.maxRetries(10)/**
* Set custom HTTP client builder for advanced networking configuration.
*
* @param httpClientBuilder HttpClientBuilder (non-null) instance from langchain4j-http-client
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public Builder httpClientBuilder(HttpClientBuilder httpClientBuilder) { ... }Usage:
import dev.langchain4j.http.client.HttpClientBuilder;
// Custom HTTP client with proxy
HttpClientBuilder customClient = // ... your custom implementation
MistralAiChatModel chatModel = MistralAiChatModel.builder()
.apiKey(apiKey)
.httpClientBuilder(customClient)
.build();Additional configuration options available only for chat models (both synchronous and streaming).
/**
* Set the chat model name using enum.
*
* @param modelName MistralAiChatModelName (non-null) enum value
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public Builder modelName(MistralAiChatModelName modelName) { ... }
/**
* Set the chat model name using string.
*
* @param modelName Model (non-null) identifier string
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public Builder modelName(String modelName) { ... }Usage:
import dev.langchain4j.model.mistralai.MistralAiChatModelName;
// Using enum (type-safe, recommended)
.modelName(MistralAiChatModelName.MISTRAL_LARGE_LATEST)
.modelName(MistralAiChatModelName.MISTRAL_SMALL_LATEST)
.modelName(MistralAiChatModelName.CODESTRAL_LATEST)
// Using string (for custom or new models)
.modelName("mistral-large-2407")
.modelName("custom-model-name")/**
* Set sampling temperature (0.0 to 1.0).
* Higher values increase randomness, lower values increase determinism.
* Default: 0.7
*
* @param temperature Temperature (non-null) value
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public Builder temperature(Double temperature) { ... }
/**
* Set top-p nucleus sampling parameter (0.0 to 1.0).
* Alternative to temperature for controlling randomness.
*
* @param topP Top (non-null)-p value
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public Builder topP(Double topP) { ... }Usage:
// Highly deterministic (factual Q&A)
.temperature(0.0)
// Low creativity (data extraction, classification)
.temperature(0.3)
// Balanced (default, general chat)
.temperature(0.7)
// High creativity (storytelling, brainstorming)
.temperature(0.9)
// Maximum randomness (experimental)
.temperature(1.0)
// Nucleus sampling (alternative to temperature)
.topP(0.9)/**
* Set maximum number of tokens to generate.
*
* @param maxTokens Maximum (non-null) token count for completion
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public Builder maxTokens(Integer maxTokens) { ... }
/**
* Set custom stop sequences to terminate generation.
*
* @param stopSequences List (non-null) of strings that stop generation when encountered
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public Builder stopSequences(List<String> stopSequences) { ... }Important Note on Stop Sequences:
Chat models (MistralAiChatModel and MistralAiStreamingChatModel) use the method name stopSequences(List<String>), while FIM models (MistralAiFimModel and MistralAiStreamingFimModel) use the method name stop(List<String>). Both methods serve the same purpose of setting stop tokens to terminate generation, but have different method names in their respective builder APIs.
Usage:
import java.util.Arrays;
// Limit response length
.maxTokens(100) // Short responses
.maxTokens(500) // Medium responses
.maxTokens(2000) // Long responses
// Custom stop sequences (for chat models)
.stopSequences(Arrays.asList("\n\n", "END", "###"))
.stopSequences(Arrays.asList("Human:", "AI:"))
// For FIM models, use .stop() instead:
// .stop(Arrays.asList("\n\n", "END", "###"))/**
* Set frequency penalty (-2.0 to 2.0).
* Positive values reduce repetition of token sequences.
*
* @param frequencyPenalty Frequency (non-null) penalty value
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public Builder frequencyPenalty(Double frequencyPenalty) { ... }
/**
* Set presence penalty (-2.0 to 2.0).
* Positive values encourage new topics.
*
* @param presencePenalty Presence (non-null) penalty value
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public Builder presencePenalty(Double presencePenalty) { ... }Usage:
// Reduce repetition
.frequencyPenalty(0.5)
// Strong anti-repetition
.frequencyPenalty(1.0)
// Encourage topic diversity
.presencePenalty(0.6)
// Combined
.frequencyPenalty(0.5)
.presencePenalty(0.5)/**
* Set response format (text or JSON object with schema).
* 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 Builder responseFormat(ResponseFormat responseFormat) { ... }Usage:
import dev.langchain4j.model.chat.request.ResponseFormat;
import dev.langchain4j.model.chat.request.ResponseFormatType;
import dev.langchain4j.model.chat.request.json.JsonSchema;
import java.util.Map;
// JSON object response
ResponseFormat jsonFormat = ResponseFormat.builder()
.type(ResponseFormatType.JSON)
.build();
.responseFormat(jsonFormat)
// Or use the constant:
.responseFormat(ResponseFormat.JSON)
// JSON with schema
Map<String, Object> schema = Map.of(
"type", "object",
"properties", Map.of(
"name", Map.of("type", "string"),
"age", Map.of("type", "number")
),
"required", List.of("name")
);
ResponseFormat schemaFormat = ResponseFormat.builder()
.type(ResponseFormatType.JSON)
.jsonSchema(JsonSchema.builder()
.name("person")
.schema(schema)
.strict(true)
.build())
.build();
.responseFormat(schemaFormat)/**
* Enable safe prompt mode for additional content safety.
*
* @param safePrompt True (non-null) to enable
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public Builder safePrompt(Boolean safePrompt) { ... }
/**
* Set random seed for reproducible outputs.
*
* @param randomSeed Integer (non-null) seed value
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public Builder randomSeed(Integer randomSeed) { ... }
/**
* Include thinking/reasoning content in response.
*
* @param returnThinking True (non-null) to include thinking
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public Builder returnThinking(Boolean returnThinking) { ... }
/**
* Send thinking/reasoning content to model.
*
* @param sendThinking True (non-null) to send thinking
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public Builder sendThinking(Boolean sendThinking) { ... }Usage:
// Content safety
.safePrompt(true)
// Reproducible outputs
.randomSeed(42)
// Include reasoning
.returnThinking(true)
.sendThinking(true)/**
* Set chat model listeners for monitoring and observability.
*
* @param listeners List (non-null) of ChatModelListener instances
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public Builder listeners(List<ChatModelListener> listeners) { ... }
/**
* Set default request parameters.
*
* @param defaultRequestParameters ChatRequestParameters (non-null) with defaults
* @return Builder instance
* @throws IllegalArgumentException if parameter validation fails
*/
public Builder defaultRequestParameters(ChatRequestParameters defaultRequestParameters) { ... }Usage:
import dev.langchain4j.model.chat.listener.ChatModelListener;
import java.util.List;
// Custom listener
ChatModelListener metricsListener = new ChatModelListener() {
@Override
public void onRequest(ChatModelRequestContext context) {
// Log or monitor request
}
@Override
public void onResponse(ChatModelResponseContext context) {
// Log or monitor response
}
@Override
public void onError(ChatModelErrorContext context) {
// Handle errors
}
};
.listeners(List.of(metricsListener))MistralAiChatModel devModel = MistralAiChatModel.builder()
.apiKey(System.getenv("MISTRAL_API_KEY"))
.modelName(MistralAiChatModelName.MISTRAL_SMALL_LATEST)
.temperature(0.7)
.maxTokens(500)
.timeout(Duration.ofSeconds(30))
.logRequests(true)
.logResponses(true)
.maxRetries(1)
.build();MistralAiChatModel prodModel = MistralAiChatModel.builder()
.apiKey(secretsManager.getSecret("mistral-api-key"))
.modelName(MistralAiChatModelName.MISTRAL_LARGE_LATEST)
.temperature(0.5)
.maxTokens(1000)
.timeout(Duration.ofMinutes(2))
.logRequests(false)
.logResponses(false)
.maxRetries(3)
.listeners(List.of(metricsListener, auditListener))
.build();MistralAiChatModel haModel = MistralAiChatModel.builder()
.apiKey(apiKey)
.baseUrl(loadBalancedEndpoint)
.modelName(MistralAiChatModelName.MISTRAL_LARGE_LATEST)
.timeout(Duration.ofMinutes(5))
.maxRetries(5)
.httpClientBuilder(resilientHttpClient)
.listeners(List.of(failoverListener, metricsListener))
.build();MistralAiChatModel costOptimized = MistralAiChatModel.builder()
.apiKey(apiKey)
.modelName(MistralAiChatModelName.MISTRAL_SMALL_LATEST)
.temperature(0.3)
.maxTokens(200) // Limit token usage
.timeout(Duration.ofSeconds(30))
.maxRetries(2)
.build();MistralAiChatModel deterministic = MistralAiChatModel.builder()
.apiKey(apiKey)
.modelName(MistralAiChatModelName.MISTRAL_LARGE_LATEST)
.temperature(0.0) // Maximum determinism
.randomSeed(42) // Reproducible outputs
.maxTokens(500)
.build();@Configuration
public class MistralAiConfig {
@Bean
public MistralAiChatModel chatModel(
@Value("${mistral.api.key}") String apiKey,
@Value("${mistral.model.name}") String modelName,
@Value("${mistral.temperature:0.7}") Double temperature,
@Value("${mistral.max-tokens:1000}") Integer maxTokens,
@Value("${mistral.timeout:60}") Integer timeoutSeconds,
@Value("${mistral.max-retries:2}") Integer maxRetries) {
return MistralAiChatModel.builder()
.apiKey(apiKey)
.modelName(modelName)
.temperature(temperature)
.maxTokens(maxTokens)
.timeout(Duration.ofSeconds(timeoutSeconds))
.maxRetries(maxRetries)
.build();
}
}application.properties:
mistral.api.key=${MISTRAL_API_KEY}
mistral.model.name=mistral-large-latest
mistral.temperature=0.7
mistral.max-tokens=1000
mistral.timeout=60
mistral.max-retries=2public class MistralAiConfigBuilder {
private final Properties props;
public MistralAiConfigBuilder(Properties props) {
this.props = props;
}
public MistralAiChatModel buildChatModel() {
return MistralAiChatModel.builder()
.apiKey(props.getProperty("mistral.api.key"))
.modelName(props.getProperty("mistral.model.name", "mistral-large-latest"))
.temperature(Double.parseDouble(props.getProperty("mistral.temperature", "0.7")))
.maxTokens(Integer.parseInt(props.getProperty("mistral.max-tokens", "1000")))
.timeout(Duration.ofSeconds(
Long.parseLong(props.getProperty("mistral.timeout", "60"))))
.maxRetries(Integer.parseInt(props.getProperty("mistral.max-retries", "2")))
.logRequests(Boolean.parseBoolean(props.getProperty("mistral.log-requests", "false")))
.logResponses(Boolean.parseBoolean(props.getProperty("mistral.log-responses", "false")))
.build();
}
}
// Usage
Properties props = new Properties();
props.load(new FileInputStream("config.properties"));
MistralAiConfigBuilder configBuilder = new MistralAiConfigBuilder(props);
MistralAiChatModel chatModel = configBuilder.buildChatModel();public class EnvironmentAwareConfig {
public static MistralAiChatModel createChatModel() {
String environment = System.getenv("ENV");
return switch (environment != null ? environment : "dev") {
case "prod" -> productionConfig();
case "staging" -> stagingConfig();
default -> developmentConfig();
};
}
private static MistralAiChatModel productionConfig() {
return MistralAiChatModel.builder()
.apiKey(System.getenv("MISTRAL_API_KEY"))
.modelName(MistralAiChatModelName.MISTRAL_LARGE_LATEST)
.temperature(0.5)
.maxTokens(1000)
.timeout(Duration.ofMinutes(2))
.maxRetries(5)
.logRequests(false)
.logResponses(false)
.build();
}
private static MistralAiChatModel stagingConfig() {
return MistralAiChatModel.builder()
.apiKey(System.getenv("MISTRAL_API_KEY"))
.modelName(MistralAiChatModelName.MISTRAL_MEDIUM_LATEST)
.temperature(0.7)
.maxTokens(800)
.timeout(Duration.ofSeconds(90))
.maxRetries(3)
.logRequests(true)
.logResponses(true)
.build();
}
private static MistralAiChatModel developmentConfig() {
return MistralAiChatModel.builder()
.apiKey(System.getenv("MISTRAL_API_KEY"))
.modelName(MistralAiChatModelName.MISTRAL_SMALL_LATEST)
.temperature(0.7)
.maxTokens(500)
.timeout(Duration.ofSeconds(30))
.maxRetries(1)
.logRequests(true)
.logResponses(true)
.build();
}
}public class ConfigurationValidator {
public static void validateChatModelConfig(MistralAiChatModel.MistralAiChatModelBuilder builder) {
// Validate required fields
if (builder.apiKey == null || builder.apiKey.isEmpty()) {
throw new IllegalArgumentException("API key is required");
}
// Validate temperature range
if (builder.temperature != null &&
(builder.temperature < 0.0 || builder.temperature > 1.0)) {
throw new IllegalArgumentException("Temperature must be between 0.0 and 1.0");
}
// Validate maxTokens
if (builder.maxTokens != null && builder.maxTokens <= 0) {
throw new IllegalArgumentException("maxTokens must be positive");
}
// Validate timeout
if (builder.timeout != null && builder.timeout.isNegative()) {
throw new IllegalArgumentException("Timeout cannot be negative");
}
}
}API Key Security
Timeouts
Retries
Logging
Model Selection
Sampling Parameters
Install with Tessl CLI
npx tessl i tessl/maven-dev-langchain4j--langchain4j-mistral-ai