Googleは先日、フルスタックAIアプリケーションを構築するためのオープンソース基盤「Genkit」向けに、Agents APIのプレビュー版をリリースした。このAPIは、メッセージ履歴、ツール実行ループ、ストリーミング、状態の永続化、およびフロントエンドプロトコルを、単一のchat()インターフェースに統合している。このインターフェースは、エージェントがプロセス内で実行される場合でも、HTTPのエンドポイントの背後で実行される場合も同じように動作可能だ。 プレビュー版は本日よりTypeScriptおよびGoで利用可能、PythonとDartへの対応も予定されている。
設計の原則は、要素を入れ替えずにスケールアップできる単一の抽象化だ。同一エージェントのオブジェクトが、ワンショットの返信、ストリーミングによるマルチターンの会話、人間の承認待ちの一時停止中のツール呼び出し、および分離された長時間実行タスクをすべて処理する。 機能が単純なチャットボットから複数エージェントでのワークフローへと拡大しても、チームは別の基盤の要素へ頼る必要はない。
Genkitは、多くのフレームワークが混同している2種類のエージェントデータを分離する。カスタム状態は、次のターンを駆動する型付きアプリケーションデータであり、ワークフローのステータス、タスク一覧、選択されたエンティティなどが該当する。成果物は、ユーザーが個別に確認、ダウンロード、またはバージョン管理できる生成出力であり、報告書、コードパッチ、旅行の旅程などが該当する。 ツールは稼働中のセッションを通じていずれかを更新し、Genkitは変更が発生すると同時にクライアントへストリーミングする。
状態の永続化には2つの経路がある。セッションストアが設定されている場合、エージェントはサーバーで管理される。メッセージ、カスタム状態、成果物はスナップショットとして永続化され、クライアントはセッションIDによって再接続する。 Genkitには、Firestore(本番環境のマルチインスタンス)、インメモリ(開発用)、ファイル基盤(ローカルテスト)用のストアが同梱されており、カスタム実装のためのプラグイン可能なインターフェースも備えている。ストアがない場合、エージェントはクライアントによって管理される。サーバーは完全な状態を返し、クライアントは各ターンごとにそれを繰り返す。
AIエンジニアのEbenezer Don氏は、このアーキテクチャの選択におけるコンプライアンスの側面を次のように強調した。
AIエージェントにメモリを追加する際、信頼性の高い文脈を維持することが最大の課題です。
クライアント側で管理の状態について、Don氏は、サーバー管理型のアプローチでは提供できないデータ所在地の観点に言及した。
この手法は、一時的なセッションや、サーバーがユーザーデータを永続化してはならないという厳格なデータ所在地の制約があるアプリケーションにとって理想的なものです。その代わり、会話が長くなるにつれてネットワークの送信量が増加してしまいます。
数多くのエージェントフレームワークが存在する中で、2つの機能が際立っている。
「デタッチド・ターン」により、クライアントはエージェントタスクを開始し、接続を切断した後、結果をポーリングできる。さらに、エージェントはサーバー側で処理を継続し、進行状況をスナップショットに書き込む。このスナップショットはどのクライアントからも読み取れる。
const chat = reportAgent.chat({ sessionId: 'report-123' }); const task = await chat.detach('Write the quarterly market report.'); savePendingSnapshot(task.snapshotId); for await (const snapshot of task.poll({ intervalMs: 1000 })) { renderStatus(snapshot.status); if (snapshot.status === 'completed') renderMessages(snapshot.state.messages); } デタッチド実行により、開発者は、長時間の調査タスク、複数手順の計画、ツールを多用する作業流れを、WebSocketや別の仕事キュー、または接続の保持なしに実用的に作成できる。
もう一つの機能である「中断可能なツール」は、偽造防止機能を備えた人間による介入制御を提供する。ツールが中断可能としてマークされると、エージェントは実行途中で一時停止し、保留中のアクションをクライアントに返し、ユーザーが承認または拒否した後にのみ再開する。 ランタイムは、セッション履歴と照合して再開ペイロードを検証し、偽造された入力によってツールが騙されて実行されるのを防ぐ。Go言語では以下である。
runShell := genkitx.DefineInterruptibleTool(g, "run_shell", "Run a shell command after a safety check.", func(ctx context.Context, input ShellInput, confirm *Confirmation) (ShellOutput, error) { if isRisky(input.Command) { if confirm == nil { return ShellOutput{}, tool.Interrupt(ShellInterrupt{ Command: input.Command, Reason: "The command can modify files.", }) } else if !confirm.Approved { return ShellOutput{}, errors.New("user rejected shell command execution") } } return execute(input.Command) }, ) 複数エージェントのオーケストレーションのために、Genkitのミドルウェアシステム(5月にリリース)は、各サブエージェント向けの委任ツールを注入し、オーケーストレーターモデルはリクエストの一部をスペシャリストに振り分けできる。 サブエージェントは、同じ chat() インターフェースを使って、ローカルでも HTTP エンドポイントの背後でも実行できる。また、ミドルウェア層は、指数関数的バックオフを伴う再試行、プロバイダー間のモデル代替、ツールの承認ゲート、 SKILL.md ファイルをシステムプロンプトに読み込むスキルシステムのための、合成可能なフックも提供する。
Genkitは、プラグイン構造によりモデル非依存である。公式プラグインはGoogle AI(Gemini)、Vertex AI、Anthropic、OpenAI、Ollama向けが存在する。Vercel AI SDKアダプターを使用すれば、チームはGenkitエージェントをNext.jsアプリケーションに統合できる。 各エージェントはすでにServableアクションとして実装されており、ルートヘルパーを使えば、わずか数行のコードで標準的なHTTPマルチプレクサ上にturn、snapshot、abortの各エンドポイントに接続できる。
競合環境は激戦区だ。LangChain、CrewAI、Semantic Kernel、Autogen、Mastra、Pydantic AIはいずれも、重複する課題に取り組んでいる。 Google自身も、2つのレイヤーで同時にエージェント用の基盤を構築している。1つはセルフホスト型エージェントアプリ向けのGenkit、もう1つはGoogleがホストするランタイムで、バックグラウンド実行、リモートMCPサーバー、サンドボックス化されたコード実行がすべてサーバーサイドで処理されるGemini API内のManaged Agentsである。 より広い視点で見ると、Genkitの差別化はフルスタックな手法にある。サーバー側のエージェントロジック、Webとモバイル向けの型付きクライアントSDK、組み込みのストリーミングプロトコル、そしてFirebaseやCloud Run、あるいはNode.jsやGoが動作するあらゆる環境への配備が可能だ。 その反面、GenkitはLangChainに比べて歴史が浅く、コミュニティの連携の仕組みが小さいことである。
Agents APIはプレビュー版だ。ミドルウェアシステムはTypeScript、Go、Dartで一般提供(GA)されている。GenkitはGitHub上でApache 2.0ライセンスのもとオープンソースとして公開されている。