こんにちは。
AI 事業本部 AI クリエイティブカンパニー BPO 事業部のエンジニアの佐藤 (@Rintarooo) です。
KAT-TUN サブスク解禁ということで、KAT-TUN を見習って『ギリギリでいつも生きていたい』をどうにかして実践していきたい所存です。

はじめに

TypeScript 製の AI エージェントフレームワークである Mastra を、バックエンド API と AI エージェントの両方を担う単一のサーバーとして本番運用しています。
Mastra は比較的新しいフレームワークで、本番運用の事例がまだ少ないのが現状です。
そこで本記事では、Mastra をモノリシックなサーバーとして開発した背景や運用を通して得られた知見を共有します。

なぜ Mastra か

プロダクトの立ち上げ・PoC フェーズで、ユーザーの嗜好やデータベースの情報に基づいて回答する高度なチャット機能をアプリの必須機能として要件に固め、AIエージェントフレームワークを検討することにしました。
静的型付け言語で型安全性があり、開発チームや個人としても慣れ親しんでいる Go または TypeScript で検討しました。
しかし当時、Go で実装されたAIエージェントフレームワークである Google の Agent Development Kit (ADK) for Go はまだ GA として提供されておらず、TypeScript 製の Mastra を選びました。
Mastra は Vercel AI SDK をベースに構築されており、複数の LLM プロバイダー(Anthropic、Google 等)を統一インターフェースで扱える点も魅力でした。
加えて、Mastra は Hono ベースの HTTP サーバーとしても動作するため、AI エージェントと API サーバーを単一のサーバーで提供できます。

バックエンド + AI エージェントの構成

なぜ単一サーバーにしたか

バックエンド API と AI エージェント処理を分離せず、モノリスとして開発を進めました。
小規模チームで開発スピードを優先するため、インフラ管理・デプロイをシンプルにして、サービス間通信が発生しない構成を選びました。

Tool 実装におけるリポジトリ/サービスの再利用

Mastra をはじめとする多くの AI エージェントフレームワークでは、DB 検索や外部 API 呼び出しを「Tool」として定義し、AI エージェントがそれらを自律的に判断して選択・実行できます。
本プロダクトでは、アプリケーション全体に4層のクリーンアーキテクチャを採用しており、モノリスの構成を活かしてバックエンド API 向けに実装した Domain 層で抽象化されたリポジトリ/サービスを Tool の実装でそのまま再利用しています。これにより、コード重複を排除し保守性とテスタビリティの向上を図っています。
agent-tool-domain

AI エージェントの可観測性

AI エージェントの処理は、LLM 呼び出しや Tool 実行など多段階にわたるため、ボトルネックの特定が困難です。「どの Tool の呼び出しに時間がかかっているのか」といった把握が開発・運用していく上で不可欠でした。
Mastra は OpenTelemetry 準拠のため、様々な可観測性ツールとシームレスに統合できます。中でも LLM 特化の可観測性ツールとして記事が多く参考にしやすい Langfuse を本番環境で利用することにしました。

Mastra Studio

Mastra は ローカル環境でも利用可能な Mastra Studio を提供しています。エージェントやワークフローの状態を可視化できるインタラクティブな GUI で、ワークフローの各ステップの実行時間やトレース情報をリアルタイムに確認できます。ローカルで手軽にエージェントの挙動を把握できるため、デバッグがしやすいです。
mastra-studio

Langfuse

Langfuse は、OSS とクラウド版の2種類が提供されています。クラウド版は AWS 基盤で提供されており、本稿執筆時点ではデータセンターが米国・EU リージョンのみのため、データが国外に送信されてしまいます。これを回避するため、OSS 版を GKE Autopilot 上にセルフホストしました。GKE Autopilot 上への構築には、Helm chart を用いた Langfuse 公式の Terraform GCP リポジトリを参考に Terraform で実装しました。
Mastra への統合も簡単で、Langfuse にトレースを送信する Exporter を提供しており、数行のコード追加でトレースの自動生成・送信が実現できました。
以下は、実際の Langfuse の画面キャプチャです。

langfuse

エージェントがネストして呼び出した Tool も、トレースツリーで構造的に可視化されます。また、会話の流れをスレッド単位で追跡できるほか、入出力・消費したトークン数やコストといった詳細情報も確認できます。

プロンプトをコードと分離

昨今、Claude Code をはじめとするコーディング AI を活用した開発が一般的になりつつあります。一方、コーディング AI がプロンプトとロジックを一度に編集してしまうことで、「エージェントの挙動が変わったのが、プロンプトの修正なのかロジックの変更によるものなのか」わからなくなってしまうことがありました。

また、プロンプトを 1 行変えるだけの微調整でも PR を作成してデプロイする必要があり、 手軽に調整できないもどかしさを感じてました。ほかに、PM からどんなプロンプトで動いているのか聞かれることもありました。

そこで、プロンプトは GitHub で管理しているコードと切り離し、Langfuse で管理しています。これにより、プロンプトの変更はアプリケーションのデプロイサイクルとは独立して即座に反映でき、変更の影響範囲が明確になります。また、プロンプトはバージョン管理されているため、変更前の状態にいつでも戻すことができ、安全にプロンプトの調整ができます。さらに、プロンプトにラベルを付与できるので、どのプロンプトがどの環境に反映されているかも一元管理でき、PM もプロンプトを確認しやすくなるというメリットもありました。加えて、Langfuse 公式が提供する MCP を介して、コーディング AI からもプロンプトの編集ができます。

おわりに

本記事では、Mastraを バックエンド API と AI エージェントのモノリシックなサーバーとしての開発・本番運用事例を紹介しました。
Mastra はバージョンアップが頻繁に行われるため、破壊的変更にキャッチアップしながら対応する必要があります。一方、エージェントの挙動を手軽に可視化・追跡できる開発体験の良さも感じています。
本記事の内容が、見てくださった方の AI エージェントを活用したプロダクト開発・運用や今後の設計や技術選定の参考になれば幸いです。