こんにちは、サイオステクノロジーの遠藤です。本ブログはSIOS Tech Labアドベントカレンダー18日目の投稿です。
今回は、RAG評価フレームワークであるRagasの最新バージョンv0.4.0について紹介します。
さらに、GPT-5のreasoning_effortパラメータを使って、minimal(高速モード)とhigh(推論重視モード)での評価結果の違いも検証しました。
- Ragasのv0.4.0で何が変わったの?
- Azure OpenAI ServiceのGPT-5でRagasを使いたい!
- GPT-5のreasoning_effortで評価結果はどう変わるの?
といった方は、ぜひ最後までご覧ください!
はじめに
Ragasって何?という方は以下の記事をご覧ください!
今回のv0.4.0では、特に最新のOpenAIモデル対応が目玉となっています。
手元の環境では ragas==0.4.0 のバージョンを利用して検証を行っています。
v0.4.0の主な変更点
公式のリリースノートによると、v0.4.0では以下の変更が加えられました。
GPT-5/o-seriesモデルのサポート
今回の目玉となる変更点です。
GPT-5およびo-seriesモデルが正式にサポートされ、temperatureやtop_pパラメータの制約が自動的にハンドリングされるようになりました。
これまでo1-previewなどのモデルを使おうとすると、パラメータの制約によりエラーが発生することがありましたが、v0.4.0ではこれが解消されています。
注意点: GPT-5はtemperature=1のみをサポートしています。Ragasは内部でtemperatureを変更しようとするため、bypass_temperature=Trueオプションを使用してこれを防ぐ必要があります。
from langchain_openai import AzureChatOpenAI
from ragas.llms import LangchainLLMWrapper
llm = AzureChatOpenAI(
azure_deployment="gpt-5-deploy",
temperature=1, # GPT-5は1のみサポート
model_kwargs={"reasoning_effort": "high"},
)
# bypass_temperature=TrueでRagasによるtemperature上書きを防ぐ
evaluator_llm = LangchainLLMWrapper(llm, bypass_temperature=True)
統一されたLLMプロバイダーサポート
instructor.from_providerへの移行により、複数のLLMプロバイダーとの互換性が向上しました。
これにより、Azure OpenAI、OpenAI、その他のプロバイダーを統一的に扱えるようになっています。
モジュラーなメトリクスアーキテクチャ
評価メトリクスの多くが標準化されたBasePromptパターンを使用するようにリファクタリングされました。
これにより、メトリクスの拡張性が向上し、カスタムメトリクスの作成がより簡単になっています。
GPT-5のreasoning_effortについて
GPT-5ではreasoning_effortパラメータにより、推論の深さを制御できます。
| パラメータ値 | 説明 |
|---|---|
minimal | 最小限の推論。高速だが精度は低い可能性 |
low | 軽量な推論 |
medium | バランスの取れた推論(デフォルト) |
high | 深い推論。時間はかかるが精度が高い可能性 |
今回の検証では、minimalとhighの2つのモードで評価結果を比較してみました。
事前準備
Azure OpenAI Serviceの設定
今回はAzure AI Foundry経由でデプロイしたGPT-5を利用します。
以下のモデルをデプロイしておいてください。
| モデル | 用途 |
|---|---|
| GPT-5 | 評価用のChatモデル |
| text-embedding-3-small | Embeddingsモデル |
パッケージのインストール
必要なパッケージをインストールします。
pip install ragas==0.4.0 langchain-openai python-dotenv
実装
それでは、実際にGPT-5を使ってRagasで評価を行っていきます。
環境変数の設定
まずは環境変数を設定します。
import os
from dotenv import load_dotenv
load_dotenv()
AZURE_OPENAI_ENDPOINT = os.getenv("AZURE_OPENAI_ENDPOINT")
AZURE_OPENAI_API_KEY = os.getenv("AZURE_OPENAI_API_KEY")
GPT5_API_VERSION = os.getenv("GPT5_API_VERSION")
GPT5_DEPLOYMENT = os.getenv("GPT5_DEPLOYMENT")
EMBEDDINGS_API_VERSION = os.getenv("EMBEDDINGS_API_VERSION")
EMBEDDINGS_DEPLOYMENT = os.getenv("EMBEDDINGS_DEPLOYMENT")
.envファイルには以下の内容を記載しておきます。
AZURE_OPENAI_ENDPOINT=https://{resource-name}.openai.azure.com/
AZURE_OPENAI_API_KEY=your-api-key
GPT5_API_VERSION=2025-01-01-preview
GPT5_DEPLOYMENT=gpt-5-deploy
EMBEDDINGS_API_VERSION=2023-05-15
EMBEDDINGS_DEPLOYMENT=text-embedding-3-small-deploy
LLMとEmbeddingsの設定
GPT-5を評価用のLLMとして設定します。
ポイントは以下の2点です:
- temperature=1 を設定(GPT-5は1のみサポート)
- bypass_temperature=True でRagasによる上書きを防ぐ
- reasoning_effort で推論の深さを制御
from langchain_openai import AzureChatOpenAI, AzureOpenAIEmbeddings
from ragas.llms import LangchainLLMWrapper
from ragas.embeddings import LangchainEmbeddingsWrapper
def create_llm(reasoning_effort: str) -> LangchainLLMWrapper:
"""指定したreasoning_effortでLLMを作成"""
llm = AzureChatOpenAI(
azure_endpoint=AZURE_OPENAI_ENDPOINT,
api_key=AZURE_OPENAI_API_KEY,
api_version=GPT5_API_VERSION,
azure_deployment=GPT5_DEPLOYMENT,
temperature=1, # GPT-5は1のみサポート
model_kwargs={"reasoning_effort": reasoning_effort},
)
# bypass_temperature=Trueでtemperatureの上書きを防ぐ
return LangchainLLMWrapper(llm, bypass_temperature=True)
def create_embeddings() -> LangchainEmbeddingsWrapper:
"""Embeddingsモデルを作成"""
embeddings = AzureOpenAIEmbeddings(
azure_endpoint=AZURE_OPENAI_ENDPOINT,
api_key=AZURE_OPENAI_API_KEY,
api_version=EMBEDDINGS_API_VERSION,
azure_deployment=EMBEDDINGS_DEPLOYMENT,
)
return LangchainEmbeddingsWrapper(embeddings)
評価データの準備
評価用のデータセットを準備します。
v0.2以降と同様に、EvaluationDatasetとSingleTurnSampleを使用します。
今回は、RAGシステムの評価を想定して就業規則PDFから10件の質問を選定しました。
各質問には正解(reference)、検索されたコンテキスト(retrieved_contexts)、RAGの回答(response)を設定しています。
from ragas import EvaluationDataset, SingleTurnSample
# 就業規則から抽出したコンテキスト
CONTEXTS = {
"試用期間": [
"(試用期間)第6条 労働者として新たに採用した者については、採用した日から3か月間を試用期間とする。",
"前項について、会社が特に認めたときは、試用期間を短縮し、又は設けないことがある。",
"試用期間は、勤続年数に通算する。"
],
"労働時間": [
"(労働時間及び休憩時間)第18条 1週間の所定労働時間は、2025年1月1日を起算日として、2週間ごとに平均して、1週間当たり40時間とする。",
"1日の所定労働時間は、7時間30分とする。",
"始業・終業の時刻及び休憩時間は、次のとおりとする。始業 午前9時00分、終業 午後17時30分、休憩時間 12時00分から13時00分まで"
],
"家族手当": [
"(家族手当)第33条 家族手当は、次の家族を扶養している労働者に対し支給する。",
"18歳未満の子 1人につき 月額 40000円",
"65歳以上の父母 1人につき 月額 50000円"
],
# ... 他のカテゴリも同様に定義
}
# RAGの回答をシミュレート(一部に余計な情報を含める)
SIMULATED_RESPONSES = {
"試用期間は何か月ですか?": "試用期間は採用した日から3か月間です。試用期間は勤続年数に通算されます。",
"18歳未満の子を扶養している場合の家族手当はいくらですか?": "18歳未満の子を扶養している場合、1人につき月額40,000円の家族手当が支給されます。なお、最近の物価上昇を受けて今後増額される可能性があります。", # ← コンテキストにない情報を追加
# ...
}
# 評価サンプルの作成
samples = []
selected_questions = [
{"question": "試用期間は何か月ですか?", "ground_truth": "試用期間は採用した日から3か月間です。", "context_key": "試用期間"},
{"question": "1日の所定労働時間は何時間ですか?", "ground_truth": "1日の所定労働時間は7時間30分です。", "context_key": "労働時間"},
{"question": "18歳未満の子を扶養している場合の家族手当はいくらですか?", "ground_truth": "18歳未満の子を扶養している場合、1人につき月額40,000円の家族手当が支給されます。", "context_key": "家族手当"},
# ... 合計10件
]
for q in selected_questions:
sample = SingleTurnSample(
user_input=q["question"],
retrieved_contexts=CONTEXTS[q["context_key"]],
response=SIMULATED_RESPONSES[q["question"]],
reference=q["ground_truth"],
)
samples.append(sample)
eval_dataset = EvaluationDataset(samples=samples)
ポイント: 一部の回答には意図的に「コンテキストにない情報」を含めています(例:「今後増額される可能性があります」)。
これにより、faithfulness(忠実性)メトリクスが正しく機能しているかを確認できます。
評価の実行
メトリクスを設定し、評価を実行します。
import time
from ragas import evaluate
from ragas.metrics import (
Faithfulness,
ResponseRelevancy,
ContextPrecision,
ContextRecall
)
def run_evaluation(reasoning_effort: str, dataset, embeddings):
"""指定したreasoning_effortで評価を実行"""
# LLMの作成
evaluator_llm = create_llm(reasoning_effort)
# メトリクスの設定
metrics = [
Faithfulness(llm=evaluator_llm),
ResponseRelevancy(llm=evaluator_llm, embeddings=embeddings),
ContextPrecision(llm=evaluator_llm),
ContextRecall(llm=evaluator_llm)
]
# 評価の実行(時間計測)
start_time = time.time()
results = evaluate(dataset=dataset, metrics=metrics)
elapsed_time = time.time() - start_time
return results.to_pandas(), elapsed_time
# 共通のEmbeddingsを作成
embeddings = create_embeddings()
# minimal(高速モード)で評価
df_minimal, time_minimal = run_evaluation("minimal", eval_dataset, embeddings)
# high(推論重視モード)で評価
df_high, time_high = run_evaluation("high", eval_dataset, embeddings)
結果と考察
minimal vs high 比較結果
実際にGPT-5のreasoning_effortを変えて、就業規則データセット(10件)で評価を行った結果を紹介します。

処理時間の比較
| モード | 処理時間 |
|---|---|
| minimal | 76.37秒 |
| high | 94.83秒 |
| 差分 | +18.46秒(24.2%増) |
評価スコアの比較
| メトリクス | minimal | high | 差分 |
|---|---|---|---|
| faithfulness | 0.8500 | 0.8833 | +0.0333 |
| answer_relevancy | 0.8290 | 0.8386 | +0.0095 |
| context_precision | 0.6917 | 0.6917 | ±0.0000 |
| context_recall | 1.0000 | 1.0000 | ±0.0000 |
考察
1. faithfulness(忠実性)に差が出た
highモードではfaithfulnessのスコアが0.85から0.88に向上しました。
今回のテストデータでは、一部の回答に意図的に「コンテキストにない情報」を含めています。
例えば、家族手当の質問に対する回答に「最近の物価上昇を受けて今後増額される可能性があります」という推測を追加しました。
highモードはこのような不正確な情報をより厳密に検出できる傾向が見られました。
2. context_recallは両モードで完璧
context_recallは両モードとも1.0000でした。
これは、正解(ground_truth)に含まれる情報がすべてコンテキストから取得できていることを意味します。
就業規則という明確なソースがあるため、このような結果になったと考えられます。
3. 処理時間とのトレードオフ
highモードは処理時間が約24%増加しますが、faithfulnessのスコアが向上する傾向が見られました。
| 用途 | 推奨モード |
|---|---|
| 開発・デバッグ時の簡易評価 | minimal |
| 本番環境のRAG品質評価 | high |
| 大量データの評価 | minimal + サンプリング |
まとめ
今回はRagas v0.4.0の主な変更点と、Azure OpenAI ServiceのGPT-5を使った評価方法を紹介しました。
ポイントとしては:
- GPT-5/o-seriesモデルのサポートにより、最新のLLMを使った評価が可能に
- GPT-5はtemperature=1のみサポートのため、
bypass_temperature=Trueが必要 - reasoning_effortパラメータで推論の深さを制御できる
highモードは処理時間が約1.2倍だが、faithfulnessのスコアが向上する傾向(0.85→0.88)- 用途に応じて
minimalとhighを使い分けるのがおすすめ
今後もRagasの進化に注目していきたいと思います。
ではまた!
