Goで書いたサーバーからLLMを呼びたい、という場面はもう珍しくない。だが実際にやろうとすると、たいていフロントエンドとの境界で止まる。ブラウザ側にはReact向けの成熟したチャットUIフックがあるのに、それが期待するストリームの形をGoから正確に吐くのが面倒で、結局TypeScriptのBFFを1枚挟むことになる。Grafana Labsが公開したGrafana AI SDK for Gografana/ai-sdk)は、その1枚を無くしにいくSDKだ。

Grafana AI SDK for Go の公式バナー。streaming, tool-calling AI backends that speak fluent @ai-sdk/react というキャッチコピーが表示される12フレームのアニメーション
公式リポジトリのバナー(docs/assets/ai-sdk-banner.gif)。副題の "speak fluent @ai-sdk/react" がこのSDKの立ち位置をそのまま表している
30秒でわかる Grafana AI SDK for Go(2026年8月2日時点)
  • 何ができるか:Goから`GenerateText`/`StreamText`でモデルを呼び、SSEをそのままReactの`useChat`へ流せる。ツール実行・構造化出力・エージェントループも同じAPIに載る
  • 何を解決するか:AI SDK規約を話すためだけのTypeScript製BFFを挟まなくてよくなる。プロトコル変換アダプタを自作する必要もない
  • 何を代替しうるか:既存フロントがAI SDK Reactなら、その裏側のTypeScriptバックエンドをGoに置き換えられる。フロント側のコードは原則そのまま
  • 成熟度:公開2026-07-28、タグは`v0.1.0-alpha.1`の1本のみ・Releasesは0件。Apache-2.0、★179
この記事のポイント
・GoのHTTPハンドラが`WriteUIMessageStream`を呼ぶだけで、ブラウザ側のフックが解釈できるSSEになる仕組みを、実装ソースと公式ドキュメントから追う
・ツール承認のHMAC署名について、GoとTypeScriptの実装を両方読み、Pythonで再実装してテストベクタを再現した結果を載せる
・「Vercel AI SDKと互換」という主張が、固定したnpmバージョンに対する適合テストと公開された`knownGaps`という形でどこまで検証されているかを見る
Grafana AI SDKのリポジトリ実測値。スター179、唯一のタグはv0.1.0-alpha.1、go.modの宣言はGo 1.26.3、ライセンスはApache-2.0
GitHub APIとgo.modから取得した実測値(2026-08-02時点)。公開から5日目という前提を最初に押さえておきたい

このSDKがどのあたりに位置するかは、AIエージェントフレームワーク比較2026|LangGraph・CrewAI・Dify等9種をStar数・実コードで検証で扱っているフレームワーク群と並べて見ると掴みやすい。あちらが「エージェントの組み立て方」を提供するのに対し、こちらは「フロントエンドとの通信規約にGoを合わせる」ことに軸足がある。

Grafana AI SDK for Goとは——GoのバックエンドがReactのフックに直接しゃべる

READMEの説明は素っ気ない。「Goアプリケーションに、モデル呼び出し・ストリーミング・ツール・構造化出力・複数ステップのエージェントのための単一のAPIを与える」。ただし直後に、このSDKの性格を決めている一文が続く。Vercel AI SDKの設計に従い、そのTypeScriptフロントエンドのフックとワイヤ互換を保つ、という宣言だ。

ここでいうワイヤ互換は比喩ではない。リポジトリのNOTICEには、何を借りたのかが具体的に列挙されている。Server-Sent Eventsのワイヤ形式、UI message chunkのプロトコル、プロバイダインターフェースの形、APIとオプションの命名、ドキュメントの一部、そしてtest/conformance/配下の「上流の振る舞いを記録した適合フィクスチャ」である。

つまりこれは、LLM SDKをゼロから設計し直した製品ではない。既に広く使われているフロントエンド側の規約を固定点として受け入れ、そこにGoの実装を合わせにいくという選択をした移植である。そう理解すると、後述する適合テストの作り込みの理由も見えてくる。

開発元:Grafana Labs。初回コミットのメッセージには、社内リポジトリgrafana/ai-sdk-internalの履歴をsquashして公開したものだと書かれている
言語構成:GitHub API上はGoが約294万バイトで最大。TypeScriptが約10万バイト含まれるが、これは後述する相互運用テスト側のコード
ライセンス:Apache-2.0。上流のVercel AI SDKも同じApache-2.0で、帰属はNOTICEに記録されている
公開状況:2026-07-28作成。タグはv0.1.0-alpha.1が1本のみで、GitHubのReleasesは0件

Goバックエンドがブラウザのフックへ直接ストリームする流れ。GoのStreamTextからSSEのtext-deltaチャンクを経てReactのuseChatへ届く
READMEが冒頭で示す構図。間にプロトコル変換のアダプタが挟まらないことがこのSDKの主張(出典:docs/concepts/wire-protocol.md

なぜ「Goで書ける」ことが問題になるのか

LLMを呼ぶだけなら、どの言語からでもHTTPクライアントで足りる。難しいのはストリーミングのほうだ。トークンが逐次届くとき、フロントエンドはそれを「テキストの差分」「推論内容」「ツール呼び出しの開始」「ツールの入力が確定した」「ソース参照」「ファイル」「エラー」といった型付きの出来事として受け取りたい。AI SDK ReactのuseChatはそういうチャンク列を前提に組まれている。

この形をGoから手で吐こうとすると、チャンクの型名・JSONのフィールド名・順序・終端の番兵まで合わせる必要がある。しかも上流の実装が更新されれば追随がいる。多くのチームがTypeScriptのBFFを挟むのは、この追随コストを上流のパッケージに任せるためだ。Grafana AI SDKは、その追随を自分のリポジトリの中の検証可能なテストとして引き受けている。

インストールと使い方——最初の1回をGenerateTextで通す

導入は本体モジュールとプロバイダを別々に取得する形になっている。プロバイダごとに依存が分かれているため、使わないSDKの依存を引き込まない。

mkdir ai-sdk-quickstart
cd ai-sdk-quickstart
go mod init example.com/ai-sdk-quickstart
go get github.com/grafana/ai-sdk
go get github.com/grafana/ai-sdk/providers/anthropic

最小の疎通確認はREADMEにそのまま載っている。ストリーミングを使わず、応答が揃うまで待つGenerateTextのほうが最初の1回には向く。

package main

import (
	"context"
	"fmt"
	"log"
	"os"

	aisdk "github.com/grafana/ai-sdk"
	"github.com/grafana/ai-sdk/provider"
	"github.com/grafana/ai-sdk/providers/anthropic"
)

func main() {
	apiKey := os.Getenv("ANTHROPIC_API_KEY")
	if apiKey == "" {
		log.Fatal("ANTHROPIC_API_KEY is required")
	}

	model := anthropic.New(apiKey, "claude-sonnet-5")
	result, err := aisdk.GenerateText(context.Background(), model,
		aisdk.WithModelMessages(provider.UserText("Explain goroutines in one sentence.")),
	)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(result.Text)
}

go.modが要求するGoのバージョンは1.26.3である。比較的新しい処理系を前提にしている点は、既存プロジェクトへ入れる前に確認しておきたい。

注意:本記事はGoの実行環境での動作確認は行っていない
本記事の検証は、リポジトリの実装ソース・テスト・ドキュメントの読解と、後述する署名アルゴリズムのPythonでの再実装によって行っている。Goツールチェーンでのビルドやテスト実行は行っていないため、上記のコードはリポジトリ収載のものをそのまま引用したものとして扱ってほしい。

ストリーミングの仕組み——SSEでuseChatへ流す通信規約

ストリーミングを使う場合、HTTPハンドラ側で書くコードは驚くほど短い。StreamTextの結果をWriteUIMessageStreamに渡すだけで、レスポンスヘッダの設定、オーケストレーションイベントの翻訳、SSEフレームのフラッシュ、完了番兵の書き出しまでが済む。

実際にブラウザへ流れるのは、次のような型付きチャンクの列である。公式ドキュメントが簡略化した例として示しているものだ。

{"type":"start","messageId":"msg_123"} でメッセージが始まる
{"type":"text-start","id":"text_1"} でテキストパートが開く
{"type":"text-delta","id":"text_1","delta":"Hello"} が差分として繰り返し届く
{"type":"text-end","id":"text_1"}{"type":"finish"} で閉じる
・最後に [DONE] が番兵として送られる

テキスト以外にも、推論・ツール呼び出し・承認・ソース・ファイル・メタデータ・エラー・カスタムデータそれぞれに型付きのチャンク種別がある。フィルタしたいときはToUIMessageStreamにオプションを渡してから書き出す形になり、たとえば推論内容は既定で送られる一方、ソースは明示的に有効化しない限り送られない。推論内容がそのままブラウザへ届く既定である点は、そのアプリケーションの利用者に見せてよい情報かどうかを判断したうえで扱う必要がある。公式ドキュメントも同じ注意を明記している。

なお、ここでいうUIストリームと、サービス間でprovider.LanguageModelの呼び出しを運ぶgateway/providerwireは別物として整理されている。前者はブラウザのフック向けで[DONE]で終わり、後者はプロバイダ水準のフレーミングでサービス間を繋ぐ。用語が似ているので混同しやすい。

ツール実行と承認フロー——なぜモデル呼び出しが2回に分かれるのか

このSDKで踏み込んで面白いのはツール承認だ。モデルが「この関数を呼びたい」と言ってきたとき、副作用の重い操作については人間かアプリケーションのポリシーが判断を挟みたい。公式ドキュメントは対象として、アクセス権の変更・データの削除・メッセージ送信・支払い・読み取り専用の安全な範囲を超える操作を挙げている。

重要なのは、承認が1回のリクエストの中で完結しないことだ。

sequenceDiagram participant U as ユーザー / ブラウザ participant G as Goバックエンド participant M as モデル U->>G: 1回目のリクエスト G->>M: StreamText(ツール定義つき) M-->>G: ツール呼び出しを提案 G-->>U: 承認要求チャンク
(ツールは実行されない) Note over G: 呼び出しはここで終了する
HTTPは開いたまま待たない U->>U: 承認 / 拒否を決める U->>G: 2回目のリクエスト
(決定を追記した履歴) G->>G: 決定を読む・署名を検証 G->>M: 承認済みツールを実行して継続 M-->>G: 実行結果を踏まえた応答 G-->>U: 応答をストリーム

公式ドキュメントは「保留中の承認は現在の呼び出しを意図的に止める。人間の判断を待つ間HTTPリクエストを開いたままにしてはいけない」と明記している。useChatを使う場合はUIMessageのパートを丸ごと永続化し、ユーザーが決めた後に更新された履歴を送り直す。

ツール側での指定は2通りある。常に承認を要求するApprovalRequired()と、提案された入力を見て判断するApprovalIf(...)だ。後者は「/tmp/配下なら承認不要、それ以外は要承認」といったパス判定を書ける。さらに呼び出し単位のポリシーWithToolApprovalが、ツール自身のNeedsApprovalより優先される設計になっている。公式の使い分けの指針は明快で、テナントやユーザーごとの認可は呼び出し単位、そのツールに内在する危険性はツール側に置く。

拒否はエラーではない

もう一点、設計として書かれているのが拒否の扱いだ。「拒否はインフラのエラーではない」。理由があれば保持し、モデルに説明させるか安全な代替案を出させる。ログには判断内容を残しつつ、保持ポリシーが許さない限り機微なツール入力そのものは記録しない、とされている。

承認署名のバイト列を検算する——Pythonで再実装して確かめた

承認の状態がブラウザを経由して往復する以上、クライアント側で書き換えられる余地が生まれる。承認IDを使い回す、ツール名だけ差し替える、引数を書き換える——いずれも「ユーザーは承認したことになっている」まま危険な操作へ化ける。これを塞ぐのがWithToolApprovalSecretだ。

result := aisdk.StreamText(ctx, model,
	aisdk.WithMessages(messages...),
	aisdk.WithTools(tools),
	aisdk.WithToolApprovalSecret(os.Getenv("TOOL_APPROVAL_SECRET")),
)

実装(tool_approval_signature.go)を読むと、署名はHMAC-SHA256で、対象は次の5要素を並べたJSON配列である。

・版数を表す固定文字列 ai-sdk-tool-approval-v1
・承認ID(approvalID
・ツール呼び出しID(toolCallID
・ツール名(toolName
・入力の正準JSONのSHA-256ダイジェスト(base64url・パディング無し)

正準JSONというのは、オブジェクトのキーを昇順に並べて空白を入れない直列化のことで、キーの並び順が違うだけで別物と判定されるのを防ぐ。

テストベクタをPythonで再現する

Goのテストには、具体的な期待値が1つ埋め込まれている。鍵がsecret、承認IDにU+2028(行区切り文字)、ツール呼び出しIDにタブ、ツール名に二重引用符とバックスラッシュを含めた意地の悪い入力に対して、署名がVOMet8mr-T4bwRmGaKmegABRxv1Q_BnLlFZ-YqoU7cIになる、というものだ。

仕様の理解が正しいかを確かめるには、独立に実装して同じ値が出るかを見るのが早い。Goを使わずPythonで書き直したものが以下で、そのまま実行できる。

import hmac, hashlib, base64, json

def b64(b):  # パディング無しの base64url
    return base64.urlsafe_b64encode(b).decode().rstrip("=")

def canonical(v):  # キー昇順・空白なしの正準JSON
    return json.dumps(v, sort_keys=True, separators=(",", ":"), ensure_ascii=False)

inp = {"b": 2, "a": 1}
digest = b64(hashlib.sha256(canonical(inp).encode()).digest())

payload = json.dumps(
    ["ai-sdk-tool-approval-v1", "apr<
", "call\t1", "name\"\\", digest],
    separators=(",", ":"), ensure_ascii=False,
)
print(b64(hmac.new(b"secret", payload.encode("utf-8"), hashlib.sha256).digest()))
# => VOMet8mr-T4bwRmGaKmegABRxv1Q_BnLlFZ-YqoU7cI

実行すると、Goのテストが期待している値と一致する。つまり署名対象のバイト列は、上に挙げた5要素をこの順にJSON配列へ入れた素朴なもので、隠れた前処理は無い。入力ダイジェストの正準化規則も、キー昇順・空白なしという読み方で合っている。

なぜJSON配列なのか——改行で境界が消える問題

実装にはもう一つ、legacyApprovalPayloadという関数が残っている。こちらはJSON配列ではなく、4つの値を改行で連結しただけの形式だ。検証時にのみ、後方互換のフォールバックとして使われる。そして条件が付いている。承認ID・ツール呼び出しID・ツール名のいずれかに改行が含まれていたら、このフォールバックは使わない。

この条件が何を防いでいるかは、フィールドの区切り方が違う2通りを並べると一目で分かる。

署名した側の解釈:
  toolCallID = "call-1"            toolName = "searchDocs\ndeleteFile"
検証にかける側の解釈:
  toolCallID = "call-1\nsearchDocs"  toolName = "deleteFile"

改行で連結すると、どちらも同一のバイト列になる:
  approval-1\ncall-1\nsearchDocs\ndeleteFile\nniy2F8anppLBE90LymGBpNCQna4pfgUfLj_vX-rtd3c

上と下では、ツール呼び出しIDとツール名の境目の位置が違う。にもかかわらず、改行で繋いだ結果の並びは1バイトも変わらない。区切り文字がデータの中にも現れうるため、連結してしまうと境界が復元できないからだ。HMACは並んだバイト列に対して計算されるので、当然どちらも同じ署名になる。結果として、searchDocsへの承認だったはずの署名が、deleteFileへの承認として通ってしまう

JSON配列にすると、改行は\nとしてエスケープされ、要素の境界は構文として決まる。同じ2通りを並べても別のバイト列になり、署名は一致しない。

承認署名の旧形式と現行形式の比較。改行連結の旧形式はフィールド境界が消えるが、JSON配列の現行形式はエスケープにより境界が一意に決まる
旧形式(改行連結)と現行形式(JSON配列)の違い。GoとTypeScript双方の実装ソースを読み、Pythonで再実装して各バイト列を確認した

これはGrafanaが見つけた欠陥ではない

ここは正確に書いておきたい。この改行の問題と対策は、上流のVercel AI SDK側に既に存在する。上流のpackages/ai/src/generate-text/tool-approval-signature.tsを読むと、同じ版数文字列ai-sdk-tool-approval-v1、同じJSON配列のペイロード、同じ改行連結のフォールバック、そして同じ「どのフィールドにも改行が無いときだけフォールバックを許す」ガードが実装されている。コメントには「符号化が単射(injective)になるようJSONで直列化する」という設計意図と、v8でこのフォールバックを削除する予定を示すTODOまで書かれている。

したがって正しい理解はこうだ。Grafanaはこの脆弱な旧形式を自ら塞いだのではなく、上流の対策済みスキームを、後方互換のフォールバックとその安全ガードごと忠実に移植した。Go側のテスト名がmatches upstream JSON payload(上流のJSONペイロードと一致する)となっているのは、まさにその意図を表している。

「相互に検証できる」と言い切れる範囲
本記事で確認したのは、GoとTypeScriptの実装ソース上で署名対象バイト列の作り方が一致していること、そしてGoのテストベクタがPythonでの独立実装で再現できることの2点である。同じ秘密鍵を設定した実サーバー同士で、TypeScriptが発行した署名をGoが検証する(あるいはその逆)という相互運用の実測までは行っていない。設計上そうなるはずだ、というところまでが本記事の根拠の範囲だと理解してほしい。

署名は認可の代わりではない

公式ドキュメントが繰り返し強調している点も引いておく。署名はメッセージの改ざんを防ぐが、認可を置き換えるものではない。ユーザーが承認した後であっても、Executeの中で副作用を起こす直前に、現在のユーザー・テナント・リソース権限・業務上の不変条件をもう一度確認せよ、とされている。秘密鍵はサーバー側に置き、ローテーションは処理中の承認への影響を踏まえた移行戦略とセットで行う、という運用上の注意も併記されている。

なお、ツール定義そのものの変化を検出するFingerprintToolsDetectToolDriftも同梱されている。ツールの説明文・入力スキーマ・タイトルという「セキュリティ上意味を持つ定義フィールド」から安定したダイジェストを作り、信頼できるベースラインと比べて追加・削除・変更を返す仕組みだ。ツール定義が後から書き換わる種類のリスクに対する材料になる。

プロバイダとミドルウェア——Grafana Agent Observability まで同梱

providers/配下を実際に列挙すると、5つのディレクトリがある。

同梱プロバイダはanthropic、bedrock、openai、openai-compatible、grafanaの5系統
providers/配下の実ディレクトリ。openai-compatibleはOpenAI互換APIを話すサーバーへ向けられる汎用プロバイダ

grafanaはGrafanaが社内向けに提供するホスト型エンドポイント用と説明されている。外部の一般利用者がそのまま使える種類のものではない点は、ドキュメントの表現(internally provisioned)から読み取れる範囲で理解しておきたい。

横断的な機能はmiddleware/に集約されている。ここにGrafanaらしさが出る。

middleware配下の構成。agentobservability、prometheus、logger、enrichment、simulate_streaming/transform_streamの各機能
middleware/配下のディレクトリとファイルを列挙した結果。Prometheusメトリクスと Agent Observability 連携が最初から同梱される

agentobservability:Grafanaの Agent Observability 連携
prometheus:Prometheusメトリクスの出力
logger:構造化ログ
enrichment:コンテキストの付加
simulate_streaming / transform_stream:ストリーミング非対応のモデルに疑似ストリームを被せる、ストリームを変換する
extract_reasoning / extract_json / add_tool_input_examples:応答からの推論部抽出・JSON抽出・ツール入力例の付加

監視基盤の会社が作ったSDKらしく、メトリクスと可観測性が後付けのプラグインではなく最初から同居している。LLMを本番のサービスに載せるとき、トークン使用量・ステップ数・プロバイダへの試行回数といった「HTTPのリクエスト数だけでは捉えられない仕事量」を測る必要が出てくる。公式のセキュリティ文書もその点を明示していて、1回のユーザーリクエストが複数のプロバイダ呼び出しを引き起こしうるため、それぞれを監視せよと書いている。

同じ文書には運用上の指針が並ぶ。ツールには必要最小限の権限だけを与える、モデルが生成した入力はSQL・シェル・パス・URL・クラウドAPIへ渡す前に検証する、到達できるホストや操作は許可リストで絞る、汎用シェルや無制限のHTTPツールは避ける。そしてクライアントから渡されたモデルIDをそのままプロバイダのコンストラクタへ渡すな——許可したモデル名だけをカタログ経由で解決せよ、という指摘もある。これはコストと能力の予期せぬ変化を抑える意味も持つ。

他のGo向けLLMライブラリとの比較と、alpha段階の判断材料

Goには既にLLM向けのライブラリがある。数値はいずれもGitHub APIで2026年8月2日に取得したものだ。

項目 grafana/ai-sdk tmc/langchaingo cloudwego/eino genkit-ai/genkit vercel/ai
主言語 Go Go Go TypeScript(go/同梱) TypeScript
179 9,578 12,556 6,308 25,944
ライセンス Apache-2.0 MIT Apache-2.0 Apache-2.0 Apache-2.0
リポジトリ作成 2026-07-28 2023-02-18 2024-12-04 2024-04-29 2023-05-23
最終push 2026-07-31 2026-01-11 2026-08-01 2026-08-01 2026-08-01
設計の出発点 AI SDK通信規約への適合 LangChain系の抽象の移植 独自のグラフ指向 複数言語のランタイム 規約そのものの提供元
フロント規約互換 AI SDK Reactと互換を明示 明示なし 明示なし 独自 規約の定義元

読み取れることを列挙する。まず規模の差は大きい。★179という数字は公開5日目のもので、成熟したライブラリと同じ土俵で比べる段階にない。次に、開発の活発さでいえばtmc/langchaingoの最終pushは2026-01-11で、他の3本(eino・genkit・vercel/ai)が2026年8月1日である点は差がある。ただしpush日時の新しさは、依存更新botの活動でも動きうる指標なので、これだけで健全性を断じることはできない。

そして本質的な違いは規模ではなく設計の出発点にある。langchaingoやeinoは、それぞれのフレームワークとしての抽象をGoに持ち込む。Grafana AI SDKは抽象を発明せず、既存のフロントエンド規約を固定点として受け入れ、そこに合わせる。だから「どちらが優れているか」ではなく、フロントエンドが既にAI SDK Reactであるかどうかが選択の分かれ目になる。既にそうなら噛み合わせは良く、そうでないなら互換性という最大の売りが効かない。

Rustで同種の設計判断を見たい場合は、AutoAgents:Rustで構築する複数AI エージェント統合フレームワークがコンパイル言語側からエージェント基盤を組む例として参考になる。エンタープライズ寄りのSDKという観点ではSemantic Kernel入門:Microsoft製AIエージェントフレームワークでエンタープライズ開発を加速が、ベンダーが自社の運用基盤と一体で提供する形という点で近い位置にある。

「互換」がどこまで検証されているか

このSDKで最も特徴的なのは、互換性の主張を検証可能な形に落としているところだ。test/conformance/upstream.yamlには、適合の対象となる上流npmパッケージのバージョンが固定で記録されている。

ai: 7.0.37 / @ai-sdk/react: 4.0.40 / @ai-sdk/provider: 4.0.3
@ai-sdk/anthropic: 4.0.19 / @ai-sdk/openai: 4.0.20 / @ai-sdk/amazon-bedrock: 5.0.30
@ai-sdk/openai-compatible: 3.0.14 / @ai-sdk/gateway: 4.0.28 / @ai-sdk/provider-utils: 5.0.12
・検証日:2026-07-27、verification.statusenforced(強制)

「互換です」と書くだけなら誰でもできるが、どのバージョンに対して・どう検証しているかが機械可読な形で置かれているのは珍しい。加えてtest/interop/にはTypeScript側と突き合わせる相互運用テストが、test/integration/にはSSEワイヤ形式やReactフックを対象にしたテストが置かれている。GitHub APIが示すTypeScript約10万バイトの正体はここだ。

さらに踏み込んでいるのが、同じファイルのknownGapsである。未達を隠さず、IDと理由つきで公開している。

gap ID 対象 内容(要約)
transcription-model-surface プロバイダ契約 上流にある音声書き起こしモデルのAPIは移植対象外
image-model-surface プロバイダ契約 上流の画像モデルAPI・画像オプションは未提供
anthropic-base-url-normalization Anthropicプロバイダ 上流が行うベースURLの/v1補完に相当する設定を持たない
openai-base-url-validation OpenAIプロバイダ 空のベースURLを生成時に弾かず、リクエスト時に失敗する
bedrock-anthropic-invoke-surface Bedrockプロバイダ Converse系のみ実装し、Anthropic Invoke面は未提供

PARITY.mdの冒頭にある一文も引いておく価値がある。これは「網羅の地図であって、完全な互換性の主張ではない」。加えて同文書は、リアルタイム通信(WebSocket)についてはgapと明記している。互換の範囲は言語モデル(LanguageModel)まわりに絞られている、というのが正確な理解になる。

導入を検討するときの現実的な線引き

2026年8月2日時点の成熟度
公開から5日、タグはv0.1.0-alpha.1の1本のみでGitHubのReleasesは0件、humanのコントリビュータは2名(ほかにRenovate bot)。一方でCIは初期の段階で全ジョブがマージゲート化されており、適合テストはenforced、未達はknownGapsとして公開されている。品質の作り込み方は明示的だが、バージョン番号が示す安定性の保証はまだ無い、という状態を切り分けて捉えたい。

判断材料を整理すると、次のようになる。

噛み合う場合:フロントエンドが既にAI SDK Reactで、バックエンドをGoに寄せたい。Prometheus/Grafanaで既に可観測性を組んでいる。承認つきツール実行のように、副作用の制御が要件に入っている
噛み合わない場合:フロントエンドがAI SDK系でない。音声書き起こし・画像生成・リアルタイム通信が必要(いずれも明示的なgap)。破壊的変更を吸収する余力が無い
確認しておくことgo.modが要求する Go 1.26.3 に既存プロジェクトが乗るか。grafanaプロバイダは社内向けエンドポイント用であり、外部利用の前提が異なること

上流に追随する設計は、上流が動けば追随作業が発生するということでもある。upstream.yamlのバージョン固定とmise run parity-checkというコマンドが用意されているのは、その追随を人手の勘ではなく手順にするためだろう。alpha段階のSDKを評価するとき、機能の数よりこうした追随の仕組みが用意されているかを見るほうが、その後の運用コストを予測しやすい。

参照ソース

grafana/ai-sdk(GitHub公式リポジトリ) — README、NOTICEgo.modproviders/middleware/の構成、tool_approval_signature.goおよび同テスト、test/conformance/upstream.yamlPARITY.md。2026-08-02時点のmainを参照
grafana/ai-sdk ドキュメント(docs/)concepts/wire-protocol.md(UI message stream protocol)、guides/tool-approval.md(承認フローと署名)、best-practices/security.md(セキュリティ指針)
vercel/ai — tool-approval-signature.ts — 上流TypeScript実装。ペイロード構築・legacyフォールバックとその改行ガード、canonical-hash.tsの正準JSON規則
Vercel AI SDK 公式ドキュメント — 上流のUI message stream protocol仕様