機密資料のナレッジベースを AWS の閉域だけで回す ― OCR ローカル案と完全 AWS 案

機密資料のナレッジベースを AWS の閉域だけで回す ― OCR ローカル案と完全 AWS 案 AI

前々回で作った paperlake は、手元の GPU で紙資料を OCR し、S3 と Bedrock Knowledge Base と S3 Vectors で索引を作って、Claude Code から MCP で検索する構成だった。前回、図の扱いを試しているうちに気づいたことがある。Bedrock 上の Claude だけで、Claude Code と同じ品質の回答が作れる。だとすれば、外に出ている経路をなくして、機密資料のナレッジベースを「自社拠点 + AWS の閉域」だけで運用できるはずだ。今回はその構成を整理する。

いま外に出ている経路は 2 つ

RAG の部分(S3 → Knowledge Base → S3 Vectors)はすでに AWS の中で完結している。外に出ているのは次の 2 つだけである。

  1. OCR を動かす GPU サーバー(自社拠点。これは閉域の内側と言える)
  2. 検索結果を読んで答えを作る Claude Code(Anthropic API に出る)

2 を Bedrock の Claude に置き換え、1 を拠点に置くか AWS に置くかで 2 案に分かれる。

前提として確かめたこと

構想を書く前に、確かめておくべきことが 3 つあった。

Bedrock の Claude だけで答えが作れるか。 Knowledge Base の検索結果(本文と、図のキャプション・図中の文字)を Bedrock の Claude Sonnet 4.6 に渡し、技術資料のシーケンス図を Mermaid で再構成させた。参加者 4 局、信号の連鎖 6 種の向きがすべて原図と一致した。1 問あたり入力 4,100 トークン・出力 850 トークン、約 10 秒、約 $0.03。Claude Code でやったときと同じ品質である。

なお、Bedrock コンソールの「テスト」画面(RetrieveAndGenerate)で同じことを頼むと箇条書きに戻ってしまう。あれは生成プロンプトが固定で、図を描くような指示が通らない。閉域運用では、検索(Retrieve API)と生成(InvokeModel)を自前のプロンプトでつなぐ数十行のアプリを持つのが本筋だ。

import boto3
from anthropic import AnthropicBedrock

rt = boto3.client("bedrock-agent-runtime", region_name="ap-northeast-1")
res = rt.retrieve(knowledgeBaseId=KB, retrievalQuery={"text": question},
                  retrievalConfiguration={"vectorSearchConfiguration": {"numberOfResults": 4}})
excerpts = "\n\n".join(r["content"]["text"] for r in res["retrievalResults"])

client = AnthropicBedrock(aws_region="ap-northeast-1")
msg = client.messages.create(
    model="jp.anthropic.claude-sonnet-4-6", max_tokens=3000,
    messages=[{"role": "user", "content": f"<excerpts>\n{excerpts}\n</excerpts>\n\n{question}\n抜粋だけを根拠に答えること。"}],
)

S3 Vectors は閉域に置けるか。 ここが唯一の懸念だった。S3 Vectors は 2025 年に出た新しいサービスで、PrivateLink 対応を私は把握していなかった。調べると対応済みで、サービス名は com.amazonaws.<region>.s3vectors。エンドポイントポリシーで特定のベクトルバケットへの QueryVectors / GetVectors だけを許可でき、Direct Connect や VPN 経由でオンプレからも使える。これで穴がなくなった。

データがどこに行くか。 Bedrock は入力を学習に使わず、データはリージョン内に留まる。推論プロファイルを jp. 系(東京・大阪)にすれば国内に固定できる。逆に global. 系は海外リージョンにルーティングされうるので、機密資料では使わない。ベンチで global. を使っていた箇所は直す必要がある。

共通部分

案 A でも案 B でも同じ部分を先に書く。

要素 内容
保管 S3 バケット。バケットポリシーで aws:SourceVpce 以外を拒否。SSE-KMS
索引 Bedrock Knowledge Base(Titan Text Embeddings v2)+ S3 Vectors。Knowledge Base は自前の VPC を持たず、サービス側が S3 と S3 Vectors にアクセスする
生成 Bedrock の Claude(jp. 推論プロファイル)。Retrieve で取った抜粋を自前のプロンプトに入れて InvokeModel
入口 社内アプリ。VPC 内の ALB + Cognito か、社内ネットワーク限定
経路 VPC エンドポイント: s3、s3vectors、bedrock-runtime、bedrock-agent-runtime。インターネットゲートウェイと NAT なし
権限 取り込み用ロール(docs/ への Put/Delete と StartIngestionJob だけ)と参照用ロール(Retrieve と InvokeModel だけ)
監査 CloudTrail。S3 Vectors は NetworkActivity イベントで見える

案 A: OCR は拠点のローカル GPU

案 A: OCR は自社拠点のローカル GPU、知識は AWS 閉域、利用は Bedrock
案 A: OCR は自社拠点のローカル GPU、知識は AWS 閉域、利用は Bedrock

今の paperlake そのものである。GPU サーバーの Docker コンテナが OCR し、完了時に Markdown とメタデータだけを S3 に置いて取り込みジョブを起動する。原本とページ画像は拠点から出ない。OCR 完了時に削除するので、拠点に残るのもテキストだけだ。AWS への経路は Direct Connect か VPN で、S3 の VPC エンドポイントに向ける。

GPU は 8GB のもので足りる。日本語特化の OCR は VRAM 2.6GB、1 ページ 1 秒で、ジョブは 1 枚の GPU で直列に流す。

  • 資料の露出は最小。AWS に上がるのは OCR 済みテキストのみ
  • 費用は GPU サーバーの電気代と、AWS が月 $1 未満(索引)+ 生成が 1 問数セント
  • 拠点の GPU サーバーの面倒を見る必要がある。故障時は OCR が止まる(索引と検索は影響なし)

案 B: OCR も AWS

案 B: OCR も AWS (B1: EC2 GPU で同じコンテナ / B2: Bedrock Claude で OCR)
案 B: OCR も AWS (B1: EC2 GPU で同じコンテナ / B2: Bedrock Claude で OCR)

拠点に GPU 機を置きたくない、複数拠点から取り込みたい、という場合である。paperlake のパイプラインは OCR エンジンを差し替えられるので、置き方は 2 通りある。

B1: EC2 の GPU インスタンスで同じコンテナを動かす。 g6.xlarge(L4 24GB)などに同じ Docker イメージを載せる。処理するときだけ起動して終わったら止める運用にすると、400 ページの資料 1 冊が 10 分弱で、インスタンス代は 1 冊 $0.2 程度。精度は拠点と同じである。

B2: Bedrock の Claude に OCR させる。 GPU が要らない。自作の業務文書ではページ画像の書き起こしが正確だったが、出版物のページは著作物として書き起こしを断られるので、社内文書専用になる。費用は概算で 1 ページあたり Haiku 4.5 で $0.005、Sonnet 4.6 で $0.02。縦書きやルビの精度は日本語特化 OCR ほど検証していない。

どちらも原本のページ画像が AWS(閉域内)に上がる点が案 A と違う。処理後に削除する運用は同じにできる。

比較と推奨

案 A: OCR ローカル 案 B1: EC2 GPU 案 B2: Bedrock OCR
原本の置き場所 拠点のみ AWS 閉域(処理中のみ) AWS 閉域(処理中のみ)
縦書き・ルビ ○ ○ △(未検証)
出版物の取り込み ○ ○ ×(拒否される)
1 冊(400 頁)の OCR 費用 電気代のみ 約 $0.2〜1 $2〜8
拠点側の設備 GPU サーバー 不要 不要
paperlake の変更 なし 配置先だけ エンジン選択だけ

推奨は案 A で、GPU 機を持たない組織や複数拠点の運用が要るときに B1 に移す。B2 は「社内文書だけ、量が少ない」場合の最短経路である。

費用で言うと、閉域化で新たに固定費になるのは VPC エンドポイントの時間課金(インターフェイス型 3 つで月 $25 前後)だけで、それが月額の大半を占める。索引は月 $1 未満、取り込みは 400 ページで $0.005、生成は 1 問 $0.03 程度。

残っている作業

  • VPC、VPC エンドポイント、バケットポリシーの Terraform 化
  • 推論プロファイルの jp. 系への統一
  • 取り込み用 IAM ユーザーをロールに置き換える(EC2 ならインスタンスプロファイル、拠点なら IAM Roles Anywhere)
  • 社内アプリの雛形(上のスニペットの整形版)
  • Web UI の認証
  • 案 B1 の起動・停止の自動化

paperlake の位置づけは、これで「ローカル OCR で安く読める」から「閉域で機密資料のナレッジベースが作れる」に変わった。OCR は手元、知識は AWS 閉域、利用は Bedrock。一日の試行錯誤の末に、構成として一貫した形になったと思う。

コメント

タイトルとURLをコピーしました