Easy RAG extension for Quarkus LangChain4j that dramatically simplifies implementing Retrieval Augmented Generation pipelines with automatic document ingestion and embedding store management
The Quarkus LangChain4j Easy RAG extension provides the easiest way to implement Retrieval Augmented Generation (RAG) pipelines in Quarkus applications. It automates document ingestion, parsing, splitting, embedding generation, and retrieval with minimal configuration, enabling developers to quickly add RAG capabilities to their applications.
io.quarkiverse.langchain4j:quarkus-langchain4j-easy-rag<dependency>
<groupId>io.quarkiverse.langchain4j</groupId>
<artifactId>quarkus-langchain4j-easy-rag</artifactId>
<version>1.7.4</version>
</dependency>Important: Native compilation is not supported with this extension.
import io.quarkiverse.langchain4j.easyrag.EasyRagManualIngestion;
import io.quarkiverse.langchain4j.easyrag.runtime.EasyRagConfig;
import io.quarkiverse.langchain4j.easyrag.runtime.IngestionStrategy;
import jakarta.inject.Inject;The Easy RAG extension works with minimal configuration. You only need to:
quarkus-langchain4j-openai or quarkus-langchain4j-ollama)application.properties:# Required: path to documents directory
quarkus.langchain4j.easy-rag.path=/path/to/documents
# Optional: use classpath instead of filesystem
quarkus.langchain4j.easy-rag.path-type=CLASSPATHThe extension automatically:
InMemoryEmbeddingStore if no embedding store bean existsRetrievalAugmentor bean if none existsExample: Using the auto-generated RetrievalAugmentor in an AI service:
import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;
import io.quarkiverse.langchain4j.RegisterAiService;
@RegisterAiService
public interface ChatBot {
@SystemMessage("You are a helpful assistant. Answer based on the provided context.")
String chat(@UserMessage String userMessage);
}import jakarta.inject.Inject;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
@Path("/chat")
public class ChatResource {
@Inject
ChatBot chatBot;
@POST
public String chat(String message) {
return chatBot.chat(message);
}
}The RetrievalAugmentor is automatically injected and used by the AI service to augment prompts with relevant document context.
The Easy RAG extension architecture integrates Quarkus CDI and LangChain4j to provide seamless RAG capabilities. Key components include the EasyRagIngestor for document processing, EasyRetrievalAugmentor for similarity search, and automatic CDI bean synthesis for zero-configuration operation.
Provides programmatic control over when document ingestion occurs, enabling scenarios where ingestion timing needs to be controlled by application logic rather than happening at startup.
package io.quarkiverse.langchain4j.easyrag;
@ApplicationScoped
public class EasyRagManualIngestion {
public void ingest();
}Comprehensive configuration options for controlling document ingestion behavior, retrieval parameters, and embeddings management.
package io.quarkiverse.langchain4j.easyrag.runtime;
import io.quarkus.runtime.annotations.ConfigRoot;
import io.quarkus.runtime.annotations.ConfigGroup;
import io.smallrye.config.ConfigMapping;
import io.smallrye.config.WithDefault;
import java.util.OptionalDouble;
@ConfigRoot(phase = RUN_TIME)
@ConfigMapping(prefix = "quarkus.langchain4j.easy-rag")
public interface EasyRagConfig {
/**
* Path to the directory containing documents to ingest (required).
*/
String path();
/**
* Type of path: FILESYSTEM or CLASSPATH (default: FILESYSTEM).
*/
@WithDefault("FILESYSTEM")
PathType pathType();
/**
* File filtering pattern (default: glob:**).
*/
@WithDefault("glob:**")
String pathMatcher();
/**
* Recursively scan subdirectories (default: true).
*/
@WithDefault("true")
Boolean recursive();
/**
* Maximum segment size in tokens (default: 300).
*/
@WithDefault("300")
Integer maxSegmentSize();
/**
* Maximum overlap between segments in tokens (default: 30).
*/
@WithDefault("30")
Integer maxOverlapSize();
/**
* Maximum number of retrieval results (default: 5).
*/
@WithDefault("5")
Integer maxResults();
/**
* Minimum similarity score threshold (optional, no filtering if not set).
*/
OptionalDouble minScore();
/**
* Ingestion strategy (default: ON).
*/
@WithDefault("ON")
IngestionStrategy ingestionStrategy();
/**
* Configuration for embeddings reuse.
*/
ReuseEmbeddingsConfig reuseEmbeddings();
/**
* Type of path reference for document location.
*/
enum PathType {
/** Path represents a filesystem directory or file */
FILESYSTEM,
/** Path represents a classpath resource location */
CLASSPATH
}
/**
* Configuration for reusing embeddings across application restarts.
* Only supported with InMemoryEmbeddingStore.
*/
@ConfigGroup
interface ReuseEmbeddingsConfig {
/**
* Enable embeddings reuse (default: false).
*/
@WithDefault("false")
boolean enabled();
/**
* File path for loading/saving embeddings (default: easy-rag-embeddings.json).
*/
@WithDefault("easy-rag-embeddings.json")
String file();
}
}The auto-generated RetrievalAugmentor implementation that integrates with LangChain4j AI services to provide RAG capabilities.
package io.quarkiverse.langchain4j.easyrag.runtime;
public class EasyRetrievalAugmentor implements RetrievalAugmentor {
public EasyRetrievalAugmentor(
EasyRagConfig config,
EmbeddingModel embeddingModel,
EmbeddingStore embeddingStore
);
public AugmentationResult augment(AugmentationRequest augmentationRequest);
}Internal document ingestion functionality that handles loading, parsing, splitting, and embedding documents from filesystem or classpath.
package io.quarkiverse.langchain4j.easyrag.runtime;
public class EasyRagIngestor {
public EasyRagIngestor(
EmbeddingModel embeddingModel,
EmbeddingStore<TextSegment> embeddingStore,
EasyRagConfig config
);
public void ingest();
}Controls when document ingestion occurs.
package io.quarkiverse.langchain4j.easyrag.runtime;
/**
* Strategy for controlling when document ingestion occurs.
*/
public enum IngestionStrategy {
/**
* Automatically ingest documents at application startup (default).
* Documents are loaded, parsed, split, and embedded immediately when the application starts.
*/
ON,
/**
* Do not perform ingestion.
* Use when the embedding store is already populated or documents are managed externally.
*/
OFF,
/**
* Wait for manual trigger via EasyRagManualIngestion.ingest().
* Provides programmatic control over when ingestion occurs.
*/
MANUAL
}Specifies the type of path reference for document location.
package io.quarkiverse.langchain4j.easyrag.runtime;
/**
* Type of path reference for document location.
* Nested enum within EasyRagConfig interface.
*/
public enum PathType {
/**
* Path represents a filesystem directory or file reference.
* Used for documents stored in the local filesystem.
*/
FILESYSTEM,
/**
* Path represents a classpath resource location.
* Used for documents packaged within the application JAR.
*/
CLASSPATH
}The extension automatically creates CDI beans when they are not already present:
EmbeddingStore bean existsRetrievalAugmentor bean existsThis allows you to replace these with custom implementations by simply providing your own beans.
Uses Apache Tika for universal document parsing, supporting:
While an in-memory store is provided by default for quick prototyping, you can use persistent embedding stores by adding extensions:
quarkus-langchain4j-redisquarkus-langchain4j-chromaquarkus-langchain4j-infinispanWhen a persistent store extension is added, the Easy RAG extension uses it automatically instead of creating an in-memory store.
In Quarkus dev mode, access the Dev UI at http://localhost:8080/q/dev-ui and click the 'Chat' button in the LangChain4j card to test your RAG pipeline without building a frontend.
Speed up development cycles by caching embeddings to a file:
quarkus.langchain4j.easy-rag.reuse-embeddings.enabled=true
quarkus.langchain4j.easy-rag.reuse-embeddings.file=embeddings.jsonWhen enabled, embeddings are computed once and reused across application restarts, significantly reducing startup time during development.
The Easy RAG extension requires an embedding model provider. Choose one:
io.quarkiverse.langchain4j:quarkus-langchain4j-openaiio.quarkiverse.langchain4j:quarkus-langchain4j-ollamaIf multiple embedding model providers are present, specify which to use:
quarkus.langchain4j.embedding-model.provider=openaiquarkus.langchain4j.easy-rag.path=/data/documentsquarkus.langchain4j.easy-rag.path=documents
quarkus.langchain4j.easy-rag.path-type=CLASSPATH
quarkus.langchain4j.easy-rag.path-matcher=glob:**.{txt,md,pdf}quarkus.langchain4j.easy-rag.path=/data/documents
quarkus.langchain4j.easy-rag.ingestion-strategy=MANUALquarkus.langchain4j.easy-rag.max-segment-size=500
quarkus.langchain4j.easy-rag.max-overlap-size=50quarkus.langchain4j.easy-rag.max-results=10
quarkus.langchain4j.easy-rag.min-score=0.7Install with Tessl CLI
npx tessl i tessl/maven-io-quarkiverse-langchain4j--quarkus-langchain4j-easy-rag