LangChain4j Agent - Input and Output Guardrails

Input and Output Guardrails

Guardrails validate and filter AI interactions to ensure security and quality. The LangChain4j Agent component provides both custom guardrail support and a set of production-ready built-in guardrails.

Using Custom Guardrails

Create classes defining InputGuardrails and OutputGuardrails as defined in the LangChain4j Guardrails documentation page.

Java-only: AgentConfiguration with guardrail classes and bean registration
// Create agent configuration with custom guardrails
AgentConfiguration configuration = new AgentConfiguration()
    .withChatModel(chatModel)
    .withInputGuardrailClassesList("com.example.MyInputGuardrail")
    .withOutputGuardrailClassesList("com.example.MyOutputGuardrail1,com.example.MyOutputGuardrail2");

Agent safeAgent = new AgentWithoutMemory(configuration);
context.getRegistry().bind("safeAgent", safeAgent);

Use the agent with guardrails:

  • Java

  • XML

  • YAML

from("direct:agent-with-guardrails")
    .to("langchain4j-agent:safe?agent=#safeAgent")
<route>
  <from uri="direct:agent-with-guardrails"/>
  <to uri="langchain4j-agent:safe?agent=#safeAgent"/>
</route>
- route:
    from:
      uri: direct:agent-with-guardrails
      steps:
        - to:
            uri: langchain4j-agent:safe
            parameters:
              agent: "#safeAgent"

The current version of the component returns a String as response. If the outputGuardrails extends JsonExtractorOutputGuardrail class, make sure to return a Json in String format.

Built-in Guardrails

The camel-langchain4j-agent-api module provides production-ready guardrails in the org.apache.camel.component.langchain4j.agent.api.guardrails package.

Available Input Guardrails

Guardrail Class Description

InputLengthGuardrail

Validates message length (min/max characters). Prevents excessively long inputs.

PiiDetectorGuardrail

Detects Personally Identifiable Information (email, phone, SSN, credit cards, IP addresses).

PromptInjectionGuardrail

Detects prompt injection attacks (role manipulation, jailbreaks, delimiter injection).

KeywordFilterGuardrail

Blocks messages containing specific keywords or patterns.

LanguageGuardrail

Validates the language/script of user messages. Can allow or block specific languages (English, Cyrillic, Chinese, Japanese, Korean, Arabic, Hebrew, Greek, Thai, Devanagari).

CodeInjectionGuardrail

Detects potential code injection attempts including shell commands, SQL injection, JavaScript, HTML/XSS, path traversal, command chaining, and template injection.

RegexPatternGuardrail

Flexible guardrail using custom regex patterns. Can define deny patterns (block if matched) and require patterns (must be present).

Available Output Guardrails

Guardrail Class Description

OutputLengthGuardrail

Validates response length with optional truncation support.

SensitiveDataOutputGuardrail

Detects and optionally redacts sensitive data (API keys, passwords, JWT tokens, AWS keys).

JsonFormatGuardrail

Validates JSON format, extracts JSON from text, and checks for required fields.

KeywordOutputFilterGuardrail

Blocks or redacts specific content in AI responses.

NotEmptyGuardrail

Ensures AI responses are not empty or contain only whitespace. Can optionally detect refusal patterns (e.g., "I cannot", "I’m unable to").

WordCountGuardrail

Validates the word count of AI responses. Can enforce minimum, maximum, or range constraints.

Quick Start with Default Guardrails

The Guardrails helper class provides convenient factory methods:

Java-only: Guardrails factory methods and bean registration
import org.apache.camel.component.langchain4j.agent.api.guardrails.Guardrails;

// Create agent with default security guardrails
AgentConfiguration configuration = new AgentConfiguration()
    .withChatModel(chatModel)
    .withInputGuardrailClasses(Guardrails.defaultInputGuardrails())
    .withOutputGuardrailClasses(Guardrails.defaultOutputGuardrails());

Agent secureAgent = new AgentWithoutMemory(configuration);
context.getRegistry().bind("secureAgent", secureAgent);
  • Java

  • XML

  • YAML

from("direct:secure-chat")
    .to("langchain4j-agent:chat?agent=#secureAgent");
<route>
  <from uri="direct:secure-chat"/>
  <to uri="langchain4j-agent:chat?agent=#secureAgent"/>
</route>
- route:
    from:
      uri: direct:secure-chat
      steps:
        - to:
            uri: langchain4j-agent:chat
            parameters:
              agent: "#secureAgent"

The default guardrails include:

  • Input: InputLengthGuardrail, PiiDetectorGuardrail, PromptInjectionGuardrail

  • Output: OutputLengthGuardrail, SensitiveDataOutputGuardrail

Using the Fluent Builder

The Guardrails.configure() method provides a fluent API for building configurations:

Java-only: Guardrails fluent builder API
import org.apache.camel.component.langchain4j.agent.api.guardrails.Guardrails;

AgentConfiguration configuration = Guardrails.configure()
    .withPiiDetection()
    .withPromptInjectionDetection()
    .withInputLengthValidation()
    .withSensitiveDataDetection()
    .withJsonFormatValidation()
    .build();

configuration.withChatModel(chatModel);

Agent agent = new AgentWithoutMemory(configuration);

Using Specific Guardrail Classes

You can specify exactly which guardrails to use:

Java-only: AgentConfiguration with specific guardrail classes
import org.apache.camel.component.langchain4j.agent.api.guardrails.*;

AgentConfiguration configuration = new AgentConfiguration()
    .withChatModel(chatModel)
    .withInputGuardrailClasses(List.of(
        InputLengthGuardrail.class,
        PiiDetectorGuardrail.class,
        PromptInjectionGuardrail.class
    ))
    .withOutputGuardrailClasses(List.of(
        SensitiveDataOutputGuardrail.class,
        JsonFormatGuardrail.class
    ));

Guardrail Presets

The Guardrails class provides preset configurations for different security levels:

Java-only: Guardrails preset factory methods
// Minimal protection (just length validation)
configuration.withInputGuardrailClasses(Guardrails.minimalInputGuardrails());

// Standard protection (length, PII, prompt injection)
configuration.withInputGuardrailClasses(Guardrails.defaultInputGuardrails());

// Strict protection (all input guardrails)
configuration.withInputGuardrailClasses(Guardrails.strictInputGuardrails());

Factory Methods for Individual Guardrails

The Guardrails class provides static factory methods to create guardrail instances:

Java-only: Guardrails static factory methods
// Input guardrails
InputLengthGuardrail lengthGuard = Guardrails.inputLength(5000);  // Max 5000 chars
PiiDetectorGuardrail piiGuard = Guardrails.piiDetector();
PromptInjectionGuardrail injectionGuard = Guardrails.promptInjectionStrict();
KeywordFilterGuardrail keywordGuard = Guardrails.keywordFilter("banned", "blocked");

// Output guardrails
OutputLengthGuardrail outputLength = Guardrails.outputLengthTruncating(10000);
SensitiveDataOutputGuardrail sensitiveData = Guardrails.sensitiveDataRedacting();
JsonFormatGuardrail jsonGuard = Guardrails.jsonFormatWithFields("name", "email");

Advanced Guardrail Configuration with Builders

Each guardrail provides a builder for custom configuration:

PII Detection Configuration

Java-only: PiiDetectorGuardrail builder API
import org.apache.camel.component.langchain4j.agent.api.guardrails.PiiDetectorGuardrail;
import org.apache.camel.component.langchain4j.agent.api.guardrails.PiiDetectorGuardrail.PiiType;

// Detect only specific PII types
PiiDetectorGuardrail guardrail = PiiDetectorGuardrail.builder()
    .detectTypes(PiiType.EMAIL, PiiType.PHONE, PiiType.SSN)
    .blockOnDetection(true)
    .build();

Prompt Injection Detection Configuration

Java-only: PromptInjectionGuardrail builder API
import org.apache.camel.component.langchain4j.agent.api.guardrails.PromptInjectionGuardrail;

// Strict mode: fail on any single pattern match
PromptInjectionGuardrail strictGuardrail = PromptInjectionGuardrail.strict();

// Custom patterns
PromptInjectionGuardrail customGuardrail = PromptInjectionGuardrail.builder()
    .strict(true)
    .addPattern(
        PromptInjectionGuardrail.InjectionCategory.JAILBREAK,
        Pattern.compile("(?i)custom\\s+attack\\s+pattern"))
    .build();

Sensitive Data Output Configuration

Java-only: SensitiveDataOutputGuardrail builder API
import org.apache.camel.component.langchain4j.agent.api.guardrails.SensitiveDataOutputGuardrail;
import org.apache.camel.component.langchain4j.agent.api.guardrails.SensitiveDataOutputGuardrail.*;

// Redact sensitive data instead of blocking
SensitiveDataOutputGuardrail guardrail = SensitiveDataOutputGuardrail.builder()
    .detectTypes(SensitiveDataType.API_KEY, SensitiveDataType.SECRET, SensitiveDataType.JWT)
    .action(Action.REDACT)
    .redactionText("***REDACTED***")
    .build();

JSON Format Validation Configuration

Java-only: JsonFormatGuardrail builder API
import org.apache.camel.component.langchain4j.agent.api.guardrails.JsonFormatGuardrail;

// Validate JSON with required fields
JsonFormatGuardrail guardrail = JsonFormatGuardrail.builder()
    .requireFields("id", "name", "email")
    .extractJson(true)      // Extract JSON from surrounding text
    .allowArray(false)      // Only allow objects, not arrays
    .build();

Keyword Filtering Configuration

Java-only: KeywordFilterGuardrail and KeywordOutputFilterGuardrail builder APIs
import org.apache.camel.component.langchain4j.agent.api.guardrails.KeywordFilterGuardrail;
import org.apache.camel.component.langchain4j.agent.api.guardrails.KeywordOutputFilterGuardrail;

// Input keyword filter
KeywordFilterGuardrail inputFilter = KeywordFilterGuardrail.builder()
    .blockedWords("spam", "inappropriate", "banned")
    .blockedPattern("\\b(hack|exploit)\\b")
    .caseSensitive(false)
    .wholeWordMatch(true)
    .build();

// Output keyword filter with redaction
KeywordOutputFilterGuardrail outputFilter = KeywordOutputFilterGuardrail.builder()
    .blockedWords("confidential", "internal-only")
    .action(KeywordOutputFilterGuardrail.Action.REDACT)
    .redactionText("[REMOVED]")
    .build();

Language Validation Configuration

Java-only: LanguageGuardrail builder API
import org.apache.camel.component.langchain4j.agent.api.guardrails.LanguageGuardrail;
import org.apache.camel.component.langchain4j.agent.api.guardrails.LanguageGuardrail.Language;

// Allow only English input
LanguageGuardrail englishOnly = LanguageGuardrail.allowOnly(Language.ENGLISH);

// Allow English and Latin script languages (Spanish, French, German, etc.)
LanguageGuardrail latinLanguages = LanguageGuardrail.allowOnly(
    Language.ENGLISH, Language.LATIN_SCRIPT);

// Block specific languages
LanguageGuardrail blockCyrillic = LanguageGuardrail.block(Language.CYRILLIC);

// Custom configuration with mixed content control
LanguageGuardrail customLanguage = LanguageGuardrail.builder()
    .allowedLanguages(Language.ENGLISH, Language.LATIN_SCRIPT)
    .blockedLanguages(Language.CYRILLIC)
    .allowMixed(false)  // Don't allow mixed language content
    .build();

Code Injection Detection Configuration

Java-only: CodeInjectionGuardrail builder API
import org.apache.camel.component.langchain4j.agent.api.guardrails.CodeInjectionGuardrail;
import org.apache.camel.component.langchain4j.agent.api.guardrails.CodeInjectionGuardrail.InjectionType;

// Default: detect all code injection types
CodeInjectionGuardrail defaultGuard = new CodeInjectionGuardrail();

// Strict mode: fail on any single pattern match
CodeInjectionGuardrail strictGuard = CodeInjectionGuardrail.strict();

// Detect only specific injection types
CodeInjectionGuardrail sqlAndShellOnly = CodeInjectionGuardrail.forTypes(
    InjectionType.SQL_INJECTION, InjectionType.SHELL_COMMAND);

// Custom configuration
CodeInjectionGuardrail customGuard = CodeInjectionGuardrail.builder()
    .detectTypes(InjectionType.SQL_INJECTION, InjectionType.JAVASCRIPT, InjectionType.PATH_TRAVERSAL)
    .strict(true)
    .build();

Regex Pattern Guardrail Configuration

Java-only: RegexPatternGuardrail builder API
import org.apache.camel.component.langchain4j.agent.api.guardrails.RegexPatternGuardrail;

// Block messages containing URLs
RegexPatternGuardrail noUrls = RegexPatternGuardrail.blocking(
    "https?://[^\\s]+", "URLs are not allowed in messages");

// Require messages to contain a ticket number
RegexPatternGuardrail requireTicket = RegexPatternGuardrail.requiring(
    "TICKET-\\d+", "Please include a ticket number (e.g., TICKET-123)");

// Complex configuration with multiple patterns
RegexPatternGuardrail customPatterns = RegexPatternGuardrail.builder()
    .denyPattern("https?://[^\\s]+", "URLs are not allowed")
    .denyPattern("\\b(password|secret)\\b", "Sensitive keywords are not allowed")
    .requirePattern("[A-Z]{2,4}-\\d+", "Please include a valid issue ID")
    .failOnFirstMatch(true)  // Stop checking after first failure
    .build();

Not Empty Guardrail Configuration

Java-only: NotEmptyGuardrail configuration
import org.apache.camel.component.langchain4j.agent.api.guardrails.NotEmptyGuardrail;

// Default: just ensure response is not empty
NotEmptyGuardrail notEmpty = new NotEmptyGuardrail();

// Also detect refusal patterns like "I cannot", "I'm unable to"
NotEmptyGuardrail withRefusalDetection = NotEmptyGuardrail.withRefusalDetection();

// Require minimum meaningful length
NotEmptyGuardrail minLength = NotEmptyGuardrail.withMinLength(50);

// Custom configuration
NotEmptyGuardrail customNotEmpty = new NotEmptyGuardrail(
    true,   // detectRefusals
    100     // minMeaningfulLength
);

Word Count Guardrail Configuration

Java-only: WordCountGuardrail builder API
import org.apache.camel.component.langchain4j.agent.api.guardrails.WordCountGuardrail;

// Require at least 10 words
WordCountGuardrail atLeast10 = WordCountGuardrail.atLeast(10);

// Limit to maximum 500 words
WordCountGuardrail atMost500 = WordCountGuardrail.atMost(500);

// Require between 50 and 200 words
WordCountGuardrail between = WordCountGuardrail.between(50, 200);

// Custom configuration
WordCountGuardrail custom = WordCountGuardrail.builder()
    .minWords(20)
    .maxWords(1000)
    .build();

Complete Example with Memory and Guardrails

Java-only: RouteBuilder class with AgentConfiguration, guardrails, memory, and doTry/`doCatch`
ChatModel chatModel = OpenAiChatModel.builder()
    .apiKey("{{openai.api.key}}")
    .modelName("gpt-4o")
    .build();

ChatMemoryProvider memoryProvider = memoryId ->
    MessageWindowChatMemory.withMaxMessages(20);

AgentConfiguration configuration = new AgentConfiguration()
    .withChatModel(chatModel)
    .withChatMemoryProvider(memoryProvider)
    .withInputGuardrailClasses(Guardrails.defaultInputGuardrails())
    .withOutputGuardrailClasses(Guardrails.defaultOutputGuardrails());

Agent secureAgent = new AgentWithMemory(configuration);
getContext().getRegistry().bind("secureAgent", secureAgent);

from("direct:chat")
    .setHeader("CamelLangChain4jAgentMemoryId", simple("${header.userId}"))
    .doTry()
        .to("langchain4j-agent:chat?agent=#secureAgent")
    .doCatch(dev.langchain4j.service.guardrail.GuardrailException.class)
        .log("Guardrail blocked request: ${exception.message}")
        .setBody(constant("Your message was blocked due to security policies."))
    .end();

Spring Boot Configuration Example

When using Camel with Spring Boot, leverage LangChain4j’s Spring Boot starters for automatic configuration of the ChatModel.

Add the dependency for LangChain4j OpenAI Spring Boot starter:

pom.xml
<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
    <version>1.10.0</version>
    <!-- use the same version as your LangChain4j version -->
</dependency>

Configure the OpenAI Chat Model in application.properties:

application.properties
langchain4j.open-ai.chat-model.api-key=${OPENAI_API_KEY}
langchain4j.open-ai.chat-model.model-name=gpt-4o
langchain4j.open-ai.chat-model.temperature=0.7

Create the Agent bean using the auto-configured ChatLanguageModel:

Java-only: Spring Boot @Configuration with auto-configured `ChatLanguageModel`
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import dev.langchain4j.model.chat.ChatLanguageModel;
import org.apache.camel.component.langchain4j.agent.api.Agent;
import org.apache.camel.component.langchain4j.agent.api.AgentConfiguration;
import org.apache.camel.component.langchain4j.agent.api.AgentWithoutMemory;
import org.apache.camel.component.langchain4j.agent.api.guardrails.Guardrails;

@Configuration
public class AgentConfig {

    @Bean("secureAgent")
    public Agent secureAgent(ChatLanguageModel chatLanguageModel) {
        AgentConfiguration config = new AgentConfiguration()
            .withChatModel(chatLanguageModel)
            .withInputGuardrailClasses(Guardrails.defaultInputGuardrails())
            .withOutputGuardrailClasses(Guardrails.defaultOutputGuardrails());

        return new AgentWithoutMemory(config);
    }
}

The ChatLanguageModel bean is automatically configured by the LangChain4j Spring Boot starter and injected into your configuration. You can also use other auto-configured beans such as:

  • StreamingChatLanguageModel - For streaming responses

  • EmbeddingModel - For generating embeddings

  • ImageModel - For image generation

  • ModerationModel - For content moderation

Refer to the LangChain4j Spring Boot Integration documentation for complete configuration options.

Manual Configuration (Alternative)

Alternatively, you can manually configure the ChatModel bean:

Java-only: Spring Boot @Configuration with manual ChatModel bean
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AgentConfig {

    @Bean
    public ChatModel chatModel() {
        return OpenAiChatModel.builder()
            .apiKey(System.getenv("OPENAI_API_KEY"))
            .modelName("gpt-4o")
            .build();
    }

    @Bean("secureAgent")
    public Agent secureAgent(ChatModel chatModel) {
        AgentConfiguration config = new AgentConfiguration()
            .withChatModel(chatModel)
            .withInputGuardrailClasses(Guardrails.defaultInputGuardrails())
            .withOutputGuardrailClasses(Guardrails.defaultOutputGuardrails());

        return new AgentWithoutMemory(config);
    }
}

Guardrail Behavior Summary

Guardrail When Triggered Result

InputLengthGuardrail

Input too short/long

Blocks the request

PiiDetectorGuardrail

PII detected

Blocks the request

PromptInjectionGuardrail

Injection attempt detected

Blocks the request

KeywordFilterGuardrail

Blocked keyword found

Blocks the request

LanguageGuardrail

Disallowed language/script detected

Blocks the request

CodeInjectionGuardrail

Code injection pattern detected

Blocks the request

RegexPatternGuardrail

Deny pattern matched or require pattern missing

Blocks the request

OutputLengthGuardrail

Response too short/long

Retries LLM or truncates

SensitiveDataOutputGuardrail

Secrets in response

Blocks or redacts

JsonFormatGuardrail

Invalid JSON format

Retries LLM call

KeywordOutputFilterGuardrail

Blocked content in response

Blocks or redacts

NotEmptyGuardrail

Empty response or refusal detected

Retries LLM call

WordCountGuardrail

Word count outside allowed range

Retries LLM call