バクラクの経費精算で「このレシート、明細と合ってる?」をAIに全部突合させてみた

読了 約6分 たびすけ
AIで領収書とカード明細を突合する記事のアイキャッチ

前回(新規取引先チェック)は、ほぼ「ルール+公式API」で動く話でした。今回は本物のAIが画像を読みます。経費精算の「レシートと明細、ちゃんと合ってる?」を、AIに全部突合させてみました。やってみたら、人が目視で見逃すやつ——1枚のレシートを複数明細に分けた計上や、税率の混在まで拾ってきました。

連載「経理をAIに任せる」(全4回)

  1. 「経理はAIに任せられない」の先へ——AI前提の統制を、いま設計する
  2. 新規取引先チェックをAIに任せたら、合併で消えた会社を見つけてきた
  3. 経費精算のレシートと明細を、AIに全部突合させてみた(この記事)
  4. AI前提の経理は、会計ソフトを「APIが開いているか」で選ぶ

何をチェックする作業か

経費精算の明細は1件ごとに、添付レシートと金額・日付・税区分が合っているかを確認します。件数が多く、しかも「税込金額がレシートに本当に載っているか」を一枚ずつ見るのは地味に消耗します。ここを自動化しました。

AIに任せた流れ

まずバクラクから申請と明細、レシート実体を取ってきます(ここはベンダーAPIなので擬似コード)。

# バクラクAPIで「申請中の経費精算」を取得し、明細ごとに
# 金額・日付・税区分・レシート(添付ファイル)を取り出してDLする
applications = bakuraku.fetch_requests(status="IN_PROGRESS", form="経費精算申請")
receipt_bytes = bakuraku.download(f"/workflow/user_upload_files/{file_id}/file")

レシートからテキストを抽出します。PDFならテキスト層が取れます。

import fitz  # PyMuPDF

def extract_text(path: str) -> str:
    """PDF/画像からテキストを抽出する。テキスト層が無ければ空文字。"""
    try:
        with fitz.open(path) as doc:
            return "".join(page.get_text() for page in doc)
    except Exception:
        return ""

そして明細の税込金額が、レシートの中に実際に出てくるかを見ます。レシートは桁ごとにセル分割されたりカンマが入ったりするので、空白・カンマを全部潰してから突合します。

import re

def amount_in_text(amount: int, text: str) -> bool:
    """金額がテキストに出現するか(空白・カンマ・改行を吸収)。"""
    if not amount:
        return None
    flat = re.sub(r"[\s,,]", "", text)      # 空白とカンマを全除去
    return str(abs(int(amount))) in flat

ここが今回のキモです。テキストが取れた分は上の機械処理で一瞬。取れない画像/スキャンのレシートだけ「要OCR」に振り分けて、そこをAI(Claude)が画像として読みます

if has_text_layer:
    verdict = "OK" if amount_in_text(amount, text) else "要確認(金額不一致)"
else:
    verdict = "要OCR(Claude)"     # ← 画像はここでAIに回す

全部AIに読ませない設計にした理由

全部をAIに読ませる必要はありません。テキストで取れるものは正規表現で一瞬・無料・確実。AI(画像OCR)は「本当に必要な画像だけ」に使う。これで速くて安くて正確になります。

目視で滑る3パターンが引っかかった

実際に回すと、目視だと滑りやすいものが引っかかりました(いずれも内容は伏せます)。

  • 分割計上:1枚のレシート(合計が大きめ)が複数の明細に割られていて、各明細の金額がレシートのどこにも出てこない→自動で「金額不一致」
  • 税率の混在:明細は課税10%なのに、レシート側に軽減8%や対象外が混ざっている→「要確認」
  • 適格請求書じゃない証憑:予約確認書・フリマの取引画面など、登録番号(T+13桁)が無いもの→種別を判定して注意フラグ

機械・AI・人の三層に分けた理由

機械とAIに任せたのは「全明細を突合して、要確認を上げてくる」ところまで。承認・差し戻しは自分です。

三層フローの責任境界

テキスト突合=機械、画像OCR=AI、判断・差し戻し=人。「確認担当」が機械とAIに分かれただけで、最終責任は自分です。

なお、コードの書き方と分担は前回の記事に書いたとおりです。経費精算と支払申請で共通する処理は、共通ヘルパーへ切り出して使い回しています。

まとめ

経費精算のレシート照合は「テキストは機械・画像はAI・判断は人」で全件突合。分割計上も税率混在も自動で要確認に。AIは「必要な所だけ」使うのがコツでした。

シリーズ最終回は、ここまでの実践で見えた「ツール選びの結論」です。→ AI前提の経理は、会計ソフトを「APIが開いているか」で選ぶ