🦜

VertexAIとLangChain サンプルコード集

2024/02/05に公開

はじめに

この記事ではVertexAIとLangChainを使ってLLMから応答を得る方法を探ってみました。

参考資料

準備

最低限に必要なパッケージをインストールします。

pip install --user --upgrade --quiet langchain-google-vertexai urllib3==1.26.18 langchain==0.1.0 urllib3==1.26.18

テンプレートを使ってLLMから応答を得る

シンプルにLLMから応答を得る場合の例です。

from langchain_google_vertexai import VertexAI
from langchain.prompts import PromptTemplate

llm = VertexAI(model_name="gemini-pro", temperature=0)

question_template = """
次のコマンドの概要を説明してください。

コマンド: {command}
"""

prompt = PromptTemplate(
    input_variables=["command"],
    template=question_template
)

result = prompt.format(command="ls")

print(llm.invoke(result))

LLMChainを使ってLLMから応答を得る

Chainsを使ってLLMから応答を得る場合の例です。
Chainsはモジュール同士を連結する役割があり、Chainsを使うことでModelsとPromptsを組み合わせて利用できます。

import langchain
from langchain.chains import LLMChain
from langchain_google_vertexai import VertexAI
from langchain.prompts import PromptTemplate

langchain.verbose = True
gemini = VertexAI(model_name="gemini-pro", temperature=0)

question_template = """
次のコマンドの概要を説明してください。

コマンド: {command}
"""

prompt = PromptTemplate(
    input_variables=["command"],
    template=question_template
)

chain = LLMChain(llm=gemini,prompt=prompt)
result = chain.run("ls")

SimpleSequentialChainを使ってLLMから応答を得る

Chain単位の処理を繋いで回答を得る場合の例です。

import langchain
from langchain.chains import LLMChain
from langchain_google_vertexai import VertexAI
from langchain.prompts import PromptTemplate
from langchain.chains import SimpleSequentialChain

langchain.verbose = False
chat = VertexAI(model_name="gemini-pro", temperature=0)

question_template = """
以下の質問に答えてください。

### 質問 ###
{question}
### 質問終了 ###

ステップバイステップで考えましょう。
"""

question_prompt = PromptTemplate(
    input_variables=["question"],
    template=question_template
)
question_chain = LLMChain(llm=chat, prompt=question_prompt)

summarize_template="""
入力を一言に要約してください。

### 入力 ###
{input}
### 入力終了 ###
"""
summarize_prompt = PromptTemplate(
    input_variables=["input"],
    template=summarize_template
)
summarize_chain = LLMChain(llm=chat, prompt=summarize_prompt)
question_summarize_chain = SimpleSequentialChain(chains=[question_chain,summarize_chain])

result = question_summarize_chain("今日は2024年02月4日です。昨日は何日ですか?")

print(result["output"])

LLMの応答をPythonのオブジェクトにマッピングする

LLMが返したデータをPythonのオブジェクトとして扱えるようにします。

import langchain
from langchain.chains import LLMChain
from langchain_google_vertexai import VertexAI
from langchain.output_parsers import PydanticOutputParser
from langchain.prompts import PromptTemplate
from pydantic import BaseModel, Field, validator
from typing import List

langchain.verbose = True
chat = VertexAI(model_name="gemini-pro", temperature=0)

class Recipe(BaseModel):
    ingredients: List[str] = Field(description="ingredients of dish")
    steps: List[str] = Field(description="step to make the dish")

template = """
料理のレシピを教えてください。

{format_instructions}

料理名:{dish}
"""

parser = PydanticOutputParser(pydantic_object=Recipe)

prompt = PromptTemplate(
    template=template,
    input_variables=["dish"],
    partial_variables={"format_instructions": parser.get_format_instructions()}
)


chain = LLMChain(llm=chat, prompt=prompt)
output = chain.run(dish="カレー")

recipe = parser.parse(output)

print(recipe)
print(type(recipe))

ここから下のソースを実行するために必要なパッケージをインストール

インデックスを使う場合は以下のコマンドでパッケージをインストールしてください。

pip install --user --upgrade unstructured==0.6.6 tabulate==0.9.0 pdf2image==1.16.3 pytesseract==0.3.10 chromadb==0.3.23 tiktoken==0.4.0 faiss-gpu==1.7.2

similarity_search_by_vector

ベクターストアを使って類似文書を検索する場合の例です。
実行する際は同じディレクトリにsample.mdという検索対象のファイルを作成してください。

from langchain_google_vertexai import VertexAI
from langchain_google_vertexai import VertexAIEmbeddings

from langchain.indexes import VectorstoreIndexCreator
from langchain.text_splitter import CharacterTextSplitter

from langchain_community.document_loaders import TextLoader
from langchain_community.vectorstores import FAISS

embeddings = VertexAIEmbeddings(model_name="textembedding-gecko@latest")
documents = TextLoader("./sample.md").load()
text_splitter = CharacterTextSplitter(chunk_size=1196, chunk_overlap=0)
texts = text_splitter.split_documents(documents)
db = FAISS.from_documents(texts, embeddings)

# embeddingあり
embedding_vector = embeddings.embed_query(query)
docs = db.similarity_search_by_vector(embedding_vector)
search_doc = docs[0].page_content

print(search_doc)

なお、本番環境などでは検索にヒットしない場合について考慮する必要があります。

retriever.get_relevant_documents

as_retrieverを使って文書を検索する例です。
実行する際は同じディレクトリにsample.mdという検索対象のファイルを作成してください。

from langchain_google_vertexai import VertexAI
from langchain_google_vertexai import VertexAIEmbeddings

from langchain.indexes import VectorstoreIndexCreator
from langchain.text_splitter import CharacterTextSplitter

from langchain_community.document_loaders import TextLoader
from langchain_community.vectorstores import FAISS

embeddings = VertexAIEmbeddings(model_name="textembedding-gecko@001")
documents = TextLoader("./sample.md").load()
text_splitter = CharacterTextSplitter(chunk_size=1196, chunk_overlap=0)
texts = text_splitter.split_documents(documents)
db = FAISS.from_documents(texts, embeddings)

retriever = db.as_retriever(search_type="similarity")
docs = retriever.get_relevant_documents("LookMLとは")

print(docs[0].page_content)

なお、本番環境などでは検索にヒットしない場合について考慮する必要があります。

ローカル上にあるファイルを使って検索を実行し、LLMから応答を得る

sample.pyというファイルをソースにして検索を実行し、LLMから応答を得る例です。

from langchain_google_vertexai import VertexAI
from langchain_google_vertexai import VertexAIEmbeddings

from langchain.indexes import VectorstoreIndexCreator

from langchain_community.document_loaders import TextLoader
from langchain_community.vectorstores import FAISS

documents = TextLoader("./sample.py")
embeddings = VertexAIEmbeddings(model_name="textembedding-gecko@001")

query = "find_elementsメソッドとは何ですか?"
index = VectorstoreIndexCreator(embedding=embeddings,vectorstore_cls=FAISS).from_loaders([documents])
chat = VertexAI(model_name="text-bison", temperature=0)

result = index.query(query,llm=chat)
print(result)

sample.pyの内容は以下の通りです。

sample.py
from ..config import const
from ..common import _request as req


def find_elements(session_id, using, value):
    return req.post(
        "/".join([const.WEB_DRIVER_URL, session_id, 'elements']),
        headers=const.REQUEST_HEADERS,
        data='{"using": "' + using + '", "value": "' + value + '"}'
    )


def get_property(session_id, element_id, property_name):
    return req.get(
        "/".join([const.WEB_DRIVER_URL, session_id,
                  'element', element_id, 'property', property_name]),
        headers=const.REQUEST_HEADERS,
    )


def is_input_type_text(input_element_type):
    return input_element_type == 'text'


def is_input_type_password(input_element_type):
    return input_element_type == 'password'


def is_input_type_checkbox(input_element_type):
    return input_element_type == 'checkbox'


def is_input_type_button(input_element_type):
    return input_element_type == 'button'

Web上の情報をもとにLLMから応答を取得する

AWS Well-Architected Frameworkから情報を抜き出してLLMから応答を取得します。

from lib import document_connector

from langchain_google_vertexai import VertexAI
from langchain_google_vertexai import VertexAIEmbeddings
from langchain.indexes import VectorstoreIndexCreator
from langchain_community.vectorstores import FAISS


from langchain_community.document_loaders.recursive_url_loader import RecursiveUrlLoader
from langchain.text_splitter import CharacterTextSplitter

# text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
documents = RecursiveUrlLoader("https://docs.aws.amazon.com/ja_jp/wellarchitected/latest/framework/oe-design-principles.html")
embeddings = VertexAIEmbeddings(model_name="textembedding-gecko@001")

query = "設計原則にあるオブザーバビリティについて教えてください。"
index = VectorstoreIndexCreator(
    embedding=embeddings, 
    vectorstore_cls=FAISS
).from_loaders([documents])

chat = VertexAI(model_name="text-bison", temperature=0)

# result = index.query(query, llm=chat)
result = index.query_with_sources(query, llm=chat)
result = f"ans: {result['answer']} {result['sources']}"
print(result)

warning memo

predictメソッド

predictメソッドは廃止されるのでinvokeを使う。

LangChainDeprecationWarning: The function `predict` was deprecated in LangChain 0.1.7 and will be removed in 0.2.0. Use invoke instead.

Google CloudのClud ShellでLangChainを使う場合

Google CloudのClud ShellでLangChainを使う場合は以下のコマンドを投入後にストレージサイズが足りない旨のエラーが発生するので注意してください。

pip install --upgrade unstructured==0.6.6 tabulate==0.9.0 pdf2image==1.16.3 pytesseract==0.3.10 chromadb==0.3.23 tiktoken==0.4.0 faiss-gpu==1.7.2

エラー内容は以下の通りです。

ERROR: Could not install packages due to an EnvironmentError: [Errno 28] No space left on device

Discussion