← 戻る ノートパソコンの上に手書きされたコード メモ。木製デスク上、柔らかい曇りの光とエスプレッソ カップ付き

Vercel AI SDK in Practice: スマートに出荷する、無理をしない

ツール

2023 年後半、フィンテック系のクライアントから電話がありました。パニック状態で、彼の開発チームが OpenAI の API 上にストリーミング チャット インターフェイスを構築するのに 6 週間を費やしていて、それでも iOS Safari でうまく動作していなかったのです。競合状態。トークン チャンキングの問題。UI が応答の途中でフリーズします。6 週間です。私は彼らのコードベースを見ました。そしてそれはまさにあなたが予想するもそのもの。自作の ReadableStream 実装、ストリーミング トークン用のカスタム状態管理レイヤー、3 年前の Stack Overflow の回答からコピーされたリトライ ロジック。それはテープで一緒に保持されていました。

私は Vercel AI SDK を使ってその中核を約 2 日間で書き直しました。ストリーミングが動きました。iOS Safari が動きました。クライアントからの電話が来なくなりました。

これは宣伝ではありません。これはただ起きたことです。だから、この SDK が実際に何をするのか、どこで時間を本当に節約できるのか、そしてどこでまだ壁にぶつかるのかを説明したいのです。

Vercel AI SDK が実際に何であるか

「Vercel AI SDK」と聞くと、Vercel インフラに限定されていると考える人もいます。違います。Node.js サーバー上の任意の場所(自分の VPS、Railway、Render など)で実行できます。実際のところ、それは TypeScript ライブラリで、LLM を搭載した機能を Web アプリに構築する際の最も厄介な部分を抽象化します。

メインで使う2つのパッケージがあります。ai はコアランタイムです。@ai-sdk/openai(または @ai-sdk/anthropic、@ai-sdk/google など)がプロバイダアダプターです。SDKは統一されたインターフェースを使うため、GPT-4o から Claude 3.5 Sonnet に切り替えることは、ほとんどの場合本当に1行の変更です。私は検証済みです。確実に動きます。

コアプリミティブ

SDKの核となる3つのものがあります:

  • streamText は、テキスト応答をトークンごとにストリーミングします。チャットインターフェース向けです。
  • generateText は、フル応答を待ちます。バックグラウンドジョブや、ストリーミングUXが不要な場合に適しています。
  • generateObject は、Zodスキーマに対して検証された構造化JSON を返します。ここが本当に面白くなるところです。

streamText がほとんどの人が最初に欲しいものです。ReadableStream の配管、エンコーディング、チャンキングを処理します。私が言及した6週間のフィンテック悪夢? それはまさに streamText が初日に解決したはずのものです。

頭を抱える前にセットアップする

Next.js 14または15 でApp Router を使っていると仮定すると(2025年にこれを読んでいるなら、おそらくそうでしょう)、セットアップは本当に素早いです。

  1. パッケージをインストール: npm install ai @ai-sdk/openai
  2. app/api/chat/route.ts にルートハンドラーを作成します
  3. streamText とプロバイダーをインポートし、モデルとメッセージを渡して、結果を StreamingTextResponse として返します
  4. クライアント側では、ai/react パッケージの useChat フックを使用します

これで完了です。Next.js をそこそこ理解していれば、1 時間以内に機能するストリーミングチャットが完成します。useChat フックはメッセージ配列、ローディング状態、入力フィールドのバインディング、ストリーミング更新を管理するため、それらを自分で書く必要がありません。

本番環境のセットアップに即座に追加すべきもの:適切なシステムプロンプト、レート制限(私は Upstash を使用しており、彼らの Redis ベースのレート制限は Edge Functions との相性が良好です)、そしてある種のトークン使用量ログです。SDK は応答オブジェクトの使用量データを公開しているため、追加の API 呼び出しなしにプロンプトトークンと完了トークンをデータベースにログできます。

generateObject は見落としている機能です

正直な意見:streamText はすべての注目を集めていますが、generateObject こそが私の AI 機能アーキテクチャの設計方法を変えた機能です。

考え方は簡単です。Zod スキーマを定義し、それを generateObject に渡すと、SDK はモデルに対してスキーマに準拠した JSON を返すよう指示します。解析して祈る必要がある文字列ではなく、型付けされたオブジェクトが返されます。

Seahawk は昨年、物件管理会社向けのプロジェクトを手掛けました。彼らはアップロードされたリース契約書から構造化されたデータを抽出したかったのです。テナント名、賃貸料、解約特約、更新日。従来のアプローチなら:モデルにプロンプトを入れ、テキストを得て、正規表現パーサーを書いて、泣きます。generateObject では、Zod で LeaseSchema を定義し、モデルが毎回きれいな型付けデータを返しました。1 週間以内に抽出されたリース契約を Postgres テーブルにプッシュしていました。

人々がつまずくポイント:すべてのモデルが構造化出力を同じように適切にサポートしているわけではありません。GPT-4o と Claude 3.5 Sonnet は確実に対応しています。小さいモデルや古いモデルの中には、フィールドを幻覚させたり、スキーマを完全に無視したりするものもあります。少なくともユースケースを検証するまでは、フラグシップモデルに固執してください。

ツール呼び出し:真の力が宿る場所

generateObjectが過小評価されているなら、ツール呼び出しは積極的に誤解されている。ほとんどの開発者は「ツール呼び出し」とはAIがインターネットを閲覧したり、コードを実行したりできることだと考えている。時にはそうだ。しかし実際には、ツールはあなたが定義した関数に過ぎず、モデルが応答中に呼び出すことを選択できるだけだ。

どう考えるべきか

SaaSプロダクト向けのサポートボットを構築しているとしよう。ユーザーが「現在のサブスクリプションプランは何ですか?」と尋ねる。モデルはそれを知ることができない。しかしあなたはgetUserSubscriptionツールを定義できます。このツールはユーザーIDを受け取り、データベースからプランデータを返します。モデルは意図を認識し、ツールを呼び出し、データを受け取り、それを応答に組み込みます。ユーザーは一貫性のある回答を見るだけです。

SDKのtools パラメータはstreamText とgenerateText で利用でき、オブジェクトを受け取ります。各キーはツール名で、各値にはdescription (モデルが呼び出すタイミングを決めるのに使う)、parameters スキーマ(これもZod)、およびexecute 関数があります。execute 関数はサーバー側で安全に実行され、クライアントから離れています。

このやり方で複数ステップのエージェントを構築しました。SDKはmaxStepsをサポートしているので、モデルはツール呼び出しをチェーンし、1つのツールを呼び出し、その結果を使い、別のツールを呼び出し、すべてを合成して、応答することができます。これは魔法ではありません。ツールの説明とシステムプロンプトについて慎重に考える必要があります。しかし配線はすべてあなたのために処理されます。

ミドルウェア、ラッピング、およびパイプラインモデル

ドキュメントをもっと詳しく読むまで気づかなかったことの1つは、SDKにはミドルウェアの概念があり、実装特性のコードに触れずにモデル呼び出しをラップしてログ、キャッシング、またはカスタム動作を追加できるということです。

wrapLanguageModelはモデルとミドルウェアオブジェクトを受け取ります。リクエストがAPIに到達する前に割り込み、パラメータを修正し、レスポンスをキャッシュできます。パブリッシャー向けに構築したコンテンツ生成ツールでこれを使用しました。彼らのユースケースでは繰り返されるプロンプトが多くありました(同じ記事の要約が1日に複数回リクエストされる)。ミドルウェアレイヤーを使用してRedisでレスポンスをキャッシュしました。最初の月でコストは約35%削減されました。

これは通常、API呼び出しの外側に不器用に取り付けるようなことです。SDKでこれをファーストクラスの概念として持つことは、それが合成可能でテスト可能であることを意味します。

それが出来ないこと(自分に正直になろう)

よし。痛い目を見ないよう先に言っておこう。

このSDKはメモリや長期の会話履歴を管理してくれない。useChatはクライアント側の状態でメッセージ配列を保持するが、ユーザーがリフレッシュした瞬間にそれは消える。永続的な会話が必要なら、自分で構築する必要がある。メッセージストレージ用のPostgresやMongoDB、マウント時に取得してチャットをリハイドレートするロジック。そういったものは提供されていない。実はこれは正しい動作だ。SDKがあなたのデータレイヤーを所有すべきではない。だが新参者はよくそれを期待する。

また、複数形式の入力をネイティブに、複雑さをすべて隠蔽する形では処理しない。メッセージ配列に画像URLを渡すことはできるし、GPT-4oのようなモデルは問題なく処理するが、プレビュー、圧縮、ストレージを備えた適切な画像アップロードフローの構築はやはり自分の仕事だ。Next.jsを使っているときはUploadthingを使う。配線するのに30分くらいかかる。

RAG(retrieval-augmented generation)も含まれていない。ベクトル検索も、エンベディングパイプラインも、チャンキングロジックも組み込まれていない。そういったことにはPostgresのpgvectorか、Pineconeのような専用サービスを使う。SDKはLLMコールを処理する。その他の検索アーキテクチャは自分で構築する必要がある。

デプロイ:Vercel対その他すべて

そう、このSDKはVercelで最も良く動く。StreamingTextResponseはVercelのEdge Runtimeとそのまま動作し、Edge FunctionsのコールドスタートはサーバーレスNode.js関数よりもはるかに低い。チャット応答が遅く感じるなら、最初のトークンまでのレイテンシが重要で、Edgeがそれを削減する。

だが僕はRailway上(Node.js、Edge以外)でデプロイしたし、うまく動く。適切なストリーミングヘッダーを持つResponseを使うだけで、Vercel固有のヘルパーの代わりになり、SDKドキュメントでもそれを説明している。「Vercel AI SDK」という名前でロックインされていると思い込まないこと。

本気で勧めることが一つある。AIルートハンドラは薄く保つこと。データベースクエリ、認証チェック、LLMコールをすべて一つの関数に詰め込まない。ミドルウェア(SDKミドルウェアではなくNext.jsミドルウェア)がリクエストがAIルートに到達する前に認証を処理する。動きが速く、デバッグしやすくなる。

FAQ

Vercel AI SDKは无料で使用できますか?

SDK自体はオープンソースで無料です。費用が発生するのは基盤となるモデルAPI、つまりOpenAI、Anthropic、Google、どのプロバイダーを呼び出すかによって決まります。その費用はあなたが管理する必要があります。SDKはマークアップを追加しません。

OpenAI以外のモデルで使用できますか?

はい、これが本当の強みの一つです。Anthropic、Google(Gemini)、Mistral、Groq、Cohereなど、公式なアダプターがあります。コミュニティもローカルモデルを実行したい場合のOllamaアダプターを構築しています。統一されたインターフェースにより、プロバイダーを切り替える際にフィーチャーコードを変更する必要がありません。

React Server Componentsで動作しますか?

部分的です。generateTextとgenerateObjectはServer Componentsで問題なく実行できます。単なる非同期関数です。streamTextとuseChat hookはクライアント側の状態が必要なため、その部分はClient Componentに存在します。これは標準的なNext.jsアーキテクチャで、境界を理解していれば問題は発生しません。

APIがダウンした場合、エラーをどのように処理しますか?

SDKは型付きエラーをスローし、それをキャッチして処理できます。実際には、LLM呼び出しをtry/catchでラップし、ストリームエラーがUIに不完全なレスポンスとして波及するのを防ぐため、グレースフルなフォールバックメッセージを返すようにしています。SDKのエラー処理に関するドキュメントはエラータイプの詳細をカバーしており、本番環境に移行する前に読む価値があります。

トークンリミットの状況はどうなっていますか?

SDKはコンテキストウィンドウのリミットを管理しません。長時間実行される会話を構築していて、メッセージ履歴をトリミングしない場合、モデルのコンテキストウィンドウに到達してエラーが発生します。簡単な修正方法は、最後のNメッセージ(私は通常20個)とピンドされたシステムプロンプトを保持することです。ほとんどのチャットアプリケーションで十分です。

聞いてくれ、Vercel AI SDKは魔法の杖じゃない。つまるところ、本当に退屈な配管作業を上手に抽象化したものに過ぎない。ストリーミングを正しく処理する、型付きの構造化出力をくれる、ツール呼び出しを使いやすくする、複数のプロバイダーに対応する。AI機能の仕事の80%では、これが正しい出発点だ。

聞いてくれ、Vercel AI SDKは魔法の杖じゃない。つまるところ、本当に退屈な配管作業を上手に抽象化したものに過ぎない。ストリーミングを正しく処理する、型付きの構造化出力をくれる、ツール呼び出しを使いやすくする、複数のプロバイダーに対応する。AI機能の仕事の80%では、これが正しい出発点だ。

ちなみに、その金融系クライアントは、私がチャットを書き直してから2週間後にはもう本番運用を始めていた。モバイルのSafariでも問題なし。競合状態もなし。6週間が2日になった。時には適切な抽象化の価値は本当に大きいんだ。

関連記事:2026年のヘッドレスとWordPressのセキュリティ:Next.jsとAstr、ヘッドレス、Astroについて

← 戻る