Module 13.5: Extending ADK - Custom Persistence with Firestore
This module sits in Part 2 (Tools & Capabilities) rather than in the Part 4 state/memory modules on purpose: writing a custom BaseSessionService is itself an act of extending the ADK's toolkit with your own infrastructure, not a production-operations concern like the topics in Part 4. Think of it as "building a new kind of tool," just one that stores state instead of taking action.
Theoryβ
The Power of Extensibilityβ
One of the key strengths of ADK 2.0 is its pluggable architecture. While the core library provides built-in services for common tasks (like InMemorySessionService or DatabaseSessionService for SQL), enterprise requirements often demand integration with specific technologies.
Instead of being locked into a fixed set of database providers, you can extend the ADK by implementing your own services.
The BaseSessionService Interfaceβ
In the ADK, all session persistence is governed by a single abstract class: BaseSessionService.
Any class that inherits from BaseSessionService and implements its core methods can be used by the Runner. This allows you to store agent conversations and state in any databaseβfrom Redis and MongoDB to Google Cloud Firestore.
Why Implement a Custom Session Service?β
- Organizational Standards: Your company may already use Firestore as its primary serverless database.
- Performance & Latency: You might need sub-second latency for a high-traffic customer bot. In this case, you could implement a custom service using Redis to cache session state in-memory, ensuring near-instant response times that a standard persistent database might not provide.
- Specific Features: You might want to leverage Firestore's real-time listeners or its native integration with Firebase.
- Cost & Scaling: Firestore offers a specialized pricing model and automatic scaling that might be better suited for your agent's traffic patterns than a traditional SQL database.
How it works: Dependency Injectionβ
The ADK uses Dependency Injection at the Runner level. When you instantiate a Runner, you don't have to use the default InMemoryRunner. Instead, you can provide your own custom session service instance.
# Custom implementation (which we will build in this lab)
custom_service = FirestoreSessionService(project_id="my-project")
# Inject it into the base Runner
runner = Runner(
app=my_app,
session_service=custom_service
)
From this point on, every call to runner.run() or runner.run_async() will automatically use your Firestore logic to save and load data, without you having to change a single line of agent instruction or tool code.
Key Takeawaysβ
- ADK is extensible: You can plug in custom implementations for sessions, artifacts, and more.
- Decoupled Logic: Your agent's "brain" (intelligence) is completely separated from its "memory" (storage technology).
- Enterprise Ready: Building custom providers is the standard way to integrate ADK into existing enterprise data ecosystems.