Phase 1 delivers the complete durability and storage layer:
- WAL with crash recovery: Append-only journal with BLAKE3 checksums,
fsync guarantees, and proper seek-to-EOF on reopen
- Storage engine: sled-backed KVStore with scan_prefix for range queries
- Content-addressed storage: H:{hash}, V:{hash}, E:{hash} key patterns
- Ingestor: Background worker tailing WAL, writing to KV with 8-byte
aligned record headers for rkyv zero-copy deserialization
- Comprehensive tests: 31 tests covering crash recovery, round-trips,
and multi-cycle durability
New crates: stemedb-wal, stemedb-storage, stemedb-ingest
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
442 lines
16 KiB
Markdown
442 lines
16 KiB
Markdown
# Google ADK-Go: Complete reference for building AI agents in Go
|
|
|
|
Google's Agent Development Kit for Go (ADK-Go) enables developers to build sophisticated AI agents using Go's native concurrency, type safety, and performance characteristics. Released in **November 2025** at version **0.2.0**, ADK-Go brings Google's agent framework to the Go ecosystem, offering first-class support for Gemini models, multi-agent orchestration, and seamless Google Cloud deployment. The toolkit follows a code-first philosophy where agent logic, tools, and workflows are defined directly in Go code rather than configuration files.
|
|
|
|
## Getting started with installation and setup
|
|
|
|
ADK-Go requires **Go 1.24.4 or later** and uses the module path `google.golang.org/adk` (not the GitHub path). Installation is straightforward:
|
|
|
|
```bash
|
|
go mod init example.com/my-agent
|
|
go get google.golang.org/adk
|
|
```
|
|
|
|
The minimal agent setup requires three components—a model, an agent configuration, and a launcher:
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"os"
|
|
|
|
"google.golang.org/adk/agent/llmagent"
|
|
"google.golang.org/adk/cmd/launcher/adk"
|
|
"google.golang.org/adk/cmd/launcher/full"
|
|
"google.golang.org/adk/model/gemini"
|
|
"google.golang.org/adk/server/restapi/services"
|
|
"google.golang.org/adk/tool"
|
|
"google.golang.org/adk/tool/geminitool"
|
|
"google.golang.org/genai"
|
|
)
|
|
|
|
func main() {
|
|
ctx := context.Background()
|
|
|
|
model, err := gemini.NewModel(ctx, "gemini-3-flash-preview", &genai.ClientConfig{
|
|
APIKey: os.Getenv("GOOGLE_API_KEY"),
|
|
})
|
|
if err != nil {
|
|
log.Fatalf("Failed to create model: %v", err)
|
|
}
|
|
|
|
agent, err := llmagent.New(llmagent.Config{
|
|
Name: "search_agent",
|
|
Model: model,
|
|
Description: "An agent that searches the web for information.",
|
|
Instruction: "You are a helpful assistant. Answer questions using web search.",
|
|
Tools: []tool.Tool{geminitool.GoogleSearch{}},
|
|
})
|
|
if err != nil {
|
|
log.Fatalf("Failed to create agent: %v", err)
|
|
}
|
|
|
|
config := &adk.Config{
|
|
AgentLoader: services.NewSingleAgentLoader(agent),
|
|
}
|
|
|
|
l := full.NewLauncher()
|
|
if err := l.Execute(ctx, config, os.Args[1:]); err != nil {
|
|
log.Fatalf("Run failed: %v\n\n%s", err, l.CommandLineSyntax())
|
|
}
|
|
}
|
|
```
|
|
|
|
Running modes include console interaction (`go run agent.go`), web interface with API (`go run agent.go web api webui`), and production mode (`go run agent.go web api a2a`).
|
|
|
|
## Repository architecture and package structure
|
|
|
|
The ADK-Go repository follows a modular structure designed for extensibility:
|
|
|
|
| Package | Purpose |
|
|
| ----------------------- | -------------------------------------------------- |
|
|
| `agent/` | Core agent interfaces and implementations |
|
|
| `agent/llmagent/` | LLM-powered agents with reasoning capabilities |
|
|
| `agent/workflowagents/` | Sequential, Parallel, and Loop agent orchestrators |
|
|
| `model/gemini/` | Gemini model implementation |
|
|
| `tool/` | Tool framework and interfaces |
|
|
| `tool/geminitool/` | Built-in Google Search and Code Execution tools |
|
|
| `tool/mcptool/` | Model Context Protocol adapter |
|
|
| `session/` | Session management and state tracking |
|
|
| `memory/` | Long-term memory and knowledge storage |
|
|
| `server/restapi/` | REST API handlers, routers, and services |
|
|
| `cmd/launcher/` | Launcher configurations (full, prod, console, web) |
|
|
|
|
## Core types and interfaces define the API
|
|
|
|
The foundation of ADK-Go rests on several key interfaces. The **Agent interface** defines what every agent must implement:
|
|
|
|
```go
|
|
type Agent interface {
|
|
Name() string
|
|
Description() string
|
|
Run(InvocationContext) iter.Seq2[*session.Event, error]
|
|
SubAgents() []Agent
|
|
}
|
|
```
|
|
|
|
The **InvocationContext** provides runtime access to agent state and services:
|
|
|
|
```go
|
|
type InvocationContext interface {
|
|
context.Context
|
|
Agent() Agent
|
|
Artifacts() Artifacts
|
|
Memory() Memory
|
|
Session() session.Session
|
|
InvocationID() string
|
|
Branch() string
|
|
UserContent() *genai.Content
|
|
RunConfig() *RunConfig
|
|
EndInvocation()
|
|
Ended() bool
|
|
}
|
|
```
|
|
|
|
The **LLM interface** abstracts model interactions for provider flexibility:
|
|
|
|
```go
|
|
type LLM interface {
|
|
Name() string
|
|
GenerateContent(ctx context.Context, req *LLMRequest, stream bool) iter.Seq2[*LLMResponse, error]
|
|
}
|
|
```
|
|
|
|
Agent configuration uses the **llmagent.Config** struct with fields including `Name` (required identifier), `Model` (LLM instance), `Description` (used for routing decisions), `Instruction` (system prompt), `Tools` (available capabilities), `SubAgents` (child agents for delegation), and `OutputKey` (state storage key).
|
|
|
|
## Tool ecosystem spans built-in, custom, and MCP integrations
|
|
|
|
ADK-Go provides **built-in tools** via the `geminitool` package:
|
|
|
|
```go
|
|
import "google.golang.org/adk/tool/geminitool"
|
|
|
|
Tools: []tool.Tool{
|
|
geminitool.GoogleSearch{}, // Web search via Google
|
|
geminitool.CodeExecution{}, // Code execution sandbox
|
|
}
|
|
```
|
|
|
|
**Custom function tools** use struct tags for schema generation:
|
|
|
|
```go
|
|
import "google.golang.org/adk/tool/functiontool"
|
|
|
|
type GetWeatherParams struct {
|
|
Location string `json:"location" jsonschema:"The city and state, e.g., San Francisco, CA"`
|
|
Unit string `json:"unit,omitempty" jsonschema:"Temperature unit: celsius or fahrenheit"`
|
|
}
|
|
|
|
type GetWeatherResult struct {
|
|
Temperature float64 `json:"temperature"`
|
|
Conditions string `json:"conditions"`
|
|
}
|
|
|
|
func getWeather(ctx tool.Context, input GetWeatherParams) GetWeatherResult {
|
|
// Implementation here
|
|
return GetWeatherResult{Temperature: 72.5, Conditions: "sunny"}
|
|
}
|
|
|
|
weatherTool, err := functiontool.New(
|
|
functiontool.Config{
|
|
Name: "get_weather",
|
|
Description: "Retrieves current weather for a location",
|
|
},
|
|
getWeather,
|
|
)
|
|
```
|
|
|
|
Fields without `omitempty` are treated as required parameters. The `jsonschema` tag provides descriptions for the LLM.
|
|
|
|
**MCP (Model Context Protocol)** support enables integration with external tool servers:
|
|
|
|
```go
|
|
import "google.golang.org/adk/tool/mcptool"
|
|
|
|
// Connect to stdio-based MCP server
|
|
params := mcptool.StdioServerParams{
|
|
Command: "npx",
|
|
Args: []string{"-y", "@modelcontextprotocol/server-filesystem"},
|
|
}
|
|
tools, closer, err := mcptool.FromServer(ctx, params)
|
|
defer closer.Close()
|
|
|
|
// Or connect via SSE/HTTP
|
|
sseParams := mcptool.SseServerParams{
|
|
URL: "http://localhost:8090/sse",
|
|
Timeout: 5.0,
|
|
SseReadTimeout: 300.0,
|
|
}
|
|
```
|
|
|
|
The **MCP Toolbox for Databases** provides out-of-the-box connectors for **30+ databases** including BigQuery, AlloyDB, PostgreSQL, MySQL, Cloud SQL, and Redis.
|
|
|
|
## Multi-agent orchestration uses workflow agents
|
|
|
|
ADK-Go provides three workflow agents for deterministic orchestration patterns:
|
|
|
|
**SequentialAgent** executes sub-agents in strict order, useful for pipelines where outputs feed into subsequent steps:
|
|
|
|
```go
|
|
import "google.golang.org/adk/agent/sequentialagent"
|
|
|
|
pipeline, err := sequentialagent.New(sequentialagent.Config{
|
|
AgentConfig: agent.Config{
|
|
Name: "DataPipeline",
|
|
Description: "Three-step data processing workflow",
|
|
SubAgents: []agent.Agent{fetcher, transformer, validator},
|
|
},
|
|
})
|
|
```
|
|
|
|
**ParallelAgent** executes sub-agents concurrently, with each operating in independent branches without shared conversation history:
|
|
|
|
```go
|
|
import "google.golang.org/adk/agent/parallelagent"
|
|
|
|
parallel, err := parallelagent.New(parallelagent.Config{
|
|
AgentConfig: agent.Config{
|
|
Name: "ParallelResearch",
|
|
SubAgents: []agent.Agent{webSearcher, docAnalyzer, factChecker},
|
|
},
|
|
})
|
|
```
|
|
|
|
**LoopAgent** repeatedly executes sub-agents until a maximum iteration count or termination condition is met:
|
|
|
|
```go
|
|
import "google.golang.org/adk/agent/loopagent"
|
|
|
|
refiner, err := loopagent.New(loopagent.Config{
|
|
AgentConfig: agent.Config{
|
|
Name: "IterativeRefiner",
|
|
SubAgents: []agent.Agent{writer, critic},
|
|
},
|
|
MaxIterations: 5,
|
|
})
|
|
```
|
|
|
|
**Agent communication** occurs through shared session state using the `OutputKey` configuration:
|
|
|
|
```go
|
|
// Agent 1 writes output to state
|
|
agent1, _ := llmagent.New(llmagent.Config{
|
|
Name: "Fetcher",
|
|
OutputKey: "fetched_data", // Saves to state["fetched_data"]
|
|
})
|
|
|
|
// Agent 2 reads from state via instruction templating
|
|
agent2, _ := llmagent.New(llmagent.Config{
|
|
Instruction: "Process the data from {fetched_data}",
|
|
})
|
|
```
|
|
|
|
## Model integration centers on Gemini with extensibility
|
|
|
|
The primary model integration uses Gemini through the `model/gemini` package:
|
|
|
|
```go
|
|
import (
|
|
"google.golang.org/adk/model/gemini"
|
|
"google.golang.org/genai"
|
|
)
|
|
|
|
// API Key authentication (AI Studio)
|
|
model, err := gemini.NewModel(ctx, "gemini-3-flash-preview", &genai.ClientConfig{
|
|
APIKey: os.Getenv("GOOGLE_API_KEY"),
|
|
})
|
|
|
|
// Vertex AI authentication (Application Default Credentials)
|
|
model, err := gemini.NewModel(ctx, "gemini-3-flash-preview", &genai.ClientConfig{})
|
|
```
|
|
|
|
Supported models include `gemini-3-flash-preview`, `gemini-2.0-flash`, `gemini-1.5-pro`, and preview models like `gemini-3-pro-preview`. The architecture supports additional providers through the `LLM` interface, with community implementations available for other models.
|
|
|
|
**Streaming responses** use Go 1.23+ iterators (`iter.Seq2`) for real-time event processing:
|
|
|
|
```go
|
|
for event, err := range runner.Run(ctx, userID, sessionID, userMsg, agent.RunConfig{
|
|
StreamingMode: agent.StreamingModeSSE,
|
|
}) {
|
|
if event.Partial {
|
|
for _, p := range event.LLMResponse.Content.Parts {
|
|
fmt.Print(p.Text) // Stream partial content
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Session and state management provides persistence options
|
|
|
|
ADK-Go supports three tiers of state management:
|
|
|
|
**Session State** manages per-conversation working memory:
|
|
|
|
```go
|
|
import "google.golang.org/adk/session"
|
|
|
|
// In-memory for development
|
|
sessionService := session.InMemoryService()
|
|
|
|
// Create session
|
|
sess, err := sessionService.Create(ctx, &session.CreateRequest{
|
|
AppName: "my_app",
|
|
UserID: "user123",
|
|
})
|
|
|
|
// Access state within agent Run method
|
|
func (a *MyAgent) Run(ctx agent.InvocationContext) iter.Seq2[*session.Event, error] {
|
|
value := ctx.Session().State().Get("key")
|
|
ctx.Session().State().Set("key", "value")
|
|
}
|
|
```
|
|
|
|
**State prefixes** control scope and persistence:
|
|
|
|
- No prefix: App-scoped persistent state
|
|
- `user:` prefix: User-scoped persistent state
|
|
- `app:` prefix: Application-wide persistent state
|
|
- `temp:` prefix: Temporary, per-invocation only
|
|
|
|
**Memory services** provide long-term knowledge storage with vector search:
|
|
|
|
```go
|
|
import "google.golang.org/adk/memory"
|
|
|
|
// Development: In-memory
|
|
memoryService := memory.InMemoryService()
|
|
|
|
// Production: Vertex AI Memory Bank
|
|
// Provides semantic search across archived sessions
|
|
```
|
|
|
|
**Database-backed sessions** support PostgreSQL, MySQL, and SQLite for production persistence with automatic table creation.
|
|
|
|
## Deployment spans local development to Google Cloud
|
|
|
|
### Cloud Run deployment
|
|
|
|
ADK-Go includes a CLI tool for streamlined Cloud Run deployment:
|
|
|
|
```bash
|
|
go build ./cmd/adkgo
|
|
|
|
./adkgo deploy cloudrun \
|
|
-p $GOOGLE_CLOUD_PROJECT \
|
|
-r us-central1 \
|
|
-s my-agent-service \
|
|
-e ./main.go \
|
|
--a2a --api --webui
|
|
```
|
|
|
|
The deployment process compiles the Go code to a statically linked Linux binary, auto-generates a Dockerfile, builds the container image, and deploys to Cloud Run with a local proxy for secure connections.
|
|
|
|
### Vertex AI Agent Engine
|
|
|
|
For fully managed deployment, Agent Engine provides auto-scaling, managed sessions via `VertexAiSessionService`, and direct Vertex AI SDK integration.
|
|
|
|
### Container configuration
|
|
|
|
Manual Docker deployment uses this pattern:
|
|
|
|
```dockerfile
|
|
FROM golang:1.24-alpine AS builder
|
|
WORKDIR /app
|
|
COPY go.mod go.sum ./
|
|
RUN go mod download
|
|
COPY . .
|
|
RUN CGO_ENABLED=0 GOOS=linux go build -o agent main.go
|
|
|
|
FROM alpine:latest
|
|
WORKDIR /app
|
|
COPY --from=builder /app/agent .
|
|
EXPOSE 8080
|
|
CMD ["./agent", "web", "api", "a2a"]
|
|
```
|
|
|
|
### A2A (Agent-to-Agent) Protocol
|
|
|
|
ADK-Go provides native support for the A2A protocol enabling secure multi-agent communication:
|
|
|
|
- **Agent Cards** expose capabilities via `/.well-known/agent-card.json`
|
|
- **Secure delegation** between agents without shared memory or tools
|
|
- **Signed security cards** for enterprise identity verification
|
|
- **HTTP and gRPC transports** for flexible connectivity
|
|
|
|
## Testing and evaluation capabilities
|
|
|
|
**Development UI** provides interactive testing at `http://localhost:8080`:
|
|
|
|
```bash
|
|
go run agent.go web api webui
|
|
```
|
|
|
|
Features include chat interface, trace inspection with Event/Request/Response/Graph views, and session management.
|
|
|
|
**HTTP Record/Replay** (`internal/httprr`) enables deterministic testing of LLM interactions by recording and replaying HTTP exchanges.
|
|
|
|
**Evaluation framework** supports trajectory evaluation (steps and tools chosen) and final response evaluation (relevance and correctness) through both the CLI (`adk eval`) and programmatic integration.
|
|
|
|
## Best practices for production deployments
|
|
|
|
**Security hardening** requires careful attention:
|
|
|
|
- Use Google Cloud Secret Manager for API keys—never hardcode credentials
|
|
- Implement `before_model_callback` to intercept and block forbidden topics
|
|
- Use `before_tool_callback` to validate tool arguments before execution
|
|
- Deploy with `--no-allow-unauthenticated` for private services
|
|
- Sign A2A Agent Cards for identity verification
|
|
|
|
**Error handling** patterns include wrapping callbacks in error handlers, implementing timeouts for external API calls, and designing idempotent callbacks for external side effects.
|
|
|
|
**Performance optimization** leverages Go's strengths:
|
|
|
|
- Use `ParallelAgent` for concurrent independent tasks
|
|
- Filter available tools with `tool_filter` to prevent model overwhelm
|
|
- Use compile-time type checking to catch errors early
|
|
- Deploy to Cloud Run with appropriate memory (4Gi recommended) and CPU (2+) allocations
|
|
|
|
## How ADK-Go differs from Python and Java versions
|
|
|
|
| Aspect | Go | Python | Java |
|
|
| --------------------- | ----------------------------------- | ----------------------------- | -------------------------- |
|
|
| **Version** | v0.2.0 | v1.19.0 | v0.3.0 |
|
|
| **Async Pattern** | `iter.Seq2[*Event, error]` iterator | `AsyncGenerator[Event, None]` | `Flowable<Event>` (RxJava) |
|
|
| **Schema Definition** | `json` + `jsonschema` struct tags | Type hints + docstrings | `@Schema` annotations |
|
|
| **Concurrency** | Goroutines and channels | async/await | RxJava Flowables |
|
|
| **Sample Agents** | 1 (llm-auditor) | 25+ | 2 |
|
|
| **Third-party Tools** | Limited | LangChain integration | Limited |
|
|
|
|
Go's advantages include **native concurrency** for parallel agent interactions, **compile-time type safety** for robust error prevention, **efficient memory management** for resource-constrained deployments, and **strong cloud-native support** optimized for Cloud Run and containerized environments.
|
|
|
|
## Enterprise adoption and ecosystem
|
|
|
|
Major companies using ADK in production include **Renault Group**, **Box**, **SAP** (via Joule AI assistant), **Zoom**, and **Revionics**. Google products powered by ADK include **Agentspace** and **Customer Engagement Suite**.
|
|
|
|
The community ecosystem spans the main repository (795+ stars), the samples repository with cross-language examples, and the **Awesome ADK Agents** collection with 80+ production-ready agents.
|
|
|
|
## Conclusion
|
|
|
|
ADK-Go represents Google's commitment to bringing AI agent development to the Go ecosystem with a focus on performance, type safety, and cloud-native deployment. The framework excels in scenarios requiring **high-throughput concurrent agent execution**, **strongly-typed tool definitions**, and **seamless Google Cloud integration**. While the Python ADK offers broader model support and a larger example library, ADK-Go provides idiomatic patterns that align with Go's philosophy of simplicity and efficiency. For teams already invested in Go infrastructure or requiring the performance characteristics Go provides, ADK-Go offers a production-ready path to building sophisticated AI agents with full access to Gemini's capabilities and the broader Google Cloud ecosystem.
|