Spring AI for Beginners

Module 4 of 17

Module 4: Your First Spring AI Chat App

4 min read740 words
What you'll learn
Send a prompt to an AI model with `ChatClient`Explain the difference between stateless and stateful chatUnderstand why memory matters for real conversationsRead the core code of a working chat app

"Two lines of Spring AI and your app can talk to an AI model. Let's write them — and then make the AI remember you."

Level: Beginner · Time: ~2–3 days · Prerequisites: Modules 1–3

Learning Objectives

By the end of this module, you will be able to:

  • Send a prompt to an AI model with ChatClient
  • Explain the difference between stateless and stateful chat
  • Understand why memory matters for real conversations
  • Read the core code of a working chat app

1. Meet the ChatClient

Spring AI's main tool for talking to a model is the ChatClient. It has a friendly, fluent style: build a prompt, call the model, get the content.

java
[object Object], ,[object Object], ,[object Object], chatClient
        .prompt()
        .user(,[object Object],)
        .call()
        .content();

That's it. ChatClient handles the HTTP request, authentication, and response parsing. You wire it up once as a bean (remember dependency injection from Module 2) and use it anywhere.

Concept: ChatClient is a thin, friendly wrapper over the raw model. It's the object you'll use in almost every module. Learn it well and everything else clicks into place.

2. The Problem: Models Forget

AI language models are stateless — every request is treated as brand new. If you tell the model "My name is John" and then ask "What's my name?", it has no idea. It never saw your first message; each call stands alone.

Stateless calls forget; stateful calls remember using conversation memory
Stateless calls forget; stateful calls remember using conversation memory

This is fine for one-off questions, but useless for a real assistant. Customer-support bots, tutors, and copilots all need to remember what was said.

Explain like I'm new: A stateless model is like talking to someone with no short-term memory. Every sentence, they've forgotten the last one. Useful for trivia, hopeless for a conversation.

3. Two Panels, One Model

The starter app shows both behaviors side by side, using the same gpt-4o-mini model — the only difference is memory:

  • Stateless chat (left): each message is independent. Say "My name is John," then ask "What's my name?" → it can't tell you.
  • Stateful chat (right): the app keeps a running history. Same two messages → it answers "John."

Try this: Run both panels and send the exact same two messages to each. Seeing one panel forget and the other remember — with the same model — makes the value of memory unforgettable.

4. The Code Behind Each Panel

The stateless endpoint builds a plain ChatClient and calls it directly:

java
[object Object], ,[object Object], ,[object Object], chatClient.prompt().user(message).call().content();

The stateful endpoint adds a memory advisor (you'll go deep on this next module). The advisor quietly loads the past messages before each call and saves the new exchange after:

java
[object Object], ,[object Object], ,[object Object], chatClient.prompt()
        .user(message)
        .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, conversationId))
        .call()
        .content();

Same model, same ChatClient API — one just has memory attached.

Real-world use case: A help-desk assistant must remember the customer's order number mentioned three messages ago. Stateful chat makes that automatic; stateless chat would force the user to repeat themselves every time.

5. From Console to Web

Because it's Spring Boot, exposing your chat over the web is just a @RestController method that takes the user's message and returns the model's reply. The browser sends text, your controller calls the ChatClient, and the answer comes back — a complete AI feature in a few lines.

Common mistake: Building a "chatbot" with a stateless call and then wondering why it feels dumb and forgetful. If your assistant should remember anything within a session, you need memory — the topic of the next module.

✅ Checkpoint

  1. Which Spring AI object do you use to send prompts to a model?
  2. Why can't a stateless chat answer "What's my name?" after you introduced yourself?
  3. What is the only difference between the two chat panels?

Answers: 1) ChatClient. 2) Each request is independent — the model never saw your earlier message. 3) The stateful panel attaches a memory advisor; both use the same model.

Key Takeaway: ChatClient is your everyday tool for talking to an AI model in Spring AI — build a prompt, .call(), read the .content(). Models are stateless by default, so a real conversation needs memory. The starter app proves the point by running stateless and stateful chat side by side on the same model; only the one with a memory advisor can remember what you said.

Further Learning

Part of "Spring AI for Beginners." Adapted from Microsoft's open Spring AI curriculum (MIT License).