はじめに
前回は、Jevを使った「Corrective RAG(CRAG)」について学び、検索結果が不十分な場合に再検索する仕組みを実装しました。今回は、生成した回答が検索文書の内容に基づいているかを評価する Self-RAG(セルフRAG) について学んでいこうと思います。
前回のCRAGでは検索結果の品質を評価しましたが、今回は生成された回答そのものをJevで評価し、根拠のない情報を検知・修正できるかを検証します。CRAGとの違いにも注目していきます。
これまでの記事・実装
- Step0:Naive RAG
- Step1:Jevを使ったReranking RAG
- Step2:Jevを使ったFiltering RAG
- Step3:Jevを使ったAdaptive RAG
- Step4:Corrective RAGの実装(GitHub PR #5)
- GitHub:jev-rag-learning
Self-RAGとは?
Self-RAGとは、検索・回答生成・自己評価を組み合わせ、回答の正確性や根拠との整合性を改善するRAGの構成です。
Self-RAGは、2024年のICLRで発表されたSelf-RAG: Learning to Retrieve, Generate, and Critique through Self-Reflectionで提案されています。
元論文では、Reflection Tokenと呼ばれる特殊なトークンを学習し、検索の必要性、文書の関連性、回答の根拠との整合性、回答の有用性などを評価します。
今回は元論文のモデルを再現するのではなく、Jevを外部の評価器として使い、生成した回答の根拠を検証する簡易的なSelf-RAGを実装します。
CRAGとSelf-RAGの違い
前回のCRAGでもJevを使って評価していましたが、両者では評価する対象と問題があった場合の修正方法が異なります。
| 比較 | CRAG | Self-RAG(今回の実装) |
|---|---|---|
| 評価対象 | 検索された文書 | 生成された回答 |
| Jevへの入力 | 質問+検索文書 | 質問+検索文書+回答 |
| 判断すること | 回答に必要な情報が揃っているか | 回答の主張に根拠があるか |
| 問題がある場合 | 検索文を変更して再検索 | 回答を修正・再評価 |
| 改善したい問題 | 検索の失敗 | 回答生成の失敗 |
例えば、検索結果に必要な文書が含まれていない場合、CRAGでは再検索によって不足を補えます。
一方、正しい文書を取得できていても、LLMが文書に書かれていない内容を回答する可能性があります。今回のSelf-RAGでは、こうした回答を検知・修正することを目指します。
つまり、**CRAGは「必要な情報を取得できているか」、今回のSelf-RAGは「取得した情報に基づいて回答できているか」**を評価します。
処理の流れ
CRAGでは回答生成前に検索結果を評価します。一方、今回のSelf-RAGでは、回答生成後にJevで根拠を検証します。
処理の内容は以下のとおりです。
| 処理 | 役割 |
|---|---|
| Retrieval | 質問に関連する文書を検索 |
| Generation | 検索結果をもとに回答を生成 |
| Reflection | Jevで生成回答の根拠を検証し、必要なら修正 |
今回は検索方法を固定し、回答生成後のReflection処理だけを追加します。
成果物
今回も、架空のSaaS「TaskFlow」の問い合わせ回答システムを使用します。
前回のCRAGの実験結果も参考にしながら、検索の失敗と回答生成の失敗で、Jevの役割がどう異なるかを確認します。
| 質問 | 確認する内容 |
|---|---|
| Standardプランを月の途中で解約したら、日割りになりますか? | CRAGによる検索失敗の修正 |
| 退会後のデータ保存期間を、有料で90日間に延長できますか? | Self-RAGによる根拠のない断定の検証 |
| 退会後、データはいつ削除されますか? | Self-RAGによる正しい回答の維持 |
① 検索結果に正解がない場合
前回のCRAGでは、「Standardプランを月の途中で解約したら、日割りになりますか?」という質問で、初回検索に必要な「退会後の請求」が含まれていませんでした。
Jevは検索結果をIncorrectと判定し、再検索によって「退会後の請求」を取得しました。その結果、「解約した月は満額請求され、日割りにならない」と回答できました。
このような問題は、検索結果を修正するCRAGが得意とするケースです。
② 回答に根拠のない断定がある場合
「退会後のデータ保存期間を、有料で90日間に延長できますか?」という質問では、マニュアルに有料延長の可否が記載されていません。
LLMが「延長できません」と断定した場合、その主張を裏付ける根拠はありません。
CRAGでは検索し直して情報を探せますが、そもそもマニュアルに記載がなければ正解を取得できません。一方、今回のSelf-RAGでは、回答に根拠がないことを検知し、断定を避けた回答へ修正できるかを確認します。
③ 正しい回答を維持できるか
「退会後、データはいつ削除されますか?」という質問には、「退会完了から30日後」という明確な答えがあります。
こちらでは、Jevが正しい回答をsupportedと判断し、不要な修正を行わないかを確認します。
回答の評価方法
今回はCRAGとSelf-RAGの評価対象を比較しつつ、Self-RAGでは回答の検証前後の変化を確認します。
| 比較項目 | CRAG | Self-RAG |
|---|---|---|
| 初期検索 | 上位3件 | 上位3件 |
| Jevの評価対象 | 検索文書 | 生成回答 |
| 評価方法 | choice |
choice |
| 問題があった場合 | 再検索 | 回答修正・再評価 |
| 回答モデル | GPT-4.1-mini | GPT-4.1-mini |
主に確認するのは、Jevの判定結果、回答の修正有無、最終回答、入力トークン数、処理時間です。
なお、今回掲載するSelf-RAGの実行結果2件について、CRAGを同じ質問・条件で再実行した結果はまだ確認できていません。そのため、数値による直接比較ではなく、前回のCRAGの実験結果と今回のSelf-RAGの仕組みを対比します。
実装内容
今回はJevのchoiceを使用し、生成した回答と検索文書の整合性を評価します。
① Jevで回答の根拠を評価する
POST https://api.typesafe.ai/v1/systemoneを使用し、モデルにはjev-latestを指定します。
stateには質問・検索文書・生成した回答を渡し、questions.supportに以下の3つの選択肢を設定します。
| 判定 | 意味 |
|---|---|
supported |
回答の主張が文書に裏付けられている |
not_supported |
文書に根拠のない主張が含まれる |
contradicted |
回答が文書の記載と矛盾している |
例えば「有料で90日間延長できますか?」という質問に対して、「延長できません」と回答した場合のリクエストです。
{
"model": "jev-latest",
"state": "質問: 退会後のデータ保存期間を、有料で90日間に延長できますか?\n\n文書:\n退会が完了してから30日後に、ワークスペースのタスク、添付ファイル、メンバー一覧は完全に削除されます。\n\n回答:\n有料でも90日間に延長することはできません。",
"questions": {
"support": {
"type": "choice",
"instructions": "回答に含まれる主張は、提示された文書の記載によって裏付けられているか。文書に書かれていないことを事実として断定している場合は not_supported とする。",
"criteria": {
"supported": "回答の具体的な主張が文書によって裏付けられている",
"not_supported": "文書に根拠のない主張が回答に含まれている",
"contradicted": "回答の主張が文書の記載と直接矛盾している"
}
}
}
}
これは検証用のリクエスト例です。今回の例では、30日後に削除されることは確認できますが、有料延長の可否については記載がありません。
そのため、not_supportedと判定できるかを確認します。
② Jevの判定に応じて回答を修正する
Jevのレスポンスに含まれるanswers.support.choiceを使い、処理を分岐させます。
| 判定結果 | 実行する処理 |
|---|---|
supported |
回答をそのまま採用 |
not_supported |
根拠のない内容を除いて回答を修正 |
contradicted |
文書の記載に合わせて回答を修正 |
Jevは評価を担当し、実際の回答修正はLLMに依頼します。
// 処理の流れを示す概念コード
const documents = await retrieve(query, 3);
const initialAnswer = await generate(query, documents);
const evaluation = await evaluateWithJev({
query,
documents,
answer: initialAnswer
});
if (evaluation.choice === "supported") {
return initialAnswer;
}
const revisedAnswer = await reviseAnswer({
query,
documents,
answer: initialAnswer
});
const recheck = await evaluateWithJev({
query,
documents,
answer: revisedAnswer
});
if (recheck.choice !== "supported") {
return "マニュアルからは確認できません。";
}
return revisedAnswer;
※ 処理の流れを示す概念コードです。
③ 修正した回答を再評価する
回答を修正した場合は、もう一度Jevで根拠を確認します。
今回は修正を最大1回とし、再評価でも根拠が確認できない場合は、断定的な回答を返さない設計にします。
ここもCRAGとの違いです。CRAGでは検索結果を修正するために再検索しますが、今回のSelf-RAGでは回答そのものを修正して再評価します。
実行結果
今回のSelf-RAGでは、根拠が不足している質問と、正しい根拠が存在する質問の2つを検証します。
① 退会後のデータ保存期間を、有料で90日間に延長できますか?
初回回答の確認
この質問に対して、マニュアルには「退会完了から30日後にデータを削除する」という情報があります。しかし、有料延長の可否は記載されていません。
そのため、「延長できない」と断定した場合は、マニュアルに根拠のない回答になります。
Jevによる根拠の検証
Self-RAGでは、質問・文書・初回回答をJevに渡して、supported、not_supported、contradictedのいずれかを判断します。
not_supportedと判定された場合は、LLMで回答を修正し、もう一度Jevで評価します。
CRAGとの違い
CRAGでは不足している情報を再検索することで解決を試みます。しかし、マニュアル自体に答えが存在しない場合、再検索しても正解を得られるとは限りません。
一方、今回のSelf-RAGでは、回答が根拠に裏付けられているかを評価し、根拠のない断定を防ぐことが目的です。
実行結果の画像には実際のログを掲載しています。Jevの判定値や回答の修正内容については、ログの確認後に数値を反映します。
② 退会後、データはいつ削除されますか?
初回回答の確認
この質問の正解は「退会完了から30日後」です。マニュアルにも明確に記載されています。
必要な文書が取得できており、LLMが正しく回答していれば、修正する必要はありません。
Jevによる根拠の検証
Self-RAGでは、生成した回答が検索文書の記載に基づいているかを確認します。
正しい回答に対して supportedと判定できれば、再生成せずに回答を採用します。
CRAGとの違い
CRAGでは、最初の検索結果に必要な情報が揃っているかを評価します。
一方、今回のSelf-RAGは、必要な情報が取得されていることに加えて、LLMがその情報を使って根拠のある回答を生成できているかを評価します。
正しい回答を不要に修正しないことも、Self-RAGに求められる重要な動作です。
まとめ
今回は、Jevを使って生成した回答の根拠を検証するSelf-RAGを実装し、前回のCRAGとの違いを整理しました。
CRAGでは、検索結果に必要な文書が含まれていない場合、再検索によって情報を補完します。前回の「解約時の日割り」の実験では、再検索によって「退会後の請求」を取得し、正しい回答を生成できました。
一方、今回のSelf-RAGでは、検索結果をもとに生成された回答が、本当に文書の記載に裏付けられているかを確認する仕組みを追加しました。
| CRAG | Self-RAG(今回) | |
|---|---|---|
| 改善対象 | 検索結果 | 生成された回答 |
| 主な対策 | 再検索 | 回答修正・再評価 |
| 目的 | 必要な情報を取得する | 根拠のある回答を返す |
今回の学習で重要なのは、正しい情報を取得することと、その情報を使って正しく回答することは別の問題だという点です。
検索結果に必要な情報がなければ、回答を修正するだけでは解決できません。反対に、必要な文書を取得できていても、LLMが根拠のない情報を生成する可能性があります。
CRAGとSelf-RAGは競合するものではなく、異なる段階の問題を改善する補完的な仕組みです。両者を組み合わせることで、検索から回答生成までの信頼性を高められると考えています。
ただし、Jevの判定も完全ではなく、評価や再生成によるAPIコストも発生します。実際に導入する場合は、回答品質の改善効果と追加コストを併せて評価する必要があります。



