クイックスタート
10分で動くAIエージェントを作ります。スタブから始め、ストリーミングとバリデーションを追加し、最後に実際のLLMへ接続します。
Goa-AI は、Goa の design-first(設計を単一の真実の源にする)哲学を、エージェント型システムに拡張します。DSL でエージェント・ツールセット・ポリシーを宣言し、型付けされたコントラクト、耐久性のあるワークフロー、ストリーミングイベントを備えたプロダクション品質の実装を生成します。
壊れやすいエージェント実装をやめて、コントラクトから始めましょう。
多くのエージェントフレームワークでは、プロンプト・ツール・API 呼び出しを命令的に配線していきます。壊れたとき(そして壊れます)に待っているのは、散在したコードのデバッグと、はっきりしない「真実の源」です。
Goa-AI は逆転します。型付き DSL で能力を定義し、実装を生成する。設計がそのままドキュメントになり、コントラクトがそのまま検証になります。変更は自動的に全体へ波及します。
Agent("assistant", "A helpful coding assistant", func() {
Use("code_tools", func() {
Tool("analyze", "Analyze code for issues", func() {
Args(func() {
Attribute("code", String, "Source code to analyze", func() {
MinLength(1) // Can't be empty
MaxLength(100000) // Reasonable size limit
})
Attribute("language", String, "Programming language", func() {
Enum("go", "python", "javascript", "typescript", "rust", "java")
})
Required("code", "language")
})
Return(AnalysisResult)
})
})
})
LLM がこのツールを不正な引数で呼び出した場合(例: code が空、language: "cobol" など)、Goa-AI は バリデーションエラーのメッセージ付きで自動リトライします。LLM は何が間違っていたのかを正確に理解し、自己修正できます。手書きのエラーハンドリングは不要です。
メリット:
→ 詳細は DSL Reference と Quickstart を参照してください。
単純で観測可能な部品から、複雑なシステムを組み立てます。
現実の AI アプリケーションは、単一エージェントで完結しません。エージェントが別のエージェントへ委譲し、ツールがサブタスクを生成し、全体を追跡できることが求められます。
Goa-AI の ランツリー(run tree)モデルは、完全な可観測性を備えた階層実行を提供します。各ランは一意の ID を持ち、子ランは親にリンクされ、イベントはリアルタイムでストリーミングされます。失敗時はツリーを辿って原因に到達できます。
メリット:
→ 詳細は Agent Composition と Runtime を参照してください。
エージェントの意思決定をリアルタイムで可視化します。
ブラックボックスなエージェントはリスクです。ツール呼び出し、思考の開始、エラーの発生を 今すぐ 知る必要があります(タイムアウト後では遅い)。
Goa-AI は実行中に 型付けされたイベントを発行します。たとえば、ストリーミングテキストの assistant_reply、ツールのライフサイクルを表す tool_start/tool_end、推論の可視化のための planner_thought、トークン消費の usage などです。イベントはシンプルな Sink インターフェースを介して任意のトランスポートへ流せます。
// Wire a sink at startup — all events from all runs flow through it
rt := runtime.New(runtime.WithStream(mySink))
// Or subscribe to a specific run
stop, _ := rt.SubscribeRun(ctx, runID, connectionSink)
defer stop()
Stream profiles は消費者ごとにイベントをフィルタします。エンドユーザ UI 用の UserChatProfile()、開発者向けの AgentDebugProfile()、観測基盤向けの MetricsProfile() など。Pulse(Redis Streams)用の組み込み sink により、サービス間で分散ストリーミングできます。
メリット:
RunID と SessionID によりルーティング・フィルタが可能→ 実装詳細は Production Streaming を参照してください。
クラッシュ、再起動、ネットワーク障害に耐えるエージェント実行。
耐久性がないと、プロセスのクラッシュで進捗が消えます。レートリミットでラン全体が失敗します。ツール実行中のネットワーク瞬断で、高価な推論をやり直すことになります。
Goa-AI は Temporal による耐久実行を採用します。エージェントランはワークフローになり、ツール呼び出しはリトライ設定可能なアクティビティになります。すべての状態遷移が永続化され、ツールがクラッシュしても LLM 呼び出しを再実行することなく 自動的にリトライできます。
// Development: in-memory (no dependencies)
rt := runtime.New()
// Production: Temporal for durability
eng, _ := temporal.New(temporal.Options{
ClientOptions: &client.Options{HostPort: "localhost:7233"},
WorkerOptions: temporal.WorkerOptions{TaskQueue: "my-agents"},
})
rt := runtime.New(runtime.WithEngine(eng))
メリット:
→ セットアップとリトライ設定は Production を参照してください。
どこからでもツールを発見し、利用できます(クラスタ内でもパブリッククラウドでも)。
AI エコシステムが拡大すると、ツールはあらゆる場所に散らばります。社内サービス、サードパーティ API、公開 MCP レジストリ。ツール定義をハードコードする方法はスケールしません。動的ディスカバリが必要です。
Goa-AI は、自社ツールセット向けの クラスタ対応の内部レジストリと、Anthropic の MCP カタログのような外部レジストリと連携する フェデレーションを提供します。一度定義すれば、どこからでも発見できます。
// Connect to public registries
var AnthropicRegistry = Registry("anthropic", func() {
Description("Anthropic MCP Registry")
URL("https://registry.anthropic.com/v1")
Security(AnthropicOAuth)
Federation(func() {
Include("web-search", "code-execution", "filesystem")
Exclude("experimental/*")
})
SyncInterval("1h")
CacheTTL("24h")
})
// Or run your own clustered registry
var CorpRegistry = Registry("corp", func() {
Description("Internal tool registry")
URL("https://registry.corp.internal")
Security(CorpAPIKey)
SyncInterval("5m")
})
内部レジストリのクラスタリング:
同じ名前の複数ノードは、Redis を介して自動的にクラスタを形成します。共有状態、協調ヘルスチェック、水平スケール——すべて自動です。
メリット:
→ 詳細は MCP Integration と Production を参照してください。
| 機能 | 得られるもの |
|---|---|
| Design-First Agents | DSL でエージェントを定義し、型安全なコードを生成 |
| MCP Integration | Model Context Protocol のネイティブサポート |
| Tool Registries | クラスタ対応のディスカバリ + 公開レジストリのフェデレーション |
| Run Trees | エージェントがエージェントを呼ぶ構成を完全に追跡 |
| Structured Streaming | UI と観測のためのリアルタイム型付きイベント |
| Temporal Durability | 障害に強い、耐久実行 |
| Typed Contracts | ツール操作のエンドツーエンド型安全性 |
| ガイド | 説明 | ~Tokens |
|---|---|---|
| Quickstart | インストールと最初のエージェント | ~2,700 |
| DSL Reference | 完全な DSL: agents / toolsets / policies / MCP | ~3,600 |
| Runtime | ランタイム構造、plan/execute ループ、エンジン | ~2,400 |
| Toolsets | ツールセット種別、実行モデル、トランスフォーム | ~2,300 |
| Agent Composition | agent-as-tool、ランツリー、ストリーミングトポロジ | ~1,400 |
| MCP Integration | MCP サーバ、トランスポート、生成ラッパ | ~1,200 |
| Memory & Sessions | トランスクリプト、メモリストア、セッション、ラン | ~1,600 |
| Production | Temporal セットアップ、ストリーミング UI、モデル統合 | ~2,200 |
| Testing & Troubleshooting | エージェント/プランナー/ツールのテスト、典型的なエラー | ~2,000 |
Total Section: ~21,400 tokens
Goa-AI は、宣言的な設計をプロダクション品質のエージェントシステムへ変換する define → generate → execute パイプラインに従います。
レイヤ概要:
| レイヤ | 目的 |
|---|---|
| DSL | バージョン管理された Go コードで、エージェント・ツール・ポリシー・外部統合を宣言 |
| Codegen | 型安全な spec/codec/workflow 定義/レジストリクライアントを生成(gen/ は編集しない) |
| Runtime | ポリシー適用、メモリ永続化、イベントストリーミングを伴う plan/execute ループの実行 |
| Engine | 実行バックエンドを交換(開発は in-memory、本番は Temporal) |
| Features | モデルプロバイダ(OpenAI/Anthropic/AWS Bedrock)、永続化(Mongo)、ストリーミング(Pulse)、レジストリなどをプラグイン |
主要な統合ポイント:
Goa-AI は 3 つの LLM プロバイダ向けにファーストクラスのアダプタを提供します。
features/model/openai)features/model/anthropic)features/model/bedrock)3 つはいずれも、プランナーが利用する同一の model.Client インターフェースを実装します。アプリケーションは rt.RegisterModel("provider-id", client) でモデルクライアントを登録し、プランナーや生成されたエージェント設定から ID で参照します。プロバイダ差し替えは設計変更ではなく設定変更になります。
新しいプロバイダを追加する手順も同様です。
model.Request / model.Response / ストリーミング model.Chunk にマッピングして model.Client を実装する。features/model/middleware.NewAdaptiveRateLimiter)でレート制限とメトリクスを付与する。rt.RegisterModel("my-provider", client) を呼び出し、プランナーやエージェント設定から "my-provider" を参照する。プランナーとランタイムは model.Client のみに依存するため、新しいプロバイダは Goa の設計や生成コードの変更なしに追加できます。
package design
import (
. "goa.design/goa/v3/dsl"
. "goa.design/goa-ai/dsl"
)
var _ = Service("calculator", func() {
Description("Calculator service with an AI assistant")
// Define a service method that the tool will bind to
Method("add", func() {
Description("Add two numbers")
Payload(func() {
Attribute("a", Int, "First number")
Attribute("b", Int, "Second number")
Required("a", "b")
})
Result(Int)
})
// Define the agent within the service
Agent("assistant", "A helpful assistant agent", func() {
// Use a toolset with tools bound to service methods
Use("calculator", func() {
Tool("add", "Add two numbers", func() {
Args(func() {
Attribute("a", Int, "First number")
Attribute("b", Int, "Second number")
Required("a", "b")
})
Return(Int)
BindTo("add") // Bind to the service method
})
})
// Configure the agent's run policy
RunPolicy(func() {
DefaultCaps(MaxToolCalls(10))
TimeBudget("5m")
})
})
})
まずは Quickstart を参照し、Goa-AI をインストールして最初のエージェントを構築してください。
DSL の全体像は DSL Reference を参照してください。
ランタイムアーキテクチャは Runtime を参照してください。