|
This version is still in development and is not considered stable yet. For the latest stable version, please use Spring AI 2.0.1! |
Session Memory
Session memory keeps a conversation as an append-only log of events, and builds the prompt the model sees from a view of that log. Where Chat Memory stores a flat list of messages per conversation id, a session adds what an agent needs over a long conversation:
-
Structured events. Every message is a
SessionEventwith an id, a timestamp, its session and metadata; other event types record what happened in the same log. -
Turn-aware compaction. Triggers decide when the history grew too large, and a strategy decides what leaves the view, always on a turn boundary, so the model never sees a tool call without its result or an answer without its question. A compaction never changes the log: it appends a boundary that defines the view from then on.
-
A repository SPI.
SessionRepositoryhas an in-memory implementation for tests and a JDBC one for production; a store of your own passes the same contract tests.
The session is the state; what runs on it is not.
A ChatClient with the session advisors is one such runtime, a harness: it reads the view, calls the model, appends what happened, and keeps nothing of its own, so a turn can be run by any instance, and the next turn by another one.
Another harness, a loop of your own for example, runs on the same session through the same SessionService.
The follow-ups build on this split: the session will carry its status, the turn that runs, the one that waits for a decision, and every harness will read and set it the same way.
Modules
| Module | Artifact | Contents |
|---|---|---|
Session |
|
The core: |
Session Advisor |
|
The |
JDBC Session |
|
|
Auto-configuration |
|
The |
Starter |
|
All of the above with Spring Boot’s JDBC starter. |
Quick Start
Add the starter:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-session-jdbc</artifactId>
</dependency>
With a DataSource on the classpath, Spring Boot creates a JdbcSessionRepository and a SessionService bean, detects the SQL dialect from the database metadata, and initializes the schema of an embedded database.
For PostgreSQL or MySQL in development, initialize the schema with spring.ai.session.repository.jdbc.initialize-schema=always.
Wire the advisors into a ChatClient and pass a session id with every call:
@Bean
ChatClient chatClient(ChatModel chatModel, SessionService sessionService) {
return ChatClient.builder(chatModel)
.defaultAdvisors(SessionAdvisors.builder(sessionService)
.compaction(new TurnCountTrigger(20), WindowCompactionStrategy.builder().lastTurns(10).build())
.build())
.build();
}
String answer = chatClient.prompt()
.user("Hello!")
.advisors(SessionAdvisors.session("session-abc"))
.call()
.content();
A session that does not exist yet is created on first use. The session id is required on every call: there is no fallback, because a shared default session would silently merge the history of different users.
Without Spring Boot, or in a test, build the service on the in-memory repository:
SessionService sessionService = DefaultSessionService.builder()
.sessionRepository(InMemorySessionRepository.builder().build())
.build();
InMemorySessionRepository is for tests and demos: sessions are lost on restart and not shared across instances.
|
Where to go next
-
Concepts: sessions, events, turns, the active view and the
SessionServiceAPI. -
Event Filtering: what a read returns, and why a window keeps turns whole.
-
Compaction: triggers, the window strategy, summarization and how a pass is recorded.
-
System Messages: why the system prompt is configuration, and the opt-in to store it.
-
ChatClient Integration: the advisors, their context keys and what they store.
-
JDBC Repository: the tables, the dialects, the auto-configuration properties, and how to write a repository of your own.