はじめに
AIが急速に進化する中で、特に注目を集めているのがRAG(Retrieval-Augmented Generation)です。この手法は、生成AIが学習していないデータにおいても正確な情報を提供するためにデータベースから関連情報を検索し、それを基に回答を生成するというアプローチを取ります。本記事では、RAGの基本概念から、その仕組みや実装方法まで詳しく解説します。
1. RAGとは何か?
RAGとは、情報検索(Retrieval)と生成(Generation)を組み合わせた手法を指します。 生成AIに学習済みではない知識に関する回答を出力させるために、データベースから取得した情報と組み合わせて回答させるということです。これにより、生成されるテキストの正確性と有用性が大幅に向上します。
一方、同じく学習していない知識に関する回答を生成する手法としてファインチューニングがありますが、ファインチューニングでは新たな情報を取り込むために再トレーニングが必要です。また、カスタマイズされたモデルを運用するために、サーバーやクラウドの維持管理コストがかかります。この点で、RAGはより手軽に実装できるという利点があります。
2. RAGの仕組み
RAGは主に以下の2つのステップで動作します。
- 情報検索:与えられた質問やプロンプトに対して、関連する情報をデータベースから取得します。
- テキスト生成:1で取得した情報を基にプロンプトを作成し、LLMが適切な応答や文章を作成します。
これにより、生成されるテキストは、LLMの学習済みの知識に加えて、外部情報を反映した回答となります。
3. RAGの利点
RAGには以下のような利点があります。
- 正確性:事前に取得した情報を基に回答を生成するため、誤情報のリスク(ハルシネーション)が低くなります。
- 柔軟性:データベースに情報を格納するため、特定の専門分野や最新の情報にも対応可能です。
4. RAGの主な応用例
RAGにはたくさんの利用用途があります。
- カスタマーサポート:ユーザーからの質問に対して、既存のナレッジベースを検索し、最適な回答を生成することができます。
- コンテンツ生成:企業のブログやニュースレターの作成において、最新情報や関連データを取り込みながら、質の高いコンテンツを効率的に作成するのに役立ちます。
- 教育と学習:教育分野では、学生の質問に対して、教科書や論文などの信頼性の高い情報を引用しつつ、解説を提供することができます。
5.RAGの実装方法
RAGにはLLMのモデルだけではなく埋め込みモデル(Embedding Model)が必要です。
埋め込みモデルは、テキストやその他のデータを数値ベクトルに変換する機械学習モデルの一種です。
では、さっそく実装に移ります。 Azure OpenAI ServiceとAmazon Bedrockなどのサービスを用い、それぞれのモデルにアクセスできるようにしておいてください。
今回はSpring AIとAzure OpenAI Serviceを使用し、LLMはGPT-4o、埋め込みモデルはtext-embedding-ada-002を使用しました。
また今回はSpring Initializrから雛形生成を行いました。Gradle / Kotlin / Spring Boot 3.2.4 を選択し、依存ライブラリとしてAzure OpenAIと動作確認のAPI提供のためにSpring Webを追加しておきます。
build.gradleの依存を確認すると以下のようにspring-ai-azure-openai-spring-boot-starter
とorg.springframework.boot:spring-boot-starter-web
が記載されていると思います。
dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'com.fasterxml.jackson.module:jackson-module-kotlin' implementation 'org.jetbrains.kotlin:kotlin-reflect' implementation 'org.springframework.ai:spring-ai-azure-openai-spring-boot-starter' testImplementation 'org.springframework.boot:spring-boot-starter-test' }
では、実装していきます。まずベクトルストアをApplicationConfiguration
に実装します、今回は"RAGとは、情報検索(Retrieval)と生成(Generation)を組み合わせた手法を指します。"
というドキュメントのみベクトルストアに格納してます。
@Configuration class ApplicationConfiguration { @Bean fun vectorStore(embeddingModel: EmbeddingModel): SimpleVectorStore { val vectorStore = SimpleVectorStore(embeddingModel) vectorStore.add(listOf(Document("RAGとは、情報検索(Retrieval)と生成(Generation)を組み合わせた手法を指します。"))) return vectorStore } }
次にサービスクラスを追加します。ここでは上で実装したベクトルストアを使いLLMにリクエストを投げます。
@Service class RagService(private val client: ChatModel, private val vectorStore: SimpleVectorStore) { fun chat(message: String): String { val docs: List<Document> = vectorStore.similaritySearch(message) val iterator: Iterator<Document> = docs.iterator() val context: String = iterator.next().content val prompt = """ 以下の情報のみを用いて質問に回答してください。 ============== %2${'$'}s ============== 質問: %1${'$'}s """.trimIndent().formatted(message, context) return client.call(prompt) } }
コントローラクラスを追加します。
@RestController class RagController(private val service: RagService) { @PostMapping("/rag") fun chat(@RequestBody request: ChatRequest): ChatResponse { return ChatResponse(service.chat(request.message)) } data class ChatRequest(val message: String) data class ChatResponse(val result: String) }
最後にapplication.yaml
にモデルの設定を記述します。
spring: application: name: demo ai: azure: ## APIの設定を記述 openai: api-key: xxxx endpoint: xxxx ### LLM用のモデルの設定を記述 chat: options: deployment-name: XXXX ### embedding用の設定を記述 embedding: metadata-mode: EMBED options: deployment-name: XXXX
起動してリクエストを送ってみます。
./gradlew bootRun
$ curl -H "Content-Type: application/json" \ -d '{"message": "RAGについて教えて"}' localhost:8080/rag
{ "result": "RAGとは、情報検索(Retrieval)と生成(Generation)を組み合わせた手法を指します。" }
無事ベクトルストアに入っている情報を用いて回答を生成しました。
6. RAGの課題
ここまでRAGについて紹介してきましたが、その性質上、いくつかの課題も抱えています。RAGを活用する上で直面する可能性のある課題について紹介します。
- 情報取得失敗: データベースから必要な情報が取れない場合、回答できないことがあります。
- 遅延: データを取得してから回答生成するため、通常の生成より時間がかかる場合があります。
- データの信頼性: 誤った情報を取得してしまった場合、正しく回答できない場合があります。
- 一貫性の問題: 外部データが正確で最新でない場合、応答に影響が出る場合があります。
- データの整備: RAGで使用するためにデータの整備をして情報検索しやすくする必要があります。
まとめ
RAGは、生成AIの分野で重要な技術です。情報検索と生成の組み合わせにより、より正確で有用なテキスト生成が可能となり、様々な分野での応用が期待されています。ぜひRAGを活用して、柔軟で効率的なアプリケーション作成にお役立てください。
新卒5年目のエンジニア。激辛が好き。好きな唐辛子はキャロライナリーパー🌶