Mastering Prompts in Spring AI: Design Tips for Better Model Responses

This article explains how Spring AI handles prompts, covering the Prompt and Message APIs, role-based message types, PromptTemplate creation, custom template renderers, tokenization basics, and practical code examples to help developers craft effective AI prompts.

Xiaolong Cloud Tech Team
Xiaolong Cloud Tech Team
Xiaolong Cloud Tech Team
Mastering Prompts in Spring AI: Design Tips for Better Model Responses

Prompt Basics

Prompts are inputs that guide an AI model; in Spring AI they are built as a collection of Message objects together with a ChatOptions request. The low‑level API mirrors JDBC: ChatModel is the core model interface, while ChatClient adds higher‑level behavior such as advisors that can incorporate past interactions, additional context documents, or proxy logic.

API Overview

Prompt

The typical call is ChatModel.call(Prompt), which returns a ChatResponse. Prompt implements ModelRequest<List<Message>> and holds a list of messages and optional chat options.

public class Prompt implements ModelRequest<List<Message>> {
    private final List<Message> messages;
    private ChatOptions chatOptions;
}

Message

Message

extends Content and adds a MessageType enum (USER, ASSISTANT, SYSTEM, TOOL). Multimodal messages also implement MediaContent, which provides a collection of Media objects.

public interface Content {
    String getContent();
    Map<String, Object> getMetadata();
}
public interface Message extends Content {
    MessageType getMessageType();
}
public interface MediaContent extends Content {
    Collection<Media> getMedia();
}

Roles are defined by the MessageType enum:

public enum MessageType {
    USER("user"),
    ASSISTANT("assistant"),
    SYSTEM("system"),
    TOOL("tool");
    // …
}

PromptTemplate

PromptTemplate

creates structured prompts and delegates rendering to a TemplateRenderer. The default renderer is StTemplateRenderer, based on the open‑source StringTemplate engine and using {} as delimiters.

public interface TemplateRenderer extends BiFunction<String, Map<String, Object>, String> {
    @Override
    String apply(String template, Map<String, Object> variables);
}

Custom delimiters can be configured, for example to avoid conflicts with JSON syntax:

PromptTemplate promptTemplate = PromptTemplate.builder()
    .renderer(StTemplateRenderer.builder()
        .startDelimiterToken('<')
        .endDelimiterToken('>')
        .build())
    .template("""
        Tell me the names of 5 movies whose soundtrack was composed by <composer>.
    """)
    .build();

String prompt = promptTemplate.render(Map.of("composer", "John Williams"));

PromptTemplate Interfaces

PromptTemplateStringActions

String render() and String render(Map<String,Object>). PromptTemplateMessageActions – creates Message objects, optionally with media or a model map. PromptTemplateActions – extends PromptTemplateStringActions and adds Prompt create(...) overloads that accept ChatOptions and/or a model map.

public interface PromptTemplateStringActions {
    String render();
    String render(Map<String, Object> model);
}
public interface PromptTemplateMessageActions {
    Message createMessage();
    Message createMessage(List<Media> mediaList);
    Message createMessage(Map<String, Object> model);
}
public interface PromptTemplateActions extends PromptTemplateStringActions {
    Prompt create();
    Prompt create(ChatOptions modelOptions);
    Prompt create(Map<String, Object> model);
    Prompt create(Map<String, Object> model, ChatOptions modelOptions);
}

Usage Examples

Simple variable substitution:

PromptTemplate promptTemplate = new PromptTemplate("Tell me a {adjective} joke about {topic}");
Prompt prompt = promptTemplate.create(Map.of("adjective", adjective, "topic", topic));
return chatModel.call(prompt).getResult();

Combining system and user messages:

String userText = """
    Tell me about three famous pirates from the Golden Age of Piracy and why they did.
    Write at least a sentence for each pirate.
""";
Message userMessage = new UserMessage(userText);

String systemText = """
    You are a helpful AI assistant that helps people find information.
    Your name is {name}
    You should reply to the user's request with your name and also in the style of a {voice}.
""";
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemText);
Message systemMessage = systemPromptTemplate.createMessage(Map.of("name", name, "voice", voice));

Prompt prompt = new Prompt(List.of(userMessage, systemMessage));
List<Generation> response = chatModel.call(prompt).getResults();

Loading a template from a Spring Resource:

@Value("classpath:/prompts/system-message.st")
private Resource systemResource;

SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemResource);

Prompt Engineering

Effective prompts typically contain four components: clear instructions, optional external context, the user input, and an output indicator (e.g., a JSON format). Community studies have shown that phrasing such as “Take a deep breath, solve the problem step by step” can noticeably improve problem‑solving efficiency.

Tokens

Tokenization converts text into model‑consumable tokens; roughly three‑quarters of a word equals one token. Token counts affect billing (both input and output tokens are charged) and define a model’s context window. Example limits: GPT‑3 ≈ 4 K tokens, Claude 2 ≈ 100 K tokens, some research models ≈ 1 M tokens. Input exceeding the limit is ignored, so prompts should be concise. The response metadata includes token usage for cost and usage monitoring.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaSpring AITokenizationMessageAI integrationPromptTemplatePrompts
Xiaolong Cloud Tech Team
Written by

Xiaolong Cloud Tech Team

Xiaolong Cloud Tech Team

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.