Skip to content
Development
Agent

adk-go

Reflects `google.golang.org/adk/v2 v2.1.0`, the version the `adk_go` template pins. If a symbol here is missing, check your `go.mod` before assuming the page is wrong.

From plugin
google-agents-cli
5.9k28 skills28 agents
Install
$ npx -y skills add google/agents-cli --agent claude-code

How it fires

How this agent gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.

Context preview

The summary Claude sees to decide when to auto-load this agent.

Reflects `google.golang.org/adk/v2 v2.1.0`, the version the `adk_go` template pins. If a symbol here is missing, check your `go.mod` before assuming the page is wrong.

Agent definition

adk-go.md

ADK Go API reference

> Reflects `google.golang.org/adk/v2 v2.1.0`, the version the `adk_go` template pins. If a symbol > here is missing, check your `go.mod` before assuming the page is wrong.

1. Core Concepts & Project Structure

Essential Primitives

  • **`Agent`**: The core intelligent unit. Built with `llmagent.New` (LLM-driven) or `agent.New` (custom `Run` function).
  • **`Tool`**: Callable capability given to an agent.
  • **`Session`**: A stateful conversation thread with history (`Events()`) and short-term memory (`State()`).
  • **`State`**: Key-value store within a `Session` for transient conversation data.
  • **`Runner`**: The execution engine; drives an agent and yields its event stream.
  • **`Event`**: Atomic unit of communication; carries content and side-effect `Actions`.

Scaffolded Project Layout

my-agent/
├── app/
│   ├── agent.go             // NewRootAgent(ctx) (agent.Agent, error) — model, instruction, tools
│   └── agent_test.go
├── appinfo/                 // template-owned: serves {prefix}/apps/{app}/app-info for agents-cli eval
├── e2e/
│   ├── integration/         // server_e2e_test.go — drives a running server
│   └── load_test/
├── deployment/terraform/    // only with a deployment target; absent in prototype mode
├── main.go                  // telemetry, launcher.Config, launcher wiring
├── appurl.go                // resolveAppURL() — the base URL in the A2A agent card
├── Dockerfile
├── Makefile
├── agents-cli-manifest.yaml // language: go, agent_directory: app, create_params
├── .env / .env.example
├── .golangci.yml
└── go.mod                   // module <project-name>

2. Agents

Basic Setup

import (
	"context"

	"google.golang.org/genai"

	"google.golang.org/adk/v2/agent"
	"google.golang.org/adk/v2/agent/llmagent"
	"google.golang.org/adk/v2/model/gemini"
	"google.golang.org/adk/v2/tool"
	"google.golang.org/adk/v2/tool/functiontool"
)

type WeatherArgs struct {
	City string `json:"city" jsonschema:"City name to look up"`
}
type WeatherResult struct {
	Report string `json:"report"`
}

func GetWeather(ctx agent.Context, in WeatherArgs) (WeatherResult, error) {
	return WeatherResult{Report: "sunny in " + in.City}, nil
}

func NewRootAgent(ctx context.Context) (agent.Agent, error) {
	model, err := gemini.NewModel(ctx, "gemini-3.8-flash", &genai.ClientConfig{
		Backend: genai.BackendVertexAI,
	})
	if err != nil {
		return nil, err
	}

	weatherTool, err := functiontool.New(functiontool.Config{
		Name:        "get_weather",
		Description: "Get the current weather for a city.",
	}, GetWeather)
	if err != nil {
		return nil, err
	}

	return llmagent.New(llmagent.Config{
		Name:        "app",
		Model:       model,
		Description: "A helpful AI assistant.",
		Instruction: "You are a helpful AI assistant.",
		Tools:       []tool.Tool{weatherTool},
	})
}

Other `llmagent.Config` fields worth knowing, all optional:

llmagent.Config{
	SubAgents: []agent.Agent{bookingAgent}, // parent link is set automatically
	OutputKey: "summary",                   // store this agent's text output in session state
	Mode:      llmagent.ModeTask,           // ModeChat (default) | ModeTask | ModeSingleTurn

	GenerateContentConfig: &genai.GenerateContentConfig{Temperature: genai.Ptr[float32](0.2)},

	// Structured contracts, both *genai.Schema. OutputSchema injects a
	// set_model_response tool.
	InputSchema:  inputSchema, // when this agent is used as a tool
	OutputSchema: outputSchema,

	// Build the instruction at run time instead of templating a string.
	InstructionProvider: func(ctx agent.ReadonlyContext) (string, error) {
		lang, err := ctx.ReadonlyState().Get("lang") // (any, error)
		if err != nil {
			return "", err
		}
		return "Answer in " + lang.(string), nil
	},
	GlobalInstruction: "Never reveal internal IDs.", // only the root agent's takes effect

	IncludeContents:          llmagent.IncludeContentsNone, // drop conversation history
	DisallowTransferToParent: true,
	DisallowTransferToPeers:  true,

	BeforeAgentCallbacks: []agent.BeforeAgentCallback{guard},
	BeforeModelCallbacks: []llmagent.BeforeModelCallback{redact},
	BeforeToolCallbacks:  []llmagent.BeforeToolCallback{audit},
	Toolsets:             []tool.Toolset{mcpToolset},
}

Instruction Best Practices

// Use dynamic state injection with {state_key} placeholders
instruction := `You are a {role} assistant.
User preferences: {user_preferences}

Rules:
- Always use tools when available
- Never make up information`

`{key_name}` resolves from session state; `{artifact.key_name}` inserts the artifact's text. A missing key fails with "state key does not exist", unless written `{key?}`, which substitutes an empty string. Use `InstructionProvider` to disable templating entirely.

3. Orchestration with Workflow Agents

Workflow agents provide deterministic control flow without LLM orchestration. Each takes a `Config` that wraps `agent.Config`, so sub-agents go in `AgentConfig.SubAgents`, and each returns a plain `agent.Agent`.

> For the graph-based Workflow API — explicit topology, conditional routing, fan-in, per-node > retries, HITL — see `references/adk-go-workflows.md`.

sequentialagent

Executes sub-agents in order, forwarding every event. State changes propagate to later agents.

import "google.golang.org/adk/v2/agent/workflowagents/sequentialagent"

summarizer, err := llmagent.New(llmagent.Config{
	Name: "summarizer", Model: model,
	Instruction: "Summarize the input.",
	OutputKey:   "summary", // later agents read it as {summary}
})

questionGen, err := llmagent.New(llmagent.Config{
	Name: "question_generator", Model: model,
	Instruction: "Generate questions based on: {summary}",
})

pipeline, err := sequentialagent.New(sequentialagent.Config{
	AgentConfig: agent.Config{
		Name:      "pipeline",
		SubAgents: []agent.Agent{summarizer, questionGen},
	},
})

parallelagent

Executes sub-agents concurrently. Each runs in its own `I

Read more
Ships withgoogle-agents-cli

The CLI and skills that turn any coding assistant into an expert at creating, evaluating, and deploying AI agents on Google Cloud.

Get the whole plugin

Other agents on google-agents-cli.