mcpField
A
ai-sdk-core

ai-sdk-core

github.com/jezweb開発1.1k479 回インストール3 週間前に更新
リポジトリ

ai-sdk-core について

AI SDK Coreは、LLM、ツール、マルチモーダル機能を使うバックエンドアプリケーション向けのTypeScriptツールキットです。エージェント実行、構造化出力、プロバイダー連携、MCPクライアント機能を備えています。

主な機能

  1. 01テキスト生成とストリーミング
  2. 02スキーマ準拠の構造化出力
  3. 03エージェントとツールループ実行
  4. 04ツール実行の承認制御
  5. 05マルチモーダル生成と埋め込み
  6. 06MCPクライアントによるツール取得

活用シーン

  1. 01バックエンドLLM機能の構築
  2. 02ツールを使うエージェントの作成
  3. 03型付きJSONレスポンスの生成
  4. 04MCPツールのアプリケーションへの接続

MCP 対応

MCPクライアント機能を備え、stdio経由でMCPサーバーに接続し、アプリケーションで使うツールを取得できます。READMEでは動的なMCPツール定義のセキュリティ上の注意点も説明しています。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jezweb/claude-skills --skill ai-sdk-core

インストール後、Claude Code で/ai-sdk-coreを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

README.md
VERIFICATION_REPORT.md
.claude-plugin/
plugin.json
references/
links-to-official-docs.md
production-patterns.md
providers-quickstart.md
top-errors.md
v5-breaking-changes.md
rules/
ai-sdk-core.md
scripts/
check-versions.sh
templates/
agent-with-tools.ts
anthropic-setup.ts
cloudflare-worker-integration.ts
generate-object-zod.ts
generate-text-basic.ts
google-setup.ts
multi-step-execution.ts
nextjs-server-action.ts
openai-setup.ts
package.json
stream-object-zod.ts
stream-text-chat.ts
tools-basic.ts

詳細

AI SDK Core

Vercel AI SDK v5 および v6 を使用したバックエンド AI です。

インストール:

npm install ai @ai-sdk/openai @ai-sdk/anthropic @ai-sdk/google zod

AI SDK 6(安定版 — 2026年1月)

ステータス: 安定版 最新: [email protected](2026年1月)

破壊的変更:Output API が generateObject/streamObject に置き換わります

⚠️ 重要:generateObject() と streamObject() は非推奨であり、将来のバージョンで削除されます。代わりに新しい Output API を使用してください。

変更前(v5 — 非推奨):

// ❌ DEPRECATED - will be removed
import { generateObject } from 'ai';

const result = await generateObject({
  model: openai('gpt-5'),
  schema: z.object({ name: z.string(), age: z.number() }),
  prompt: 'Generate a person',
});

変更後(v6 — こちらを使用):

// ✅ NEW OUTPUT API
import { generateText, Output } from 'ai';

const result = await generateText({
  model: openai('gpt-5'),
  output: Output.object({ schema: z.object({ name: z.string(), age: z.number() }) }),
  prompt: 'Generate a person',
});

// Access the typed object
console.log(result.object); // { name: "Alice", age: 30 }
Output の型
import { generateText, Output } from 'ai';

// Object with Zod schema
output: Output.object({ schema: myZodSchema })

// Array of typed objects
output: Output.array({ schema: personSchema })

// Enum/choice from options
output: Output.choice({ choices: ['positive', 'negative', 'neutral'] })

// Plain text (explicit)
output: Output.text()

// Unstructured JSON (no schema validation)
output: Output.json()
Output API によるストリーミング
import { streamText, Output } from 'ai';

const result = streamText({
  model: openai('gpt-5'),
  output: Output.object({ schema: personSchema }),
  prompt: 'Generate a person',
});

// Stream partial objects
for await (const partialObject of result.objectStream) {
  console.log(partialObject); // { name: "Ali..." } -> { name: "Alice", age: ... }
}

// Get final object
const finalObject = await result.object;
v6 の新機能

1. エージェントの抽象化 ToolLoopAgent クラスを使った、エージェント構築のための統一インターフェースです。

  • 実行フロー、ツールループ、状態管理を完全に制御できます
  • 手動でのツール呼び出しオーケストレーションに置き換わります

2. ツール実行の承認(Human-in-the-Loop)

UX を向上させるため、選択的な承認を使用します。すべてのツール呼び出しで承認が必要なわけではありません。

tools: {
  payment: tool({
    // Dynamic approval based on input
    needsApproval: async ({ amount }) => amount > 1000,
    inputSchema: z.object({ amount: z.number() }),
    execute: async ({ amount }) => { /* process payment */ },
  }),

  readFile: tool({
    needsApproval: false, // Safe operations don't need approval
    inputSchema: z.object({ path: z.string() }),
    execute: async ({ path }) => fs.readFile(path),
  }),

  deleteFile: tool({
    needsApproval: true, // Destructive operations always need approval
    inputSchema: z.object({ path: z.string() }),
    execute: async ({ path }) => fs.unlink(path),
  }),
}

ベストプラクティス:

  • リスクがパラメーターによって変わる操作(例:支払い金額)には、動的な承認を使用します
  • 破壊的な操作(削除、変更、購入)では、必ず承認を求めます
  • 安全な読み取り操作では、承認を求めないようにします
  • システム指示に「ツールの実行が承認されなかった場合は、再試行しないでください」と追加します
  • 承認リクエストが停止状態にならないよう、タイムアウトを実装します
  • 繰り返し実行するアクションについて、ユーザーの設定を保存します

参考資料:

3. RAG の再ランキング

import { rerank } from 'ai';

const result = await rerank({
  model: cohere.reranker('rerank-v3.5'),
  query: 'user question',
  documents: searchResults,
  topK: 5,
});

4. MCP ツール(Model Context Protocol)

⚠️ セキュリティ警告:MCP ツールには、本番環境における重大なリスクがあります。以下のセキュリティに関するセクションを参照してください。

import { experimental_createMCPClient } from 'ai';

const mcpClient = await experimental_createMCPClient({
  transport: { type: 'stdio', command: 'npx', args: ['-y', '@modelcontextprotocol/server-filesystem'] },
});

const tools = await mcpClient.tools();

const result = await generateText({
  model: openai('gpt-5'),
  tools,
  prompt: 'List files in the current directory',
});

既知の問題:ストリーミングモードでは、MCP ツールが実行されないことがあります(Vercel コミュニティでのディスカッション)。MCP ツールでは、streamText() ではなく generateText() を使用してください。

MCP のセキュリティに関する考慮事項

⚠️ 重要:本番環境での動的な MCP ツールには、セキュリティリスクがあります。

リスク:

  • ツール定義がエージェントのプロンプトの一部になります
  • 警告なく予期せず変更される可能性があります
  • 侵害された MCP サーバーが悪意のあるプロンプトを注入する可能性があります
  • 新しいツールによって、ユーザー権限が昇格する可能性があります(例:読み取り専用サーバーに削除機能が追加される)

解決策 — 静的ツールの生成を使用する:

// ❌ RISKY: Dynamic tools change without your control
const mcpClient = await experimental_createMCPClient({ /* ... */ });
const tools = await mcpClient.tools(); // Can change anytime!

// ✅ SAFE: Generate static, versioned tool definitions
// Step 1: Install mcp-to-ai-sdk
npm install -g mcp-to-ai-sdk

// Step 2: Generate static tools (one-time, version controlled)
npx mcp-to-ai-sdk generate stdio 'npx -y @modelcontextprotocol/server-filesystem'

// Step 3: Import static tools
import { tools } from './generated-mcp-tools';

const result = await generateText({
  model: openai('gpt-5'),
  tools, // Static, reviewed, versioned
  prompt: 'Use tools',
});

ベストプラクティス:静的ツールを生成してレビューし、バージョン管理にコミットしたうえで、意図した場合にのみ更新してください。

参考資料:Vercel ブログ:MCP のセキュリティ

5. 言語モデルのミドルウェア

import { wrapLanguageModel, extractReasoningMiddleware } from 'ai';

const wrappedModel = wrapLanguageModel({
  model: anthropic('claude-sonnet-4-5-20250929'),
  middleware: extractReasoningMiddleware({ tagName: 'think' }),
});

// Reasoning extracted automatically from <think>...</think> tags

6. テレメトリー(OpenTelemetry)

const result = await generateText({
  model: openai('gpt-5'),
  prompt: 'Hello',
  experimental_telemetry: {
    isEnabled: true,
    functionId: 'my-chat-function',
    metadata: { userId: '123' },
    recordInputs: true,
    recordOutputs: true,
  },
});

公式ドキュメント: https://ai-sdk.dev/docs


最新の AI モデル(2025~2026年)

OpenAI

GPT-5.2(2025年12月):

  • コンテキストウィンドウは 400k、出力トークンは 128k
  • 推論能力が強化されています
  • API プラットフォームで利用できます

GPT-5.1(2025年11月):

  • GPT-5 より速度と効率が向上しています
  • より「温かみ」があり、知的な応答を返します

GPT-5(2025年8月):

  • GPT-4o よりハルシネーションが 45% 少なくなっています
  • 数学、コーディング、視覚認識で最先端の性能を発揮します

o3 推論モデル(2025年12月):

  • o3、o3-pro、o3-mini — 高度な推論
  • o4-mini — 高速な推論
import { openai } from '@ai-sdk/openai';
const gpt52 = openai('gpt-5.2');
const gpt51 = openai('gpt-5.1');
const gpt5 = openai('gpt-5');
const o3 = openai('o3');
const o3mini = openai('o3-mini');
Anthropic

Claude 4 ファミリー(2025年5月~10月):

  • Opus 4(5月22日):複雑な推論に最適。100万トークンあたり $15/$75
  • Sonnet 4(5月22日):バランスの取れた性能。100万トークンあたり $3/$15
  • Opus 4.1(8月5日):エージェントタスクや実環境でのコーディングを強化
  • Sonnet 4.5(9月29日):コーディング、エージェント、コンピューター操作において最も高い能力を発揮
  • Haiku 4.5(10月15日):小型で高速、低レイテンシのモデル
import { anthropic } from '@ai-sdk/anthropic';
const sonnet45 = anthropic('claude-sonnet-4-5-20250929');  // Latest
const opus41 = anthropic('claude-opus-4-1-20250805');
const haiku45 = anthropic('claude-haiku-4-5-20251015');
Google

Gemini 2.5 ファミリー(2025年3月~9月):

  • Pro(2025年3月):最も高い知能を備え、リリース時にLMArenaで第1位
  • Pro Deep Think(2025年5月):強化された推論モード
  • Flash(2025年5月):高速でコスト効率に優れています
  • Flash-Lite(2025年9月):効率性を向上
import { google } from '@ai-sdk/google';
const pro = google('gemini-2.5-pro');
const flash = google('gemini-2.5-flash');
const lite = google('gemini-2.5-flash-lite');

コア機能

テキスト生成

generateText() - ツールを使ったテキスト補完
streamText() - リアルタイムストリーミング

構造化出力(v6 Output API)

Output.object() - Zod スキーマを使った型付きオブジェクト(generateObject を置き換え)
Output.array() - 型付き配列
Output.choice() - 列挙型の選択
Output.json() - 非構造化 JSON

使用例については、上記の「AI SDK 6」セクションを参照してください。

マルチモーダル機能
音声合成(テキスト読み上げ)
import { experimental_generateSpeech as generateSpeech } from 'ai';
import { openai } from '@ai-sdk/openai';

const result = await generateSpeech({
  model: openai.speech('tts-1-hd'),
  voice: 'alloy',
  text: 'Hello, how can I help you today?',
});

// result.audio is an ArrayBuffer containing the audio
const audioBuffer = result.audio;

対応プロバイダー:

  • OpenAI:tts-1、tts-1-hd、gpt-4o-mini-tts
  • ElevenLabs:eleven_multilingual_v2、eleven_turbo_v2
  • LMNT、Hume
文字起こし(音声テキスト変換)
import { experimental_transcribe as transcribe } from 'ai';
import { openai } from '@ai-sdk/openai';

const result = await transcribe({
  model: openai.transcription('whisper-1'),
  audio: audioFile, // File, Blob, ArrayBuffer, or URL
});

console.log(result.text); // Transcribed text
console.log(result.segments); // Timestamped segments

対応プロバイダー:

  • OpenAI:whisper-1
  • ElevenLabs、Deepgram、AssemblyAI、Groq、Rev.ai
画像生成
import { generateImage } from 'ai';
import { openai } from '@ai-sdk/openai';

const result = await generateImage({
  model: openai.image('dall-e-3'),
  prompt: 'A futuristic city at sunset',
  size: '1024x1024',
  n: 1,
});

// result.images is an array of generated images
const imageUrl = result.images[0].url;
const imageBase64 = result.images[0].base64;

対応プロバイダー:

  • OpenAI:dall-e-2、dall-e-3
  • Google:imagen-3.0
  • Fal AI、Black Forest Labs(Flux)、Luma AI、Replicate
埋め込み
import { embed, embedMany, cosineSimilarity } from 'ai';
import { openai } from '@ai-sdk/openai';

// Single embedding
const result = await embed({
  model: openai.embedding('text-embedding-3-small'),
  value: 'Hello world',
});
console.log(result.embedding); // number[]

// Multiple embeddings (parallel processing)
const results = await embedMany({
  model: openai.embedding('text-embedding-3-small'),
  values: ['Hello', 'World', 'AI'],
  maxParallelCalls: 5, // Parallel processing
});

// Compare similarity
const similarity = cosineSimilarity(
  results.embeddings[0],
  results.embeddings[1]
);
console.log(`Similarity: ${similarity}`); // 0.0 to 1.0

対応プロバイダー:

  • OpenAI:text-embedding-3-small、text-embedding-3-large
  • Google:text-embedding-004
  • Cohere、Voyage AI、Mistral、Amazon Bedrock
マルチモーダルプロンプト(ファイル、画像、PDF)
import { generateText } from 'ai';
import { google } from '@ai-sdk/google';

const result = await generateText({
  model: google('gemini-2.5-pro'),
  messages: [{
    role: 'user',
    content: [
      { type: 'text', text: 'Summarize this document' },
      { type: 'file', data: pdfBuffer, mimeType: 'application/pdf' },
    ],
  }],
});

// Or with images
const result = await generateText({
  model: openai('gpt-5'),
  messages: [{
    role: 'user',
    content: [
      { type: 'text', text: 'What is in this image?' },
      { type: 'image', image: imageBuffer },
    ],
  }],
});

API の全容については、公式ドキュメントを参照してください:https://ai-sdk.dev/docs/ai-sdk-core


v5 ストリームレスポンスメソッド

API からストリーミングレスポンスを返す場合は、適切なメソッドを使用してください:

メソッド出力形式用途
toTextStreamResponse()プレーンテキストのチャンクシンプルなテキストストリーミング
toUIMessageStreamResponse()JSON イベントを含む SSEチャット UI(text-start、text-delta、text-end、finish)

チャットウィジェットや UI では、必ず toUIMessageStreamResponse() を使用してください:

const result = streamText({
  model: workersai('@cf/qwen/qwen3-30b-a3b-fp8'),
  messages,
  system: 'You are helpful.',
});

// ✅ For chat UIs - returns SSE with JSON events
return result.toUIMessageStreamResponse({
  headers: { 'Access-Control-Allow-Origin': '*' },
});

// ❌ For simple text - returns plain text chunks only
return result.toTextStreamResponse();

注: AI SDK v5 に toDataStreamResponse() は存在しません(よくある誤解です)。


workers-ai-provider のバージョン互換性

重要: [email protected] には AI SDK v4 ではなく、AI SDK v5 が必要です。

# ✅ Correct - AI SDK v5 with workers-ai-provider v2
npm install ai@^5.0.0 workers-ai-provider@^2.0.0 zod@^3.25.0

# ❌ Wrong - AI SDK v4 causes error
npm install ai@^4.0.0 workers-ai-provider@^2.0.0
# Error: "AI SDK 4 only supports models that implement specification version v1"

Zod のバージョン: AI SDK v5 で zod/v3 および zod/v4 のエクスポートを使うには、zod@^3.25.0 以降が必要です。古いバージョン(3.22.x)では、ビルドエラー「Could not resolve zod/v4」が発生します。


Cloudflare Workers の起動時の修正

問題: AI SDK v5 と Zod の組み合わせにより、起動時間が270msを超えます(Workers の制限である400msを超過します)。

解決策:

// ❌ BAD: Top-level imports cause startup overhead
import { createWorkersAI } from 'workers-ai-provider';
const workersai = createWorkersAI({ binding: env.AI });

// ✅ GOOD: Lazy initialization inside handler
app.post('/chat', async (c) => {
  const { createWorkersAI } = await import('workers-ai-provider');
  const workersai = createWorkersAI({ binding: c.env.AI });
  // ...
});

その他:

  • トップレベルの Zod スキーマを最小限に抑える
  • 複雑なスキーマはルートハンドラーに移動する
  • Wrangler で起動時間を監視する

v5 のツール呼び出しに関する変更

互換性を損なう変更:

  • parameters → inputSchema(Zod スキーマ)
  • ツールのプロパティ:args → input、result → output
  • ToolExecutionError を削除(現在は tool-error コンテンツパーツ)
  • maxSteps パラメーターを削除 → stopWhen(stepCountIs(n)) を使用

v5 の新機能:

  • 動的ツール(コンテキストに応じて実行時にツールを追加)
  • Agent クラス(ツールを使ったマルチステップ実行)

v4 から v5 への重要な移行

AI SDK v5 では、互換性を損なう変更が多数導入されました。v4 から移行する場合は、このガイドに従ってください。

破壊的変更の概要
  1. パラメーター名の変更

    • maxTokens → maxOutputTokens
    • providerMetadata → providerOptions
  2. ツール定義

    • parameters → inputSchema
    • ツールのプロパティ:args → input、result → output
  3. メッセージの型

    • CoreMessage → ModelMessage
    • Message → UIMessage
    • convertToCoreMessages → convertToModelMessages
  4. ツールのエラー処理

    • ToolExecutionError クラスを削除
    • tool-error コンテンツパーツを使用
    • 自動再試行が可能に
  5. 複数ステップの実行

    • maxSteps → stopWhen
    • stepCountIs() または hasToolCall() を使用
  6. メッセージ構造

    • シンプルな content 文字列 → parts 配列
    • パーツ:text、file、reasoning、tool-call、tool-result
  7. ストリーミングアーキテクチャ

    • 単一チャンク → start/delta/end のライフサイクル
    • 同時ストリームには一意の ID を使用
  8. ツールのストリーミング

    • デフォルトで有効
    • toolCallStreaming オプションを削除
  9. パッケージの再編成

    • ai/rsc → @ai-sdk/rsc
    • ai/react → @ai-sdk/react
    • LangChainAdapter → @ai-sdk/langchain
移行例

変更前(v4):

import { generateText } from 'ai';

const result = await generateText({
  model: openai.chat('gpt-4-turbo'),
  maxTokens: 500,
  providerMetadata: { openai: { user: 'user-123' } },
  tools: {
    weather: {
      description: 'Get weather',
      parameters: z.object({ location: z.string() }),
      execute: async (args) => { /* args.location */ },
    },
  },
  maxSteps: 5,
});

変更後(v5):

import { generateText, tool, stopWhen, stepCountIs } from 'ai';

const result = await generateText({
  model: openai('gpt-4-turbo'),
  maxOutputTokens: 500,
  providerOptions: { openai: { user: 'user-123' } },
  tools: {
    weather: tool({
      description: 'Get weather',
      inputSchema: z.object({ location: z.string() }),
      execute: async ({ location }) => { /* input.location */ },
    }),
  },
  stopWhen: stepCountIs(5),
});
移行チェックリスト
  • すべての maxTokens を maxOutputTokens に更新する
  • providerMetadata を providerOptions に更新する
  • ツールの parameters を inputSchema に変換する
  • ツールの execute 関数を更新する:args → input
  • maxSteps を stopWhen(stepCountIs(n)) に置き換える
  • メッセージの型を更新する:CoreMessage → ModelMessage
  • ToolExecutionError の処理を削除する
  • パッケージのインポートを更新する(ai/rsc → @ai-sdk/rsc)
  • ストリーミングの動作をテストする(アーキテクチャが変更されています)
  • TypeScript の型を更新する
自動移行

AI SDK には移行ツールが用意されています。

npx ai migrate

このツールは、破壊的変更の大半を自動で更新します。変更内容を慎重に確認してください。

公式移行ガイド: https://ai-sdk.dev/docs/migration-guides/migration-guide-5-0


よくあるエラーと解決方法トップ15

1. AI_APICallError

原因: API リクエストが失敗しています(ネットワーク、認証、レート制限)。

解決方法:

import { AI_APICallError } from 'ai';

try {
  const result = await generateText({
    model: openai('gpt-4-turbo'),
    prompt: 'Hello',
  });
} catch (error) {
  if (error instanceof AI_APICallError) {
    console.error('API call failed:', error.message);
    console.error('Status code:', error.statusCode);
    console.error('Response:', error.responseBody);

    // Check common causes
    if (error.statusCode === 401) {
      // Invalid API key
    } else if (error.statusCode === 429) {
      // Rate limit - implement backoff
    } else if (error.statusCode >= 500) {
      // Provider issue - retry
    }
  }
}

予防策:

  • 起動時に API キーを検証する
  • 指数バックオフによる再試行ロジックを実装する
  • レート制限を監視する
  • ネットワークエラーを適切に処理する

2. AI_NoObjectGeneratedError

原因: モデルがスキーマに一致する有効なオブジェクトを生成しませんでした。

解決方法:

import { AI_NoObjectGeneratedError } from 'ai';

try {
  const result = await generateObject({
    model: openai('gpt-4-turbo'),
    schema: z.object({ /* complex schema */ }),
    prompt: 'Generate data',
  });
} catch (error) {
  if (error instanceof AI_NoObjectGeneratedError) {
    console.error('No valid object generated');

    // Solutions:
    // 1. Simplify schema
    // 2. Add more context to prompt
    // 3. Provide examples in prompt
    // 4. Try different model (gpt-5 or claude-sonnet-4-5 for complex objects)
  }
}

予防策:

  • シンプルなスキーマから始め、段階的に複雑さを加える
  • プロンプトに例を含める:「次のような人物を生成してください:{ name: 'Alice', age: 30 }」
  • 複雑な構造化出力には GPT-4 を使用する
  • まずサンプルデータでスキーマをテストする

3. Worker の起動時間制限(270ms 以上)

原因: AI SDK v5 と Zod の初期化オーバーヘッドにより、Cloudflare Workers の起動時間制限を超過します。

解決方法:

// BAD: Top-level imports cause startup overhead
import { createWorkersAI } from 'workers-ai-provider';
import { complexSchema } from './schemas';

const workersai = createWorkersAI({ binding: env.AI });

// GOOD: Lazy initialization inside handler
export default {
  async fetch(request, env) {
    const { createWorkersAI } = await import('workers-ai-provider');
    const workersai = createWorkersAI({ binding: env.AI });

    // Use workersai here
  }
}

予防策:

  • AI SDK のインポートをルートハンドラー内に移動する
  • トップレベルの Zod スキーマを最小限にする
  • Worker の起動時間を監視する(400ms 未満である必要があります)
  • Wrangler の起動時間レポートを使用する

GitHub Issue: Vercel AI SDK の Issue で「Workers startup limit」を検索してください


4. streamText が何も通知せずに失敗する

原因: createDataStreamResponse によってストリームエラーが握りつぶされることがあります。

ステータス: ✅ 解決済み - [email protected] で修正済み(2025年2月)

解決方法(推奨):

// Use the onError callback (added in v4.1.22)
const stream = streamText({
  model: openai('gpt-4-turbo'),
  prompt: 'Hello',
  onError({ error }) {
    console.error('Stream error:', error);
    // Custom error logging and handling
  },
});

// Stream safely
for await (const chunk of stream.textStream) {
  process.stdout.write(chunk);
}

代替方法(手動の try-catch):

// Fallback if not using onError callback
try {
  const stream = streamText({
    model: openai('gpt-4-turbo'),
    prompt: 'Hello',
  });

  for await (const chunk of stream.textStream) {
    process.stdout.write(chunk);
  }
} catch (error) {
  console.error('Stream error:', error);
}

予防策:

  • 適切にエラーを捕捉するため、onError コールバックを使用する(推奨)
  • サーバー側のエラー監視を実装する
  • ストリームのエラー処理を明示的にテストする
  • 本番環境では必ずサーバー側でログを記録する

GitHub Issue: #4726(解決済み)


5. AI_LoadAPIKeyError

原因: API キーがない、または無効です。

解決方法:

import { AI_LoadAPIKeyError } from 'ai';

try {
  const result = await generateText({
    model: openai('gpt-4-turbo'),
    prompt: 'Hello',
  });
} catch (error) {
  if (error instanceof AI_LoadAPIKeyError) {
    console.error('API key error:', error.message);

    // Check:
    // 1. .env file exists and loaded
    // 2. Correct env variable name (OPENAI_API_KEY)
    // 3. Key format is valid (starts with sk-)
  }
}

予防策:

  • アプリケーションの起動時に API キーを検証する
  • 環境変数の検証を使用する(例:zod)
  • 開発環境では明確なエラーメッセージを表示する
  • 必要な環境変数をドキュメントに記載する

6. AI_InvalidArgumentError

原因: 関数に無効なパラメーターが渡されました。

解決方法:

import { AI_InvalidArgumentError } from 'ai';

try {
  const result = await generateText({
    model: openai('gpt-4-turbo'),
    maxOutputTokens: -1,  // Invalid!
    prompt: 'Hello',
  });
} catch (error) {
  if (error instanceof AI_InvalidArgumentError) {
    console.error('Invalid argument:', error.message);
    // Check parameter types and values
  }
}

予防方法:

  • 型チェックには TypeScript を使用します
  • AI SDK 関数を呼び出す前に入力値を検証します
  • 関数のシグネチャを注意深く確認します
  • パラメーターの制約について公式ドキュメントを確認します

7. AI_NoContentGeneratedError

原因: モデルがコンテンツを生成しませんでした(セーフティフィルターなど)。

解決方法:

import { AI_NoContentGeneratedError } from 'ai';

try {
  const result = await generateText({
    model: openai('gpt-4-turbo'),
    prompt: 'Some prompt',
  });
} catch (error) {
  if (error instanceof AI_NoContentGeneratedError) {
    console.error('No content generated');

    // Possible causes:
    // 1. Safety filters blocked output
    // 2. Prompt triggered content policy
    // 3. Model configuration issue

    // Handle gracefully:
    return { text: 'Unable to generate response. Please try different input.' };
  }
}

予防方法:

  • ユーザー入力をサニタイズします
  • セーフティフィルターに引っかかる可能性のあるプロンプトを避けます
  • フォールバックメッセージを用意します
  • 分析できるよう、発生状況をログに記録します

8. AI_TypeValidationError

原因: 生成された出力に対する Zod スキーマの検証に失敗しました。

解決方法:

import { AI_TypeValidationError } from 'ai';

try {
  const result = await generateObject({
    model: openai('gpt-4-turbo'),
    schema: z.object({
      age: z.number().min(0).max(120),  // Strict validation
    }),
    prompt: 'Generate person',
  });
} catch (error) {
  if (error instanceof AI_TypeValidationError) {
    console.error('Validation failed:', error.message);

    // Solutions:
    // 1. Relax schema constraints
    // 2. Add more guidance in prompt
    // 3. Use .optional() for unreliable fields
  }
}

予防方法:

  • 最初は緩やかなスキーマを使い、段階的に厳しくします
  • 常に存在するとは限らないフィールドには .optional() を使用します
  • フィールドの説明に検証のヒントを追加します
  • さまざまなプロンプトでテストします

9. AI_RetryError

原因: すべての再試行に失敗しました。

解決方法:

import { AI_RetryError } from 'ai';

try {
  const result = await generateText({
    model: openai('gpt-4-turbo'),
    prompt: 'Hello',
    maxRetries: 3,  // Default is 2
  });
} catch (error) {
  if (error instanceof AI_RetryError) {
    console.error('All retries failed');
    console.error('Last error:', error.lastError);

    // Check root cause:
    // - Persistent network issue
    // - Provider outage
    // - Invalid configuration
  }
}

予防方法:

  • 失敗の根本原因を調査します
  • 必要に応じて再試行の設定を調整します
  • プロバイダーの停止に備えてサーキットブレーカーパターンを実装します
  • フォールバックプロバイダーを用意します

10. レート制限エラー

原因: プロバイダーのレート制限(RPM/TPM)を超過しました。

解決方法:

// Implement exponential backoff
async function generateWithBackoff(prompt: string, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      return await generateText({
        model: openai('gpt-4-turbo'),
        prompt,
      });
    } catch (error) {
      if (error instanceof AI_APICallError && error.statusCode === 429) {
        const delay = Math.pow(2, i) * 1000;  // Exponential backoff
        console.log(`Rate limited, waiting ${delay}ms`);
        await new Promise(resolve => setTimeout(resolve, delay));
      } else {
        throw error;
      }
    }
  }
  throw new Error('Rate limit retries exhausted');
}

予防方法:

  • レート制限ヘッダーを監視します
  • 制限を超えないようにリクエストをキューに入れます
  • 必要に応じてプロバイダーのプランをアップグレードします
  • リクエストのスロットリングを実装します

11. Zod による TypeScript のパフォーマンス低下

原因: 複雑な Zod スキーマによって、TypeScript の型チェックが遅くなります。

解決方法:

// Instead of deeply nested schemas at top level:
// const complexSchema = z.object({ /* 100+ fields */ });

// Define inside functions or use type assertions:
function generateData() {
  const schema = z.object({ /* complex schema */ });
  return generateObject({ model: openai('gpt-4-turbo'), schema, prompt: '...' });
}

// Or use z.lazy() for recursive schemas:
type Category = { name: string; subcategories?: Category[] };
const CategorySchema: z.ZodType<Category> = z.lazy(() =>
  z.object({
    name: z.string(),
    subcategories: z.array(CategorySchema).optional(),
  })
);

予防方法:

  • トップレベルに複雑なスキーマを定義しないようにします
  • 再帰型には z.lazy() を使用します
  • 大きなスキーマを小さなものに分割します
  • 適切な場合は型アサーションを使用します

公式ドキュメント: https://ai-sdk.dev/docs/troubleshooting/common-issues/slow-type-checking


12. 無効な JSON レスポンス(プロバイダー固有)

原因: モデルによっては、無効な JSON を返すことがあります。

解決方法:

// Use built-in retry and mode selection
const result = await generateObject({
  model: openai('gpt-4-turbo'),
  schema: mySchema,
  prompt: 'Generate data',
  mode: 'json',  // Force JSON mode (supported by GPT-4)
  maxRetries: 3,  // Retry on invalid JSON
});

// Or catch and retry manually:
try {
  const result = await generateObject({
    model: openai('gpt-4-turbo'),
    schema: mySchema,
    prompt: 'Generate data',
  });
} catch (error) {
  // Retry with different model
  const result = await generateObject({
    model: openai('gpt-4-turbo'),
    schema: mySchema,
    prompt: 'Generate data',
  });
}

予防方法:

  • 利用可能な場合は mode: 'json' を使用します
  • 構造化出力には GPT-4 を優先します
  • 再試行ロジックを実装します
  • レスポンスを検証します

GitHub Issue: #4302(Imagen 3.0 の無効な JSON)


13. Gemini の暗黙的なキャッシュがツール使用時に機能しない

エラー:エラーは発生しませんが、キャッシュが無効になるため API コストが増加します
原因:Google Gemini 3 Flash のコスト削減に役立つ暗黙的なキャッシュは、ツールが一度も使用されない場合でも、リクエストにツールが定義されていると機能しません。
出典:GitHub Issue #11513

発生する理由:Gemini API は、ツールが呼び出されたかどうかにかかわらず、リクエストにツールが含まれている場合にキャッシュを無効にします。

予防方法:

// Conditionally add tools only when needed
const needsTools = await analyzePrompt(userInput);

const result = await generateText({
  model: google('gemini-3-flash'),
  tools: needsTools ? { weather: weatherTool } : undefined,
  prompt: userInput,
});

影響:大 - コンテキストを繰り返し使用すると、API コストが大幅に増加する可能性があります


14. Anthropic のツールエラー結果による JSON 解析クラッシュ

エラー:SyntaxError: "[object Object]" is not valid JSON
原因:Anthropic プロバイダーの組み込みツール(web_fetch など)が返すエラーオブジェクトを、SDK が JSON.parse しようとします
出典:GitHub Issue #11856

発生する理由:Anthropic の組み込みツールが失敗すると(例:url_not_allowed)、エラーオブジェクトを返します。AI SDK は誤ってこれを JSON 文字列として解析しようとします。

予防方法:

try {
  const result = await generateText({
    model: anthropic('claude-sonnet-4-5-20250929'),
    tools: { web_fetch: { type: 'anthropic_defined', name: 'web_fetch' } },
    prompt: userPrompt,
  });
} catch (error) {
  if (error.message.includes('is not valid JSON')) {
    // Tool returned error result, handle gracefully
    console.error('Tool execution failed - likely blocked URL or permission issue');
    // Retry without tool or use custom tool
  }
  throw error;
}

影響:大 - Anthropic の組み込みツールを使用すると、本番環境でクラッシュが発生します


15. アシスタントメッセージ内のツール結果(Anthropic)

エラー:Anthropic API エラー - アシスタントメッセージ内では tool-result は許可されていません 原因:サーバーで実行されるツールが、誤ってアシスタントメッセージ内に tool-result パーツを配置しています ソース:GitHub Issue #11855

発生する理由:サーバーで実行されるツール(モデルに送信されず、サーバー上で execute が実行されるツール)を使用すると、AI SDK が誤ってアシスタントメッセージ内に tool-result パーツを含めます。Anthropic では、tool-result はユーザーメッセージ内にのみ含める必要があります。

防止策:

// Workaround: Filter messages before sending
const filteredMessages = messages.map(msg => {
  if (msg.role === 'assistant') {
    return {
      ...msg,
      content: msg.content.filter(part => part.type !== 'tool-result'),
    };
  }
  return msg;
});

const result = await generateText({
  model: anthropic('claude-sonnet-4-5-20250929'),
  tools: { database: databaseTool },
  messages: filteredMessages,
  prompt: 'Get user data',
});

影響:大 - Anthropic プロバイダーでサーバー実行ツールのパターンが機能しなくなります

ステータス:既知の問題。PR #11854 が提出済みです


その他のエラー: https://ai-sdk.dev/docs/reference/ai-sdk-errors (合計 31 件)


既知の問題と制限事項

メモ化されたオプションを使う場合の useChat の古いクロージャー

問題:useChat でメモ化されたオプションを使用すると(パフォーマンス向上のためによく使われます)、onData コールバックと onFinish コールバックが古いクロージャーを参照し、更新された状態変数を認識できません。

ソース:GitHub Issue #11686

再現方法:

const [count, setCount] = useState(0);

const chatOptions = useMemo(() => ({
  onFinish: (message) => {
    console.log('Count:', count); // ALWAYS 0, never updates!
  },
}), []); // Empty deps = stale closure

const { messages, append } = useChat(chatOptions);

回避策 1 - コールバックをメモ化しない:

const { messages, append } = useChat({
  onFinish: (message) => {
    console.log('Count:', count); // Now sees current count
  },
});

回避策 2 - useRef を使う:

const countRef = useRef(count);
useEffect(() => { countRef.current = count; }, [count]);

const chatOptions = useMemo(() => ({
  onFinish: (message) => {
    console.log('Count:', countRef.current); // Always current
  },
}), []);

完全な再現例:https://github.com/alechoey/ai-sdk-stale-ondata-repro


タブ切り替え時にストリームの再開に失敗する

問題:AI ストリームの実行中にユーザーがブラウザーのタブを切り替えたり、アプリをバックグラウンドに移動したりすると、戻ったときにストリームが再開しません。接続が失われ、自動的に再接続されません。

ソース:GitHub Issue #11865

影響:大 - 長時間実行されるストリームで、UX に重大な問題が生じます

回避策 1 - onError ハンドラーを実装する:

const { messages, append, reload } = useChat({
  api: '/api/chat',
  onError: (error) => {
    if (error.message.includes('stream') || error.message.includes('aborted')) {
      // Attempt to reload last message
      reload();
    }
  },
});

回避策 2 - 表示状態の変更を検出する:

useEffect(() => {
  const handleVisibilityChange = () => {
    if (document.visibilityState === 'visible') {
      // Check if stream was interrupted
      const lastMessage = messages[messages.length - 1];
      if (lastMessage?.role === 'assistant' && !lastMessage.content) {
        reload();
      }
    }
  };

  document.addEventListener('visibilitychange', handleVisibilityChange);
  return () => document.removeEventListener('visibilitychange', handleVisibilityChange);
}, [messages, reload]);

ステータス:既知の制限事項。自動再接続機能は組み込まれていません


このスキルを使用する場面

次の場合は ai-sdk-core を使用してください:
  • バックエンドの AI 機能(サーバーサイドのテキスト生成)を構築する
  • サーバーサイドのテキスト生成を実装する(Node.js、Workers、Next.js)
  • 構造化された AI 出力(JSON、フォーム、データ抽出)を作成する
  • ツールを使う AI エージェントを構築する(複数ステップのワークフロー)
  • 複数の AI プロバイダー(OpenAI、Anthropic、Google、Cloudflare)を統合する
  • AI SDK v4 から v5 に移行する
  • AI SDK のエラー(AI_APICallError、AI_NoObjectGeneratedError など)が発生している
  • Cloudflare Workers で AI を使用する(workers-ai-provider を使用)
  • Next.js Server Components/Actions で AI を使用する
  • 異なる LLM プロバイダー間で一貫した API が必要である
次の場合はこのスキルを使用しないでください:
  • React チャット UI を構築する(代わりに ai-sdk-ui スキルを使用してください)
  • useChat などのフロントエンドフックが必要である(代わりに ai-sdk-ui スキルを使用してください)
  • エンベディングや画像生成などの高度なトピックが必要である(公式ドキュメントを確認してください)
  • マルチプロバイダーを使わずに Cloudflare Workers AI のネイティブアプリを構築する(代わりに cloudflare-workers-ai スキルを使用してください)
  • Generative UI / RSC が必要である(https://ai-sdk.dev/docs/ai-sdk-rsc を参照してください)

バージョン

AI SDK:

  • 安定版:[email protected](2026 年 1 月)
  • ⚠️ v6.0.40 は使用しないでください - ストリーミングに互換性のない変更があります(v6.0.41 で取り消されました)
  • レガシー v5:[email protected](ai-v5 タグ)
  • Zod 3.x/4.x の両方をサポート

最新モデル(2026 年):

  • OpenAI:GPT-5.2、GPT-5.1、GPT-5、o3、o3-mini、o4-mini
  • Anthropic:Claude Sonnet 4.5、Opus 4.1、Haiku 4.5
  • Google:Gemini 2.5 Pro/Flash/Lite

最新情報を確認する:

npm view ai version
npm view ai dist-tags

公式ドキュメント

コア:

マルチモーダル:

GitHub:


最終更新日: 2026-01-20 スキルバージョン: 2.1.0 変更点: 新しいエラーを3件追加(Gemini のキャッシュ、Anthropic のツールエラー、ツール結果の配置)、MCP のセキュリティガイダンス、ツール承認のベストプラクティス、React フックのエッジケース、ストリーム再開の回避策 AI SDK: 6.0.26 安定版(v6.0.40 は避けてください)

コメント