本文へ移動
AI Dev Lab Japan AI開発ツール、AIコーディングエージェント、M...

Vercel AI SDKのtool approval設計:needsApproval・toolApproval・WorkflowAgentの使い分け

Vercel AI SDKのtool approval設計:needsApproval・toolApproval・WorkflowAgentの使い分けの要点をタイトルと確認軸で示すアイキャッチ

3行まとめ

このテーマをもう少し広げて見るなら、OpenAI Agents SDKのtool guardrailsを実務に入れる前に:handoff・built-in tools・人間承認の分け方MCP ElicitationをAIエージェントに入れる前に:form・URL・OAuth・人間承認の分け方 も合わせて確認してください。Vercel AI SDKのtool approvalと、OpenAI Agents SDK側のtool guardrailsやhandoff設計を比較できる。

Visualapprovalの3経路短時間、UI、長時間停止を分けます。
Core

generateText/streamTextは2回呼び出し前提。

Chat UI

approval stateをUIで扱います。

Workflow

長時間停止と再開はWorkflowAgentへ。

承認はボタンを出すだけでなく、どこで状態を保持するかまで決めます。

  • Vercel AI SDKのtool approvalは、短時間のgenerateText/streamText、chat UI上の承認、長時間停止できるWorkflowAgentで分けて設計します。
  • needsApprovalを付けたtoolは、Coreでは承認要求を返して一度止まり、approval responseをmessagesへ追加して2回目のmodel callで続行する前提です。
  • 承認まで数時間空く、retryや画面更新をまたぐ、step単位で観測したい場合は、in-memoryのToolLoopAgentではなくWorkflowAgentへ寄せます。

本文の事実確認には、AI SDK公式Docs、Vercel Knowledge BaseのWorkflowAgent記事、VercelのChat SDK/Workflow SDK human-in-the-loop記事、OpenAI Agents SDKのhuman-in-the-loop Docsを使っています。Xで見かけるhuman-in-the-loopやtool approvalへの投稿は需要シグナルとして扱い、本文の根拠にはしていません。

この記事でわかること

Visual読後に決める項目AI SDK導入前に分ける判断です。
対象tool

どの操作に承認を付けるか。

呼び出し

2回目のmodel callを組みます。

UI

approve/deny後の続行を扱います。

Durability

長時間承認ならworkflowへ寄せます。

tool approvalはUX、状態管理、監査をまとめて扱います。

  • needsApprovalを付けるべきtoolの条件
  • generateText/streamTextでapprovalが2回呼び出しになる理由
  • useChatでapproval UIを扱うときのstate
  • ToolLoopAgentを短いagent loopとして使うときの注意
  • WorkflowAgentへ寄せるべき長時間承認の条件
  • subagent toolsでneedsApprovalを使えない制限

AI agentのtool approvalは、単に「危ない操作の前にボタンを出す」だけでは足りません。承認者が何を見て判断するのか、否認されたらどう会話を続けるのか、承認待ちの状態をどこに保存するのかまで決めます。

この記事では、Vercel AI SDKで承認付きtool callingを作るときの置き場所を、実務の運用単位で分けます。

前提知識

Visual公式情報で見る対象この記事で扱うAI SDK機能です。
項目内容見方
needsApprovaltool実行前に承認を要求します。
toolApprovalCore/agent側の承認経路です。
ToolLoopAgentin-memoryのagent loopです。
WorkflowAgentworkflow runtimeで再開できます。

同じ承認でも、保持する状態と再開方法が違います。

AI SDKのtool referenceでは、tool()needsApprovalはbooleanまたはtool argumentsを受け取る関数として指定でき、tool実行前にuser approvalが必要かを表すと説明されています。

AI SDK Coreのtool calling Docsでは、needsApproval: trueのtoolは、generateTextstreamTextで自動実行されず、approval requestを返す流れが説明されています。approval responseをmessagesへ追加して、もう一度generateTextを呼び出すと、承認ならtoolが実行され、否認ならmodelへ否認が伝わります。

VercelのWorkflowAgent記事では、ToolLoopAgentはin-memoryで、process crash、function timeout、refreshで進行状態を失う一方、WorkflowAgentはWorkflow SDK runtime上でstatefulness、resumability、human-in-the-loop、observabilityを補うと説明されています。

この記事の扱う範囲

領域役割
needsApprovaltool実行前に承認を要求する
Core approvalgenerateText/streamTextで2回呼び出しを組む
useChatUI stateとして承認/否認を扱う
ToolLoopAgent短いin-memory agent loop
WorkflowAgent長時間停止、retry、再開、観測を扱う
subagentcontext分離とapproval制限を確認する

条件

2026年5月31日時点で公開されているAI SDK/Vercel公式情報を確認しています。AI SDKはversionごとの変更が起きやすいため、実装時には利用version、Next.js/Vercel runtime、Chat SDK/Workflow SDKの組み合わせを確認してください。

注意点

承認は安全性を上げますが、承認者が入力、対象、影響、rollback可否を読めなければレビューになりません。承認UIには「何を実行するか」を必ず出します。

approvalを3つの経路に分ける

Visual使い分け早見表承認の持ち方で分けます。
項目内容見方
Core短時間の2回呼び出しで承認します。
Chat UImessage partのstateを画面で扱います。
ToolLoopAgent短いagent loop向けです。
WorkflowAgent長時間停止、retry、再開向けです。

人がすぐ押す承認と、数時間後に戻る承認は分けて扱います。

tool approvalは、3つの経路に分けます。

経路向く場面状態の持ち方
Core generateText/streamText短い承認、1画面で完結messagesへapproval responseを追加
Chat UI useChatユーザーが画面でapprove/denyするchatmessage part stateとUI
WorkflowAgent数分から数日待つ承認、retry、resumeWorkflow SDK runtime

短時間ならCoreでよい

たとえば「このメールを送信してよいか」「このコマンドを実行してよいか」を同じ画面で確認するなら、Coreのapproval flowで十分なことがあります。

chat体験ならUI stateを中心にする

チャット画面で承認するなら、承認要求、承認済み、否認、tool結果、tool失敗を見せます。承認ボタンだけを出して、否認後のmodel応答を設計しないと、会話が不自然になります。

長時間ならWorkflowAgentへ寄せる

承認まで時間が空く、function timeoutをまたぐ、画面更新やdeployをまたぐ、toolごとにretryしたいなら、WorkflowAgentへ寄せます。

判断基準

「承認待ちの状態をメモリに置いて失ってもよいか」で分けます。失ってはいけないならworkflow runtimeへ寄せます。

needsApprovalで止める操作

Visual承認を付けるtoolユーザーが実行内容を確認すべき操作です。
Payment

課金、返金、購入。

Mutation

DB更新、削除、外部API変更。

Message

メール、Slack、通知送信。

Private

非公開データや社内情報へのアクセス。

承認対象は、失敗時に取り消しにくい操作から選びます。

needsApprovalは、tool実行前にユーザーの明示判断を入れたい操作に付けます。

承認を付けるtool

操作
金銭購入、返金、課金、送金
データ変更DB更新、削除、外部API mutation
外部送信メール、Slack、通知、SNS投稿
コマンド実行shell、deploy、file write
非公開情報private data取得、社内ログ参照
権限変更invite、role変更、API key発行

AI SDK Docsでも、sensitive operationsとしてpayment、deletion、external API callsなどにtool execution approvalを使う説明があります。

動的approvalを使う

AI SDKのtool referenceでは、needsApprovalに関数を渡せるため、tool inputに応じて承認要否を変えられます。

import { tool } from "ai";
import { z } from "zod";

export const processRefund = tool({
  description: "Process a refund after user approval",
  inputSchema: z.object({
    orderId: z.string(),
    amount: z.number(),
    reason: z.string(),
  }),
  needsApproval: async ({ amount }) => amount > 1000,
  execute: async ({ orderId, amount, reason }) => {
    return { orderId, amount, reason, status: "refunded" };
  },
});

この例では、高額返金だけ承認にします。すべてのtoolに承認を付けるとUXが壊れるので、取り消しにくい操作から選びます。

承認UIに出す情報

承認者には、最低限次の情報を出します。

  • tool名
  • 実行対象
  • 入力値
  • 影響範囲
  • 取り消し可否
  • 実行者
  • 否認した場合の次の挙動

ただの確認ボタンにしない

「AIがtoolを使おうとしています。承認しますか」だけでは弱いです。何が変わるのか、誰に影響するのか、戻せるのかを表示します。

generateTextとstreamTextの2回呼び出し

VisualCore approval flow承認後にもう一度modelへ渡します。
  1. 11st call

    tool approval requestが返ります。

  2. 2Review

    ユーザーが内容を確認します。

  3. 3Message

    approval responseをmessagesへ追加。

  4. 42nd call

    承認ならtool実行、否認なら説明へ。

Coreでは承認要求を返して終わり、続行はアプリ側が組み立てます。

AI SDK Coreのtool calling Docsでは、generateTextstreamTextはapprovalが必要なtoolをその場でpauseするのではなく、approval requestを返して完了すると説明されています。続行するにはapproval responseをmessagesへ追加し、もう一度model callを行います。

基本フロー

  1. needsApproval: trueのtoolを含めてgenerateTextを呼ぶ
  2. modelがtool callを生成する
  3. result contentにapproval requestが返る
  4. アプリがユーザーへ承認を求める
  5. approval responseをmessagesへ追加する
  6. もう一度generateTextを呼ぶ
  7. 承認ならtoolが実行され、否認ならmodelが否認を受け取る

否認後の再試行を止める

AI SDK Docsでは、tool executionがdeniedされたときに、同じtoolを再試行しないようsystem instructionを検討する説明があります。これは実務でかなり大事です。

const system = `
When a tool execution is not approved, do not retry the same tool call.
Explain what was not done and ask the user for a safer next step.
`;

否認されたのにmodelが少し引数を変えて再度tool callする、という体験は避けます。

streamTextでも設計は同じ

streamingだから承認が自動的に安全になるわけではありません。approval requestを受け取り、UIで確認し、approval responseをmessage historyへ入れ、続きのcallを走らせます。

実務例

「このSlack通知を送って」と言われたら、1回目のcallでsendSlackMessageのapproval requestを返します。UIで送信先、本文、影響を表示し、承認されたら2回目のcallで実行します。

useChatでapproval UIを扱う

VisualUI stateの見方画面で扱うtool stateです。
項目内容見方
input-availabletool入力が確定した状態。
approval-requested承認待ちを表示します。
approval-respondedユーザー判断が入った状態。
output-denied否認時の表示も用意します。

承認UIは、承認ボタンだけでなく否認後の会話も設計します。

AI SDK UIのChatbot Tool Usage Docsでは、tool execution approvalはserver-side toolの実行前にユーザー確認を入れる用途として説明されています。needsApprovalをtoolに設定し、UIではapproval stateを見てボタンを出します。

UI stateの例

state画面でやること
input-streaming入力生成中として表示
input-availabletool入力を表示
approval-requestedapprove/denyボタンを表示
approval-responded判断済みとして表示
output-availabletool結果を表示
output-denied否認されたことを表示
output-error実行失敗を表示

approve/deny後の続行

Chat UIでは、addToolApprovalResponseでapproval responseを追加し、承認後に自動続行する条件を作る流れが紹介されています。

承認後だけでなく、否認後の会話も用意します。否認されたら、「実行しませんでした。必要なら条件を変えて再依頼してください」と返す方が自然です。

表示すべき情報

承認カードには、tool nameよりユーザーが理解できるtitleを出します。たとえばsend_emailではなく「メールを送信」、delete_recordではなく「顧客レコードを削除」です。

UIで避けること

  • 入力JSONだけを出す
  • 送信先や金額を省く
  • denyボタンを目立たなくする
  • 否認後に同じtoolをすぐ再提案する
  • 誰が承認したか残さない

ToolLoopAgentで使うときの注意

Visual短いagent loop向けin-memory前提で扱います。
Loop

tool結果を使って次stepへ進みます。

Stop

stopWhenで上限を決めます。

Approval

短時間の承認に向きます。

Timeout

長時間停止はWorkflowAgentを検討。

ToolLoopAgentは便利ですが、長時間承認を永続化する層ではありません。

AI SDK Agents overviewでは、agentはLLM、tools、loopで構成され、ToolLoopAgentがcontext managementとstopping conditionsを扱うと説明されています。ToolLoopAgent referenceでは、tool resultを集め、completionまたはuser approvalが必要になるまでloopできる説明があります。

ToolLoopAgentに向く場面

向く場面理由
短いmulti-stepmemory上で完結しやすい
すぐ承認される操作approval待ちが短い
UI session内の作業画面が残っている
retryを自前で扱うworkflow化するほどではない

stopWhenを決める

AI SDKのstepCountIs()は、generateTextstreamTextstopWhenでtool-calling loopを止める条件として使える説明があります。ToolLoopAgentでも、loopが伸びすぎないようstop conditionを決めます。

import { ToolLoopAgent, stepCountIs } from "ai";

const agent = new ToolLoopAgent({
  model,
  instructions: "Use tools only when needed. Ask before sensitive actions.",
  tools,
  stopWhen: stepCountIs(6),
});

長時間承認には弱い

VercelのWorkflowAgent記事では、standard ToolLoopAgentはin-memoryで、process crash、function timeout、user refreshにより進行状態を失うと説明されています。

だから、ToolLoopAgentは「短く終わるloop」に使います。承認まで何時間も待つ業務フローは、WorkflowAgentの方が自然です。

実務例

「検索して候補を3つ出し、選ばれた候補で下書きメールを作る」程度ならToolLoopAgentでよいです。「承認者が翌日に確認して、その後deployする」ならWorkflowAgentへ寄せます。

WorkflowAgentへ寄せる条件

VisualWorkflowAgentにするサインdurableに扱いたい承認です。
項目内容見方
Hours承認まで時間が空きます。
Retrytool callをworkflow stepとしてretryしたい。
Refresh画面更新やtimeoutをまたぎたい。
Auditstep単位でinput/outputを見たい。

長時間止まる承認は、in-memory loopではなくworkflow runtimeへ寄せます。

VercelのWorkflowAgent記事では、WorkflowAgentはToolLoopAgentと同じagent loopをworkflow runtime上で動かし、tool callをdurable stepにすることで、statefulness、resumability、tool retries、human-in-the-loop、observabilityを補うと説明されています。

WorkflowAgentにするサイン

条件理由
承認まで時間が空くhours/days待てる
function timeoutをまたぐworkflow stateへ保存できる
refreshやdeployをまたぐstateを失いにくい
tool retryが必要step単位でretryできる
承認履歴を見たいworkflow dashboardで観測しやすい

needsApprovalの違い

WorkflowAgent記事では、WorkflowAgentではtoolにneedsApprovalを設定でき、booleanまたはasync functionでper-input decisionsができる説明があります。一方、generateTextstreamText、ToolLoopAgentのequivalent featureはtoolApproval optionと説明されています。

ここを混ぜると実装が崩れます。Core/ToolLoopAgentのapproval flowと、WorkflowAgentのworkflow runtime上の承認を分けます。

retryと副作用に注意

workflow stepはretryされる可能性があります。外部APIや決済のような副作用toolは、idempotency key、重複実行防止、実行済み記録を必ず設計します。

実務例

「本番deploy承認」はWorkflowAgent向きです。承認カードを出し、webhookで待ち、承認者と時刻を記録し、deploy stepを実行し、結果をthreadへ返します。

subagentとapprovalの制限

Visualsubagentで迷う点承認が使えない経路を把握します。
No approval

subagent toolsではneedsApprovalを使えません。

Isolated

subagent contextは独立します。

Delegate

承認が必要な操作は親側へ戻します。

Scope

subagentにはread-only toolを渡します。

subagentに危険toolを持たせて承認で止める、という設計にはしません。

AI SDKのSubagents Docsでは、subagent toolsではneedsApprovalを使えず、すべてのtoolsはuser confirmationなしに自動実行される必要があると説明されています。

subagentに渡すtool

tool種別渡すか
read-only search渡しやすい
summarization渡しやすい
local transform条件付き
DB write渡さない
email送信渡さない
payment/refund渡さない

承認が必要なら親に戻す

subagentに危険toolを持たせて、needsApprovalで止める設計にはしません。承認が必要な操作は、親agentやworkflowへ戻して承認します。

context isolationも見る

Subagents Docsでは、subagent contextは独立し、main agentの蓄積contextを継承しないことが利点として説明されています。承認判断に必要な情報をsubagentだけに持たせると、親側の承認UIで説明が不足します。

実務例

research subagentには検索と要約だけを渡します。メール送信やDB更新は親agentの承認付きtoolとして残します。

最小実装の形

Visual最初に置く部品小さく始める構成です。
項目内容見方
Tool schema入力を具体的にします。
needsApproval危険toolだけ承認にします。
UI state承認/否認/失敗を表示します。
Audit log誰が何を承認したか残します。

承認は安全弁なので、説明とログも一緒に作ります。

最初は、危険toolを1つだけ承認付きにします。

import { tool } from "ai";
import { z } from "zod";

export const sendEmail = tool({
  title: "メールを送信",
  description: "Send an email after the user reviews the recipient and body.",
  inputSchema: z.object({
    to: z.string().email(),
    subject: z.string().max(120),
    body: z.string().max(4000),
  }),
  needsApproval: true,
  execute: async ({ to, subject, body }) => {
    return {
      status: "sent",
      to,
      subject,
      messageId: "sample-message-id",
    };
  },
});

approval cardで見せる内容

type ApprovalView = {
  toolTitle: string;
  target: string;
  summary: string;
  irreversible: boolean;
  requestedBy: string;
};

UIには、tosubject、bodyの要約、取り消し可否、要求者を出します。body全文が長い場合は折りたたみますが、承認前に確認できるようにします。

audit log

type ToolApprovalAudit = {
  approvalId: string;
  toolName: string;
  approved: boolean;
  approverId: string;
  requestedAt: string;
  decidedAt: string;
  inputHash: string;
  reason?: string;
};

実行結果だけでなく、否認も残します。否認が多いtoolは、説明不足かtool description不足の可能性があります。

最初に作るテスト

  • 承認されたらtoolが1回だけ実行される
  • 否認されたらtoolが実行されない
  • 否認後に同じtoolを再試行しない
  • approvalIdが不正ならエラーになる
  • UIに対象、入力、影響、否認理由が出る

導入初週の進め方

Visual1週間の導入順approvalを段階的に増やします。
  1. 1日目

    承認対象toolを3つに絞ります。

  2. 2日目

    Core flowで2回呼び出しを確認。

  3. 3日目

    UIでdeny時の表示を作る。

  4. 5日目

    長時間承認をWorkflowAgentへ分離。

  5. 7日目

    audit logと失敗ケースを追加。

最初から全部承認にせず、取り消しにくい操作から始めます。

tool approvalは、最初から全toolに入れません。UXが重くなり、承認者が流れ作業で押すようになります。

1日目: 承認対象を3つに絞る

payment、delete、external sendのように、取り消しにくいtoolだけを承認対象にします。read-only toolには承認を付けません。

2日目: Core flowで2回呼び出しを確認する

generateTextまたはstreamTextでapproval requestが返り、approval responseをmessagesへ追加して続行できることを確認します。

3日目: deny時のUXを作る

否認後に同じtoolを再試行しないsystem instruction、否認理由の表示、代替案の提示を作ります。

5日目: 長時間承認をWorkflowAgentへ分ける

承認まで時間が空く業務をWorkflowAgentへ分けます。workflow stepのretryと副作用のidempotencyも確認します。

7日目: audit logと失敗ケースを追加する

誰が何を承認したか、否認したか、toolが実行されたかを残します。不正なapprovalId、二重クリック、期限切れ承認もテストします。

評価するログ

  • 承認者が実行内容を理解できたか
  • deny後にagentが同じtoolを再試行していないか
  • toolが二重実行されていないか
  • long-running approvalがrefreshやtimeoutをまたげたか
  • subagentへ危険toolが渡っていないか

FAQ

Visualよくある迷いtool approval実装で詰まりやすい点です。
全部承認?

UXが壊れるので危険操作だけにします。

deny後?

同じtoolを再試行しない指示を入れます。

長時間?

WorkflowAgentへ寄せます。

subagent?

承認toolを持たせない設計にします。

迷ったら、承認者が何を見て判断できるかに戻ります。

すべてのtoolにapprovalを付けるべきですか

不要です。read-only searchやformat変換まで承認にすると、ユーザーは内容を読まずに押すようになります。承認は、取り消しにくい操作や外部影響のある操作へ絞ります。

needsApprovalだけで監査になりますか

なりません。承認機能と監査ログは別です。誰が、いつ、どの入力で、何を承認または否認したかをアプリ側で残します。

否認されたらどうしますか

toolを実行せず、modelへ否認を伝えます。さらに、同じtool callをすぐ再試行しないようsystem instructionを入れます。否認理由があるなら、次の安全な選択肢を提示します。

長時間承認はCoreだけでできますか

短い承認ならCoreで十分ですが、数時間から数日待つ、function timeoutやpage refreshをまたぐ、step単位でretryしたいならWorkflowAgentを検討します。

subagentに承認付きtoolを持たせられますか

AI SDKのSubagents Docsでは、subagent toolsではneedsApprovalを使えないと説明されています。承認が必要なtoolは親agentやworkflow側に残します。

MCP toolにも同じ考え方を使えますか

使えます。read-only toolから始め、write toolには承認、権限、audit logを置きます。MCPの権限設計は、MCP仕様・SDK更新時の実務影響チェックTypeScriptで作る最小MCP Serverも合わせて確認してください。


次に読むなら

参照した主な情報源

  • AI SDK Docs: Tool Calling / Tool Execution Approval

https://ai-sdk.dev/docs/ai-sdk-core/tools-and-tool-calling

  • AI SDK Docs: tool() reference

https://ai-sdk.dev/docs/reference/ai-sdk-core/tool

  • AI SDK Docs: Chatbot with Tool Calling

https://ai-sdk.dev/docs/ai-sdk-ui/chatbot-with-tool-calling

  • AI SDK Docs: Subagents

https://ai-sdk.dev/docs/agents/subagents

  • Vercel Knowledge Base: What is WorkflowAgent?

https://vercel.com/kb/guide/what-is-workflowagent

  • Vercel Knowledge Base: How to build AI Agents with Vercel and the AI SDK

https://vercel.com/kb/guide/how-to-build-ai-agents-with-vercel-and-the-ai-sdk

  • Vercel Knowledge Base: Human-in-the-Loop with Chat SDK and Workflow SDK

https://vercel.com/kb/guide/human-in-the-loop-with-chat-sdk-and-workflow-sdk

次に読むなら

AI Agentアプリ開発入門

tool calling、workflow、guardrails、structured outputの全体像から設計したい場合に確認できます。

更新履歴

Visual確認と更新の記録AI SDKの仕様は更新されるため確認日を残します。
  1. 2026年5月31日

    AI SDK Docs、Vercel WorkflowAgent KB、Chat/Workflow HITL記事、OpenAI Agents SDK HITL Docsを確認して初版を作成しました。

導入時にはAI SDKのversionと利用runtimeを確認してください。

  • 2026年5月31日: AI SDK Docs、Vercel WorkflowAgent記事、Vercel Chat/Workflow human-in-the-loop記事を確認し、初版を公開しました。