The ADK development environment provides tooling for rapid agent iteration, testing, and debugging. The google-adk-dev module includes a Spring Boot development server, an Angular-based browser UI, agent auto-discovery, and testing infrastructure. This page provides an overview of the development tooling ecosystem; detailed documentation for each component is available in the following sub-sections:
For production deployment patterns, see Deployment Patterns.
The ADK supports distinct operational modes optimized for different use cases:
| Aspect | Development Mode | Production Mode |
|---|---|---|
| Entry Point | mvn exec:java or mvn google-adk:run | AdkWebServer.start(agents...) |
| Agent Loading | CompiledAgentLoader (auto-discovery) | AgentStaticLoader (explicit) |
| Agent Discovery | Scans source/build directories for ROOT_AGENT fields | Pre-created agent instances passed programmatically |
| Session Service | InMemorySessionService | Pluggable (e.g., Firestore) |
| Artifact Service | InMemoryArtifactService | Pluggable (e.g., Cloud Storage) |
| Memory Service | InMemoryMemoryService | Pluggable (e.g., Vertex Memory) |
| Hot Reload | Supported (YAML config monitoring) | Not applicable |
| Dev UI | Included at /dev-ui | Optional |
| Configuration | Zero-configuration for quick start | Explicit service configuration |
Development mode prioritizes developer experience with automatic discovery and in-memory implementations. Production mode provides deterministic initialization and pluggable service implementations for persistence and scalability.
Sources: dev/src/main/java/com/google/adk/web/AdkWebServer.java42-175 tutorials/city-time-weather/README.md19-62
The development server is a Spring Boot application that provides web endpoints, agent execution, and the development UI.
The AdkWebServer class serves as both a Spring Boot application class and a programmatic server launcher. It configures service beans, web resource handlers, and integrates with the agent loading system.
Sources: dev/src/main/java/com/google/adk/web/AdkWebServer.java42-175
The server provides singleton beans for core services with in-memory implementations:
InMemorySessionService for conversation state managementInMemoryArtifactService for file storageInMemoryMemoryService for memory managementThese in-memory implementations provide zero-configuration setup for development. Production deployments can replace these beans with persistent implementations.
Sources: dev/src/main/java/com/google/adk/web/AdkWebServer.java52-92
The server maps static resources and view controllers:
The resource handler (dev/src/main/java/com/google/adk/web/AdkWebServer.java98-126) serves static content from either:
adk.web.ui.dir system propertybrowser/ (default)The view controller configuration (dev/src/main/java/com/google/adk/web/AdkWebServer.java132-137) redirects the root path to the dev UI and forwards dev UI requests to index.html.
Sources: dev/src/main/java/com/google/adk/web/AdkWebServer.java98-137
The ADK provides two agent loading strategies through the AgentLoader interface:
Sources: dev/src/main/java/com/google/adk/web/AgentLoader.java22-77 dev/src/main/java/com/google/adk/web/CompiledAgentLoader.java47-377 dev/src/main/java/com/google/adk/web/AgentStaticLoader.java30-67
CompiledAgentLoader automatically discovers agents by scanning directories for compiled classes containing ROOT_AGENT fields. It is enabled by default or when adk.agents.loader=compiled.
Discovery Algorithm:
sourceDir from AgentLoadingPropertiestarget/classes or similar)buildOutputDirsURLClassLoader for the build output directory.class files in the directoryROOT_AGENT of type BaseAgentConfiguration Properties:
| Property | Default | Description |
|---|---|---|
adk.agents.source-dir | . | Base directory to scan for agents |
adk.agents.build-output-dirs | ["target/classes", "build/classes/java/main", "build/classes"] | Build output directories to search |
Example Directory Structure:
source-dir/
├── target/classes/ # Maven build output (scanned if exists)
│ └── com/example/
│ └── MyAgent.class # Contains ROOT_AGENT field
├── agent1/ # Agent unit directory
│ └── target/classes/
│ └── Agent1.class
└── agent2/ # Agent unit directory
└── build/classes/
└── Agent2.class
Thread Safety: Uses Suppliers.memoize() to ensure each agent is created only once when first requested. The agent map is immutable after construction.
Sources: dev/src/main/java/com/google/adk/web/CompiledAgentLoader.java47-377 dev/src/main/java/com/google/adk/web/config/AgentLoadingProperties.java22-44
AgentStaticLoader takes pre-created agent instances and registers them by name. This is used when calling AdkWebServer.start(agents...) or when adk.agents.loader=static.
The loader stores agents in an ImmutableMap<String, BaseAgent> keyed by agent name (dev/src/main/java/com/google/adk/web/AgentStaticLoader.java44-46). The loadAgent() method performs a direct map lookup without reflection or dynamic loading.
Example Usage:
This approach:
adk.agents.loader=static system property (dev/src/main/java/com/google/adk/web/AdkWebServer.java155)ApplicationContextInitializer (dev/src/main/java/com/google/adk/web/AdkWebServer.java163-171)AgentStaticLoader instance as a singleton bean before context refreshThread Safety: The agent map is immutable after construction, making this loader fully thread-safe for concurrent access.
Sources: dev/src/main/java/com/google/adk/web/AgentStaticLoader.java30-67 dev/src/main/java/com/google/adk/web/AdkWebServer.java153-174
Start the server with automatic agent discovery:
This executes AdkWebServer.main() which:
SpringApplication.run() (dev/src/main/java/com/google/adk/web/AdkWebServer.java148)CompiledAgentLoader by default (or when adk.agents.loader=compiled)ROOT_AGENT fieldsSources: dev/src/main/java/com/google/adk/web/AdkWebServer.java144-150 tutorials/city-time-weather/README.md21-33
Start the server with explicit agent instances:
Run with:
The start() method:
adk.agents.loader=static to disable CompiledAgentLoader (dev/src/main/java/com/google/adk/web/AdkWebServer.java155)ApplicationContextInitializer (dev/src/main/java/com/google/adk/web/AdkWebServer.java163-171)AgentStaticLoader as a singleton bean with the provided agentsSources: dev/src/main/java/com/google/adk/web/AdkWebServer.java153-174 tutorials/city-time-weather/src/main/java/com/google/adk/tutorials/CityTimeWeather.java98-100
| System Property | Default | Description |
|---|---|---|
adk.agents.loader | compiled | Agent loader type: compiled or static |
adk.agents.source-dir | . | Source directory for CompiledAgentLoader |
adk.web.ui.dir | (classpath) | Directory for dev UI static resources |
server.port | 8080 | HTTP server port |
org.apache.tomcat.websocket.DEFAULT_BUFFER_SIZE | 10485760 (10MB) | WebSocket buffer size |
Sources: dev/src/main/java/com/google/adk/web/AdkWebServer.java49-50 dev/src/main/java/com/google/adk/web/AdkWebServer.java146-147 dev/src/main/java/com/google/adk/web/config/AgentLoadingProperties.java26-27
The Telemetry utility class provides OpenTelemetry-based tracing for agent execution, capturing LLM interactions, tool calls, and data flow.
Key Tracing Functions:
| Function | Purpose | Key Attributes |
|---|---|---|
traceToolCall() | Records tool invocation arguments | tool_call_args (JSON) |
traceToolResponse() | Records tool execution results | event_id, tool_response, invocation_id, session_id |
traceCallLlm() | Records LLM request/response pairs | llm_request, llm_response, gen_ai.request.model, invocation_id, session_id, event_id |
traceSendData() | Records data sent to agent/model | data (JSON), invocation_id, session_id |
traceFlowable() | Manages OpenTelemetry scope for RxJava Flowables | Scope lifecycle via doFinally |
LLM Request Filtering:
The buildLlmRequestForTrace() method (core/src/main/java/com/google/adk/Telemetry.java121-140) filters the LLM request before tracing to exclude binary data:
model, config (generation config), contents (text parts only)inlineData (binary content like images/audio)This reduces trace payload size while preserving essential debugging information.
RxJava Scope Management:
traceFlowable() (core/src/main/java/com/google/adk/Telemetry.java256-266) ensures OpenTelemetry context propagation across RxJava async boundaries:
spanContext.makeCurrent()doFinally() to close the scope when the stream terminates (success, error, or cancellation)This pattern is necessary because RxJava Flowables execute lazily—operators run at subscription time, not construction time. Using try-with-resources would close the scope before subscription, breaking span parent-child relationships.
Sources: core/src/main/java/com/google/adk/Telemetry.java44-267
The typical development workflow uses auto-discovery for rapid iteration:
Key Features:
Sources: dev/src/main/java/com/google/adk/web/AdkWebServer.java144-150 dev/src/main/java/com/google/adk/web/CompiledAgentLoader.java89-109 tutorials/city-time-weather/README.md1-64
Refresh this wiki
This wiki was recently refreshed. Please wait 7 days to refresh again.