🐒

Pythonで学ぶRAG入門 ― LangChainとStreamlitで作る質問箱アプリ

に公開

✨ はじめに

こんにちは、リーディング・エッジ社でAIエンジニアをしている和泉です。
今回は、LangChainを使って RAG(Retrieval-Augmented Generation) を体験できる「質問箱アプリ」を作るサンプルプログラムをご紹介したいと思います。
今回の記事の対象者は RAG を使ったことがない Python エンジニアです。

🧩 RAGの仕組み

まず、RAGの流れをイメージしましょう。

RAGの本質は「LLM単体では持たない情報を、ベクトル検索で補強してから回答させる」ことです。


🛠 アプリの構成

  • UI: Streamlit(チャット UI / ストリーミング表示)
  • RAG 実装: LangChain
    • Embeddings: OpenAIEmbeddings
    • Retriever / VectorStore: Chroma
    • チェーン構築: Runnable パイプ演算子(|
  • 履歴保存: SQLChatMessageHistory(SQLite)
  • 実行環境: Docker / docker-compose
  • リポジトリ: rag_sample

💡 RAG の中核コードを理解する

1) ベクトルストア(Chroma)のロード

from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
from client import client

def load_vector_store():
    embeddings = OpenAIEmbeddings()
    vector_store = Chroma(
        embedding_function=embeddings,
        persist_directory="./data/rag_data",
        client=client,  # chromadb.PersistentClient(path="./data/rag_data")
    )
    return vector_store

Chroma に保存されたベクトル DB をロードし、Retriever として利用可能にします。


2) プロンプト生成(ChatPromptTemplate)

from langchain_core.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_template("""
あなたは参考文書を基に質問に回答するアシスタントです。
以下の参考文書の内容を基に、ユーザーの質問に回答してください。

参考文書:
{context}

質問:
{question}
""")
  • {context} に Retriever で取得した文脈
  • {question} にユーザーの入力
    を差し込むテンプレートです。

3) チェーンの構築

from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.5)

st.session_state.chain = {
    "question": RunnablePassthrough(),
    "context": st.session_state.vector_store.as_retriever()
} | prompt | llm
  • RunnablePassthrough: ユーザーの質問をそのまま渡す
  • Retriever: ベクトルDBから文脈を検索
  • | prompt | llm: LangChain のパイプで「質問+文脈 → プロンプト → LLM」と流れる

4) 出力処理(ストリーミング表示)

if question := st.chat_input("質問を入力してください"):
    with st.chat_message("assistant"):
        response = st.write_stream(
            st.session_state.chain.stream(question)
        )
        st.session_state.history.add_user_message(question)
        st.session_state.history.add_ai_message(response)
  • chain.stream(question) でトークンごとに応答を取得
  • st.write_stream でストリーミング描画 → 自然なチャット体験を実現

🐳 Dockerを用いたアプリの起動方法

1. .env ファイルを準備

cp .env.sample .env

.env に OpenAI API キーを記載します。

OPENAI_API_KEY=sk-xxxx...

2. コンテナを起動

docker-compose up --build

3. ブラウザでアクセス

http://localhost:8501

🎯 まとめ

今回は、LangChainとStreamlitを用いて、RAGアプリを作成してみました。
今後は、OSSのLLMも登場してきており、企業内でも積極的にローカルRAGアプリケーションの開発が進むと考えられますので、ご興味がある方は参考にして頂けると幸いです。

Discussion