How to Build AI Agents with ADK-Go in Go
This guide walks through installing ADK-Go, configuring a simple LLM agent, handling model selection and errors, leveraging Google Search and custom function tools, and orchestrating complex workflows with SequentialAgent, LoopAgent, and ParallelAgent, all illustrated with concrete Go code examples and output.
Repository and Documentation
Library source: https://github.com/google/adk-go
Documentation: https://google.github.io/adk-docs/
Example code repository: https://github.com/raoxiaoya/learn-adk
Setup
Install the ADK‑Go library: go get google.golang.org/adk Requires Go >= 1.24.4 and ADK version v0.2.
Simple LLM Agent Example
The program below creates a time‑telling agent that uses the Gemini‑2.5‑pro model and the built‑in google_search tool.
package main
import (
"context"
"log"
"os"
"google.golang.org/adk/agent"
"google.golang.org/adk/agent/llmagent"
"google.golang.org/adk/cmd/launcher"
"google.golang.org/adk/cmd/launcher/full"
"google.golang.org/adk/model/gemini"
"google.golang.org/adk/tool"
"google.golang.org/adk/tool/geminitool"
"google.golang.org/genai"
"learn-adk/config"
)
func main() {
RunAgent()
}
func RunAgent() {
ctx := context.Background()
model, err := gemini.NewModel(ctx, "gemini-2.5-pro", &genai.ClientConfig{APIKey: config.APIKey})
if err != nil { log.Fatalf("Failed to create model: %v", err) }
timeAgent, err := llmagent.New(llmagent.Config{
Name: "hello_time_agent",
Model: model,
Description: "Tells the current time in a specified city.",
Instruction: "You are a helpful assistant that tells the current time in a city.",
Tools: []tool.Tool{ geminitool.GoogleSearch{} },
})
if err != nil { log.Fatalf("Failed to create agent: %v", err) }
cfg := &launcher.Config{AgentLoader: agent.NewSingleLoader(timeAgent)}
l := full.NewLauncher()
if err = l.Execute(ctx, cfg, os.Args[1:]); err != nil {
log.Fatalf("Run failed: %v
%s", err, l.CommandLineSyntax())
}
}Running go run agent.go starts an interactive session. Sample dialogue shows the agent reporting the current time for London and New York, confirming that the Google Search tool is invoked to obtain accurate time‑zone information.
Agent Configuration Fields
Name (required) : unique identifier used for internal routing; avoid reserved names such as user.
Description (optional, recommended for multi‑agent systems) : concise capability summary that other agents can read for routing decisions.
Model (required) : identifier of the underlying LLM, e.g., gemini-2.5-pro. Model choice influences capability, cost, and performance.
Instruction : defines core task, persona, behavioral constraints, tool usage, and expected output format.
Effective Instruction Tips
Be clear and explicit about the desired action.
Use Markdown headings and lists for readability.
Provide few‑shot examples for complex output formats.
Explain when and why each tool should be used.
Error Handling
Typical errors include network failures, quota exhaustion, and unsupported model names. Example messages:
AGENT_ERROR: doRequest: error sending request: Post "https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:streamGenerateContent?alt=sse": EOF ---- Network issue
AGENT_ERROR: Error 429, Message: You exceeded your current quota, please check your plan and billing details. ---- Paid model or quota exhausted
AGENT_ERROR: Error 404, Message: models/gemini-3 is not found for API version v1beta. ---- Unsupported model nameThe gemini-2.5-pro model is the minimal version that runs successfully.
Model Listing
The following function enumerates models available through the Gemini API:
func ListModels() {
ctx := context.Background()
client, err := genai.NewClient(ctx, &genai.ClientConfig{APIKey: "YOUR_API_KEY"})
if err != nil { log.Fatalf("Failed to create client: %v", err) }
models := client.Models.All(ctx)
for m, e := range models {
if e != nil { log.Printf("Error: %v", e); continue }
log.Printf("Model: %s", m.Name)
}
}Sample output includes many Gemini variants (e.g., models/gemini-2.5-pro, models/gemini-2.5-flash) and other models such as Gemma and Imagen. Not all listed models are free; pricing varies per model.
Google Search Tool Integration
Enabling the google_search tool lets the model ground answers in real‑time web content, improving factual accuracy and providing citations.
Workflow:
User prompt is sent to the Gemini API.
The model decides whether a web search would improve the answer.
If needed, the model generates one or more search queries and executes them.
Search results are processed and integrated into the final response.
The API returns the answer together with groundingMetadata that contains the queries, results, and citations.
Only a subset of models support Google Search; the free tier may not include it, and pricing can be confusing.
Custom FunctionTool Example
ADK also supports user‑defined functionTool s that agents can invoke directly. The two examples below provide weather and time retrieval for a specified city.
func GetWeather() (tool.Tool, error) {
handler := func(ctx tool.Context, input Input) (Output, error) {
if strings.ToLower(input.City) == "new york" {
return Output{Status: "success", Report: "The weather in New York is sunny with a temperature of 25°C (77°F)."}, nil
}
return Output{Status: "error", Report: "The weather information for " + input.City + " is not available."}, nil
}
return functiontool.New(functiontool.Config{Name: "GetWeather", Description: "Retrieves the current weather report for a specified city."}, handler)
}
func GetCurrentTime() (tool.Tool, error) {
handler := func(ctx tool.Context, input Input) (Output, error) {
if strings.ToLower(input.City) == "new york" {
return Output{Status: "success", Report: "The current time in New York is " + time.Now().Format(time.DateTime)}, nil
}
return Output{Status: "error", Report: "Sorry, I don't have timezone information for " + input.City + "."}, nil
}
return functiontool.New(functiontool.Config{Name: "GetCurrentTime", Description: "Returns the current time in a specified city."}, handler)
}These tools are added to an agent configuration similarly to built‑in tools:
a, err := llmagent.New(llmagent.Config{
Name: "weather_time_agent",
Model: model,
Description: "Agent to answer questions about the time and weather in a city.",
Instruction: "You are a helpful agent who can answer user questions about the time and weather in a city.",
Tools: []tool.Tool{weatherTool, timeTool},
})Sample interaction shows successful time queries for London and New York, successful weather queries for New York, and graceful error messages for unsupported locations.
Agent Types and Workflow
ADK provides three workflow agents:
SequentialAgent : Executes sub‑agents in the order listed, sharing the same InvocationContext so that state (e.g., temporary variables) is passed between steps.
LoopAgent : Repeatedly runs sub‑agents until a termination condition is met (e.g., maximum iterations or a signal from a sub‑agent). Users must implement a termination mechanism.
ParallelAgent : Starts all sub‑agents concurrently. Each runs in an independent branch; results are collected after all finish, but ordering is nondeterministic unless explicitly managed.
Example: a code‑development pipeline uses three agents—code‑writing llmAgent, code‑review llmAgent, and refactoring llmAgent. The output of each step is stored in shared state under an OutputKey and read by the next step.
LoopAgent is useful for tasks that require repeated attempts until a condition is satisfied, such as generating exactly five bananas by invoking an image‑generation tool until the desired count is achieved.
ParallelAgent can be employed for parallel web research on multiple topics (e.g., renewable energy, electric‑vehicle technology, carbon capture), with each sub‑agent operating independently and results merged afterward.
Planner Support
The current ADK‑Go version does not support the Planner capability (advanced reasoning and planning).
Typical Built‑in Agents
ADK includes built‑in agents such as llmAgent, SequentialAgent, LoopAgent, and ParallelAgent, which can be combined to create sophisticated AI workflows.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Golang Shines
We share daily the latest Golang technical articles, practical resources, language news, tutorials, and real-world projects to help everyone learn and improve.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
