skip to content

In Spring AI, what is a Prompt, and what roles do SystemMessage and UserMessage play inside it?

level: juniorimportance: must knowfreq 70%

answer

  1. Prompt = List<Message> + ChatOptions
  2. SYSTEM sets behavior, USER is the question
  3. ASSISTANT = replayed history
  4. MessageType role enum
  5. chatModel.call(Prompt) -> ChatResponse

basics

~10 s

A Prompt is the request sent to the model: a list of Messages plus optional options. A SystemMessage sets the model's behavior/persona; a UserMessage carries the user's actual input.

solid answer

~40 s

In Spring AI a `Prompt` is the object you pass to a `ChatModel`/`ChatClient`. It holds an ordered list of `Message` objects and optional `ChatOptions` (temperature, model, etc.). Each `Message` has a role via `MessageType`: `SystemMessage` (SYSTEM) sets global instructions, persona, tone, or rules the model should follow; `UserMessage` (USER) is the end user's question or input; `AssistantMessage` (ASSISTANT) represents a prior model reply, used to replay conversation history in multi-turn chats. You typically build a Prompt with one SystemMessage plus one UserMessage: `new Prompt(List.of(new SystemMessage("You are a terse assistant"), new UserMessage(userInput)))`. The framework serializes these roles into the provider's native chat format (e.g. system/user/assistant messages).

code

java · 21 lines
java
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import java.util.List;

public class Greeter {
    private final ChatModel chatModel;

    public Greeter(ChatModel chatModel) { this.chatModel = chatModel; }

    public String greet(String name) {
        Prompt prompt = new Prompt(List.of(
            new SystemMessage("You are a friendly assistant. Reply in one short sentence."),
            new UserMessage("Greet a user named " + name)
        ));
        ChatResponse response = chatModel.call(prompt);
        return response.getResult().getOutput().getText();
    }
}

go deeper

for a junior

Know that Prompt holds messages, and SystemMessage vs UserMessage is behavior vs input.

for a middle

Should build a Prompt with both roles and read the reply via ChatResponse.getResult().getOutput().getText().

for a senior

Explains role semantics per provider, multi-turn history with AssistantMessage, and where ChatOptions live.

for a principal

Discusses why system-role separation aids prompt-injection defense and how providers normalize/limit system messages.

**What a Prompt is.** In Spring AI (`org.springframework.ai.chat.prompt.Prompt`), a `Prompt` is the complete request you hand to a `ChatModel.call(Prompt)` or build via the higher-level `ChatClient`. It bundles two things: (1) an ordered `List<Message>` — the conversation content — and (2) optional `ChatOptions` (model name, temperature, maxTokens, etc.). A Prompt is provider-agnostic; the specific model implementation (OpenAI, Anthropic, Ollama…) translates it into that provider's wire format. **Messages and roles.** A `Message` is one turn of conversation with a `MessageType` role. The main implementations: - `SystemMessage` (role SYSTEM): high-level instructions that shape *how* the model behaves — persona, tone, constraints, output rules. It is not the user's question; it frames the whole interaction. - `UserMessage` (role USER): the actual human input/question for this turn. It can also carry media (images) for multimodal models. - `AssistantMessage` (role ASSISTANT): a previous model response. You include these to give the model memory of earlier turns in a multi-turn conversation. - `ToolResponseMessage` (role TOOL): results returned from tool/function calls, fed back so the model can continue. **Typical construction.** ```java Prompt prompt = new Prompt(List.of( new SystemMessage("You are a concise Java tutor. Answer in one sentence."), new UserMessage("What is a bean?") )); ChatResponse resp = chatModel.call(prompt); String text = resp.getResult().getOutput().getText(); ``` With `ChatClient` the roles are set fluently: `chatClient.prompt().system("...").user("...").call()`. **Why roles matter.** Providers treat the system role as privileged/global guidance; putting rules there rather than concatenating them into the user text produces more reliable behavior and cleaner separation of instructions from data. Mixing everything into one UserMessage works but blurs that separation and makes prompt-injection defense harder. **Gotchas.** - Some providers historically supported only a single system message or none; Spring AI normalizes this per-provider, but stacking many SystemMessages is not always honored. - Message order matters — the model reads them in sequence; the latest UserMessage is the current turn. - `getText()` (formerly `getContent()`) reads a message's text; the API was renamed across Spring AI versions, so match your version. - A Prompt with no UserMessage is usually not what you want; the model has nothing to respond to. **When to use what.** Use a SystemMessage for durable behavior/rules, a UserMessage for the request, and AssistantMessage history when you manage multi-turn context manually (though `ChatMemory` / advisors usually automate that).

  • Where do you set temperature or the model name for a single call?
    In the optional ChatOptions passed to the Prompt (e.g. new Prompt(messages, ChatOptions.builder().temperature(0.2).build())), or via ChatClient's .options(...). These override the client's defaults for that call.
  • What is the difference between a UserMessage and an AssistantMessage?
    UserMessage (USER role) is the human's input for the current turn; AssistantMessage (ASSISTANT role) is a prior model reply you include to give the model conversation memory. You don't create AssistantMessages for the current answer — the model produces those.

saying these in an interview costs you the question

  • Thinking a Prompt is just a raw string with no message roles
  • Claiming SystemMessage carries the user's question
  • Believing you must create an AssistantMessage for the model's current answer
  • Assuming roles are cosmetic and identical to concatenating text

context