Google ADK — App Pattern
When to Use App vs Plain Agent
| Feature Needed | Use |
|---|---|
| Simple agent, no plugins | root_agent = Agent(...) |
| Plugins, compaction, resumability | app = App(...) |
Import
from google.adk.agents import Agent
from google.adk.apps import App, ResumabilityConfig
Basic App
from google.adk.agents import Agent
from google.adk.apps import App
root_agent = Agent(
name="my_agent",
model="gemini-2.5-flash",
instruction="You are a helpful assistant.",
tools=[],
)
app = App(
name="my_app",
root_agent=root_agent,
plugins=[],
)
App with Plugins
from google.adk.plugins import ContextFilterPlugin
app = App(
name="my_app",
root_agent=root_agent,
plugins=[
ContextFilterPlugin(num_invocations_to_keep=3),
],
)
Available Plugins
| Plugin | Purpose |
|---|---|
ContextFilterPlugin |
Limits conversation history sent to LLM |
ContextFilterPlugin
Keeps only the last N invocations in context (saves tokens):
from google.adk.plugins import ContextFilterPlugin
plugin = ContextFilterPlugin(
num_invocations_to_keep=5, # Only last 5 turns sent to model
)
Event Compaction
Summarizes old events to manage session size over long conversations:
from google.adk.apps import App
from google.adk.apps.compaction import EventsCompactionConfig
from google.adk.apps.llm_event_summarizer import LlmEventSummarizer
app = App(
name="my_app",
root_agent=root_agent,
events_compaction_config=EventsCompactionConfig(
summarizer=LlmEventSummarizer(model="gemini-2.5-flash"),
compaction_interval=10, # Compact after every 10 invocations
overlap_size=2, # Keep 2 invocations of overlap
),
)
How Compaction Works
- After
compaction_intervalnew invocations accumulate - The summarizer generates a summary of older events
- Old events are replaced with a
CompactedEventcontaining the summary overlap_sizeensures continuity between compacted and live events
Resumability
For long-running operations that may timeout or fail:
from google.adk.apps import App, ResumabilityConfig
app = App(
name="my_app",
root_agent=root_agent,
resumability_config=ResumabilityConfig(
is_resumable=True,
),
)
Resumability Requirements
- Tool calls must be idempotent (safe to retry)
- Only guarantees at-least-once execution on resume
- Temporary/in-memory state is lost on resumption
Context Cache Config
Cache static instruction content for cost savings:
from google.adk.agents import Agent
from google.adk.agents.context_cache_config import ContextCacheConfig
agent = Agent(
name="cached_agent",
model="gemini-2.5-flash",
instruction="Very long system instruction...",
context_cache_config=ContextCacheConfig(
enabled=True,
min_tokens_to_cache=2048,
),
)
App Discovery by CLI
The CLI finds apps the same way it finds agents:
# agent.py — CLI auto-discovers `app` variable
from google.adk.agents import Agent
from google.adk.apps import App
root_agent = Agent(name="my_agent", model="gemini-2.5-flash", instruction="...")
app = App(
name="my_app",
root_agent=root_agent,
plugins=[...],
)
When both root_agent and app exist, the CLI uses app.
App Parameters
| Parameter | Type | Description |
|---|---|---|
name |
str | App identifier (valid Python identifier, not "user") |
root_agent |
BaseAgent | The top-level agent |
plugins |
list[BasePlugin] | List of plugins to apply |
events_compaction_config |
EventsCompactionConfig | Event summarization settings |
resumability_config |
ResumabilityConfig | Enable pause/resume |
Key Rules
- App name must be a valid Python identifier and cannot be "user"
- When
appvariable exists in agent.py, CLI uses it overroot_agent - Plugins run on every invocation — keep them lightweight
- Compaction trades detail for token efficiency — tune
compaction_interval - Resumability requires idempotent tools
Related Skills
google-adk-session— Session services (used by App)google-adk-memory— Memory services (used by App)google-adk-deploy— Deploying apps to production