はじめに
LangChainのv1.0がリリースされたということで、触ってみることにした。
https://docs.langchain.com/oss/python/releases-v1
以前LangChain v0.3でRAGを構築したことがあったので、手始めに同じコードで動くか確認してみることにした。
記事:https://qiita.com/yum11/items/edf9d7338b8ef03c3f8f
結論
特にコードを変えず動かすことができた。ただライブラリのインストールに少し手間取った。
以前の記事と同じ内容になるが、以下に実装の流れとコードを載せる。
実装
LangChainとOpenAI APIを使ってシンプルなRAGを作ってみた。
- 検索対象ドキュメント:ローカルにあるPDFファイル
- embeddingモデル:OpenAIのtext-embedding-ada-002
- ベクトルDB:LangchainのInMemoryVectorStore
- LLM:OpenAIのgpt-4o-mini
Pythonと主なライブラリのバージョン
- python==3.11.11
- langchain==1.0.0a4
- langchain-community==0.3.29
- langchain-core==1.0.0a2
- langchain-openai==1.0.0a2
- pypdf==6.0.0
※ OSはMac
langchain v1.0は以下のように入れた。
pip install --pre -U langchain
今回のコードを動かすには、langchain-community、langchain-openaiのインストールが必要になる。
langchain-communityは現在v0.3が最新でlangchain v1.0と互換性があるようで、v0.3で問題なく動く。
langchain-openaiはv1.0がリリースされており、v1.0をインストールしないとうまく動かなかった。
pip install --pre langchain-openai==1.0.0a2
どこかの段階で(確かpypdfのインストール後)、cryptographyのDependencyErrorが出たので、最新版のライブラリを入れた。
pip install -U cryptography
なお、langchain-core v1.0はlangchainをインストールする際に同時にインストールされる。
ドキュメントの用意
- 内閣府が公開している月例経済報告のpdfファイルをダウンロードして使うことにする。
- 今回は9月、10月、11月の3つのpdfファイルを使う。
OpenAIのAPIキーの設定
- 実行するpythonファイルと同じ階層に.envファイルを作成。
- .envファイルにOpenAIのAPIキーを記載。
OPENAI_API_KEY="your-api-key"
- python-dotenvで環境変数を設定。
from dotenv import load_dotenv
load_dotenv()
ドキュメントの読み込み
- LangChainのPyPDFLoaderを使って読み込む。
- pdfファイルはページ単位で読み込む。
from langchain_community.document_loaders import PyPDFLoader
# pdfファイルのリスト
file_paths = ["./内閣府月例経済報告_202409.pdf", "./内閣府月例経済報告_202410.pdf", "./内閣府月例経済報告_202411.pdf"]
# pdfファイルの各ページを格納するリスト
pages = []
for file_path in file_paths:
loader = PyPDFLoader(file_path)
for page in loader.load():
pages.append(page)
ドキュメントのベクトル化とベクトルDBへの格納
- OpenAIのembeddingモデルtext-embedding-ada-002を使ってドキュメントをベクトル化。
- LangchainのInMemoryVectorStoreをベクトルDBとして使う。
from langchain_core.vectorstores import InMemoryVectorStore
from langchain_openai import OpenAIEmbeddings
vector_store = InMemoryVectorStore.from_documents(pages, OpenAIEmbeddings())
RAG chainの作成
- RAGを実現するchainは、LCEL(LangChain Expression Language)で記載。
- Prompt template、LLM model、Output parserを繋げる基本の形を採用。
- ChatPromptTemplateでプロンプトのテンプレートを作る。
- ユーザーの質問が変数questionに入り、ベクトルDBの検索結果が変数contextに格納される。
- ChatOpneAIでLLMの設定をする。
- 検索を行うretriverはvectore_storeのas_retrieverメソッドで設定。
- as_retrieverはデフォルトで類似検索を行う。
- as_retrieverの引数search_kwargsを使って、検索方法を指定することができる。
-
search_kwargs={"k": 3}は、検索結果を3個に絞っている。
-
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI
prompt = ChatPromptTemplate.from_template('''
以下の文脈だけを踏まえて質問に回答してください。
文脈: """
{context}
"""
質問: {question}
''')
model = ChatOpenAI(model="gpt-4o-mini", temperature=0)
retriever = vector_store.as_retriever(search_kwargs={"k": 3})
chain = {
"question": RunnablePassthrough(),
"context": retriever,
} | prompt | model | StrOutputParser()
RAGによる回答
- chainのinvokeメソッドを使い、質問をインプット。
query = "11月の月例経済報告の開催日は?"
chain.invoke(query)
- 以下のようにドキュメントの情報を元にLLMが回答してくれた。
'11月の月例経済報告の開催日は令和6年11月26日です。'
- 別の質問:9月の製造業での雇用人員判断DIは?
- 回答:
'9月の製造業での雇用人員判断DIは-22です。'
参考
- LangChainとLangGraphによるRAG・AIエージェント[実践]入門
- LangChain公式サイト

