CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-quarkiverse-langchain4j--quarkus-langchain4j-core-deployment

Quarkus deployment extension for LangChain4j integration providing build-time processing, BuildItem APIs, and configuration for integrating Large Language Models into Quarkus applications

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

Quarkus LangChain4j Core Deployment Extension

Package Overview

The quarkus-langchain4j-core-deployment module is a Quarkus deployment extension that provides build-time processing for LangChain4j integration. This module runs exclusively at build time and enables other Quarkus extensions to integrate LangChain4j capabilities into their applications.

Package: io.quarkiverse.langchain4j.deployment Type: Quarkus Deployment Extension Language: Java (Maven) Group ID: io.quarkiverse.langchain4j Artifact ID: quarkus-langchain4j-core-deployment Version: 1.7.4

Maven Dependency

To use this deployment extension in your Quarkus extension, add the following dependency:

<dependency>
    <groupId>io.quarkiverse.langchain4j</groupId>
    <artifactId>quarkus-langchain4j-core-deployment</artifactId>
    <version>1.7.4</version>
</dependency>

Purpose

This deployment module enables Quarkus extensions to:

  • Register AI model providers (chat, embedding, image, moderation, scoring models)
  • Configure AI services declaratively using @RegisterAiService
  • Discover and register tools for AI agents
  • Configure build-time behavior for LangChain4j components
  • Integrate with Quarkus DevServices for local model inference
  • Process guardrails for input/output validation
  • Configure chat memory providers
  • Enable observability (metrics and tracing) for AI services

Core Concepts

Quarkus Build-Time Architecture

Quarkus follows a build-time/runtime split architecture:

  • Build Time: Code analysis, configuration resolution, bytecode generation, native image preparation
  • Runtime: Optimized application execution with pre-computed metadata

This deployment module runs at build time and uses the following key abstractions:

BuildItem

BuildItems are data carriers used in the Quarkus build step chain. They are the primary API for communication between extensions during the build process.

  • MultiBuildItem: Multiple instances can be produced (e.g., multiple model providers)
  • SimpleBuildItem: Single instance per build (e.g., consolidated metadata)

BuildStep

Methods annotated with @BuildStep that execute during the build process. BuildSteps:

  • Consume BuildItems as method parameters
  • Produce BuildItems via BuildProducer<T> parameters
  • Execute in dependency order based on BuildItem consumption/production

BuildProducer

A parameter type used in BuildStep methods to produce BuildItems:

@BuildStep
void myBuildStep(BuildProducer<MyBuildItem> producer) {
    producer.produce(new MyBuildItem(...));
}

BuildConsumer

Implicitly used when a BuildStep method accepts a BuildItem as a parameter:

@BuildStep
void myBuildStep(MyBuildItem item) {
    // Consume the BuildItem
}

Basic Usage Example

Here's a simple processor that registers a custom chat model provider:

package com.example.deployment;

import io.quarkiverse.langchain4j.deployment.items.ChatModelProviderCandidateBuildItem;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;

public class MyModelProcessor {

    @BuildStep
    public void registerChatModelProvider(
            BuildProducer<ChatModelProviderCandidateBuildItem> chatModelProvider) {

        // Register "my-provider" as a candidate chat model provider
        chatModelProvider.produce(
            new ChatModelProviderCandidateBuildItem("my-provider")
        );
    }
}

Architecture Overview

The deployment extension follows a multi-phase build process:

  1. Discovery Phase: Extensions register model provider candidates
  2. Selection Phase: Core module selects providers based on configuration
  3. Bean Creation Phase: CDI beans are synthesized for selected providers
  4. AI Service Phase: AI services are created with tools and guardrails
  5. DevServices Phase: Optional local inference servers are started (dev/test mode)

Core Import Classes

// BuildItem base classes
import io.quarkus.builder.item.MultiBuildItem;
import io.quarkus.builder.item.SimpleBuildItem;

// Build step annotations
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.annotations.ExecutionTime;

// Configuration
import io.quarkiverse.langchain4j.deployment.config.LangChain4jBuildConfig;

// Common BuildItems
import io.quarkiverse.langchain4j.deployment.items.ChatModelProviderCandidateBuildItem;
import io.quarkiverse.langchain4j.deployment.items.SelectedChatModelProviderBuildItem;
import io.quarkiverse.langchain4j.deployment.DeclarativeAiServiceBuildItem;

// Utility classes
import io.quarkiverse.langchain4j.deployment.DotNames;
import io.quarkiverse.langchain4j.deployment.LangChain4jDotNames;

API Categories

The deployment extension provides 73 public API elements organized into the following categories:

1. BuildItems (37 classes)

BuildItems are the primary extension API. See BuildItems Documentation for complete details.

Key BuildItems:

  • Model Providers: Register and select model providers
    • ChatModelProviderCandidateBuildItem - Register chat model provider
    • SelectedChatModelProviderBuildItem - Access selected provider
    • Similar items for embedding, image, moderation, and scoring models

Example: Registering a model provider

@BuildStep
void registerProvider(BuildProducer<ChatModelProviderCandidateBuildItem> producer) {
    producer.produce(new ChatModelProviderCandidateBuildItem("openai"));
}
  • AI Services: Configure declarative AI services
    • DeclarativeAiServiceBuildItem - AI service metadata from @RegisterAiService

Example: Consuming AI service metadata

@BuildStep
void processAiServices(List<DeclarativeAiServiceBuildItem> aiServices) {
    for (DeclarativeAiServiceBuildItem service : aiServices) {
        String modelName = service.getChatModelName();
        // Process service configuration
    }
}
  • Tools: Tool discovery and metadata

    • ToolMethodBuildItem - Methods annotated with @Tool
    • ToolsMetadataBuildItem - Consolidated tool metadata
  • Behavior Customization: Control extension behavior

    • RequestChatModelBeanBuildItem - Force bean creation
    • AnnotationsImpliesAiServiceBuildItem - Custom AI service detection
    • SkipOutputFormatInstructionsBuildItem - Control output formatting

See BuildItems Documentation for all 37 BuildItem classes.

2. Processors (12 classes)

Processors contain @BuildStep methods that execute during the build. See Processors Documentation.

Key Processors:

  • AiServicesProcessor - Main AI service registration
  • BeansProcessor - Model provider selection and bean creation
  • ToolProcessor - Tool discovery and validation
  • ChatMemoryProcessor - Chat memory provider setup
  • InProcessEmbeddingProcessor - Local embedding models

See Processors Documentation for all processors and build step patterns.

3. Configuration (7 classes)

Build-time configuration classes using SmallRye Config. See Configuration Documentation.

Root Configuration:

@ConfigRoot(phase = BUILD_TIME)
@ConfigMapping(prefix = "quarkus.langchain4j")
public interface LangChain4jBuildConfig {
    BaseConfig defaultConfig();
    Map<String, BaseConfig> namedConfig();
    DevServicesConfig devservices();
    boolean responseSchema();
}

Example: Accessing configuration in a BuildStep

@BuildStep
void useConfig(LangChain4jBuildConfig config) {
    boolean devServicesEnabled = config.devservices().enabled();
    String provider = config.defaultConfig().chatModel().provider().orElse("default");
}

See Configuration Documentation for all configuration classes.

4. Utilities (8 classes)

Utility classes for common tasks. See Utilities Documentation.

Key Utilities:

  • DotNames - Constants for common Java types (50+ DotName constants)
  • LangChain4jDotNames - Constants for LangChain4j types (100+ constants)
  • TemplateUtil - Template parsing and validation
  • MethodUtil - Method signature utilities
  • HashUtil - SHA-1 hashing

Example: Using DotNames

import io.quarkiverse.langchain4j.deployment.DotNames;
import io.quarkiverse.langchain4j.deployment.LangChain4jDotNames;

// Check if a type is a String
if (DotNames.STRING.equals(methodParameter.type().name())) {
    // Handle string parameter
}

// Check if a method is annotated with @Tool
if (method.hasAnnotation(LangChain4jDotNames.TOOL)) {
    // Process tool method
}

See Utilities Documentation for all utility classes.

Extension Points

Extensions can integrate with this deployment module by:

Producing BuildItems

Register new capabilities:

@BuildStep
void registerCapabilities(
        BuildProducer<ChatModelProviderCandidateBuildItem> chatProvider,
        BuildProducer<EmbeddingModelProviderCandidateBuildItem> embeddingProvider) {

    // Register as a chat model provider
    chatProvider.produce(new ChatModelProviderCandidateBuildItem("my-provider"));

    // Register as an embedding model provider
    embeddingProvider.produce(new EmbeddingModelProviderCandidateBuildItem("my-provider"));
}

Consuming BuildItems

React to configuration decisions:

@BuildStep
void reactToSelection(List<SelectedChatModelProviderBuildItem> selected) {
    for (SelectedChatModelProviderBuildItem item : selected) {
        if ("my-provider".equals(item.getProvider())) {
            String configName = item.getConfigName();
            // Create beans for this configuration
        }
    }
}

Customizing Behavior

Control how AI services behave:

@BuildStep
void customizeBehavior(
        BuildProducer<AnnotationsImpliesAiServiceBuildItem> annotations,
        BuildProducer<SkipOutputFormatInstructionsBuildItem> skipFormat) {

    // Make @MyAnnotation imply AI service
    annotations.produce(new AnnotationsImpliesAiServiceBuildItem(
        Set.of(DotName.createSimple("com.example.MyAnnotation"))
    ));

    // Skip output format for certain methods
    skipFormat.produce(new SkipOutputFormatInstructionsBuildItem(
        method -> method.hasAnnotation(DotName.createSimple("com.example.NoFormat"))
    ));
}

Build Step Execution Order

BuildSteps execute in an order determined by their BuildItem dependencies. The core execution flow is:

  1. Provider Registration: Extensions register provider candidates
  2. Configuration Loading: Build-time configuration is resolved
  3. Provider Selection: Core selects providers based on config
  4. Bean Synthesis: CDI beans are created for selected providers
  5. AI Service Discovery: @RegisterAiService interfaces are processed
  6. Tool Discovery: @Tool methods are discovered
  7. Guardrail Processing: Input/output guardrails are configured
  8. DevServices: Local inference servers are started (dev/test only)

Common Patterns

Pattern 1: Conditional BuildStep

Only run when a capability is present:

@BuildStep(onlyIf = MyCondition.class)
void conditionalStep() {
    // Only runs if MyCondition.getAsBoolean() returns true
}

Pattern 2: Recording Runtime Values

Pass build-time decisions to runtime:

@BuildStep
@Record(ExecutionTime.STATIC_INIT)
void recordValues(MyRecorder recorder, List<SelectedChatModelProviderBuildItem> selected) {
    for (SelectedChatModelProviderBuildItem item : selected) {
        recorder.recordProvider(item.getProvider(), item.getConfigName());
    }
}

Pattern 3: Consuming Multiple BuildItems

@BuildStep
void combineData(
        List<DeclarativeAiServiceBuildItem> aiServices,
        List<ToolMethodBuildItem> tools,
        ToolsMetadataBuildItem metadata) {

    // Combine multiple sources of information
    Map<String, List<ToolMethodCreateInfo>> toolsByService = metadata.getMetadata();

    for (DeclarativeAiServiceBuildItem service : aiServices) {
        String serviceName = service.getServiceClassInfo().name().toString();
        List<ToolMethodCreateInfo> servicTools = toolsByService.get(serviceName);
        // Process combined data
    }
}

Next Steps

Key Notes

  • This is a deployment-time module - all classes run at build time only
  • BuildItems are the primary API for extension communication
  • Use BuildProducer<T> to produce BuildItems, method parameters to consume them
  • Configuration is resolved at build time via @ConfigRoot and @ConfigMapping
  • The module follows Quarkus conventions for native image optimization
  • DevServices-related BuildSteps use @BuildSteps(onlyIfNot = IsNormal.class) to run only in dev/test mode
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/io.quarkiverse.langchain4j/quarkus-langchain4j-core-deployment@1.7.x
Publish Source
CLI
Badge
tessl/maven-io-quarkiverse-langchain4j--quarkus-langchain4j-core-deployment badge