ooligo
n8n-flow

n8n でベンダー契約の更新通知期限を締め切り前に検知する

Difficulty
中級
Setup time
120min
For
legal-ops
Legal Ops

Stack

契約リポジトリを毎営業日読み取り、各ベンダー契約を解約または再交渉すべき日付、つまり満了日ではなく通知期限を算出し、ライセンス利用率と提示された価格変動を自社のテーブルから取得して、その期限が過ぎる前に「更新する / 再交渉する / 終了する」のブリーフを担当者に通知する n8n フローです。Claude の推論コストは 1 件あたり 0.05〜0.07 USD、n8n の実行回数は月あたり約 22 回です。

ワークフローは apps/web/public/artifacts/contract-renewal-radar-n8n/contract-renewal-radar-n8n.json に含まれます (15 ノード、スケジュールトリガー 1 つ)。必要な 3 つの Postgres テーブルは同じディレクトリの schema.sql にあり、認証情報の設定と 7 ステップの検証手順は _README.md に記載しています。

使うべき場面

ベンダー契約を 40 件以上管理しており、その大半が自動更新で、Ironclad、Docusign Agreement Manager、あるいは満了・更新メタデータを API で公開している同等のリポジトリに構造化された日付として保管されている場合です。ベンダー支出の責任者がいて、誰も承認していない価格で契約が更新されたときに説明責任を負う立場にあることも前提です。価値があるのはアラートそのものではありません。アラートなら CLM がすでに送っています。価値があるのは、アラートが通知期限に紐づいて届き、担当者が自分で探しに行くはずだった利用率と価格変動の数値を伴い、推奨を明示している点です。これにより意思決定は 3 週間の日程調整ではなく 1 通のメッセージで完結します。

使うべきでない場面

通知期間がどこにも機械可読な形で記録されていないなら見送ってください。このフローは満了日と通知期間から期限を計算できますが、PDF の中の通知条項を読み取ることはできません。その項目が大半のレコードで空のリポジトリでは、ほぼ全面的に 90 日というデフォルト仮定の上に成り立つレーダーができあがります。まずその条項を抽出することが別のプロジェクトであり、実際に必要なのはそちらです。契約が 40 件程度に満たない場合も見送ってください。1 契約あたり 4 件のカレンダーリマインダーを並べたスプレッドシートのほうが明確に優れています。調達部門がすでに機能している更新カレンダーを運用しているなら、これは不在のプロセスを置き換えるものであって、機能しているプロセスを置き換えるものではありません。また通知条項が暦日ではなく営業日で書かれていて、それに合わせてアラート段階を前倒しする気がないなら見送ってください。このフローは暦日で数えるため、算出される期限は実際の期限より後ろになります。

セットアップ

まず schema.sql を実行します。CLM が保持しない支出・利用データを格納する vendor_context、監査証跡と重複排除キーを兼ねる renewal_radar_log、そして人間が記入し成功指標が誠実に読める唯一のテーブルである renewal_decisions が作成されます。次に JSON をインポートし、README に従って 4 つのプレースホルダー認証情報を接続し、ワークフローのタイムゾーンが通知期限を規定するタイムゾーンと一致していることを確認してください。

実際に重要な設定は 2 つの Code ノード冒頭にある少数の定数です。Normalize + Compute Notice WindowRENEWAL_FIELD_NAMES は、Ironclad のレコードフィールドの表示名をフロー内部の構造にマッピングします。Ironclad のレコードメタデータのフィールド ID はテナントごとに異なるため、誰も動作するデフォルト値を用意できない唯一の設定です。DEFAULT_NOTICE_DAYS は 90 で、TIERS は期限の 90 日前、60 日前、30 日前、7 日前に通知を発火させます。Score + Route では、利用率の帯 (0.40 と 0.70)、価格上昇のしきい値 (10%)、エスカレーション下限 (年間 50,000 USD) が、何を推奨し誰に届けるかを決めます。

これらのしきい値は 2 回調整することを見込んでください。デフォルトで運用を開始し、1 四半期分のルーティング結果をチームが実際に下した判断と突き合わせ、帯をそれに合わせて動かします。

フローの動作

Daily Radar Run — 07:00 Weekdays が発火します。Load Radar State が、どの契約がどの段階ですでに通知済みかを読み取ります。Ironclad — Record SchemaRENEWAL_FIELD_NAMES に対してテナントのフィールド ID を解決し、続いて Ironclad — List Recordspublic.records.readRecords スコープで /public/api/v1/records の締結済み契約リポジトリを走査します。Docusign — List Agreements は Agreement Manager API に対して同じことを行い、Iris による抽出が expiration_daterenewal_typerenewal_notice_datetotal_agreement_value を provisions として返します。Merge Contract Sources が両方を連結します。片方のノードを無効化すれば単一リポジトリで運用できます。

Normalize + Compute Notice Window が実際の処理の中心であり、モデル呼び出しではなく意図的に地味な算術で構成しています。両ソースを 1 つの構造に写像し、notice_deadline を満了日から通知期間を差し引いた値として、UTC の暦日境界上で計算します。夏時間が法的な日付を動かせないようにするためです。90 日の対象期間内にある契約に段階が付与され、それ以外は除外されます。続いて New Tier Only が現在の段階ですでに通知済みの契約を除外します。これが同じ 40 件を毎営業日投稿し続けることを防いでいます。

Load Spend + Usagevendor_context から契約シート数と稼働シート数、前期および提示更新価格を取得します。Claude — Renewal Briefclaude-sonnet-5 に対して Messages API を 1 回呼び出し、adaptive thinking を medium effort で実行して、推奨、60 語以内の根拠、最大 3 点の交渉材料、そして必要だったのに受け取れなかったフィールドの明示的な一覧を含む JSON ブリーフを返します。system prompt は、渡された JSON に存在しない数値の使用を禁じています。これこそが AI の作成する商務ブリーフを危険にする失敗モードだからです。

Score + Route は利用率と価格変動から推奨を決定論的に算出し、そのうえでモデルの回答と突き合わせます。ルートを決めるのは算術であり、モデルは文章を書く役割です。両者の不一致自体がルーティング信号となり、2 つの推奨を並べて表示したうえで契約を法務に回します。Needs Legal Escalation#legal-ops-renewals#vendor-renewals に分岐し、どちらの経路も Upsert Radar Log で終わります。このノードは contract_id で upsert するため、部分的な失敗後の再実行も安全です。

コストの実態

ブリーフ 1 件あたり、入力 5,000〜8,000 トークン、出力 800〜1,500 トークンの Sonnet 5 呼び出しが 1 回、これに出力として課金される adaptive thinking が加わります。入力 100 万トークンあたり 3 USD、出力 100 万トークンあたり 15 USD の定価では 0.05〜0.07 USD です。400 契約のポートフォリオでは通常、月に 30〜40 件が段階の境界を越えるため、推論コストは 2〜3 USD になります。

n8n 側は通常の従量課金の経済性を逆転させるため、理解しておく価値があります。契約をまたぐファンアウトは単一のワークフロー実行の内部で起こるため、営業日ごとの cron でも月に約 22 実行しか消費しません。n8n Cloud Starter は月額 24 EUR で 2,500 実行が含まれるので、エントリープランの 1% 未満です。2026 年時点ですべての Cloud プランでワークフロー数とユーザー数は無制限です。

これに対し、中規模契約で意図しない自動更新が 1 件発生すれば、最低でも 4 桁のコストになります。このフローで興味深いのは経済性ではなく、運用上の規律のほうです。

成功指標

renewal_decisions に記録された更新判断のうち、decided_onnotice_deadline 以前であるものの割合を追跡してください。クエリは schema.sql の末尾にあります。基準値は、現時点でウィンドウが閉じる前に判断されている割合です。これに着手するチームの多くにとって、誰も測ったことのない数値なので、改善を主張する前に 1 四半期かけて記録してください。

送信したアラート数を指標にしてはいけません。誰も読まないメッセージを 40 通投稿するフローはその指標で満点を取りますが、何も変えていません。併せて見るべき二次指標は、判断されないまま 7 日段階に到達する契約の件数です。2 四半期目になってもこの件数が減っていないなら、問題はツールではなく責任分担にあります。

代替手段との比較

Ironclad と Docusign に組み込まれた更新アラートとの比較。これらは確実に発火し追加費用もかかりませんが、ある日付に通知してそこで止まります。ベンダーの管理コンソールにあるライセンス利用率にも、メールの中にある見積にも到達できず、推奨も出さないため、担当者は結局自分で判断材料を組み立てることになります。この組み立てこそが後回しにされる工程です。チームがネイティブのアラートに一貫して対応できているなら、ネイティブのアラートを使ってください。

SaaS 管理プラットフォーム、つまり Zylo、Productiv、Vendr の系統との比較。これらは利用テレメトリと更新トラッキングを製品として提供するので、利用データの面では確かにこのフローより多くを得られます。一方で相応の費用がかかり、独自の統合プロジェクトを必要とし、それでも担当者に渡されるのは判断ではなくダッシュボードです。このフローが正しい選択になるのは、契約データはすでにあり、欠けているのがラストワンマイルだけである場合です。

cron で動く自作スクリプトとの比較。ロジックは同じですが、リトライ、認証情報のローテーション、ページネーション、可観測性を自分で抱えることになります。これを n8n で作る具体的な理由は、Anthropic 呼び出しにおけるノード単位のリトライ制御と、視覚的な実行ログです。新しい契約の構造が Normalize ノードを壊したとき、どのレコードが原因かを目で確認できます。

注意点

通知期間の欠落は、このフローを静かに壊す唯一の値です。 ガード: Normalize + Compute Notice Window は、通知期間が null または負の値の場合、0 ではなく DEFAULT_NOTICE_DAYS (90) として扱い、notice_source: 'assumed' を付与します。0 をデフォルトにすると通知期限が満了日そのものになり、契約が更新される当日まで安全と表示されてしまいます。仮定値に基づくカードはすべて 1 行目にその旨を記載し、仮定値の契約は金額にかかわらず強制的に法務へ回されます。

Ironclad のレコードフィールド ID はテナント固有であるため、固定のマッピングは他社のインスタンスで静かに失敗します。 ガード: フローは実行時にレコードスキーマのエンドポイントを呼び出し、満了日または通知期間のフィールドを解決できない場合は schema_field_missing を投げます。ここでは導入時に大きな音を立てて失敗するのが正解です。代替となるのは、きれいに動いて何も見つけないレーダーです。

毎日の再通知は人にチャンネルをミュートさせる訓練となり、まさにこのフローが防ごうとしている期限超過を引き起こします。 ガード: New Tier Only ノードが renewal_radar_log.last_tier_notified を読むため、各契約は段階の境界ごとに 1 回だけ投稿されます。90 日間で 60 通ではなく 4 通です。

モデルは、利用データが一度も読み込まれなかった契約についても流暢なブリーフを書けてしまいます。 ガード: Score + Route は推奨を算術で計算し、モデルの回答は参考として扱います。context_complete が false の場合、決定論的な経路は renegotiate を返し、決して renew を返しません。データがないことは現行条件が妥当であることの証拠ではないからです。両者が不一致の場合は model_agrees: false となり、双方の回答を表示したうえでエスカレーションを強制します。

アラート疲れの静かな親戚として、誰の名前も付いていないブリーフが届く問題があります。 ガード: owner_email はリポジトリから引き継がれ、担当者チャンネルのカードに表示されます。担当者が登録されていない契約も投稿されますが、エスカレーションチャンネルに届きます。所有者不在の更新は、予算の問題である前に Legal Ops の問題だからです。

スタック

オーケストレーションは n8n が担います。Claude Sonnet 5 が Anthropic の Messages API 経由でブリーフを作成します。IroncladDocusign が契約リポジトリで、どちらか一方だけでも成立します。Postgres が支出・利用コンテキスト、レーダーログ、判断記録を保持します。Slack が担当者への通知と法務へのエスカレーションを受け取ります。

これは contract lifecycle management の上に載る運用レイヤーです。何かを動かす前に、リポジトリが整備され通知期間がそこに入っている必要があります。新規ベンダーを ベンダーデューデリジェンスのワークフロー で受け入れることが、今後これらの項目を埋まった状態に保ちます。このフローが引き受けるのは、誰もそれをしていなかった時期に締結した契約のほうです。

Files in this artifact

Download all (.zip)