🤖

[ADK][Go] adk-go を利用して、GoでAIエージェントを書いてみる

に公開

こんにちは、サントリーこと大橋です。

2025/11/07に、Google Agent Development Kit (ADK) のGo言語版である ADK for Go (google.golang.org/adk) のバージョン0.1.0がリリースされました。

https://developers.googleblog.com/en/announcing-the-agent-development-kit-for-go-build-powerful-ai-agents-with-your-favorite-languages/

https://github.com/google/adk-go

ADKはこれまでPythonとJava(と公式リリースはしていないがTypeScript)がサポートされていましたが、ついにGoが加わりました。
今回はこのADK for Goを利用してGoでAIエージェントを書き、その特徴や利用方法を探っていきます。


※著者のイメージするADK Go

対象読者

  • Goユーザー
  • ADKを触ったことがある方々
  • AIエージェントに興味がある方

なお本記事中ではADKのAgentをAgent、それ以外のAIエージェントをエージェントと表記します。

ADK Goとは

ADK Goは、その名の通りADKのGo言語実装です。ADK(Python)の主要な設計思想を継承しつつ、Goの持つ並行処理と強い型付けといった強みを最大限に活用し、堅牢でスケーラブルなエージェントアプリケーションの構築を可能にするフレームワークです。

ADK Pythonと同様の、以下の設計思想が引き継がれています。

  • コードファースト開発: Agentのロジック、ツール、オーケストレーションをコードで直接定義することによる、高い柔軟性、テスト容易性、バージョン管理。
  • マルチエージェントシステム: 複数の専門Agentを協調させるスケーラブルなアプリケーション設計。
  • データ統合: データベースやAPIなど、様々なデータソースとの容易な連携。
  • 開発UI: Agentのテスト、デバッグ、評価を支援する組み込みのWeb UI。
  • Googleエコシステム、Geminiへの最適化: GeminiモデルやGoogle Cloudの各種サービスとのシームレスな連携。

ただし、バージョンはまだ0.1.0であり、公式にも「1.0に達する前に破壊的変更が含まれる可能性がある」とアナウンスされているため、本番環境での利用はまだ推奨されていません。実験的な段階にあると言えるでしょう。

ADK Goの使い方

それでは、実際にADK Goを使って簡単なAIエージェントを作成してみましょう。

1. プロジェクトのセットアップ

まず、プロジェクト用のディレクトリを作成し、Goモジュールを初期化します。

# プロジェクト用のディレクトリ作成
mkdir adk-go-sample
cd adk-go-sample

# Goモジュールの初期化 (PROJECT_NAMEは適宜変更してください)
go mod init adk-go-sample

2. 依存関係のインストール

次に、ADK Go本体をインストールします。

go get google.golang.org/adk

3. エージェントの作成

main.goファイルを作成し、エージェントのロジックを記述します。今回は、タイムゾーンを指定して現在時刻を返すシンプルなエージェントを作成します。

main.go
package main

import (
	"context"
	"log"
	"os"
	"time"

	"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/functiontool"
	"google.golang.org/genai"
)

type NowToolParams struct {
	Timezone string `json:"timezone" jsonschema:"A timezone name, e.g. 'Asia/Tokyo'"`
}

type NowToolResult struct {
	// Current time
	Time time.Time `json:"time" jsonschema:"ISO8601 formatted time"`

	// Error
	Err error `json:"err" jsonschema:"Error message, if any"`
}

// NowTool returns the current time in the given timezone.
func now(_ tool.Context, params NowToolParams) NowToolResult {

	location, err := time.LoadLocation(params.Timezone)

	if err != nil {
		return NowToolResult{Err: err}
	}

	return NowToolResult{Time: time.Now().In(location)}
}

func main() {

	ctx := context.Background()

	model, err := gemini.NewModel(ctx, "gemini-2.5-flash", &genai.ClientConfig{
		HTTPOptions: genai.HTTPOptions{APIVersion: "v1"},
	})

	if err != nil {
		panic(err)
	}

	time_tool, err := functiontool.New(functiontool.Config{
		Name:        "now",
		Description: "Get the current time in the given timezone",
	}, now)
	if err != nil {
		panic(err)
	}

	root_agent, err := llmagent.New(llmagent.Config{
		Name:        "time_agent",
		Model:       model,
		Description: "A time agent",
		Instruction: "You are a time agent. You can answer questions about the current time and date.",
		Tools:       []tool.Tool{time_tool},
	})
	if err != nil {
		panic(err)
	}

	agentLoader, err := services.NewMultiAgentLoader(root_agent)
	if err != nil {
		log.Fatalf("failed to create agent loader: %v", err)
	}
	l := full.NewLauncher()
	if err := l.Execute(ctx, &adk.Config{
		AgentLoader: agentLoader,
	}, os.Args[1:]); err != nil {
		log.Fatalf("run failed: %v\n\n%s", err, l.CommandLineSyntax())
	}
}

4. 開発サーバーの起動

環境変数を設定し、go runコマンドで開発サーバーを起動します。今回はVertex AIを利用します。

GOOGLE_CLOUD_PROJECT={YOUR_PROJECT} \
GOOGLE_CLOUD_LOCATION=us-central1 \
GOOGLE_GENAI_USE_VERTEXAI=True \
go run main.go web webui api

起動に成功すると、http://localhost:8080でサーバーが起動します。
ブラウザでアクセスすると見慣れたADKの開発UIが表示されるはずです。ここで「東京は今何時?」などと質問してみてください。


ADK GoのWeb UI

細かいコード解説

ADK Goの実装は、ADK Pythonの思想を色濃く反映しており、いくつかの主要なコンポーネントから構成されています。

1. Model

ModelはAgentに設定するLLMを表すインターフェースです。このインターフェースを実装したstructをAgentに渡します。

type LLM interface {
    Name() string
    GenerateContent(ctx context.Context, req *LLMRequest, stream bool) iter.Seq2[*LLMResponse, error]
}

現状、ADK GoではGeminiモデルのみがサポートされており、gemini.NewModel関数を使って簡単にインスタンスを作成できます。

model, err := gemini.NewModel(ctx, "gemini-2.5-flash", &genai.ClientConfig{
    HTTPOptions: genai.HTTPOptions{APIVersion: "v1"},
})

2. Tool

AIエージェントの強力な機能であるツール(Function Calling)は、Toolインターフェースを実装したstructとして定義します。

Function Callingとは

Function Calling はLLMだけでは行えないリアルタイムの情報を取得したり、なにかしらのアクションを行うために、LLMに対して利用可能な機能群とその機能に必要なパラメータ、その機能が返却する値の情報を提供し、必要なタイミングでそれらの呼び出し要求を行ってもらう機能です。
なおLLMや利用する機能にもよりますが、基本的には機能の呼び出し自体はLLM側ではなくAgentフレームワーク内で行います。

例えばLLMに現在時刻を取得する機能を提供したりするために利用します。
ADKではLlmAgentのコンストラクタにて tools パラメータに利用するツール(Goの場合は関数)リストを渡すことでFunction Callingを利用できます。

ADK Goには、独自のツールを定義するためのfunctiontool、Agentをツールとして扱うagenttool、MCPサーバーと連携するmcptoolset、Google検索を行うgeminitool.GoogleSearchなどが用意されています。

独自のツールを定義する場合、tool.Contextとパラメータ用のstructを引数に取り、結果用のstructを返す関数を作成し、それをfunctiontool.Newでラップします。

// パラメータと戻り値の型をstructで定義
type NowToolParams struct {
	Timezone string `json:"timezone" jsonschema:"A timezone name, e.g. 'Asia/Tokyo'"`
}

type NowToolResult struct {
	Time time.Time `json:"time" jsonschema:"ISO8601 formatted time"`
	Err  error     `json:"err" jsonschema:"Error message, if any"`
}

// ツールの実体となる関数
func now(_ tool.Context, params NowToolParams) NowToolResult {
    // ...処理...
}

// functiontool.Newでツールを作成
time_tool, err := functiontool.New(functiontool.Config{
    Name:        "now",
    Description: "Get the current time in the given timezone",
}, now)

面白い点として、パラメータや結果のstructにjsonschemaタグを付けることで、ツールのスキーマ情報(説明など)を定義できるようです。これはPython版でdocstringからスキーマを生成していた機能に相当するものですが、Goの型システムを活かしたアプローチと言えるでしょう。

3. Agent

Agentは、他のADK実装と同様にAIエージェントそのものを表します。LLMとの対話を行うllmagent、ワークフローを制御するworkflowagents、A2A通信を行うremoteagentなどが提供されています。
実行にはPython版と異なり、sync/async用の個別の関数は用意されていません。代わりに Run というメソッドが1つ提供されており、これは goroutine による非同期実行を想定していると思われます。

root_agent, err := llmagent.New(llmagent.Config{
    Name:        "time_agent",
    Model:       model,
    Description: "A time agent",
    Instruction: "You are a time agent. You can answer questions about the current time and date.",
    Tools:       []tool.Tool{time_tool},
})

設定できる項目はPython版とほぼ同じで、コールバックやOutputKeyなどもサポートされています。

4. Runner

Runnerも他のADK実装と同様に、定義したAgentを実行するためのコンポーネントです。
ただし、サンプルコードではRunnerを直接利用するのではなく、後述するLauncherを使っています。
Python版のInMemoryRunnerのように、CLIで手軽にAgentを実行したい場合は、以下のようにrunnerパッケージを利用することになります。

// runnerを利用する場合
rnr, err := runner.New(runner.Config{
    AppName: "time_agent",
    Agent:   root_agent,
})
if err != nil {
    panic(err)
}
for event, err := range rnr.Run(
    ctx,
    "user_id",
    "session_id",
    genai.NewContentFromText("今東京は何時?", genai.RoleUser),
    agent.RunConfig{
        StreamingMode:             agent.StreamingModeSSE,
        SaveInputBlobsAsArtifacts: false,
    },
) {
    if err != nil {
        panic(err)
    }
    log.Printf("event: %+v", event)
}

5. Launcher

Launcherは、ADK Goに特有の概念で、Python版のadkコマンド(adk web, adk runなど)に相当する機能を提供します。
Goは動的にコードを読み込むのが難しいため、コンパイルされたバイナリ自体にCLIランチャーの機能を持たせる、というGoらしい設計思想が見て取れます。

// Agentをロードするローダーを作成
agentLoader, err := services.NewMultiAgentLoader(root_agent)
if err != nil {
    log.Fatalf("failed to create agent loader: %v", err)
}

// Launcherを作成し、実行
l := full.NewLauncher()
if err := l.Execute(ctx, &adk.Config{
    AgentLoader: agentLoader,
}, os.Args[1:]); err != nil {
    log.Fatalf("run failed: %v\n\n%s", err, l.CommandLineSyntax())
}

full.NewLauncher()は、CLIでの対話(Console Launcher)とWeb UI(Web Launcher)の両方を扱える便利なランチャーです。go run main.go web webui apiのように引数を渡すことで、その動作を切り替えることができます。

まとめ

今回は、リリースされたばかりのADK for Goについて、その概要と使い方を解説しました。

  • ADKの思想を継承: コードファースト、マルチエージェント、ツール連携といったADKのコアコンセプトはGo版でも健在です。
  • Goらしい再設計: Launcherの仕組みや、Runメソッドのみの提供など、Goの機能や特性を考慮した設計になっています。
  • 今後の発展に期待: まだ実験的な段階ではありますが、Python版ADKの基本的な機能は揃っており、今後の機能追加や安定化が非常に楽しみです。

Go言語の持つパフォーマンスと堅牢性は、特に本番環境でAIエージェントを運用する上で大きな利点となる可能性があります。Goを得意とする開発者にとって、AIエージェント開発の新たな選択肢が登場したと言えるでしょう。


お知らせ/宣伝

ADK開発者が集う日本語のDiscordコミュニティがあります。ADKに関する情報交換や議論に興味がある方は、ぜひご参加ください!

https://discord.gg/BKpGRzjtqZ

また、ADKの最新のコミットログやリリースノートを分かりやすく解説するPodcastを、月・水・金に配信しています。ADKの動向を追いかけたい方は、ぜひ聴いてみてください。

https://www.youtube.com/playlist?list=PL0Zc2RFDZsM_MkHOzWNJpaT4EH5fQxA8n

Discussion