Amazon Bedrock の RAG は、2026年に入って構成の前提が入れ替わりました。長らく定番だった Amazon Kendra との組み合わせは、新規受付が終了した2026年7月30日をもって新規案件の選択肢から外れています。現在 AWS 自身が移行先として名指ししているのは Amazon Bedrock Managed Knowledge Base で、検索から回答生成までを1つの API で扱えます。この記事では、2026年8月時点の公式ドキュメントに基づいて、構築手順・boto3 のコード・料金の分岐点・東京リージョンで踏みやすい落とし穴までを実装者向けに整理します。
まとめ
新規に Amazon Bedrock で RAG を組むなら、Managed Knowledge Base を選んでください。ベクトルストアの調達が不要で、検索側の料金はインデックスストレージ 5.00 USD/GB/月と標準 Retrieve 1.00 USD/1,000 コールに収まります(多段推論の Agentic Retrieval を使う場合は 1,000 コールあたり 4.00 USD と内部 Retrieve 分 1.00 USD が加算。生成モデルのトークン課金は別枠)。
自前で OpenSearch Serverless を立てる場合、Classic コレクションなら最低 2 OCU(0.24 USD/OCU時)が回り続けます。NextGen コレクショングループのスケールゼロを使えば固定費は消せますが、復帰時の遅延と引き換えです。
Amazon Kendra は2026年6月30日にメンテナンスモードへ入り、7月30日以降は新規顧客を受け付けません。Kendra 前提で書かれた2024〜2025年の実装記事は、そのまま流用できないと考えてください。
東京リージョンには落とし穴があります。Managed Knowledge Base 自体は ap-northeast-1 に作れますが、回答生成に使うモデル側の可用性は別問題です。Claude Sonnet 5 は東京では Global クロスリージョン推論しか選べず、推論の処理先が世界中に及びます。処理まで国内に留めたいなら、Claude Haiku 4.5 のように東京で In-Region 推論が使えるモデルを選んでください。
Kendra終了で置き換わったAmazon BedrockのRAG構成
AWS は Amazon Kendra について、2026年6月30日付でメンテナンスモードへ移行したと公式ドキュメントに明記しています。同日以降は新機能の開発が止まり、2026年7月30日をもって新規顧客への提供も終了しました。既存顧客に対してはサポートが継続され、バグ修正とセキュリティ更新は提供されます。新規の機能要望はもう受け付けられません。
この変更で影響を受けるのは Kendra だけではありません。2026年6月の AWS のサービス提供状況アナウンスでは、Amazon Bedrock Agents Classic(2023年11月に提供が始まった旧 Agents)と Amazon Q Business も同じ2026年7月30日で新規受付終了の対象に入っています。「Kendra で検索し、Bedrock Agents で回答を組み立てる」という2024年当時の定番構成は、両端が同時に新規調達できなくなったことになります。
AWS が示している移行先は Amazon Bedrock Managed Knowledge Base です。公式ドキュメントは、組み込みコネクタ・スマートパース・ハイブリッド検索付きのマネージドベクトルストアに加えて、回答生成を行う Retrieve and Generate API と、複数のナレッジベースを横断して多段推論する Agentic Retrieval API を備えた「フルマネージドの RAG ソリューション」と説明しています。Kendra 側の詳しい終了条件と移行判断はAmazon Kendraの新規受付終了と移行先の整理にまとめました。既存の Kendra インデックスを Bedrock のナレッジベースから引く選択肢についてはAmazon Kendra GenAI Indexの新機能と主要ポイントを参照してください。本記事は Bedrock 側の実装に絞ります。
ManagedとCustomer-managedの料金差と機能ギャップ
Amazon Bedrock Knowledge Bases には2種類あります。Bedrock がデータ取り込み・インデックス・ストレージ・検索の基盤ごと面倒を見る Managed Knowledge Base と、ベクトルストア(Amazon OpenSearch Serverless、Amazon Aurora、Amazon Neptune など)を自分で用意する Customer-managed Knowledge Base です。公式ドキュメントは検索精度と運用の両面から前者を推奨しています。
月額コストが逆転する規模の目安
料金体系がまったく違います。Managed Knowledge Base は使った分だけの課金で、インデックスストレージが生データ 1 GB あたり月 5.00 USD、標準の Retrieve が 1,000 コールあたり 1.00 USD です。Agentic Retrieval を使う場合は 1,000 コールあたり 4.00 USD に、内部で走る Retrieve の 1,000 コールあたり 1.00 USD が加算されます。マルチモーダル文書のパース、埋め込み生成、マネージドモデルによるリランクは追加料金なしで含まれます。
| 項目 | Managed Knowledge Base | Customer-managed(OpenSearch Serverless) |
|---|---|---|
| 最小OCU | 該当なし | Classicは2 OCU/NextGenは0 OCU |
| 固定費の概算(Classic・HA) | 0 USD | 約350 USD/月 |
| 固定費の概算(Classic・dev-test) | 0 USD | 約175 USD/月 |
| 固定費の概算(NextGen・アイドル時) | 0 USD | 0 USD+ストレージ |
| 保管 | 5.00 USD/GB/月 | OCUに内包 |
| 検索 | 1.00 USD/1,000コール | OCUに内包 |
| 埋め込み・リランク | マネージドモデルは無料 | 別途モデル課金 |
OpenSearch Serverless の Classic コレクションでは、アカウント内の最初のコレクションに対してインデックス用 1 OCU と検索用 1 OCU の計 2 OCU が最低課金として発生します。冗長スタンバイを外す dev-test オプションを選べばインデックス 0.5 OCU、検索 0.5 OCU まで下げられます。一方、NextGen 世代のコレクショングループは最小 OCU の既定値が 0 で、グループ内のどのコレクションにも10分間リクエストが来なければワーカーがゼロまで縮退し、課金が止まります。このアイドル時間は変更できません。復帰時は検索ワーカー2台・インデックスワーカー1台が再確保され、最初のリクエストに10〜30秒の遅延が乗ります。
社内文書 5 GB・月 10 万クエリという典型的な社内 RAG なら、Managed 側の検索費用は 25 USD と 100 USD で 125 USD 程度です(RetrieveAndGenerate を使う場合は生成モデルのトークン課金が別途乗ります)。常時トラフィックがある本番用途で Classic コレクションを選ぶなら、この規模では Managed のほうが安く付きます。逆に、開発環境やバッチ処理のように無通信の時間が長いワークロードなら、NextGen のスケールゼロで固定費を消せるため、コストだけを理由に Customer-managed を排除する必要はありません。
Managedを選ぶと使えなくなる設定
安さの代わりに、握れるつまみは減ります。公式の比較表では、Managed 側のコネクタは Amazon S3、SharePoint、Confluence、Web Crawler、Google Drive、OneDrive、Custom の7種です。Kendra が32以上のネイティブコネクタを持っていたのに対し、対応外のデータソースは自分で S3 へ書き出す前処理が必要になります。なお Customer-managed 側のコネクタは S3 と Custom の2種だけなので、コネクタの数で見るなら Managed のほうが手厚い構成です。
セマンティックチャンキングは Managed Knowledge Base では選べません。公式の機能比較表は組み込み(既定)と固定サイズの2択と書き、Kendra 移行ガイドは階層チャンキングとチャンキングなしも挙げていて記述が割れているため、階層チャンキングを前提に設計するなら作成前にコンソールで選択肢を確認してください。埋め込みモデルを自前指定する場合も、float32 かつ1024次元の Bedrock 埋め込みモデルに限られます。検索は常にキーワードとセマンティックのハイブリッドで動作し、セマンティック単独のモードはありません。
メタデータフィルタは equals、in、greaterThan、andAll、orAll などが使える一方、startsWith と stringContains は非対応です。前方一致や部分一致でフィルタしている既存アプリは、メタデータの設計自体を作り直すことになります。
クォータも押さえておきます。1つのナレッジベースに登録できるデータソースは200、同時に走らせられる取り込みジョブは50、生データの保管上限は10 TB、Retrieve のリクエストは1ナレッジベースあたり毎分600件、AgenticRetrieveStream はアカウントあたり毎分60件です。クエリ入力の上限は API ごとに違い、Retrieve と AgenticRetrieveStream が英文10,000文字、RetrieveAndGenerate の input.text は SDK のサービスモデル上1,000文字までです。長文の質問をそのまま RetrieveAndGenerate に投げると弾かれます。
boto3でManaged Knowledge Baseを構築する手順
コンソールからでも作れますが、環境を再現可能にするならコードで作るほうが早いです。ここでは AWS の移行ガイドが示している最小構成に、実運用で必要になる待機処理を足した形でなぞります。使うクライアントは2つで、リソース管理が bedrock-agent、検索と生成の実行が bedrock-agent-runtime です。この分担を取り違えると呼び出しが通りません。なお MANAGED 型と MANAGED_KNOWLEDGE_BASE_CONNECTOR は boto3 1.43 系で追加された定義のため、古い boto3 では ParamValidationError になります。先に pip install -U boto3 を通しておいてください。
Bedrockに引き受けさせるIAMロール
先に IAM ロールを用意します。信頼ポリシーで bedrock.amazonaws.com が AssumeRole できるようにし、権限ポリシーにデータ元の S3 バケットと埋め込みモデルの呼び出しを許可します。
import boto3
import json
iam = boto3.client("iam")
trust_policy = {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "bedrock.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}
iam.create_role(
RoleName="BedrockKBRole",
AssumeRolePolicyDocument=json.dumps(trust_policy),
Description="Role for Bedrock Managed Knowledge Base"
)
permissions_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::your-bucket-name",
"arn:aws:s3:::your-bucket-name/*"
]
},
{
"Effect": "Allow",
"Action": ["bedrock:InvokeModel"],
"Resource": ["arn:aws:bedrock:*::foundation-model/amazon.titan-embed-text-v2:0"]
}
]
}
iam.put_role_policy(
RoleName="BedrockKBRole",
PolicyName="BedrockKBPermissions",
PolicyDocument=json.dumps(permissions_policy)
)
埋め込みモデルを明示する場合、amazon.titan-embed-text-v2:0 は ap-northeast-1 を含む20以上のリージョンで単独利用に対応しています。マネージドの既定モデルに任せるなら、この bedrock:InvokeModel の指定は不要です。
MANAGED型でのナレッジベース作成
CreateKnowledgeBase では type に MANAGED を指定します。ここで VECTOR を選ぶと、自分でベクトルストアを用意する Customer-managed 側の作法になります。
bedrock_agent = boto3.client("bedrock-agent", region_name="ap-northeast-1")
response = bedrock_agent.create_knowledge_base(
name="my-managed-kb",
description="Migrated from Kendra index",
roleArn="arn:aws:iam::123456789012:role/BedrockKBRole",
clientToken="kb-create-20260806-01",
knowledgeBaseConfiguration={
"type": "MANAGED",
"managedKnowledgeBaseConfiguration": {
"embeddingModelArn": "arn:aws:bedrock:ap-northeast-1::foundation-model/amazon.titan-embed-text-v2:0",
"embeddingModelConfiguration": {
"bedrockEmbeddingModelConfiguration": {
"embeddingDataType": "FLOAT32"
}
}
}
}
)
kb_id = response["knowledgeBase"]["knowledgeBaseId"]
clientToken を渡しておくと、リトライで二重にナレッジベースが作られる事故を防げます。CI から流す構成なら必ず入れてください。
データソースのAVAILABLE待ちと取り込みジョブ
データソース作成は同期的に完了しません。CreateDataSource を呼ぶとステータスは CREATING から始まり、通常2〜5分で AVAILABLE に変わります。公式ドキュメントも「AVAILABLE になるまで取り込みへ進むな」と明記しているため、ここでポーリングを挟みます。
import time
response = bedrock_agent.create_data_source(
knowledgeBaseId=kb_id,
name="my-s3-data-source",
dataSourceConfiguration={
"type": "MANAGED_KNOWLEDGE_BASE_CONNECTOR",
"managedKnowledgeBaseConnectorConfiguration": {
"connectorParameters": {
"type": "S3",
"version": "1",
"connectionConfiguration": {
"bucketName": "your-bucket-name",
"bucketOwnerAccountId": "123456789012"
},
"filterConfiguration": {
"inclusionPrefixes": ["documents/"]
}
}
}
},
vectorIngestionConfiguration={
"parsingConfiguration": {"parsingStrategy": "SMART_PARSING"}
}
)
data_source_id = response["dataSource"]["dataSourceId"]
ds_status = "CREATING"
while ds_status == "CREATING":
time.sleep(15)
ds_status = bedrock_agent.get_data_source(
knowledgeBaseId=kb_id,
dataSourceId=data_source_id
)["dataSource"]["status"]
if ds_status != "AVAILABLE":
raise RuntimeError("data source not available: " + ds_status)
job = bedrock_agent.start_ingestion_job(
knowledgeBaseId=kb_id,
dataSourceId=data_source_id,
description="Initial ingestion"
)["ingestionJob"]
while job["status"] not in ("COMPLETE", "FAILED", "STOPPED"):
time.sleep(30)
job = bedrock_agent.get_ingestion_job(
knowledgeBaseId=kb_id,
dataSourceId=data_source_id,
ingestionJobId=job["ingestionJobId"]
)["ingestionJob"]
stats = job.get("statistics", {})
if stats.get("numberOfDocumentsFailed", 0) or job["status"] != "COMPLETE":
print(job["status"], job.get("failureReasons", []))
numberOfDocumentsFailed を必ず見てください。ステータスが COMPLETE でも失敗ドキュメントは黙って残ります。文書ごとの属性は S3 上に置く metadata.json のサイドカーファイルで与え、1ファイルあたり10 KB まで、型は STRING・NUMBER・BOOLEAN のいずれかです。
RetrieveとRetrieveAndGenerateの使い分け
クエリ側の API は2つあり、どちらを使うかでアーキテクチャが変わります。実行クライアントはどちらも bedrock-agent-runtime です。
検索結果だけを受け取るRetrieve
Retrieve は関連するパッセージとスコア、出典の位置情報を返すだけで、文章生成は行いません。取得件数の上限は100件です。プロンプトの組み立てや生成モデルの選択を自分で握りたいとき、あるいは検索結果を既存の検索 UI に流し込みたいときはこちらを使います。検索工程そのものの精度改善はRAGの検索工程で何を調整すると精度が上がるかにまとめています。
runtime = boto3.client("bedrock-agent-runtime", region_name="ap-northeast-1")
response = runtime.retrieve(
knowledgeBaseId=kb_id,
retrievalQuery={"text": "VPCエンドポイントの設定手順"},
retrievalConfiguration={
"managedSearchConfiguration": {
"numberOfResults": 10,
"filter": {
"andAll": [
{"equals": {"key": "department", "value": "engineering"}},
{"equals": {"key": "doc_type", "value": "policy"}}
]
}
}
}
)
for r in response["retrievalResults"]:
print(r["score"], r["content"]["text"][:80])
print(r["location"]["s3Location"]["uri"])
Kendra から移す場合、クエリ文字列が最上位パラメータの QueryText からネストした retrievalQuery.text へ移り、AttributeFilter が managedSearchConfiguration 内の filter に変わります。Customer-managed のナレッジベースでは、この managedSearchConfiguration ではなく vectorSearchConfiguration を使う点にも注意してください。
生成まで任せるRetrieveAndGenerate
RetrieveAndGenerate は検索と生成を1コールで済ませ、引用付きの回答文を返します。modelArn に指定するモデルが生成を担当します。下の例では、東京と大阪だけにルーティングされる JP ジオの推論プロファイルを指定しています。
MODEL_ARN = (
"arn:aws:bedrock:ap-northeast-1:123456789012:"
"inference-profile/jp.anthropic.claude-haiku-4-5-20251001-v1:0"
)
response = runtime.retrieve_and_generate(
input={"text": "VPCエンドポイントからS3へアクセスする設定を教えて"},
retrieveAndGenerateConfiguration={
"type": "KNOWLEDGE_BASE",
"knowledgeBaseConfiguration": {
"knowledgeBaseId": kb_id,
"modelArn": MODEL_ARN,
"retrievalConfiguration": {
"managedSearchConfiguration": {"numberOfResults": 5}
}
}
}
)
print(response["output"]["text"])
for citation in response.get("citations", []):
for ref in citation.get("retrievedReferences", []):
print(ref["location"]["s3Location"]["uri"])
リージョン内で完結させるなら、推論プロファイルではなく arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-haiku-4-5-20251001-v1:0 の形で基盤モデルの ARN を直接指定します。会話を継続する場合は、初回レスポンスに含まれる sessionId を次回以降のリクエストで使い回してください。ストリーミングで受け取りたいときは retrieve_and_generate_stream に差し替えます。生成側だけを自前で制御したいなら、Retrieve の結果を Converse APIで会話履歴とツール呼び出しを組み立てる実装に渡す構成のほうが、モデル差し替えやツール併用の自由度は高くなります。
東京リージョンでのモデル選定とデータ所在の落とし穴
ここが実装で最も事故が起きやすい箇所です。Managed Knowledge Base が使えるリージョンは us-east-1、us-west-2、eu-west-1、eu-west-2、eu-central-1、ap-northeast-1、ap-southeast-2、us-gov-west-1 の8つで、東京は含まれます。ところが「東京にナレッジベースを作ったから国内で完結する」とはなりません。RetrieveAndGenerate の modelArn に指定する生成モデルが、そのリージョンでどの推論方式に対応しているかは、モデルごとに違うからです。
東京でIn-Region推論が使えるモデルの見分け方
| モデル | Knowledge base対応 | 東京 In-Region | 東京 Geo | 東京 Global |
|---|---|---|---|---|
| Claude Haiku 4.5 | 対応 | 可 | 可(jp.接頭辞) | 可 |
| Claude Sonnet 5 | 対応 | 不可 | 不可 | 可のみ |
| Nova 2 Lite | 非対応 | 不可 | 可(jp.接頭辞) | 可 |
Claude Sonnet 5 のモデルカードでは、ap-northeast-1 の In-Region と Geo がいずれも非対応で、使えるのは global.anthropic.claude-sonnet-5 だけです。公式のクロスリージョン推論の比較表は、Geographic を「Within geographic boundaries」、Global を「Any supported AWS commercial Region worldwide」と定義し、データレジデンシー要件がある組織には Geographic を推奨しています。ナレッジベースに取り込んだデータ自体は東京に保管されたままですが、生成のたびにクエリと検索結果は国外のリージョンで処理されます。ナレッジベース側のドキュメントにも、クロスリージョン推論を使うとデータがリージョン間で共有されうる旨の注意書きが置かれています。処理リージョンまで国内に限定する要件があるなら、Global は選べません。
国内に留めるなら、anthropic.claude-haiku-4-5-20251001-v1:0 のように東京で In-Region 推論が使えるモデルを選ぶのが確実です。このモデルには jp.anthropic.claude-haiku-4-5-20251001-v1:0 という JP ジオの推論プロファイルもあり、ルーティング先は東京と大阪に限定されます。逆に Nova 2 Lite は jp. 接頭辞のジオ推論を持ちながら、モデルカードの機能表で Knowledge base が非対応と明記されているため、RetrieveAndGenerate の生成モデルには指定できません。ジオ推論の有無だけを見て選ぶと外します。
データレジデンシーの制約が無い案件では、判断は逆になります。公式表は Global を「Approximately 10% savings」と位置づけ、コスト最適化目的なら Global を推奨しています。転送データは AWS ネットワーク内に留まり、リージョン間は暗号化されるため、要件が「公衆インターネットを通さないこと」までなら Global で足ります。
GovCloudで落ちる機能
GovCloud(us-gov-west-1)では制約が重くなります。データソースは S3 のみで、ACL による文書単位のアクセス制御と AgentCore Gateway 連携は対象外です。サービスマネージドの埋め込み・リランク・Agentic Retrieval も提供されないため、埋め込みモデルは作成時に自分で指定する必要があります。
Kendraからの移行で埋まらない機能と代替手段
移行ガイドは「入念な計画があれば多くのエンタープライズ検索と RAG のワークロードは移行可能」としつつ、そのまま置き換えられない機能を列挙しています。実務で問題になるのは次の6つです。
- クエリサジェスト(GetQuerySuggestions 相当)が無い
- ファセット検索が無い
- カスタムシソーラス(同義語辞書)が無い
- スペルチェックが無い
- インクリメンタルラーニング(SubmitFeedback による学習)が無い
- 取り込み時の Lambda フック(Custom Document Enrichment)が無い
自前レイヤーで埋まる4機能
同義語とスペルチェックは、クエリを投げる前に自前で書き換える層を挟めば実用上は埋まります。Managed Knowledge Base は常にハイブリッド検索で動くため、展開した同義語をクエリ文字列に足すだけでキーワード側とセマンティック側の両方に効きます。クエリサジェストも、よく使われる語彙を別途インデックス化してフロントから引く形なら再現できます。取り込み時の加工は、Step Functions や Lambda で S3 に置く前に処理する形へ寄せれば代替可能です。
代替できないファセットと関連度学習
ファセット検索とインクリメンタルラーニングは代替になりません。メタデータフィルタでカテゴリを絞ることはできても、Kendra が返していた件数付きの動的ファセットは再現できず、UI 側で既知のメタデータスキーマを固定表示する運用に落とすしかありません。クリックログから関連度を学習させる仕組みも同様で、外部ストアにシグナルを溜めてリランクのパラメータを人手で調整する運用に置き換わります。
したがって、業務要件にファセット付きの社内検索 UI が入っている場合、Managed Knowledge Base 単体への移行は選ぶべきではありません。OpenSearch を併設して検索 UI を支える前提が立たないなら、移行計画そのものを組み直してください。逆に、用途が「社内文書に基づいて回答を返すチャット」であれば機能ギャップはほぼ問題になりません。この形の実装例はKnowledge Baseを使った社内RAGチャットの構成例で扱っています。ベクトルストアを自前で持ちたい事情がある場合は、S3 Vectors APIを使ったRAG構築も比較対象に入れる価値があります。
よくある質問
Amazon Kendraは今も使えますか?
既存のインデックスは動きます。AWS は2026年6月30日にメンテナンスモードへ移行させた後も、既存顧客にはバグ修正とセキュリティ更新を提供すると明記しています。ただし新機能の開発は止まっており、2026年7月30日以降は新規顧客を受け付けていません。これから RAG や社内検索を作るなら Amazon Bedrock Managed Knowledge Base を選ぶことになります。
Amazon BedrockのRAGでmodel idには何を指定しますか?
RetrieveAndGenerate の modelArn には、Knowledge base 機能に対応した基盤モデルの ARN を指定します。東京リージョンで In-Region 推論まで使うなら anthropic.claude-haiku-4-5-20251001-v1:0 が該当します。クロスリージョン推論を使う場合は us. や jp. といったジオ接頭辞、あるいは global. 接頭辞の推論プロファイル ID を指定してください。モデルごとの対応可否は Bedrock のモデルカードで必ず確認しましょう。
Bedrock APIの呼び出しはどのクライアントを使いますか?
用途で3つに分かれます。ナレッジベースやデータソースの作成・取り込みは bedrock-agent、Retrieve と RetrieveAndGenerate の実行は bedrock-agent-runtime、モデルへの直接の推論リクエストは bedrock-runtime です。Bedrock 全体の始め方はAmazon Bedrockの使い方と料金・モデルの選び方を参照してください。
東京リージョンだけでRAGを完結できますか?
できますが、モデルの選び方次第です。Managed Knowledge Base は ap-northeast-1 に対応し、埋め込みの amazon.titan-embed-text-v2:0 も東京で使えます。問題は生成側にあり、Claude Sonnet 5 は東京では Global クロスリージョン推論しか選べないため、推論の処理先が世界中に及びます。処理まで国内で完結させたいなら、東京で In-Region 推論が使えるモデルを選んでください。
Managed Knowledge Baseの料金はどう決まりますか?
3つの要素で決まります。インデックスストレージが生データ 1 GB あたり月 5.00 USD、標準の Retrieve が 1,000 コールあたり 1.00 USD、Agentic Retrieval を使う場合は 1,000 コールあたり 4.00 USD に内部 Retrieve の 1,000 コールあたり 1.00 USD が加わります。生成に使ったモデルのトークン課金は別途かかる点に注意してください。マルチモーダルのパース、埋め込み生成、マネージドモデルによるリランクは追加料金なしです。