🐍

LangChainを使って、EmbeddingとAgentを試す

2023/04/13に公開

はじめに

LLMが流行する中で、EmbeddingやLangChainという言葉を耳にしたので実装したものをまとめてみました。
今回の記事では、LangChainを使って、PDFのデータをEmbeddingしてPDFの質問に答える機能を作りたいと思います。

Vector検索には、Pineconeを使用しています。
https://www.pinecone.io/

用意するもの

PineconeのAPI Keyの取得が必要になります。

Embedding

必要なライブラリのインストール

pip install --upgrade openai
pip install --upgrade langchain
pip install pypdf
pip install tiktoken

OpenAIの環境変数を入れる

env OPENAI_API_KEY=""

必要なデータをloadする

今回は、PDFをロードする例で、PyPDFLoader("")に読ませたい、PDFのリンクを入れます。

from langchain.document_loaders import PyPDFLoader

loader = PyPDFLoader("")
documents = loader.load_and_split()

文字を分割する

from langchain.text_splitter import CharacterTextSplitter

text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(documents)

Pineconeを初期化

pip install pinecone-client
import pinecone
from langchain.embeddings.openai import OpenAIEmbeddings

pinecone.init(
    api_key="", #api keyのセット
    environment="asia-southeast1-gcp"
)

index_name = "pdf_example"

# dimensionは、Embedding時の次元数になり、OpenAIのadaを使う際は1536になります。
pinecone.create_index(index_name, dimension=1536, metric="euclidean", pod_type="p1")

Embeddingを行う

from langchain.vectorstores import Pinecone

embeddings = OpenAIEmbeddings()
embedd_docs_result = Pinecone.from_documents(docs, embeddings, index_name=index_name)

LangChainのAgentを使って、Embedding結果を取得する

Chainの作成

Agentで使われるToolを指定するためには、Chainの作成が必要なのではじめにChainを作成します。
今回は、ベクター検索に対応したQA用のツールを作りたいため、VectorDBQAWithSourcesChainを使用します。
chain typeに関しては、npakaさんのこちらの記事が参考になります。
https://note.com/npaka/n/nb9b70619939a
今回は、PDFという文字数が多いものを使用するためmap_reduceを使用しました。

from langchain.vectorstores import Pinecone
from langchain.embeddings.openai import OpenAIEmbeddings

embedding = OpenAIEmbeddings()
vector_store = Pinecone.from_existing_index(
    index_name,
    embedding
)

llm = ChatOpenAI(model_name="gpt-3.5-turbo")
qa =VectorDBQAWithSourcesChain.from_chain_type(llm, chain_type="map_reduce", vectorstore=vector_store)

Toolの作成

from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.agents import AgentType
from langchain.agents import Tool

tools = [
    Tool(
      name = "pinecone_searcher",
      func=qa,
      description="PDFを読み取った資料です"
  )
]

Agentの作成

agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)

質問してみる

queryにPDFに関する質問を入力すると答えてくれます。

from langchain.chains.qa_with_sources.map_reduce_prompt import QUESTION_PROMPT
from langchain import PromptTemplate

template = """
あなたは親切なアシスタントです。下記の質問に日本語で回答してください。
質問:{question}
回答:
"""

prompt = PromptTemplate(
    input_variables=["question"],
    template=template,
)
query = ""
question = prompt.format(question=query)
agent.run(question)

やってみて

LangChainが提供してくれている機能は、かなり豊富でキャッチアップが大変なのでやってみたという記事が結構あるのが助かりました。

実際に検索してみると、PDFの細かな部分も回答してくれたりとかなり精度が高い印象でした。

Discussion