Vercel AI SDK v6(AI SDK 6)は2025年12月22日に正式版になった版で、ツールを呼びながら答えを出すエージェント用の ToolLoopAgent と、ツール実行の前に人の承認を挟む needsApproval が加わりました。2026年6月25日にAI SDK 7が出たため、いま npm install ai で入るのはv7です。最新版(AI SDK 7)での書き方はVercel AI SDKの使い方|AI SDK 7でNext.jsチャットとLangChain連携を実装にまとめています。
この記事はv6を使っている、またはv6のコードを読む必要がある人向けです。v6系の現行パッチ6.0.320(2026年10月30日公開)を入れ、コード例はTypeScript 7.0.2で型検査し、ToolLoopAgentと承認の流れはAPIキー不要のモックモデル(MockLanguageModelV3)で実行して出力を確かめました。
まとめ|v6を使うときに押さえる要点
- v6はメンテナンス中の旧メジャー。6.0.0のGAは2025-12-22、v7.0.0は2026-06-25。v6系にもパッチが出続けており、6.0.320が2026-10-30に公開されている。
- v6に留めるなら
npm install ai@ai-v6 @ai-sdk/react@ai-v6 @ai-sdk/openai@ai-v6のように全パッケージをdist-tagで揃える。ai@6だけ固定して@ai-sdk/reactをタグ無しで入れると、v7の[email protected]が別に入って2つの版が混在する。 ToolLoopAgentの停止条件の既定はstepCountIs(20)。一方generateTextは既定1ステップで、最初の応答がツール呼び出しだけならtextは空になる。- 実行時の引数は
callOptionsSchema+prepareCall。日本語記事に出てくるprepareCallsは存在せず、型検査で TS2561 になる。 - 承認をクライアントから受け取る構成では
experimental_toolApprovalSecretを設定する。設定しないと、偽造した承認メッセージでツールが実行される(6.0.320で実測)。
AI SDK 6の位置づけとサポート状況
リリース日とv5・v7との関係
npmレジストリの公開日時で見ると、5.0.0が2025-07-31、6.0.0が2025-12-22、7.0.0が2026-06-25です。v6がメジャー版になった理由について、公式のAI SDK 6 Betaの告知は、プロバイダとの接続仕様をv3 Language Model Specificationへ上げたためと説明しています。正式版のリリースブログも「AI SDK 5と違い、多くの利用者にとって大きな破壊的変更は想定していない」としており、v5からの移行はv4→v5ほど重くありません。
| メジャー版 | x.0.0の公開日 | 2026-10-31時点の最終版 | npmのdist-tag | Node.js要件 |
|---|---|---|---|---|
| AI SDK 5 | 2025-07-31 | 5.0.283 | ai-v5 |
18以上 |
| AI SDK 6 | 2025-12-22 | 6.0.320 | ai-v6 |
18以上 |
| AI SDK 7 | 2026-06-25 | 7.0.159 | latest |
22以上(ESM専用) |
v6で追加された機能の一覧
リリースブログの章立てから、v6で入った機能を整理すると次のとおりです。安定性の列は、名前に experimental_ が付くか、ドキュメントにexperimentalの注記があるかで判定しています。
| 機能 | 主なAPI・パッケージ | 安定性 |
|---|---|---|
| エージェント | ToolLoopAgent・Agentインターフェース |
安定 |
| 実行時の引数 | callOptionsSchema・prepareCall |
安定 |
| ツール実行の承認 | needsApproval |
安定 |
| 承認の署名検証 | experimental_toolApprovalSecret |
experimental |
| ツール併用の構造化出力 | Output.object など |
安定 |
| MCPクライアント | @ai-sdk/mcp の createMCPClient |
安定 |
| DevTools | @ai-sdk/devtools |
experimental |
| リランキング | rerank |
安定 |
| 画像編集 | generateImage の参照画像 |
安定 |
| LangChain連携 | @ai-sdk/langchain(作り直し) |
安定 |
ツール定義では、厳密なスキーマ検証をツールごとに有効にする strict と、入力例を渡す inputExamples(ネイティブ対応はAnthropicのみ)が入りました。モデルへ返す内容をツールの戻り値と分ける toModelOutput はv5からありますが、v6では引数が { output } のオブジェクトに変わりました。
v6のインストールとバージョン固定
dist-tag ai-v6による関連パッケージの統一
AI SDKは本体の ai と、UIフック・プロバイダ・DevToolsなどが別パッケージです。v6に留めるときは、すべてを ai-v6 タグで指定します。
npm install --save-exact ai@ai-v6 @ai-sdk/react@ai-v6 @ai-sdk/openai@ai-v6 zod
空のプロジェクトで npm install ai@6 @ai-sdk/react react@19 と、本体だけ版を指定して試すと、npm ls ai の結果は次のようになりました。@ai-sdk/react のタグ無しは4.0.163(v7用)で、依存として [email protected] を持ち込みます。
+-- @ai-sdk/[email protected]
| `-- [email protected]
`-- [email protected]
この状態ではサーバー側はv6、useChat 側はv7の型とストリーム形式で動きます。ai-v6 タグで揃えた場合は @ai-sdk/[email protected] と @ai-sdk/[email protected] が入り、[email protected] は1つにまとまりました(deduped)。
移行ガイドのai@latestに注意
v6同梱の移行ガイド(v5→v6)は、更新コマンドの例として pnpm install ai@latest @ai-sdk/react@latest @ai-sdk/openai@latest を載せています。v6公開時はこれでv6が入りましたが、2026年6月25日以降はv7が入ります。v5からv6へ上げる途中でこのコマンドを写すと、v6を飛ばしてv7になります。codemodも同様に、v5→v6だけを当てたいときは npx @ai-sdk/codemod v6 を使います(upgrade はv4以降の全codemodを当てます)。
ToolLoopAgentによるツール呼び出しループの実装
ToolLoopAgent は、モデル・指示・ツールを一度設定し、モデルの応答にツール呼び出しがある限り「ツール実行→結果をモデルへ返す」を繰り返すクラスです。v5の Experimental_Agent の後継で、v6.0.320でも互換のため Experimental_Agent はexportされています。
import { ToolLoopAgent, tool, stepCountIs } from 'ai';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod';
const weather = tool({
description: '都市の気温を返す',
inputSchema: z.object({ city: z.string() }),
execute: async ({ city }) => ({ city, tempC: 21 }), // 動作説明用の固定値。実際の気温は取得しない
});
export const weatherAgent = new ToolLoopAgent({
model: openai('gpt-5.6'),
instructions: '気温を調べてから日本語で答える',
tools: { weather },
stopWhen: stepCountIs(5),
});
const result = await weatherAgent.generate({ prompt: '東京の気温は?' });
console.log(result.text, result.steps.length);
モックモデルで「1回目はツール呼び出し、2回目は文章」を返すようにして実行すると、エージェントは2ステップで「東京は21度です」を返しました。同じモデルとツールを stopWhen 無しの generateText に渡すと1ステップで止まり、text は空文字でした。停止条件の既定値は、ToolLoopAgent が stepCountIs(20)、generateText・streamText が1ステップです。v6のツール解説ページには stepCountIs(count) の説明に「default: stepCountIs(20)」と書かれていますが、これはエージェントの既定値で、generateText には当てはまりません。
callOptionsSchemaとprepareCallによる呼び出し単位の指示変更
ユーザー名や契約プランなど、呼び出しのたびに変わる値は callOptionsSchema で型を決め、prepareCall で指示やモデル設定に反映します。
const supportAgent = new ToolLoopAgent({
model: openai('gpt-5.6'),
callOptionsSchema: z.object({
userName: z.string(),
plan: z.enum(['free', 'pro']),
}),
prepareCall: ({ options, ...rest }) => ({
...rest,
instructions: `${options.userName}さん(${options.plan}プラン)に回答する`,
}),
});
await supportAgent.generate({
prompt: '請求書の再発行方法は?',
options: { userName: '佐藤', plan: 'pro' },
});
プロパティ名は単数形の prepareCall です。v6リリース直後の日本語解説には prepareCalls と書いたものがあり、そのまま写すと error TS2561: ... 'prepareCalls' does not exist in type 'ToolLoopAgentSettings<...>'. Did you mean to write 'prepareCall'? になります。
また6.0.171(2026-04-30)より前は、callOptionsSchema が型だけで実行時には検証されていませんでした(CHANGELOGの「enforce callOptionsSchema at runtime」)。6.0.320で plan: 'enterprise' を渡すと AI_TypeValidationError で止まり、モデルは呼ばれません。スキーマで入力を制限している前提のコードなら、6.0.171以上に上げてください。
Output.objectによるツール結果の構造化出力
v5までは、ツールを使うループは generateText、型付きのJSONを返す専用APIは generateObject でしたが、generateText にも実験的な experimental_output がありました。v6では generateText に output を渡すと、ツールを呼んだ後の最終応答をスキーマで検証して受け取れます。generateObject・streamObject はv6で非推奨になりました。
import { generateText, Output, stepCountIs } from 'ai';
const { output } = await generateText({
model: openai('gpt-5.6'),
tools: { weather },
stopWhen: stepCountIs(5),
output: Output.object({
schema: z.object({ city: z.string(), tempC: z.number(), advice: z.string() }),
}),
prompt: '大阪の気温と服装のアドバイス',
});
console.log(output.advice);
モックでは、1ステップ目でツール呼び出し、2ステップ目でJSON文字列を返すと、output に {"city":"大阪","tempC":21,"advice":"上着不要"} が入りました。ツール実行後、その結果をモデルに渡して最終応答を生成するには、stopWhen で2ステップ以上を許す必要があります。
needsApprovalによるツール実行前の承認制御
ファイル削除・送金・データ更新のように、モデルの判断だけで実行させたくないツールには needsApproval: true を付けます。承認待ちでも処理は一時停止せず、いったん結果を返します。アプリ側で承認を集め、2回目の呼び出しで実行させる2段構えです。以下は承認応答の形式を示すデモで、approved を true に固定しています。人の承認を待つ処理は含まず、削除処理も戻り値だけのダミーです。実装時は承認画面で受け取った判断を approved に設定してから再開します。
import { ToolLoopAgent, tool, type ModelMessage, type ToolApprovalResponse } from 'ai';
const deleteFile = tool({
description: 'ファイルを削除する',
inputSchema: z.object({ path: z.string() }),
needsApproval: true,
execute: async ({ path }) => ({ deleted: path }),
});
const fileAgent = new ToolLoopAgent({
model: openai('gpt-5.6'),
tools: { deleteFile },
experimental_toolApprovalSecret: (() => {
const secret = process.env.TOOL_APPROVAL_SECRET;
if (!secret) throw new Error('TOOL_APPROVAL_SECRET is required');
return secret;
})(),
});
const messages: ModelMessage[] = [{ role: 'user', content: 'a.txtを削除して' }];
const first = await fileAgent.generate({ messages });
messages.push(...first.response.messages);
const approvals: ToolApprovalResponse[] = [];
for (const part of first.content) {
if (part.type === 'tool-approval-request') {
console.log(part.toolCall.toolName, part.toolCall.input); // 承認画面に出す
approvals.push({ type: 'tool-approval-response', approvalId: part.approvalId, approved: true });
}
}
messages.push({ role: 'tool', content: approvals });
const second = await fileAgent.generate({ messages });
console.log(second.text);
モックで実行すると、1回目の content は ["tool-call","tool-approval-request"]、finishReason は tool-calls で、ツールはまだ動いていません。承認して2回目を呼ぶとツールが実行され、モデルに {"deleted":"/tmp/a.txt"} が渡りました。approved: false と reason: '本番データのため' を返すと、モデルには execution-denied と理由が渡ります。useChat を使う画面では、addToolApprovalResponse で同じ応答を返します。承認を業務フローにどう組み込むかはヒューマンインザループ(HITL)とは?意味・HOTLとの違い・承認の実装と導入判断で扱っています。
送金額に応じた承認要否の切り替え
needsApproval には関数も渡せます。入力を見て承認が要るときだけ true を返します。
const payment = tool({
description: '送金する',
inputSchema: z.object({ amount: z.number(), to: z.string() }),
needsApproval: async ({ amount }) => amount > 1000,
execute: async ({ amount, to }) => ({ ok: true, amount, to }),
});
モックで amount: 500 の呼び出しはそのまま実行されて2ステップで完了し、amount: 5000 は承認要求を返して1ステップで止まりました。拒否されたツールをモデルが繰り返し呼ぶことがあるため、公式ドキュメントは「承認されなかったツールは再試行しない」旨を指示に入れるよう勧めています。
experimental_toolApprovalSecretによる承認要求の署名検証
useChat の構成では、会話履歴(承認の応答を含む)をクライアントが送り返し、サーバーはそれを messages として渡します。つまり承認の記録はクライアントが書き換えられます。v6.0.320で、ツール呼び出し・承認要求・承認応答を自作したメッセージ(パスは /etc/important)を渡す実験をしました。
| 設定 | 結果 |
|---|---|
| シークレット未設定 | ツールが /etc/important で実行された |
experimental_toolApprovalSecret 設定 |
AI_InvalidToolApprovalSignatureError(missing signature)で拒否 |
| 設定+正規の承認 | 実行された(承認要求に signature が付く) |
6.0.202(2026-06-11)のCHANGELOGには「fix(security): re-validate tool approvals from client message history before execution」とあり、以降は承認の再生時に入力のスキーマ検証と承認要否の再判定が入りました。ただしスキーマに合う偽の入力は通るため、署名で縛らない限り防げません。v6のツール解説も、危険な操作をするツールにはシークレットを設定し、承認を受け付ける全サーバーで同じ値を使うよう求めています。名前に experimental_ が付くので、使う場合はバージョンを範囲指定(^)でなく完全一致で固定します。
DevTools・MCPをv6で使うときの版
AI SDK DevToolsによるステップと入出力の確認
DevToolsは、モデルをミドルウェアで包んで呼び出しを記録し、ローカルのビューアで各ステップの入力・出力・ツール呼び出しを見る仕組みです。v6同梱のドキュメントは「experimentalで、ローカル開発専用。本番環境では使わない」と注記しています。
npm install -D @ai-sdk/devtools@ai-v6
import { wrapLanguageModel } from 'ai';
import { devToolsMiddleware } from '@ai-sdk/devtools';
const model = wrapLanguageModel({
model: openai('gpt-5.6'),
middleware: devToolsMiddleware(),
});
ビューアは、上記のインストールを行ったプロジェクト内で npx @ai-sdk/[email protected] を実行して起動し、http://localhost:4983 で開きます。v6用は ai-v6 タグの0.0.29です。タグ無しの1.0.62は依存に [email protected] を持ち、Node.js 22以上を要求するため、v6のプロジェクトに入れると先ほどと同じ混在が起きます。
MCPクライアントの提供パッケージとv6対応版
v6でMCPクライアントは @ai-sdk/mcp パッケージの createMCPClient になり、HTTPトランスポート、OAuth認証、リソース・プロンプトの取得、サーバーからの入力要求(elicitation)に対応しました。v6用の版は ai-v6 タグの1.0.100で、タグ無しは2.0.88(Node.js 22以上)です。TypeScriptでMCPサーバーを自作する側の注意点はMCP TypeScript SDKの脆弱性:2026年10月の7件の対象版と更新後に要る設定変更を参照してください。
v6のパッチで変わった挙動
v6系は「6.0.x」のまま300回以上パッチが出ており、その中で既定の挙動が変わったものがあります。^6.0.0 で指定していても、lockファイルが古ければ修正前の版で動いています。npm ls ai で実際の版を確認し、下の修正を含む6.0.203以上(できれば6.0.x の最終版)へ上げてください。
| 版(公開日) | 変更 |
|---|---|
| 6.0.170(2026-04-29) | messages内のsystemメッセージに警告 |
| 6.0.171(2026-04-30) | callOptionsSchema を実行時に検証 |
| 6.0.188(2026-05-21) | ToolLoopAgent に allowSystemInMessages |
| 6.0.202(2026-06-11) | 承認の再生時に入力と承認要否を再検証 |
| 6.0.203(2026-06-12) | UIストリームのエラー詳細を既定で秘匿 |
| 6.0.203(2026-06-12) | ダウンロード時のSSRF対策を強化 |
6.0.203のエラー秘匿は、toUIMessageStream() の onError を省略したとき、それまでサーバー例外の文字列(内部ホスト名やパスを含みうる)をそのままクライアントへ流していた問題の修正です。以後は「An error occurred.」だけが送られます。画面に個別のエラー案内が必要な場合は、onError で公開してよい文言だけを返し、内部ホスト名・パス・例外の詳細はサーバーログに残します。
systemメッセージの扱いは版で異なります。6.0.320で messages に role: 'system' を入れると、generateText も ToolLoopAgent も処理は続き、「プロンプトインジェクションの危険がある」という警告が出るだけでした。v7では同じ入力が AI_InvalidPromptError で止まります。v6のうちに、システムプロンプトを system(エージェントでは instructions)へ移しておくと、v7へ上げたときに止まりません。
v7への移行判断と主な差分
v7で名前が変わるAPI
v7の移行ガイドに載っている変更のうち、v6のコードで出番が多いものを抜き出しました。多くは改称で、npx @ai-sdk/codemod v7 がまとめて書き換えます。
| v6の書き方 | v7の書き方 | v7での扱い |
|---|---|---|
stepCountIs(n) |
isStepCount(n) |
旧名は別名で残る |
system |
instructions |
旧名は非推奨 |
onFinish・onStepFinish |
onEnd・onStepEnd |
codemodで改称 |
experimental_telemetry |
telemetry |
codemodで改称 |
result.fullStream |
result.stream |
codemodで改称 |
ツールの needsApproval |
呼び出し側の toolApproval |
非推奨 |
result.toUIMessageStreamResponse() |
createUIMessageStreamResponse |
非推奨 |
| messages内のsystem | 同じ | 警告からエラーへ |
| Node.js 18以上・CJS可 | Node.js 22以上・ESM専用 | 要件変更 |
v7の型定義では、ツール定義の needsApproval に「Tool approval is handled on a generateText / streamText level now」という@deprecatedの注記が付いています。承認の設計はツール単位から呼び出し単位へ移るため、承認画面を作り込んだアプリほど移行の手間がかかります。v7での具体的な書き方はVercel AI SDKの使い方|AI SDK 7でNext.jsチャットとLangChain連携を実装に載せています。
v6に留める場面と移行する場面
新規開発はv7で始めてください。v6で書く場合は、将来の移行で承認・終了コールバック・システムプロンプトに使うAPIを見直す必要があります。ただし、v7でも非推奨の互換APIとして残るものがあり、すべての即時書き換えが必須ではありません。
既存のv6アプリは、Node.js 22以上とESMの要件を満たし、必要なv7機能や移行後の保守負担を評価できた段階で移行します。逆に、Node.js 20以下のサーバーで動いている、CommonJSの require('ai') が残っている、needsApproval を前提にした承認画面がある、のどれかに当てはまるなら、まずv6系の最終パッチへ上げて ai-v6 タグで固定し、ランタイムとモジュール形式を先に整えるほうが安全です。v6系にもパッチは出続けています。移行の優先度は、利用中の版に影響する脆弱性とv6への修正提供状況を確認したうえで、v7固有の機能が必要かどうかも含めて判断します。エージェントの設計から相談したい場合は、弊社のAIエージェント開発でも承っています。
よくある質問
Vercel AI SDK v6はいつリリースされましたか?
6.0.0は2025年12月22日にnpmで公開されました。2026年6月25日にv7.0.0が出たため最新版ではありませんが、v6系のパッチは続いており、2026年10月30日に6.0.320が公開されています。
ToolLoopAgentとExperimental_Agentの違いは何ですか?
ToolLoopAgent はv5の Experimental_Agent を正式化したクラスで、指示は instructions、停止条件の既定は stepCountIs(20) です。6.0.320でも Experimental_Agent は互換のためexportされていますが、新しく書くコードでは ToolLoopAgent を使います。
prepareCallsというAPIはありますか?
ありません。正しくは callOptionsSchema と prepareCall(単数形)の組み合わせです。prepareCalls と書くとTypeScriptが TS2561 を出し、型検査をしないJavaScriptでは設定が無視されます。
AI SDK DevToolsは本番環境で使えますか?
使えません。公式ドキュメントがexperimentalかつローカル開発専用と明記しています。v6で使うときは @ai-sdk/devtools@ai-v6(0.0.29)を開発依存に入れ、本番のビルドではミドルウェアを外します。
v6からv7へはどう移行しますか?
Node.js 22以上とESMの環境を用意し、npx @ai-sdk/codemod v7 で改称をまとめて当てます。codemodで直らないのは承認(needsApproval から toolApproval へ)とレスポンス生成(createUIMessageStreamResponse へ)の書き換えで、これは手で直します。