生成AIのAPIを使ってWebアプリにAI機能の試作検証してみた
OpenAI や Gemini の API は前から知ってはいたものの、実際に使う機会はなかなかありませんでした。
本記事では、生成AIを使って「売上レポートを自動生成する」機能を、NestJS + React 構成で試作した実装例を紹介します。
APIの使い方やプロンプトの組み立て方など、「実際に動かして理解する」ことを目的にした内容です。
最初は OpenAI API を試していたのですが、無料枠を使い切ってしまったため、途中から Gemini API に切り替えています。
実装したサンプルは、OpenAI API と Gemini API のどちらでも動くように分岐できるようにしています。
OpenAI 側はまだ十分に検証できていない部分もあるので、別のタイミングで確認予定です。
開発環境
- フロントエンド: React + TypeScript + Vite
- バックエンド: NestJS
- AI API: OpenAI / Google Gemini(@google/genai)
- 言語: TypeScript
- 実行時間: 約2時間(試作ベース)
AIレポート機能を作ってみた
既存のデータをもとに、生成 AI の API を経由して自動でレポートを生成する仕組みを試作しました。
「実際にどんな実装で動かせるのか?」を勉強ついでに触ってみた形です。
アーキテクチャ全体はざっくり考えつつも、実装はバイブコーディングで試行錯誤しながら進め、約2時間ほどで形になるところまで作ることができました。
よくある「予測分析レポート」を自動で作成するようなアプリケーションのミニ版です。
社内の Analytics やログなど、溜まっている大量のデータをもとに AI がレポートを生成することで、営業支援ツールや経営支援ツールのような仕組みも、比較的少ない工数で実装できると感じています。
プロトタイプ段階で価値検証するには、かなり良い題材だと思います。
リポジトリ
以下が、今回試作として作成したリポジトリになります。
レポート生成の流れ
今回の試作品では、「売上予測レポート」をテーマにしました。
DB に蓄積された売上データを元に AI がレポートを生成する、というシンプルな機能です。
現段階ではフロント側でモックデータを用意し(本来は DB から取得する想定)、NestJS 経由で生成 AI にレポート作成を依頼しています。
実際の流れ
実際のアプリケーションでは、最初にユーザーがレポートしたい月の範囲に指定して売上データを取得します。
その範囲に応じて DB から対象データを取得し、そのデータを generateReport
関数を通して生成 AI に渡します。
AI は受け取ったデータをもとにレポートを作成し、フロントエンドに結果を返す――という流れを想定しています。
// レポートボタンを実行
const handleGenerate = () => {
// ダミーデータ(実際はDBから取得する想定)
generateReport({
salesData: [
{ date: '2024-06-01', value: 100000 },
{ date: '2024-07-01', value: 120000 },
{ date: '2024-08-01', value: 155000 },
{ date: '2024-09-01', value: 5125000 },
{ date: '2024-10-01', value: 5030000 },
{ date: '2024-11-01', value: 5030000 },
{ date: '2024-12-01', value: 5030000 },
{ date: '2025-01-01', value: 5030000 },
{ date: '2025-02-01', value: 5030000 },
{ date: '2025-03-01', value: 5030000 },
{ date: '2025-04-01', value: 5030000 },
{ date: '2025-05-01', value: 5030000 },
{ date: '2025-06-01', value: 5530000 },
{ date: '2025-07-01', value: 5080000 },
{ date: '2025-08-01', value: 5030000 },
{ date: '2025-09-01', value: 5530000 },
],
forecastData: [{ date: '2025-10-01', expected: 7030000 }],
monthsAhead: 3,
reportType: 'sales',
});
};
生成 AI を 分析・レポーティングの補助
に使うパターンは、実務でも応用範囲が広いです。
今回のように、まずはダミーデータで流れをつかんでおくと、後でリアルデータと接続する際もスムーズに実装できます。
受け取った情報をバックエンドが生成AIに渡す
フロントエンドから受け取った売上データやレポート条件(monthsAhead
や reportType
)を、NestJS のサービスクラスで処理しています。
この ReportsService
では、利用するAIプロバイダ(OpenAI / Gemini / Mock)を切り替えられるようにしており、APIキーや環境変数を設定して使い分けることができます。
AIレポート生成のデータフロー図
実際にフロントからバックエンドをデータ通してAIレポートを生成する流れになります。
フロントエンドで入力(またはモックデータ)を生成し、NestJS バックエンドを経由して生成AIにレポートを依頼します。
返ってきた結果を整形して、フロントエンドで表示・グラフ化する構成です。
Mockについて、実際の画面がどのようなUIで確認が取れるようにしておきました。
このダミーデータがあることで、不要な生成AIの実行回数を減らしながらUIの調整が行えます。
コードの解説
実際に生成して返すロジックは、 /services/src/reports/reports.service.ts
にまとめるようにしました。
複数のAIプロバイダを統一インタフェースで扱う
import OpenAI from 'openai';
import { GoogleGenAI } from '@google/genai';
type AIProvider = 'openai' | 'gemini' | 'mock';
private aiProvider: AIProvider = (process.env.AI_PROVIDER as AIProvider) || 'mock';
複数のAIプロバイダを統一インタフェースで扱えるように .env
で AI_PROVIDER=openai
のように指定するようにして、簡単に切り替えが可能です。
検証時は mock
モードにして動作確認だけ行うこともできます。
OpenAIの呼び出し部分
import OpenAI from 'openai';
@Injectable()
export class ReportsService {
private openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
}
// ..他のコード...
const completion = await this.openai.chat.completions.create({
model: 'gpt-4o-mini',
messages: [{ role: 'user', content: prompt }],
response_format: { type: 'json_object' },
});
OpenAI APIでは response_format: { type: 'json_object' }
を指定して、JSON構造で結果を返すようにしています。
レポートの整形やパース処理がシンプルになります。
OpenAI Platform のAPIリファレンスがあるため、どのような結果が返ってきて、どのような情報で返したいのか確認することができます。
Gemini APIの呼び出し部分
公式のドキュメントを参考にしました。
const response = await this.gemini.models.generateContent({
model: "gemini-2.0-flash",
contents
});
Geminiの場合は @google/genai
パッケージを使用し、テキストとして返されるレスポンスを正規表現でJSON抽出しています。
公式のリファレンスを参考に型情報などを参照することができます。
生成AIへ渡すプロンプト
生成 AI に渡すプロンプトは、以下のような形式にしています。
messages: [{ role: 'user', content: prompt }]
の content
に組み立てた文字列を渡す形です。
売上データや受注見込みデータを取得し、それらを JSON.stringify()
で文字列化してプロンプト内に埋め込みます。
const prompt = `
あなたは経営レポートを生成するAIです。
以下のデータをもとに今後${dto.monthsAhead}ヶ月の売上を予測し、
重要なトレンドと要因を簡潔に説明してください。
### 売上データ
${JSON.stringify(dto.salesData, null, 2)}
### 受注見込みデータ
${JSON.stringify(dto.forecastData, null, 2)}
出力フォーマットは以下の形式で返してください:
{
"summary": string,
"insights": string[],
"predictedValues": [{ "month": string, "value": number }]
}
`;
プロンプト内で出力フォーマットを明示することで、AI から返ってくる JSON の構造を安定させやすくしています。
/reports/ai
のリクエストボディとレスポンス
POST フロントエンドでは、生成したデータをバックエンドへ送信し、
AI から返ってきたレポート結果を受け取って画面に反映する構成にしています。
リクエストボディ
試作ではダミーデータを使用していますが、実際には DB から取得した売上データを以下のような形でバックエンドへ送ります。
{
"salesData": [
{ "date": "2025-06-01", "value": 100000 },
{ "date": "2025-07-01", "value": 120000 },
{ "date": "2025-08-01", "value": 125000 }
],
"forecastData": [
{ "date": "2025-09-01", "expected": 130000 }
],
"monthsAhead": 3,
"reportType": "sales"
}
レスポンス
生成 AI によって summary
(要約)と insights
(示唆)が生成され、バックエンドではそれに predictedValues
(予測値)を結合して返却します。
フロントエンドではグラフ描画などに活用できるようになります。
{
"summary": "売上は順調に成長しています...",
"insights": [
"前月比5%の成長を維持",
"季節要因により9月は好調が見込まれる"
],
"predictedValues": [
{ "month": "2025-09", "value": 135000 },
{ "month": "2025-10", "value": 140000 },
{ "month": "2025-11", "value": 145000 }
]
}
実行結果
実際にGeminiが生成したレポートの一例です。
# 実行結果
## 📝 概要
過去の売上データに基づき、今後の3ヶ月の売上を予測しました。直近の売上高と、特異な売上増加が見られる期間、および受注見込みデータを考慮し、堅調な売上を予測しています。
## 💡 インサイト
- 2024年6月から8月にかけて売上が増加傾向にあります。
- 2024年9月から2025年5月にかけて売上が急増し、その後安定しています。
- 2025年6月と9月には、他の月と比較して売上が増加しています。これらの要因を分析する必要があります。
- 受注見込みデータに基づき、2025年10月には大幅な売上増加が見込まれます。
## 📈 予測グラフ
実装PR
今回は、開発環境を整えたうえで AIレポート生成機能 を実装した差分になります。
対象は「売上予測」レポートのみですが、必要なデータ量が少なかったこともあり、実装はおよそ10ファイル前後で完結しました。
データの出力やグラフ表示など、最低限のレポート表示機能を追加しただけの構成ですが、生成AIとのAPI連携は思っていたよりもシンプルに組み込めました。
NestJS でのバックエンド連携からフロント側での描画まで、全体の流れを確認できる良い試作になったと思います。
細かなレポート分析やUI表現を詰めていくには、もう少し工夫が必要そうですが、 「AIを使って既存データから自動レポートを作る」 という体験を短時間で形にできたのはかなり良い手応えでした。
まとめ
今回の試作では、OpenAI と Gemini の両方の API を実際に動かしながら、既存データを使ったレポート生成の仕組みを短時間で構築できました。
特に印象的だったのは、生成AIを「文章生成」ではなく「分析支援」 として組み込むときの設計のしやすさでした。
プロンプトを工夫するだけで、構造化されたレポートを安定して生成できるのは非常に強力だと感じたので、工夫すると色々なアイディアで実装ができそうです。
今回は基本となる部分をまとめてみました。プロダクトで活用するときの参考としてなればと思います。
Discussion