Amazon KendraとAzureChatOpenAIで日本語での文書検索を実行してみた(Python)

  • Windows 11
  • Python 3.11.5

ステップ1:IAMユーザーにAmazonKendraFullAccessをアタッチする

任意のIAMユーザーを選択し、「許可を追加」を選択します。

image.png

「AmazonKendraFullAccess」と検索し、「次へ」を選択します。

image.png

「許可を追加」を選択します。

image.png
これで任意のIAMユーザーにAmazonKendraFullAccessがアタッチされました。

ステップ2:Amazon Kendra インデックスを設定する

Amazon Kendra console にアクセスし、「Create an Index」を選択します。

image.png
以下のように、Index nameとIAM role、Role nameを入力します。各項目名はご自身で

決めてください。入力したら「Next」を選択します。

image.png

次の画面では、何も変更せずに「Next」を選択します。

image.png

「Developer editions」を選択し、「Next」を選択します。

image.png

「Create」を選択します。

image.png

Statusが「Active」になったら、作成完了です。

image.png

ステップ3:IAMロールを更新する

IAM console で先ほど作成したRoleを選択し、「ポリシーをアタッチ」を選択します。

image.png

今回はS3を使うため、「AmazonS3ReadOnlyAccess」と検索し、ヒットしたポリシーにチェックを入れた状態で、「許可を追加」を選択します。

image.png
許可ポリシーに追加されました。

許可ポリシーに追加されました。

image.png

ステップ4:データソースへのS3コネクタを構成する

S3のページに移動し、「バケットを作成」を選択します。

image.png

AWSリージョンは「米国東部(バージニア北部)us-east-1、バケットタイプは「汎用」を選択し、バケット名を入力してバケットを作成します。

image.png

作成したバケットに移動し、「アップロード」を選択します。

image.png

今回は以下のAmazon Kendraのデベロッパーガイドをアップロードします。

次に、データソースを作成します。作成したインデックスの画面に移動し、「Data management」の「Data sources」タブを選択すると以下のような画面が表示されるので、「Add data sources」を選択します。

image.png

Amazon S3 connecterの「Add connecter」を選択します。

image.png

Data sourse nameを入力し、Default Languageは「Japanese(ja)」を選択し、「Next」で移動します。

image.png

「Create a new Role(Recommended)」を選択し、任意のRole nameを入力して「Next」で移動します。

image.png

Enter the data source locationには先ほど作成したs3へのパスを通し、Sync modeは「Full sync」、Sync run scheduleは「Run on demand」を選択して「Next」で移動します。

image.png

そのまま「Next」で移動します。

image.png

確認画面では「Add data source」を選択してください。データソースが作成されます。

データソースの作成が完了したら、以下の「Sync now」を選択してください。

image.png

StatusがCompletedになったら完了です。

image.png

ステップ5:Search console上で実行する

「Data management」の「Search indexed content」タブに移動し、右側のSettingsのDefault language of sourse documentsから「Japanese(ja)」を選択して、「Kendraの料金」というクエリを実行すると、以下のように結果が返ってきます。

image.png

ステップ6:Pythonから実行する

ライブラリのインストール

以下のコマンドで必要なライブラリをインストールします。

1pip install langchain openai python-dotenv boto3

環境変数の設定

.envファイルを作成して、以下の変数をご自身の環境に合わせて設定します。

1OPENAI_API_KEY = "Azure OpenAIのキー"2OPENAI_API_BASE = "Azure OpenAIのエンドポイント"3OPENAI_API_VERSION = "Azure OpenAIのバージョン"45AWS_REGION = "インデックスを作成したリージョン"6KENDRA_INDEX_ID = "インデックスのID"

コードの追加

https://github.com/aws-samples/amazon-kendra-langchain-extensions/blob/main/kendra_retriever_samples/kendra_chat_open_ai.py  を参考に、いくつか変更点を加えた以下のコードを追加します。

1test.py2from langchain.retrievers import AmazonKendraRetriever3from langchain.chains import ConversationalRetrievalChain4from langchain.prompts import PromptTemplate5from langchain.chat_models import AzureChatOpenAI6import sys7import os89from dotenv import load_dotenv10load_dotenv()1112MAX_HISTORY_LENGTH = 51314def build_chain():15  region = os.environ["AWS_REGION"]16  kendra_index_id = os.environ["KENDRA_INDEX_ID"]1718  llm = AzureChatOpenAI(19      temperature=0,20      openai_api_version=os.environ["OPENAI_API_VERSION"],21  )2223  attribute_filter = {"EqualsTo": {"Key": "_language_code", "Value": {"StringValue": "ja"}}}24      25  retriever = AmazonKendraRetriever(26    index_id=kendra_index_id, attribute_filter=attribute_filter, region_name=region27  )2829  prompt_template = """30  タグには参考文書が書かれています。31  {context}32  \n\nHuman: 上記参考文書を元に、に対して説明してください。言語の指定が無い場合は日本語で答えてください。33    もしの内容が参考文書に無かった場合は「文書にありません」と答えてください。34  {question}35  \n\nAssistant:36  """37  PROMPT = PromptTemplate(38      template=prompt_template, input_variables=["context", "question"]39  )4041  condense_qa_template = """42  Given the following conversation and a follow up question, rephrase the follow up question 43  to be a standalone question.4445  Chat History:46  {chat_history}47  Follow Up Input: {question}48  Standalone question:"""49  standalone_question_prompt = PromptTemplate.from_template(condense_qa_template)5051  qa = ConversationalRetrievalChain.from_llm(52        llm=llm, 53        retriever=retriever, 54        condense_question_prompt=standalone_question_prompt, 55        return_source_documents=True, 56        combine_docs_chain_kwargs={"prompt":PROMPT})57  return qa5859def run_chain(chain, prompt: str, history=[]):60  return chain({"question": prompt, "chat_history": history})6162if __name__ == "__main__":63  class bcolors:64    HEADER = '\033[95m'65    OKBLUE = '\033[94m'66    OKCYAN = '\033[96m'67    OKGREEN = '\033[92m'68    WARNING = '\033[93m'69    FAIL = '\033[91m'70    ENDC = '\033[0m'71    BOLD = '\033[1m'72    UNDERLINE = '\033[4m'7374  qa = build_chain()75  chat_history = []76  print(bcolors.OKBLUE + "Hello! How can I help you?" + bcolors.ENDC)77  print(bcolors.OKCYAN + "Ask a question, start a New search: or CTRL-D to exit." + bcolors.ENDC)78  print(">", end=" ", flush=True)79  for query in sys.stdin:80    if (query.strip().lower().startswith("new search:")):81      query = query.strip().lower().replace("new search:","")82      chat_history = []83    elif (len(chat_history) == MAX_HISTORY_LENGTH):84      chat_history.pop(0)85    result = run_chain(qa, query, chat_history)86    chat_history.append((query, result["answer"]))87    print(bcolors.OKGREEN + result['answer'] + bcolors.ENDC)88    if 'source_documents' in result:89      print(bcolors.OKGREEN + 'Sources:')90      for d in result['source_documents']:91        print(d.metadata['source'])92    print(bcolors.ENDC)93    print(bcolors.OKCYAN + "Ask a question, start a New search: or CTRL-D to exit." + bcolors.ENDC)94    print(">", end=" ", flush=True)95  print(bcolors.OKBLUE + "Bye" + bcolors.ENDC)

変更点

  • dotenvで.envファイルにある環境変数を読み込む
  • OpenAIではなくAzureChatOpenAIを使用
  • attribute_filterで日本語のドキュメントに対応
  • こちらの記事  を参考にしたprompt_templateに

実行

1Hello! How can I help you?2Ask a question, start a New search: or CTRL-D to exit.3> Kendraの料金45Amazon Kendraの料金については、参考文書に詳細な情報が記載されています。料金は、Amazon Kendraの使用状況に応じて請求されます。最初の30日間は、最大750時間のAmazon Kendraの使用が無料で利用できるデベロッパーエディションがあります。ただし、試用期間が終了すると、プロビジョニングされたインデックスが空でクエリが実行されていない場合でも、Amazon Kendraプロビジョニングされたすべてのインデックスに対して料金が請求されます。また、試用期間が終 了すると、Amazon Kendraデータソースを使用してドキュメントをスキャンおよび同期するための追加料金がかかります。詳細な料金と価格については、Amazon Kendra料金表をご覧ください。6Sources:7https://t-tsuchiyama-test.s3.amazonaws.com/kendra-dg.pdf8https://t-tsuchiyama-test.s3.amazonaws.com/kendra-dg.pdf9https://t-tsuchiyama-test.s3.amazonaws.com/kendra-dg.pdf

回答結果が日本語で取得できました。

フィニッシュ

お疲れ様でした。

値段が高いので、継続的に使用しない場合は今回作成したリソースは削除しましょう。

以下のXでも情報発信してます!

参考文献

この記事を書いた人

aws-recipe-user