This content originally appeared on DEV Community and was authored by Mariano Álvarez 🇨🇷
In my previous post, I walked through how to build a basic AI agent using ADK. It’s exciting to get an agent running and see it respond to prompts — but once the session ends, that context is gone. It has no memory of anything that happened before.
This is fine for demos, but if you’re aiming to build something real then you’ll quickly hit a wall.
Fortunately, ADK gives us tools to fix that.
Why Sessions Matter
Let’s say you build a ticket finder agent that helps someone search for flights. During the conversation, the user mentions that they prefer Delta and want to fly out of San Francisco.
Without session management, the agent forgets all of that context between interactions. So even if the user follows up with, “What about something cheaper?” the agent has no clue what they’re referring to.
That’s where Session comes in.
What is a Session?
In ADK, a Session is an object that represents a conversation. It keeps track of who the user is, what app (agent) is running, what’s been said, what tools were called, and any custom state you want to track along the way.
Each session includes:
Basic identifiers
• id: A unique session ID
• appName: Name of the agent application
• userId: The user having the conversation
Events
A chronological list of everything that happens — user messages, tool calls, agent replies, etc.
State
A dictionary that stores structured data the agent can access and modify during the session.
lastUpdateTime
Timestamp for the latest interaction in the session.
Choosing the Right SessionService
To use sessions, you need a session service. ADK gives you a few out-of-the-box options, depending on your environment:
1. InMemorySessionService
This is great for local development or protyping. Everything is stored in memory — and wiped as soon as the app restarts.
from google.adk.sessions import InMemorySessionService
session_service = InMemorySessionService()
2. DatabaseSessionService
This option is for when you’re running something in production. It stores sessions in a relational database and uses a built-in migration system to manage the schema.
from google.adk.sessions import DatabaseSessionService
db_url = "your_database_url"
session_service = DatabaseSessionService(db_url=db_url)
A heads-up: ADK manages the database schema internally, so if you’re integrating this with your existing database, I strongly recommend using a dedicated schema with a separate user that has limited access.
3. VertexAiSessionService
If you’re on Google Cloud and want tight integration with Vertex AI, you can use this session service to leverage Google’s managed infrastructure.
from google.adk.sessions import VertexAiSessionService
session_service = VertexAiSessionService(
project="your-gcp-project-id",
location="us-central1"
)
Creating a Session
Once your session service is initialized, you can create a new session like this:
session = await session_service.create_session(
app_name="ticket_finder_app",
user_id="marianocodes",
state={"preferred_airline": "delta"}
)
You’ll get back a session object that you can attach events to, store state in, and use throughout the conversation.
Working with Session State
The state object is a dictionary you can use to store anything your agent should remember while the session is active.
If you’re a frontend developer, think of it like a Redux store scoped to the conversation. If you’re coming from a backend background, you can think of it like a session object tied to a user’s request — only it’s more flexible.
State Guidelines
A few things to keep in mind:
1. Use primitives — strings, numbers, booleans. Don’t store complex objects or custom classes.
2. Scope your data using prefixes:
No prefix
session.state["last_message"] = "hello"
visible only during this sessionuser:
session.state["user:theme"] = "dark"
shared across all of the user’s sessionsapp:
session.state["app:language"] = "en"
shared across the apptemp:
session.state["temp:step"] = "waiting_for_payment"
temporary info, not persisted long-term
How to Update State
There are multiple ways to update the session state, depending on the structure of your agent.
1. Via output_key
This is the simplest method. If your agent returns a value and you want to store it automatically:
ticket_finder_agent = LlmAgent(
name="Ticket Finder",
model="gemini-2.5-flash",
instruction="...",
output_key="best_ticket"
)
Whatever value is returned from the model will be stored under session.state["best_ticket"].
2. Via ToolContext or CallbackContext
Inside tool or callback functions, you get access to the session’s context. You can use that to manually update state at any point.
def purchase_ticket(tool_context: ToolContext):
context.state["waiting_for_purchase"] = False
This is useful when you want to track a specific action or condition and update state based on logic inside your tools.
3. Using EventActions.state_delta
This gives you full control — you define what changes in the state and register that as a system-level event.
state_changes = {
"ticket_in_screen": "AV-258"
}
actions = EventActions(state_delta=state_changes)
event = Event(
invocation_id="inv_state_update",
author="system",
actions=actions,
timestamp=time.time()
)
await session_service.append_event(session, event)
It’s more verbose, but also more precise when you want to track a series of changes or attach metadata.
Adding Memory
Sessions let your agent remember context during a conversation. But what about after the session ends?
That’s where memory comes in.
InMemoryMemoryService
This lets your agent access information during a single session — similar to InMemorySessionService
but not the same.
VertexAiRagMemoryService (GCP)
ADK includes a memory service built on RAG (retrieval-augmented generation). It stores content as embeddings and lets your agent retrieve relevant context across sessions.
from google.adk.memory import VertexAiRagMemoryService
memory_service = VertexAiRagMemoryService(
rag_corpus="projects/your-gcp-project-id/locations/us-central1/ragCorpora/your-corpus-id",
similarity_top_k=5,
vector_distance_threshold=0.7
)
To use it inside an agent:
from google.adk.tools import load_memory
ticket_finder_agent = LlmAgent(
name="Ticket Finder",
model="gemini-2.5-flash",
instruction="...",
tools=[load_memory]
)
Then, once the session is done, you can store its content:
session = await runner.session_service.get_session(
app_name=APP_NAME,
user_id=USER_ID,
session_id=session_id
)
await memory_service.add_session_to_memory(session)
What If You’re Not Using GCP?
I got you, You can still build something similar.
Under the hood, load_memory
just performs a similarity search using Vertex AI. You can replicate this using your own vector DB (like Pinecone, Qdrant, or AstraDB). You just need to handle chunking, embedding, and retrieval on your own.
Here’s a peek at what the function looks like behind the scenes:
What's next?
We’ve covered how to set up an agent — and now, how to give it memory. But so far, everything’s only been accessible through the testing UI.
What if you want to run it in a real web app?
Want to support my work? A quick like goes a long way ❤️.
This content originally appeared on DEV Community and was authored by Mariano Álvarez 🇨🇷

Mariano Álvarez 🇨🇷 | Sciencx (2025-06-29T16:42:54+00:00) Adding Sessions and Memory to Your AI Agent with Agent Development Kit (ADK). Retrieved from https://www.scien.cx/2025/06/29/adding-sessions-and-memory-to-your-ai-agent-with-agent-development-kit-adk/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.