Amazon Kendraでコネクタを使わずにドキュメントを直接インデックス登録する方法
Amazon Kendraでは、検索インデックスにドキュメントを登録する方法として、データコネクタを利用する方法と batch_put_document
APIを使ってインデックスに直接登録する方法があります。
本記事では、後者の batch_put_document
APIを用いてドキュメントを直接Kendraインデックスに登録する方法を紹介します。
コネクタを利用せずにちょっとした動作検証を行うようなユースケースを想定し、特に、GenAI Enterprise Editionではコネクタを利用すると、利用時間によらず月額$30の固定費が発生するため、このようなコネクタを使わないAPI方式は経済的です。
batch_put_document
API では以下の点に注意しましょう
- ドキュメントのインデクシングは、S3オブジェクトを参照する方法とAPIにインラインで渡す方法があります
- インデクシングは非同期に行われます
- KendraのインデックスIDだけでなくKendraのIAMロールのARNも渡す必要があります
- このAPIはKendraのEdition(GenAI/従来のBasic系)によらず、同じ操作が可能です
事前準備
Amazon Kendraのインデックスを作成します。
作成した以下のリソースを控えましょう。
- インデックスID
- KendraがassumeするIAMロール
S3 上のオブジェクトをAPIで参照してインデクシング
batch_put_document
API に S3Path
引数でS3上のドキュメントのURIを指定します。
API 呼び出し時には
- KendraのインデックスID
- KendraがassumeするIAMロール
も指定します。
KendraがS3上のオブジェクトを参照できるように、KendraのIAMロールに以下のようなS3の参照権限を付与しましょう。
{
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*",
"s3:Describe*",
"s3-object-lambda:Get*",
"s3-object-lambda:List*"
],
"Resource": "arn:aws:s3:::your-bucket-name/*"
}
ウィザードで生成されるポリシーにはS3系は含まれていません。不足していると、以下のようなエラーが発生します
"The IAM Role (arn:aws:iam::123456789012:role/service-role/AmazonKendra-XXX) provided does not have access to (s3://YOUR-BUCKET-NAMEkendra-faq/01.txt).
Please make sure the IAM Role provided has sufficient permissions.
必須ではないIAMロールの引数を省くと、API呼び出し元のロールが利用されるようで、以下のエラーが発生しました
- "ErrorCode": "InvalidRequest"
- "ErrorMessage": "The provided RoleArn is invalid.
Pythonから
import boto3
client = boto3.client('kendra')
INDEX_ID="c8b2286a-5983-11f0-9106-b7040c759cc8"
ROLE_ARN="arn:aws:iam::123456789012:role/service-role/AmazonKendra-us-east-1-XXX"
response = client.batch_put_document(
IndexId=INDEX_ID,
RoleArn=ROLE_ARN,
Documents=[
{
"Id": "00",
"Title": "What is Amazon Kendra?",
"S3Path": {"Bucket": "<YOUR-BUCKET-NAME>", "Key": "kendra-faq/00.txt"},
"ContentType": "PLAIN_TEXT",
"Attributes": [{"Key": "_language_code", "Value": {"StringValue": "en"}}],
},
],
)
AWS CLIから
INDEX_ID="c8b2286a-5983-11f0-9106-b7040c759cc8"
ROLE_ARN="arn:aws:iam::123456789012:role/service-role/AmazonKendra-us-east-1-XXX"
aws kendra batch-put-document \
--index-id $INDEX_ID \
--role-arn $ROLE_ARN \
--documents '[{
"Id": "01",
"Title": "How does Amazon Kendra work with other AWS services?",
"S3Path": {
"Bucket": "<YOUR-BUCKET-NAME>",
"Key": "kendra-faq/01.txt"
},
"ContentType": "PLAIN_TEXT",
"Attributes": [
{
"Key": "_language_code",
"Value": {
"StringValue": "en"
}
}
]
}]'
ドキュメントをAPIにインラインで渡してインデクシング
S3を経由せずに、APIでインラインでドキュメントを渡すことも可能です。
ドキュメント本文は base64 エンコードして渡します。
S3を参照しないため、KendraのIAMロールにS3系参照権限は不要です。
Pythonから
import boto3
client = boto3.client('kendra')
INDEX_ID="c8b2286a-5983-11f0-9106-b7040c759cc8"
ROLE_ARN="arn:aws:iam::123456789012:role/service-role/AmazonKendra-us-east-1-XXX"
response = client.batch_put_document(
IndexId=INDEX_ID,
RoleArn=ROLE_ARN,
Documents=[
{
"Id": "05",
"Title": "What is Amazon Kendra GenAI Index?",
"Blob": "Amazon Kendra GenAI Index is a new index in Kendra designed for retrieval-augmented generation (RAG).".encode(
"utf-8"
),
"ContentType": "PLAIN_TEXT",
"Attributes": [{"Key": "_language_code", "Value": {"StringValue": "en"}}],
},
],
)
AWS CLIから
INDEX_ID="c8b2286a-5983-11f0-9106-b7040c759cc8"
ROLE_ARN="arn:aws:iam::123456789012:role/service-role/AmazonKendra-us-east-1-XXX"
aws kendra batch-put-document \
--index-id $INDEX_ID \
--role-arn $ROLE_ARN \
--documents '[{
"Id": "09",
"Title": "How does Kendra GenAI Index compare to Kendra Developer Edition (KDE) and Enterprise Edition Indexes (KEE)?",
"Blob": "'$(echo -n "GenAI Index enhances semantic accuracy by integrating vector search and improved semantic models." | base64 -w 0)'",
"ContentType": "PLAIN_TEXT",
"Attributes": [
{
"Key": "_language_code",
"Value": {
"StringValue": "en"
}
}
]
}]'
base64エンコード時に、1行の文字列となるように base64 -w 0
と -w 0
オプションを渡しています。
$ echo -n "GenAI Index enhances ... 長い文字列" | base64
R2VuQUkgSW5kZXggZW5oYW5jZXMgc2VtYW50aWMgYWNjdXJhY3kgYnkgaW50ZWdyYXRpbmcgdmVj
dG9yIHNlYXJjaCBhbmQgaW1wcm92ZWQgc2VtYW50aWMgbW9kZWxzLCB3aGljaCBoYXZlIGJlZW4g
cmlnb3JvdXNseSBldmFsdWF0ZWQgYWNyb3NzIGRpdmVyc2UgZGF0YXNldHMuIEdlbkFJIEluZGV4
IHdvcmtzIHdpdGggQmVkcm9jayBrbm93bGVkZ2UgYmFzZXMgYW5kIHRoZSBHZW5BSSBpbmRleCBo
YXMgYSBzbWFsbGVyIHN0YXJ0aW5nIGNhcGFjaXR5IGVuYWJsaW5nIGN1c3RvbWVycyB0byBzdGFy
dCB3aXRoIGEgc21hbGwgd29ya2xvYWQu
$ echo -n "GenAI Index enhances ... 長い文字列" | base64 -w 0
R2VuQUkgSW5kZXggZW5oYW5jZXMgc2VtYW50aWMgYWNjdXJhY3kgYnkgaW50ZWdyYXRpbmcgdmVjdG9yIHNlYXJjaCBhbmQgaW1wcm92ZWQgc2VtYW50aWMgbW9kZWxzLCB3aGljaCBoYXZlIGJlZW4gcmlnb3JvdXNseSBldmFsdWF0ZWQgYWNyb3NzIGRpdmVyc2UgZGF0YXNldHMuIEdlbkFJIEluZGV4IHdvcmtzIHdpdGggQmVkcm9jayBrbm93bGVkZ2UgYmFzZXMgYW5kIHRoZSBHZW5BSSBpbmRleCBoYXMgYSBzbWFsbGVyIHN0YXJ0aW5nIGNhcGFjaXR5IGVuYWJsaW5nIGN1c3RvbWVycyB0byBzdGFydCB3aXRoIGEgc21hbGwgd29ya2xvYWQ
データソースを利用しないKendraとAmazon Bedrock Knowledge Basesを連携させた場合
Bedrock Knowledge Base と GenAI Enterprise Edition を連携させた時、KendraがS3コネクタ等のデータソースを利用しないのは想定していないからなのか、 Ready to add data source in Kendra というメッセージが表示されます。
Amazon Bedrock Knowledge Basesから問題なく検索できるので、心配いりません。
Kendraのエディションによるコネクタの利用費の違い
Kendraのエディションによって、コネクタの利用費が異なります。
2024年末に発表されたGenAI Enterprise Editionの場合、毎月の利用時間によらず、1インデックスあたり毎月$30の固定費(Amazon Kendra Kendra-Connector-MonthlyFee)が発生します。
一方で、従来型のBasic Editionの場合、ドキュメントの同期処理に対して1時間あたり$0.35の従量課金(USD0.35 per hours for ConnectorSync:ConnectorSync in Asia Pacific (Tokyo))が発生します。
最後に
2024年末に発表されたAmazon Kendra GenAI Enterprise Editionの利用費を調べていたときに、コネクタの固定費に頭を悩ませていたところ、料金ページの計算例からコネクタを利用しなくてもドキュメントを同期できると知り、ブログにまとめてみました。
GenAI Enterprise Editionは早く英語を含む多言語対応や東京を含む他リージョン対応を進めてほしいですね。
それでは。