ooligo
n8n-flow

n8nによるコンポジット顧客ヘルススコア

Difficulty
上級
Setup time
120min
For
revops · csm
RevOps

Stack

Gainsightのデフォルトヘルススコアは、たまたま最初に接続したインテグレーションから最も速くロードされるデータで重み付けされた色付きのピルです。その結果、スコアはチャーンではなくデータに向かってドリフトします。このワークフローは、CSポッドが実際に説明できるコンポジットに置き換えます:各アカウントの28日間ベースラインに対して測定された使用状況、リーセンシー減衰でスコア付けされたCSMアクティビティ、そして明示的な信頼度フロアを持つGongトランスクリプトから導出されたセンチメントシグナルです。コンポジットには何が変動したかを示すClaudeが生成した1文の説明が付属するため、アカウントレコードを開いたCSMは「62、黄色」だけでなく「3回の最近のミーティングにもかかわらず製品使用量が28日間ベースラインを38%下回っているため、コンポジットが14ポイント低下」と表示されます。その文こそがスコアをアクション可能にするものです。

アーティファクトバンドルは apps/web/public/artifacts/customer-health-score-n8n/ にあります。n8nエクスポートは customer-health-score-n8n.json、認証情報と検証ガイドは _README.md です。スケジュールを有効化する前に両方を必ず読んでください。

使う場面

このワークフローは、CSオーグが少なくとも100アカウントを管理しており、Gainsightまたは同様のCSPをライトバックターゲットとして使用し、Gong(またはHTTPノードを向け直せる同等の会話インテリジェンスツール)を持ち、チームに対する重み付けの選択を説明できるCSMまたはRevOpsリードがいる場合に使用してください。このモデルは過去12ヶ月のグランドトゥルースチャーンデータがある場合に最も有用です — それが重みのバックテストに使うものです。バックテストデータなしでは推測であり、推測に基づくコンポジットスコアはGainsightが提供するスコアと何ら変わりありません。

また、既存のヘルススコアへの信頼が失われた瞬間にも適しています。最も一般的なシグナルは、CSMがQBRの準備でスコアを無視して自分で生の使用データを引き出すことです。その場合、問題は「どうすれば彼らにスコアを使ってもらえるか」ではなく「スコアが何をすれば使ってもらえるか」です。このフローの答えは:数値とベースラインを引用し、最大の変動要因を表面化することです。それが「why-changed」文が提供するものです。

使わない場面

アクティブアカウントが約50件未満の場合はスキップしてください。そのスケールでは、CSMがバッチ待機ノードのデバッグにかかる時間よりも自分でアカウントを読む方が速く、モデルは少数サンプルのノイズに過学習します。使用テレメトリがGainsightで信頼できない場合はスキップしてください — アカウントごとのベースラインはイベントが一貫してタグ付けされている場合のみ機能し、汚れたデータの上にフローを構築するとその汚れを継承して増幅します。CSオーグにチャーンの明確な定義とラベル付き履歴がない場合はスキップしてください;なければ重みをバックテストできず、バックテストされていないモデルは数値の権威を持ちながら機能しないため、モデルがない状態より悪いです。GongインスタンスでトランスクリプトがONになっていない場合はスキップしてください — センチメントはすべてのアカウントでニュートラルに崩壊し、センチメント重みの20%が無駄になります。最後に、チームの実際の問題がCSMがスコアに基づいてアクションするワークフローを持っていないことである場合はスキップしてください;より正確なスコアに実行計画が伴わなければ何も変わりません。

セットアップ

セットアップは apps/web/public/artifacts/customer-health-score-n8n/_README.md に端から端まで文書化されています。短縮版:n8nで「設定 → ファイルからインポート」でJSONをインポートし、5つのプレースホルダー認証情報(Postgres、Gainsight、HubSpot、Gong、Anthropic、Slack — 合計6つ)を作成し、ライトバックノードがターゲットとする7つのGainsightカスタムフィールドをプロビジョニングし、スケジュールを有効化する前に単一のカナリアアカウントに対して8ステップの検証シーケンスを実行します。クリーンなn8nインストールから最初のライトバックまでの時間は約2時間で、そのほとんどはHubSpot Private Appトークンの待機とGainsightカスタムフィールドのプロビジョニングが反映されるまでの待機です。

accounts_in_scope テーブルがセグメントごとの重み付けの場所です。エンタープライズアカウントは更新を促す関係性ヘルスのためにアクティビティを0.4、センチメントを0.3で重み付けするかもしれません;PLGアカウントはプロダクトがディールであるため使用状況を0.7で重み付けするかもしれません。重みをハードコードされた定数ではなくテーブルの列として持つことが、反復できるモデルと6ヶ月ごとに置き換えるモデルの違いです。

フローが実際に行うこと

cronは America/New_York の02:00に毎晩起動します。Pull Accounts In Scopelast_scored_at が20時間以上前のアカウントを最大500件引き出します(このギャップはリトライ時の二重スコアを防ぎます)。Batch Accounts (25/group) は並列API呼び出しがプロバイダーのレートキャップを超えないようにチャンク化します。バッチごとに3つのブランチが並行して実行されます:GainsightはGong28日間の使用量ロールアップを返し、HubSpotは過去90日間のエンゲージメントを返し、Gongは最大30日間の通話メタデータを返します。

Score Usage (vs baseline) は現在の28日間イベント数とアカウントの保存されたベースラインの比率を計算します。比率1.0は100にマップされ、0.5以下は0にマップされ、その間は線形です。追加のガードが1つあります:過去28日間のユニークユーザー数が3を下回ると、イベント量に関わらずスコアが40にキャップされます — 単一ユーザー依存はイベント数だけでは見えないチャーンリスクです。

Score Activity (recency-weighted) はエンゲージメントリストを走査し、21日間の半減期で指数関数的減衰を適用します。昨日のミーティングは5ポイント、21日前のミーティングは2.5ポイント、60日前のミーティングは約0.3ポイントです。メールは1、通話は4、ノートは0.5で重み付けされます。重み付きの合計は0〜100にマップされ、ハードフロアがあります:過去60日間にミーティングがゼロの場合、スコアは25にキャップされます。

Claude — Score Sentiment はアカウントごとに最新の最大6件の通話トランスクリプトに対して claude-sonnet-4-6 を実行し、トランスクリプトごとに最大4,000文字を上限とします。システムプロンプトは厳密なJSONを強制し、トランスクリプトが200ワード未満または単一話者のモノローグのように見える場合はconfidenceを0にして返すよう要求し、捏造されたシグナルを禁止します。Score Sentiment (with confidence floor) は信頼度が0.4を下回るすべての結果をニュートラルな50に落とします — モデルからの推測は、わからないと認めるより悪いです。

Compute Composite は3つのサブスコアとアカウントごとの重みを取り、コンポジットとバンド(green ≥ 75、yellow ≥ 50、red < 50)を生成します。Lookup Previous Scoreaccount_health_history テーブルと結合します。絶対デルタが5ポイント以上の場合、Claude — Why-Changed Sentence は最大の変動要因とその具体的な数値を示す1文の説明を生成します;そうでない場合は決定論的なフォールバック文を使用します。ペイロードは7つのGainsightカスタムフィールドにライトバックされ、(account_id, date_trunc('day', scored_at)) をキーとする ON CONFLICT 句でリトライが冪等になるように account_health_history に永続化されます。レッドバンドへのドロップ、または-10以上のデルタは #cs-health-alerts のSlackアラートにwhy-changed文が引用されてファンアウトします。

コストの実態

アカウントごとに毎晩のフローは3つの外部読み取り呼び出し(Gainsight使用状況、HubSpotエンゲージメント、Gong通話)、1つのClaudeセンチメント呼び出し(最大512トークン出力、トランスクリプトに対して約6kトークン入力)、デルタが5ポイントを超えた場合のオプションのClaude why-changed呼び出し(最大200トークン出力、約400トークン入力)、1つのGainsightライトバック、2つのPostgresクエリを行います。Sonnet 4.6が入力100万トークンあたり約3ドル、出力100万トークンあたり15ドルとして、センチメント呼び出しはアカウントあたり約0.018ドル、why-changed呼び出しはトリガーされた場合約0.005ドルです。why-changedブランチをトリガーする約30%の500アカウントの場合、Anthropicの総費用は1晩あたり約9.75ドル、つまり月約295ドルです。Gong読み取りはより大きな制約です:ワークスペースあたり毎秒3回の呼び出しで、500アカウントは最低でも167秒のAPI時間を必要とするため、バッチごとの待機ノードと25アカウントのバッチサイズはそれに合わせてサイズ設定されています。n8n CloudのSmallエグゼキューターで500アカウントのエンドツーエンドランタイムは18〜25分です。オペレーションコスト:四半期ごとにCSM/RevOpsが約2時間でバックテスト結果をレビューして重みを再チューニングする、これがスコアが維持コストを正当化するオペレーションコストです。

成功の見え方

最初の90日間で4つの数値を監視してください。まず、バンドの変化がCSMの見方と一致したアカウントの割合 — 最初の1ヶ月は毎週チームに調査し、比較します。目標:4週目までに70%以上の一致。50%未満はモデルではなく重みが間違っていることを意味します。2番目は、スコアが実際のチャーンにどれだけリードタイムを与えるか — 次の2四半期のすべてのチャーンについて、スコア軌跡を振り返り、チャーン通知の前にスコアがレッドに落ちた日数を測定します。目標:中央値リードタイム30日以上。3番目は、why-changed文の品質 — 毎週20文をサンプリングし、アクション可能/正確だが曖昧/間違いとして評価します。目標:6週目までに80%以上アクション可能。4番目は、Slackアラートのフォールスアラートレート — フォローアップアクションを引き起こさなかったアラートを数えます。30%を超える場合、アラートしきい値を-10から-15に引き上げ、バンドドロップブランチにより多くの負荷を担わせます。

代替手段との比較

デフォルトは Gainsight Scorecards 2.0 プロダクトです。これはメジャーを取り込み、ルールを適用し、ロールアップを表面化することに関しては本当に優れています — ただし、このフローでは行えない3つのことを行います。インテグレーションを構築しなければLLMトランスクリプト分類の結果をロールアップに入れられず、アカウント自身の歴史的ベースラインに対してネイティブに推論しない(アカウントごと、セグメントごとにルールを書く必要がある)、スコアを生成するがセンテンスを生成しません。CSオーグがスコアを必要としてCSMがそれを解釈することを信頼する場合、Scorecards 2.0の方が手間が少なく良い選択です。問題がCSMがそれを解釈しないことである場合、why-changed文が重要な変化であり、それがビルドを正当化するものです。

2番目の代替手段は LambdaまたはEC2上のcronでDIY Pythonスクリプト です。これはn8nフローよりも最初のバージョンを書くのが速いですが、引き渡しが難しく、視覚的にデバッグが難しく、コードとして認証情報ローテーションの負担を担います。n8nバージョンは生の柔軟性を認証情報UI、すぐに使えるリトライセマンティクス、エンジニアリングエスコートなしにCSMリードが読めるビジュアルフローと交換します。常駐のプラットフォームエンジニアがいる場合はDIYを選び、そうでない場合はn8nフローを選びます。

3番目の代替手段は Catalyst、ChurnZero、またはVitallyの組み込みヘルススコア です。これらは独自のスコアリングエンジンを持つ良いプロダクトですが、そのCSPに標準化していることを前提とします。すでにCatalystのお客様であれば、Catalystのスコアを使用してwhy-changed Claude呼び出しをCatalyst Actionとして追加してください;数学は同じです。このワークフローは、野生のほとんどのチームがまだGainsightを使用しており、Gainsightライトバックがバンドルを価値あるものにする部分だから存在します。

注意点

  • ガベージ使用タグ付けは自信を持って間違ったスコアを生成する。 Gainsightイベントがプロダクトサーフェスにわたってタグ付けが一貫していない場合、アカウントごとのベースラインは意味がなく、モデルは行動の変化ではなくタグ付けの変化を反映するドロップを表面化します。対策:フローを有効化する前に、過去90日間のアカウントごとのイベント名分布をクエリし、上位5つのイベントタイプが一貫していることを確認します。Pull Accounts In Scope クエリには baseline_usage_28d 列があり、ベースラインが一度計算され、監査され、固定されます — ドリフトするイベント定義に対して毎晩再計算されるのではなく。
  • 短いトランスクリプトでのセンチメント幻覚。 Claudeは制約がなければ50ワードのボイスメールスニペットから自信たっぷりに見えるセンチメント数値を生成します。対策:Claude — Score Sentiment システムプロンプトは200ワード未満または単一話者のモノローグのトランスクリプトには confidence: 0 を要求し、Score Sentiment (with confidence floor) は信頼度が0.4未満のものをニュートラルな50に落とします。センチメントの重み20%は、それらのアカウントではゴミの20%ではなく0%になります。
  • why-changed文が因果関係を捏造する。 重み付き合計のデルタには「原因」がありません;最大の変動要因があるだけです。対策:why-changedプロンプトはサブスコア入力を超えた推測を禁止し、具体的な数値を引用することを要求します。Claudeのレスポンスが空の場合、決定論的フォールバックが実行されるため、Claudeの障害がライトバックをブロックするのではなく文が数値サマリーにダウングレードされます。
  • スケジュールのリトライによる二重履歴書き込み。 リトライされた実行が同じ日に2つの履歴行を挿入する可能性があります。対策:account_health_history(account_id, date_trunc('day', scored_at)) に一意制約があり、Persist HistoryON CONFLICT ... DO UPDATE を使用するため、その日の最新実行が勝ちます。冪等性は02:00の実行が失敗した場合に監査証跡を汚染せずに09:00に再実行できるプロパティです。
  • Slackアラート疲弊。 最初の有効化で20件のレッドバンドアラートが発生すると(最初の夜はすべてのアカウントが50を下回るため)、CSMがチャンネルをミュートするよう訓練されます。対策:最初の有効化では最初の3夜はSlackノードを無効にし、履歴テーブルを埋め、その後再度有効化します。ベースラインが存在するとその後のDelta ≥ 5? チェックがほとんどのノイズをフィルタリングします。

スタック

  • n8n — オーケストレーション、リトライ、認証情報管理、ビジュアルワークフロー
  • Gainsight — 使用テレメトリソースおよび7つのカスタムフィールドの宛先
  • HubSpot — CSMアクティビティ(通話、ミーティング、メール、ノート)ソース
  • Gong — センチメントブランチ用の通話トランスクリプト
  • Claude (Sonnet 4.6) — センチメント分類とwhy-changed文
  • Postgresaccounts_in_scope の重み、account_health_history の監査証跡、冪等性キー
  • Slack — レッドバンドおよび大幅デルタドロップのアラートチャンネル

Files in this artifact

Download all (.zip)