見出し画像

VertexAI Geminiを使ってみる|Langchainを使ってRAGをする。


*GCPでVertexAIのAPIが有効になっている前提での記事になります。

Googleが開発しているGeminiの呼び出しについて書きましたが、

今回は、LangChainとGeminiを使ったRAGをしてみたいと思います。AzureのGPTを使った記事を書いていますが、基本的には同じです。言語モデルの呼び出しをGeminiにして、埋め込みモデルもVertexAIから呼び出します。

LLM

現在VertexAIで利用できる主な言語モデルは、以下の3つになります。
Gemini 1.5 Flash
Gemini 1.5 Pro
Gemini 2.0 Flash

Embedding model

・text-embedding-005
・text-multilingual-embedding-002

公式によると、英語のテキストには、text-embedding-005を使用して、多言語には、text-multilingual-embedding-002を使用するというこです。

実装
必要なライブラリーの呼び出し。

#langchain-google-vertexai=2.0.8  
#langchain-text-splitters=0.3.2 
#langchain-chroma=0.1.4 
#langchain-core=0.3.24   

from langchain_google_vertexai import VertexAI
from langchain_google_vertexai import VertexAIEmbeddings

from langchain_text_splitters import MarkdownHeaderTextSplitter
from langchain_chroma import Chroma

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser

ドキュメントの分割とリトリーバーの定義。
ドキュメントには「ジョジョの奇妙な冒険」についてのドキュメントを使用します。

# Load example document
with open("jojo.md") as f:
    state_of_the_union = f.read()

# Markdown見出しで文章を分割します    
headers_to_split_on = [
    ("#", "Header 1"),
    ("##", "Header 2"),
    ("###", "Header 3"),
    ("####", "Header 4"),
]    

markdown_splitter = MarkdownHeaderTextSplitter(
    headers_to_split_on=headers_to_split_on,
    strip_headers = False #コンテンツび分割されるヘッダーを含めるかどうか
    )

md_header_splits = markdown_splitter.split_text(state_of_the_union)

documents = md_header_splits

# Initialize the a specific Embeddings Model version
#embeddings = VertexAIEmbeddings(model_name="text-embedding-004")
embed = VertexAIEmbeddings(model_name="text-multilingual-embedding-002")

# VectorStoreの準備
vectorstore = Chroma.from_documents(
    documents,
    embedding=embed,
    #collection_name="example_collection",
    #persist_directory="./chroma_langchain_db",  # Where to save data locally, remove if not neccesary
)   

# Retrieverの準備
retriever = vectorstore.as_retriever()

LLMの定義

RESOURCE_ID = "gemini-1.5-flash-002"
#RESOURCE_ID = "gemini-1.5-pro-002"
#RESOURCE_ID ="gemini-2.0-flash-exp"

# To use model
llm = VertexAI(model_name=RESOURCE_ID)

レスポンスの取得

# プロンプトテンプレートの準備
message = """
提供されたコンテキストのみを使用して、この質問に答えてください。
    - 回答は次のフォーマットで記述してください。

        (ここに回答内容を記述)
        ### 参考ドキュメント
        (ここに'Header 1'と'Header 2'を記述)

{question}

Context:
{context}
"""

prompt = ChatPromptTemplate.from_messages([("human", message)]) 

output_parser = StrOutputParser()

# RAGチェーンの準備
rag_chain = ({"context": retriever, "question": RunnablePassthrough()} 
| prompt 
| llm
| output_parser
)

# ユーザー入力
user_input="ジョセフ・ジョースターについて教えてください。"

result = rag_chain.invoke(user_input)
print(result)

ジョセフ・ジョースターは、『ジョジョの奇妙な冒険』Part2『戦闘潮流』の主人公です。ジョナサン・ジョースターの孫であり、1920年9月27日生まれ、身長195cm、体重97kg、B型です。生まれつきの波紋使いであり、シーザー・ゼッペリと共に「柱の男」と戦います。彼は好奇心旺盛で旅行好きであり、ジョースター家の男性に共通する高身長で頑健な体格を持っています。また、ジョースター家の代々続く「短命」や「生涯1人の異性しか愛さない」というジンクスを破っています。Part6でも生存しており、多少ボケているものの生きていると作者の荒木飛呂彦先生は述べています。 彼の母親はリサリサ(エリザベス・ジョースター)です。


### 参考ドキュメント
Header 1: 1 シリーズ構成, Header 2: Part 2 『戦闘潮流』
Header 1: 3 ジョースター家・家系図, Header 2: (Header2は明示的に記載されていない)

text-embedding-005を使用するとどうなるか試してみます。

embed = VertexAIEmbeddings(model_name="text-embedding-005")

このテキストにはジョセフ・ジョースターについての記述がありません。そのため、質問にお答えすることはできません。


### 参考ドキュメント
Header 1: 作風, Header 2: 悪役観
Header 1: 作風, Header 2: キャラクター作り
Header 1: 作風, Header 2: ファッション
Header 1: 作風, Header 2: カラーリング

いろいろドキュメントを取得しているようですが、ジョセフについてのドキュメントをとってこれていないようです。
念のため、

user_input="花京院について教えてください。"

このコンテキストからは、花京院についての情報は得られません。


### 参考ドキュメント
Header 1: 作風, Header 2: 悪役観
Header 1: 作風, Header 2: キャラクター作り
Header 1: 作風, Header 2: ファッション
Header 1: 作風, Header 2: カラーリング

なぜか、同じドキュメントを取得しいますが、やはり回答はできないようです。

embed = VertexAIEmbeddings(model_name="text-multilingual-embedding-002")

とすれば、

花京院典明は、承太郎の通う高校に転校してきた17歳の高校生です。身長178センチメートル、体重65キログラム、血液型A型で、生まれつきのスタンド使いです。端正な顔立ちで、DIOによって「肉の芽」を植え付けられ、承太郎への最初の刺客として登場します。承太郎との戦闘後、「肉の芽」を取り除かれ、正気を取り戻し、その後ジョースター一行に加わってDIOを倒すためエジプトへ向かいます。冷静沈着で洞察力に優れ、一行の中では比較的控えめで礼儀正しい性格ですが、悪質な敵には容赦しません。チェリーが好物で、テレビゲームも得意です。旅の途中で負傷し、サングラスをかけて戦線復帰しますが、DIOとの決戦で致命傷を負い死亡します。彼のスタンドは「ハイエロファントグリーン」で、遠隔操作型のスタンドです。


### 参考ドキュメント
Header 1: 1 シリーズ構成, Header 2: Part 3 『スターダストクルセイダース』

いいなと思ったら応援しよう!