AIエージェント・MCP

Vercel AI SDK v6の新機能|ToolLoopAgent・needsApprovalの使い方とv7への移行【6.0.320対応】

Vercel AI SDK v6の新機能|ToolLoopAgent・needsApprovalの使い方とv7への移行【6.0.320対応】

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 へ)の書き換えで、これは手で直します。

関連記事

お気に入りに入れた記事の一覧

一創の公式 SNS

X では毎朝の新着記事と IT ニュースの速報を、YouTube・TikTok・Instagram・LinkedIn・Facebook では記事の解説動画を配信しています。

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.10.29 テックブログ ソニー生命の情報漏洩38.5万件|ログインできない理由、再開状況と窓口の電話番号
  2. 2026.10.31 テックブログ 松屋の不正アクセス:237万件の対象確認と窓口、漏れたパスワードの守り方
  3. 2026.11.01 コラム インボイスの経過措置とは?70%控除の期間と計算方法・帳簿の書き方・1億円制限【2026年10月改正対応】
  4. 2026.03.17 コラム 所得金額調整控除とは?年収850万円超で最大15万円、対象者と計算式・申告書の書き方【令和8年分】
  5. 2026.11.02 テックブログ pgAdminの脆弱性:9.19で直った15件のCVEと更新前に要るサーバーモードの設定

RELATED POSTS 関連記事

目次