帳票の OCR 後処理パイプライン(CLI)
このシステムは何をするか
書類を読み取った結果から必要な項目を取り出して形を整え、そのまま使える項目と、人が確認すべき項目とを理由つきで選り分ける処理です。
この作品は OCR を実行していない。入力は合成 OCR レスポンスであり、実装しているのは読み取り後(post-OCR)の項目取り出し・正規化・確認要否の判定である。読み取り精度の数値は持っていない。
想定業務課題
- 読み取った値のうち、どれをそのまま使ってよく、どれを人が確認すべきかが分からない。
- 確信度をページ平均で持つと、はっきり読めた印字と滲んだ手書きが同じ扱いになる。
使う人と、いまのやり方
使うのは、届いた帳票を業務システムへ入力する事務担当と、内容を確認する現場の責任者です。読み取りの仕組みを調整する人はいません。いまは紙や PDF を見ながら手で入力し、判読できない欄は都度現場へ問い合わせています。
満たすべきこと
機能
- 帳票の 12 項目を取り出し、日付・区分・チェック欄を決まった形に整える(読み取り後の項目抽出/post-OCR field extraction)
- 項目ごとの「読み取り自信度」を出す(Confidence scoring)
- 確認が必要な項目だけを、理由つきで振り分ける(Review Gate)
制約
- 読めない値を勝手に補正・補完しない
- 外部サービスへ送らない・追加インストールを要求しない・同じ入力なら毎回同じ出力になる
- エラーに書類の中身・ファイル名・接続情報を載せない
作ったもの
なぜこの設計にしたか
自信度をページ全体ではなく、項目ごとに出す(Confidence scoring(block 単位))。
見本の平均は 0.86 ですが、手書きの所見は 0.49 です。
確信度をブロック単位で採点し、読めなかった項目は自信度をゼロにする(欠損項目の confidence = 0)。
却下した案 — 却下したのはページ平均で判定する案です。平均に埋もれると人に回すべき項目が拾われません。
読めない値を直さず、そのまま人に回す。
あり得ない日付や、判定できないチェック欄が入力に現れる。
補正せず null を返す。チェック欄は有・無・判定できず の 3 状態にする(tri-state checkbox)。取り出す範囲も次の項目名で打ち切る(キーワードアンカー)。
却下した案 — 却下したのは、あり得ない日付を近い日付へ補正し、チェック欄の判定できない状態を「なし」に寄せる案です。補正すると誰も間違いに気づけません。
代償 — 補正しない方針は review_required の件数を増やす方向に働きます。
振り分けまでを実装範囲とし、確定画面は作らない(Review Gate)。
確定画面まで作ると、運用に乗っていると誤読されます。
判定を返すところまでを実装範囲とし、読み取りサービスも差し替え口だけ用意する(provider 抽象化)。
却下した案 — 却下したのは確定画面まで作る案です。
代償 — 差し替えた実例はありません。
見どころ
12 項目のうち 10 項目はそのまま使え、2 項目だけが確認に回ります。
回るのは手書きの所見(0.49)と点検者の区分(0.56)で、なぜ回るのかも一緒に出ます。その間は確定操作を許可しません(confirm allowed = false)。
この画面で確認できること
- 項目ごとに確信度が出て、LOW の 2 項目だけが人に戻る
- 同じ入力なら毎回同じ出力になる(固定クロック / golden ファイル)
Evidence の対象外
- OCR の精度の証拠ではない。入力は合成 OCR レスポンス 1 種類のみ
- レビュー画面の証拠ではない。判定を返すところまでしか実装していない
この画像の出所と、拡大
- 種別
- Terminal output(node src/index.js --scenario success)
- 出所
- assets/document-field-extraction/publish/01-cli-demo.png
- 掲載サイズ
- 1531×1260
- 倍率
- 等倍 1.000
- SHA256
- 1f1abc17…
読めない入力では、合図と決まった文だけを返します。
書類の中身も応答の本文も出しません。
どの欄がどの項目になるかを対応表で確認できます。
左の帳票は表示用の見本で、処理はこれを読み取っていません。
実装範囲
個人開発です。項目の取り出し・正規化・自信度・振り分け・形式検証・合成データの生成・テストまでを 1 人で実装しました。読み取りサービス本体は含めておらず、入力は合成された読み取り結果です。
品質の担保方法
- 何を確認しているか — 項目を取り出す範囲の打ち切り、チェック欄の 3 状態、あり得ない日付の拒否、欠損の自信度ゼロ、振り分けの 4 状態と理由、出力形式の検証、エラーの形、外部通信が発生しないこと。
- 出力が変わっていないことを毎回照合します(Golden file /回帰テスト)。時計を固定しているため出力は毎回同じです。見本の帳票と正解データも同じ定義から作られます(合成データの単一仕様生成)。すべて架空のデータです。
- 出力の形式は毎回確認します(JSON Schema /スキーマ検証)。依存を持たない部分実装で、未対応のルールは失敗させます。
- 自動の動作チェック(node:test)は追加インストールなしで再実行できます。157 passed / 40 suites(2026-08-15 に npm test)。
安全性とデータの扱い
運用と納品物
| 区分 | 内容 |
|---|---|
| 渡すもの | src/ 一式(JavaScript 12 ファイル)、出力の形式定義 schema/equipment-inspection-output.schema.json、合成データ fixtures/ 3 点、tests/、scripts/、docs/architecture.md |
| 依頼者側で行うこと | Node 20 以降を用意する(package.json の engines.node = >=20)。インストールするものは無い(dependencies / devDependencies の宣言そのものが無い) |
| 別の帳票へ広げるとき | src/field-definitions.js と JSON Schema の 2 ファイルを編集する(docs/architecture.md「Extending it」) |
| 読み取りサービスを実物に替えるとき | annotate() を持つオブジェクトを 1 つ書く。差し替えた実例は無い |
| 確認担当者が使う画面・運用体制 | 未定義(振り分けまでが実装範囲) |
できること・含めていないこと
| Implemented | Not Included | Why |
|---|---|---|
| 読み取り後(post-OCR)の項目抽出・正規化・確信度・振り分け | OCR エンジンの実行 | このデモの対象外。入力は合成 OCR レスポンス。読み取り精度の数値は持っていない |
| 人が確認すべき項目の判定と理由の出力 | レビュー画面(人が確定する UI) | 実装範囲は振り分けまで。UI を作ると「運用に乗っている」と誤読される |
| passed / review_required / blocked / extraction_failed の判定 | blocked を再現するデモ経路 | 低品質ページの合成 fixture が無い。実装とユニットテストには存在する |
| 合成 PDF(視覚用)と合成 OCR レスポンス(入力) | PDF からの読み取り | パイプラインは PDF を読まない。両者は同一仕様から生成している |
| 依存ゼロの JSON Schema 部分実装 | JSON Schema の完全実装 | 未対応キーワードは「検証済み」にせず失敗させる方針 |
| 外部通信なし(毒化 + ソース走査で固定) | 実プロバイダ接続時の通信遮断 | 差し替えれば通信は発生する。この構成では送らない、という範囲での話 |
| 別帳票への差し替え口(2 ファイル + provider 1 メソッド) | 実際に別帳票へ差し替えた実例 | 差し替え口を設計として備えているところまで。別帳票での稼働実績はない |
規模の目安
| 項目 | 実測値 | 取得方法 |
|---|---|---|
| パイプライン | 9 段(合成 OCR レスポンス → 構造化 JSON) | DFE-V04 の 9 ボックス。合成 OCR レスポンス起点の数え方 |
| 抽出項目 | 12 | src/field-definitions.js の定義数 |
| 実装 | src/ の JavaScript 12 ファイル | src 配下の JavaScript 12 ファイル(src/providers/mock-provider.js を含む) |
| テスト | 157 passed / 40 suites / 0 failed | npm test(2026-08-15 実行。2026-08-20 に再実行し同数を確認)/ CI run 32023326504 |
| 依存パッケージ | 0 | package.json に dependencies / devDependencies のキー自体が無い。tests/no-network.test.js が検証 |
対応可能な作業の例
以下は対応できる作業の種類であり、受注実績ではありません。
- 読み取り・自動処理の後処理(項目の取り出し・正規化・確認要否の判定)
- 帳票・伝票データの構造化と、連携先へ渡す形式の検証
- 入力データの検証ルール設計(補正しない/欠損を区別する方針を含む)
- 外部サービスへデータを出せない環境での処理設計
技術詳細
証拠へのリンク
- リポジトリ(document-field-extraction-demo)→
- README — このページが説明している範囲→
- CI の設定ファイル→
- CI の実行ログ(157 passed / 0 failed)→
CI 実行ログは GitHub Actions で確認できます。閲覧には GitHub へのサインインが必要な場合があります。
- 01想定業務課題
- 02使う人と、いまのやり方
- 03満たすべきこと
- 04作ったもの
- 05なぜこの設計にしたか
- 06見どころ
- 07実装範囲
- 08品質の担保方法
- 09安全性とデータの扱い
- 10運用と納品物
- 11できること・含めていないこと
- 12規模の目安
- 13対応可能な作業の例
- 14技術詳細
- 15証拠へのリンク