この記事のゴール
Llama 4 はネイティブマルチモーダル——テキストと画像を後付けではなく最初から同じモデルで扱います(early fusion)。これが効くのは、**「画像を見て、構造化データを返す」**タスクです。帳票・レシート・名刺・図面・スクリーンショット・本人確認書類……現場には“紙とスクショ”が溢れています。
本稿は、その画像理解をデモではなく本番——推測させない・型で縛る・誤れない値を守る・PIIを漏らさない——に仕上げます。
信頼性の開示:「生成に数値を推測させず、誤れない値はマスタ照合に分業させる」という設計は、私が音声接客の事例で型番・サイズの誤答を構造的に潰したときの中核思想です。本稿の画像抽出も同じ規律——LLMは読み取りの言葉、真実は検証——で組みます。
どんな場面で効くか
| 入力画像 | 抽出したい構造 | 価値 |
|---|---|---|
| 請求書・領収書 | 取引先・金額・日付・明細 | 経理の手入力ゼロ化 |
| 名刺 | 氏名・会社・役職・連絡先 | CRM 自動登録 |
| 図面・仕様書 | 型番・寸法・材質 | 見積もり・発注の前処理 |
| スクリーンショット | エラー文・UI状態 | サポート/QAの自動分類 |
| 本人確認書類 | 氏名・生年月日・番号 | KYC(※PII保護が前提) |
共通するのは「非構造な画像 → 後段システムが使える構造化データ」。ここを LLM のマルチモーダルで埋めると、人手の転記が消えます。
投入する:Bedrock Converse の画像入力
Bedrock の Converse API は、メッセージに画像ブロックを混ぜられます。形式は format(png / jpeg / gif / webp)+ source.bytes。AWS SDK が base64 化を肩代わりするので、生バイトを渡すだけです。
# llama_vision.py — 画像+指示を Llama 4 に渡し、テキストで理解させる
import boto3
from botocore.config import Config
_bedrock = boto3.client(
"bedrock-runtime", region_name="us-east-1",
config=Config(retries={"max_attempts": 4, "mode": "adaptive"}, read_timeout=60),
)
MODEL_ID = "us.meta.llama4-maverick-17b-instruct-v1:0" # 画像理解は上位のMaverickが堅い
def read_image(path: str) -> dict:
with open(path, "rb") as f:
data = f.read() # SDKがbase64を処理するので生バイトでよい
ext = path.rsplit(".", 1)[-1].lower()
fmt = "jpeg" if ext == "jpg" else ext # jpg→jpeg に正規化
return {"image": {"format": fmt, "source": {"bytes": data}}}
def describe(image_path: str, instruction: str) -> str:
resp = _bedrock.converse(
modelId=MODEL_ID,
messages=[{"role": "user", "content": [read_image(image_path), {"text": instruction}]}],
inferenceConfig={"maxTokens": 1024, "temperature": 0.0}, # 抽出は温度0で揺らさない
)
return resp["output"]["message"]["content"][0]["text"]
📌 制約(公式):1メッセージあたり画像は最大20枚、各画像は3.75MB・8000px 以下。多ページ帳票はページ単位に分割して投入します。温度は抽出では
0.0が基本——創造性は不要、毎回同じに読むことが品質です。
型で縛る:画像から構造化データへ(推測させない)
画像理解の出力も信頼境界の外側です。自由文ではなくスキーマ準拠のJSONを要求し、Zodで境界検証して初めて後段に流します。Vercel AI SDK なら画像パートと generateObject を組み合わせられます。
// lib/extract-receipt.ts — レシート画像 → 型安全な構造化データ
import { bedrock } from "@ai-sdk/amazon-bedrock";
import { generateObject } from "ai";
import { z } from "zod";
const Receipt = z.object({
merchant: z.string().min(1),
total: z.number().nonnegative(),
currency: z.enum(["JPY", "USD", "EUR"]),
purchasedAt: z.string().date(), // YYYY-MM-DD
items: z.array(z.object({ name: z.string(), price: z.number() })).max(100),
confidence: z.number().min(0).max(1), // モデルに自己申告させる読み取り確度
});
export async function extractReceipt(image: Uint8Array) {
const { object, usage } = await generateObject({
model: bedrock("us.meta.llama4-maverick-17b-instruct-v1:0"),
schema: Receipt,
messages: [{
role: "user",
content: [
{ type: "image", image },
{ type: "text", text: "レシート画像から構造化データのみ抽出。読み取れない値は推測せず、confidenceを下げる。" },
],
}],
});
// object は Receipt 準拠が型レベルで保証された安全な値。usage は画像トークン課金の可観測性。
return { receipt: object, usage };
}
何を返そうと Receipt を通った値しか後段に流れない——これで「崩れたJSON」「想定外フィールド」を構造的に排除できます。
誤れない値を守る:信頼度ゲートと分業
ここが本番の肝です。金額・型番・本人情報のような“誤ると事故”の値を、モデルの一発出力で確定させてはいけません。音声接客で「数字はLLMでなくマスタ照合」と分業したのと同じ規律を、画像抽出にも敷きます。
// 抽出結果を“信頼度”と“検証可能性”で振り分ける(自動確定はしない)
type Routed =
| { status: "auto"; receipt: Receipt } // 高確度かつ検算一致 → 自動採用
| { status: "review"; receipt: Receipt }; // 低確度 or 検算不一致 → 人手レビュー
function route(receipt: Receipt): Routed {
const sumOfItems = receipt.items.reduce((a, b) => a + b.price, 0);
const arithmeticOk = Math.abs(sumOfItems - receipt.total) < 1; // 明細合計と総額の検算
const confident = receipt.confidence >= 0.9;
return confident && arithmeticOk ? { status: "auto", receipt } : { status: "review", receipt };
}
ポイントは検算(明細合計=総額)という“モデルに依存しない真実”で裏取りしていること。LLM は読み取りの労を担い、正しさはコードが保証します。これにより、人手レビューを「全件」から「怪しい一部だけ」に絞れ、品質とコストを両立できます。
落とし穴と対策
- 幻覚フィールド:読めない欄を“それっぽく”埋める。→ プロンプトで「推測禁止・不明はnull/低confidence」を明示し、
temperature=0。スキーマでnullableを許容して“空”を表現可能にする。 - 低解像度・傾き・影:読み取り精度が落ちる。→ 前処理(リサイズ・回転補正・コントラスト)を1段挟む。8000px 上限・3.75MB 制約にも前処理で寄せる。
- 多ページ:1リクエストに詰めすぎる。→ ページ分割し、ページごとに抽出して統合。
- 画像トークン課金:画像は入力トークンを多く消費する。→ 解像度を必要十分に落とす、難しい画像だけ上位モデルに回す(コスト設計)。
- 評価不在:見た目で判断。→ 正解付き評価セットでフィールド一致率(精度/再現率)を測り、回帰を検出してから出す。
セキュリティ:画像は PII の塊
帳票・名刺・本人確認書類は個人情報そのものです。設計に保護を織り込みます。
- ログにバイト列・抽出本文を残さない:可観測性はメタデータ(モデル・トークン数・confidence・処理時間)だけで足ります。
- 最小権限:画像ストレージ(S3等)は最小権限・暗号化・短命URL。処理後は保持ポリシーに従い削除。
- マスキング:番号類は後段で必要最小限に。表示UIでは伏字(アクセシブルに——読み上げで全桁を露出しない)。
- 入力検証:ファイル形式・サイズ・枚数を境界で検証してから投入(型安全の規律)。
抽出した構造化データは、最終的に人が使う画面へ流れます。伏字・ラベル・エラー表現をアクセシブルに設計してこそ、抽出パイプラインは“プロダクト”になります。
よくある質問(FAQ)
Q. OCR専用サービスと何が違う? A. 従来OCRは「文字を読む」まで。Llama 4 は「読んで、意味を理解し、構造化して返す」まで一気通貫。レイアウトが多様な帳票や、文脈依存の項目抽出に強い。一方で誤れない値は必ず検算/マスタ照合で裏取りする設計は OCR と同じく必須です。
Q. どのモデルを使うべき? A. 画像理解は Maverick が堅い。大量・簡単なものは Scout でコストを抑え、難しい画像だけ上位へ回すルーティングが費用対効果の最適点です。
Q. 日本語の帳票も読める? A. 読めます。ただし手書き・低解像度・特殊フォントは精度が落ちるので、前処理と信頼度ゲート、人手レビュー経路を必ず用意してください。
Q. 何枚まで一度に渡せる? A. 公式制約で1メッセージ最大20枚・各3.75MB/8000px。多ページや高解像度はページ分割・リサイズで寄せます。
Q. セルフホストでも画像理解できる? A. できます。vLLM で Scout/Maverick をサーブすれば、OpenAI互換の画像入力で同様に扱えます。データを外に出せない KYC 等はこちら。
まとめ
Llama 4 のマルチモーダルは、「紙とスクショを、後段が使えるデータに変える」実務の道具です。鍵は派手な使い方ではなく、規律にあります。
- Converse の画像ブロックで投入(format+bytes、温度0)。
- Zodで境界検証し、崩れた出力を構造的に排除する。
- 誤れない値は検算/マスタ照合で裏取りし、自動確定しない。
- PII保護(ログ非出力・最小権限・マスキング)を織り込む。
- 評価セットで精度を測り、回帰を見てから出す。
帳票・本人確認・図面などの画像理解を、検算・人手レビュー・PII保護・コスト設計まで含めて本番に載せたいなら、実績をご覧のうえご相談ください。一人 × 生成AIで、速く・安く・安全に。
出典・公式リソース
- The Llama 4 herd(Meta AI) — ネイティブマルチモーダル
- Bedrock Converse API(画像入力) — 画像ブロックの形式・制約
- boto3 converse リファレンス
- Vercel AI SDK —
generateObjectと画像パート
※ モデル・制約・料金は更新されます。実装前に一次情報を確認し、正解付き評価で精度を検証してください。