0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

8種類のRAGアーキテクチャ解説と実装サンプル集

Posted at

RAG(Retrieval-Augmented Generation)は、大規模言語モデル(LLM)に外部知識を取り込み、より正確で文脈に沿った回答を生成するための手法です。
ここでは、代表的な8種類のRAGアーキテクチャを 概要 → 実例 → 実装サンプル の順で紹介します。

前提として、以下の依存パッケージを使用します。

pip install langchain langchain-openai faiss-cpu chromadb duckduckgo-search neo4j networkx

共通セットアップ:

from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain.docstore.document import Document
from langchain.text_splitter import RecursiveCharacterTextSplitter

llm = ChatOpenAI(model="gpt-4o")
emb = OpenAIEmbeddings()

docs = [
    Document(page_content="返品ポリシー: 未開封なら30日以内に返金可。"),
    Document(page_content="海外発送は一部地域のみ。関税は購入者負担。"),
    Document(page_content="製品AはIP67防水。バッテリーは3000mAh。")
]
splitter = RecursiveCharacterTextSplitter(chunk_size=300, chunk_overlap=30)
chunks = splitter.split_documents(docs)

1. Naive RAG

概要
もっとも基本的なRAG。クエリを埋め込みベクトル化し、ベクトルDBから関連文書を検索してLLMへ渡します。

実例

  • 社内FAQ Bot(Slack経由で社内Wikiを検索)

実装サンプル

from langchain_community.vectorstores import FAISS
from langchain.chains import RetrievalQA

vs = FAISS.from_documents(chunks, emb)
retriever = vs.as_retriever(k=3)

qa = RetrievalQA.from_chain_type(llm=llm, retriever=retriever)
print(qa.run("海外発送の条件を教えて"))

2. Multimodal RAG

概要
テキストだけでなく、画像・音声など複数モーダルの情報を統合検索します。

実例

  • 製造業のトラブルシュート(写真+マニュアル+FAQ)

実装サンプル

from langchain_community.vectorstores import Chroma

img_doc = Document(page_content="製品Aの背面図。USB-Cポートは下部中央。")
multi_chunks = splitter.split_documents(docs + [img_doc])
vs_mm = Chroma.from_documents(multi_chunks, emb)

retriever_mm = vs_mm.as_retriever(k=4)
ctx = retriever_mm.get_relevant_documents("USB-Cポートはどこ?")
print(llm.invoke(f"{[d.page_content for d in ctx]} を参考に回答してください。").content)

3. HyDE(Hypothetical Document Embeddings)

概要
クエリから仮想的な回答文をLLMで作成し、それを埋め込み検索に利用して精度を上げます。

実例

  • 契約書検索(曖昧な法務用語を含む検索)

実装サンプル

from langchain.prompts import PromptTemplate
from langchain.schema import StrOutputParser

hyde_prompt = PromptTemplate.from_template("質問に対する模範解答を簡潔に作成: {q}")
def hyde_search(question):
    hypo = (hyde_prompt | llm | StrOutputParser()).invoke({"q": question})
    vs = FAISS.from_documents(chunks, emb)
    hits = vs.similarity_search_by_vector(emb.embed_query(hypo), k=3)
    ctx = "\n".join([h.page_content for h in hits])
    return llm.invoke(f"{ctx} を参考に回答: {question}").content

print(hyde_search("賠償条項の一般的な例を教えて"))

4. Corrective RAG

概要
初回のRAG結果を自己検証し、不足や誤りがあれば追加検索して修正します。

実例

  • 医療相談AI(正確性の高い情報提供)

実装サンプル

from langchain_community.vectorstores import Chroma

vs_corr = Chroma.from_documents(chunks, emb)
retriever_corr = vs_corr.as_retriever(k=3)

def corrective_rag(q):
    ctx1 = retriever_corr.get_relevant_documents(q)
    ans1 = llm.invoke(f"{[d.page_content for d in ctx1]} を参考に: {q}").content
    grade = llm.invoke(f"この回答の正確性を0-1で評価。不足あれば'不足'と出力:\n{ans1}").content
    if "不足" in grade:
        ctx2 = retriever_corr.get_relevant_documents(q + " 詳細")
        ctx = ctx1 + ctx2
        return llm.invoke(f"{[d.page_content for d in ctx]} を参考に正確に回答: {q}").content
    return ans1

print(corrective_rag("海外発送の条件をまとめて"))

5. Graph RAG

概要
データをノードと関係で構造化して検索します。

実例

  • 脅威インテリジェンス分析(攻撃者→手法→脆弱性)

実装サンプル

import networkx as nx

G = nx.MultiDiGraph()
G.add_edge("製品A", "特性", relation="IP67防水")
G.add_edge("製品A", "バッテリー", relation="3000mAh")

def graph_retrieve(q):
    facts = [f"{u}-{d['relation']}->{v}" for u,v,d in G.edges(data=True)]
    return "\n".join(facts)

print(llm.invoke(f"以下の関係から質問に答えて:\n{graph_retrieve('製品A')}\n製品Aの特性は?").content)

6. Hybrid RAG

概要
ベクトル検索とグラフ検索を組み合わせます。

実例

  • 新薬研究(論文類似検索+化合物関係探索)

実装サンプル

vs_hybrid = FAISS.from_documents(chunks, emb)
retriever_hybrid = vs_hybrid.as_retriever(k=3)

def hybrid_rag(q):
    v_hits = retriever_hybrid.get_relevant_documents(q)
    graph_ctx = graph_retrieve(q)
    ctx = "\n".join([d.page_content for d in v_hits]) + "\n" + graph_ctx
    return llm.invoke(f"{ctx} を参考に: {q}").content

print(hybrid_rag("製品Aの仕様を教えて"))

7. Adaptive RAG

概要
クエリの難易度やタイプに応じて検索戦略を切り替えます。

実例

  • EC顧客サポート(FAQ直回答/詳細検索切替)

実装サンプル

from langchain_community.vectorstores import FAISS

def classify(q):
    return llm.invoke(f"質問を0=簡単,1=通常,2=複雑で分類: {q}").content[0]

def adaptive_rag(q):
    t = classify(q)
    if t == "0":
        return "FAQから即回答"
    elif t == "2":
        return "質問を分解して複数回RAG実行"
    else:
        return qa.run(q)

print(adaptive_rag("送料はいくら?"))

8. Agentic RAG

概要
複数エージェントや外部ツールを組み合わせ、計画・実行を分担します。

実例

  • マーケット調査(Web検索+社内DB+分析)

実装サンプル

from langchain.agents import initialize_agent, AgentType, Tool
from langchain_community.tools import DuckDuckGoSearchRun

def rag_tool_run(q:str)->str:
    docs = retriever.get_relevant_documents(q)
    return "\n".join([d.page_content for d in docs])

tools = [
    Tool(name="RAG", func=rag_tool_run, description="社内ドキュメント検索"),
    Tool(name="WebSearch", func=DuckDuckGoSearchRun().run, description="ウェブ検索")
]

agent = initialize_agent(tools=tools, llm=llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION)
print(agent.run("海外発送ルールと一般的な国際配送条件をまとめて"))

まとめ

  • Naive RAG: 最初の一歩に最適
  • Multimodal RAG: 図面・画像込みの検索
  • HyDE: 曖昧な質問に強い
  • Corrective RAG: 正確性最優先
  • Graph/Hybrid RAG: 関係性を活用
  • Adaptive RAG: 問合せ難易度に応じて戦略切替
  • Agentic RAG: 外部APIや複数タスク統合
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?