Skip to content

Building a Conversational Chatbot with LangChain4j

LangChain4j makes building stateful, conversational applications in Java incredibly simple, especially with its high-level AiServices API. It allows you to create a chatbot that remembers previous interactions with minimal boilerplate code.

This tutorial will guide you through creating a conversational chatbot that uses the Voidon API and manages conversation history automatically.

The Power of AiServices and ChatMemory

In LangChain4j, you define a chatbot's capabilities with a simple Java interface. By binding a ChatMemory instance to this service, the framework automatically handles the loading and saving of the conversation history for every call, making your chatbot stateful.


Prerequisites

Add the LangChain4j dependencies to your project's pom.xml:

XML
<dependencies>
    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j</artifactId>
        <version>0.30.0</version> <!-- Use the latest version -->
    </dependency>
    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j-open-ai</artifactId>
        <version>0.30.0</version> <!-- Use the same version -->
    </dependency>

    <!-- Add a logger to see LangChain4j's output -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>2.0.12</version>
    </dependency>
</dependencies>

Implementation

Step 1: Define the Chatbot Interface

We start by creating a Java interface that defines our chatbot's behavior. We can use the @SystemMessage annotation to give it a personality and instructions.

src/main/java/com/voidon/chatbot/Chatbot.java

Java
package com.voidon.chatbot;

import dev.langchain4j.service.SystemMessage;

public interface Chatbot {

    @SystemMessage("You are a helpful and friendly AI assistant. Your name is Voidy.")
    String chat(String userMessage);
}```

### Step 2: Configure the Language Model and Memory

In our main class, we configure the `OpenAiChatModel` to point to the Voidon API. Crucially, we also create a `ChatMemory` instance. `MessageWindowChatMemory` is a great choice as it keeps a sliding window of the most recent messages.

`src/main/java/com/voidon/chatbot/ChatbotExample.java`
```java
package com.voidon.chatbot;

import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;

public class ChatbotExample {

    public static void main(String[] args) {
        // 1. Configure the model to use the Voidon API
        ChatLanguageModel model = OpenAiChatModel.builder()
                .baseUrl("https://api.voidon.astramind.ai/v1")
                .apiKey("your-voidon-api-key")
                .modelName("auto")
                .build();

        // 2. Create a memory component to store the conversation history
        // This will keep the last 10 messages of the conversation
        ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);
    }
}

Step 3: Build and Use the Chatbot AiService

Now, we use AiServices.builder to assemble our chatbot. We connect the interface, the model, and the chat memory.

src/main/java/com/voidon/chatbot/ChatbotExample.java (updated)

Java
package com.voidon.chatbot;

import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;

import java.util.Scanner;

public class ChatbotExample {

    public static void main(String[] args) {
        // 1. Configure the model to use the Voidon API
        ChatLanguageModel model = OpenAiChatModel.builder()
                .baseUrl("https://api.voidon.astramind.ai/v1")
                .apiKey("your-voidon-api-key")
                .modelName("auto")
                .build();

        // 2. Create a memory component
        ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);

        // 3. Build the AiService (our chatbot)
        Chatbot chatbot = AiServices.builder(Chatbot.class)
                .chatLanguageModel(model)
                .chatMemory(chatMemory)
                .build();

        // 4. Interact with the chatbot in a loop
        Scanner scanner = new Scanner(System.in);
        System.out.println("Chatbot is ready! Type 'exit' to end.");

        while (true) {
            System.out.print("You: ");
            String userInput = scanner.nextLine();

            if ("exit".equalsIgnoreCase(userInput)) {
                System.out.println("Chatbot: Goodbye!");
                break;
            }

            String response = chatbot.chat(userInput);
            System.out.println("Chatbot: " + response);
        }
        scanner.close();
    }
}

// Example Conversation:
// You: Hi, my name is Jane.
// Chatbot: Hello Jane! It's a pleasure to meet you. How can I assist you today?
// You: what is my name?
// Chatbot: Your name is Jane.

How It Works

  1. You call the chatbot.chat() method with your message.
  2. The AiServices proxy intercepts this call. It first retrieves all previous messages from the ChatMemory instance.
  3. It constructs a complete prompt including the @SystemMessage, the entire chat history, and your new message.
  4. This complete prompt is sent to the Voidon LLM.
  5. The LLM generates a response based on the full context.
  6. The AiServices proxy receives the response. Before returning it to you, it saves both your original message and the AI's new response into the ChatMemory for future turns