販売奨励金・リベートの支払額を、契約の条件と販売実績から検算する
取引先と結んだ販売奨励金(リベート)の契約書から、支払の条件をAIに読み取らせて条件テーブルにします。そのテーブルと販売実績から支払額を機械で計算し、取引先からの請求との差異を理由ごとに切り分けます。
- 利用ツール
- ChatGPT/Claude/Gemini/Google Apps Script/Make/n8n/Python/Zapier
- 対象業界
- EC/商社/小売/製造/飲食
- 対象部門
- 営業/財務
- 対象業務
- 内容確認・チェック/集計・分析
- 主な課題
- データ分析に時間がかかる/属人化している/確認ミスが多い
- AIで行う処理
- 判定
- 主な効果
- 品質標準化/工数削減/機会損失防止
- 導入難易度
- ★★☆☆☆
- 実装レベル
- 半自動化
- 費用感
- API連携(中)
- 人間の確認
- 条件付き
01導入前 / 導入後の業務フロー
- 締め日の後、販売管理システムから取引先ごとの販売実績を取り出す
- 担当する取引先の契約書PDFを開き、販売奨励金の条・別表を読み直す
- 対象商品、期間、率、控除するもの、上限を読み取り、表計算のシートに写す
- 実績から対象商品だけを抜き出し、期間で絞り込み、返品と値引を差し引く
- 階段状の率のどの段に当たるかを見て、率を掛ける
- 上限の定めがあれば、計算した金額と上限を比べる
- 取引先から届いた請求書・申請書の金額と、自社の計算を並べて見る
- 差があれば、実績の数字と契約書を行き来しながら原因を探す
- 説明がついたものは精算表に記録し、支払の承認に回す
- 自動契約書PDFが契約フォルダに保存されたことをきっかけに、奨励金の条・別表を切り出す
- 自動AIが条件を読み取り、対象商品・期間・階段状の率・基準・控除・上限・支払時期を条件テーブルにする
- 自動読み取った各行に、ページ番号・条番号・根拠にした原文を添える
- 人担当者が条件テーブルと原文を並べて突き合わせ、承認する(契約ごとに1回。改定時にもう1回)
- 自動締め日の翌営業日に、販売管理システムから実績を取り出す
- 自動条件テーブルを読んだプログラムが、対象商品と期間で絞り、控除を引き、段を判定して金額を計算する
- 自動上限の定めがあれば適用し、適用したかどうかを記録する
- 自動取引先からの請求・申請の金額と比べ、差があれば理由コードを付ける
- 人差異のある行と、条件が `needs_review` の行だけを開いて確かめる
- 人支払額を承認する
- 人承認された金額が、既存の支払の手続きに回る
各工程の詳しい説明を読む
- 締め日の後、販売管理システムから取引先ごとの販売実績を取り出す
- 担当する取引先の契約書PDFを開き、販売奨励金の条・別表を読み直す
- 対象商品、期間、率、控除するもの、上限を読み取り、表計算のシートに写す
- 実績から対象商品だけを抜き出し、期間で絞り込み、返品と値引を差し引く
- 階段状の率のどの段に当たるかを見て、率を掛ける
- 上限の定めがあれば、計算した金額と上限を比べる
- 取引先から届いた請求書・申請書の金額と、自社の計算を並べて見る
- 差があれば、実績の数字と契約書を行き来しながら原因を探す
- 説明がついたものは精算表に記録し、支払の承認に回す
(a)2番と3番が毎月繰り返される。 契約が変わっていなくても、担当者は毎回契約書を開き直します。前回どう読んだかが表計算の数式の中にしか残っていないので、数式を読むより契約書を読むほうが早い、という状態になっています。
(b)差異の原因が3種類の中に埋もれている。 請求と自社の計算が合わないとき、原因は「条件の読み違い」「実績の切り取り方の違い」「取引先側の間違い」のどれかです。最初に疑うべきなのは条件の読み違いではなく、締め日と返品の扱いです。 8番に時間がかかるのは、切り分けの手順が決まっていないからです。
(c)覚書の反映が遅れる。 率を改定する覚書は営業が受け取り、契約書のフォルダに入るまでに時間差があります。改定前の率で払った後に覚書が回ってくると、遡って計算し直すことになります。 どこまで遡り、差額をどう立てるかは、そのつど相談で決めています。
(d)払いすぎと払い漏れは、気づかないまま通る。 上限の定めを見落とせば払いすぎ、対象商品を狭く読めば払い漏れです。どちらも取引先が指摘しない限り表に出ず、払いすぎは何年も続くことがあります。
- 【自動】 契約書PDFが契約フォルダに保存されたことをきっかけに、奨励金の条・別表を切り出す
- 【自動】 AIが条件を読み取り、対象商品・期間・階段状の率・基準・控除・上限・支払時期を条件テーブルにする
- 【自動】 読み取った各行に、ページ番号・条番号・根拠にした原文を添える
- 【人】 担当者が条件テーブルと原文を並べて突き合わせ、承認する(契約ごとに1回。改定時にもう1回)
- 【自動】 締め日の翌営業日に、販売管理システムから実績を取り出す
- 【自動】 条件テーブルを読んだプログラムが、対象商品と期間で絞り、控除を引き、段を判定して金額を計算する
- 【自動】 上限の定めがあれば適用し、適用したかどうかを記録する
- 【自動】 取引先からの請求・申請の金額と比べ、差があれば理由コードを付ける
- 【人】 差異のある行と、条件が
needs_reviewの行だけを開いて確かめる - 【人】 支払額を承認する
- 【人】 承認された金額が、既存の支払の手続きに回る
4番が、この設計の要です。人が原文と突き合わせるのは、契約ごとに1回だけです。 毎月の精算120件で契約書を開くのではなく、条件が入るときと変わるときに1回ずつ確かめます。一度確かめれば、毎月の計算は機械の仕事になります。
6番と7番をAIから切り離しているのは、計算だからです。 どの段に当たるか、控除をいくら引くか、上限に当たったかは、条件テーブルさえあれば四則演算で決まります。言語モデルに渡せば、桁が落ちても率が丸まっても、それらしい金額が返ってきます。
9番で人が開くのは全件ではありません。 差が出ず、条件も ok の行は、一覧で件数と金額を流し見て終わりにします。全件を開く設計にすると、26.0時間はほとんど減りません。
02今回想定するシステム構成
契約書PDF(原契約・覚書・別表) │ 奨励金の条・別表だけを切り出す ▼【トリガー1】契約フォルダへの保存 Make ▼ OpenAI API(ファイル入力 + 構造化出力) │ 条件を読み取り、根拠(ページ・条番号・原文)を添える ▼ 条件テーブル(JSON) ▼ 【人が原文と突き合わせて承認】── 契約ごとに1回/改定時にもう1回 │ ▼ ここから下は毎月動く 【トリガー2】締め日の翌営業日(Make のスケジュール) ▼ Make ── 販売管理システムから実績・返品・値引を取得 ▼ Python ── 条件テーブルを読み、対象を絞り、控除を引き、段を判定し、 │ 上限を当てて金額を計算する(AIは通さない) ▼ Python ── 取引先からの請求と比べ、差異に理由コードを付ける ▼ 精算表(match / review / hold) ▼ 【人が差異のある行だけ確認 → 支払額を承認】 ▼ 既存の支払の手続きへ
| 役割 | 想定する製品 | 代替候補 |
|---|---|---|
| 処理 | OpenAI API | Claude API、Gemini API |
| 差異計算 | Python | Google Apps Script |
| 連携 | Make | Zapier、n8n |
販売管理システムと支払の仕組みは、新しく足すものではありません。実績は読み取るだけで、どちらにも書き込みません。
契約書を読ませる土台になるのが、OpenAI API のファイル入力です。 モデルの入力として渡すファイルは purpose に user_data を使ってアップロードし、input_file という content part で参照します。参照の仕方は3通りあり、file_id、base64 にした file_data、Responses API での file_url です。ファイルは1つあたり50MB未満で、1回のリクエストの合計も50MBまでとされています。
PDFについては、テキストとページ画像の両方が抽出されてモデルへ渡されます。 別表が表の形で組まれている契約書でも読める理由がここにあります。ただし両方が文脈に入るためトークンは増え、この読み取り方には画像を扱えるモデルが必要とされています。
出力を表に落とすために使うのが構造化出力(Structured Outputs)です。 JSON Schema を渡すと、モデルは常にそのスキーマに沿った応答を生成するため、required なキーが欠けることや、enum に無い値が作られることを心配しなくてよいとされています。
毎月の精算を動かすのが Make です。 シナリオは既定では15分ごとに実行され、実行のしかたは「一定の間隔(分で指定)」「1回だけ」「毎日」「曜日を指定」「毎月の日付を指定」「日付を個別に指定」「オンデマンド(手動またはAPI呼び出し)」から選べます。最短の間隔は契約プランによって決まります。 詳細設定では開始日と終了日を決められ、1日に複数の時刻も登録できます。
03どうやって実装するのか
処理の起点を決める
起点は2つあり、動く頻度がまったく違います。1つ目は、契約フォルダへのPDFの保存です。 契約書と覚書のどちらも同じフォルダに入れ、保存をきっかけに条件の読み取りが動きます。覚書を別の場所に置かないでください。 率を改定した覚書がフォルダの外にあると、条件テーブルは改定前のまま毎月の計算に使われ続けます。
2つ目は、締め日の翌営業日に動く毎月の精算です。 Make では「毎月の日付を指定」を選びます。既定の15分ごとのままにしないでください。 月に1度で足りる処理が1日に96回走ります。
取引先からの請求が届く時期はばらばらです。 1日のうちに複数の時刻を登録し、届いた請求だけを突き合わせます。届いていない行は hold のまま置きます。
入力データを集める
| データ | 中身 | 取得元 |
|---|---|---|
| 契約書 | 原契約、覚書、別表。条・別表を切り出したPDF | 契約フォルダ |
| 条件テーブル | 人が承認した条件の一覧(版を持つ) | この構成が作る |
| 販売実績 | 取引先 × 商品 × 計上日の数量と金額 | 販売管理システム |
| 返品・値引 | 返品日、元の売上との対応、値引の種類 | 販売管理システム |
| 商品マスタ | 型式、ブランド、新製品かどうかの区分 | 商品マスタ |
| 取引先マスタ | 取引先コード、締め日、支払時期 | 取引先マスタ |
| 取引先からの請求 | 対象期間と金額 | メール、取引先ポータル |
| 過去の精算履歴 | どの期間をどの版で精算したか | 精算表 |
いちばん下の2つを軽く見ないでください。 請求が無いまま自社の計算だけで払うと払いすぎが検知されず、過去の精算履歴が無いと同じ期間を二度精算します。
取引先マスタの締め日も同じです。 自社が月末、取引先が20日という組み合わせは珍しくなく、この1項目が無いだけで毎月「原因不明の差異」が出続けます。
データの取得方法を決める
契約書は、奨励金に関係する条・別表だけを切り出してから渡します。 容量の問題というより、関係のない条項を渡すと、支払条件や解除の条項から数字を拾ってしまうからです。
実績、返品、値引、商品の区分、締め日は、販売管理システムと各マスタから読み取るだけです。書き込みません。 実績は「取引先 × 商品 × 計上日」の明細で取ります。取引先ごとの合計では、後から対象商品で絞り込めません。 請求は金額と対象期間だけを拾えば足ります。
AIへ渡す前に整形する
- 契約の版をそろえる … 日付の新しい覚書が優先ですが、条ごとに効力が違うことがあります
- ページ番号と条番号を振る … 根拠を書かせるために、番号が読める状態にします
- 奨励金の条・別表を切り出す … 支払条件、解除、秘密保持などの条項は渡しません
- 実績の締め日をそろえる … 取引先マスタの締め日で期間を切ります。自社の月次のまま渡さないでください
- 単位をそろえる … 契約書が「台」で、実績が「ケース」のことがあります。 税抜と税込も同じです
- 返品と値引を元の売上に紐づける … 返品日ではなく、元の売上の計上日で期間に入れます
- 対象商品の区分を付ける … どの型式が新製品かを、日付付きで持ちます
- 精算済みの範囲を引く … 前回までに精算した期間と重なる部分を除きます。二重計上を止めるためのもので、遡及適用で過去の期間を計算し直すときも、すでに払った金額を引いた差額だけを立てます
4番と5番が、差異の主な出どころです。 契約書の読み取りをいくら正確にしても、この2つがずれていれば金額は合いません。前処理で直せるものを、AIの精度の問題として扱わないでください。
AIに処理させる
させるのは、契約書の文章を条件テーブルの1行に直すことだけです。 1行に入れるのは次の9項目で、1本の契約に条件が複数あれば、その数だけ行を作ります。設計で効くのは、読み取れなかったときの扱いのほうです。
| 項目 | 読み取れないときの扱い |
|---|---|
| 対象商品 | 「主力商品」など特定できなければ needs_review |
| 期間 | 記述が無ければ needs_review。契約期間を当てはめない |
| 階段状の率 | 率が「別途協議」なら needs_review |
| 基準(数量か金額か) | どちらとも読めれば needs_review |
| 控除するもの | 記述が無ければ空の一覧。推測で足さない |
| 上限 | 記述が無ければ null。0 を入れない |
| 支払時期 | 記述が無ければ needs_review |
| 効力の起算日 | 覚書に無ければ needs_review |
| 遡及の起算日 | 定めが無ければ null |
表の項目を埋めることが目的ではありません。埋まらない項目を、埋まらないまま人に渡すことが目的です。 読み取れなかった1行は担当者が10分で確かめられますが、推測で埋まった1行は誰も確かめません。
| させないこと | 理由 |
|---|---|
| 金額の計算 | 桁を落とし、それらしい合計を作る。 計算はプログラムの仕事 |
| 率の丸め | 3.5%が3%や4%になる。読み取れた文字のとおりに写す |
| 上限の補完 | 記述が無い上限を 0 で埋めると、支払額が 0 になる |
| 原文の要約 | quote をそのまま写す。要約すると突合の意味が消える |
| 支払ってよいかの結論 | 契約の解釈と支払の可否は人が決める |
1行目が、この記事全体の前提です。 「では今月はいくらですか」と聞けば金額は返ってきますが、桁が1つ落ちていてもそれらしく見えます。
指示内容を固定する
あなたは、販売奨励金(リベート)の契約書から支払条件を読み取り、
機械が計算できる表に直す係です。金額の計算はしないでください。
【やること】
契約書の販売奨励金の条件を、条件の単位ごとに1行として書き出してください。
1本の契約に条件が複数あれば、その数だけ行を作ります。
【1行に入れる項目】
- target_products: 対象の商品・ブランド・型式。契約書の書き方をそのまま写す
- period_from / period_to: 条件が適用される販売期間
- basis: 率をかける基準。quantity(数量)か amount(金額)か
- tiers: 階段状の率。下限・上限・率を段の数だけ並べる
- deductions: 控除するもの(返品、値引、運賃、他の奨励金など)
- cap: 支払額の上限。記述が無ければ null
- payment_timing: 支払の時期(毎月、四半期ごと、年1回など)
- effective_from: この条件が効力を持つ日
- retroactive_from: 遡って適用する定めがあればその起算日。無ければ null
【根拠】どの行にも source を付けてください。
- page: ページ番号 article: 条番号・別表番号(例:第7条第2項、別表2)
- quote: 根拠にした原文を、変えずにそのまま写す
【status の選び方】
- ok: 契約書の記述だけで値が決まる
- needs_review: 記述はあるが、値が一つに決まらない
- not_found: その項目についての記述が見当たらない
迷ったときに ok を選ばないでください。
【厳守事項】
- 金額を計算しないでください。率を数量や金額に掛けないでください。
ここでの仕事は、計算に使う条件を書き出すことだけです。
- 率を丸めないでください。「3.5%」を「3%」や「4%」に直さないでください。
- 書かれていない項目を、他の条件から類推して埋めないでください。
上限の記述が無ければ cap は null です。0 を入れないでください。
- 「別途協議のうえ決定する」「前年実績を勘案し」のように値が一つに決まらない
書き方は needs_review にし、それらしい数字を置かないでください。
- 「主力商品」とだけ書かれていて型式が分からない場合や、期間の記述が無い
場合も needs_review です。対象商品を広げないでください。
- quote は要約せず、原文をそのまま写してください。原文に無い言葉を入れないこと。
- 改定前の条件テーブルは、変わった箇所を見つけるための参考です。
そこの値を、契約書の記述の代わりに使わないでください。
- 販売奨励金の契約でなければ、行を作らず document_type に書いてください。
【契約書】{contract_pdf}
【この取引先のコード】{partner_code}
【改定前の条件テーブル】{current_terms}
「率を丸めない」を明記しないと丸まります。 3.5%や2.75%のような端数のある率は、読み取りの途中で切りのよい数字に寄ります。毎月の支払額に0.5ポイントの差が乗り続けても、誰も気づきません。
「上限が無ければ null、0 を入れない」も必ず書いてください。 欄がある以上、何かを入れようとします。0 が入ると上限が0円という意味になり、その取引先への支払が全部止まります。 逆に、上限があるのに読み落とせば払いすぎです。無いことと0であることを、同じ欄で区別させます。
出力形式を固定する
条件テーブルは、次の形のJSONで受け取ります。
{
"contract_id": "", "partner_code": "", "document_type": "rebate_agreement",
"terms": [
{
"term_id": "",
"target_products": [""],
"period_from": "", "period_to": "",
"basis": "quantity | amount",
"tiers": [ { "from": 0, "to": null, "rate": 0 } ],
"deductions": [""],
"cap": null,
"payment_timing": "monthly | quarterly | annual | other",
"effective_from": "",
"retroactive_from": null,
"status": "ok | needs_review | not_found",
"source": { "page": 0, "article": "", "quote": "" }
}
],
"unresolved": [ { "point": "", "reason": "", "source": {} } ]
}
構造化出力を使う理由は2つあります。
1つ目は、null を正しく書けることです。 すべての項目を required にすることが求められ、値が無いことがある項目は null との組み合わせ(例:"type": ["number", "null"])で表します。 これが、上限の無いことと0であることを分ける仕組みです。
2つ目は、後段が読みやすいことです。 ルートはオブジェクトである必要があり、additionalProperties は false にします。 決めた欄以外が増えず、required なキーの欠落も enum に無い値も心配しなくてよいからです。
返ってこないことも設計に入れます。 拒否されると refusal の欄が入り、出力の上限で切れると response.status が incomplete、incomplete_details.reason が max_output_tokens になります。長い別表で起きやすいので、条ごとに分けて投げ直します。
計算結果は Python が次の形で書き出します。AIを通しません。
{
"partner_code": "", "term_id": "", "terms_version": "",
"period": { "from": "", "to": "" },
"base_amount": 0,
"applied_tier": { "from": 0, "to": 0, "rate": 0 },
"deducted": 0, "capped": false,
"calculated_amount": 0, "claimed_amount": 0, "difference": 0,
"reason_code": "cutoff | return | unit | scope | period | cap | retro | unknown",
"verdict": "match | review | hold"
}
terms_version は、どの版の条件で計算したかを残すためのものです。 版が無いと、条件が改定されたときに遡って直す範囲が決まりません。
システムへ連携する
| つなぎ先 | 方式 | 内容 |
|---|---|---|
| 契約フォルダ | Make のトリガー | PDFの保存を検知する |
| OpenAI API | ファイル入力+構造化出力 | 条件テーブルを作る |
| 販売管理システム/各マスタ | 読み取り | 実績、返品、値引、商品の区分、締め日 |
| Python | Make から呼び出し | 金額の計算と差異の切り分け |
| 精算表 | 書き込み | 計算結果、理由コード、承認の記録 |
| 支払の手続き | 既存の経路 | 承認された金額だけが回る |
差異に付ける理由コードは、次の順に当てます。順番に意味があります。
| コード | 何が起きているか | 見分け方 |
|---|---|---|
cutoff | 締め日が自社と取引先で違う | 取引先の締めで切り直すと差が消える |
return | 返品の扱いが違う | 返品を控除せずに計算すると差が消える |
unit | 単位が違う(ケースと本、税抜と税込) | 差が一定の倍率になっている |
scope | 対象商品の範囲が違う | 特定の型式を足す、引くと差が消える |
period | 期間のまたぎ | 月またぎの出荷が前月に入っている |
cap | 上限の適用 | 上限を当てない金額と請求が一致する |
retro | 遡及適用の反映漏れ | 改定前の率で計算すると一致する |
unknown | どれでも説明がつかない | 人へ回す |
cutoff と return を先に当てるのは、この2つが圧倒的に多いからです。 先に契約の読み違いを疑うと、契約書を読み直す時間だけが増えます。理由を機械が先に1つに絞ると、④の2分が短くなります。
人が確認する
人が見る場所は3つです。それ以外は開きません。
- 条件テーブルの承認 … 契約ごとに1回、改定時にもう1回。行と
sourceのquoteを並べて読み、 原文に無い言葉がquoteに入っていたら作り直します - 差異のある行の確認 …
verdictがreviewかholdの行だけを開きます。理由コードが合っていなければunknownに戻します - 支払額の承認 … 支払の実行は必ず人が承認します。 自動で支払データを作りません
1番を飛ばすと、この構成は成り立ちません。 条件テーブルが間違っていれば、毎月その間違いで計算され続けます。契約ごとに1回きちんと見れば、あとは機械が同じ条件で回します。
3番は「承認ボタンを押すだけ」にしないでください。 画面に条件テーブルの版、当てた段、控除額、上限の適用を並べ、何にもとづく金額かが読める状態にします。
目標は、120件をならして1件3分の確認と1分の承認です。 開くのは2割前後という想定で、それより多い月は、needs_review が残っているか、前処理の単位がそろっていません。
例外に対処する
| 起きること | 対応 |
|---|---|
| 条件が「別途協議」と書かれている | needs_review。確認がつくまで、その条件では精算しない |
| 覚書が見つからない、版が特定できない | hold。原契約だけで計算しない |
| 遡及適用の覚書が後から届く | 過去の精算を上書きせず、差額の行を新しく立てる |
応答が途中で切れる、refusal が入る | incomplete なら条ごとに分けて投げ直す。refusal は人が読む |
| 実績が締め日時点で確定していない | 精算を止める。暫定値で払わない |
| 同じ期間の精算行が二度立つ | 精算済みの範囲を引いてから計算する |
| 取引先からの請求が届かない | hold。自社の計算だけで支払に回さない |
| 上限に当たった | verdict を review にし、人が確かめる |
| 契約期間が切れている | 期間外の実績を計算に入れない。自動で延長しない |
上から3行目が、いちばん間違えやすいところです。 遡及適用のときに過去の精算行を書き換えると、すでに払った金額との対応が分からなくなります。 過去の行を残して差額だけを新しい行にすれば、どの版の条件でいくら足りなかったのかが後から読めます。
請求が届かない分を「たぶんこの金額だろう」で払うのも避けてください。 その金額が翌年の基準になります。
記録を残す
- 契約書PDFと、そこから切り出した条・別表の範囲
- 条件テーブルの版ごとの全文と、
source(ページ・条番号・原文) - 人が条件テーブルを直した記録 … どの項目を、何から何に変えたか
- 計算に使った実績のスナップショット(取引先 × 商品 × 計上日)
- 計算結果、理由コード、当てた段、控除額、上限の適用の有無
- 承認した人と日時、承認の画面に表示されていた内容
- 遡及適用の記録 … どの期間を、どの版の条件で計算し直したか
条件テーブルの版と実績のスナップショットは対になっています。 「どの条件で」と「どの実績で」の両方が無いと、金額を再現できません。取引先に根拠を見せてほしいと言われたときに出すのは、この2つです。
04実装レベルの3段階
本記事が想定しているのは、真ん中の半自動化です。 条件の読み取りと金額の計算、差異の切り分けまでが自動になり、人は条件テーブルの承認と、差異のある行の確認と、支払の承認だけを行います。1件13分が4分になるのは、この段階です。 最小構成では120件をさばけません。 ただし、条件テーブルという考え方が自社の契約書に合うかどうかは、この段階で分かります。 本格構成にしても、1件4分が大きく下がるわけではありません。 残る4分は人の確認と承認で、減らす場所ではないからです。本格構成が効くのは、取引先が増えたときと、精算の証跡を監査で求められたときです。 段階を飛ばさないでください。 半自動化の精算表を2か月見ると、needs_review の多い契約と unknown の多い取引先が先に分かります。そこを直してから広げるほうが、確認に使う時間が短くなります。
05工数削減シミュレーション
導入後 120件 × 4分 ÷ 60 = 8 時間/月
自社条件で導入効果を整理したい方へ
このユースケースを自社に当てはめた場合の前提値と削減見込みを、業務ヒアリングをもとに整理します。
06向いている企業・向いていない企業
- 取引先ごとに販売奨励金の条件が違い、契約書の文章を担当者が読み解きながら表計算で精算しているメーカー・卸・商社。取引先が数十社以上あり、階段状の率、対象商品の限定、控除するもの、上限の有無が契約ごとにばらばらな場合。覚書による率の改定や遡及適用が毎年発生し、どの版の条件で計算したのかを後から説明できる形で残したい場合。
- 取引先が数社で、条件が一律の率だけで決まっている場合。販売奨励金の条件がすでに販売管理システムの設定値として登録され、実績から自動で計算されている場合。契約書が紙でしか存在せず、電子化の見通しが立たない場合。なお、取引先ごとに条件を変えることの妥当性や、率そのものの決め方についての判断は、この構成では扱いません。
07最小構成で試す方法
- 取引先10社の契約書を選ぶ(うち2社は覚書で率が改定されているもの、1社は「別途協議」の記述があるものを入れる)
- 奨励金の条・別表のページだけを抜き出し、PDFにする
- 手元のAIサービスの画面に1本ずつ貼り付け、第7章のプロンプトで条件テーブルを作らせる
- 出てきた行を契約書の原文と並べて読む。
quoteが原文と一致しているかを最優先で見る - 表計算に条件を写し、先月の実績で金額を計算する。計算はAIにさせない
- 当時の精算表の金額と突き合わせる
10社は必ずやってください。 組む前に、「契約書から条件が表になるのか」だけを確かめます。
| 出てきた内容 | 判断 |
|---|---|
| 条件テーブルが原文と一致し、金額も当時と合った | Make と Python での自動化に進む |
| 「別途協議」の行に数字が入った | 指示の書き方で直る。構成は有効 |
| 率が切りのよい数字に丸まっていた | 指示で直るが、全件で原文突合が要ることが分かる |
| 覚書の改定が反映されていなかった | 契約の版の管理が先。 AIの問題ではない |
| 金額が当時と合わない | 条件ではなく、締め日か単位を先に疑う |
4行目と5行目が出たら、それは収穫です。 毎月の精算に時間がかかっていた理由が、契約書の読み取りではなくその手前にあったということが分かります。
08実装時につまずきやすいポイント
| 問題 | 対策 |
|---|---|
| AIに金額を計算させてしまう | 条件テーブルを作るところで切る。 計算はプログラムに渡す |
| 率が切りのよい数字に丸まる | 3.5%が3%になる。指示で禁じ、承認時に原文と突き合わせる |
| 上限が無い契約に 0 が入る | cap は null と 0 を分ける。スキーマで null を許す |
| 根拠が要約されている | quote を原文のまま写させる。一致しない行は作り直す |
| 覚書の反映が漏れる | 条件テーブルに効力の起算日を持たせ、版で管理する |
| 遡及で過去の精算を上書きする | 上書きせず、差額の行を新しく立てる |
| 締め日の違いを条件の誤りと取り違える | 理由コードの順で切り分ける。cutoff を先に当てる |
| 単位が混ざる | ケースと本、税抜と税込を前処理でそろえる |
| 長い別表で応答が切れる | incomplete を検知し、条ごとに分けて投げ直す |
| 支払データが自動で作られる | 計算結果は精算表までで止め、承認を必ず挟む |
| 条件テーブルを手で直してしまう | 変更は契約書の改定に紐づける。手で書いた値を残さない |
上の4行が、この構成の失敗のほとんどです。 どれも「AIが表を埋めてくれた」ように見える点が共通しています。埋まっているかどうかではなく、原文に書いてあるかどうかで見ます。
下の2行も、早く効いてきます。 支払の自動実行は最初から作らないこと。条件テーブルを手で直す運用も、一度許すと、どの値が契約書から来たものか分からなくなります。
09セキュリティ・AIガバナンス上の注意点
この構成で扱うデータ: 取引先ごとの販売奨励金の率と条件、販売実績と返品、取引先の名称と取引規模です。契約書には、奨励金以外の条項も含まれています。
- 取引先ごとの率は、他の取引先に知られてはいけない情報です … 条件テーブルは、全取引先の率が1つの表に並んだものになります。営業の誰もが見られる場所に置かず、 閲覧を担当者と承認者に限ります
- 外部のAIへ渡すのは、奨励金の条・別表だけにします … 契約書には支払条件、解除、損害賠償、秘密保持などの条項も入っています。前処理で切り出すのは、費用のためだけではありません
- 契約書の秘密保持条項を確認してください … 第三者への開示を禁じる定めがあれば、外部のAPIへ渡してよいかを法務と確認します。渡せない契約は対象から外し、従来どおり人が読みます
- 支払の実行を自動にしないでください … 出すのは精算表までです。金額の誤りは、そのまま社外への支払になります
- 率や条件の決め方そのものは、この構成では扱いません … 取引先ごとに条件を変えることの妥当性や、条件の設計が適切かという判断は、法務と顧問弁護士の領域です。この構成が出すのは、契約書にそう書かれているという事実と、その条件で計算した金額だけです
- 実績のスナップショットを残す範囲を決めてください … 再現のために明細を保存しますが、これは取引先の販売動向そのものです。保存期間と閲覧の範囲を先に決めます
誤りが起きた場合のリスクは、払いすぎと払い漏れの2つです。 払いすぎは取引先に返してもらう交渉が必要になり、払い漏れは取引先の信頼を損ないます。どちらも、条件テーブルの原文突合と支払の承認という2つの人の関門で止めます。
10まず何から始めるか
1週目:契約書の版をそろえる
取引先80社のうち、奨励金の金額が大きい上位20社について、原契約と覚書の対応をそろえ、どの覚書がいま効いているのかを一覧にします。この20社で、月の奨励金の大半が埋まります。
2週目:10社で条件テーブルを作ってみる
上位20社のうち10社の契約書から奨励金の条・別表を抜き出し、手元のAIサービスで条件テーブルを作らせます。quote が原文と一致しているかを最優先で見ます。 一致していない行があれば、指示の書き方を直します。
3週目:先月の精算を計算し直す
条件テーブルを表計算に写し、先月の実績で10社分の金額を計算します。当時の精算表と合わない行を、締め日、返品、単位、対象商品の順に確かめます。 合わない理由の分布が、そのまま理由コードの設計になります。
4週目:差異の切り分けの規則を決める
理由コードをいくつ持つか、どの順で当てるか、unknown をどう扱うかを決めます。ここが決まらないうちにワークフローを組むと、差額は出るのに誰も切り分けられない状態になります。
2か月目: Make で実績の取得と精算の実行をつなぎ、Python で計算と切り分けを行い、精算表に書き出すところまで作ります。この時点では支払の承認を既存のやり方のまま残します。
3か月目以降: 対象を80社へ広げ、1件13分が何分になったかを実測します。needs_review の残る契約と unknown の多い取引先を毎月数え、どちらも減らせた時点で完成です。
11関連ユースケース
12この仕組みを理解するための記事
13技術仕様の確認日・参考情報
| 確認した内容 | 情報源 | 確認日 |
|---|---|---|
渡したJSON Schemaに沿った応答が常に生成され、required なキーの欠落や enum に無い値を心配しなくてよいとされること。strict を指定して渡すこと。ルートはオブジェクトで additionalProperties は false にすること。すべての項目を required にし、値が無いことがある項目は null との組み合わせで表すこと。拒否されると refusal の欄が入り、出力の上限で切れると response.status が incomplete、incomplete_details.reason が max_output_tokens になること | OpenAI API: Structured Outputs | 2026-09-23 |
入力として渡すファイルは purpose に user_data を使い、input_file という content part で参照すること。参照の方法が file_id、base64 の file_data、Responses API での file_url の3通りであること。各ファイル50MB未満、1回のリクエストの合計も50MBであること。PDFはテキストとページ画像の両方が渡され、その分トークンが増えること。画像を扱えるモデルが必要とされること | OpenAI API: File inputs | 2026-09-23 |
| シナリオが既定で15分ごとに実行されること。実行のしかたが「一定の間隔(分で指定)」「1回だけ」「毎日」「曜日を指定」「毎月の日付を指定」「日付を個別に指定」「オンデマンド」から選べること。最短の間隔は契約プランによること。詳細設定で開始日と終了日を決められ、1日に複数の時刻を登録できること | Make: Schedule a scenario | 2026-09-23 |
契約の解釈と、支払ってよいかどうかの判断は、この構成では代替できません。 本記事は公開仕様で確認できた範囲だけを扱っています。取引先ごとの条件の設計が妥当かという点は、法務および顧問弁護士に確認してください。
実装ステータス:構成例。 公開仕様に基づいて設計した構成であり、当社で実際に構築・検証したものではありません。工数の数値はモデル条件による試算です。
自社の業務に使えるAI活用候補を整理します
このユースケース(UC-0190)についてのご相談はこちらから。
