← Code Recipes
Frameworks & SDKs

LangChain4j Free code examples in Java

The mature LLM toolkit for plain Java, no Spring required.

C# Python Java JavaScript

WHAT THIS PAGE COVERS

AI Services — declaring an interface and letting it be implemented for you.

Model gpt-5.4-mini
Package langchain4j
Checked

Model ids change. If a sample returns a 404 on the model, that is the first thing to check against the official docs.

Install

Two artifacts: the core and one model provider. langchain4j-open-ai is the provider; swapping it for langchain4j-anthropic changes the builder line and nothing else.

# Gradle
implementation("dev.langchain4j:langchain4j:1.20.1")
implementation("dev.langchain4j:langchain4j-open-ai:1.20.1")

export OPENAI_API_KEY="sk-your-key"
The first call

The model object is the low level. Useful for one-shot work and not where you should stay — the AI Service below is what this library is for.

import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.openai.OpenAiChatModel;

public class Ask {
    public static void main(String[] args) {
        ChatModel model = OpenAiChatModel.builder()
            .apiKey(System.getenv("OPENAI_API_KEY"))
            .modelName("gpt-5.4-mini")
            .build();

        System.out.println(model.chat("Explain a database index in two sentences."));
    }
}
An AI Service is an interface you do not implement

DECLARE THE SHAPE, GET THE IMPLEMENTATION. The annotations are the prompt, the parameters are the template variables, and the return type is the output schema — so a List<Finding> return is structured output with no parsing code.

import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;

import java.util.List;

record Finding(String title, String severity, String file) {}

interface Reviewer {

    @SystemMessage("You are a terse code reviewer. Report only real defects.")
    @UserMessage("Review this {{language}} file and list the findings:\n\n{{code}}")
    List<Finding> review(@V("language") String language, @V("code") String code);
}

Reviewer reviewer = AiServices.create(Reviewer.class, model);

// A typed List<Finding>. No JSON parsing anywhere in your code.
List<Finding> findings = reviewer.review("Java", sourceText);
Tools, and memory per conversation

@Tool turns a method into something the model can call. @MemoryId is what keeps two users' histories apart — the memory provider is asked per id, so one service instance safely serves everyone.

import dev.langchain4j.agent.tool.Tool;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;

class StockTools {

    @Tool("Gets the current stock level for a single product code.")
    int getStock(String code) {
        return 42;
    }
}

interface Assistant {
    // The id is the tenant, the session, the ticket — whatever
    // separates one conversation from another.
    String chat(@MemoryId String conversationId, @UserMessage String message);
}

Assistant assistant = AiServices.builder(Assistant.class)
    .chatModel(model)
    .tools(new StockTools())
    .chatMemoryProvider(id -> MessageWindowChatMemory.withMaxMessages(20))
    .build();

System.out.println(assistant.chat("ticket-118", "How many X-17 do we have?"));
Streaming, and knowing when it finished

A StreamingChatModel plus a streaming return type. onCompleteResponse is where the token usage lands — which is the only place you can bill or budget a request from.

import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
import dev.langchain4j.service.TokenStream;

interface StreamingAssistant {
    TokenStream chat(String message);
}

StreamingAssistant streaming = AiServices.create(
    StreamingAssistant.class,
    OpenAiStreamingChatModel.builder()
        .apiKey(System.getenv("OPENAI_API_KEY"))
        .modelName("gpt-5.4-mini")
        .build());

streaming.chat("Explain B-trees in 200 words.")
    .onPartialResponse(System.out::print)
    .onCompleteResponse(response ->
        System.out.println("\n" + response.tokenUsage()))
    .onError(Throwable::printStackTrace)
    .start();

QUESTIONS

Which languages are the LangChain4j examples in?

Java. Every sample runs as pasted and reads its credentials from an environment variable — no key is ever written into the code.

Which package do I install for LangChain4j?

The samples use langchain4j. The install step on each language tab gives the exact command.

Which LangChain4j model do these examples use?

gpt-5.4-mini, checked against the official documentation on 26 September 2026. Model ids change often; if a call returns a model-not-found error, check the current list in the official docs.

Where is the official LangChain4j documentation?

https://docs.langchain4j.dev/ — it is linked at the bottom of this page, and it is the authority whenever it disagrees with a sample here.

ALSO IN FRAMEWORKS & SDKS

The authority

Official LangChain4j documentation

Model names, pricing and rate limits change faster than any page here can. When this page and the official docs disagree, the official docs are right.

Read the docs ↗

https://docs.langchain4j.dev/

New drops, every week

Free tools & Claude templates, landing regularly.

We keep shipping new free tools, code recipes and Claude Code templates. Follow @freeyantra on Instagram or join the newsletter so you never miss one.

Follow @freeyantra

or get them by email

Double opt-in. Unsubscribe any time. Privacy