銀行材料スキャン文書の世帯別分割(一括材料→世帯別Word)
トリガー条件
- 顧客(法律事務所/銀行/回収機関)から一括材料の圧縮ファイル(RAR/ZIP暗号化)または巨大docx(61MB以上、スキャン画像のみ)が届いた
- 「IDカードと口座開設申込書を抽出し、それぞれ別のWordファイルにまとめてほしい」という依頼
- 「1世帯のWord = その顧客のID表+対応する裏+対応する銀行申請書類、1枚も漏らさない」という要件
- ユーザーが「最初から最後まで確認してほしい」と強調——この種のタスクは品質要求が高く、認識ミス=顧客の損失になる
ユーザー鉄則(2026-08-19 ユーザー)
- 各世帯のWordには必ず:ID表+対応裏(国章面)+対応申込書類(申請書)を1枚も漏れなく含める
- ファイル名を明確に:
氏名-身分証+口座開設申込書.docx - 要確認:認識できなかった/マッチしなかったものは「要確認」フォルダに隔離し、正常結果に混入させない
- ユーザーは統計を要求:認識開始から分割完了までの所要時間、呼び出し回数、トークン、費用——顧客が価格設定の根拠として再利用できるように
完全なワークフロー(5ステップ)
Step1 展開
# 暗号化RARは7zを使用(本機 C:\Program Files\7-Zip\7z.exe)
"C:/Program Files/7-Zip/7z.exe" x -p"パスワード" input.rar -y
# 顧客からパスワードを聞くこと;RAR5形式も7zで解凍可能
- よくある形態:RAR解凍後は1つの巨大docx(例:「画像資料2.docx」61MB)、中に文字はなく、画像のみ
Step2 docxから画像抽出
import zipfile
with zipfile.ZipFile('画像資料2.docx') as z:
media = [f for f in z.namelist() if f.startswith('word/media/') and f.endswith('.png')]
for f in media: z.extract(f, out_dir)
- docxは本質的にzipで、画像は word/media/ 下にあり、命名は image1.png〜imageN.png
- 画像番号 = 元のスキャン順序、後の世帯割り当てで使用
Step3 視覚認識による分類(⭐核心:モデル選定)
重要なIDカード認識にGLM-4V-Flashは絶対に使わない!(本セッションで実測された幻覚:18枚中11枚のID裏面を「表面」で捏造し、氏名まで捏造)
豆包 Seed 2.0 Pro(doubao-seed-2-0-pro-260215、VLM、高精度)を使用:
payload = {
"model": "doubao-seed-2-0-pro-260215",
"messages": [{"role": "user", "content": [
{"type": "text", "text": "これは銀行顧客資料のスキャン画像です。カテゴリを判別し、キー情報を抽出してください:\nカテゴリは次のうちの1つ:身分証明書表面、身分証明書裏面、口座開設申込書、クレジットカード申込書、その他の資料\n表面→氏名+身分証番号を抽出;裏面→発行機関を抽出;申込書→申込者氏名を抽出\n出力形式:カテゴリ:XXX\n氏名:XXX(ない場合は「なし」)\n身分証番号:XXX\n発行機関:XXX"},
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{b64}"}}
]}],
"max_tokens": 200
}
# base_url: https://ark.cn-beijing.volces.com/api/v3/chat/completions
# KEY: .env の ARK_API_KEY
- 各画像間は1秒待機(レート制限対策)、15枚ごとに進捗をjson保存(レジューム対応)、リトライ3回(429/タイムアウト時は5-8秒待機)
- 136枚で約35~40分(17秒/枚)——バックグラウンド実行+notify_on_complete
Step4 世帯別グループ化(表面で世帯確定→裏面マッチング→申込書マッチング)
- 表面氏名で世帯確定:各「身分証明書表面」から氏名を抽出→世帯を作成(各世帯に front/back/apps の3つのリスト)
- 裏面マッチング(発行機関の地域 ↔ 表面の身分証番号上位6桁の地域コード):
- 地域コード→公安局名のマッピングテーブルを管理(450122=武鳴、452128=武鳴、450126=賓陽…広西がメイン、顧客が広西の銀行の場合)
- マッチ成功→世帯に所属;市レベルの発行機関(南寧市公安局/柳州市公安局)は一意にマッチできない→豆包でペア比較(一度に表面+裏面の2枚を送信し「同一人物か」を質問)または要確認へ
- 申込書マッチング(氏名):直接マッチング+拼音ファジーマッチング(pypinyin):
lazy_pinyin(name)の最初の2文字が同音ならマッチ(黄祉玲→黄令、唐咸梅→唐鳳梅、姚賢明→姚先明)- 手書きの申込書氏名認識は誤差が大きいため、ファジーマッチングが救いの鍵
- ⚠️ 「元の順序が隣接している」だけで表裏をマッチさせない——複数人が混在すると、他人の裏面を誤って世帯に含める(本セッションの教訓:順序マッチングで44枚→実際は34枚)
Step5 世帯別Word生成(python-docx)
from docx import Document
from docx.shared import Cm
doc = Document()
# タイトル(中央太字):{氏名} - 銀行資料
# 【身分証表面】→ 画像幅8cm、1枚ずつ add_picture + 空行
# 【身分証裏面】→ 同上
# 【銀行申請資料】→ 画像幅12cm
doc.save(f"{out_dir}/{氏名}-身分証+口座開設申込書.docx")
- ファイル名:
{氏名}-身分証+口座開設申込書.docx - マッチしなかった裏面/申込書 →
要確認/サブディレクトリにコピー
コスト統計(ユーザー要求、納品時に提示)
# APIレスポンスの usage フィールドから累積:prompt_tokens/completion_tokens
# 推定:高解像度スキャン1枚あたり約2000トークン入力、200トークン出力
# 豆包Seed 2.0 Pro ビジョン:入力約0.008元/千トークン → 136枚全量で約2〜5元
# 所要時間:認識開始からWord完成まで
納品時にユーザーに提示する統計表:呼び出し回数、入力/出力トークン、推定費用、総所要時間(本セッション:136枚で約180回呼び出し、45万トークン、3〜5元、認識35分+グループ化数分)
重要な落とし穴
- GLM-4V-Flashの幻覚(本セッションで最も痛い教訓):認識できないと「捏造」する——裏面を表面として捏造し、氏名も捏造。重要な認識には必ず豆包を使用
- docx画像抽出:zipfileで直接 word/media/ を読むこと。python-docxのinline_shapesは使わない(大ファイルでは遅く不完全)
- PIL画像拡張:RGBAモードの場合は事前に convert('RGB') しないと Contrast/Sharpness/autocontrast が使えない。90°回転したIDは h>w*1.5 の場合、±90°の2バージョンを生成してそれぞれ認識
- 地域コードマッピングテーブル:広西がメインの場合、手動で県→公安局のマッピングを管理(4501=南寧、4502=柳州…)。顧客が他省の場合は身分証番号上位6桁から行政区画を検索
- 豆包が遅い:17秒/枚。バッチ処理は必ずバックグラウンド実行+レジューム機能、フロントで待たない
- 「見えにくい」画像:先にPIL拡張して再認識、それでもダメなら要確認フォルダへ
関連スキル
- ビジョンモデルマトリクス/費用規律: model-cost-discipline(ユーザー所有、参考のみ)
- ローカルOCR: deepseek-ocr(Ollama)はページ全体のテキストOCRに適しており、ID分類には不向き
作者について
九品錦锂e | 踏んだ落とし穴を「すぐに使える」スキルにパッケージ化し、教科書は書きません。
このスキルは私自身が使っているバージョンで、中の落とし穴はすべて実際に経験したものです。使用中に詰まった場合、高度な使い方を知りたい場合、または別のシナリオをスキル化してほしい場合、直接私の微信に連絡してください。追加時に「SkillHub」とメモを入れてください。優先的に通過します:

QRコードをスキャンして作者の微信を追加 ・ 「SkillHub」とメモすると優先通過