コスト最適化されたドキュメント処理のために Amazon Nova 2 Lite と Claude を組み合わせる方法
本文の状態
日本語全文を表示中
詳細モードで約18分の本文を読めます。
同じ出来事の情報源
この情報源を基点に整理
AWS Machine Learning Blog
AWS は、Amazon Nova 2 Lite と Anthropic の Claude Sonnet 4.6 を組み合わせて、スキャンした年鑑ページから写真と名前を正確に抽出し、関連付ける効率的なドキュメント処理ソリューションを発表しました。
Continue in AI NEW LAB
このニュースを、実務の判断につなげる
AI NEW LABで、試したことや先に確認したい条件を共有できます。まずはログインなしで読めます。
AI NEW LABで論点を見るSource Article
元記事を日本語で読む
本文に関係しない購読案内、埋め込み通知、サイト内プロモーションは除いています。
スキャンされた卒業アルバムの一ページには、印刷された名前が 176 件、ポートレート写真が 4 枚含まれていますが、これらを機械的に結びつける構造化データは存在しません。このページをデジタル化するには、信頼性の高い写真検出機能(バウンディングボックス付き)と正確な名前の抽出が必要です。さらに、ページのレイアウトに基づいて「どの名前がどの顔に対応するか」を判定する仕組みも不可欠です。
本稿では、Amazon Nova 2 Lite と Anthropic の Claude Sonnet 4.6 を組み合わせることで、スキャン文書の大規模デジタル化を効率的に実現する方法を紹介します。私たちは Amazon Bedrock 上で、卒業アルバムのページをデジタル化する 2 モデル構成のパイプラインを構築しました。まず Amazon Nova 2 Lite が単一の呼び出しでネイティブなマルチモーダル抽出を行い、写真の検出、座標付きの名前抽出、そしてページレベルのメタデータ取得を担当します。その後、Claude Sonnet 4.6 がページのレイアウトに基づいて空間的な推論を行い、名前と顔を紐付けます。
このパイプラインを 336 ページのスキャンされた卒業アルバムで検証した結果、3,122 組の名前と顔の対応関係が生成され、その 93% が 0.95 以上の高い信頼スコアを獲得しました。この 2 モデル構成のアプローチは、単一のビジョン・ランゲージモデルに全タスクを任せる従来の手法と比較して、ページあたりのコストを約 3 分の 1 に削減できます。詳細な内訳については「コストに関する考慮事項」セクションをご覧ください。
ソリューションの概要
このパイプラインは 2 つの工程で構成されています。各工程では、特定のタスクに最適化された異なるモデルが使用されます。

図1:2モデル構成のパイプラインアーキテクチャ
スキャンされたページ画像は、2 つの連続したステージを経て処理されます。第 1 ステージでは、Amazon Nova 2 Lite が単一の API コールでネイティブなマルチモーダル抽出を実行します。これにより、写真の検出と分類(バウンディングボックス付き)、ページ上の可視テキストからの名前読み取りとその概略位置の特定、そしてページレベルのメタデータ出力が行われます。
第 2 ステージでは、Claude Sonnet 4.6 が空間推論を行い、Nova の出力結果を統合して名顔を照合します。
まず Amazon Nova 2 Lite が動作します。テキストと画像が混在する内容をネイティブに処理できるため、単一の Converse API コールで以下の 3 つの情報を取得できます:
- バウンディングボックスと分類情報が付与された検出写真
- 概略位置付きで読み取られたページ上の名前
- タイトルやカテゴリなどのページレベルメタデータ
このタスクでは、Converse API コールに推論設定を含めることで、推論レベルを LOW に設定しています。後述する Step 1 のコードブロック内の推論設定をご参照ください。336 ページすべてでテストした結果、構造化抽出においては LOW、MEDIUM、HIGH の各推論レベル間で精度に有意な差は見られませんでした。コスト面を考慮すると、LOW が最も安価な選択肢です。
Nova はこの設定を reasoning_config フィールドを通じて公開しています。一方、Claude(Step 2)では thinking フィールドが別途用意されているため、両モデルは異なる名称で推論制御を行っています。
1 段階目で「Nova 2 Lite」に求める情報を名前に限定し、ページ上のすべての OCR トークンを取得しないことが、コストを抑える鍵となります。下流の空間推論ステップでは、学級名簿や行事の説明といった全文を必要とするわけではありません。写真の近くに登場する名前さえ分かれば十分です。
Nova 2 Lite の出力を名前に制限することで、1 ページあたりの出力トークン数を約 4,500 トークン(フル OCR パスで想定される量)から約 1,000 トークンに抑えることが可能です。
Claude Sonnet 4.6 は、空間推論を行う 2 段階目のみで呼び出されます。Nova 2 Lite が取得した「名前と位置情報」と写真のバウンディングボックスをもとに、どの名前にどの顔が対応するかを特定します。このステップでは、年鑑のレイアウトがページごとに異なるという変動に対応する必要があります。キャプションは写真の上や下に配置されることもあり、ポートレートグリッドとグループショットが混在するページもあります。
Claude の適応思考機能により、各レイアウトタイプごとの追加プロンプトエンジニアリングなしで、こうした多様なレイアウトを柔軟に処理できます。
本ソリューションでは、Nova 2 Lite が高ボリュームな抽出作業をネイティブで 1 回の呼び出しで完結させます。一方、空間推論ステップには 1 ページあたり Claude を 1 回呼び出します。
Nova 2 Lite の画像ごとの固定料金:スケール時の予測可能なコスト
Amazon Nova 2 Lite が画像入力を課金する仕組みに関する最近の変更により、数十万ページを処理する場合でも、ページ単位の費用が予測可能になりました。
画像ごとの固定料金: Amazon Nova 2 Lite は、解像度やファイルサイズに関わらず、画像およびドキュメントのページ入力に対して「1 枚あたりの固定レート」で課金します。
この変更は、ドキュメント処理パイプラインにおいて大きな意味を持ちます。従来は画像トークンのコストが解像度によって変動するため、代表的なサンプルで概念実証を行わない限り、ページ単位の費用を正確に見積もることが困難でした。しかし、固定課金方式に移行したことで、Nova 2 Lite が処理するすべての画像は解像度のいかんに関わらず、同一の画像あたりの料金で請求されるようになりました。
プロンプトと出力を含むフルページ抽出における、ページ単位の費用内訳は以下の通りです。
| コンポーネント | トークン数/ページ | 単価 | コスト/ページ |
|---|---|---|---|
| 画像トークン(固定) | 230 | $0.30/M(入力) | $0.000069 |
| プロンプトトークン(推定) | 500 | $0.30/M(入力) | $0.000150 |
| 出力トークン(推定) | 1,000 | $2.50/M(出力) | $0.0025 |
| 合計 | 約$0.0027 |
現在発表されている Nova 2 Lite の入力トークン単価では、画像入力の費用はページあたりの総コストのごく一部に過ぎません。最新の料金は Amazon Bedrock の価格設定ページ をご確認ください。
年間数十万ページの処理規模(年次誌などの大規模ワークロード)において、この固定課金方式により費用予測が格段に容易になります。画像入力コストはページ数に対して線形に増減するため、解像度に依存しないからです。解像度の正規化処理も不要となります。
空間推論のための適応的思考
Amazon Bedrock上のClaudeは、入力データの複雑さに基づいてモデルが内部でどの程度の推論を行うかを自動判断する「適応的思考(adaptive thinking)」機能をサポートしています。この機能は、Converse APIの思考設定でtypeを"adaptive"に指定することで有効化できます。
response = bedrock_runtime.converse(
modelId='us.anthropic.claude-sonnet-4-6',
messages=[{
'role': 'user',
'content': [
{'image': {'format': 'jpeg', 'source': {'bytes': image_bytes}}},
{'text': spatial_reasoning_prompt}
]
}],
additionalModelRequestFields={
'thinking': {
'type': 'adaptive'
}
}
)適応的思考を有効にすると、Claudeは入力内容に応じて推論の深さを自動調整します。例えば、8人の名前が8枚の顔写真の上に整然と配置されたシンプルなポートレートグリッドであれば、最小限の推論で即座に回答を返します。一方、3枚のグループ写真が共通のキャプションブロックを共有し、名前がサイドバーに表示されているような複雑なレイアウトでは、段階的な空間分析が行われます。
今回の336ページにわたる処理において、Claudeはすべてのページで拡張された推論を実施しました。その推論プロセス(思考の痕跡)は544文字から1,658文字の範囲に及びました。比較的シンプルなページであっても、年鑑のレイアウトが完全に均一であることは稀なため、何らかの空間分析の恩恵を受けています。推論の詳細を見ると、Claudeは名前の位置と顔写真の位置との間の列アライメントや垂直方向のオフセットを計算し、グループ写真が表示される際にはキャプションとの近接関係も確認していました。
このように構造化された空間タスクでは、適応的思考(adaptive thinking)により、ページごとに適切な推論量を提供できます。手動でのチューニングや、固定のトークン予算の設定、レイアウト固有のプロンプト記述は不要です。モデルが入力を読み込み、自動的に判断します。
コストに関する注意:適応的思考について
適応的思考を有効にする際は、以下の 3 つのコスト要因に留意してください。
- 推論トークンは、出力トークンとして標準の出力レート(Claude Sonnet 4.6 のクロスリージョン推論では $15.00/M トークン)で課金されます。
- 推論トレースは API レスポンス内の別々の思考コンテンツブロックに返されますが、エンドユーザーには表示されません。
- 複雑なページでは推論により出力トークン数が大幅に増加する可能性があるため、レスポンスメタデータの入力トーク数と出力トーク数を監視し、ページあたりの実際のコストを追跡してください。
実装のウォークスルー
完全なソースコード、サンプル画像、Jupyter ノートブックは、GitHub の AWS Samples リポジトリ で利用可能です。
事前準備
パイプラインを実行する前に、以下の環境が整っていることを確認してください。
このチュートリアルを実行するには、Amazon Nova 2 Lite と Claude Sonnet 4.6 が利用可能な AWS リージョンで、Amazon Bedrock にアクセスできる AWS アカウントが必要です。
また、Amazon Bedrock コンソールで us.amazon.nova-2-lite-v1:0 と us.anthropic.claude-sonnet-4-6 の両モデルへのアクセス権限を有効化しておく必要があります。さらに、これらの 2 つのモデルに対して bedrock:InvokeModel および bedrock:Converse を呼び出せる IAM プリンシパルも用意してください。
開発環境には Python 3.10 以降と boto3 SDK のインストールが必要です。サンプルノートブックでは、名前の類似度マッチングに rapidfuzz を、視覚的なオーバーレイ表示に Pillow を使用しています。
入力データとしてスキャンしたページ画像(JPEG または PNG)を用意します。Converse API を通じて画像を入力する場合は、リクエスト内で画像のバイトデータを直接渡す形式となります。
ステップ 1: Amazon Nova 2 Lite で写真の検出と名前抽出
スキャンしたページを Amazon Nova 2 Lite に送信し、検出された写真(バウンディングボックスと分類情報を含む)と表示されている名前(ページ上の概略位置を含む)の両方を取得するプロンプトを送ります。Nova のネイティブなマルチモーダル理解機能により、これら 2 つの情報は 1 つの Converse コールで同時に返されます。
Nova は写真と名前の両方に対して、0 から 1000 の座標スケールでバウンディングボックスを返します。この情報をそのままステップ 2 に引き渡してください。Claude もプロンプト内で同じ座標空間を受け取るため、変換処理は不要です。
def extract_photos_and_names(image_bytes):
"""Amazon Nova 2 Lite を使用して写真の検出と表示名名の抽出を行う。"""
# Bedrock のすべての呼び出しに Converse API を一貫して使用する
このコードは、Amazon Bedrock の converse API を使用して、画像とテキストの両方を含むプロンプトを Nova モデルに送信する処理を示しています。具体的には、"us.amazon.nova-2-lite-v1:0" というモデル ID を指定し、画像データ(image_bytes)を JPEG 形式で渡すとともに、名前や写真の抽出を指示するプロンプト文を併せて送ります。
推論設定では、最大トークン数を 8000 に制限し、温度パラメータを 0 に固定して出力の安定性を確保しています。さらに、"reasoning_config" を "LOW" レベルで有効化することで、モデルに思考プロセスを促しつつコストを抑える最適化が施されています。
このプロンプトにより、Nova モデルはページ上の写真とその位置情報、そして名前を抽出した JSON オブジェクトを返すよう指示されます。以下はその出力例です。
{
"page_title": "Junior Class Officers",
"photos": [
{
"bbox": [245, 180, 410, 520],
"type": "portrait",
"category": "class_officers",
"summary": "Individual portrait photo"
}
],
"names": [
{
"text": "Cecilia Phillips",
"bbox": [260, 540, 395, 570]
},
{
"text": "John Kolander",
"bbox": [420, 540, 555, 570]
}
]
}
この例では、"Junior Class Officers" というタイトルに加え、クラス役員の写真と、それぞれの名前が正確に抽出されています。各項目にはバウンディングボックス(bbox)情報が付与されており、写真の位置やテキストの座標を特定可能です。
各写真には境界ボックス、タイプ(ポートレート、グループ、またはスナップ)、カテゴリタグ、短い説明が付与されます。各名前には表示されるテキストとページ上の境界ボックスが対応します。page_title と category フィールドは、メタデータ抽出という第二のユースケースにも活用できます。API 呼び出しを一度行うだけで、Nova 2 Lite は写真検出、マッチングパイプライン用の位置情報付き名前の取得、構造化されたメタデータの提供を一括で実現します。このメタデータは、検索インデックスの構築やイベントタイプによるフィルタリング、あるいは数百ページにわたる目次作成などに利用できます。
ステップ 2:Claude を用いて名前と顔をマッチングさせる
次に、Nova で取得した位置情報付きの名前と写真の境界ボックスを Claude に渡して空間推論を行います。両者とも同じ 0–1000 の座標系を使用するため、正規化は不要です。
spatial_prompt = f"""Given these names with page coordinates:
{json.dumps(ocr_tokens)}
And these detected photos with bounding boxes:
{json.dumps(photo_detections)}
Match each person's name to their photo based on spatial position.
Return JSON: {{"associations": [{{"name": str, "face_idx": int,
"confidence": float, "reasoning": str}}]}}"""
response = bedrock_runtime.converse(
modelId='us.anthropic.claude-sonnet-4-6',
messages=[{
'role': 'user',
'content': [
{'image': {'format': 'jpeg', 'source': {'bytes': image_bytes}}},
{'text': spatial_prompt}
]
}],
additionalModelRequestFields={
'thinking': {'type': 'adaptive'}
}
)テストセットの 50 ページ目では、Nova が 176 の名前エントリと 4 つの写真のバウンディングボックスを返しました。これらの名前のほとんどは、ページ内の他の箇所に記載された名簿や本文の一部です。写真に隣接する名前のみが一致可能であるため、Claude は 5 つの関連付けを生成しました。
{
"associations": [
{"name": "Cecilia Phillips", "face_idx": 0, "confidence": 0.95,
"reasoning": "Row 0, position 1 of 3 - matches caption above photo"},
{"name": "John Kolander", "face_idx": 1, "confidence": 0.95,
"reasoning": "Row 0, position 2 of 3 - matches caption above photo"},
{"name": "Julie Ostrander", "face_idx": 2, "confidence": 0.95,
"reasoning": "Row 0, position 3 of 3 - matches caption above photo"}
]
}
各関連付けには、空間的なロジックを説明する理由(reasoning)の文字列が含まれています。これは、関連付けに失敗したページのデバッグ時に役立ちます。
ステップ 3: 結果の検証と統合
最終ステップでは、信頼度閾値の適用と、rapidfuzz を使用したファジー名一致処理を行い、低品質な関連付けをフィルタリングします。このパイプラインはページごとに 2 つの出力を生成します。1 つ目は関連付けデータを含む JSON ファイル、もう 1 つ目は一致した名前と顔を結ぶ線を描画した可視化画像です。
結果
このパイプラインで 336 ページのスキャンされた学年誌を処理しました。その結果、名前から顔への関連付けが合計 3,122 件生成され、そのうち 93.3% が信頼度 0.95 以上を獲得しました。信頼度閾値 0.90 を下回ったのはわずか 0.3% です。

図 2. 336 ページの卒業アルバムをスキャンして得られた 3,122 の「名前と顔の対応付け」における信頼スコアの分布。この分布は高いスコアに大きく偏っており、2,912 の対応付け(93.3%)が 0.95 以上、202 の対応付け(6.5%)が 0.90〜0.94 の間にあり、0.90 を下回るのはわずか 8 つ(0.3%)のみでした。これらの信頼スコアは Claude Sonnet 4.6 が空間推論ステップで生成したもので、特定のトークン化された名前が特定の顔のバウンディングボックスに正しく対応しているというモデルの確信度を反映しています。**
image
ポートレートグリッドページ(全 336 ページ中 282 ページ)では、1 ページあたり平均 10.9 の関連付けが実現されました。これらのページは名写真が対応する人物の名前の上下に配置される規則的なレイアウトを採用しており、パイプラインはこれを確実に処理できました。
テキストのみのページ(クラスリスト、イベント説明、索引ページなど)には検出対象の写真が含まれておらず、正しくスキップされました。
ポートレートとグループショットが混在するページでは、部分的な関連付けにとどまりました。キャプションに曖昧さがある場合、パイプラインは名前の写真とのマッチングは成功しましたが、グループショットのマッチングは見送られました。
各ページごとに出力される JSON レポートと可視化結果により、エラーを容易に特定できます。可視化では、名前トークンから対応する顔へ色付きの線で結ぶことで、手動レビュー時の誤り発見が容易になります。
コストに関する考慮事項
2 つのモデルを分割して使用する構成により、写真・位置情報付きの名前抽出・メタデータの統合呼び出しには Nova 2 Lite の料率が適用され、1 ページあたりの推論呼び出しには Claude の料率が適用されます。Nova 2 Lite は画像ごとの固定料金体系を採用しているため、第 1 ステージのコストは予測可能で、入力解像度に依存しません。一方、1 ページあたりのコストを支配するのは Claude による推論ステップです。
ページ別コスト内訳**
| ステージ | サービス | コスト要因 | 1 ページあたり概算コスト |
|---|---|---|---|
| 写真と名前の抽出 | Amazon Nova 2 Lite | 固定の画像トークン数 230 + プロンプト約 500 + 出力約 1,000 | 約$0.0027 |
空間推論
Claude Sonnet 4.6
画像 + Nova JSON + 適応型推論トークン
約 0.030 ドル
パイプライン全体
約 0.033 ドル
以下の表は、このパイプラインと、各ページを Claude に送信して OCR、写真検出、空間マッチングの 3 つのタスクをすべて 1 回の呼び出しで処理する単一モデル方式を比較したものです。
| 項目 | 2 モデル構成のパイプライン | 単一モデル(Claude) |
|---|---|---|
| 入力トークン | 画像 (Nova: 固定 230) + Nova JSON → Claude | 画像 @ 約 1,500 トークン + プロンプト @ 約 1,300 = 約 2,800 トークン @ 3 ドル/1M トークン = 約 0.008 ドル |
| 出力トークン | Nova
原文を表示
A scanned yearbook page contains 176 printed names, 4 portrait photographs, and zero machine-readable structure linking them. To digitize this page, you need reliable photo detection with bounding boxes and accurate name extraction. You also need a way to determine which name belongs to which face based on page layout.
In this post, we show how pairing Amazon Nova 2 Lite with Anthropic’s Claude Sonnet 4.6 delivers an efficient solution for digitizing scanned documents at scale. We built a two-model pipeline on Amazon Bedrock for digitizing scanned yearbook pages. Amazon Nova 2 Lite handles native multimodal extraction in a single call: detecting photos, extracting visible names with coordinates, and returning page-level metadata. Claude Sonnet 4.6 then performs spatial reasoning to match names to faces based on page layout.
We ran this pipeline against 336 scanned yearbook pages and produced 3,122 name-to-face associations, with 93 percent scoring at or above 0.95 confidence. This two-model approach costs about two-thirds less per page than a single-model alternative that sends the entire task to one vision-language model. See the Cost considerations section for the detailed breakdown.
Solution overview
The pipeline has two stages. Each stage uses a different model, chosen for the specific task it performs.

Figure 1. Two-model pipeline architecture. The scanned page image flows through two sequential stages. In stage 1, Amazon Nova 2 Lite performs native multimodal extraction in a single API call. It detects and classifies photos with bounding boxes, reads visible names on the page and returns their approximate positions, and emits page-level metadata. In stage 2, Claude Sonnet 4.6 performs spatial reasoning to match names to faces using the combined Nova output.
Amazon Nova 2 Lite runs first. Because it handles interleaved text and images natively, a single Converse call returns three things:
- The detected photos with bounding boxes and classifications.
- The names visible on the page with approximate positions.
- Page-level metadata like titles and categories.
We set reasoning to LOW for this task by including a reasoning configuration in the Converse API call. See the reasoning block in the Step 1 code that follows. Testing across all 336 pages showed no meaningful accuracy difference between LOW, MEDIUM, and HIGH reasoning levels for this structured extraction, and LOW is the cheapest option. Nova exposes this setting through the reasoning_config field. Claude, in Step 2, uses a separate thinking field, so the two models control reasoning under different names.
Asking *Nova 2 Lite* only for names, not every OCR token on the page, is what keeps the first stage cheap. The downstream spatial reasoning step doesn’t need the full text of class rosters or event descriptions. It needs names that appear near photos. Constraining Nova output to names keeps the output-token cost at approximately 1,000 tokens per page instead of the approximated 4,500 tokens a full OCR pass would produce.
Claude Sonnet 4.6 enters only at stage 2 for the spatial reasoning step. Given Nova names-with-positions and photo bounding boxes, Claude determines which names correspond to which faces. This step requires handling page layout variability, because yearbook layouts vary from page to page. Captions might appear above or below photos, and some pages mix portrait grids with group shots. Claude adaptive thinking handles this variability without additional prompt engineering per layout type.
In this solution, Nova 2 Lite handles the high-volume extraction work natively, in one call. Claude is called once per page for the spatial reasoning step.
Nova 2 Lite fixed per-image pricing: Predictable cost at scale
A recent change to how Amazon Nova 2 Lite bills image inputs makes per-page cost predictable at scale, which matters when you are processing hundreds of thousands of pages.
Fixed per-image pricing: Amazon Nova 2 Lite bills image and document page inputs at *a fixed per-image rate*, regardless of resolution or file size.
This change is significant for document processing pipelines. Previously, image token costs varied based on resolution, making it difficult to project per-page costs without running a proof-of-concept on representative samples. With fixed billing, every image Nova 2 Lite processes is billed at the same per-image rate, regardless of resolution.
For a full page extraction including prompt and output, the per-page cost breaks down as follows:
| Component | Tokens/Page | Rate | Cost/Page |
|---|---|---|---|
| Image tokens (fixed) | 230 | $0.30/M input | $0.000069 |
| Prompt tokens (estimated) | 500 | $0.30/M input | $0.000150 |
| Output tokens (estimated) | 1,000 | $2.50/M output | $0.0025 |
| Total | ~$0.0027 |
At published Nova 2 Lite input-token rates, image input is a small fraction of total per-page cost. For current rates, see the Amazon Bedrock pricing page.
For yearbook-scale workloads (hundreds of thousands of pages annually), this fixed pricing makes cost forecasting straightforward because image input cost scales linearly with page count and is independent of page resolution. No resolution normalization is required.
Adaptive thinking for spatial reasoning
Claude on Amazon Bedrock supports adaptive thinking, a feature where the model decides how much internal reasoning to apply based on the input complexity. You enable it by setting type to adaptive in the thinking configuration of the Converse API:
response = bedrock_runtime.converse(
modelId='us.anthropic.claude-sonnet-4-6',
messages=[{
'role': 'user',
'content': [
{'image': {'format': 'jpeg', 'source': {'bytes': image_bytes}}},
{'text': spatial_reasoning_prompt}
]
}],
additionalModelRequestFields={
'thinking': {
'type': 'adaptive'
}
}
)With adaptive thinking enabled, Claude adjusts its reasoning depth based on what it receives. A straightforward portrait grid with eight names neatly arranged above eight faces gets a direct response with minimal reasoning. A page where three group photos share a caption block and names appear in a sidebar triggers step-by-step spatial analysis.
In our 336-page run, Claude used extended reasoning on every page, with reasoning traces ranging from 544 to 1,658 characters. Even the simpler pages benefited from some spatial analysis because yearbook layouts are rarely perfectly uniform. The reasoning traces show Claude working through column alignment and vertical offsets between name positions and face positions, and checking caption proximity when group photos appear on the page.
For this type of structured spatial task, adaptive thinking gives you the right amount of reasoning per page without manual tuning. You don’t need to set a fixed token budget or write layout-specific prompts. The model reads the inputs and decides.
Cost note on adaptive thinking: When adaptive thinking is enabled, keep three cost factors in mind.
- Reasoning tokens are billed as output tokens at the standard output rate ($15.00/M output tokens for Claude Sonnet 4.6 through cross-Region inference).
- Reasoning traces are returned in the API response under a separate thinking content block, but aren’t shown to end users.
- Monitor inputTokens and outputTokens in the response metadata to track actual cost per page, because reasoning can significantly increase output token counts on complex pages.
Implementation walkthrough
The full source code, sample images, and Jupyter notebook are available in the AWS Samples repository on GitHub.
Prerequisites
Before running the pipeline, make sure that you have the following in place:
- An AWS account with access to Amazon Bedrock in an AWS Region where Amazon Nova 2 Lite and Claude Sonnet 4.6 are available.
- Model access enabled in the Amazon Bedrock console for both us.amazon.nova-2-lite-v1:0 and us.anthropic.claude-sonnet-4-6.
- An AWS Identity and Access Management (IAM) principal with permission to call bedrock:InvokeModel and bedrock:Converse on the preceding two models.
- Python 3.10 or later with the boto3 SDK installed. The sample notebook also uses rapidfuzz for fuzzy name matching and Pillow for visualization overlays.
- Scanned page images (JPEG or PNG). For image input through the Converse API, image bytes are passed inline in the request.
Step 1: Detect photos and extract names with Amazon Nova 2 Lite
Send the scanned page to Amazon Nova 2 Lite with a prompt that requests both detected photos (with bounding boxes and classifications) and visible names (with approximate positions on the page). Nova native multimodal understanding returns both in a single Converse call.
Nova returns bounding boxes on a 0–1000 coordinate scale for both photos and names. Pass both directly into Step 2. Claude reads the same coordinate space when given in the prompt, so no conversion is needed.
def extract_photos_and_names(image_bytes):
"""Detect photos and extract visible names with Amazon Nova 2 Lite."""
# Using the Converse API consistently for all Bedrock calls
response = bedrock_runtime.converse(
modelId='us.amazon.nova-2-lite-v1:0',
# Note: cross-region inference profile (us.amazon.nova-2-lite-v1:0)
messages=[{
'role': 'user',
'content': [
{
'image': {
'format': 'jpeg',
'source': {'bytes': image_bytes}
}
},
{'text': PHOTO_AND_NAME_EXTRACTION_PROMPT}
]
}],
inferenceConfig={
'maxTokens': 8000,
'temperature': 0
},
additionalModelRequestFields={
'reasoning_config': {
'type': 'enabled',
'level': 'LOW'
}
}
)
raw = response['output']['message']['content'][0]['text']
return json.loads(raw)The prompt instructs Nova to return a JSON object with both the photos and the names visible on the page.
{
"page_title": "Junior Class Officers",
"photos": [
{
"bbox": [245, 180, 410, 520],
"type": "portrait",
"category": "class_officers",
"summary": "Individual portrait photo"
}
],
"names": [
{
"text": "Cecilia Phillips",
"bbox": [260, 540, 395, 570]
},
{
"text": "John Kolander",
"bbox": [420, 540, 555, 570]
}
]
}Each photo gets a bounding box, a type (portrait, group, or candid), a category tag, and a short description. Each name gets its visible text and its bounding box on the page. The page_title and category fields also serve a second use case: metadata extraction. With one API call, Nova 2 Lite gives you photo detection, names-with-positions for the matching pipeline, and structured metadata. You can use this metadata for search indexing, filtering by event type, or building a table of contents across hundreds of pages.
Step 2: Match names to faces with Claude
Now pass Nova names-with-positions and photo bounding boxes to Claude for spatial reasoning. Both use the same 0–1000 coordinate space, so no normalization is needed:
spatial_prompt = f"""Given these names with page coordinates:
{json.dumps(ocr_tokens)}
And these detected photos with bounding boxes:
{json.dumps(photo_detections)}
Match each person's name to their photo based on spatial position.
Return JSON: {{"associations": [{{"name": str, "face_idx": int,
"confidence": float, "reasoning": str}}]}}"""
response = bedrock_runtime.converse(
modelId='us.anthropic.claude-sonnet-4-6',
messages=[{
'role': 'user',
'content': [
{'image': {'format': 'jpeg', 'source': {'bytes': image_bytes}}},
{'text': spatial_prompt}
]
}],
additionalModelRequestFields={
'thinking': {'type': 'adaptive'}
}
)On page 50 of our test set, Nova returned 176 name entries and 4 photo bounding boxes. Most of those names are roster and body text elsewhere on the page. Only the names adjacent to the 4 photos are matchable, so Claude produced 5 associations:
{
"associations": [
{"name": "Cecilia Phillips", "face_idx": 0, "confidence": 0.95,
"reasoning": "Row 0, position 1 of 3 - matches caption above photo"},
{"name": "John Kolander", "face_idx": 1, "confidence": 0.95,
"reasoning": "Row 0, position 2 of 3 - matches caption above photo"},
{"name": "Julie Ostrander", "face_idx": 2, "confidence": 0.95,
"reasoning": "Row 0, position 3 of 3 - matches caption above photo"}
]
}Each association includes a reasoning string that explains the spatial logic. This is useful for debugging pages where associations fail.
Step 3: Validate and assemble results
The final step applies confidence thresholds and fuzzy name matching (using rapidfuzz) to filter out low-quality associations. The pipeline writes two outputs per page: a JSON file with the association data and a visualization image showing lines drawn between matched names and faces.
結果
We processed 336 scanned yearbook pages through this pipeline. The pipeline produced 3,122 name-to-face associations total, with 93.3 percent of those associations scoring confidence at or above 0.95. Only 0.3 percent fell below the 0.90 confidence threshold.

Figure 2. Confidence score distribution across the 3,122 name-to-face associations produced from 336 scanned yearbook pages. The distribution is heavily skewed toward high confidence: 2,912 associations (93.3 percent) scored at or above 0.95, 202 (6.5 percent) scored between 0.90 and 0.94, and only 8 (0.3 percent) fell below 0.90. Claude Sonnet 4.6 produced confidence scores during the spatial reasoning step. They reflect the model’s certainty that a given name token maps to a specific face bounding box.**

- Portrait grid pages (282 of 336 pages) averaged 10.9 associations per page. These pages have a regular layout where names appear directly above or below corresponding photos, and the pipeline handled them reliably.
- Text-only pages (class rosters, event descriptions, index pages) had no photos to detect and were correctly skipped.
- Mixed-layout pages with portraits and group shots on the same page produced partial associations. The pipeline matched names to portrait photos but left group shots unmatched when captions were ambiguous.
The pipeline outputs a JSON report and a visualization for each page. The visualization draws colored lines from each name token to its matched face, which makes it easy to spot errors during manual review.
Cost considerations
The two-model split means that you pay Nova 2 Lite rates for the combined extraction call (photos, names-with-positions, metadata) and Claude rates for one reasoning call per page. Under Nova 2 Lite’s fixed per-image pricing, the first stage cost is predictable and independent of input resolution. Claude reasoning step dominates per-page cost.
Per-page cost breakdown**
| Stage | Service | Cost Driver | Approximate Cost/Page |
|---|---|---|---|
| Photo + name extraction | Amazon Nova 2 Lite | Fixed 230 image tokens + ~500 prompt + ~1,000 output | ~$0.0027 |
| Spatial reasoning | Claude Sonnet 4.6 | Image + Nova JSON + adaptive reasoning tokens | ~$0.030 |
| Pipeline total | ~$0.033 |
The following table compares the pipeline against a single-model approach where each page is sent to Claude to do all three tasks (OCR, photo detection, and spatial matching) in one call.
Dimension
Two-model pipeline
Single-model Claude
Input tokens
Image (Nova: 230 fixed) + Nova JSON → Claude
Image @ ~1,500 tokens + prompt @ ~1,300 = ~2,800 tokens @ $3/M = ~$0.008
Output tokens
Nova
関連記事
News to Guide
ニュースの次に確認する
発表内容を、現在の料金や仕様と照らし合わせられる関連ガイドです。
今日のまとめ
AIデイリーブリーフで今日の重要ニュースをまとめ読み