Bedrock Knowledge Bases RAG Chunking Retrieval Agents連携 統合実装ガイド

目次

1. なぜRAG実装か — AIシリーズVol1(Bedrock Agents)からの架橋 + AIシリーズ深化結節点

関連シリーズ ナビゲーション (AIシリーズ Vol1↔Vol2 + 全8軸)

IAM入門4巻: Vol1 / Vol2 / Vol3 / Vol4

EKS本番運用3巻: Vol1 / Vol2 / Vol3

復旧・運用編4巻: Vol1 / Vol2 / Vol3 / Vol4

セキュリティ本格運用 Vol1: Security Hub × GuardDuty × Audit Manager

コスト最適化 Vol1: Cost Explorer × Budgets × Compute Optimizer

マルチアカウント運用 Vol1: Organizations × Control Tower × Landing Zone

Observability実践 Vol1: Application Signals × SLO × X-Ray

1-1. LLM/Agent 単独では届かない壁 — なぜ RAG が必要か

大規模言語モデル (LLM) は広範な知識と高い文章生成能力を持ちます。しかし本番システムに組み込もうとすると、3 つの本質的な壁にぶつかります。

壁 1: 知識更新困難 (Knowledge Staleness)

LLM は学習カットオフ日以降の情報を持ちません。2023 年に学習を終えたモデルは、2025 年以降の製品仕様改訂・社内規程更新・新しい API 仕様を知らない状態で動きます。Fine-tuning は数十万円のコストと数日の時間を要し、週次・日次の情報更新には現実的に対応できません。

RAG は S3 のドキュメントを Vector store に同期するだけで、Fine-tuning なしに最新情報を LLM に供給します。

# S3 に新ドキュメントをアップロード → sync で知識を即日更新
aws s3 cp updated-policy-2026.pdf s3://kb-data-source/policies/
aws bedrock-agent start-ingestion-job \
 --knowledge-base-id "KBID12345" \
 --data-source-id "DS67890"

壁 2: Hallucination (幻覚)

LLM は「それらしい答え」を生成しますが、根拠なく事実と異なる情報を出力することがあります。固有名詞・数値・手順の正確性が求められる業務領域では致命的です。

Hallucination の根本原因は「モデルが生成時に参照文書を持っていない」点にあります。RAG は Retrieve フェーズで実際のドキュメントを取得し、「この文脈のみを元に回答せよ」と指示することで Hallucination を大幅に抑制します。

response = bedrock_agent_runtime.retrieve_and_generate(
 input={"text": "2026年度の健康診断申し込み期限はいつですか?"},
 retrieveAndGenerateConfiguration={
  "type": "KNOWLEDGE_BASE",
  "knowledgeBaseConfiguration": {
"knowledgeBaseId": KNOWLEDGE_BASE_ID,
"modelArn": (
 "arn:aws:bedrock:ap-northeast-1::foundation-model"
 "/anthropic.claude-3-5-sonnet-20241022-v2:0"
),
"generationConfiguration": {
 "promptTemplate": {
  "textPromptTemplate": (
"以下の文脈のみを使い、文脈に記載がない場合は"
"「資料に記載がありません」と答えてください。\n\n"
"文脈:\n$search_results$\n\n質問: $query$"
  )
 }
}
  }
 }
)

プロンプトで「文脈のみを使う」と明示することで、モデルが推測で補完することを防ぎます。

壁 3: 文脈長制約 (Context Length Limitation)

Claude 3.5 Sonnet は最大 200K トークンを処理できますが、企業の社内ドキュメント全体は数百万トークンに及ぶことがあります。全文書を毎回コンテキストに詰め込む手法はコスト・レイテンシ・精度の 3 面で非現実的です。

問題具体的な影響
コスト増大無関係なドキュメントを大量に含む → 入力トークン費用が数十倍
レイテンシ悪化大量トークン処理 → レスポンスが 5〜10 秒超に
精度低下無関係な文書が大量に混入 → モデルが本質を見失う

RAG は「質問に関連する文書断片のみを検索して提供する」ことで、3 つの壁を同時に解消します。

Vector store にはドキュメントの意味をベクトル表現 (Embedding) として格納します。クエリも同じ Embedding 空間に変換し、コサイン類似度で最も関連する文書断片を高速に取得します。


1-2. AIシリーズ Vol1 (Bedrock Agents) からの地続き設計

AIシリーズ Vol1 「Bedrock Agents 本番運用 完全ガイド」 では Bedrock Agents の 5 要素 (Agent / Action Group / Prompt / Session / Guardrails) を体系化しました。特に Action Group は「LLM が外部 API を呼び出す」仕組みとして詳しく解説しています。

Vol2 (本記事) の Knowledge Bases は Action Group と補完関係 にあります。

機能役割呼び出す先
Action Group (Vol1)外部 API / Lambda 呼び出しREST API / DynamoDB / 社内システム
Knowledge Bases (Vol2)外部ドキュメントを Vector 検索S3 → Vector store → LLM

具体例: 社内 FAQ チャットボット

ユーザー質問: 「2026年度の健康診断の申し込み期限と手順を教えて」

1. Agent がクエリを受信
2. Knowledge Bases で社内規程 PDF から該当箇所を Retrieve
3. Retrieve 結果をプロンプトに組み込んで Claude に回答生成を依頼
4. 申請フォーム送信が必要 → Action Group で申請 API を呼び出し

KB が「知識の引き出し」、Action Group が「実行の手」として機能します。両者を組み合わせることで高度な Multi-step reasoning が可能になります。

Vol1 の Agent に KB を追加する Terraform (概念)

# Vol1 で作成した Agent に Knowledge Bases を関連付ける
resource "aws_bedrockagent_agent_knowledge_base_association" "faq_kb" {
  agent_id = aws_bedrockagent_agent.main.agent_id
  description = "社内FAQ・規程ドキュメントの検索"
  knowledge_base_id = aws_bedrockagent_knowledge_base.faq.id
  knowledge_base_state = "ENABLED"
}

Vol1 で作成した aws_bedrockagent_agentaws_bedrockagent_agent_knowledge_base_association を追加するだけで、既存 Agent が Knowledge Bases を参照できます。Terraform 完全例は §5 で詳しく解説します。

Vol1 → Vol2 の学習パス

[Vol1: Bedrock Agents 本番運用]
  ├─ Action Group (Lambda 呼び出し / REST API 連携)
  ├─ Session 管理 (会話コンテキストの保持)
  └─ Guardrails (出力フィルタリング / PII 除去)
 ↓ Knowledge Bases を追加して AI の深度を上げる
[Vol2: Knowledge Bases × RAG 実装 ← 本記事]
  ├─ Knowledge Bases (S3 → Embedding → Vector store → Retrieve)
  ├─ Chunking strategy (Fixed / Hierarchical / Semantic)
  ├─ Retrieval API (Retrieve / RetrieveAndGenerate / Metadata filtering)
  └─ Agents × KB 統合 Terraform 完全例

Vol1 未読の方は AIシリーズ Vol1 を先に読むことで、本記事の理解がより深まります。


1-3. 本記事の到達ゴール 5 点

本記事を読み終えると、以下 5 点が達成できる状態になります。各ゴールは §2〜§7 に対応しており、§1 から順に読むことで体系的に習得できる構成になっています。

(a) Knowledge Bases 4 要素の統合理解

S3 データソース / Vector store (OpenSearch Serverless・Pinecone・pgvector) / Embedding model (Titan v2・Cohere Multilingual) / Sync 戦略 の 4 要素を関連付けて理解し、要件に応じた Vector store を選定できる。

(b) Chunking strategy 3 形式の選択判断

Fixed-size (デフォルト) / Hierarchical (親子 chunk) / Semantic (意味境界) の違いと適用場面を理解し、ドキュメント種別・検索精度要件・コストの 3 軸で最適な strategy を選べる。

(c) Retrieval API の本番品質実装

Retrieve API と RetrieveAndGenerate API の使い分け、Metadata filtering JSON 完全例、Reranking の追加手順を実装コード付きで習得できる。

(d) Bedrock Agents × Knowledge Bases 連携の Terraform 実装

aws_bedrockagent_agent + aws_bedrockagent_knowledge_base + aws_bedrockagent_agent_knowledge_base_association の Terraform 完全例で、Vol1 の Action Group に Knowledge Bases を追加する地続き実装ができる。

(e) 詰まりポイント 7 選の乗り越え方

Hallucination 抑制 / Chunk size 最適化 / Embedding 選定 / Vector store 選定 / コスト最適化 / レイテンシ改善 / Re-indexing 戦略 — 本番投入前後に直面する 7 パターンの根本原因と対処法を把握できる。

5 点すべてを習得すると、「RAG を構築したが精度が出ない」「コストが想定より大きく膨れた」「KB の更新頻度をどう設計すべきか」といった本番特有の課題を自力で解決できる力が身につきます。


2. Knowledge Bases 構成要素整理 — S3 / Vector store / Embedding model / Sync戦略

Knowledge Bases 全体アーキテクチャ — S3→Embedding→Vector store→Retrieve

2-1. Knowledge Bases 4要素全体像 — S3 / Vector store / Embedding model / Sync戦略

AWS Bedrock Knowledge Bases は以下の 4 要素で構成されます。各要素を正しく設計しないと、精度低下・コスト超過・運用負荷増大のいずれかが本番で顕在化します。

要素役割主な選択肢
S3 data source文書 (PDF/TXT/DOCX/CSV/HTML) を格納・管理S3 Standard / S3 Standard-IA
Vector storeEmbedding ベクトルを保管・高速検索OpenSearch Serverless / Pinecone / Aurora pgvector
Embedding model文書テキストをベクトルに変換Titan Embeddings G2 / Cohere Embed Multilingual
Sync戦略S3 変更を Vector store に反映Incremental sync / Full re-sync

4 要素が連携して「S3 文書 → Embedding変換 → Vector store格納 → Retrieve」のパイプラインを形成します。

S3 → Embedding → Vector store → Retrieve フロー:

[文書取り込み (Ingestion)]
  S3 (PDF / TXT / DOCX / CSV / HTML)
↓ Chunking (文書を断片 Chunk に分割 / §3 で詳述)
  Bedrock Embedding model
↓ テキスト → 高次元ベクトル変換
  Vector store (ベクトル + メタデータを格納)

[クエリ時 (Retrieval)]
  ユーザーの質問 (テキスト)
↓ Embedding model (クエリも同じモデルでベクトル化)
  Vector store (コサイン類似度検索)
↓ 類似度上位 K 件のチャンクを取得
  LLM (取得チャンクを文脈として回答生成)

Ingestion と Retrieval で必ず同じ Embedding model を使用します。モデルを後から変更すると既存ベクトルとクエリベクトルの空間が一致せず、Full re-sync が必要になります (§2-5 参照)。

2-2. Vector store 3社比較 — OpenSearch Serverless / Pinecone / Aurora pgvector

Vector store の選定は「スケール・コスト・管理負荷」の 3 軸で判断します。

項目OpenSearch ServerlessPineconeAurora pgvector
Bedrock統合ネイティブ (Managed)ネイティブネイティブ
コスト構造OCU 課金 (2 OCU 最小)Index Units 課金Aurora インスタンス課金
最小コスト/月約 $350 (2 OCU)Starter: 約 $70db.t3.medium: 約 $60
最大ベクトル数数十億 (スケーラブル)数十億 (Pod型)数百万 (RDS制約内)
レイテンシ10–30ms10–50ms5–20ms (同一VPC)
管理負荷ゼロ (Serverless)中 (RDS運用必要)
推奨ユースケース本番・中大規模KBサードパーティ統合必要時既存Aurora環境流用

OpenSearch Serverless が推奨な理由:

Bedrock との統合が最も深く、Vector store のプロビジョニング・スケーリングを完全に Bedrock が管理します。OCU (OpenSearch Compute Unit) は 2 OCU が最小単位のため、小規模 PoC では割高ですが、本番規模では最もコスト効率に優れます。

resource "aws_bedrockagent_knowledge_base" "main" {
  name  = "product-knowledge-base"
  description = "製品カタログ + FAQ 文書 RAG KB"
  role_arn = aws_iam_role.bedrock_kb_role.arn

  knowledge_base_configuration {
 type = "VECTOR"
 vector_knowledge_base_configuration {
embedding_model_arn = "arn:aws:bedrock:ap-northeast-1::foundation-model/cohere.embed-multilingual-v3"
 }
  }

  storage_configuration {
 type = "OPENSEARCH_SERVERLESS"
 opensearch_serverless_configuration {
collection_arn = aws_opensearchserverless_collection.kb_collection.arn
vector_index_name = "bedrock-kb-default-index"
field_mapping {
  vector_field= "bedrock-knowledge-base-default-vector"
  text_field  = "AMAZON_BEDROCK_TEXT_CHUNK"
  metadata_field = "AMAZON_BEDROCK_METADATA"
}
 }
  }
}

pgvector が有力な場面:

既存の Aurora PostgreSQL クラスターを保有しており追加インフラコストを抑えたい場合、pgvector 拡張を有効化するだけで Vector store に転用できます。ただしベクトル数が数百万を超えると HNSW インデックスのメモリ消費が問題になるため、スケーリング計画を事前に立案してください。

2-3. Embedding model 選定軸 — Titan G2 vs Cohere Embed Multilingual

Embedding model は「言語・精度・コスト」の 3 軸で選定します。

項目Titan Embeddings G2Cohere Embed Multilingual v3
次元数1,024 次元1,024 次元
対応言語英語中心 (日本語は限定的)100+ 言語 (日本語高精度)
コスト$0.00002 / 1K tokens$0.0001 / 1K tokens
日本語 RAG非推奨 (精度低)推奨
英語 RAG推奨 (コスト優位)推奨 (精度優位)
最大 Input8,192 tokens512 tokens

日本語コンテンツには Cohere Embed Multilingual を選択:

Titan Embeddings は英語コーパスで学習されており、日本語の意味的類似性を正確にベクトル化できません。製品マニュアル・社内規定・FAQ など日本語文書が主体の場合、Cohere Embed Multilingual v3 を選択することで Recall@5 が 20–35% 向上します。

EMBEDDING_MODEL_JAPANESE = (
 "arn:aws:bedrock:ap-northeast-1::foundation-model/"
 "cohere.embed-multilingual-v3"
)

EMBEDDING_MODEL_ENGLISH = (
 "arn:aws:bedrock:ap-northeast-1::foundation-model/"
 "amazon.titan-embed-text-v2:0"
)

コスト試算例 (初期 Embedding / 月次):

  • 10万文書 × 平均500 tokens = 5,000万 tokens
  • Titan G2: 5,000万 ÷ 1,000 × $0.00002 = $1.0
  • Cohere Multilingual: 5,000万 ÷ 1,000 × $0.0001 = $5.0

Embedding 初期費用は 5 倍差ですが、Incremental sync を正しく設計すれば月次の再計算コストは大幅に削減できます。Embedding model を後から変更すると Full re-sync が必要になるため、初期選定が最も重要な意思決定です。

2-4. S3 data source × KMS 暗号化 — 機密データ管理

Knowledge Bases で扱う文書が業務上の機密情報を含む場合、AWS KMS カスタマー管理キー (CMK) を使用した暗号化と IAM ポリシーによるアクセス制御が必須です。

resource "aws_s3_bucket" "kb_data_source" {
  bucket = "company-bedrock-kb-${data.aws_caller_identity.current.account_id}"
}

resource "aws_s3_bucket_server_side_encryption_configuration" "kb_sse" {
  bucket = aws_s3_bucket.kb_data_source.id

  rule {
 apply_server_side_encryption_by_default {
sse_algorithm  = "aws:kms"
kms_master_key_id = aws_kms_key.kb_key.arn
 }
 bucket_key_enabled = true
  }
}

resource "aws_kms_key" "kb_key" {
  description = "Bedrock KB data source encryption key"
  deletion_window_in_days = 30
  enable_key_rotation  = true
}

機密文書を扱う KB では、S3 バケットポリシーで「Bedrock サービスプリンシパルからのアクセスのみ許可」する構成も有効です。詳細な暗号化設計・KMS キーローテーション・IAM 最小権限パターンは「セキュリティ本格運用 Vol1」を参照してください。

2-5. Sync戦略 — Incremental sync vs Full re-sync

S3 の文書が更新された際に Vector store をどう同期するかは、運用コストとデータ鮮度のトレードオフです。

戦略仕組みメリットデメリット
Incremental sync変更差分のみ Embedding 再計算コスト低 / 高速S3 versioning 必須
Full re-sync全文書を再 Embeddingシンプルコスト高 / 時間がかかる

Incremental sync の実装:

import boto3

bedrock_agent = boto3.client("bedrock-agent", region_name="ap-northeast-1")

def sync_knowledge_base(kb_id: str, data_source_id: str) -> str:
 response = bedrock_agent.start_ingestion_job(
  knowledgeBaseId=kb_id,
  dataSourceId=data_source_id,
  description="Incremental sync triggered by S3 change"
 )
 return response["ingestionJob"]["ingestionJobId"]

def get_sync_status(kb_id: str, data_source_id: str, job_id: str) -> dict:
 response = bedrock_agent.get_ingestion_job(
  knowledgeBaseId=kb_id,
  dataSourceId=data_source_id,
  ingestionJobId=job_id
 )
 job = response["ingestionJob"]
 return {
  "status": job["status"],
  "statistics": job.get("statistics", {}),
 }

S3 Event + Lambda による自動同期:

S3 PUT/DELETE イベント
  → EventBridge Rule
 → Lambda (sync_knowledge_base 呼び出し)
→ Bedrock StartIngestionJob API
  → Vector store 差分更新

落とし穴:

  • S3 versioning を無効にした状態で Incremental sync を設定すると、削除文書が Vector store に残留します。S3 versioning は Incremental sync の前提条件です。
  • 文書更新頻度が高い場合 (1 時間に 100 件以上)、Ingestion job のキューが溢れる可能性があります。SQS でバッファリングし、5–15 分間隔でまとめて同期するバッチ設計を採用してください。
  • Full re-sync は全文書分の Embedding コストが発生するため、Embedding model 切り替え・インデックス再設計時以外は実施しないルールを定めてください。
Knowledge Bases 4要素 設計原則

  1. Vector store選定: 本番・中大規模KBはOpenSearch Serverlessを第1候補に。既存Aurora環境があればpgvectorも有力。PineconeはサードパーティVectorDB統合が必要な場合のみ。
  2. Embedding選定: 日本語コンテンツはCohere Embed Multilingual v3を必ず選択。Titan G2は英語専用。Embedding model変更時はFull re-syncが必須となるため初期選定を慎重に行うこと。
  3. S3暗号化: 機密文書を扱うKBはKMS CMK暗号化必須。S3バケットポリシーでBedrockサービスプリンシパルのアクセスのみを許可する最小権限設計を採用すること。
  4. Sync戦略: S3 versioningを必ず有効化し、Incremental syncを標準とする。Full re-syncはEmbedding model変更・インデックス再設計時のみ実施し、実行前に費用試算を行うこと。

3. Chunking strategy 実践 (山場1) — Fixed-size / Hierarchical / Semantic 選択フローチャート

Chunking strategy 比較図 — Fixed / Hierarchical / Semantic 選択フローチャート

3-1. Chunking が RAG精度を決める理由 — 検索精度の70%は chunk設計で決まる

RAGシステムの精度向上において、多くの実装者がEmbedding modelの選定やVector storeのスペックに注目しがちだ。しかし実際にはChunking設計が検索精度全体の約70%を左右するという現実がある。

なぜChunkingがこれほど重要なのか。RAGの検索フロー「S3 → Embedding → Vector store → Retrieve」において、Chunk(断片)は検索の最小単位だ。Chunkが大きすぎると1件のChunkが複数のトピックを含み、ベクトル空間での位置が曖昧になる。Chunkが小さすぎると文脈情報が断絶し、LLMが回答生成に必要な背景情報を得られない。

具体的な影響を数値で示す:

Chunk問題検索精度への影響LLM出力品質
chunk_size=2000 (大きすぎ)Recall@5が15%低下無関係な文章を含む回答が増加
chunk_size=50 (小さすぎ)Precision@5が25%低下文脈不足によるHallucination多発
overlap=0 (重複なし)境界部の情報欠損段落またぎの質問で回答品質が劣化
最適設計 (後述)Recall@5=0.85以上本番品質の回答生成が可能

Bedrock Knowledge Basesでは、現時点で3種類のChunking strategyをサポートしている: Fixed-size chunking (デフォルト)、Hierarchical chunking (親子構造)、Semantic chunking (意味境界)。それぞれ用途と特性が異なるため、文書種別と精度要件に応じた選択が必須だ。


3-2. Fixed-size chunking (デフォルト) — chunk_size 300 / overlap 60 の根拠と適用場面

Fixed-size chunkingは、文書をトークン数ベースで一定サイズに分割する最もシンプルなstrategy。Bedrock Knowledge Basesのデフォルト設定であり、大半のユースケースをカバーできる。

chunk_size=300 / overlap=60 が「本番標準値」の根拠:

  • chunk_size=300: Titan Embeddingsの最適処理範囲 (200-500トークン) の中央付近。300トークンは英語で約200単語、日本語で約400文字に相当し、1つの論点を完結させるのに十分な単位。
  • overlap=60 (chunk_sizeの20%): 段落をまたぐ質問 (例: 「前節で説明した〇〇について詳しく」) に対し、Chunk境界で情報が断絶しないよう前後20%のオーバーラップを設ける。20%未満だと境界断絶リスクが増し、25%超だと重複コンテンツがVector storeの精度を下げる。

Terraform設定例 (Fixed-size chunking):

resource "aws_bedrockagent_knowledge_base" "main" {
  name  = "production-kb"
  role_arn = aws_iam_role.kb.arn

  knowledge_base_configuration {
 type = "VECTOR"
 vector_knowledge_base_configuration {
embedding_model_arn = "arn:aws:bedrock:ap-northeast-1::foundation-model/amazon.titan-embed-text-v2:0"
 }
  }

  storage_configuration {
 type = "OPENSEARCH_SERVERLESS"
 opensearch_serverless_configuration {
collection_arn = aws_opensearchserverless_collection.main.arn
vector_index_name = "bedrock-knowledge-base-default-index"
field_mapping {
  vector_field= "bedrock-knowledge-base-default-vector"
  text_field  = "AMAZON_BEDROCK_TEXT_CHUNK"
  metadata_field = "AMAZON_BEDROCK_METADATA"
}
 }
  }
}

resource "aws_bedrockagent_data_source" "main" {
  knowledge_base_id = aws_bedrockagent_knowledge_base.main.id
  name  = "s3-documents"

  data_source_configuration {
 type = "S3"
 s3_configuration {
bucket_arn = aws_s3_bucket.documents.arn
 }
  }

  # Fixed-size chunking: chunk_size=300, overlap=60 (20%)
  vector_ingestion_configuration {
 chunking_configuration {
chunking_strategy = "FIXED_SIZE"
fixed_size_chunking_configuration {
  max_tokens= 300
  overlap_percentage = 20
}
 }
  }
}

Python (boto3) での設定例:

import boto3

client = boto3.client("bedrock-agent", region_name="ap-northeast-1")

response = client.create_data_source(
 knowledgeBaseId="XXXXXXXXXX",
 name="s3-documents",
 dataSourceConfiguration={
  "type": "S3",
  "s3Configuration": {
"bucketArn": "arn:aws:s3:::your-documents-bucket",
  },
 },
 vectorIngestionConfiguration={
  "chunkingConfiguration": {
"chunkingStrategy": "FIXED_SIZE",
"fixedSizeChunkingConfiguration": {
 "maxTokens": 300,
 "overlapPercentage": 20,  # 300の20% = 60トークンオーバーラップ
},
  }
 },
)

Fixed-size chunkingの適用場面:

向いているケース向いていないケース
構造が均一な文書 (FAQリスト / 製品仕様書)章の長さが不均一なドキュメント
PoC / 初期実装 (設定シンプル)技術論文 (1つの定理が複数ページに跨る)
コスト最優先の本番環境法律文書 (条項の意味が前後関係に依存)
テキストの密度が均一なデータソース会話ログ (発話ごとに意味が独立)

3-3. Hierarchical chunking (親子構造) — 子Chunkで検索し親Chunkで生成するメリット

Hierarchical chunkingは、文書を大きな親Chunk小さな子Chunkの2層構造で管理する手法。子Chunkでベクトル検索を行い、ヒットした子Chunkの親Chunkを取得してLLMに渡す設計だ。

なぜ2層構造が高精度を生むのか:

  • 子Chunk (検索層): 小さい単位 (50-100トークン) でEmbeddingすることで、ベクトル空間での意味的な純度が高まる。質問文との類似度計算が精密になり、Recall@Kが向上する。
  • 親Chunk (生成層): LLMに渡す文脈は大きい単位 (400-800トークン) で与える。子Chunkだけでは情報が断絶するが、親Chunkを渡すことで前後の文脈を含めた回答生成が可能になる。

構造イメージ (テキスト版):

親Chunk (parent_chunk_size=512トークン)
├─ 子Chunk-A (child_chunk_size=100): "Bedrockは..."
├─ 子Chunk-B (child_chunk_size=100): "Knowledge Basesは..."
├─ 子Chunk-C (child_chunk_size=100): "Embeddingには..."
├─ 子Chunk-D (child_chunk_size=100): "Vector storeとして..."
└─ 子Chunk-E (child_chunk_size=100): "RAGフローは..."

検索フェーズ: 子Chunkのベクトルで候補を選出
生成フェーズ: 親Chunkを丸ごとLLMのコンテキストに渡す

Terraform設定例 (Hierarchical chunking):

vector_ingestion_configuration {
  chunking_configuration {
 chunking_strategy = "HIERARCHICAL"
 hierarchical_chunking_configuration {
level_configurations {
  max_tokens = 512  # 親Chunk (生成コンテキスト用)
}
level_configurations {
  max_tokens = 100  # 子Chunk (検索精度向上用)
}
overlap_tokens = 30  # 子Chunk間のオーバーラップ
 }
  }
}

Hierarchical chunkingの適用場面と注意点:

向いているケース注意点
技術ドキュメント (章をまたぐ説明)Embeddingコストが2層分になる
FAQ (問いと答えのペア)Vector storeの保管量が増加
長い説明文書で「要点検索+詳細生成」が必要な場合Bedrock KBのHierarchicalは親子2層固定
Recall@K重視で文脈欠損を防ぎたい場合PoC段階では設定が複雑

Fixed-sizeと比べてEmbeddingコストは約2倍になるが、技術文書や製品マニュアルのような長文ドキュメントでは精度向上効果がコスト増を上回ることが多い。まずFixed-sizeで計測し、Recall@Kが0.75未満の場合にHierarchicalへの切り替えを検討するのが実践的な判断軸だ。


3-4. Semantic chunking (意味境界) — sentence boundary 検出と文書構造活用

Semantic chunkingは、文書の意味的な境界を検出して分割点を決定するstrategy。固定トークン数ではなく、文の区切りや段落の終端を分割点にするため、Chunk内の意味的一貫性が最も高い。

仕組みの詳細:

  1. テキストを文単位に分割 (sentence boundary detection)
  2. 隣接する文のEmbeddingの類似度を計算
  3. 類似度が閾値を下回るポイント (意味の断絶点) を分割境界として採用
  4. 境界で区切られたChunk群をVector storeに格納

このアプローチにより、「前の文はAというトピック、次の文はBというトピック」という意味の切れ目でChunkが分割される。法律文書・学術論文・会議議事録のような、段落ごとにトピックが切り替わる不均一な構造の文書で特に効果を発揮する。

Terraform設定例 (Semantic chunking):

vector_ingestion_configuration {
  chunking_configuration {
 chunking_strategy = "SEMANTIC"
 semantic_chunking_configuration {
max_token  = 300  # Chunkの最大トークン数 (上限)
buffer_size= 0 # 前後文をバッファに含める文数
breakpoint_percentile_threshold = 95# 意味断絶閾値 (95%ile = より積極的に分割)
 }
  }
}

breakpoint_percentile_threshold は類似度スコアの下位N%ile以下を分割境界とするパラメータ。90未満では分割過多でChunkが細かくなりすぎ、97超では分割不足で大きなChunkが残る。90-97の範囲でチューニングすることを推奨する。

3 strategy コストトレードオフ比較:

観点Fixed-sizeHierarchicalSemantic
Embeddingコスト中〜高 (2層分)高 (境界検出にも使用)
検索精度最高
Sync時間短い中程度長い (境界検出処理)
適用難易度中〜高
推奨ユースケースPoC / 均一文書技術文書 / FAQ法律・論文・不均一文書

Semantic chunkingは精度が最も高いが、Sync処理のコストと時間が増大する。文書量が多い本番環境では、差分Sync比較検証を行い、Embeddingコストと精度向上のトレードオフを定量的に評価してから採用することを推奨する。


3-5. Chunking strategy 選択フローチャート — 文書種別×検索精度要件×コスト

以下のフローで、自社ユースケースに最適なstrategyを選択できる。

[START]
 │
 ▼
Q1: PoC / 初期実装 or コスト最優先?
 │ YES → Fixed-size (chunk_size=300, overlap=60) ← 迷ったらまずこれ
 │ NO ↓
 ▼
Q2: 文書の長さや構造が均一か?
 │ YES (FAQ / 製品仕様 / 均一テキスト)
 │→ Fixed-size (chunk_size=200-400, overlap=15-25%)
 │ NO ↓
 ▼
Q3: 「要点検索 + 詳細生成」の両立が必要か?
 │ YES (技術文書 / マニュアル / FAQ深掘り)
 │→ Hierarchical (parent_chunk_size=512, child_chunk_size=100)
 │ NO ↓
 ▼
Q4: 文書が不均一構造か / 法律文書・論文・会話ログか?
 │ YES → Semantic (breakpoint_percentile=95, max_token=300)
 │ NO ↓
 ▼
Q5: Embeddingコスト上限あり or 文書量が大規模 (100万ページ超)?
 │ YES → Fixed-size (コスト制約優先)
 │ NO  → Hierarchical (汎用高精度)

3軸決定表 (文書種別×精度要件×コスト許容):

文書種別精度要件コスト許容推奨 Strategy
FAQ / 均一テキスト標準Fixed-size (300/60)
製品マニュアルHierarchical (512/100)
技術論文 / 法律文書最高Semantic (max=300, p=95)
会話ログ / チャット標準〜高低〜中Fixed-size (150/30)
ニュース / ブログ標準Fixed-size (300/60)
契約書 / 規約最高Semantic (max=200, p=90)

3-6. chunk_size / overlap 推奨値早見表

本番運用から得られた推奨値をまとめる。

ユースケースchunk_sizeoverlapoverlap_%Strategy
汎用スタート (推奨デフォルト)3006020%Fixed-size
短文FAQリスト1502013%Fixed-size
長文技術ドキュメント4008020%Fixed-size
マニュアル (要点+詳細両立)親:512 / 子:10030Hierarchical
法律文書 / 学術論文max:300Semantic (p=95)
会話ログ / チャット履歴1501510%Fixed-size
コード / 設定ファイル2004020%Fixed-size

調整時の注意点:

  • chunk_sizeを変更したら必ず全文書を再Sync (差分Syncでは古いChunkが残留し、精度が混在する)
  • overlapはchunk_sizeの15-25%の範囲に収める (この範囲外はコストと精度の両方で非効率)
  • Semantic chunkingのbreakpoint_percentile_threshold90-97の範囲でチューニング (低すぎると分割過多、高すぎると大Chunkが残存)
  • Hierarchical chunkingは親Chunkサイズを子Chunkの4-8倍に設定するのが一般的な目安
Chunking 3鉄則

  1. chunk_size最適化: 本番デフォルトはchunk_size=300 / overlap=60 (20%)。文書均一性と精度要件に応じて150-512の範囲で調整する。変更時は必ず全文書を再Syncすること — 差分Syncでは古いChunkが残留し、検索精度が混在する。
  2. overlap設計: オーバーラップはchunk_sizeの15-25%に設定する。段落をまたぐ質問のChunk境界断絶を防ぐ。overlap=0は禁止 — 境界部の情報欠損でHallucinationが多発する。25%超は重複コンテンツがVector storeの精度を下げる。
  3. strategy選定: まずFixed-sizeで検証し、Recall@Kが0.75未満ならHierarchical/Semanticを検討する。切り替えはEmbeddingコストと精度向上を定量比較してから行う。Semanticはコスト最高・精度最高なため、法律文書・論文・不均一構造の文書に限定して採用するのが現実解だ。

4. Retrieval API 実践 (山場2) — Retrieve / RetrieveAndGenerate / Metadata filtering / Reranking

Retrieval API 処理フロー — Retrieve / RetrieveAndGenerate / Metadata filtering / Reranking
RAG精度改善フロー — Chunk→Embed→Store→Retrieve→Rerank→Generate

4-1. Retrieve API vs RetrieveAndGenerate API — 使い分けの判断軸

Bedrock Knowledge Bases の Retrieval フェーズは 2 つの API で構成されます。選択を誤ると「精度は高いが柔軟性がない」「柔軟だが実装コストが高い」という問題を招きます。

観点RetrieveAndGenerateRetrieve
処理内容検索 + LLM 生成を 1 API で完結検索結果のみ返却 (生成なし)
プロンプト制御Bedrock 管理 (カスタマイズ限定的)独自プロンプトで完全制御
実装難易度低 (1 API 呼び出し)高 (Retrieve + InvokeModel の 2 段階)
推奨場面PoC / 汎用 FAQ / プロンプトへのこだわりが薄い場面複数 KB 統合 / カスタム出力形式 / Bedrock Agents 連携

RetrieveAndGenerate — シンプル RAG の boto3 実装:

import boto3

bedrock_agent_runtime = boto3.client(
 "bedrock-agent-runtime", region_name="ap-northeast-1"
)

def retrieve_and_generate(query: str, kb_id: str) -> dict:
 response = bedrock_agent_runtime.retrieve_and_generate(
  input={"text": query},
  retrieveAndGenerateConfiguration={
"type": "KNOWLEDGE_BASE",
"knowledgeBaseConfiguration": {
 "knowledgeBaseId": kb_id,
 "modelArn": (
  "arn:aws:bedrock:ap-northeast-1::foundation-model"
  "/anthropic.claude-3-5-sonnet-20241022-v2:0"
 ),
 "retrievalConfiguration": {
  "vectorSearchConfiguration": {
"numberOfResults": 5,
"overrideSearchType": "HYBRID",
  }
 },
 "generationConfiguration": {
  "promptTemplate": {
"textPromptTemplate": (
 "以下の文脈のみを使用して質問に答えてください。"
 "文脈に記載がない場合は「資料に記載がありません」と回答してください。\n\n"
 "文脈:\n$search_results$\n\n質問: $query$"
)
  }
 },
},
  },
 )
 return {
  "answer": response["output"]["text"],
  "citations": response.get("citations", []),
 }

Retrieve — 独自プロンプト制御の boto3 実装:

import json

bedrock_runtime = boto3.client("bedrock-runtime", region_name="ap-northeast-1")

def retrieve_then_generate(query: str, kb_id: str) -> dict:
 # Step 1: KB から関連ドキュメントを取得
 retrieve_response = bedrock_agent_runtime.retrieve(
  knowledgeBaseId=kb_id,
  retrievalQuery={"text": query},
  retrievalConfiguration={
"vectorSearchConfiguration": {
 "numberOfResults": 5,
 "overrideSearchType": "HYBRID",
}
  },
 )
 chunks = retrieve_response["retrievalResults"]

 # Step 2: Retrieve 結果を文脈として整形
 context = "\n\n---\n\n".join(
  f"[出典: {r['location']['s3Location']['uri']}]\n{r['content']['text']}"
  for r in chunks
 )

 # Step 3: 独自プロンプトで InvokeModel
 prompt = (
  f"以下の文脈のみを根拠に回答してください。"
  f"文脈にない情報は推測せず「資料に記載がありません」と述べてください。\n\n"
  f"文脈:\n{context}\n\n質問: {query}"
 )
 model_response = bedrock_runtime.invoke_model(
  modelId="anthropic.claude-3-5-sonnet-20241022-v2:0",
  body=json.dumps({
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 1000,
"messages": [{"role": "user", "content": prompt}],
  }),
 )
 body = json.loads(model_response["body"].read())
 return {"answer": body["content"][0]["text"], "retrieved_chunks": chunks}

Retrieve API を選択すると、複数 KB を統合したり、Retrieve 結果に後処理 (Reranking / フィルタリング) を挟んでから LLM に渡すことができます。Bedrock Agents との Multi-step reasoning 連携では Retrieve が基本となります。


4-2. Metadata filtering JSON 完全例 — andAll / orAll / greaterThan パターン

Metadata filtering は Vector 検索の前に文書属性 (カテゴリ・日付・部門等) で候補を絞り込む機能です。S3 上の各ドキュメントに .metadata.json を配置することで任意のメタデータを付与できます。

メタデータ JSON 例 (document.pdf.metadata.json として S3 に配置):

{
  "metadataAttributes": {
 "category": "sales",
 "department": "east",
 "year": 2026,
 "confidential": false
  }
}

andAll — 複数条件の AND 結合:

filter_config = {
 "filter": {
  "andAll": [
{"equals": {"key": "category", "value": "sales"}},
{"equals": {"key": "department", "value": "east"}},
{"equals": {"key": "confidential", "value": False}},
  ]
 }
}

orAll — 複数カテゴリ横断検索 (OR 結合):

filter_config = {
 "filter": {
  "orAll": [
{"equals": {"key": "category", "value": "sales"}},
{"equals": {"key": "category", "value": "support"}},
  ]
 }
}

greaterThan — 年度指定 (数値比較) + andAll のネスト:

filter_config = {
 "filter": {
  "andAll": [
{"greaterThanOrEquals": {"key": "year", "value": 2025}},
{"equals": {"key": "department", "value": "east"}},
{
 "orAll": [
  {"equals": {"key": "category", "value": "sales"}},
  {"equals": {"key": "category", "value": "contract"}},
 ]
},
  ]
 }
}

Retrieve API に Metadata filtering を組み込む:

retrieve_response = bedrock_agent_runtime.retrieve(
 knowledgeBaseId=kb_id,
 retrievalQuery={"text": query},
 retrievalConfiguration={
  "vectorSearchConfiguration": {
"numberOfResults": 5,
"filter": filter_config["filter"],
  }
 },
)

サポートされる演算子: equals / notEquals / greaterThan / greaterThanOrEquals / lessThan / lessThanOrEquals / in / notIn / startsWith / listContains

大規模 KB (100 万チャンク超) では Metadata filtering によって検索対象を事前に絞り込むことで、Vector 検索のレイテンシを大幅に削減できます。


4-3. Reranking 戦略 — Cohere Rerank / コスト・精度トレードオフ

Retrieve API が返す検索結果は Vector 類似度スコアで並んでいますが、類似度が高い順 = 回答に最適な順とは限りません。Reranking は Retrieve 後に別のモデルが「質問との関連性」を再評価し、順位を入れ替えることで精度を向上させます。

[Query] → Retrieve (top-20 取得) → Reranker (top-20 を再評価) → top-5 に絞り込んで LLM へ渡す

Bedrock Reranking API (Cohere Rerank 統合):

def retrieve_with_reranking(query: str, kb_id: str, top_k: int = 5) -> list:
 # Step 1: 多めに Retrieve (top-20)
 retrieve_response = bedrock_agent_runtime.retrieve(
  knowledgeBaseId=kb_id,
  retrievalQuery={"text": query},
  retrievalConfiguration={
"vectorSearchConfiguration": {"numberOfResults": 20}
  },
 )
 chunks = retrieve_response["retrievalResults"]

 # Step 2: Bedrock Reranking API で再評価
 rerank_response = bedrock_agent_runtime.rerank(
  sources=[
{
 "type": "INLINE",
 "inlineDocumentSource": {
  "type": "TEXT",
  "textDocument": {"text": c["content"]["text"]},
 },
}
for c in chunks
  ],
  rerankingConfiguration={
"type": "BEDROCK_RERANKING_MODEL",
"bedrockRerankingConfiguration": {
 "modelConfiguration": {
  "modelArn": (
"arn:aws:bedrock:ap-northeast-1::foundation-model"
"/cohere.rerank-v3-5:0"
  )
 },
 "numberOfResults": top_k,
},
  },
  queries=[{"type": "TEXT", "textQuery": {"text": query}}],
 )
 reranked_indices = [r["index"] for r in rerank_response["rerankingResults"]]
 return [chunks[i] for i in reranked_indices]

コスト・精度トレードオフ比較:

手法精度向上追加コストレイテンシ増推奨場面
Reranking なし (top-5 直取)ベースラインなしなしPoC / コスト最優先
Bedrock Reranking (Cohere Rerank)+15-25% (Recall@5)$0.001/1K tokens+200-500ms本番 / 精度要件高
カスタム cross-encoder (SageMaker)+20-30%SageMaker 推論費用+500ms-2s特定ドメイン特化

4-4. RAG 精度評価 — Recall@K / Precision / Hallucination 率 の計測手法

RAG 精度の改善は「測定できるものだけ改善できる」が原則です。以下の 3 指標を定期計測し、改善サイクルを回します。

Recall@K — 関連ドキュメント取得率の計測:

def calculate_recall_at_k(
 relevant_doc_ids: list[str],
 retrieved_results: list[dict],
 k: int = 5,
) -> float:
 retrieved_uris = {
  r["location"]["s3Location"]["uri"]
  for r in retrieved_results[:k]
 }
 hit_count = len(set(relevant_doc_ids) & retrieved_uris)
 return hit_count / len(relevant_doc_ids) if relevant_doc_ids else 0.0

# テストセット評価ループ
test_cases = [
 {
  "query": "EKS ノードグループの推奨スペック",
  "relevant_doc_ids": ["s3://kb-data/eks-design-guide.pdf"],
 },
]
scores = []
for case in test_cases:
 result = retrieve_then_generate(case["query"], kb_id="KBID12345")
 scores.append(calculate_recall_at_k(
  case["relevant_doc_ids"], result["retrieved_chunks"], k=5
 ))
print(f"Recall@5: {sum(scores)/len(scores):.3f}")  # 0.75 以上が本番品質目安

Hallucination 率 — LLM Evaluation による自動検出:

def evaluate_hallucination(query: str, answer: str, context: str) -> dict:
 eval_prompt = (
  f"文脈と回答を評価してください。\n\n文脈:\n{context}\n\n"
  f"質問: {query}\n\n回答: {answer}\n\n"
  f"文脈に根拠がない主張を特定し、JSON で返答してください: "
  f'{{"grounded": true/false, "unsupported_claims": ["..."], "score": 0.0-1.0}}'
 )
 response = bedrock_runtime.invoke_model(
  modelId="anthropic.claude-3-5-sonnet-20241022-v2:0",
  body=json.dumps({
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 500,
"messages": [{"role": "user", "content": eval_prompt}],
  }),
 )
 body = json.loads(response["body"].read())
 return json.loads(body["content"][0]["text"])

評価指標の目安値と改善アクション:

指標目標値改善アクション
Recall@5≥ 0.75chunk_size縮小 / Hierarchical化 / numberOfResults増加
Precision@5≥ 0.60Metadata filtering追加 / Reranking導入
Hallucination 率≤ 10%プロンプト強化 (文脈外回答禁止) / Reranking精度向上

4-5. EKS 本番運用シリーズとの連携 — KB 呼出元 EKS アプリの設計

RAG を搭載したアプリケーションを EKS 上にデプロイする場合、EKS本番運用 Vol1 (クラスター設計 / IRSA / ALB Ingress) で解説した IRSA (IAM Roles for Service Accounts) パターンが Bedrock KB の認証基盤として直接活用できます。

EKS IRSA で Bedrock KB を呼び出す最小権限 IAM ポリシー:

{
  "Version": "2012-10-17",
  "Statement": [
 {
"Effect": "Allow",
"Action": [
  "bedrock:Retrieve",
  "bedrock:RetrieveAndGenerate",
  "bedrock:InvokeModel"
],
"Resource": [
  "arn:aws:bedrock:ap-northeast-1:ACCOUNT_ID:knowledge-base/KBID12345",
  "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0"
]
 }
  ]
}

EKS本番運用 Vol2 (Observability / FluentBit / Container Insights / ADOT) で解説した ADOT Collector を使うと、Bedrock API 呼び出しのトレースを X-Ray に送信し、RAG の各ステップ (Retrieve → Rerank → Generate) のレイテンシを可視化できます。EKS本番運用 Vol3 (GitOps × ArgoCD) の ArgoCD パイプラインを通じてデプロイすることで、KB 設定変更も GitOps フローで管理できます。


4-6. Observability Vol1 との連携 — CloudWatch Metrics + X-Ray で RAG 精度監視

Observability実践 Vol1 で解説した Application Signals / SLO / X-Ray は、RAG システムの精度監視にそのまま適用できます。

CloudWatch Metrics でカスタム RAG 精度指標を送信:

cloudwatch = boto3.client("cloudwatch", region_name="ap-northeast-1")

def publish_rag_metrics(recall_score: float, latency_ms: float, kb_id: str) -> None:
 cloudwatch.put_metric_data(
  Namespace="RAG/KnowledgeBases",
  MetricData=[
{
 "MetricName": "RecallAt5",
 "Dimensions": [{"Name": "KnowledgeBaseId", "Value": kb_id}],
 "Value": recall_score,
 "Unit": "None",
},
{
 "MetricName": "RetrieveLatencyMs",
 "Dimensions": [{"Name": "KnowledgeBaseId", "Value": kb_id}],
 "Value": latency_ms,
 "Unit": "Milliseconds",
},
  ],
 )

CloudWatch Alarm を設定して Recall@5 が 0.75 を下回ったら通知を受け取ることで、KB 再構築 (Re-indexing) のタイミングを自動検知できます。X-Ray トレースと組み合わせると、精度劣化の原因が Retrieve / Reranking / LLM 生成のどのフェーズにあるかを特定できます。

Retrieval 3鉄則

  1. API選定: PoC / 汎用 FAQ は RetrieveAndGenerate (1 API 呼び出し / 実装シンプル) を選択する。複数 KB 統合 / カスタム出力形式 / Bedrock Agents との Multi-step reasoning では Retrieve + 独自 InvokeModel の 2 段階構成を採用する。切り替えコストは低く、要件が変わったタイミングで移行できる。
  2. Metadata filtering: 本番 KB は必ず文書属性 (カテゴリ / 部門 / 年度) を付与し、クエリに応じた filtering を実装する。filtering なしの大規模 KB は Vector 検索が全文対象となりレイテンシが増大する。andAll / orAll / greaterThan を組み合わせて検索対象を最小化し、Precision を高めることが本番品質の鍵となる。
  3. Reranking: 本番環境では Retrieve (top-20) → Bedrock Reranking (Cohere Rerank, top-5) の 2 段階構成を標準とする。Reranking の追加によって Recall@5 が 15-25% 向上する一方、レイテンシは 200-500ms 増加する。Observability Vol1 で解説した SLO (P95 レイテンシ 3 秒以内など) を CloudWatch Alarm で監視し、許容範囲内での Reranking 採用可否を定量的に判断すること。

5. Bedrock Agents × Knowledge Bases 連携 — Action Group + KB / Multi-step reasoning / Terraform完全例

Bedrock Agents × Knowledge Bases 統合アーキテクチャ — Action Group + KB + Multi-step Reasoning
Agents × KB 呼び出しシーケンス

5-1. Vol1 Action Group の上に KB を追加するアーキテクチャ

AIシリーズ Vol1「Bedrock Agents 本番運用 完全ガイド」では、Action Group を使って外部 API を呼び出す Bedrock Agent の基礎を解説しました。Vol2 の本章では、その Action Group の上に Knowledge Bases を追加する地続き設計を実践します。

Action Group のみ (Vol1) と Action Group + KB (Vol2) の比較:

観点Action Group のみ (Vol1)Action Group + KB (Vol2)
情報ソースLambda で実装した外部 APIKB (Vector store) + 外部 API 両方
ユースケース動的データ取得 (在庫照会・予約)文書検索 + 動的操作の組み合わせ
Multi-step reasoning限定的フル対応 (KB検索→API呼出→回答生成)
Hallucination対策プロンプト依存KB Retrieval 根拠文書で抑制

Multi-step reasoning フロー:

ユーザーが「製品Aの最新仕様を教えて。在庫も確認してほしい」と問い合わせた場合、Agent は以下の Multi-step reasoning を実行します。

Step 1: KB Retrieve
  → ユーザークエリ「製品A 最新仕様」
  → Vector store から仕様文書チャンク取得 (Recall@5)

Step 2: Action Group 呼び出し
  → Lambda 「在庫照会 API」実行
  → 在庫数・納期を動的取得

Step 3: 統合回答生成
  → KB 根拠文書 + API レスポンスを Foundation Model に渡す
  → 根拠付き回答を生成 (Hallucination 抑制)

この設計により、「文書に書いていない最新情報 (在庫) は Action Group で取得し、文書情報 (仕様) は KB で正確に参照する」という役割分担が実現します。

5-2. Terraform完全例 — Agent + KB + Association の3リソース

# aws_bedrockagent_knowledge_base: KB 本体
resource "aws_bedrockagent_knowledge_base" "product_kb" {
  name  = "product-catalog-kb"
  description = "製品カタログ + 仕様書 RAG Knowledge Base"
  role_arn = aws_iam_role.bedrock_kb_role.arn

  knowledge_base_configuration {
 type = "VECTOR"
 vector_knowledge_base_configuration {
embedding_model_arn = "arn:aws:bedrock:ap-northeast-1::foundation-model/cohere.embed-multilingual-v3"
 }
  }

  storage_configuration {
 type = "OPENSEARCH_SERVERLESS"
 opensearch_serverless_configuration {
collection_arn = aws_opensearchserverless_collection.kb_collection.arn
vector_index_name = "bedrock-kb-default-index"
field_mapping {
  vector_field= "bedrock-knowledge-base-default-vector"
  text_field  = "AMAZON_BEDROCK_TEXT_CHUNK"
  metadata_field = "AMAZON_BEDROCK_METADATA"
}
 }
  }
}

# aws_bedrockagent_agent: Agent 本体 (Vol1 設計を継承)
resource "aws_bedrockagent_agent" "product_agent" {
  agent_name  = "product-support-agent"
  description = "製品サポート Agent — KB検索 + 在庫照会 Action Group"
  agent_resource_role_arn = aws_iam_role.bedrock_agent_role.arn
  foundation_model  = "anthropic.claude-3-5-sonnet-20241022-v2:0"
  idle_session_ttl_in_seconds = 600

  instruction = <<-EOT
 あなたは製品サポートエージェントです。
 Knowledge Base から製品仕様・FAQ を検索し、
 在庫照会 API と組み合わせて正確な回答を提供してください。
 Knowledge Base に情報がない場合は「確認できませんでした」と答えてください。
  EOT
}

# aws_bedrockagent_agent_knowledge_base_association: Agent ↔ KB 紐付け
resource "aws_bedrockagent_agent_knowledge_base_association" "product_kb_assoc" {
  agent_id = aws_bedrockagent_agent.product_agent.agent_id
  agent_version  = "DRAFT"
  description = "製品カタログKBをAgentに関連付け"
  knowledge_base_id = aws_bedrockagent_knowledge_base.product_kb.id
  knowledge_base_state = "ENABLED"
}

5-3. Agent IAM Role 設計 — 最小権限ポリシー

Bedrock Agent が KB を呼び出すには、Agent 実行ロールに bedrock:InvokeModelbedrock:Retrievebedrock:RetrieveAndGenerate の 3 権限が必要です。

{
  "Version": "2012-10-17",
  "Statement": [
 {
"Sid": "AllowFoundationModelInvocation",
"Effect": "Allow",
"Action": "bedrock:InvokeModel",
"Resource": "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0"
 },
 {
"Sid": "AllowKnowledgeBaseRetrieval",
"Effect": "Allow",
"Action": [
  "bedrock:Retrieve",
  "bedrock:RetrieveAndGenerate"
],
"Resource": "arn:aws:bedrock:ap-northeast-1:123456789012:knowledge-base/*"
 },
 {
"Sid": "AllowEmbeddingModelForSync",
"Effect": "Allow",
"Action": "bedrock:InvokeModel",
"Resource": "arn:aws:bedrock:ap-northeast-1::foundation-model/cohere.embed-multilingual-v3"
 }
  ]
}

Trust Policy (Bedrock サービスが Agent ロールを引き受ける設定):

{
  "Version": "2012-10-17",
  "Statement": [
 {
"Effect": "Allow",
"Principal": {
  "Service": "bedrock.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {
  "StringEquals": {
 "aws:SourceAccount": "123456789012"
  },
  "ArnLike": {
 "aws:SourceArn": "arn:aws:bedrock:ap-northeast-1:123456789012:agent/*"
  }
}
 }
  ]
}

aws:SourceArn 条件を必ず含めてください。aws:SourceAccount のみでは、同じアカウント内の別 Bedrock リソースが Agent ロールを引き受ける混乱した代理問題 (Confused Deputy) のリスクが残ります。aws:SourceArn で Agent ARN パターンを限定することで、このリスクを排除できます。

KB 専用 IAM ロールの定義 (aws_bedrockagent_knowledge_baserole_arn):

KB 本体のロールは Agent 実行ロールとは別に作成します。KB ロールには Embedding モデルの呼び出し権限・S3 データソースへのアクセス権限・OpenSearch Serverless への書き込み権限が必要です。

{
  "Version": "2012-10-17",
  "Statement": [
 {
"Sid": "AllowEmbeddingModel",
"Effect": "Allow",
"Action": "bedrock:InvokeModel",
"Resource": "arn:aws:bedrock:ap-northeast-1::foundation-model/cohere.embed-multilingual-v3"
 },
 {
"Sid": "AllowS3DataSource",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": [
  "arn:aws:s3:::your-kb-documents-bucket",
  "arn:aws:s3:::your-kb-documents-bucket/*"
]
 },
 {
"Sid": "AllowOpenSearchServerless",
"Effect": "Allow",
"Action": "aoss:APIAccessAll",
"Resource": "arn:aws:aoss:ap-northeast-1:123456789012:collection/*"
 }
  ]
}

Terraform での KB IAM ロール定義:

resource "aws_iam_role" "bedrock_kb_role" {
  name = "bedrock-kb-execution-role"

  assume_role_policy = jsonencode({
 Version = "2012-10-17"
 Statement = [{
Effect = "Allow"
Principal = { Service = "bedrock.amazonaws.com" }
Action = "sts:AssumeRole"
Condition = {
  StringEquals = {
 "aws:SourceAccount" = data.aws_caller_identity.current.account_id
  }
  ArnLike = {
 "aws:SourceArn" = "arn:aws:bedrock:ap-northeast-1:${data.aws_caller_identity.current.account_id}:knowledge-base/*"
  }
}
 }]
  })
}

resource "aws_iam_role_policy" "bedrock_kb_role" {
  name = "bedrock-kb-policy"
  role = aws_iam_role.bedrock_kb_role.id

  policy = jsonencode({
 Version = "2012-10-17"
 Statement = [
{
  Effect= "Allow"
  Action= "bedrock:InvokeModel"
  Resource = "arn:aws:bedrock:ap-northeast-1::foundation-model/cohere.embed-multilingual-v3"
},
{
  Effect= "Allow"
  Action= ["s3:GetObject", "s3:ListBucket"]
  Resource = [
 aws_s3_bucket.documents.arn,
 "${aws_s3_bucket.documents.arn}/*",
  ]
},
{
  Effect= "Allow"
  Action= "aoss:APIAccessAll"
  Resource = aws_opensearchserverless_collection.kb_collection.arn
},
 ]
  })
}

2 つのロール (Agent 実行ロール / KB ロール) を分離することで、それぞれの最小権限を正確に制御できます。KB ロールに Agent 呼び出し権限を混在させると、権限過多になりリスクが高まります。

5-4. IAM Vol1-4 クロスリンク — KB/Agent ロール設計の深化

Bedrock Agent と KB の IAM 設計は、IAM 基礎シリーズで解説したパターンを応用します。

5-5. AIシリーズ Vol1 との地続き設計

AIシリーズ Vol1 で構築した Action Group 基盤は、KB を追加することでそのまま拡張できます。既存の Action Group (Lambda 関数・API スキーマ) はそのままに、aws_bedrockagent_agent_knowledge_base_association リソースを追加するだけで Multi-step reasoning が有効になります。Vol1 で投資したコードベースを破棄せずに RAG 能力を後付けできるのが、Bedrock Agent + KB 統合の最大の強みです。

Action Group + KB 統合チェックリスト

  • aws_bedrockagent_agent_knowledge_base_association で Agent ↔ KB を紐付け済み
  • ☐ Agent 実行ロールに bedrock:Retrieve / bedrock:RetrieveAndGenerate を付与済み
  • ☐ Trust Policy の aws:SourceAccount 条件でアカウントを限定済み
  • ☐ KB の knowledge_base_state = "ENABLED" を確認済み
  • ☐ Agent instruction に「KB に情報がない場合の応答方針」を明記済み
  • ☐ Multi-step reasoning 動作をコンソールの Trace 機能で検証済み
  • ☐ fig04 (統合アーキテクチャ図) と mermaid02 (シーケンス図) で設計を可視化済み

6. 詰まりポイント7選 図解

6-1. Hallucination 抑制 — Retrieval 失敗時のフォールバック設計

症状: KB から関連チャンクが取得できなかった際、LLM が「それらしい」回答を捏造する。

原因: Retrieval スコアが低いチャンクでも RetrieveAndGenerate API がそのまま LLM に渡してしまう。スコア閾値の未設定が根本原因。

対処:

def retrieve_with_fallback(query: str, kb_id: str, score_threshold: float = 0.5):
 response = bedrock_runtime.retrieve(
  knowledgeBaseId=kb_id,
  retrievalQuery={"text": query},
  retrievalConfiguration={
"vectorSearchConfiguration": {
 "numberOfResults": 5,
 "overrideSearchType": "HYBRID"
}
  }
 )
 results = response["retrievalResults"]
 high_score = [r for r in results if r["score"] >= score_threshold]

 if not high_score:
  return "申し訳ございませんが、その件については情報を確認できませんでした。担当者にお問い合わせください。"

 context = "\n".join([r["content"]["text"] for r in high_score])
 return generate_answer(query, context)
Hallucination 抑制 3ステップ

  1. Retrieve API でスコアを取得し、閾値 (0.4–0.6) 未満のチャンクを除外する
  2. 高スコアチャンクが 0 件の場合は「確認できませんでした」の定型文を返す (LLM に渡さない)
  3. RetrieveAndGenerate の guardrailConfiguration でコンテンツフィルタリングを有効化する

6-2. Chunk size 最適化 — 短すぎ→文脈欠落 / 長すぎ→コスト増

症状: 検索結果が的外れ (短すぎ) またはトークン消費が異常に大きい (長すぎ)。

原因: デフォルトの chunk_size=300 を変更せずに長文PDF・仕様書を取り込んでいる。文書の性質に合わせた調整が未実施。

対処:

文書タイプ推奨 chunk_size推奨 overlap
FAQ / 短文ドキュメント150–300 tokens20–40 tokens
技術仕様書 / マニュアル300–500 tokens50–80 tokens
契約書 / 法的文書500–800 tokens100–150 tokens
長文レポートHierarchical 推奨

Hierarchical Chunking を使うと親チャンク (文脈) → 子チャンク (詳細) の 2 段階検索が可能になり、文脈欠落と精度の両立ができます。詳細は §3 の Chunking 戦略選択フローチャートを参照してください。

Chunk size 最適化の指針

  1. まず Hierarchical Chunking (parent 512 / child 150) を試し、Recall@5 を測定する
  2. Recall@5 が 0.7 未満の場合は chunk_size を 100 tokens 単位で調整する
  3. コスト制約がある場合は Fixed-size (300/60) を基本とし、コスト vs 精度のトレードオフを可視化する

6-3. Embedding 選定ミス — Titan vs Cohere の言語適合性

症状: 日本語クエリの検索精度が英語クエリより著しく低い。関連文書が検索されない。

原因: Titan Embeddings G2 を日本語コンテンツに適用している。Titan は英語コーパス中心で学習されており、日本語の意味的類似性を正確にベクトル化できない。

対処:

Embedding model を Cohere Embed Multilingual v3 に変更し、Full re-sync を実施する。変更後に Recall@5 を再測定して改善を定量評価する。

# Embedding model 変更後の Full re-sync
aws bedrock-agent start-ingestion-job \
  --knowledge-base-id kb-xxxxxxxx \
  --data-source-id ds-xxxxxxxx \
  --description "Full re-sync after Embedding model change"
Embedding 選定ミス 対処サマリ

  1. 日本語文書が含まれる KB は必ず Cohere Embed Multilingual v3 を選択する
  2. Embedding model を変更したら Full re-sync を実施する (差分では不十分)
  3. 変更前後で Recall@5 を比較し、改善を定量的に記録する

6-4. Vector store 選定ミス — スケール特性の見誤り

症状: 初期は問題なかったが、文書数が増えると検索レイテンシが劣化した。またはコストが想定の 5 倍以上になった。

原因: pgvector で数百万ベクトルを管理しようとして HNSW インデックスのメモリが枯渇。または OpenSearch Serverless の OCU が不足してレイテンシが増大。

対処:

問題原因移行先
pgvector でレイテンシ劣化ベクトル数 > 100万OpenSearch Serverless
OpenSearch OCU 不足検索 QPS > 50OCU 増設 または Pinecone
Pinecone コスト超過Index Units 肥大化不要 Index 削除 + 圧縮

Vector store の移行は Full re-sync が必要です。移行前に「現在のベクトル数」「月次 QPS」「コスト実績」の 3 点を計測し、移行判断を行ってください。

Vector store 移行の判断基準

  1. ベクトル数が 100 万を超えたら OpenSearch Serverless への移行を検討する
  2. P95 レイテンシが 100ms を超えたら OCU 増設または Vector store 移行を実施する
  3. 移行は Full re-sync を伴うため、移行前に Embedding 費用試算を必ず行う

6-5. コスト最適化 — Embedding + Vector store + Retrieve の3層コスト構造

症状: 月次の AWS 請求が想定の 3–10 倍になった。どのサービスがコストを押し上げているか不明。

原因: Embedding API 呼び出し / Vector store 保管 / Retrieve API 呼び出しの 3 層それぞれにコストが発生しており、いずれかで設計ミスが発生している。

3層コスト試算 (文書 10 万件 / 月 100 万クエリ の例):

サービス単価月次試算
Embedding (初期)Cohere Embed$0.0001/1K tokens$5 (初回のみ)
Embedding (差分)Cohere Embed$0.0001/1K tokens$0.5–$2
Vector storeOpenSearch Serverless$0.24/OCU時間$345 (2 OCU)
Retrieve APIBedrock Retrieve$0.001/1K retrieve$1,000

コスト最適化の詳細は「コスト最適化 Vol1 — Cost Explorer × Budgets × Compute Optimizer」を参照してください。

コスト削減策:
– Retrieve 回数削減: クライアント側キャッシュ (同一クエリ 60 秒 TTL)
– Vector store 最適化: OpenSearch Serverless の OCU を負荷に合わせてスケール調整
– Embedding 再計算防止: S3 versioning + Incremental sync で差分のみ再計算

Cross-Account KB 共有でコストを集約管理する方法は「マルチアカウント運用 Vol1 — Organizations × Control Tower × Landing Zone」を参照してください。

3層コスト管理の鉄則

  1. Embedding コストは初期 (Full sync) と月次 (Incremental) を分けて予算計上する
  2. Vector store コストは OpenSearch Serverless OCU の稼働時間で決まる — 開発環境は夜間停止を検討する
  3. Retrieve API コストはクライアント側キャッシュで 30–60% 削減できる — 同一クエリのキャッシュ TTL を設定する

6-6. レイテンシ管理 — Reranking 追加で精度↑だがレイテンシ↑

症状: Reranking を導入したら精度は上がったが、API レスポンスが 3 秒を超えるようになった。

原因: Retrieve (top-20) → Reranking (Cohere Rerank) の 2 段階処理が追加されており、Reranking に 200–500ms の追加レイテンシが発生している。

対処:

RAG パイプラインのレイテンシ内訳を計測し、ボトルネックを特定する。

import time

def retrieve_with_reranking_timed(query: str, kb_id: str):
 t0 = time.time()

 retrieve_resp = bedrock_runtime.retrieve(
  knowledgeBaseId=kb_id,
  retrievalQuery={"text": query},
  retrievalConfiguration={
"vectorSearchConfiguration": {"numberOfResults": 20}
  }
 )
 t1 = time.time()
 print(f"Retrieve: {(t1 - t0)*1000:.0f}ms")

 rerank_resp = bedrock_runtime.rerank(
  sources=[{"type": "INLINE", "inlineDocumentSource": {
"type": "TEXT_DOCUMENT",
"textDocument": {"text": r["content"]["text"]}
  }} for r in retrieve_resp["retrievalResults"]],
  rerankingConfiguration={
"type": "BEDROCK_RERANKING_MODEL",
"bedrockRerankingConfiguration": {
 "modelConfiguration": {
  "modelArn": "arn:aws:bedrock:ap-northeast-1::foundation-model/cohere.rerank-v3-5:0"
 },
 "numberOfRerankedResults": 5
}
  },
  textSources=[{"type": "QUERY", "textQuery": {"text": query}}]
 )
 t2 = time.time()
 print(f"Reranking: {(t2 - t1)*1000:.0f}ms / Total: {(t2 - t0)*1000:.0f}ms")
 return rerank_resp

レイテンシの CloudWatch 監視と SLO 設計は「Observability実践 Vol1 — Application Signals × SLO × X-Ray」を参照してください。

Reranking レイテンシ管理の指針

  1. Retrieve (top-20) → Reranking (top-5) の 2 段階構成を標準とする — top 数を増やすほどレイテンシが増大する
  2. P95 レイテンシを CloudWatch Alarm で監視し、SLO (例: 3 秒以内) を定量的に管理する
  3. レイテンシ SLO を満たせない場合は Reranking を省略し Retrieve のみ (top-5) に戻す判断基準を事前に定める

6-7. Re-indexing 戦略 — S3 versioning + KB 再同期フロー

症状: 文書を更新したが KB の検索結果が古いままになっている。または大量文書を更新した際に Ingestion job が失敗した。

原因: S3 versioning が無効のため削除文書が Vector store に残留している。または Ingestion job の並列実行数上限に到達している。

対処:

文書更新 → S3 versioning で差分追跡
  → EventBridge で S3 PutObject イベント検知
 → Lambda で StartIngestionJob 呼び出し (Incremental sync)
→ Bedrock が差分チャンクのみ再 Embedding
  → OpenSearch Serverless を更新

Full re-sync が必要な場合 (Embedding model 変更時):
  → S3 全オブジェクトを再アップロード (touch)
 → StartIngestionJob (Full sync)
→ Ingestion 完了後に古いチャンクを削除 (DeleteIngestionJob)

KB の障害復旧 (Vector store 損傷・誤削除からの復元) については「復旧・運用編 Vol1 — AWS Backup × Cross-Region DR」「復旧・運用編 Vol2 — Chaos Engineering × AWS FIS」「復旧・運用編 Vol3 — 対応手順自動化」「復旧・運用編 Vol4 — Multi-Region Active-Active / Active-Passive」を参照してください。

Re-indexing 戦略の鉄則

  1. S3 versioning を必ず有効化する — Incremental sync の前提条件であり、誤削除からの復元にも有効
  2. Ingestion job は同時実行数の上限 (デフォルト 1 件) があるため、高頻度更新は SQS でバッファリングして 5–15 分間隔でまとめて同期する
  3. Full re-sync は Embedding model 変更・インデックス再設計時のみ実施し、実行前に費用試算と影響範囲確認を行うこと

7. アンチパターン→正解パターン変換演習 (Terraform + Bedrock SDK + RetrieveAndGenerate API 3形式)

演習1: 壊れた KB Terraform (Embedding ARN欠落)

アンチパターン:

resource "aws_bedrockagent_knowledge_base" "broken" {
  name  = "my-kb"
  role_arn = aws_iam_role.kb_role.arn

  knowledge_base_configuration {
 type = "VECTOR"
 vector_knowledge_base_configuration {
# ❌ embedding_model_arn が未設定 → apply エラー
 }
  }

  storage_configuration {
 type = "OPENSEARCH_SERVERLESS"
 opensearch_serverless_configuration {
collection_arn = "arn:aws:aoss:ap-northeast-1:123456789012:collection/xxxxxx"
vector_index_name = "bedrock-kb-index"
field_mapping {
  vector_field= "bedrock-knowledge-base-default-vector"
  text_field  = "AMAZON_BEDROCK_TEXT_CHUNK"
  metadata_field = "AMAZON_BEDROCK_METADATA"
}
 }
  }
}

問題点: embedding_model_arn が未設定のため terraform apply がエラーになる。Bedrock は Embedding model なしで KB を作成できない。

正解パターン:

resource "aws_bedrockagent_knowledge_base" "correct" {
  name  = "product-kb"
  description = "製品カタログ Knowledge Base"
  role_arn = aws_iam_role.bedrock_kb_role.arn

  knowledge_base_configuration {
 type = "VECTOR"
 vector_knowledge_base_configuration {
# ✅ Embedding model ARN を必ず指定する
embedding_model_arn = "arn:aws:bedrock:ap-northeast-1::foundation-model/cohere.embed-multilingual-v3"
 }
  }

  storage_configuration {
 type = "OPENSEARCH_SERVERLESS"
 opensearch_serverless_configuration {
collection_arn = aws_opensearchserverless_collection.kb.arn
vector_index_name = "bedrock-kb-default-index"
field_mapping {
  vector_field= "bedrock-knowledge-base-default-vector"
  text_field  = "AMAZON_BEDROCK_TEXT_CHUNK"
  metadata_field = "AMAZON_BEDROCK_METADATA"
}
 }
  }
}

解説: embedding_model_arn は必須パラメーター。日本語コンテンツは cohere.embed-multilingual-v3、英語コンテンツは amazon.titan-embed-text-v2:0 を選択する。後から変更すると Full re-sync が必要になるため初期設定を慎重に行うこと。


演習2: 低精度 RAG (chunk_size=2000 / overlap=0)

アンチパターン:

# ❌ chunk_size が大きすぎ / overlap なし → 検索精度低下 + コスト増
chunking_config = {
 "chunkingStrategy": "FIXED_SIZE",
 "fixedSizeChunkingConfiguration": {
  "maxTokens": 2000,  # 大きすぎ: 文脈過多でトークン消費激増
  "overlapPercentage": 0  # overlap なし: チャンク境界で文脈が切断される
 }
}

問題点: chunk_size=2000 は技術仕様書向けでも過大。Vector search のスコアが文書全体の平均化になり精度が低下。overlap=0 はチャンク境界をまたぐ概念の検索を不可能にする。

正解パターン:

# ✅ Hierarchical Chunking (技術仕様書向け推奨)
chunking_config = {
 "chunkingStrategy": "HIERARCHICAL",
 "hierarchicalChunkingConfiguration": {
  "levelConfigurations": [
{"maxTokens": 512},  # 親チャンク: 文脈保持
{"maxTokens": 150}# 子チャンク: 詳細検索
  ],
  "overlapTokens": 60  # チャンク境界の文脈をオーバーラップ
 }
}

# ✅ Fixed-size (FAQ向け代替)
chunking_config_faq = {
 "chunkingStrategy": "FIXED_SIZE",
 "fixedSizeChunkingConfiguration": {
  "maxTokens": 300,# FAQ: 短め
  "overlapPercentage": 20  # 20% overlap で境界切断を防ぐ
 }
}

解説: 技術仕様書は Hierarchical Chunking (parent 512 / child 150) が最も効果的。FAQ・短文は Fixed-size (300/20%) が適切。Chunking 戦略の選択フローは §3 を参照。


演習3: コスト爆発 (Embedding 全文書再計算)

アンチパターン:

# ❌ 毎日 Full re-sync → 全文書の Embedding 費用が毎日発生
aws events put-rule \
  --name "daily-full-resync" \
  --schedule-expression "cron(0 2 * * ? *)"

# Lambda 関数で毎日実行
aws bedrock-agent start-ingestion-job \
  --knowledge-base-id kb-xxxxxxxx \
  --data-source-id ds-xxxxxxxx

問題点: Full re-sync は全文書を毎回 Embedding し直す。10 万文書 × $0.0001/1K tokens = 毎日 $5 × 30 日 = 月 $150 の不要な費用が発生する。

正解パターン:

# ✅ S3 Event + Incremental sync (変更差分のみ Embedding)
import boto3
import json

def lambda_handler(event, context):
 s3_event = event["Records"][0]["s3"]
 bucket = s3_event["bucket"]["name"]
 key = s3_event["object"]["key"]

 bedrock_agent = boto3.client("bedrock-agent")

 # S3変更差分のみを同期 (Incremental sync)
 response = bedrock_agent.start_ingestion_job(
  knowledgeBaseId=os.environ["KB_ID"],
  dataSourceId=os.environ["DATA_SOURCE_ID"],
  description=f"Incremental sync: s3://{bucket}/{key}"
 )
 print(f"Ingestion job: {response['ingestionJob']['ingestionJobId']}")

解説: S3 versioning を有効化し、S3 PutObject/DeleteObject イベントを EventBridge → Lambda → StartIngestionJob に流す設計。変更差分のみ再 Embedding するため、毎日の Full re-sync と比較してコストを 90%以上削減できる。


演習4: Hallucination が止まらない RAG

アンチパターン:

# ❌ Metadata filtering なし + Reranking なし → 無関係なチャンクで Hallucination
def generate_answer_no_filter(query: str, kb_id: str) -> str:
 response = bedrock_runtime.retrieve_and_generate(
  input={"text": query},
  retrieveAndGenerateConfiguration={
"type": "KNOWLEDGE_BASE",
"knowledgeBaseConfiguration": {
 "knowledgeBaseId": kb_id,
 "modelArn": "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0"
 # ❌ retrievalConfiguration なし → 全文書を無差別検索
}
  }
 )
 return response["output"]["text"]

正解パターン:

# ✅ Metadata filtering + Reranking で精度向上
def generate_answer_with_filter(query: str, kb_id: str, category: str) -> str:
 response = bedrock_runtime.retrieve_and_generate(
  input={"text": query},
  retrieveAndGenerateConfiguration={
"type": "KNOWLEDGE_BASE",
"knowledgeBaseConfiguration": {
 "knowledgeBaseId": kb_id,
 "modelArn": "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0",
 "retrievalConfiguration": {
  "vectorSearchConfiguration": {
"numberOfResults": 20,
"filter": {
 "equals": {
  "key": "category",
  "value": category  # カテゴリでフィルタ
 }
},
"rerankingConfiguration": {
 "type": "BEDROCK_RERANKING_MODEL",
 "bedrockRerankingConfiguration": {
  "modelConfiguration": {
"modelArn": "arn:aws:bedrock:ap-northeast-1::foundation-model/cohere.rerank-v3-5:0"
  },
  "numberOfRerankedResults": 5
 }
}
  }
 }
}
  }
 )
 return response["output"]["text"]

解説: Metadata filtering でカテゴリ・部門・年度など属性を絞り込み、Reranking で上位 5 件の精度を向上させる 2 段階設計が Hallucination 対策の標準パターン。


演習5: KB 呼出 Lambda の IAM 不足

アンチパターン:

{
  "Version": "2012-10-17",
  "Statement": [
 {
"Effect": "Allow",
"Action": "bedrock:*",
"Resource": "*"
 }
  ]
}

問題点: bedrock:* はワイルドカード付与で過剰な権限。セキュリティ審査で必ず指摘される。

正解パターン (AWS CLI形式):

# Lambda 実行ロールに最小権限ポリシーを付与
aws iam put-role-policy \
  --role-name lambda-bedrock-kb-role \
  --policy-name bedrock-kb-minimal \
  --policy-document '{
 "Version": "2012-10-17",
 "Statement": [
{
  "Sid": "AllowKBRetrieve",
  "Effect": "Allow",
  "Action": [
 "bedrock:Retrieve",
 "bedrock:RetrieveAndGenerate"
  ],
  "Resource": "arn:aws:bedrock:ap-northeast-1:123456789012:knowledge-base/kb-xxxxxxxx"
},
{
  "Sid": "AllowModelInvoke",
  "Effect": "Allow",
  "Action": "bedrock:InvokeModel",
  "Resource": "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0"
}
 ]
  }'

解説: KB へのアクセスは bedrock:Retrieve + bedrock:RetrieveAndGenerate の 2 アクションに絞り、Resource は Knowledge Base の ARN を明示する。bedrock:* は絶対に使用しない。IAM 最小権限設計の基礎は「IAM Vol1 — ポリシー設計基礎」を参照。


8. まとめ + Vol3予告 + 落とし穴10選 + 全8軸クロスリンク + AIシリーズ Vol1↔Vol2双方向リンク

8-1. 本記事で学んだこと

本記事では以下の 6 テーマを体系的に解説しました。

  1. Knowledge Bases 4要素 — S3 data source / Vector store (OpenSearch Serverless 推奨) / Embedding model (日本語は Cohere 必須) / Sync戦略 (Incremental sync 標準)
  2. Chunking 3形式 — Fixed-size (FAQ向け) / Hierarchical (仕様書向け) / Semantic (意味境界自動分割) の要件別選択フロー
  3. Retrieval API 実践 — Retrieve vs RetrieveAndGenerate の使い分け / Metadata filtering / Reranking で精度を段階的に向上
  4. Bedrock Agents × KB 連携 — Action Group + KB の Multi-step reasoning / Terraform 3リソース完全例 / IAM 最小権限ポリシー
  5. 詰まりポイント7選 — Hallucination / Chunk size / Embedding選定 / Vector store選定 / コスト / レイテンシ / Re-indexing
  6. 演習5問 — アンチパターン→正解パターン変換で実践力を強化

8-2. 落とし穴10選

#落とし穴対策
1chunk_size を調整せずデフォルトのまま運用文書タイプ別に chunk_size と overlap を最適化する
2overlap=0 でチャンク境界の文脈が切断overlap を 15–20% に設定する
3日本語文書に Titan Embeddings を使用Cohere Embed Multilingual v3 に変更し Full re-sync
4小規模 PoC に OpenSearch Serverless (2 OCU = 月 $350) を適用PoC は pgvector / 本番移行時に OpenSearch Serverless へ
5S3 versioning を無効のまま Incremental sync を設定S3 versioning を先に有効化してから KB を作成する
6bedrock:* ワイルドカード付与Retrieve + RetrieveAndGenerate + InvokeModel の最小権限に絞る
7Full re-sync を定期実行してコスト爆発S3 Event + Incremental sync に変更し差分のみ再計算
8Reranking 追加後のレイテンシ SLO 未設定P95 レイテンシを CloudWatch Alarm で監視し SLO を定量管理
9Retrieval スコア閾値未設定で Hallucination が多発score < 0.5 のチャンクを除外し定型文を返すフォールバックを実装
10Embedding model 変更コストを試算せずに切り替え実施変更前に全文書 × トークン数 × 単価で費用試算を必ず行う

8-3. AIシリーズ Vol3 予告

Vol2 では Knowledge Bases × RAG の本番実装を体系化しました。AIシリーズ Vol3 では以下のテーマを深化予定です。

  • Multi-Agent 協調 — 複数 Bedrock Agent が連携して複雑なタスクを分担処理するアーキテクチャ
  • Guardrails 本番設計 — コンテンツフィルタリング / PII 検出 / 拒否リスト管理の実装
  • Prompt Engineering 実践 — RAG プロンプトの最適化 / Few-shot / Chain-of-Thought の効果測定

8-4. 全8軸クロスリンク再掲

関連シリーズ 全8軸 完全ナビゲーション

  • AIシリーズ Vol2 (本記事): Bedrock Knowledge Bases × RAG実装
  • AIシリーズ Vol1: Bedrock Agents 本番運用 完全ガイド (前提・Vol2への地続き)
  • AIシリーズ Vol3: 近日公開予定 (Multi-Agent / Guardrails / Prompt Engineering)

IAM入門4巻: Vol1 / Vol2 / Vol3 / Vol4

EKS本番運用3巻: Vol1 / Vol2 / Vol3

復旧・運用編4巻: Vol1 / Vol2 / Vol3 / Vol4

セキュリティ本格運用 Vol1: Security Hub × GuardDuty × Audit Manager

コスト最適化 Vol1: Cost Explorer × Budgets × Compute Optimizer

マルチアカウント運用 Vol1: Organizations × Control Tower × Landing Zone

Observability実践 Vol1: Application Signals × SLO × X-Ray

8-5. AIシリーズ Vol1↔Vol2 双方向リンク — 地続き設計の完結

AIシリーズ Vol1「Bedrock Agents 本番運用 完全ガイド」では、Bedrock Agent の 5 要素 (Foundation Model / Action Group / Memory / Guardrails / Agent Alias) を体系化しました。Vol2 の本記事はその続編として、「Action Group で実現した外部 API 連携の上に、Knowledge Bases × RAG を重ねる地続き設計」を完成させます。

Vol1 で構築した Agent に aws_bedrockagent_agent_knowledge_base_association を追加するだけで KB 検索能力が付与される点は §5 で実証しました。Vol1 読了者は §5 から読み進めることで、既存 Agent をそのまま RAG 対応に発展させることができます。

3 箇所の Vol1 参照:
1. §1 冒頭 — AIシリーズの位置付けナビゲーション (架橋宣言)
2. §5 本文 — Action Group + KB 統合設計の地続き性 (実装架橋)
3. §8 本節 — Vol1→Vol2→Vol3 シリーズロードマップ (完結宣言)

AIシリーズは知識の積み上げ設計です。Vol1 で Agent 基礎を固め、Vol2 で RAG 実装を習得し、Vol3 で Multi-Agent / Guardrails の高度設計へ進む段階的ロードマップで、AWS 生成 AI 本番運用の全容を体系化します。

AIシリーズ Vol2 完結宣言 — Bedrock Knowledge Bases × RAG実装 完全習得

本記事を読了した方は以下をすべて習得しています。

  • Knowledge Bases 4要素 (S3 / Vector store / Embedding / Sync) の本番設計
  • Chunking 3形式 (Fixed-size / Hierarchical / Semantic) の要件別選択
  • Retrieval API (Retrieve / RetrieveAndGenerate / Metadata filtering / Reranking) の本番品質実装
  • Bedrock Agents × KB 連携の Terraform 完全例と IAM 最小権限設計
  • 詰まりポイント7選 (Hallucination / Chunk / Embedding / Vector store / Cost / Latency / Re-indexing) の対処法
  • 演習5問 (アンチパターン→正解パターン変換) による実践力の強化

次のステップ: AIシリーズ Vol3 (近日公開予定) — Multi-Agent 協調 / Guardrails 本番設計 / Prompt Engineering 実践で生成 AI の高度運用へ。

前巻: AIシリーズ Vol1 — Bedrock Agents 本番運用 完全ガイド (Vol2 への地続き入門)


第9軸 Network/VPC設計入門: Network/VPC設計入門 Vol1 — Transit Gateway × VPC Lattice × PrivateLink