0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonで見積CSVの単位ズレをAIレビュー前に検出する

0
Posted at

AIに見積CSVを読ませるとき、先に見るべきなのは金額でしょうか。それとも単位でしょうか。

僕は単位から止めます。金額がきれいに並んでいても、「単位:千円」の一行を落とすと、レビュー結果はもっともらしいまま1000倍ずれます。数字を読めるモデルほど、この事故は気づきにくいです。

9月3日にOpenAIが公開した導入事例では、LegoraがGPT-6 Astraで財務諸表41件を数分でレビューしたと紹介されていました。こういう速さが現実になるほど、入力側の小さな前提を人が残しておく価値は上がります。Legoraの導入事例を読んで、提案前の見積CSVで使っている小さな検査を整理しました。

今朝、サンプルCSVを3つ通したら、2つに警告が出ました。一つは「単位:千円」と書いた表の4行目に2,000円が混ざっていました。もう一つは単位の記載がありませんでした。見落としやすいのに、相手へ出た後は説明が面倒なやつです。ここ地味に効きます。

先に止めるのは、単位なしと単位混在

この検査で見るのは二つだけです。

  • CSV内に単位:千円のような宣言があるか
  • 宣言した単位と違う、2,000円のような金額表記が混ざっていないか

金額そのものの正しさまでは判定しません。1,200が正しいかどうかは、案件の一次情報がないと機械では決められないからです。その代わり、読む人もツールも判断できない状態を先に浮かび上がらせます。

例えば、売上見込みを千円で集計する表に、返金だけ円で貼り付けてしまうことがあります。合計欄は数式で整って見えても、元の桁が違えば意味がありません。レビューに回す前なら、その行だけ元ファイルを確認して直せます。

この順番で止めます。

見積CSVを単位の宣言と別単位の金額で検査し、問題がなければAIレビューへ渡す流れ

標準ライブラリだけで確認するPython

inputフォルダにCSVを置き、次のスクリプトをcheck_units.pyとして保存します。UTF-8とUTF-8 BOM付きCSVを対象にしています。外部ライブラリは使いません。

import csv
import re
import sys
from pathlib import Path

UNIT_RE = re.compile(r"単位\s*[::]\s*(億円|百万円|千円|万円|円)")
AMOUNT_RE = re.compile(
    r"(?<![0-90-9])[-+]?[0-90-9][0-90-9,,]*(?:[..][0-90-9]+)?\s*(億円|百万円|千円|万円|円)"
)

def inspect_rows(name, rows):
    declarations = []
    amount_units = []

    for row_no, row in enumerate(rows, start=1):
        text = " | ".join(str(cell).strip() for cell in row)
        declarations.extend((row_no, m.group(1)) for m in UNIT_RE.finditer(text))
        amount_units.extend(
            (row_no, m.group(1), m.group(0))
            for m in AMOUNT_RE.finditer(text)
        )

    units = sorted({unit for _, unit in declarations})
    if not units:
        print(f"[WARN] {name}: 単位の宣言がありません")
        return 1

    if len(units) > 1:
        detail = ", ".join(f"{unit}({row_no}行目)" for row_no, unit in declarations)
        print(f"[WARN] {name}: 単位の宣言が複数あります: {detail}")
        return 1

    declared = units[0]
    conflicts = [
        (row_no, unit, value)
        for row_no, unit, value in amount_units
        if unit != declared
    ]
    if conflicts:
        detail = ", ".join(f"{row_no}行目={value}" for row_no, _, value in conflicts)
        print(f"[WARN] {name}: 宣言は{declared}ですが、別単位の金額があります: {detail}")
        return 1

    print(f"[OK]   {name}: 単位={declared}")
    return 0

def inspect_file(path):
    with path.open(encoding="utf-8-sig", newline="") as f:
        return inspect_rows(path.name, csv.reader(f))

def main():
    root = Path(sys.argv[1] if len(sys.argv) > 1 else "input")
    if not root.is_dir():
        raise SystemExit(f"ディレクトリがありません: {root}")

    files = sorted(root.glob("*.csv"))
    if not files:
        raise SystemExit(f"CSVがありません: {root}")

    warnings = sum(inspect_file(path) for path in files)
    print(f"\n確認が必要なCSV: {warnings}件")
    return 1 if warnings else 0

if __name__ == "__main__":
    raise SystemExit(main())

実行はこれだけです。

python3 check_units.py input

検証には、次の3パターンを使いました。Python 3.14.6で実行しています。

[WARN] forecast.csv: 宣言は千円ですが、別単位の金額があります: 4行目=2,000円
[WARN] budget.csv: 単位の宣言がありません
[OK]   plan.csv: 単位=百万円

確認が必要なCSV: 2件

警告が1件でもあれば終了コードは1になります。ローカルで見るだけなら表示を確認すれば十分ですし、提案資料を作る前のバッチに入れるなら、1で止めればいい。人が直すべきファイルだけに絞れます。

なぜAIレビューの前に置くのか

単位は表の文脈です。CSVにすると、Excelのシート名、セルの色、見出しの結合といった手がかりが落ちます。AIへ渡す時点で単位の一行まで残っていなければ、「売上1200」と「売上1200千円」を区別する材料がありません。

だから、プロンプトに「単位を確認して」と足すだけでは足りません。単位なしのファイルを渡さない運用にした方が再現できます。レビュー結果が速く返るほど、入力の欠けに気づくタイミングは減ります。

このスクリプトは、複数通貨の正当性や、¥2,000のような表記までは扱いません。そこまで一度に拾おうとすると、普通のメモや日付まで金額扱いして警告だらけになります。まずは見積・予算・売上見込みで使う5単位に狭めています。例外が多い帳票は、正規表現を増やす前にCSVを分けた方が保守しやすいです。

見積レビューで守る順番

AIに渡す資料が増えるほど、レビューの強さより入口の整備で差がつきます。単位なしと単位混在を先に止めれば、レビュー担当は本当に見たい金額の根拠へ時間を使えます。

僕なら、このチェックを見積CSVの出力直後に置きます。通ったファイルだけを要約や比較に回す。派手ではありませんが、商談の数字を扱うなら、この一手の方がモデルを替えるより先です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?