Agent Development Kit (ADK) for Java
repository·main·Indexed 23 days ago
https://github.com/google/adk-javaA code-first toolkit for building, evaluating, and deploying AI agents integrated with Google Cloud. It features an A2A (Agent-to-Agent) runtime and Spring Boot webservice for JSON-RPC communication, a Firestore session service for scalable user session management, and integrations with LangChain4j for wrapping ChatModels and StreamingChatModels. The kit also includes pluggable planner implementations for orchestrating sub-agents via PlannerAgent.
What's inside google-adk-java
- ADK Telemetry and Tracing uses OpenTelemetry to capture and report execution data. This provides observability into agent behavior by tracing agent invocations, LLM requests/responses, and tool calls. Traces can be exported to backends like Google Cloud Trace or Zipkin, or viewed via the ADK Dev Server UI.
Overview of the Agent Development Kit (ADK) for Java
mainThe Agent Development Kit (ADK) for Java is a core library designed to facilitate the development, evaluation, and deployment of AI agents. It provides a familiar interface for developers transitioning from the Python ADK and includes features for building agentic workflows, utilizing a development UI, and evaluating agent performance. It also supports A2A (Agent-to-Agent) and ADK integration.Overview of ADK development utilities
mainThe ADK (Agent Development Kit) for Java provides development utilities to assist in building and testing agents. One primary utility is a Spring REST server designed to host an agent, allowing for interaction and testing via standard HTTP requests.Overview of Agent Development Kit (ADK) for Java
mainThe Agent Development Kit (ADK) for Java is an open-source, code-first toolkit designed for building, evaluating, and deploying sophisticated AI agents. It is optimized for developers who need fine-grained control and tight integration with Google Cloud services.
Key capabilities include:
- Code-First Development: Define logic, tools, and orchestration directly in Java.
- Rich Tool Ecosystem: Use pre-built tools, custom functions, or OpenAPI specs.
- Modular Multi-Agent Systems: Compose specialized agents into hierarchical structures.
- Development UI: A built-in interface to test, evaluate, and debug agents.
- A2A Integration: Support for remote agent-to-agent communication via the A2A protocol.
Overview of ADK Planner strategies
mainThe
google-adk-plannersmodule provides several strategies for orchestrating sub-agent execution:Planner Package Execution Model LLM Required Primary Use Case SequentialPlannerplannerOne at a time, in order No Fixed pipelines, ETL steps ParallelPlannerplannerAll at once No Independent fan-out tasks LoopPlannerplannerCyclic, repeating No Review/revision cycles SupervisorPlannerplannerLLM selects next agent(s) Yes Open-ended task delegation GoalOrientedPlannerplanner.goapDependency-resolved groups No Workflows with input/output contracts P2PPlannerplanner.p2pReactive dynamic activation No Collaborative refinement loops Project Layout of the Hello World Sample
mainThe Hello World sample is structured as follows:
HelloWorldAgent.java: Contains the agent definition and tool wiring.HelloWorldRun.java: The console runner entry point.pom.xml: Maven configuration specifying theexecmain class.README.md: Documentation for the sample.
Understand the A2A Basic Sample implementation
mainThe A2A Basic Sample consists of several key components that illustrate the integration between local tools and remote agents:
A2AAgent.java: This file builds a root agent. The root agent is configured with a local dice-rolling tool and aRemoteA2AAgentwhich acts as a sub-agent for remote prime-checking.A2AAgentRun.java: A minimal driver class used to execute a singleSendMessageturn, demonstrating how the remote call is triggered and handled.pom.xml: The standalone Maven configuration required to build and run this specific sample.
Use the Peer-to-Peer (P2P) Planner for iterative refinement
mainThe P2P planner (
com.google.adk.planner.p2p) is designed for collaborative, iterative workflows where agents react to changes in session state. Unlike GOAP, it does not compute a plan upfront. Instead, agents activate dynamically when their requiredinputKeysappear in the state.Key behaviors:
- Parallel activation: Multiple agents can run simultaneously if their dependencies are met.
- Iterative refinement: If an agent produces a new or changed output (detected via
Objects.equals()), downstream agents that depend on that key are re-activated. - Value-change detection: To prevent infinite loops or wasted compute, agents only re-execute if the output value actually changes.
Use this planner when you need a 'research collaboration' pattern where a critic's feedback triggers a re-run of a hypothesis agent.
List<AgentMetadata> metadata = List.of( new AgentMetadata("literature", ImmutableList.of("topic"), "researchFindings"), new AgentMetadata("hypothesis", ImmutableList.of("topic", "researchFindings"), "hypothesis"), new AgentMetadata("critic", ImmutableList.of("topic", "hypothesis"), "critique"), new AgentMetadata("scorer", ImmutableList.of("topic", "hypothesis", "critique"), "score") ); // Exit when score is high enough P2PPlanner planner = new P2PPlanner(metadata, 20, (state, count) -> { Object score = state.get("score"); return score instanceof Number && ((Number) score).doubleValue() >= 0.85; }); PlannerAgent agent = PlannerAgent.builder() .name("research") .subAgents(literatureAgent, hypothesisAgent, criticAgent, scorerAgent) .planner(planner) .build();Use Goal-Oriented Action Planning (GOAP) for agent orchestration
mainThe GOAP subsystem (
com.google.adk.planner.goap) resolves agent execution order by analyzing input/output dependencies. Instead of manual sequencing, you define what state keys each agent reads (inputKeys) and writes (outputKey). The planner then computes a dependency graph to determine which agents can run in parallel and in what order to reach a target goal.To use GOAP, you must define
AgentMetadatafor each sub-agent and then initialize aGoalOrientedPlannerwith your target goal and the metadata list.List<AgentMetadata> metadata = List.of( new AgentMetadata("personExtractor", ImmutableList.of("prompt"), "person"), new AgentMetadata("signExtractor", ImmutableList.of("prompt"), "sign"), new AgentMetadata("horoscopeGen", ImmutableList.of("person", "sign"), "horoscope"), new AgentMetadata("writer", ImmutableList.of("person", "horoscope"), "writeup") ); // Goal is to produce "writeup" GoalOrientedPlanner planner = new GoalOrientedPlanner("writeup", metadata); PlannerAgent agent = PlannerAgent.builder() .name("horoscope") .subAgents(personExtractor, signExtractor, horoscopeGen, writer) .planner(planner) .build();Understand the compatibility policy for contributions
mainCode located in the
contrib/directory does not have backwards API compatibility guarantees. This applies even across minor (patch) releases.Maintainers may merge changes to both implementations and interfaces without concern for API stability. This policy is intended to allow contributors to raise PRs and incrementally improve code without the overhead of maintaining strict API stability.
Understand the Trace Hierarchy for Nested Agents
mainADK produces a hierarchical trace structure. A standard interaction follows this pattern:
invocation └── invoke_agent my_agent ├── call_llm │ ├── tool_call [search_flights] │ └── tool_response [search_flights] └── call_llmWhen using Nested Agents (where one agent uses the
transfer_to_agenttool to call another), the sub-agent's invocation appears as a child of the parent agent's invocation:invocation └── invoke_agent AgentA ├── call_llm │ ├── tool_call [transfer_to_agent] │ └── tool_response [transfer_to_agent] └── invoke_agent AgentB ├── call_llm └── ...How the ADK Stale Issue Auditor decides to act
mainThe agent uses a
Unified History Trace(reconstructed via GraphQL) to classify the last actor of an issue as anauthor,maintainer, orother_user. It then follows this decision logic:Last actor Verdict & Action Author / other user ACTIVE: Remove stalelabel. If the author silently edited the description, post a one-time maintainer alert.Maintainer (asked question) STALE: If days_since_activity> threshold, comment + addstalelabel (andrequest clarificationif missing).Issue already staleCLOSE: If days_since_stale_label> close threshold, comment + close as not planned.Maintainer (status update) ACTIVE: No action. Thresholds default to 7 days for both stale and close actions but are configurable via environment variables.