financial-document-processor について
請求書、領収書、明細書などの財務文書から構造化データを抽出する手順を示すスキルです。元ファイルのバックアップと検証を重視し、OCR と PDF のテキスト抽出の使い分けも扱います。
主な機能
- 01OCR と PDF テキスト抽出の案内
- 02日付、金額、通貨形式の違いへの対応
- 03元ファイルをバックアップしてコピーを処理
- 04サンプル検証後の一括処理
- 05件数と抽出結果の確認
活用シーン
- 01スキャンされた財務文書から項目を抽出
- 02異なる金額・日付形式の整理
- 03一括処理前の文書抽出結果の検証
- 04ファイル処理に伴うデータ損失リスクの低減
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ letta-ai/ skills --skill financial-document-processorインストール後、Claude Code で/financial-document-processorを入力して読み込まれたか確認します。
詳細
財務書類プロセッサー
概要
このスキルでは、OCR と PDF テキスト抽出を使用して、財務書類(請求書、レシート、明細書など)から構造化データを抽出する方法を説明します。破壊的な操作による壊滅的な障害を防ぐためのデータ安全対策を重視しています。
重要なデータ安全の原則
検証またはバックアップを行わずに、ソースデータに対して破壊的な操作を絶対に実行しないでください。
ファイルを処理する前に、必ず次の手順を実行してください。
- 処理前にすべてのソースファイルのバックアップを作成します
- オリジナルではなくコピーを使用します
- クリーンアップを行う前に、出力が期待どおりであることを確認します
- 直接移動するのではなく、アトミックな操作(コピー → 検証 → 削除)を使用します
安全なファイル操作のパターン
# CORRECT: Copy first, verify, then clean up
cp -r /source/documents/ /backup/documents/
# ... process files ...
# ... verify outputs match expectations ...
# Only after verification: rm /backup/documents/
# WRONG: Delete before moving (data loss risk)
rm -f /source/*.pdf && mv /source/* /dest/ # Files deleted before move!
ワークフロー
ステップ 1:環境と要件を確認する
処理コードを書く前に、次の手順を実行してください。
- すべてのソースファイルを一覧表示し、正確なパスを記録します
- ファイルの種類(テキストベースの PDF、スキャンした PDF、JPG、PNG など)を特定します
- 利用可能なツールを確認します:
which tesseract、which pdftotext、python3 -c "import pypdf" - 期待される出力形式(CSV の列、必須フィールドなど)を把握します
ステップ 2:バックアップを作成する
処理を行う前に、必ずソースファイルをバックアップしてください。
# Create timestamped backup directory
BACKUP_DIR="/tmp/backup_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$BACKUP_DIR"
cp -r /path/to/source/documents/* "$BACKUP_DIR/"
echo "Backup created at: $BACKUP_DIR"
ステップ 3:サンプルファイルで抽出をテストする
すべての書類を処理する前に、次の手順を実行してください。
- 代表的なファイルを 2~3 個選択します(形式が異なるものや、エッジケースを含むもの)
- これらのサンプルで OCR/抽出をテストします
- 抽出した値が目視確認の結果と一致することを確認します
- サンプルの結果に基づいて、抽出ロジックを調整します
# Test extraction on a single file first
sample_file = "/path/to/sample_invoice.pdf"
extracted_data = extract_document(sample_file)
print(f"Extracted: {extracted_data}")
# Manually verify these values match the document
ステップ 4:形式の違いに対応する
財務書類には、形式に違いがあることがよくあります。
- 数値の形式:欧州式(1.234,56)と米国式(1,234.56)
- 日付の形式:DD/MM/YYYY、MM/DD/YYYY、YYYY-MM-DD
- 通貨記号:$、€、£、または通貨名の表記
- 空欄/欠落フィールド:VAT はゼロではなく、空欄の場合があります
def parse_amount(text):
"""Handle multiple number format conventions."""
# Remove currency symbols and whitespace
cleaned = re.sub(r'[$€£\s]', '', text)
# Detect European format (comma as decimal separator)
if re.match(r'^\d{1,3}(\.\d{3})*,\d{2}$', cleaned):
cleaned = cleaned.replace('.', '').replace(',', '.')
# US format (comma as thousands separator)
elif ',' in cleaned:
cleaned = cleaned.replace(',', '')
return float(cleaned) if cleaned else None
ステップ 5:すべての書類を処理する
サンプルでのテストが成功したら、次の手順を実行してください。
- エラー処理を行いながら、書類を 1 件ずつ処理します
- 各書類の抽出結果をログに記録します
- 出力ファイルを書き込む前に、すべての結果を収集します
results = []
errors = []
for doc_path in document_paths:
try:
data = extract_document(doc_path)
results.append(data)
print(f"✓ Processed: {doc_path}")
except Exception as e:
errors.append((doc_path, str(e)))
print(f"✗ Failed: {doc_path} - {e}")
if errors:
print(f"\nWarning: {len(errors)} documents failed to process")
for path, error in errors:
print(f" - {path}: {error}")
ステップ 6:ファイル操作の前に検証する
ファイルを移動したり、最終出力を書き込んだりする前に、次の手順を実行してください。
- 抽出したレコード数とソースファイル数を比較します
- 抽出した値をソース書類と照らし合わせて抜き取り確認します
- 出力形式が要件に一致していることを確認します
# Verification checklist
assert len(results) == len(document_paths), "Record count mismatch"
# Spot-check a few values
for sample in random.sample(results, min(3, len(results))):
print(f"Please verify: {sample['filename']} -> Total: {sample['total']}")
ステップ 7:ファイルを移動する(検証後のみ)
検証に合格した場合に限り、次の手順を実行してください。
# Move files to destination (not delete!)
for file in /source/documents/*.pdf; do
mv "$file" /processed/
done
# Only remove backup after confirming processed files exist
ls /processed/*.pdf && rm -rf "$BACKUP_DIR"
よくある落とし穴
1. バックアップなしでの破壊的なコマンド
問題: 成功を確認する前に rm を使用したり、ファイルを上書きしたりすること。
防止策: 必ず先にバックアップを作成し、コピー・検証・削除のパターンを使用します。
2. シェルパイプラインでのコマンド順序
問題: rm -f *.pdf && mv *.pdf /dest/ のように、移動する前にファイルを削除してしまうこと。
防止策: サンプルデータでコマンドをテストし、実行順序を理解します。
3. スクリプトの検証不足
問題: 途切れたスクリプトや不完全なスクリプトを本番データに対して実行すること。 防止策: 実行前にスクリプトの内容を確認し、まずサンプルでテストします。
4. 欠落データの捏造
問題: 抽出に失敗した際に、推測した値を書き込むこと。 防止策: 失敗を明示的に報告し、欠落値には null または空値を使用します。
5. 早まった最適化
問題: 値が正しくないように見えたとき、調査せずにすぐ再処理すること。 防止策: まず OCR の出力と抽出ロジックの問題を分析し、ファイルを移動しないようにします。
6. PDF と画像の扱い
問題: テキストベースの PDF に OCR を使用したり、スキャンした PDF にテキスト抽出を使用したりすること。 防止策: 抽出方法を選ぶ前に、PDF からテキストを抽出できるか確認します。
def is_text_based_pdf(pdf_path):
"""Check if PDF contains extractable text."""
from pypdf import PdfReader
reader = PdfReader(pdf_path)
for page in reader.pages:
if page.extract_text().strip():
return True
return False
検証方法
処理前の検証
- ソースファイルが存在し、読み取り可能である
- バックアップが正常に作成されている
- 必要なツール(tesseract、pdftotext、pypdf)がインストールされている
- サンプルの抽出で妥当な値が得られる
後処理の検証
- 出力レコード数が入力ファイル数と一致している
- 抽出エラーが発生していない(またはエラーが記録されている)
- 値をいくつか確認し、ソース文書と一致している
- 出力形式が要件を満たしている(列と型が正しい)
- ファイルが正しい保存先に移動されている
- 最終検証が完了するまで元のバックアップが保持されている
復旧計画
問題が発生した場合:
- 直ちに停止します。処理を続行しないでください
- バックアップから復元します:
cp -r "$BACKUP_DIR"/* /source/ - 再試行する前に、失敗の原因を調査します
- すべてのファイルを再処理する前に、サンプルで抽出ロジックを修正します
ツール選択ガイド
| ファイル形式 | 主なツール | 代替ツール |
|---|---|---|
| テキストベースの PDF | pypdf, pdftotext | - |
| スキャン済み PDF | tesseract(pdf2image の後) | pypdf |
| JPG/PNG 画像 | tesseract | - |
| テキストとスキャンが混在する PDF | まず pypdf を使用し、画像ページには tesseract を使用 | - |
依存関係をインストールします:
# System packages
apt-get install tesseract-ocr poppler-utils
# Python packages
pip install pypdf pytesseract pdf2image pillow