Langchain4j defines five types of ChatMessages, each representing a distinct communication role or purpose in a conversation pipeline with LLM. Understanding these is key to designing robust, context-aware LLM integrations.
1. Types of Chat messages
1.1. UserMessage
This message originates from the end user (a person or your application logic). It represents a direct query or command.
Example
UserMessage userMessage = new UserMessage("What's the weather in London today?");
1.2. AiMessage
This message is the LLM’s response to a UserMessage. It can either be a text reply or a structured command to invoke a tool.
Example
AiMessage aiTextResponse = new AiMessage("It looks sunny in London with a high of 22°C.");
This is what you usually get back from the LLM.
1.3. ToolExecutionResultMessage
This message is used to return the result of executing a tool that the AI requested in a previous ToolExecutionRequest.
Example
ToolExecutionResultMessage resultMessage = new ToolExecutionResultMessage("toolId1", "temp_prediction_tool", "Current temperature in London is 22°C.");
ToolExecutionResultMessage is used in AI-to-tool roundtrips in tool-augmented LLM systems.
1.4. SystemMessage
This is a message from the developer or system that sets up rules, behaviors, tone, or context for the AI model.
Example
SystemMessage systemMessage = new SystemMessage("You are a helpful assistant that predicts Wather conditions");
SystemMessages are explicit instructions to the model about:
· What role it should take (e.g., “You are a medical assistant”)
· How it should respond (e.g., “Always reply formally”)
· What it should or should not do (e.g., “Do not answer questions about politics”)
LLMs are trained to pay more attention to instructions in system prompts, so even if a UserMessage contradicts it, the model will often follow the SystemMessage instead.
1.5. CustomMessage (For Advanced Use)
A message type that allows arbitrary attributes. Only supported by specific chat models (like Ollama).
Example
Map<String, Object> attributes = Map.of("type", "meta", "value", "some extra context"); CustomMessage customMessage = new CustomMessage(attributes);
2. What’s happening in the simplest LLM chat scenario?
When you want to talk to the AI using Langchain4j, you can send just one message like this:
UserMessage message = new UserMessage("Hi"); ChatResponse response = chatModel.chat(message);
This is similar to how you might send just a string like "Hi" to a chat method, but there's a big difference. Instead of just getting the AI’s reply as a plain string, now you get a full ChatResponse object.
public class ChatResponse { private final AiMessage aiMessage; private final ChatResponseMetadata metadata; }
2.1 AiMessage
The ChatResponse contains an AiMessage, which represents the actual reply generated by the AI. Here’s how you can extract the AI’s response text and any tool execution requests from it.
AiMessage aiMessage = response.aiMessage(); // Get the AI's text response String responseFromLLM = aiMessage.text(); // Get any tool execution requests made by the AI List<ToolExecutionRequest> toolsToExecute = aiMessage.toolExecutionRequests(); // Print the response System.out.println("AI Response: " + responseFromLLM); // Print tool execution details (if any) for (ToolExecutionRequest toolExecutionRequest : toolsToExecute) { System.out.println( "Tool ID: " + toolExecutionRequest.id() + ", Name: " + toolExecutionRequest.name() + ", Arguments: " + toolExecutionRequest.arguments() ); }
2.2 ChatResponseMetadata
This contains additional details about the model’s response, including:
TokenUsage:
Indicates how many tokens were used:
· In the input messages
· In the AI’s response
· Total tokens used in the entire interaction
This is especially useful for tracking usage costs, as LLM providers typically charge based on the number of tokens processed.
FinishReason:
· Explains why the model stopped generating a response.
· In most cases, the reason will be FinishReason.STOP, which means, the AI completed its response naturally.
Here’s how you can extract and log this metadata
ChatResponseMetadata chatResponseMetadata = response.metadata(); FinishReason finishReason = chatResponseMetadata.finishReason(); String modelName = chatResponseMetadata.modelName(); TokenUsage tokenUsage = chatResponseMetadata.tokenUsage(); System.out.println("Model stopped because: " + finishReason); System.out.println("Model used: " + modelName); System.out.println("Input tokens: " + tokenUsage.inputTokenCount()); System.out.println("Output tokens: " + tokenUsage.outputTokenCount()); System.out.println("Total tokens: " + tokenUsage.totalTokenCount());
Find the below working application.
ChatMessagesDemo.java
package com.sample.app.chatmodels; import java.util.List; import dev.langchain4j.agent.tool.ToolExecutionRequest; import dev.langchain4j.data.message.AiMessage; import dev.langchain4j.data.message.UserMessage; import dev.langchain4j.model.chat.ChatModel; import dev.langchain4j.model.chat.response.ChatResponse; import dev.langchain4j.model.chat.response.ChatResponseMetadata; import dev.langchain4j.model.ollama.OllamaChatModel; import dev.langchain4j.model.output.FinishReason; import dev.langchain4j.model.output.TokenUsage; public class ChatMessagesDemo { public static void main(String[] args) { // Create the Ollama language model ChatModel chatModel = OllamaChatModel.builder().baseUrl("http://localhost:11434").modelName("llama3.2").build(); UserMessage userMessage = new UserMessage("Hi"); ChatResponse response = chatModel.chat(userMessage); AiMessage aiMessage = response.aiMessage(); String responseFromLLM = aiMessage.text(); List<ToolExecutionRequest> toolsToExecute = aiMessage.toolExecutionRequests(); System.out.println("responseFromLLM : " + responseFromLLM); for (ToolExecutionRequest toolExecutionRequest : toolsToExecute) { System.out.println(toolExecutionRequest.id() + " " + toolExecutionRequest.name() + " " + toolExecutionRequest.arguments()); } ChatResponseMetadata chatResponseMetadata = response.metadata(); FinishReason finishReason = chatResponseMetadata.finishReason(); String modelName = chatResponseMetadata.modelName(); TokenUsage tokenUsage = chatResponseMetadata.tokenUsage(); System.out.println("The reason why a model call finished : " + finishReason); System.out.println("modelName : " + modelName); System.out.println("inputTokenCount : " + tokenUsage.inputTokenCount()); System.out.println("outputTokenCount : " + tokenUsage.outputTokenCount()); System.out.println("totalTokenCount : " + tokenUsage.totalTokenCount()); } }
Output
responseFromLLM : How can I assist you today? The reason why a model call finished : STOP modelName : llama3.2 inputTokenCount : 26 outputTokenCount : 8 totalTokenCount : 34
Previous Next Home
No comments:
Post a Comment