planning-voice-agent-user-interviews について
PostHog の AI 音声エージェントが実施するユーザーインタビューを計画するスキルです。調査目的の確認、対象者の選定と解決、トピックや質問の準備を支援します。
主な機能
- 01自動インタビューの意図確認
- 02コホートや行動による対象者選定
- 03コホートメンバーから連絡先 ID を解決
- 04トピックとエージェントコンテキストの設定
- 05順序付きインタビュー質問の準備
活用シーン
- 01トライアルユーザーへの自動架電の計画
- 02チェックアウトを中断したユーザーへの聞き取り
- 03ヘビーユーザーや離脱リスクのあるユーザーの募集
- 04コホートを固定のインタビュー対象者に変換
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ posthog/ ai-plugin --skill planning-voice-agent-user-interviewsインストール後、Claude Code で/planning-voice-agent-user-interviewsを入力して読み込まれたか確認します。
詳細
音声エージェントによるユーザーインタビューの計画
このスキルを使用するのは、PostHog の AI 音声エージェント(「ロボットインタビュアー」)に、ユーザーインタビューの通話を実際に一巡させたい場合に限ります。計画は UserInterviewTopic として記録され、音声エージェントは後でその内容に沿って、対象者一人ひとりに電話をかけ、質問を進めます。
これは特定のプロダクトであり、汎用的なリサーチ支援ツールではありません。ユーザーがインタビュー対象者を 見つける、または 候補を絞り込む ことだけを希望している場合、人間が実施するインタビューの質問を計画したい場合、あるいはすでに集めたフィードバックを分析したい場合は、このスキルは適切ではありません。その場合は通常のオーディエンス探索/データ作業として対応してください(querying-posthog-data を参照)。必要であれば、音声エージェントの選択肢があることだけを伝えてください。
ステップ 0:音声エージェントを使うフローか確認する
何かを始める前に、ユーザーが本当に AI 音声エージェントにインタビューを実施してほしいのか確認してください。「ユーザーにインタビューしたい」と言及するリクエストの多くは、会話をロボットに任せたいのではなく、話を聞くべき 相手 を見つけたいというものです。
- ユーザーが音声エージェント/ロボットによるインタビュー/自動通話を明確に依頼した場合は、ステップ 1 に進みます。
- インタビュー対象者の特定や順位付けだけを依頼された場合(例:「受信トレイについてインタビューするのに適した人は誰でしょうか?」)は、オーディエンス探索として扱います。通常のクエリで回答し、トピックは作成しないでください。回答の後に、たとえば 「ご希望であれば、PostHog の AI 音声エージェントによる自動インタビューとして設定できます。設定しましょうか?」 と一文添えてもかまいません。
- 意図が曖昧な場合は、まず確認してください。たとえば、「ご希望を確認させてください。どのようなユーザーリサーチをお考えですか?PostHog の AI 音声エージェントに実際にインタビューを実施してほしいですか(対象者に電話をかけ、質問を進めます)?それとも、話を聞くべきユーザーを見つけるだけでよいですか?」
ユーザーが音声エージェントによるインタビューの実施を確認してから、このステップを先に進めてください。
完成したトピックに必要な情報
user-interview-topics-create を呼び出す前に、次の情報を集めてください。
- インタビュー対象者 — 次のうち少なくとも 1 つ:
interviewee_emails— メールアドレスのリストinterviewee_distinct_ids— PostHog の distinct ID のリスト
- 質問のテーマ —
topic(必須の自由記述) - エージェントが会話を進める際の前提 — 任意の
agent_context(追加のシステムプロンプト) - 順に尋ねる質問 — 任意の
questionsリスト
トピックの対象者は作成時点のスナップショットとして保存されます。コホートへのライブリンクはありません。ユーザーがコホートを指定した場合は、user-interview-topics-create の呼び出し前に、エージェントがコホートのメンバーをメールアドレス/distinct ID に解決してください。解決フローと 500 人の上限に関する UX については、ステップ 2 を参照してください。
対象者が指定されていないトピックは API に拒否されるため、最終的に interviewee_emails および/または interviewee_distinct_ids が空でない必要があります。
ステップ 1:意図を明確にする
リクエストが曖昧な場合は、次の点を確認してください。
- どの機能や行動についてですか? 「チェックアウト」は、ボタンのクリック、ページの表示、支払いの送信を指す場合があります。対象を 1 つのイベントに絞ってください。
- 何を知りたいですか? なぜ途中で離脱したのか、何に戸惑ったのか、どのような代替手段を試したのか。目的によって、対象者と質問の両方が変わります。
- どのようなユーザーが対象ですか? ヘビーユーザー(うまく機能している点を把握)、途中離脱したユーザー(導入を妨げている要因を把握)、離脱リスクのあるユーザー(継続利用を損なう要因を把握)、またはその組み合わせです。
ユーザーがすでに回答している場合に限り、これらの質問は省略してください。
ステップ 2:対象者を選ぶ
ユーザーの発言を、次のいずれかのパスに当てはめます。
- コホートを指定している(「当社のパワーユーザー」「先週登録したトライアルユーザー」)—
cohorts-list(またはsystem.cohortsの SQL 検索)を使ってコホートを見つけ、一致していることを確認してから、コホートのメンバーをメールアドレス/distinct_ids に解決します(下記「コホートの解決」を参照)。 - 該当する人の種類を説明しているが、コホートは存在しない — 先にコホートを作成してから(
cohorts-create)解決するか、行動をもとに対象者を見つけるか、どちらにするか提案します(下記を参照)。 - メールアドレスまたは distinct ID を指定している — そのまま受け付けます。コホートの検索はスキップします。
- コホートではなく行動を説明している(「チェックアウトを試したが完了しなかったユーザー」「以前はダークモードを使っていたが、使わなくなった人」)— イベントをクエリして対象者を見つけます(下記を参照)。
- 曖昧な表現をしている(「何人かの顧客」「パワーユーザーを何人か」)— どの方法がよいか確認します。
- 既存のコホートを選ぶ →
cohorts-list - 名前またはメールアドレスで特定の人物を検索する → 検索クエリを指定して
persons-list - 行動をもとにユーザーを見つける → 下記を参照
- メールアドレスのリストを貼り付ける
- 既存のコホートを選ぶ →
各メールアドレスには DRF のメールアドレス検証が適用されます(通常の [email protected] に加えて、表示名形式の Paul D'Ambra <[email protected]> も受け付けます)。
コホートの解決
トピックの対象者は作成時点の状態でスナップショットされます。ユーザーがコホートを選んだら、トピックを作成する前にメンバーリストを interviewee_emails に(メールアドレスのないメンバーは interviewee_distinct_ids に)展開する必要があります。
-
まずコホートの人数を数えます。 低コストのクエリで、次の手順を判断します。
SELECT count() FROM persons WHERE id IN COHORT <cohort_id> -
コホートのメンバーが 500 人以下の場合、メールアドレスを取得します。
SELECT properties.email AS email FROM persons WHERE id IN COHORT <cohort_id> AND properties.email IS NOT NULL LIMIT 500各行を
interviewee_emailsに追加します。重複は除外してください。メールアドレスのプロパティを持たないコホートメンバーは、デフォルトでは含まれません。
persons.id列は人物の UUID であり、SDK の distinct_id ではないため、pdi.distinct_idとの結合なしにinterviewee_distinct_idとして使用することはできません。distinct ID としてのみ存在するメンバーにも連絡する必要がある場合は、先にユーザーに確認してから、明示的に結合してください。 -
コホートのメンバーが 500 人を超える場合、処理を止めてユーザーに確認します。黙って切り詰めたり、サンプリングしたり、別のコホートに切り替えたりしてはいけません。ユーザー自身が選択する必要があります。次の情報を伝えます。
- コホート名と人数(例:「PostHog チームのメンバーは 28,563 人で、上限の 500 人を超えています。」)
- 上限がある理由(「対象者は作成時点の状態でスナップショットされます。また、500 人という上限は、1 つのインタビューキャンペーンを管理しやすくするためのエージェント側の安全策です。バックエンド自体は配列の長さを制限していません。」)
- 選択肢:
- コホートを絞り込む — 実際に対象としたいサブセットを説明してもらいます(例:「エンジニアのみ」「過去 30 日間にアクティブだった人」)。より具体的な HogQL フィルターを作成するか、
cohorts-createを使って、より小さなコホートを作成することを提案できます。 - ランダムにサンプリングする — 件数(例:200 人)を確認し、コホートのクエリに
ORDER BY rand() LIMIT <n>を使用します。「上位」のメンバーではなくランダムに選ばれることを明確に伝えます。 - 選別済みのリストを貼り付ける — ユーザー自身に対象者を選んでもらい、メールアドレスを直接指定してもらいます。
- コホートを絞り込む — 実際に対象としたいサブセットを説明してもらいます(例:「エンジニアのみ」「過去 30 日間にアクティブだった人」)。より具体的な HogQL フィルターを作成するか、
ユーザーと一緒にパスを決めてから、解決をやり直します。明示的な決定がない限り、先に進んではいけません。
-
解決結果をユーザーに伝えます。 解決後、作成前に次のように確認します。「コホート『X』には N 人のメンバーがおり、E 件のメールアドレスと D 件の distinct ID に解決されました(スナップショットのため、後でコホートが変更されても更新されません)。」これにより、スナップショットの仕様を明確にできます。
行動に基づいてユーザーを見つける
ユーザーが話したい相手を行動の特徴で説明した場合は、プロジェクト独自のデータから該当するユーザーを見つけます。
- 適切なイベントを見つけます。
read-data-schemaを呼び出して、プロジェクトに実際に存在するイベントを一覧表示します。トレーニングデータからイベント名を推測しないでください。PostHog のイベント分類はプロジェクトごとに異なります。ユーザーの説明に合う候補イベントを 1 つか 2 つ選びます。複数の候補が考えられる場合は、それらを列挙し、どの行動を対象にするか尋ねます。 - ユーザーをクエリします。 HogQL を使って
execute-sqlを呼び出します。選んだイベントを過去 60 日間に絞り込み、coalesce(person.properties.email, distinct_id) AS idでユーザーごとにグループ化します。これにより、1 つのクエリで 2 種類の行を扱えます。メールアドレスがあるユーザーはそのメールアドレスでグループ化され(interviewee_emailsでそのまま使用できます)、メールアドレスがないユーザーは独自のdistinct_idにフォールバックします(interviewee_distinct_idsで使用できます)。これにより、すべてがジャンクなNoneのバケットにまとめられてORDER BY count() DESCで先頭に並び、サンプル枠を無駄にすることを防げます。ルーティング時には、選択したemail列でどちらかを判別できます(以下を参照)。各テンプレートの集計値(event_count、last_seen、days_since_last_seen)は、ステップ 5 で面談対象者ごとのコンテキストに使用します。<event_name>を選んだイベントに置き換えます。- ヘビーユーザー —
SELECT coalesce(person.properties.email, distinct_id) AS id, person.properties.email AS email, count() AS event_count, max(timestamp) AS last_seen, dateDiff('day', max(timestamp), now()) AS days_since_last_seen FROM events WHERE event = '<event_name>' AND timestamp > now() - INTERVAL 60 DAY GROUP BY id, email HAVING count() >= 5 ORDER BY count() DESC LIMIT 20 - 離脱ユーザー(1、2 回試した後、再び利用していないユーザー)—
SELECT coalesce(person.properties.email, distinct_id) AS id, person.properties.email AS email, count() AS event_count, max(timestamp) AS last_seen, dateDiff('day', max(timestamp), now()) AS days_since_last_seen FROM events WHERE event = '<event_name>' AND timestamp > now() - INTERVAL 60 DAY GROUP BY id, email HAVING count() <= 2 AND dateDiff('day', max(timestamp), now()) > 14 ORDER BY count() ASC LIMIT 20 - 離脱リスクのあるユーザー(以前はアクティブだったものの、現在は利用していないユーザー)—
SELECT coalesce(person.properties.email, distinct_id) AS id, person.properties.email AS email, count() AS event_count, max(timestamp) AS last_seen, dateDiff('day', max(timestamp), now()) AS days_since_last_seen FROM events WHERE event = '<event_name>' AND timestamp > now() - INTERVAL 60 DAY GROUP BY id, email HAVING count() >= 3 AND dateDiff('day', max(timestamp), now()) > 14 ORDER BY days_since_last_seen DESC LIMIT 20
- ヘビーユーザー —
- バランスの取れたサンプルを作成します。 ユーザーが特定のセグメントを指定していない限り、ヘビーユーザー 5 人、離脱ユーザー 3 人、離脱リスクのあるユーザー 2 人を組み合わせると、最も有益な面談ができます。うまくいっている点、導入を妨げている要因、継続利用を損なう要因を把握できます。ユーザーの実際の希望に合わせて人数を調整してください。
各行は email 列に基づいて振り分けます。email が null でない行は interviewee_emails に、email が null の行(つまり、id に distinct_id が入っている行)は interviewee_distinct_ids に入れます。両方を同じトピックに設定できます。各ユーザーの event_count と days_since_last_seen を保持し、ステップ 5 で「過去 60 日間にチェックアウトを 47 回利用し、最後に確認されたのは 2 日前」といったコンテキストを統合できるようにします。
ステップ 3:トピックを記録する
topic は、面談の内容を説明する 1、2 文です。可能であればコンテキストから推測し、ユーザーに同じことを繰り返し尋ねないでください。
例:「トライアルユーザーがコンバージョンしなかった理由を尋ねる」→ topic: "Why trial users didn't convert in the first 14 days"。
ステップ 4:音声エージェントを準備する
エージェントが通話中に実際に行うことは、2 つのフィールドで決まります。トピックを作成する前に、必ず両方について尋ねてください。
必ず確認する:どのような質問をしたいですか?
questions は、エージェントが順に進める質問のリストです。台本ではなく、話の手がかりとして使います。エージェントは表現を適宜調整します。自由回答形式にしてください。
- ✅ 「PostHogを試してみようと思ったきっかけは何ですか?」
- ❌ 「PostHogは気に入りましたか?」
ユーザーが元の依頼ですでに質問を挙げている場合は、それを使い、確認してください。それ以外の場合は、明示的に「エージェントにどのような質問をしてほしいですか?」と尋ねてください。
ユーザーが思いつかない場合は、topic に基づく自由回答形式の質問を3〜5個提案し、作成前に確認してもらってください。
このフィールドはAPI上では任意ですが、黙って省略してはいけません。質問のないインタビューは、役に立たないことがほとんどです。
調査目的別の質問テンプレート:
- ユーザーが離脱した理由/解約した理由:
- 「最後に[feature]を試したときのことを教えてください。何をしようとしていましたか?」
- 「何が起きたのか、順を追って教えてください。」
- 「何を期待していましたか?実際にはどうなりましたか?」
- 「やめた、または続けないと決めたきっかけは何ですか?」
- 「[feature]を定期的に使うには、何が変わる必要がありますか?」
- ヘビーユーザーが機能を気に入っている理由:
- 「[feature]をどのように使っているか教えてください。どのような問題を解決できますか?」
- 「普段のワークフローを順を追って教えてください。」
- 「[feature]がなかったら、どうしますか?」
- 「初めて試したとき、使わないことになりかけた要因は何ですか?」
- 「違う動作をしてほしいと思うことを、ひとつ挙げるとしたら何ですか?」
- まだ機能を試していない理由:
- 「製品で[feature]を見かけたことはありますか?」
- 「試すのをためらった理由は何ですか?」
- 「試す価値があると思うには、どのような条件が必要ですか?」
必ず提案する:インタビューの指針となる追加のコンテキスト
agent_context は任意ですが、ここに数文加えるだけで会話の質が大きく向上します。必ず、次のようにユーザーに情報提供の機会を提示してください。
「エージェントに伝えておきたい追加のコンテキストはありますか?トーン、避けるべきこと、インタビュー対象者の背景などがあると、会話の指針になります。任意です。」
役立つコンテキストの種類:
- トーン:「親しみやすく会話的に」「前置きは省略してください。10分間の通話です」
- 制約:「機能の提供を約束しない」「価格について話さない」
- エージェントが把握しておくべき背景:「ユーザーはScaleプランを解約したばかりです。共感を示してください」「この人は6か月前にPostHogを試し、すぐに使わなくなりました」
- ペルソナ:「あなたはPostHogのプロダクトリサーチャー、Samです」
ユーザーが断った場合は、そのままで問題ありません。agent_context は空のままにして続けてください。
user-interview-topics-create の呼び出し
必要な情報が揃ったら:
{
"topic": "Why trial users churned in week 2",
"interviewee_emails": ["[email protected]", "[email protected]"],
"interviewee_distinct_ids": ["distinct-id-with-no-email"],
"agent_context": "Be warm. The interviewee just churned — don't pitch.",
"questions": [
"What were you hoping PostHog would help with?",
"Where did you get stuck?",
"What would have made you stay?"
]
}
作成後、返されたトピックIDを取得してください。Step 5で使い、音声エージェントに引き継ぐ際にも必要です。
Step 5:任意でインタビュー対象者ごとのコンテキストを追加する
トピックレベルのagent_contextは、すべてのインタビュー対象者に適用されます。個々のインタビュー対象者について、その人との会話に反映すべき具体的な情報がユーザーにある場合は、user-interview-topics-interviewees-createを使用して、インタビュー対象者ごとの行として追加してください。これは任意です。ほとんどのトピックでは必要ありません。
各行には、interviewee_identifier(親トピックのターゲティングに含まれるメールアドレスまたは個別IDのいずれかと一致する必要があります)とagent_context文字列を指定します。トピックとインタビュー対象者の組み合わせごとに、行は最大1つです。行が0件でもかまいません。
インタビュー対象者ごとのコンテキストの例:
- 「リプレイ製品は使っているが、要約機能は一度も使ったことがない」
- 「先月Scaleプランを解約。共感を示し、売り込みはしない」
- 「創業者で、技術にとても詳しい。基本的な製品説明は省略」
Step 4が成功した後、ユーザーに「インタビュー対象者ごとのコンテキストも追加しますか?個々の人の背景が大きく異なる場合に役立ちます。行を口頭で指定するか、CSVを貼り付けられます。」と尋ねてください。
Step 2で行動クエリを使って対象者を見つけた場合は、すでに個人ごとのコンテキスト(使用回数、非アクティブ期間)が得られています。それを活用してください。たとえば、ヘビーユーザーには"過去60日間にcheckoutを47回使用。最後に確認されたのは2日前"、離脱者には"18日前にcheckoutを1回試したが、その後は一度も戻っていない"のように記述します。
CSV 入力の受け付け
ユーザーが CSV を貼り付けた場合、identifier,context の 2 列を想定します。ヘッダー行があってもなくてもかまいません。例:
[email protected],uses replay but never summarization
[email protected],founder; very technical; skip product basics
または、ヘッダー付きの場合:
identifier,context
abc-distinct-id-1,churned from Scale last month — be empathetic
CSV を解析し、取得した topic_id を使って各行を作成します。行数が 2、3 行を超える場合は、user-interview-topics-interviewees-bulk-create を優先してください。このツールは (interviewee_identifier, agent_context) の items 配列を受け取り、1 回のリクエストで最大 500 行を作成します。また、すでに存在するペアについては inserted_count、skipped_count、skipped_identifiers を返します。1 行の場合は user-interview-topics-interviewees-create を使用します。空白行はスキップします。コンテキストのセル内にあるカンマは、標準的な CSV の規則に従って引用符でエスケープしてください。
ある行の識別子が親トピックの interviewee_emails または interviewee_distinct_ids に含まれていない場合は、作成前にユーザーに警告してください。音声エージェントは完全一致する文字列でコンテキストを検索するため、識別子が一致しないと実行時に無視されます。
エッジケース
- 行動クエリに一致するユーザーがいません。 イベントが発火していない、日付範囲が狭すぎる、または人物プロパティとしてメールアドレスを取得したユーザーがいない可能性があります。日付範囲を広げる、別のイベントを試す、またはコホート/明示的なメールアドレスに切り替える方法を提案してください。
- 一致したユーザーはいるものの、メールアドレスがあるユーザーが少数です。 PostHog には SDK が取得したデータが保存されます。一致したユーザーのうち、人物プロフィールにメールアドレスがあるユーザーがわずかであれば、件数を伝え、少ないサンプルを使用するか、
interviewee_distinct_idsに切り替えるか(エージェントはアプリ内配信を通じて引き続き連絡できます)、行動クエリをスキップしてユーザーがメールアドレスを直接貼り付けるか、確認してください。 - イベント名が曖昧です。
read-data-schemaが複数の候補(例:checkout_started、checkout_completed、checkout_abandoned)を返した場合は、件数とともに候補を一覧表示し、理解したい行動をユーザーに選んでもらいます。黙って選択しないでください。 - ユーザーが離脱したユーザーのみ(または 1 つのセグメントのみ)にインタビューしたい場合。 実施できますが、トレードオフを伝えてください。離脱したユーザーだけにインタビューすると、何がうまくいっていないかは分かりますが、何がうまくいっているかは分かりません。サンプルを絞る理由がユーザーにない限り、比較のために成功したユーザーを 2~3 人含めることを推奨してください。
このスキルの対象外
- 録音済みのインタビューをアップロードすること — それには別の
UserInterviewモデルを使用します(音声ファイルを指定してuser_interviews_createを実行します)。フローもモデルも異なります。 - 既存のトピックを一覧表示すること —
user-interview-topics-listがsearch、limit、offsetを使って直接処理します。スキルは不要です。 - インタビュー後にトランスクリプトを分析すること — ここでは対象外です。録音済みの
UserInterviewフローで扱います。