Quarkus extension for Azure OpenAI integration with LangChain4j, providing ChatModel, StreamingChatModel, EmbeddingModel, and ImageModel implementations with Azure-specific authentication and configuration support.
The Quarkus LangChain4j Azure OpenAI extension provides comprehensive configuration options through Quarkus's declarative configuration system. All configuration is done via application.properties with the prefix quarkus.langchain4j.azure-openai.
The extension uses several configuration interfaces that map to properties in application.properties. Configuration is split into runtime and build-time interfaces.
Runtime configuration is accessed via application.properties and can be modified between application runs:
package io.quarkiverse.langchain4j.azure.openai.runtime.config;
@ConfigRoot(phase = RUN_TIME)
@ConfigMapping(prefix = "quarkus.langchain4j.azure-openai")
public interface LangChain4jAzureOpenAiConfig {
/**
* Default configuration (no name qualifier).
*/
AzureAiConfig defaultConfig();
/**
* Named configurations for multiple model instances.
* Key is the model name used with @ModelName qualifier.
*/
Map<String, AzureAiConfig> namedConfig();
}Main configuration group for all Azure OpenAI settings:
public interface AzureAiConfig {
// Endpoint Configuration
Optional<String> resourceName();
Optional<String> domainName(); // Default: "openai.azure.com"
Optional<String> deploymentName();
Optional<String> endpoint();
// Authentication
Optional<String> apiKey();
Optional<String> adToken();
String apiVersion(); // Default: "2024-10-21"
// Network Settings
Optional<Duration> timeout(); // Default: 10s
Integer maxRetries(); // Default: 1
String proxyType(); // Default: "HTTP"
Optional<String> proxyHost();
Integer proxyPort(); // Default: 3128
// Logging
Optional<Boolean> logRequests(); // Default: false
Optional<Boolean> logResponses(); // Default: false
Optional<Boolean> logRequestsCurl(); // Default: false
// Integration Control
Boolean enableIntegration(); // Default: true
// Model-specific Configurations
ChatModelConfig chatModel();
EmbeddingModelConfig embeddingModel();
ImageModelConfig imageModel();
// Helper methods for model-type specific configuration
Optional<String> domainNameFor(EndpointType type);
Optional<String> endPointFor(EndpointType type);
Optional<String> resourceNameFor(EndpointType type);
Optional<String> deploymentNameFor(EndpointType type);
enum EndpointType {
CHAT, EMBEDDING, IMAGE
}
}Chat model specific configuration:
package io.quarkiverse.langchain4j.azure.openai.runtime.config;
public interface ChatModelConfig {
// Endpoint overrides for chat models
Optional<String> resourceName();
Optional<String> domainName();
Optional<String> deploymentName();
Optional<String> endpoint();
// Authentication overrides
Optional<String> adToken();
Optional<String> apiVersion();
Optional<String> apiKey();
// Chat-specific parameters
Double temperature(); // Default: 1.0
Double topP(); // Default: 1.0
Optional<Integer> seed();
Optional<Integer> maxTokens();
Double presencePenalty(); // Default: 0
Double frequencyPenalty(); // Default: 0
Optional<String> responseFormat();
// Logging
Optional<Boolean> logRequests();
Optional<Boolean> logResponses();
}Embedding model specific configuration:
package io.quarkiverse.langchain4j.azure.openai.runtime.config;
public interface EmbeddingModelConfig {
// Endpoint overrides for embedding models
Optional<String> resourceName();
Optional<String> domainName();
Optional<String> deploymentName();
Optional<String> endpoint();
// Authentication overrides
Optional<String> adToken();
Optional<String> apiVersion();
Optional<String> apiKey();
// Logging
Optional<Boolean> logRequests();
Optional<Boolean> logResponses();
}Image model specific configuration:
package io.quarkiverse.langchain4j.azure.openai.runtime.config;
public interface ImageModelConfig {
// Endpoint overrides for image models
Optional<String> resourceName();
Optional<String> domainName();
Optional<String> deploymentName();
Optional<String> endpoint();
// Authentication overrides
Optional<String> adToken();
Optional<String> apiVersion();
Optional<String> apiKey();
// Image generation parameters
String modelName(); // Default: "dall-e-3"
String size(); // Default: "1024x1024"
String quality(); // Default: "standard"
String style(); // Default: "vivid"
int number(); // Default: 1
String responseFormat(); // Default: "url"
Optional<String> user();
// Persistence settings
Optional<Boolean> persist(); // Default: false
Optional<Path> persistDirectory(); // Default: ${java.io.tmpdir}/dall-e-images
// Logging
Optional<Boolean> logRequests();
Optional<Boolean> logResponses();
}Build-time configuration is processed during application build and determines which model types are enabled. These configurations require a rebuild to take effect:
package io.quarkiverse.langchain4j.azure.openai.deployment;
@ConfigRoot(phase = BUILD_TIME)
@ConfigMapping(prefix = "quarkus.langchain4j.azure-openai")
public interface LangChain4jAzureOpenAiBuildConfig {
/**
* Chat model build-time configuration.
*/
ChatModelBuildConfig chatModel();
/**
* Embedding model build-time configuration.
*/
EmbeddingModelBuildConfig embeddingModel();
/**
* Image model build-time configuration.
*/
ImageModelBuildConfig imageModel();
/**
* Moderation model build-time configuration.
*/
ModerationModelBuildConfig moderationModel();
}package io.quarkiverse.langchain4j.azure.openai.deployment;
public interface ChatModelBuildConfig {
/**
* Whether to enable chat model support at build time.
* Default: true
*/
Optional<Boolean> enabled();
}package io.quarkiverse.langchain4j.azure.openai.deployment;
public interface EmbeddingModelBuildConfig {
/**
* Whether to enable embedding model support at build time.
* Default: true
*/
Optional<Boolean> enabled();
}package io.quarkiverse.langchain4j.azure.openai.deployment;
public interface ImageModelBuildConfig {
/**
* Whether to enable image model support at build time.
* Default: true
*/
Optional<Boolean> enabled();
}package io.quarkiverse.langchain4j.azure.openai.deployment;
public interface ModerationModelBuildConfig {
/**
* Whether to enable moderation model support at build time.
* Default: true
*/
Optional<Boolean> enabled();
}Build-Time Configuration Example:
To disable specific model types at build time, add to application.properties:
# Disable image model support at build time
quarkus.langchain4j.azure-openai.image-model.enabled=false
# Disable embedding model support at build time
quarkus.langchain4j.azure-openai.embedding-model.enabled=falseNote: Build-time configuration changes require a full rebuild of the application. Disabling a model type at build time reduces the application's footprint and startup time by excluding unnecessary CDI beans and dependencies.
Minimal configuration to get started:
# Required: Authentication (choose one)
quarkus.langchain4j.azure-openai.api-key=your-api-key
# Required: Endpoint (choose one method)
# Method 1: Composite endpoint (recommended)
quarkus.langchain4j.azure-openai.resource-name=my-azure-resource
quarkus.langchain4j.azure-openai.deployment-name=my-gpt-4-deployment
# Method 2: Direct endpoint URL
# quarkus.langchain4j.azure-openai.endpoint=https://my-resource.openai.azure.com/openai/deployments/my-deployment
# Optional: API version (defaults to 2024-10-21)
quarkus.langchain4j.azure-openai.api-version=2024-10-21Full configuration with all available options:
# ========== Core Configuration ==========
# Endpoint configuration - Composite method
quarkus.langchain4j.azure-openai.resource-name=my-resource
quarkus.langchain4j.azure-openai.domain-name=openai.azure.com
quarkus.langchain4j.azure-openai.deployment-name=gpt-4
# Or direct endpoint
# quarkus.langchain4j.azure-openai.endpoint=https://my-resource.openai.azure.com/openai/deployments/gpt-4
# Authentication (choose one)
quarkus.langchain4j.azure-openai.api-key=your-api-key
# quarkus.langchain4j.azure-openai.ad-token=your-azure-ad-token
# API version
quarkus.langchain4j.azure-openai.api-version=2024-10-21
# ========== Network Settings ==========
# Timeout for API calls
quarkus.langchain4j.azure-openai.timeout=60s
# Retry configuration
quarkus.langchain4j.azure-openai.max-retries=3
# Proxy configuration
quarkus.langchain4j.azure-openai.proxy-type=HTTP
quarkus.langchain4j.azure-openai.proxy-host=proxy.example.com
quarkus.langchain4j.azure-openai.proxy-port=8080
# ========== Logging ==========
# Request/response logging
quarkus.langchain4j.azure-openai.log-requests=true
quarkus.langchain4j.azure-openai.log-responses=true
quarkus.langchain4j.azure-openai.log-requests-curl=true
# ========== Chat Model Configuration ==========
# Override endpoint for chat models
quarkus.langchain4j.azure-openai.chat-model.deployment-name=gpt-4-turbo
# Sampling parameters
quarkus.langchain4j.azure-openai.chat-model.temperature=0.7
quarkus.langchain4j.azure-openai.chat-model.top-p=1.0
quarkus.langchain4j.azure-openai.chat-model.seed=42
# Response control
quarkus.langchain4j.azure-openai.chat-model.max-tokens=2000
quarkus.langchain4j.azure-openai.chat-model.presence-penalty=0.1
quarkus.langchain4j.azure-openai.chat-model.frequency-penalty=0.1
quarkus.langchain4j.azure-openai.chat-model.response-format=json_object
# Chat-specific logging
quarkus.langchain4j.azure-openai.chat-model.log-requests=true
quarkus.langchain4j.azure-openai.chat-model.log-responses=true
# ========== Embedding Model Configuration ==========
# Override endpoint for embedding models
quarkus.langchain4j.azure-openai.embedding-model.deployment-name=text-embedding-ada-002
# Embedding-specific logging
quarkus.langchain4j.azure-openai.embedding-model.log-requests=false
quarkus.langchain4j.azure-openai.embedding-model.log-responses=false
# ========== Image Model Configuration ==========
# Override endpoint for image models
quarkus.langchain4j.azure-openai.image-model.deployment-name=dall-e-3
# Image generation parameters
quarkus.langchain4j.azure-openai.image-model.model-name=dall-e-3
quarkus.langchain4j.azure-openai.image-model.size=1024x1024
quarkus.langchain4j.azure-openai.image-model.quality=hd
quarkus.langchain4j.azure-openai.image-model.style=vivid
quarkus.langchain4j.azure-openai.image-model.number=1
quarkus.langchain4j.azure-openai.image-model.response-format=url
# Image persistence
quarkus.langchain4j.azure-openai.image-model.persist=true
quarkus.langchain4j.azure-openai.image-model.persist-directory=/var/generated-images
# Optional user identifier
quarkus.langchain4j.azure-openai.image-model.user=user-123
# Image-specific logging
quarkus.langchain4j.azure-openai.image-model.log-requests=true
quarkus.langchain4j.azure-openai.image-model.log-responses=true
# ========== Integration Control ==========
# Disable the extension entirely
# quarkus.langchain4j.azure-openai.enable-integration=falseConfigure multiple independent model instances:
# ========== Default Configuration ==========
quarkus.langchain4j.azure-openai.api-key=default-key
quarkus.langchain4j.azure-openai.resource-name=default-resource
quarkus.langchain4j.azure-openai.deployment-name=gpt-4
quarkus.langchain4j.azure-openai.chat-model.temperature=0.5
# ========== "creative" Configuration ==========
quarkus.langchain4j.azure-openai.creative.api-key=creative-key
quarkus.langchain4j.azure-openai.creative.resource-name=creative-resource
quarkus.langchain4j.azure-openai.creative.deployment-name=gpt-4
quarkus.langchain4j.azure-openai.creative.chat-model.temperature=0.9
quarkus.langchain4j.azure-openai.creative.chat-model.max-tokens=2000
# ========== "analytical" Configuration ==========
quarkus.langchain4j.azure-openai.analytical.api-key=analytical-key
quarkus.langchain4j.azure-openai.analytical.resource-name=analytical-resource
quarkus.langchain4j.azure-openai.analytical.deployment-name=gpt-4
quarkus.langchain4j.azure-openai.analytical.chat-model.temperature=0.1
quarkus.langchain4j.azure-openai.analytical.chat-model.max-tokens=1000
# ========== "embeddings" Configuration ==========
quarkus.langchain4j.azure-openai.embeddings.api-key=embeddings-key
quarkus.langchain4j.azure-openai.embeddings.resource-name=embeddings-resource
quarkus.langchain4j.azure-openai.embeddings.embedding-model.deployment-name=text-embedding-ada-002
# ========== "image-gen" Configuration ==========
quarkus.langchain4j.azure-openai.image-gen.api-key=image-key
quarkus.langchain4j.azure-openai.image-gen.resource-name=image-resource
quarkus.langchain4j.azure-openai.image-gen.image-model.deployment-name=dall-e-3
quarkus.langchain4j.azure-openai.image-gen.image-model.quality=hdUse profiles for different environments:
# ========== Development (default) ==========
%dev.quarkus.langchain4j.azure-openai.api-key=dev-api-key
%dev.quarkus.langchain4j.azure-openai.resource-name=dev-resource
%dev.quarkus.langchain4j.azure-openai.deployment-name=gpt-3-5-turbo
%dev.quarkus.langchain4j.azure-openai.log-requests=true
%dev.quarkus.langchain4j.azure-openai.log-responses=true
# ========== Test ==========
%test.quarkus.langchain4j.azure-openai.api-key=test-api-key
%test.quarkus.langchain4j.azure-openai.resource-name=test-resource
%test.quarkus.langchain4j.azure-openai.deployment-name=gpt-3-5-turbo
%test.quarkus.langchain4j.azure-openai.max-retries=1
# ========== Production ==========
%prod.quarkus.langchain4j.azure-openai.api-key=${AZURE_OPENAI_API_KEY}
%prod.quarkus.langchain4j.azure-openai.resource-name=prod-resource
%prod.quarkus.langchain4j.azure-openai.deployment-name=gpt-4
%prod.quarkus.langchain4j.azure-openai.timeout=120s
%prod.quarkus.langchain4j.azure-openai.max-retries=3
%prod.quarkus.langchain4j.azure-openai.log-requests=false
%prod.quarkus.langchain4j.azure-openai.log-responses=falseConfigure different endpoints for different model types:
# Global settings
quarkus.langchain4j.azure-openai.api-key=global-key
quarkus.langchain4j.azure-openai.resource-name=my-resource
# Chat models use gpt-4 deployment
quarkus.langchain4j.azure-openai.chat-model.deployment-name=gpt-4-deployment
# Embedding models use a different deployment
quarkus.langchain4j.azure-openai.embedding-model.deployment-name=embeddings-deployment
# Image models use yet another deployment
quarkus.langchain4j.azure-openai.image-model.deployment-name=dalle-deploymentThe configuration automatically integrates with Quarkus CDI, allowing dependency injection of models.
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.image.ImageModel;
import jakarta.inject.Inject;
public class AiService {
@Inject
ChatModel chatModel; // Uses default configuration
@Inject
StreamingChatModel streamingChatModel; // Uses default configuration
@Inject
EmbeddingModel embeddingModel; // Uses default configuration
@Inject
ImageModel imageModel; // Uses default configuration
}import io.quarkiverse.langchain4j.ModelName;
public class AiService {
@Inject
@ModelName("creative")
ChatModel creativeChat;
@Inject
@ModelName("analytical")
ChatModel analyticalChat;
@Inject
@ModelName("embeddings")
EmbeddingModel embeddingModel;
@Inject
@ModelName("image-gen")
ImageModel imageModel;
}import io.quarkiverse.langchain4j.RegisterAiService;
@RegisterAiService(modelName = "creative")
public interface CreativeAssistant {
String writePoem(String topic);
}
@RegisterAiService(modelName = "analytical")
public interface AnalyticalAssistant {
String analyzeData(String data);
}Configuration follows a hierarchical priority system:
Model-type specific configuration (highest priority)
chat-model.api-key, embedding-model.endpointGlobal configuration
api-key, endpoint, timeoutDefault values (lowest priority)
Example:
# Global API key (used by all models unless overridden)
quarkus.langchain4j.azure-openai.api-key=global-key
# Chat model uses its own key (overrides global)
quarkus.langchain4j.azure-openai.chat-model.api-key=chat-specific-key
# Embedding model uses global key
# (no embedding-model.api-key specified)
# Global timeout
quarkus.langchain4j.azure-openai.timeout=30s
# All models use global timeout unless individually overriddenTo disable the extension without removing configuration:
quarkus.langchain4j.azure-openai.enable-integration=falseWhen disabled, all injected models will be replaced with "Disabled" implementations that throw exceptions if used.
Use environment variables for sensitive values:
quarkus.langchain4j.azure-openai.api-key=${AZURE_OPENAI_API_KEY}
quarkus.langchain4j.azure-openai.ad-token=${AZURE_AD_TOKEN}Set environment variables:
export AZURE_OPENAI_API_KEY=your-api-key
export AZURE_AD_TOKEN=your-ad-tokenThe extension validates configuration at startup:
api-key or ad-token must be providedendpoint OR (resource-name AND deployment-name) must be providedInvalid configurations will cause startup failure with descriptive error messages.
Use named configurations for failover:
@Inject
@ModelName("primary")
ChatModel primaryModel;
@Inject
@ModelName("backup")
ChatModel backupModel;
public String chat(String message) {
try {
return primaryModel.generate(message);
} catch (Exception e) {
logger.warn("Primary model failed, using backup", e);
return backupModel.generate(message);
}
}# Model A - Conservative
quarkus.langchain4j.azure-openai.model-a.chat-model.temperature=0.3
# Model B - Creative
quarkus.langchain4j.azure-openai.model-b.chat-model.temperature=0.9public String abTestChat(String message, boolean useModelB) {
ChatModel model = useModelB ? modelB : modelA;
return model.generate(message);
}# Cheap model for simple tasks
quarkus.langchain4j.azure-openai.cheap.deployment-name=gpt-3-5-turbo
quarkus.langchain4j.azure-openai.cheap.chat-model.max-tokens=500
# Expensive model for complex tasks
quarkus.langchain4j.azure-openai.premium.deployment-name=gpt-4
quarkus.langchain4j.azure-openai.premium.chat-model.max-tokens=2000"<dummy>" as a default sentinel value - these are filtered out internallyopenai.azure.com if not specified2024-10-21, the latest stable versionInstall with Tessl CLI
npx tessl i tessl/maven-io-quarkiverse-langchain4j--quarkus-langchain4j-azure-openai