RAG入門:AIに知識を与える技術
ハンズオン:LangChainで基本的なRAGを実装する
このレッスンで分かること
- この記事では「ハンズオン:LangChainで基本的なRAGを実装する」を RAG 実装 の現場で使える形で整理します
- LangChainでRAGを構築するための基本コンセプト をおさえれば、現場で迷ったときに立ち戻れる
- RAGを構成する5つのステップ をおさえれば、現場で迷ったときに立ち戻れる
- ステップバイステップ:PythonによるRAGの実装手順 をおさえれば、現場で迷ったときに立ち戻れる
- 1. ライブラリのセットアップ をおさえれば、現場で迷ったときに立ち戻れる
ハンズオン とは
LangChainを使ってPythonで基本的なRAGを実装する方法を、5つのステップで解説します。テキスト分割やベクトルデータベースの活用など、具体的なコード例を交えて学べる実践的な内容です。
LangChainでRAGを構築するための基本コンセプト
生成AIの力を最大限に引き出し、自社独自の知識を持たせる手法として「RAG(Retrieval-Augmented Generation)」が注目されています。しかし、ゼロから検索エンジンとLLM(大規模言語モデル)を連携させる仕組みを構築するのは容易ではありません。そこで登場するのが、LangChain(ラングチェイン)です。
LangChainは、LLMを用いたアプリケーション開発を効率化するためのオーケストレーションツールです。RAGの実装に必要な「データの読み込み」「テキストの分割」「ベクトルの保存」「情報の検索」といった一連の工程を、標準的なパーツとして提供しています。本レッスンでは、PythonとLangChainを使い、実際に動作するRAGシステムの最小構成をハンズオン形式で学んでいきましょう。
LangChain — RAGの配線をまとめる司令塔。Loader / Splitter / Embedding / Vector Store / Chain を共通インターフェイスで繋ぎ、最小コードで動くパイプラインを組めるのが最大の価値です。
RAGを構成する5つのステップ
LangChainでRAGを実装する場合、一般的に以下の5つのコンポーネントを組み合わせてパイプラインを作成します。
- Document LoadersはPDFやテキスト、Webサイトなどの外部データを読み込む
- Text Splittersは読み込んだデータをLLMが扱いやすい適切な長さに分割する
- Embeddingsはテキストをコンピューターが理解できる数値の羅列(ベクトル)に変換する
- Vector Storesは変換したベクトルデータを保存し、高速に検索できるようにする
- Chainsはユーザーの質問に対して関連情報を検索し、LLMに回答させる一連の流れを定義する
ステップバイステップ:PythonによるRAGの実装手順
それでは、具体的なコードのイメージとともに実装の流れを見ていきましょう。今回は、特定のテキストファイルを知識源として、それに基づいた回答を行うRAGを構築します。
1. ライブラリのセットアップ
まずは必要なライブラリをインストールし、環境変数を設定します。LangChain本体に加え、OpenAIのモデルや、ベクトルデータベースとして軽量な「Chroma(クロマ)」を使用するのが一般的です。
Python
import os
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_chroma import Chroma
from langchain.chains import RetrievalQA
# APIキーの設定
os.environ["OPENAI_API_KEY"] = "your-api-key"2. データの読み込みと分割
次に、外部知識となるドキュメントを読み込みます。ここで重要なのがチャンク分割という工程です。LLMには一度に処理できる文字数に制限があるため、長い文書は小さな塊(チャンク)に分ける必要があります。
Python
# ドキュメントの読み込み
loader = TextLoader("./my_data.txt")
documents = loader.load()
# テキストの分割(1000文字ごと、100文字の重複を持たせる)
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
texts = text_splitter.split_documents(documents)Splitter のパラメータが品質の8割を決める —
chunk_sizeとchunk_overlapは最初に固定値で動かし、評価セットで回しながら詰めるのが現実的です。
避けたい例 ドキュメント全体を一つの大きな塊としてベクトル化し、そのままLLMに渡す。 この方法では、LLMのコンテキストウィンドウ(扱える情報量)を超えてしまい、エラーが発生したり、情報の精度が著しく低下したりします。
良い例 ドキュメントを適切なサイズ(チャンク)に分割し、関連性の高い箇所のみを抽出してLLMに渡す。 LangChainの
RecursiveCharacterTextSplitterなどを使用して、文脈を維持しつつ分割することで、検索精度と回答の質が向上します。
3. ベクトル化とデータベースへの保存
分割したテキストを、OpenAIのEmbeddingモデルを使用して数値ベクトルに変換し、ベクトルデータベースに保存します。これにより、ユーザーの質問と「意味が近い」テキストを瞬時に探し出せるようになります。
Python
# Embeddingモデルの初期化
embeddings = OpenAIEmbeddings()
# ベクトルデータベースの作成(メモリ上に一時保存)
vectorstore = Chroma.from_documents(documents=texts, embedding=embeddings)4. 検索と回答生成(Chainの構築)
最後に、検索機能(Retriever)とLLMを組み合わせた「Chain(鎖)」を作成します。これにより、「質問を受け取る → データベースから情報を探す → LLMに情報を渡す → 回答を得る」という一連の処理が自動化されます。
Python
# 検索エンジンの設定
retriever = vectorstore.as_retriever()
# QAシステムの構築
qa_chain = RetrievalQA.from_chain_type(
llm=ChatOpenAI(model="gpt-4o-mini"),
chain_type="stuff",
retriever=retriever
)
# 実際に質問してみる
query = "自社の福利厚生制度について教えてください"
response = qa_chain.run(query)
print(response)RAG実装において考慮すべき「精度向上」のポイント
基本的なRAGは上記の手順で実装できますが、業務レベルで活用するには、さらにいくつかのパラメータ調整が必要になります。
- チャンクサイズの最適化は
chunk_sizeが小さすぎると文脈が失われ、大きすぎるとノイズ(不要な情報)が混ざります。扱うデータの特性に合わせて調整が必要です。 - 重複(
Overlap)の設定はチャンク同士に少し重なりを持たせることで、文章の途中で情報が途切れるのを防ぎます。 プロンプトテンプレートの活用はLLMに渡す指示(「あなたは誠実なアシスタントです。以下の資料に基づいて回答してください」など)をカスタマイズすることで、回答のトーンを安定させることができます。
やってみよう もし、社内規定のPDFを読み込ませたときに「回答が不正確だ」と感じたら、どのステップを見直すべきでしょうか?
chunk_sizeを変えてみる- 検索エンジンが取得するドキュメントの数(k値)を増やしてみる
- Embeddingモデルをより高性能なものに変えてみる
これらはすべて正解になり得ます。まずはどのステップで情報が欠落しているのかを特定することが大切です。
まとめ
本レッスンでは、LangChainを用いて基本的なRAGシステムを構築する流れを学びました。Document Loaderから始まり、RetrievalQAで回答を得るまでの一連のパイプラインは、RAG開発の土台となる非常に重要な知識です。まずは手元のテキストデータを使って、自分だけのAI知識ベースを作ってみることから始めてみましょう。
「RAGの実装はパズルのようなものです。一つひとつのコンポーネントを理解して組み合わせることで、AIは驚くほど賢くなります。まずは動くものを作り、そこから徐々に洗練させていきましょう!」 (編集部:プログラミング教育担当)
現場でよくある具体例
- 業務ケース 1 — 社内規程 200 ページに RAG を導入。チャンクサイズ 512、
top-k=5、Re-ranker 有りで Recall@5 が 0.62 → 0.81 - 業務ケース 2 — エンジニア向け技術文書では「コードブロックを 1 チャンク」にしたら検索精度が大きく改善
- 業務ケース 3 — 営業 FAQ では
BM25+ Embedding の Hybrid Retrieval で、固有名詞検索の取りこぼしが減った
次にとるべきアクション
- 手元の社内 PDF / FAQ 10 件で RAG ミニ版を作る —
LangChainかLlamaIndexで構築し、「ハンズオン:LangChainで基本的なRAGを実装する」の論点を試す - チャンクサイズと検索件数を 2 通り試す — 256 / 512 トークン × top-k=3 / 5 など、定量比較する
- 評価指標を 1 つ決める — Recall@k / 回答正答率 / コストのいずれかをチームで KPI 化する
次のレッスン
次は RAGを業務利用する際の注意点:セキュリティ、コスト、精度管理 で、RAGを業務利用する際の注意点:セキュリティ、コスト、精度管理 を学びます。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- LangChain RAG の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. LangChain RAG とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
参考にした出典
- Lewis et al.「Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks」 — RAG の原論文(出典: NeurIPS 2020, https://arxiv.org/abs/2005.11401)
- OpenAI Cookbook「Question answering using embeddings」 — Embedding ベース検索の実装例(出典: OpenAI, https://cookbook.openai.com/examples/question_answering_using_embeddings)
- LangChain 公式ドキュメント「RAG」 — チャンク分割・リトリーバ設計のベストプラクティス(出典: LangChain, https://python.langchain.com/docs/tutorials/rag/)
学習を加速したい方へ
RAG (検索拡張生成) 入門ガイドを体系的にマスターするなら、chotdekiru の無料学習ポータル で実際に手を動かして学習を始めるのがおすすめです。質問・つまずきも現役エンジニアが伴走します。
復習ミニクイズ
RAGの実装において、読み込んだドキュメントを「Text Splitters」でチャンク分割する主な理由として、最も適切なものはどれですか?