LlamaIndex × OpenAI/Claude/Gemini 設定手順:モデル切替とコスト最適化
LlamaIndex を使った開発で、OpenAI、Claude、Gemini といった複数の LLM プロバイダーを自在に切り替えられたら、開発効率とコスト最適化の両立が実現できます。この記事では、LlamaIndex で複数の LLM を設定し、用途に応じてモデルを切り替える実践的な手順を解説いたします。
プロジェクトの規模が大きくなるにつれて、API コストは無視できない問題になりますよね。タスクの種類によって最適なモデルを選択できれば、品質を保ちながらコストを大幅に削減できるでしょう。
背景
LlamaIndex とは
LlamaIndex は、LLM(大規模言語モデル)を活用したアプリケーション開発を支援するデータフレームワークです。RAG(Retrieval-Augmented Generation)パターンの実装を簡単にし、データのインデックス化、検索、LLM へのクエリを統合的に扱えます。
複数 LLM プロバイダーのサポート
LlamaIndex は、OpenAI、Anthropic(Claude)、Google(Gemini)など、主要な LLM プロバイダーに対応しています。各プロバイダーは異なる特徴を持っており、用途に応じて使い分けることで最適な結果が得られるでしょう。
以下の図で、LlamaIndex がどのように LLM プロバイダーと連携するかを示します。
mermaidflowchart TB
app["アプリケーション"] -->|データ| llamaindex["LlamaIndex"]
llamaindex -->|インデックス化| index["Vector Index"]
llamaindex -->|クエリ| llm_router["LLM Router"]
llm_router -->|タスクA| openai["OpenAI<br/>GPT-4/GPT-3.5"]
llm_router -->|タスクB| claude["Anthropic<br/>Claude 3"]
llm_router -->|タスクC| gemini["Google<br/>Gemini Pro"]
openai -->|応答| llamaindex
claude -->|応答| llamaindex
gemini -->|応答| llamaindex
llamaindex -->|結果| app
図で理解できる要点:
- LlamaIndex が複数の LLM プロバイダーを統一的に扱う
- タスクの種類に応じて最適なモデルにルーティング可能
- すべての応答が LlamaIndex を通じてアプリケーションに返される
各プロバイダーの特徴
| # | プロバイダー | 主要モデル | 強み | 料金目安(入力/百万トークン) |
|---|---|---|---|---|
| 1 | OpenAI | GPT-4、GPT-3.5-turbo | 高精度、豊富な事例 | $0.50〜$30 |
| 2 | Anthropic | Claude 3 Opus/Sonnet/Haiku | 長文理解、安全性 | $0.25〜$15 |
| 3 | Gemini Pro/Flash | コスト効率、マルチモーダル | $0.075〜$7 |
課題
モデル選択の複雑さ
プロジェクトで複数の LLM を使う場合、以下のような課題に直面します。
コストと品質のトレードオフ:高性能な GPT-4 は優れた結果を出しますが、コストが高くなります。一方、GPT-3.5-turbo や Gemini Flash は安価ですが、複雑なタスクでは精度が落ちることもあるでしょう。
プロバイダー固有の設定:各プロバイダーは API キー、エンドポイント、パラメータ形式が異なるため、切り替えのたびにコードを修正する必要がありました。
運用時のモデル切り替え:開発環境では高性能モデル、本番環境ではコスト効率の良いモデルを使いたいケースがありますが、環境ごとに設定を管理するのは煩雑ですね。
エラーハンドリングの問題
複数のプロバイダーを使うと、それぞれ異なるエラーが発生します。
よくあるエラーコード:
| # | エラーコード | プロバイダー | 発生条件 |
|---|---|---|---|
| 1 | Error 401: Unauthorized | 全プロバイダー | API キーが無効または未設定 |
| 2 | Error 429: Rate limit exceeded | OpenAI、Anthropic | リクエスト制限超過 |
| 3 | Error 500: Internal Server Error | 全プロバイダー | プロバイダー側の一時的障害 |
| 4 | InvalidRequestError | OpenAI | トークン数制限超過 |
以下の図で、エラー発生時のフローを示します。
mermaidflowchart TD
start["APIリクエスト"] --> check["APIキー<br/>検証"]
check -->|有効| send["LLMへ送信"]
check -->|無効| err401["Error 401:<br/>Unauthorized"]
send -->|成功| response["応答取得"]
send -->|失敗| check_err["エラー種別<br/>判定"]
check_err -->|429| err429["Rate Limit<br/>リトライ待機"]
check_err -->|500| err500["Server Error<br/>別モデル切替"]
check_err -->|その他| err_other["エラー<br/>ログ記録"]
err429 --> retry["リトライ"]
retry --> send
err500 --> fallback["フォールバック<br/>モデル使用"]
fallback --> response
図で理解できる要点:
- API キー検証が最初のチェックポイント
- エラー種別によって異なるリカバリー戦略を適用
- Rate Limit はリトライ、Server Error は別モデルへフォールバック
解決策
LlamaIndex による統一的な LLM 管理
LlamaIndex は、複数の LLM プロバイダーを統一的なインターフェースで扱えるように設計されています。これにより、モデルの切り替えが簡単になり、コードの保守性が向上するでしょう。
モデル切替の戦略
以下の 3 つの戦略でモデルを使い分けます。
タスクベース切替:タスクの種類に応じてモデルを選択します。例えば、要約タスクには高性能な GPT-4、簡単な分類タスクには Gemini Flash を使用します。
コストベース切替:予算制約に応じて、コスト効率の良いモデルを優先的に使用します。
フォールバック戦略:メインのモデルでエラーが発生した場合、自動的に別のモデルに切り替える仕組みを実装します。
以下の図で、タスクベースの切替フローを示します。
mermaidflowchart LR
task["タスク入力"] --> classify["タスク分類"]
classify -->|要約・分析| gpt4["GPT-4<br/>高精度"]
classify -->|質問応答| claude["Claude Sonnet<br/>バランス型"]
classify -->|分類・抽出| gemini["Gemini Flash<br/>高速・低コスト"]
gpt4 --> result["結果出力"]
claude --> result
gemini --> result
環境変数による設定管理
API キーやモデル設定を環境変数で管理することで、環境ごとに異なる設定を簡単に切り替えられます。
具体例
環境構築
まず、必要なパッケージをインストールします。
bash# Yarn を使ってパッケージをインストール
yarn add llamaindex openai @anthropic-ai/sdk @google/generative-ai
yarn add -D @types/node dotenv
次に、TypeScript の設定ファイルを用意します。
json{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}
環境変数の設定
.envファイルを作成し、各プロバイダーの API キーを設定します。
bash# OpenAI設定
OPENAI_API_KEY=sk-your-openai-api-key
# Anthropic (Claude) 設定
ANTHROPIC_API_KEY=sk-ant-your-anthropic-api-key
# Google (Gemini) 設定
GOOGLE_API_KEY=your-google-api-key
# デフォルトモデル設定
DEFAULT_LLM_PROVIDER=openai
DEFAULT_MODEL_NAME=gpt-3.5-turbo
基本的な LLM 設定(OpenAI)
LlamaIndex で OpenAI のモデルを使用する基本的な設定です。
typescriptimport { OpenAI, Settings } from 'llamaindex';
import * as dotenv from 'dotenv';
// 環境変数を読み込み
dotenv.config();
次に、OpenAI の LLM インスタンスを作成します。
typescript// OpenAI LLMの初期化
const openaiLLM = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
model: 'gpt-4', // または 'gpt-3.5-turbo'
temperature: 0.7,
maxTokens: 1000,
});
// グローバル設定に適用
Settings.llm = openaiLLM;
このコードでは、OpenAI の GPT-4 モデルを初期化し、グローバル設定に適用しています。temperatureは応答のランダム性を制御し、maxTokensは最大トークン数を制限します。
Claude(Anthropic)の設定
Claude モデルを使用する場合の設定です。LlamaIndex では Anthropic のモデルもサポートされています。
typescriptimport { Anthropic } from 'llamaindex';
// Claude LLMの初期化
const claudeLLM = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
model: 'claude-3-sonnet-20240229', // または haiku, opus
temperature: 0.7,
maxTokens: 1000,
});
Claude モデルには、Haiku(高速・低コスト)、Sonnet(バランス型)、Opus(高精度)の 3 つのバリエーションがあります。タスクの要件に応じて選択しましょう。
Gemini(Google)の設定
Google の Gemini モデルを使用する設定です。
typescriptimport { Gemini } from 'llamaindex';
// Gemini LLMの初期化
const geminiLLM = new Gemini({
apiKey: process.env.GOOGLE_API_KEY,
model: 'gemini-pro', // または gemini-pro-vision
temperature: 0.7,
maxTokens: 1000,
});
Gemini は、テキストのみのgemini-proとマルチモーダルなgemini-pro-visionがあります。画像を扱う場合は後者を選択してください。
モデル切替の実装
タスクの種類に応じてモデルを動的に切り替える関数を実装します。
typescript/**
* タスクの種類を定義
*/
type TaskType =
| 'summary'
| 'qa'
| 'classification'
| 'analysis';
/**
* タスクに応じて最適なLLMを選択
*/
function selectLLM(taskType: TaskType) {
switch (taskType) {
case 'summary':
case 'analysis':
// 高精度が必要なタスクはGPT-4
return openaiLLM;
case 'qa':
// 質問応答はClaude Sonnetでバランス良く
return claudeLLM;
case 'classification':
// 分類タスクはGemini Flashで高速・低コスト
return geminiLLM;
default:
return openaiLLM;
}
}
この関数では、タスクの種類に応じて最適な LLM を返します。要約や分析には高精度な GPT-4、質問応答にはバランスの良い Claude、分類には高速で低コストな Gemini を使用しています。
実践的な使用例
実際に LlamaIndex を使ってドキュメントをインデックス化し、質問に答える例を示します。
typescriptimport {
VectorStoreIndex,
Document,
Settings
} from 'llamaindex';
/**
* ドキュメントのインデックス化と検索
*/
async function processDocument(
text: string,
query: string,
taskType: TaskType
) {
try {
// タスクに応じたLLMを選択
const llm = selectLLM(taskType);
Settings.llm = llm;
次に、ドキュメントを作成してインデックス化します。
typescript// ドキュメントの作成
const document = new Document({ text });
// インデックスの作成
const index = await VectorStoreIndex.fromDocuments([
document,
]);
console.log(`使用モデル: ${llm.model}`);
最後に、クエリエンジンを使って質問に答えます。
typescript // クエリエンジンの作成と実行
const queryEngine = index.asQueryEngine();
const response = await queryEngine.query(query);
return {
answer: response.toString(),
model: llm.model,
};
} catch (error) {
console.error('処理エラー:', error);
throw error;
}
}
このコードでは、テキストをインデックス化し、選択された LLM を使ってクエリに応答しています。エラーが発生した場合は、適切にログを記録して例外を再スローします。
フォールバック機能の実装
メインのモデルでエラーが発生した場合、自動的に別のモデルに切り替える仕組みを実装します。
typescript/**
* フォールバック付きLLM実行
*/
async function executeWithFallback(
text: string,
query: string,
taskType: TaskType
) {
// 優先順位付きのLLMリスト
const llmPriority = [
selectLLM(taskType),
claudeLLM,
geminiLLM,
];
次に、各 LLM を順番に試行します。
typescript for (let i = 0; i < llmPriority.length; i++) {
try {
Settings.llm = llmPriority[i];
const document = new Document({ text });
const index = await VectorStoreIndex.fromDocuments([document]);
const queryEngine = index.asQueryEngine();
const response = await queryEngine.query(query);
console.log(`成功: ${llmPriority[i].model}を使用`);
return response.toString();
} catch (error: any) {
console.error(`エラー: ${llmPriority[i].model}`, error.message);
エラーハンドリングと次のモデルへの切り替えを行います。
typescript // 最後のLLMでもエラーの場合は例外をスロー
if (i === llmPriority.length - 1) {
throw new Error('すべてのLLMで処理に失敗しました');
}
// 次のLLMを試行
console.log(`次のモデルを試行: ${llmPriority[i + 1].model}`);
}
}
}
この実装では、優先順位付きの LLM リストを順番に試行し、1 つが失敗しても次のモデルで処理を続行します。すべてのモデルで失敗した場合のみエラーを返すでしょう。
コスト最適化の実装
API コールのコストを追跡し、予算内で運用するための仕組みを実装します。
typescript/**
* モデルごとのコスト設定(入力/百万トークンあたりのドル)
*/
const MODEL_COSTS = {
'gpt-4': { input: 30, output: 60 },
'gpt-3.5-turbo': { input: 0.5, output: 1.5 },
'claude-3-opus-20240229': { input: 15, output: 75 },
'claude-3-sonnet-20240229': { input: 3, output: 15 },
'claude-3-haiku-20240307': { input: 0.25, output: 1.25 },
'gemini-pro': { input: 0.5, output: 1.5 },
'gemini-1.5-flash': { input: 0.075, output: 0.3 },
};
次に、コストを計算する関数を実装します。
typescript/**
* 推定コストの計算
*/
function estimateCost(
model: string,
inputTokens: number,
outputTokens: number
): number {
const costs =
MODEL_COSTS[model as keyof typeof MODEL_COSTS];
if (!costs) {
console.warn(
`モデル ${model} のコスト情報がありません`
);
return 0;
}
const inputCost = (inputTokens / 1_000_000) * costs.input;
const outputCost =
(outputTokens / 1_000_000) * costs.output;
return inputCost + outputCost;
}
コスト追跡機能付きの実行関数を作成します。
typescript/**
* コスト追跡付き実行
*/
async function executeWithCostTracking(
text: string,
query: string,
taskType: TaskType,
maxCostUSD: number = 0.01 // デフォルト予算: 1セント
) {
const llm = selectLLM(taskType);
Settings.llm = llm;
// 入力トークン数の推定(簡易計算: 4文字=1トークン)
const estimatedInputTokens = (text.length + query.length) / 4;
const estimatedOutputTokens = 500; // 出力の推定値
const estimatedCost = estimateCost(
llm.model,
estimatedInputTokens,
estimatedOutputTokens
);
予算チェックと実行を行います。
typescript // 予算チェック
if (estimatedCost > maxCostUSD) {
console.warn(
`推定コスト $${estimatedCost.toFixed(4)} が予算 $${maxCostUSD} を超過`
);
// より安価なモデルに切り替え
Settings.llm = geminiLLM;
console.log(`低コストモデルに切替: ${geminiLLM.model}`);
}
// 実行
const document = new Document({ text });
const index = await VectorStoreIndex.fromDocuments([document]);
const queryEngine = index.asQueryEngine();
const response = await queryEngine.query(query);
return {
answer: response.toString(),
model: Settings.llm.model,
estimatedCost: estimatedCost.toFixed(4),
};
}
このコスト追跡機能により、予算を超過する場合は自動的に低コストなモデルに切り替えることができます。
エラーハンドリングの実装
各プロバイダーで発生する可能性のあるエラーを適切に処理します。
typescript/**
* エラー種別の判定
*/
function identifyErrorType(error: any): string {
const message = error.message || '';
if (
error.status === 401 ||
message.includes('Unauthorized')
) {
return 'AUTH_ERROR';
}
if (
error.status === 429 ||
message.includes('rate limit')
) {
return 'RATE_LIMIT';
}
if (
error.status === 500 ||
message.includes('Internal Server')
) {
return 'SERVER_ERROR';
}
if (message.includes('maximum context length')) {
return 'TOKEN_LIMIT';
}
return 'UNKNOWN_ERROR';
}
エラータイプに応じた処理を実装します。
typescript/**
* エラー処理付き実行
*/
async function executeWithErrorHandling(
text: string,
query: string,
taskType: TaskType
) {
const maxRetries = 3;
let retryCount = 0;
while (retryCount < maxRetries) {
try {
const result = await executeWithFallback(text, query, taskType);
return result;
} catch (error: any) {
const errorType = identifyErrorType(error);
エラータイプごとに異なる対応を行います。
typescript switch (errorType) {
case 'AUTH_ERROR':
console.error('Error 401: APIキーが無効です');
throw new Error('認証エラー: APIキーを確認してください');
case 'RATE_LIMIT':
console.warn('Error 429: レート制限超過、リトライ待機中...');
retryCount++;
// 指数バックオフで待機(2秒、4秒、8秒)
await new Promise(resolve =>
setTimeout(resolve, Math.pow(2, retryCount) * 1000)
);
break;
case 'SERVER_ERROR':
console.error('Error 500: サーバーエラー、フォールバック実行');
retryCount++;
break;
トークン制限エラーとその他のエラーを処理します。
typescript case 'TOKEN_LIMIT':
console.error('トークン数超過: テキストを分割して再試行');
// テキストを半分に分割して再試行
const halfLength = Math.floor(text.length / 2);
const firstHalf = text.substring(0, halfLength);
return await executeWithErrorHandling(
firstHalf,
query,
taskType
);
default:
console.error('予期しないエラー:', error.message);
throw error;
}
}
}
throw new Error('最大リトライ回数に達しました');
}
このエラーハンドリング実装により、各種エラーに対して適切なリカバリー戦略を適用できますね。
実行例とテストコード
実際に複数のタスクを実行してモデルの切り替えを確認します。
typescript/**
* メイン実行関数
*/
async function main() {
const sampleText = `
LlamaIndexは、LLMアプリケーション開発のためのデータフレームワークです。
RAGパターンを簡単に実装でき、複数のLLMプロバイダーをサポートしています。
OpenAI、Anthropic、Googleなどのモデルを統一的に扱うことができます。
`;
console.log('=== タスク1: 要約(GPT-4使用)===');
const summary = await executeWithCostTracking(
sampleText,
'このテキストを3行で要約してください',
'summary'
);
console.log(summary);
別のタスクタイプで実行します。
typescript console.log('\n=== タスク2: 質問応答(Claude使用)===');
const qa = await executeWithCostTracking(
sampleText,
'LlamaIndexの主な機能は何ですか?',
'qa'
);
console.log(qa);
console.log('\n=== タスク3: 分類(Gemini使用)===');
const classification = await executeWithCostTracking(
sampleText,
'このテキストのカテゴリを判定してください',
'classification'
);
console.log(classification);
}
最後に、エラーハンドリングを含めた実行を行います。
typescript// 実行
main()
.then(() => {
console.log('\n処理が正常に完了しました');
})
.catch((error) => {
console.error('エラーが発生しました:', error.message);
process.exit(1);
});
このテストコードを実行すると、各タスクで異なるモデルが使用され、コストが表示されることが確認できるでしょう。
コスト比較とモデル選択の指針
実際の使用例をもとに、各モデルのコストパフォーマンスを比較します。
| # | タスク種別 | 推奨モデル | 理由 | 100 万トークンあたりコスト |
|---|---|---|---|---|
| 1 | 要約・分析 | GPT-4 / Claude Opus | 高精度が必要 | $30〜$45 |
| 2 | 質問応答 | Claude Sonnet | バランス型 | $3〜$9 |
| 3 | 分類・抽出 | Gemini Flash | 高速・低コスト | $0.075〜$0.3 |
| 4 | 大量処理 | GPT-3.5-turbo | コスト重視 | $0.5〜$1.5 |
選択の指針:
- プロトタイプ開発では高性能モデルで品質を確認
- 本番環境では処理量に応じてコスト効率の良いモデルを選択
- クリティカルな処理のみ高性能モデル、それ以外は低コストモデルで運用
まとめ
LlamaIndex を使った複数 LLM プロバイダーの設定と切り替え手順について解説しました。OpenAI、Claude、Gemini の 3 つの主要プロバイダーを統一的に扱い、タスクに応じて最適なモデルを選択する方法を実装できましたね。
コスト最適化は、モデルの特性を理解し、タスクの要件に応じて使い分けることで実現できます。フォールバック機能を実装することで、エラーが発生しても処理を継続でき、システムの信頼性が向上するでしょう。
環境変数による設定管理、エラーハンドリング、コスト追跡機能を組み合わせることで、本番環境でも安心して運用できるシステムが構築できます。今回紹介した実装パターンを活用して、効率的な LLM アプリケーション開発を進めてください。
関連リンク
articleLlamaIndex × OpenAI/Claude/Gemini 設定手順:モデル切替とコスト最適化
articleHaystack と LangChain/LlamaIndex 徹底比較:設計思想・拡張性・学習コスト
articleLlamaIndex のコア概念を図解で理解:Data Loader/Index/Retriever/Query Engine
articleLlamaIndex トラブルシュート大全:検索ヒットしない・幻覚が増える時の対処
articleLlamaIndex の可観測性運用:Tracing/Telemetry/失敗ケースの可視化
articleLlamaIndex と LangChain を徹底比較:開発速度・可観測性・精度ベンチ
articleLodash vs ネイティブ(`Array.prototype`/`Object.*`):実行速度と可読性の実測
articlePostgreSQL vs MySQL 徹底比較:トランザクション・索引・JSON 機能の実測
articleSpring Boot の起動が遅い/落ちるを診断:Auto-config レポートと条件分岐の切り分け
articleLlamaIndex × OpenAI/Claude/Gemini 設定手順:モデル切替とコスト最適化
articleNode.js 25.x, 24.x, 22.x, 20.x の脆弱性対応:2025 年 12 月版で修正された 3 件の High Severity 問題の詳細
articleEmotion × Vite の最短構築:開発高速化とソースマップ最適設定
blogiPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
blogGoogleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
blog【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
blogGoogleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
blogPixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
blogフロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
review今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
reviewついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
review愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
review週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
review新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
review科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来