はじめに
こんにちは、フトシ(AI侍 Xでは@samuraiai)です。
2025年11月6日、GoogleがGemini APIにFile Searchという強力な機能を追加しました。これは、開発者がインフラを意識することなく、簡単に高精度なRAG(検索拡張生成)システムを構築できるというものです。さらに、最新のGemini 2.5 Flash-Liteモデルを使うことで、従来の1.5モデルよりも低コスト・高速・高精度なRAGアプリケーションを実現できます。
この記事では、ReactとGemini APIを使って、ドキュメント検索用のWebアプリケーションを半日で構築する手順を、技術的なポイントに絞って解説します。
完成したデモのソースコードは、以下のリポジトリで公開しています。
また、本記事の内容は弊社(株式会社フィールフロウ)テックブログでも紹介しています。ビジネス寄りの内容に興味がある方は、こちらもご覧ください。
- FeelFlow Report: Gemini API File Search実装ガイド
File Searchはなぜ「ゲームチェンジャー」なのか?
従来のRAGシステム構築は、多くの開発者にとって茨の道でした。
- ベクトルDBの選定・構築: Pinecone, Chroma, pgvector...どれを選ぶ?
- チャンキング戦略: 固定長?再帰的?最適な分割方法は?
- 埋め込みモデルの管理: モデルのバージョン管理や更新が大変。
- 引用機能の実装: 回答の根拠を示すロジックを自前で組む必要がある。
File Searchは、これらの面倒な作業をすべてGoogle側でマネージドしてくれます。開発者はAPIを叩くだけで、最先端のRAGをアプリケーションに組み込めるようになりました。
| 項目 | 従来のRAG | File Search |
|---|---|---|
| ベクトルDB | 自前で構築・運用 | 完全マネージド |
| チャンク分割 | 独自実装が必要 | 自動処理 |
| 埋め込み生成 | モデル選定・管理 | Gemini Embeddingが自動 |
| 引用機能 | 独自実装 | 自動付与 |
| 初期コスト | 高(インフラ構築) | 低(API利用料のみ) |
まさに「RAGの民主化」と言えるでしょう。
Gemini 2.5 Flash-Liteのコスト優位性
本記事で使用するGemini 2.5 Flash-Liteは、Googleが提供する最小・最軽量モデルで、コスト重視のプロジェクトに最適です。
| モデル | Input ($/1M tokens) | Output ($/1M tokens) | 特徴 |
|---|---|---|---|
| Gemini 2.5 Flash-Lite | $0.10 | $0.40 | 最小コスト・高速・1Mトークンコンテキスト |
| Gemini 2.0 Flash-Lite | $0.075 | $0.30 | 従来の軽量モデル |
| Gemini 2.5 Flash | $0.30 | $1.20 | バランス型 |
さらに、File Search APIの価格も魅力的です:
- 初期インデックス作成: $0.15/1M tokens
- ストレージと検索時の埋め込み生成: 無料
つまり、一度インデックス化すれば、その後の検索・応答はモデル使用料のみで利用できます。
最小構成デモアプリの実装
今回は、以下の技術スタックでシンプルな文書検索アプリを構築します。
- フロントエンド: React 19.2.0
-
AI SDK:
@google/genai1.29.0 (最新の公式SDK) -
AIモデル:
gemini-2.5-flash-lite
注意: 従来の
@google/generative-aiパッケージは2025年8月31日にサポート終了予定です。本記事では最新の@google/genaiSDKを使用します。
プロジェクト構成
create-react-appで作成したシンプルな構成です。
gemini-file-search-demo/
├── src/
│ ├── App.js # メインコンポーネント
│ ├── App.css # スタイリング
│ └── index.js
├── public/
├── sample_product_spec.txt # 検索対象のサンプルファイル
└── package.json
コアロジック (src/App.js)
App.jsに実装するコア機能は主に2つです。
- ファイルをフロントエンドで読み込み、Base64エンコードする処理
- ファイルデータと質問をGemini APIに送信する処理
今回はシンプル化のため、ファイルをアップロードするたびにクライアントサイドでデータを保持する「インラインデータ方式」を採用します。
1. ファイルのハンドリング
FileReader を使ってファイルを読み込み、stateに保持します。ポイントは、Gemini APIが要求する inlineData オブジェクトの形式に整形する部分です。
// ... ReactのuseStateなどをimport
const App = () => {
// ... state定義 (apiKey, file, query, response, loading, error)
const handleFileChange = (e) => {
setFile(e.target.files[0]);
};
const handleFileUpload = async () => {
if (!file) {
setError('ファイルを選択してください');
return;
}
setLoading(true);
setError('');
// FileReaderでファイルを読み込み、Base64に変換
const reader = new FileReader();
reader.onload = (e) => {
const fileData = {
inlineData: {
data: e.target.result.split(',')[1], // "data:mime/type;base64," の部分を除去
mimeType: file.type,
},
};
// 整形したデータをstateに保存
setUploadedFile({
name: file.name,
data: fileData,
});
setResponse(`ファイル「${file.name}」を読み込みました。質問をどうぞ。`);
setLoading(false);
};
reader.onerror = (err) => {
setError('ファイル読み込みに失敗: ' + err.message);
setLoading(false);
};
reader.readAsDataURL(file);
};
// ...
};
2. Gemini APIへの問い合わせ
最新の @google/genai SDKを使い、generateContent メソッドを呼び出します。質問とファイルデータを含む contents を渡すだけです。
// ...
import { GoogleGenAI } from '@google/genai';
const handleQuery = async () => {
if (!apiKey || !uploadedFile || !query) {
setError('APIキーを設定し、ファイルをアップロードしてから質問してください');
return;
}
setLoading(true);
setError('');
try {
const ai = new GoogleGenAI({ apiKey });
// 最新のSDKでは、models.generateContentメソッドを使用
const result = await ai.models.generateContent({
model: 'gemini-2.5-flash-lite',
contents: [
{ text: query },
uploadedFile.data
]
});
setResponse(result.text);
} catch (err) {
setError('APIリクエストに失敗しました: ' + err.message);
} finally {
setLoading(false);
}
};
// ...
これだけで、基本的なRAGアプリケーションのコア機能は完成です。驚くほどシンプルですね。
簡易的な性能検証
3.2KBの製品仕様書(TXT)を対象に、いくつかの質問を投げてみました。
| 項目 | 結果 | 備考 |
|---|---|---|
| ファイル読み込み時間 | 0.3秒 | フロントエンド処理 |
| 初回応答時間 | 1.2秒 | コールドスタート |
| 2回目以降の応答時間 | 0.8秒 | 平均値 |
テストケース1: 情報抽出
-
質問:
この製品の標準価格はいくらですか? -
回答:
この製品の標準価格は29,800円(税込)です。 - 評価: ◎ 完璧
テストケース2: 計算
-
質問:
この製品を10台導入する場合、延長保証を含めた初期費用の総額は? -
回答:
...合計: 347,800円 - 評価: ◎ 計算も正確
テストケース3: 存在しない情報
-
質問:
この製品のバッテリー寿命は何時間ですか? -
回答:
申し訳ございませんが、提供された製品仕様書にはバッテリーに関する記載がありません。 - 評価: ◎ ハルシネーションを起こさず、誠実に回答
gemini-2.5-flash-lite の速さと精度のバランスは素晴らしく、しかも従来の1.5モデルより低コスト。簡単なドキュメント検索なら十分実用レベルだと感じました。
プロダクト化への「次の一歩」
このデモは最小構成ですが、実用的なアプリケーションにするには、いくつかの追加機能が考えられます。
-
引用(Citation)の表示:
File Search APIは、回答の根拠となった箇所をcitationMetadataとして返します。これをUIに表示することで、回答の信頼性が格段に向上します。 -
チャット履歴:
一問一答形式ではなく、過去のやり取りを保持するチャットUIにすることで、文脈に沿った対話が可能になります。 -
File Search Toolの本格導入:
今回のデモでは、シンプルなinlineData方式を使いました。より本格的なRAGシステムを構築する場合は、File Search Toolを使いましょう。これにより、複数のファイル(最大100MB/ファイル)を事前にインデックス化し、ベクトル検索による高精度な情報取得が可能になります。- サポート形式: PDF, DOCX, TXT, JSON, 各種プログラミング言語ファイル
- ストレージ上限: Free tier 1GB、有料tier 10GB〜1TB
- 自動引用機能: 回答の根拠箇所を自動で提示
-
フィードバック機能:
ユーザーがAIの回答を評価(Good/Badなど)できる機能をつけ、そのログを分析することで、ナレッジソース(元の文書)の改善やプロンプトのチューニングに繋げられます。
まとめ
Gemini APIのFile Search機能とGemini 2.5 Flash-Liteを使えば、これまで数週間かかっていたRAGシステムのプロトタイピングが、わずか半日で可能になります。
- インフラ不要: 面倒なベクトルDBやチャンキング処理はGoogleにお任せ。
- 圧倒的低コスト: Gemini 2.5 Flash-Liteは入力$0.10/1M tokens、出力$0.40/1M tokensという驚異的な価格設定。
- 高精度: 最新のGemini 2.5モデルの能力を最大限に活用し、従来の1.5モデルより高品質な回答を実現。
-
開発が容易:
@google/generative-aiSDKを使えば数行で実装可能。
RAGアプリ開発のハードルを劇的に下げたFile Search、そしてコスト重視のプロジェクトに最適なGemini 2.5 Flash-Lite。ぜひ皆さんも、お手元のドキュメントでその実力を試してみてください。
株式会社フィールフロウでは、生成AIを活用したシステム開発やコンサルティングを行っています。ご興味のある方は、お気軽にご相談ください。