Amazon Bedrockで文書検索をやってみた(FAISS、LangChain)

はじめに

Amazon Bedrockで文書検索をやってみました。ベクトル化にはamazon.titan-embed-text-v1モデル、回答生成にはanthropic.claude-v2モデルを使用しました。

環境

  • Windows11
  • Python 3.11.5
  • LangChain
  • OpenAI

実装

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

1pip install langchain openai python-dotenv faiss-cpu pypdf PyPDF2 tiktoken boto3

AWS CLIの設定

AWS IAMの「ユーザー」タブに移動して、任意のユーザーを選択または作成します。

「セキュリティ認証情報」タブから、「アクセスキーを作成」を選択します。

記事投稿用 (4).png

ユースケースは「コマンドラインインターフェイス(CLI)を選択し、「次へ」を選択します。

記事投稿用 (5).png

説明タグ値の入力は任意となるため、入力せずに「アクセスキーを作成」を選択します。

記事投稿用 (6).png

アクセスキーとシークレットキーをメモして「完了」を選択します。

記事投稿用 (7).png

続いて、AWS CLIをインストールしていない場合は、インストールします。

以下の記事を参考にして、インストールしてください。

今回のチャットボットを実行するディレクトリに移動し、AWS CLIがインストールされたかを以下のコマンドで確認します。

1aws --version23aws-cli/2.13.29 Python/3.11.6 Windows/10 exe/AMD64 prompt/off

結果が表示されれば、インストールされています。

以下のコマンドで、アクセスキーとシークレットキーを設定します。

最初は空の状態なので、ご自身のアクセスキーやシークレットキーを入力し、エンターキーを押してください。region nameは「us-east-1」、output formatは「json」にしてください。

1aws configure23AWS Access Key ID [****************YK63]:4AWS Secret Access Key [****************2DbP]:5Default region name [us-east-1]:6Default output format [json]:

ベクトルストアの作成

まず、PDFをベクトル化してベクトルストアを作成します。

私は以下のAmazon KendraのPDFをベクトル化しました。

1vectorstore.py2import os34from langchain.embeddings import BedrockEmbeddings5from langchain.text_splitter import CharacterTextSplitter6from langchain.vectorstores import FAISS7from langchain.document_loaders import PyPDFLoader89embeddings = BedrockEmbeddings(model_id="amazon.titan-embed-text-v1")1011dummy_text, dummy_id = "1", 11213vectorstore = FAISS.from_texts([dummy_text], embeddings, ids=[dummy_id])1415vectorstore.delete([dummy_id])1617dirname = "datasets"18files = []1920for filename in os.listdir(dirname):21    full_path = os.path.join(dirname, filename)22    if os.path.isfile(full_path):23        files.append({"name": filename, "path": full_path})24dirname = "datasets"25files = []2627for filename in os.listdir(dirname):28    full_path = os.path.join(dirname, filename)29    if os.path.isfile(full_path):30        files.append({"name": filename, "path": full_path})31for file in files:32    if file["path"].endswith(".pdf"):33        loader = PyPDFLoader(file["path"])34    else:35        raise ValueError(f"Unsupported file format: {file['path']}")3637    pages = loader.load_and_split()38    for page in pages:39        page.metadata["source"] = file["path"]40        page.metadata["name"] = file["name"]4142    text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)43    docs = text_splitter.split_documents(pages)44    vectorstore.merge_from(FAISS.from_documents(docs, embeddings))4546vectorstore.save_local("./vectorstore")

コードの解説は以下のとおりです。

  • BedrockEmbeddings(langchain.embeddings)

Amazonのamazon.titan-embed-text-v1モデルを使ってテキストの埋め込み(ベクトル表現)を生成します。これにより、テキストの意味的内容を数値ベクトルとして表現できます。

  • FAISS(langchain.vectorstores)

Facebook AI Similarity Search(FAISS)を使用して、生成されたテキストのベクトルを効率的に保存し、検索できるようにします。FAISSは、大量のベクトルを高速に検索するためのライブラリです。

  • PyPDFLoader(langchain.document_loaders)

PDFファイルを読み込み、処理するためのツールです。PDFの各ページを読み込み、テキストを抽出します。

  • CharacterTextSplitter(langchain.text_splitter)

文書を指定されたサイズのチャンクに分割するために使用されます。これにより、大きな文書も効率的に処理できるようになります。

文書検索を実行する

1qa.py2from langchain.llms import Bedrock3from langchain.embeddings import BedrockEmbeddings45from langchain.vectorstores import FAISS6from langchain.chains import RetrievalQA78llm = Bedrock(9    model_id="anthropic.claude-v2",10    model_kwargs={"max_tokens_to_sample": 16000},11)1213embeddings = BedrockEmbeddings(model_id="amazon.titan-embed-text-v1")1415vectorstore = FAISS.load_local("./vectorstore", embeddings)16retriever = vectorstore.as_retriever()1718chain = RetrievalQA.from_chain_type(llm=llm, retriever=retriever)1920results = chain("Amazon Kendraの仕組みについて教えてください。")2122print(results["result"])

コードの解説は以下のとおりです。

  • LangChainとBedrockのインポート
  • from langchain.llms import Bedrock: LangChainライブラリからBedrockモジュールをインポートします。BedrockはAnthropic社のAIモデル、ClaudeのためのAPIラッパーです。
  • from langchain.embeddings import BedrockEmbeddings: 埋め込み(embeddings)の取り扱いに特化したBedrockEmbeddingsモジュールをインポートします。
  • FAISSとRetrievalQAのインポート
  • from langchain.vectorstores import FAISS: FAISSはFacebook AI Similarity Searchの略で、大規模なデータセットから効率的に類似アイテムを検索するためのライブラリです。
  • from langchain.chains import RetrievalQA: 質問応答のための複合型チェーンを提供するRetrievalQAモジュールをインポートします。
  • LangChainモデルの設定
  • llm = Bedrock(...): Claudeモデルの設定を行います。ここで、モデルIDと最大トークン数を指定します。
  • 埋め込みモデルの設定
  • embeddings = BedrockEmbeddings(...): Amazon Titanのテキスト埋め込みモデルを設定します。
  • ベクターストアのロードとリトリバーの設定
  • vectorstore = FAISS.load_local(...): ローカルに保存されているFAISSベクターストアをロードします。
  • retriever = vectorstore.as_retriever(): ロードしたベクターストアをリトリバー(検索エンジン)として設定します。
  • RetrievalQAチェーンの構築
  • chain = RetrievalQA.fromchaintype(...): LangChainモデルとリトリバーを使用して、質問応答チェーンを構築します。
  • 質問応答の実行と結果の出力
  • results = chain("..."): 指定した質問(ここでは「Amazon Kendraの仕組みについて教えてください。」)に対する応答を取得します。
  • print(results["result"]): 取得した応答を出力します。

上記のPythonファイルを実行すると以下のような結果が返ってきました。

1Amazon Kendraは、機械学習と自然言語処理を利用したクラウドベースのインテリジェント検索サー2ビスです。34主な特徴は以下の通りです。56- ドキュメントのインデックス作成と検索: Kendraは様々なデータソースからドキュメントを収集し、内容を解析してインデックスを作成します。7ユーザーは自然言語でクエリを行い、関連性の高いドキュメントが検索結果として表示されます。89- インテリジェントなランキング: 検索結果は、ドキュメントの内容とユーザーのクエリの意図に基づいてランク付けされます。Kendraは機械学習を使って、クエリとの関連性が高いドキュメントを上位にランク付けします。1011- カスタマイズ可能な検索エクスペリエンス: 検索結果ページのレイアウトや表示方法をカスタマイズできます。また、シソーラスや同義語検索などの機能で検索精度を高めることもできます。1213- 多様なデータソースのサポート: S3、SharePoint、Salesforceなど、様々なデータソースからドキュメントを取得できます。1415- セキュリティと拡張性: KendraはIAMを使ったアクセスコントロールやVPCエンドポイントによるセキュリティをサポートしています。また、インデックスの容量を拡張することもできます。1617このようにKendraは、大量の非構造化データからユーザーが必要とする情報を見つけ出すことを可能にする、インテリジェントなエンタープライズ検索サービスです。機械学習を活用した高度な検索機能と拡張性の高さが特徴です。

おわりに

お疲れ様でした!

参考文献は以下のとおりです。

この記事を書いた人

aws-recipe-user