こんにちは! 気ままなねぎとろ♪ です。😊
お待たせしました! 「PythonでRAG!Gemini APIで動かす」の【後編】です!
▼【前編】をまだ読んでいない方は、こちらからどうぞ!
PythonでRAG!Gemini APIで動かす(前編)〜いろんなファイルを食べさせる準備〜 - プログラミング ときどき 雑談
【前編】では、Excelのデータを読み込んで、AIが食べやすい一口サイズにカットして、いつでも取り出せる「魔法の冷蔵庫(FAISS)」に入れるところまで、RAGの【下ごしらえ】をやりましたね。
今回の【後編】では、いよいよこの「魔法の冷蔵庫」を使って、 「Gemini 2.5 Proに、Excelの中身について質問する」 という、RAGの一番楽しい「心臓部」の組み立て&実行をしていきますよー!
果たして、AIはちゃんとExcelの中身を理解して、私たちの質問に答えてくれるんでしょうか…?
さっそく、コードを見ていきましょう!
ステップ6:RAGの心臓部!「チェーン」を組み立てよう
さあ、いよいよ【後編】のメインディッシュです! 【前編】で準備した「魔法の冷蔵庫(vectorstore)」から、どうやってAI(Gemini)に質問を投げて、賢い答えをもらうのか?
その「一連の流れ(=チェーン)」を、LangChain (LCEL) を使って組み立てていきますよー!
rag-test.pyのコードだと、この部分!
# --- LangChainの魔法の道具をインポート --- from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnableParallel, RunnablePassthrough from langchain_core.output_parsers import StrOutputParser from langchain_google_genai import ChatGoogleGenerativeAI # (中略) # 4. 《実行》RAGチェーンの組み立て print("--- RAGの仕組みを組み立てます ---") # DBから質問に関係する文書を探してくる部品(リトリーバー) retriever = vectorstore.as_retriever(search_kwargs={"k": 10}) # Geminiに渡すための指示書(プロンプトテンプレート) template = """ あなたは質問応答アシスタントです。以下の取り出した文脈を元に質問に答えてください。 もし文脈に答えがなければ、わからないと答えてください。 文脈: {context} 質問: {question} """ prompt = ChatPromptTemplate.from_template(template) # Geminiモデルを準備 model = ChatGoogleGenerativeAI(model="gemini-2.5-pro", temperature=0) # これまで準備した部品をぜんぶ繋げて、RAGの一連の流れ(チェーン)を定義! rag_chain = ( RunnableParallel( context=retriever, question=RunnablePassthrough() ) | prompt | model | StrOutputParser() )
なんだか急に「|」(パイプ)とか「RunnableParallel」とか出てきて、難しそうに見えますよね!?
大丈夫、私も最初「なにこれ!?」ってなりました!
これは、LangChainの新しい書き方(LCEL)っていうらしくて、「処理の流れ」を|(パイプ)でつないでいく書き方なんだそうです。
ここでやってることを、ゆるーく分解すると、こんな感じです。
1. 必要な「部品」を準備する
★retriever(検索係さん)
vectorstore.as_retriever(...)これは、【前編】で作った「魔法の冷蔵庫」から、質問に関係ありそうなデータ(search_kwargs={"k": 10} なので、最大10個)を、超高速で取ってきてくれる「検索係」です。
★prompt(指示書)
ChatPromptTemplate.from_template(template)これは、Geminiに渡す「指示書」のテンプレートです。
「あなたはアシスタントだよ!この
{context}(検索係さんが取ってきたデータ)と{question}(私たちが聞く質問)を元に、答えてね!」って書いてあります。
★model(AI本体)
ChatGoogleGenerativeAI(model="gemini-2.5-pro", ...)今回の主役、賢い「Gemini 2.5 Pro」くん本人です。
2. 「部品」を|(パイプ)でつなげる!
そして、最後のrag_chain = (...)の部分が、その部品を流れ作業(パイプライン)でつなげているところです。
# ここがRAGの「流れ」 rag_chain = ( # (A) まず、私たちが聞く「質問」を、 # 「検索係(retriever)」と「そのまま(Passthrough)」に同時に渡す! RunnableParallel( context=retriever, # ← 検索係は「質問」をもとに冷蔵庫から{context}を探す question=RunnablePassthrough() # ← 質問は{question}としてそのまま流す ) # (B) (A)の結果({context}と{question})を、 # 「指示書(prompt)」にぜんぶ書き込む! | prompt # (C) (B)で完成した「指示書」を、 # 「AI本体(model)」に渡して、答えを考えてもらう! | model # (D) (C)の答え(AIの難しいデータ)を、 # 「キレイな文字(StrOutputParser)」に変換してもらう! | StrOutputParser() )
こんな感じ! LangChain (LCEL) を使うと、「データを取ってきて」→「指示書にセットして」→「AIに渡して」→「答えをキレイにする」っていう一連の流れ(チェーン)を、こんなにスッキリ書けちゃうんですね。
ステップ7:いよいよ、AIに質問してみよう!
お待たせしました!ついに、私たちが作ったRAGシステムに、質問を投げかける時が来ました!
【前編】で読み込ませたExcelファイル(sample.xlsx)の中身について、ちゃんと答えてくれるんでしょうか…?
rag-test.pyのコードだと、この最後の部分です!
# 5. 《実行》RAGに質問してみる! print("--- RAGに質問します ---") question = "ねぎとろ商店のトータル金額は?" print(f"質問: {question}") response = rag_chain.invoke(question) # 6. 回答の表示 print("\n------ 回答 ------") print(response) print("--------------------")
question = "..." のところに、聞きたいことを書くだけ! あとは、rag_chain.invoke(question)っていう呪文が、さっきのステップ6で組み立てた流れ(検索→指示書作成→AI回答→キレイな文字に)を、ぜーんぶ自動でやってくれるんです!
果たして、結果は…!?

【後編】まとめ:動いたー!これがRAGだ!
やりましたー!(≧▽≦) 「ねぎとろ商店のトータル金額は?」って聞いたら、ちゃんとExcelの中から答えを探してきてくれました!

これで、 「AIに、自分の好きなファイル(Excelとか)を食べさせて、その内容にもとづいて賢く答えてもらう技術」 …そう、「RAG」が、私たちの手で完成しましたね!
Gemini API と LangChain を使えば、意外と(Markdownのクセと戦う方が大変だったかも?笑)スッキリしたコードで作れちゃうんだなーって、私も感動しました!
ローカルLLMを動かすのはPCのスペックも必要だけど、Gemini APIなら高性能な gemini-2.5-pro が手軽に使えて、本当に便利ですよね。
皆さんも、自分のExcelファイルやPDFを読み込ませて、オリジナルRAGで遊んでみてくださいね!
(ここまで【前編】【後編】と読んでくださって、本当にありがとうございました!😊)
【おまけ】RAG(前編・後編)の全部入りコード
import os from dotenv import load_dotenv # --- LangChainの魔法の道具をインポート --- from langchain_google_genai import ChatGoogleGenerativeAI, GoogleGenerativeAIEmbeddings from langchain_community.vectorstores import FAISS from langchain_community.document_loaders import UnstructuredExcelLoader from langchain_text_splitters import RecursiveCharacterTextSplitter from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnableParallel, RunnablePassthrough from langchain_core.output_parsers import StrOutputParser from langchain_core.documents import Document # 0. APIキーの準備 # .envファイルからAPIキーを読み込む load_dotenv() # 環境変数からAPIキーを読み込む(もし.envがなくてもOSに設定されていればOK) if "GOOGLE_API_KEY" not in os.environ: os.environ["GOOGLE_API_KEY"] = "(ここにAPIキーを入れてね)" # --- ここからRAGの処理スタート! --- # 1. 《下準備》データの準備 # "sample.xlsx"という名前のExcelファイルを読み込む loader = UnstructuredExcelLoader("sample.xlsx") documents = loader.load() # 2. 《下準備》データの分割(チャンキング) text_splitter = RecursiveCharacterTextSplitter(chunk_size=250, chunk_overlap=30) split_docs = text_splitter.split_documents(documents) print("--- データを2つのかたまりに分割しました ---") # 3. 《下準備》ベクトル化してデータベースに保存 print("--- データをベクトル化して、DBに保存します ---") embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001") vectorstore = FAISS.from_documents(split_docs, embeddings) # 4. 《実行》RAGチェーンの組み立て print("--- RAGの仕組みを組み立てます ---") # DBから質問に関係する文書を探してくる部品(リトリーバー) retriever = vectorstore.as_retriever(search_kwargs={"k": 10}) # Geminiに渡すための指示書(プロンプトテンプレート) template = """ あなたは質問応答アシスタントです。以下の取り出した文脈を元に質問に答えてください。 もし文脈に答えがなければ、わからないと答えてください。 文脈: {context} 質問: {question} """ prompt = ChatPromptTemplate.from_template(template) # Geminiモデルを準備 model = ChatGoogleGenerativeAI(model="gemini-2.5-pro", temperature=0) # これまで準備した部品をぜんぶ繋げて、RAGの一連の流れ(チェーン)を定義! rag_chain = ( RunnableParallel( context=retriever, question=RunnablePassthrough() ) | prompt | model | StrOutputParser() ) # 5. 《実行》RAGに質問してみる! print("--- RAGに質問します ---") question = "ねぎとろ商店のトータル金額は?" print(f"質問: {question}") response = rag_chain.invoke(question) # 6. 回答の表示 print("\n------ 回答 ------") print(response) print("--------------------")













