SESSION 04

LangGraph +
RAG総合演習

State / Node / Edgeの3概念でグラフを組み立て、全パーツを統合してRAGシステムを完成させる。午前の部の集大成。

12:00 - 12:30(30分)
実践 2トピック
HANDS-ON 01 / 15 MIN
LangGraphの基礎 ── State / Node / Edge

05_langgraph_basics.py

EXERCISE

python 05_langgraph_basics.py を実行

CONCEPT

State

グラフ全体で共有するデータ。辞書に型を付けたもの

CONCEPT

Node

処理の単位。普通のPython関数。Stateを受け取り、更新したい値を辞書で返す

CONCEPT

Edge

処理の順番を定義。add_edgeで繋ぐ

Step 1 ── Stateを定義する
from typing import TypedDict class SimpleState(TypedDict): question: str # ユーザーの質問 answer: str # AIの回答
Step 2 ── Nodeを2つ作る
def log_node(state: SimpleState) -> dict: print(f"受け取った質問: {state['question']}") return {} def answer_node(state: SimpleState) -> dict: response = model.invoke(state["question"]) return {"answer": response.content}
Step 3 ── グラフを組み立てる
from langgraph.graph import StateGraph, END graph = StateGraph(SimpleState) graph.add_node("log", log_node) graph.add_node("answer", answer_node) graph.set_entry_point("log") graph.add_edge("log", "answer") graph.add_edge("answer", END) app = graph.compile()
log_node
answer_node
END
Step 4 ── 実行
result = app.invoke({ "question": "LangGraphとは何ですか?", "answer": "" }) print(f"回答: {result['answer']}")
HANDS-ON 02 / 15 MIN
総合演習 ── LangGraphでRAGシステムを作る

06_rag_with_langgraph.py

EXERCISE

python 06_rag_with_langgraph.py を実行

PDF読込
分割
ベクトル化
格納
質問で検索
LLMが回答
Code コードの全体構成
# --- 準備 --- model = ChatOpenAI(model="gpt-4o-mini", temperature=0) embeddings = OpenAIEmbeddings(model="text-embedding-3-small") loader = PyPDFLoader("data/sample.pdf") pages = loader.load() splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50) chunks = splitter.split_documents(pages) vectorstore = FAISS.from_documents(chunks, embeddings) retriever = vectorstore.as_retriever(search_kwargs={"k": 3}) # --- State --- class RAGState(TypedDict): question: str documents: List[str] answer: str # --- Node --- def retrieve_node(state): docs = retriever.invoke(state["question"]) return {"documents": [doc.page_content for doc in docs]} def generate_node(state): context = "\n\n".join(state["documents"]) prompt = ChatPromptTemplate.from_messages([ ("system", "以下の文書を参考に質問に回答してください。\n\n{context}"), ("human", "{question}") ]) chain = prompt | model | StrOutputParser() return {"answer": chain.invoke({"context": context, "question": state["question"]})} # --- Graph --- graph = StateGraph(RAGState) graph.add_node("retrieve", retrieve_node) graph.add_node("generate", generate_node) graph.set_entry_point("retrieve") graph.add_edge("retrieve", "generate") graph.add_edge("generate", END) app = graph.compile()
retrieve_node
generate_node
END
Map 各パーツの対応関係
コード学んだ場所
PyPDFLoader, TextSplitter, FAISS, RetrieverSession 03
ChatPromptTemplate, LCELSession 02
StateGraph, add_node, add_edgeこの演習の前半
# 期待される出力 質問: PCが起動しない場合の対処手順を教えてください 回答: PCが起動しない場合の対処手順は以下の通りです。 1. 電源ケーブルが正しく接続されているか確認する。 2. 電源ボタンを10秒間長押しして強制シャットダウン...
確認ポイント

PDFの内容に基づいた回答が返ってくれば成功。

EXERCISE

自分で試してみよう

難易度: 低

A. AIの人格を変える

SystemMessageを書き換えて、丁寧語やフランクな口調など異なるトーンで回答させてみる

難易度: 中

B. 検索結果を回答に添付する

generate_nodeの出力にdocumentsを含め、回答の根拠となった文書チャンクも表示する

難易度: 中

C. 複数の質問に連続で答える

質問リストをループで回し、同じグラフに複数回invokeする処理を書いてみる

午前の部 終了

午前の部はここで終了。午後はAI駆動開発(Claude Code)に入ります。

Session 04 参考リンク
LangGraph 公式ドキュメント LangChain RAG チュートリアル LCEL 概要 LangGraph サンプル集(GitHub)