>_tech-draft
Mastra AIのアイコン
Mastra AI
動画公開日
タイトル

Building Type-safe AI Applications - Nico Albanese, Vercel

再生時間

15分 47秒

AI SDKで実現するエンドツーエンド型安全なAIアプリケーション開発ガイド

ポイント

  • AIエージェントをエンドユーザー向けのWebアプリケーションとして構築する際、型安全かつ保守性を保つための課題と重要性を解説します。
  • エージェントのツール呼び出しをUIに反映する方法や、ツール名・スキーマ変更による開発の保守性・型安全性の課題を具体的に示します。
  • AI SDKを用いることで、エージェントを型情報の「真のソース」とし、効率的で堅牢なエンドツーエンドのAIアプリケーション開発を実現する道筋を提示します。

AI SDKで実現するエンドツーエンド型安全なAIアプリケーション開発ガイドAIエージェントの構築は素晴らしい成果ですが、それをエンドユーザーに届けることはまた別の課題です。本記事では、AI SDKを活用して、エージェントを基盤としたエンドツーエンドで型安全なアプリケーションを構築する方法を、具体的な課題と解決策を交えながら詳しく解説します。

導入: AIエージェントと型安全なアプリケーション開発の重要性

AIエージェントの開発が進むにつれて、「このエージェントをどのように共有し、他の人が利用できるようにするか?」という問いが浮上します。単にコードをGitHubにプッシュするだけでは不十分であり、ユーザーフレンドリーなWebインターフェースを通じて提供するのが最も効果的な方法です。

私たちは、アプリケーション開発において「まず動くものを作る(make it work)」ことから始め、次に「保守可能な状態にする(make it maintainable)」、そして最終的に「魅力的な体験を提供する(make it delightful)」という三段階のアプローチを提唱します。本記事では特に「保守可能」な状態に焦点を当て、AI SDKが提供する型安全な開発手法について掘り下げていきます。

AI SDKは、AIエージェントとアプリケーションを構築するためのTypeScriptツールキットであり、その柔軟性と強力な機能によって、開発者は効率的に作業を進めることができます。

AI SDKと「Social Agent」の紹介

AI SDKは、AIを活用したアプリケーション開発を加速させる強力なTypeScriptツールキットです。本記事では、そのアプリケーション側の側面に焦点を当てて解説を進めます。

本記事のデモンストレーションとして、筆者が実際に運用している「Social Agent」を紹介します。このエージェントは、日々の開発プロセスにおける特定の課題を解決するために作られました。それは、GitHubのプルリクエスト(PR)から、チームのブランドボイスとフォーマットに沿ったX(旧Twitter)スレッドを自動生成するというものです。これにより、新機能のリリース情報を効率的に周知できるようになります。

Social Agentは、AI SDK 6で導入された新しいエージェント抽象化を用いて構築されており、人間が利用する様々なツールと連携して動作します。

エージェントをWebアプリケーションにするための基礎構築

構築したエージェントをWebアプリケーションとして公開するために、まずは基本的なアーキテクチャを理解し、実装を進めていきましょう。WebアプリケーションのフレームワークとしてはNext.jsを使用しますが、AI SDK UIパッケージは、React、Vue、Svelte、Angularといった主要なフレームワークを公式サポートしており、コミュニティによってSolidJSパッケージも提供されているため、高い拡張性を持っています。

アプリケーションの構成

筆者のアプリケーションでは、Social Agentをagentディレクトリに配置し、使用するツール群はそれぞれを個別のファイルに分離してtoolディレクトリに整理しています。これにより、コードの可読性と保守性が向上します。

バックエンド (API Route Handler) の実装

Webアプリケーションからエージェントと連携するためには、APIエンドポイントが必要です。Next.jsのAPI Route Handlerを利用して、/api/chatへのPOSTリクエストを処理するエンドポイントを作成します。

このハンドラーは以下の処理を行います。

  1. リクエストボディからメッセージ(messages)を取得します。
  2. 取得したメッセージを使ってエージェントを呼び出します。
  3. エージェントからの応答をストリーミングレスポンスとして返します。

フロントエンド (useChat Hook) の実装

次に、ユーザーがエージェントと対話するためのフロントエンドを構築します。ここではAI SDKが提供するuseChatフックが中心的な役割を果たします。

useChatフックの主な機能は以下の通りです。

  • メッセージストア: 送受信されるメッセージはmessages変数に保存され、UIでのレンダリングに利用されます。
  • UIレンダリング: 保存されたメッセージをマップし、UIに表示します。例えば、テキスト部分は<p>タグでレンダリングできます。
  • エラーハンドリング: 生成プロセス中に発生する可能性のあるエラーを解析し、シンプルな方法でエラー状態を処理できます。
  • メッセージ送信: sendMessage関数を提供し、ユーザーからの入力をエンドポイントに送信し、その応答を処理します。これは、フォームのonSubmitハンドラーに紐付けて使用します。

これらの機能を組み合わせることで、基本的なチャットインターフェースが構築され、ユーザーはエージェントと対話できるようになります。

ツール呼び出しのUI表現とその課題

エージェントが動作し、基本的なチャットインターフェースが完成したところで、さらなる課題に直面します。それは、エージェントが内部でツールを呼び出した際のUI表現です。

初期の問題: ツール呼び出しの非表示

ブラウザでアプリケーションを起動し、エージェントにメッセージを送ると、一見するとUIが固まっているように見えることがあります。実際にはエージェントはバックエンドで正常に動作し、ツールを呼び出しているのですが、フロントエンド側でそのツール呼び出しが適切にレンダリングされていないため、ユーザーには何も変化がないように見えてしまうのです。

この問題を解決するためには、メッセージのレンダリング部分を修正し、part.typetool_callである場合に、そのツールの名前を表示するようにします。これにより、エージェントがどのツールを呼び出しているかをユーザーが視覚的に確認できるようになり、エージェントが正常に機能していることを示せます。

さらなるUIのカスタマイズ: ツールに応じたコンポーネントレンダリング

ツール呼び出しの名前を表示するだけでなく、特定のツールに対して独自のUIコンポーネントをレンダリングしたいと考えるのが自然な次のステップです。

AI SDKのメッセージパートの型定義を見ると、ツールはtool-[ツール名]という命名規則に従っていることがわかります。例えば、fetch-pull-requestというツールが呼び出された場合、tool-fetch-pull-requestというpart.typeが生成されます。これを利用して、特定のツール名に合わせた条件分岐を追加し、任意のマークアップをレンダリングできます。

例えば、fetch-pull-requestツールが呼び出された際には、GitHubのロゴとリポジトリ名、プルリクエスト番号を表示するようなカスタムコンポーネントを実装することが可能です。これにより、よりリッチで情報豊富なユーザー体験を提供できます。

開発の保守性と型安全性の課題

ツールに応じたカスタムUIのレンダリングは魅力的ですが、このアプローチにはいくつかの深刻な課題が潜んでいます。特に、開発の保守性と型安全性に大きな影響を与えます。

課題1: ツール名のハードコーディングとオートコンプリートの欠如

現在の方法では、ツール名をtool-[ツール名]のように文字列としてハードコーディングしています。このアプローチには以下の問題があります。

  • 破損のリスク: エージェント定義内でツールの名前が変更された場合、フロントエンドのUIは対応できず、壊れてしまいます。
  • 開発体験の悪化: case文などでツール名を記述する際に、エディタのオートコンプリート機能が効かないため、タイプミスや既存のツール名の確認に手間がかかります。

課題2: ツール入出力スキーマの変更とバージョン管理の困難さ

さらに大きな問題は、ツールの入出力スキーマの変更に伴う開発プロセスです。モデルが生成すべき入力や、ツールが返す出力のスキーマを変更する際、フロントエンド側でその変更を正確に把握し、対応する型定義やロジックを更新するのは非常に骨の折れる作業です。しばしば、スキーマの不一致によるランタイムエラーが発生し、デバッグに多くの時間を費やすことになります。

このような状況は、複数の開発者が関わる大規模なプロジェクトにおいて、バージョン間のスキーマのずれを引き起こし、「保守可能」な状態を維持することを極めて困難にします。

理想的な状態

理想的なシナリオは、「ツールを更新すれば、フロントエンドが自動的にその変更を認識し、適切な型情報に基づいて更新される」という状態です。つまり、エージェント自体が、それを消費するすべての型の「真のソース(Source of Truth)」となるべきです。

AI SDKによるエンドツーエンドの型安全な解決策 (導入)

幸いなことに、AI SDKはこの理想的な状態を実現するための仕組みを提供しています。ただし、そのためにはいくつかのセットアップが必要です。

解決策の出発点となるのは、AI SDKにおけるアプリケーションの最小単位のステートである「メッセージ」、特にUI messageです。UI messageはジェネリック型として設計されており、これを利用することで、アプリケーション固有のカスタム型を作成し、エンドツーエンドの型安全性を確立することが可能になります。


まとめ

本記事では、AI SDKを用いてエンドツーエンドで型安全なAIアプリケーションを構築するための道のりを探りました。エージェントをWebアプリケーションとして公開するための基礎構築から始まり、ツール呼び出しのUI表現における初期の課題と、それを解決するためのアプローチについて解説しました。そして、ハードコーディングやスキーマの不一致が引き起こす保守性の問題を明確にし、AI SDKのUI messageが提供するジェネリックな型システムが、これらの課題を根本的に解決する鍵となることを示しました。

AI SDKを活用することで、開発者はより堅牢で保守性の高いAIアプリケーションを効率的に構築できるようになります。このフレームワークの持つ強力な型システムを最大限に活用し、より信頼性の高いAIプロダクトを共に作り上げていきましょう。

参考動画

Building End-to-End Type-Safe Applications on Top of Your AI Agents with AI SDK