About

契約書・法律文書向けのOCR — 条項の抽出、当事者の識別、構造化まで

Legal-BERT・CUAD・LayoutLMv3で契約書を構造化し、APIとローカルをどこで分けるかまで

契約書OCRは文字を抜いて終わりではない。抜いた文章から条項・当事者・期限・金額を取り出して、ようやく使えるものになる。この記事を読めば、そのパイプラインをどのモデルで組むか、そして「OpenAIのAPIを使うか、自前で動かすか」をどこで分けるかを決められる。

2段階に分けて考える

ステップ1:OCR — 契約書の画像/PDF → テキスト
ステップ2:理解 — テキスト → 構造化データ(条項、当事者、期限、金額)

ステップ1は一般的なOCR(PaddleOCR、Markerなど)で足りることが多い。難しいのはステップ2、法律の文章を理解する側だ。

Legal-BERT — 法律文書で追加学習したBERT

普通のBERTはWikipediaのような一般的な文章で学習している。Legal-BERTはそこに英語の法律テキスト12GB(法令、判例、契約書)を追加で学習したものだ。だから「indemnification」「force majeure」のような用語を普通のBERTよりうまく扱う。ただし英語のモデルなので、日本語や韓国語の契約書にはそのまま使えない。

from transformers import AutoTokenizer, AutoModel

tokenizer = AutoTokenizer.from_pretrained("nlpaueb/legal-bert-base-uncased")
model = AutoModel.from_pretrained("nlpaueb/legal-bert-base-uncased")

CUAD — 契約書理解のデータセット

実際の契約書500件余りに専門家のアノテーションが13,000以上、ラベルは41種類。解除条項、責任上限、知的財産の帰属、競業避止、更新条件などだ。Legal-BERTをCUADでファインチューニングすると、「解除条項は?」「責任上限はいくら?」に答えるモデルになる。

from datasets import load_dataset
dataset = load_dataset("theatticusproject/cuad-qa")
print(dataset["train"][0])
# → {'question': ..., 'context': '契約書のテキスト...', 'answers': {...}}

LayoutLMv3 — 位置まで見る

Legal-BERTは文字だけを見る。LayoutLMv3は文字+位置+画像をまとめて見る。契約書は署名欄・日付欄・条番号のようにどこにあるかが意味を決める場所が多いので、この差は大きい。

Legal-BERT:「このテキストは解除条項か?」(文字だけ)
LayoutLMv3:「この位置のこのテキストは解除条項か?」(文字+位置+画像)

できあいのものを使う道

OpenContracts はMITライセンスのオープンソース文書分析プラットフォームだ。人がPDFにラベルを付けるアノテーション画面、ベクトル検索、LLMによる構造化抽出まで入っている。自前でパイプラインを組む前に、どんな画面や流れが要るのか感触をつかむのにいい。

Azure Document Intelligence には契約書用の prebuilt-contract モデルがある。当事者(Parties)、管轄(Jurisdictions)、契約ID、タイトルなどをJSONで返す。ただ公式ドキュメントでは英語の文書のみ対応だ(2026-10-19確認)。日本語や韓国語の契約書なら、この道は使えない。

APIに送るか、ローカルで動かすか

「契約書をOCRして分析するとき、OpenAIのAPIを使うのとtransformersで自前で動かすのはどう分かれるのか」という質問を受けて整理した部分だ。性能で比べると答えを間違える。精度だけなら大型APIがほぼ必ず勝つからだ。実際に分けるのは3つ。データを外に出せるか、作業が定型か、件数がどれくらいか。

そして契約書の分析は二者択一の問題ではない。ひとつのパイプラインの中に定型作業と開かれた解釈が混ざっている。

Contract pipelineSmall or local modelLarge LLM APIOCRscan to textfitsField extractiondate, amount, partiesfitsClause classificationtermination, liabilityfitsFind risky clausesopen-ended readingfitsNot either-or: one pipeline, two kinds of steps
基準 API(OpenAI・Azure・Claude) 自前運用(transformersなど)
始めるまで すぐ モデル選定・サーバー・GPUの準備
開かれた解釈の精度 高い(条項の解釈、リスク要約) 小さいモデルには限界がある
データの持ち出し 外部に出る 社内で完結する
コスト構造 件数課金 → 多くなると高い 初期費用が大きく、件数が増えるほど安くなる
運用負担 ほぼない モデル更新・障害対応を自分で
オフライン 不可 可能

切り替えのサインはこうだ。

  • 契約書を外に出せない(セキュリティ・法務の要件) → 自前運用

  • 件数が増えて件数課金が重い → 定型部分だけローカルに移す

  • 抜く項目が決まった(フィールド3つ、条項5種) → 小さいモデルをファインチューニング

  • まだ何を抜くか決まっていない、PoC段階 → まずAPI

中間の選択肢としてAzure OpenAIがある。Microsoftの公式ドキュメントには、プロンプトと出力はモデルの学習に使われず、OpenAIにも渡らないと書かれている。ただし不正利用の監視のため、問題がありそうなリクエストは人が確認することがあり、これを止めるには別途申請が要る。契約書を扱うならここまで読んでから決める。このリポジトリでもAzure OpenAIをすでにサービスオブジェクトとして組み込んでいて、社内文書を扱うときはまずこちらを検討している。

実践パイプラインの例

契約書PDF
  ↓ Marker/PaddleOCR(テキスト抽出)
テキスト
  ↓ Legal-BERT + CUADでファインチューニングしたモデル(条項分類)
構造化データ(例):

  - 当事者:A社、B社

  - 契約期間:2026.01.01〜2028.12.31

  - 解除条件:30日前までに書面で通知
  ↓ 必要な所だけLLMのAPI(「この契約でこちらに不利な条項は?」)

まだ自分で測っていないこともある。同じ契約書1,000件でのコスト比較、日本語・韓国語の契約書でのTesseract・PaddleOCR・クラウドOCRの精度比較は、測ってから別に書く。比較表の全体は OCR API vs セルフホスト にある。

契約書や社内文書の分析を組み込みたいが、どこまでAPIに送っていいか判断がつかないなら、negabaroに相談してほしい(お問い合わせ)。

キーコンセプト

1

OCRでテキスト抽出 — Marker/PaddleOCRなどの一般的なツールで足りることが多い

2

Legal-BERT + CUADで条項分類 — ただし英語の契約書が前提

3

LayoutLMv3で位置まで見る — 署名欄・日付欄・条番号

4

定型の段階は小さいモデル・ローカル、開かれた解釈だけLLMのAPI

5

APIかローカルかは、持ち出せるか・定型か・件数で決める

ユースケース

契約書の自動チェック — 解除条項、責任上限、競業避止などの主要条項を抽出 契約書の比較 — 2つの契約書の条項の違いを自動で比べる 持ち出せない社内文書をローカルモデルで構造化
← PDF特化OCR — 複雑なレイアウト・表・数式をMarkdownに変換するツール 日本語特化OCR — 漫画、縦書き、ふりがな、古文書まで →