Planification d'entretiens utilisateurs avec agent vocal
Utilisez cette skill uniquement quand quelqu'un veut que l'agent vocal IA de PostHog — un « interviewer robotisé » — conduise réellement une série d'appels d'entretiens utilisateurs. Le plan est capturé dans un UserInterviewTopic que l'agent vocal exécute ensuite, en appelant chaque personne ciblée et en travaillant sur les questions.
C'est un produit spécifique, pas un assistant de recherche générique. Si l'utilisateur veut seulement trouver ou présélectionner des personnes à interviewer, préparer des questions pour un entretien qu'un humain mènera, ou analyser des retours qu'il a déjà, ce n'est pas la bonne skill — traitez cela comme une découverte d'audience ordinaire / du travail sur les données (voir querying-posthog-data) et, au maximum, mentionnez que l'option agent vocal existe.
Étape 0 : Confirmer que c'est le flux agent vocal
Avant toute chose, assurez-vous que l'utilisateur veut vraiment que l'agent IA mène les entretiens. Beaucoup de requêtes qui mentionnent « interviewer des utilisateurs » concernent vraiment la découverte de qui parler, pas la remise de la conversation à un robot.
- Si l'utilisateur a explicitement demandé l'agent vocal / les entretiens robotisés / les appels automatisés, passez à l'étape 1.
- S'il a seulement demandé à trouver ou classer les utilisateurs à interviewer (par ex. « qui serait un bon candidat pour un entretien sur la boîte de réception ? »), traitez-le comme une découverte d'audience : répondez avec des requêtes normales et ne créez pas de topic. Vous pouvez ajouter une offre d'une ligne après, par ex. « Si vous voulez, je peux les mettre en place comme des entretiens automatisés menés par l'agent vocal IA de PostHog — vous le voulez ? »
- Si l'intention est ambiguë, posez d'abord une question, par ex. « Une vérification rapide : quel genre de recherche utilisateur est-ce, et voulez-vous que l'agent vocal IA de PostHog mène réellement les entretiens (il appelle les gens et travaille sur vos questions) ? Ou vouliez-vous juste que je trouve les bons utilisateurs à qui parler ? »
Continuez au-delà de cette étape uniquement une fois que l'utilisateur a confirmé qu'il veut que l'agent vocal mène les entretiens.
Ce qu'un topic complet requiert
Avant d'appeler user-interview-topics-create, rassemblez ceci :
- Qui interviewer — au moins un de :
interviewee_emails— liste d'adresses e-mailinterviewee_distinct_ids— liste d'ID distincts PostHog
- Ce qu'il faut demander —
topic(texte libre obligatoire) - Comment l'agent doit cadrer la conversation — facultatif
agent_context(invite système supplémentaire) - Les questions à traiter — liste facultative
questionsordonnée
Les topics capturent leur audience au moment de la création — il n'y a pas de lien de cohort en direct. Si l'utilisateur nomme une cohort, vous (l'agent) résolvez les membres de la cohort en e-mails/ID distincts avant d'appeler user-interview-topics-create. Voir l'étape 2 pour le flux de résolution et le plafond UX de 500 membres.
L'API rejette les topics sans ciblage, donc interviewee_emails et/ou interviewee_distinct_ids doivent finir non-vides.
Étape 1 : Clarifier l'intention
Si la requête est vague, posez :
- Quelle fonctionnalité ou comportement ? « checkout » pourrait être le clic du bouton, la vue de page ou la soumission de paiement — réduisez à un événement.
- Que voulez-vous apprendre ? Pourquoi ils ont rebondi ? Qu'est-ce qui les a confus ? Quelles alternatives ont-ils essayées ? L'objectif façonne à la fois l'audience et les questions.
- Quel genre d'utilisateurs ? Utilisateurs intensifs (ce qui fonctionne), abandons (ce qui bloque l'adoption), utilisateurs à risque (ce qui casse la rétention), ou un mélange.
Ignorez ces questions uniquement si l'utilisateur y a déjà répondu.
Étape 2 : Choisir l'audience
Mappez ce que l'utilisateur a dit à l'un de ces chemins :
- Ils ont nommé une cohort (« nos utilisateurs puissants », « inscriptions d'essai la semaine dernière ») — utilisez
cohorts-list(ou une recherche SQLsystem.cohorts) pour trouver la cohort, confirmez la correspondance, puis résolvez les membres de la cohort en e-mails/ID distincts (voir « Résoudre une cohort » ci-dessous). - Ils ont décrit le genre de personne mais aucune cohort n'existe — offrez de créer la cohort en premier (
cohorts-create), puis de la résoudre, ou retombez sur la recherche de personnes par comportement (voir ci-dessous). - Ils ont donné des adresses e-mail ou des ID distincts — acceptez-les directement. Ignorer la recherche de cohort.
- Ils ont décrit un comportement, pas une cohort (« utilisateurs qui ont essayé checkout mais n'ont pas terminé », « personnes qui utilisaient le mode sombre et qui ont arrêté ») — trouvez-les en interrogeant leurs événements (voir ci-dessous).
- Ils ont été vagues (« quelques clients », « certains utilisateurs puissants ») — demandez ce qu'ils préfèrent :
- Choisir une cohort existante →
cohorts-list - Chercher des personnes spécifiques par nom ou e-mail →
persons-listavec une requête de recherche - Trouver des utilisateurs par comportement → voir ci-dessous
- Coller une liste d'adresses e-mail
- Choisir une cohort existante →
Chaque e-mail passe par la validation d'e-mail DRF (le format affichage-nom Paul D'Ambra <paul@x.com> est accepté à côté du simple paul@x.com).
Résoudre une cohort
Les topics capturent leur audience au moment de la création. Quand l'utilisateur choisit une cohort, vous devez matérialiser la liste des membres dans interviewee_emails (et interviewee_distinct_ids pour les membres sans e-mail) avant de créer le topic.
-
Comptez d'abord la cohort. Requête bon marché, détermine l'étape suivante :
SELECT count() FROM persons WHERE id IN COHORT <cohort_id> -
Si la cohort a 500 membres ou moins, récupérez leurs e-mails :
SELECT properties.email AS email FROM persons WHERE id IN COHORT <cohort_id> AND properties.email IS NOT NULL LIMIT 500Mettez chaque ligne dans
interviewee_emails. Dédupliquées.Les membres de la cohort sans propriété e-mail ne sont pas inclus par défaut — la colonne
persons.idest l'UUID de la personne, pas le distinct_id du SDK, donc elle ne peut pas être utilisée commeinterviewee_distinct_idsans une jointurepdi.distinct_id. Si vous avez spécifiquement besoin de joindre les membres qui n'existent que comme des ID distincts, demandez d'abord à l'utilisateur, puis faites la jointure explicitement. -
Si la cohort a plus de 500 membres, arrêtez et demandez à l'utilisateur. Ne tronquez pas, n'échantillonnez pas silencieusement, et ne retombez pas sur une cohort différente — l'utilisateur doit choisir. Présentez :
- Le nom et le compte de la cohort (par ex. « PostHog Team a 28 563 membres — au-dessus du plafond de 500. »)
- Pourquoi le plafond existe (« nous capturons l'audience au moment de la création, et 500 est une protection côté agent pour garder une campagne d'entretien gérable — le backend lui-même ne limite pas la longueur du tableau »)
- Leurs options :
- Réduire la cohort — décrivez le sous-ensemble qu'ils veulent vraiment (par ex. « ingénieurs seulement », « actifs dans les 30 derniers jours »). Vous pouvez offrir d'écrire un filtre HogQL plus spécifique ou de créer une nouvelle cohort plus petite via
cohorts-create. - Échantillonner aléatoirement — confirmez un compte (par ex. 200) et utilisez
ORDER BY rand() LIMIT <n>sur la requête cohort. Rendez le caractère aléatoire explicite pour qu'ils sachent qu'ils ne prennent pas les membres « supérieurs ». - Coller une liste curée — ils prennent le relais et fournissent des e-mails directement.
- Réduire la cohort — décrivez le sous-ensemble qu'ils veulent vraiment (par ex. « ingénieurs seulement », « actifs dans les 30 derniers jours »). Vous pouvez offrir d'écrire un filtre HogQL plus spécifique ou de créer une nouvelle cohort plus petite via
Choisissez le chemin avec eux, puis réexécutez la résolution. Ne continuez jamais sans une décision explicite.
-
Dites à l'utilisateur ce que vous avez résolu. Après la résolution, confirmez avant de créer : « La cohort 'X' a N membres, résolue en E e-mails et D ID distincts (snapshot — ne sera pas mise à jour si la cohort change ultérieurement). » Cela rend les sémantiques de snapshot visibles.
Trouver les utilisateurs par comportement
Quand l'utilisateur décrit qui il veut parler en termes comportementaux, trouvez-les dans les données du projet :
- Trouvez l'événement correct. Appelez
read-data-schemapour lister les événements qui existent réellement dans le projet. Ne devinez pas les noms d'événements à partir des données d'entraînement — les taxonomies d'événements PostHog sont bespoke. Mappez la description de l'utilisateur à un ou deux événements candidats ; s'il existe plusieurs correspondances plausibles, listez-les et demandez quel comportement ils veulent comprendre. - Interrogez les utilisateurs. Appelez
execute-sqlavec HogQL. Filtrez par l'événement choisi au cours des 60 derniers jours et groupez par personne aveccoalesce(person.properties.email, distinct_id) AS id— cela garde les deux genres de lignes dans une seule requête : les personnes avec un e-mail groupé sous lui (directement utilisable commeinterviewee_emails), tandis que les personnes sans e-mail reviennent à leur propredistinct_id(pourinterviewee_distinct_ids) à la place de s'effondrer en un bacNonejunk qui trierait en haut sousORDER BY count() DESCet prendrait une place d'échantillon. La colonneemailsélectionnée vous indique lequel est lequel lors du routage (voir ci-dessous). Les agrégats dans chaque modèle (event_count,last_seen,days_since_last_seen) sont ce qui alimentent le contexte par-interviewé de l'étape 5. Remplacez<event_name>par l'événement choisi :- Utilisateurs intensifs —
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 - Abandons (essayé une ou deux fois et jamais revenu) —
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 - À risque (était actif, maintenant dormant) —
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
- Utilisateurs intensifs —
- Construisez un échantillon équilibré. À moins que l'utilisateur n'ait demandé un segment spécifique, mélanger 5 utilisateurs intensifs + 3 abandons + 2 utilisateurs à risque donne les entretiens les plus exploitables : vous apprenez ce qui fonctionne, ce qui bloque l'adoption, et ce qui casse la rétention. Ajustez les comptes pour correspondre à ce que l'utilisateur veut vraiment.
Routez chaque ligne par sa colonne email : les lignes où email n'est pas nul vont dans interviewee_emails, et les lignes où email est nul (donc id contient le distinct_id) vont dans interviewee_distinct_ids — les deux peuvent être définis sur le même topic. Gardez event_count et days_since_last_seen par personne pour que l'étape 5 puisse synthétiser un contexte comme « utilisé checkout 47 fois dans les 60 derniers jours ; vu pour la dernière fois il y a 2 jours ».
Étape 3 : Capturer le topic
topic est une ou deux phrases décrivant ce sur quoi porte l'entretien. Déduisez du contexte quand c'est possible — ne demandez pas à l'utilisateur de se répéter.
Exemple : « demander aux utilisateurs d'essai pourquoi ils n'ont pas converti » → topic: "Pourquoi les utilisateurs d'essai n'ont pas converti au cours des 14 premiers jours".
Étape 4 : Préparer l'agent vocal
Deux champs façonnent ce que l'agent fait réellement sur l'appel. Posez toujours des questions sur les deux avant de créer le topic.
Toujours demander : quelles questions veulent-ils poser ?
questions est une liste ordonnée que l'agent travaille. Des ancres, pas un script — l'agent adaptera la formulation. Gardez-les ouvertes :
- ✅ « Qu'est-ce qui vous a poussé à essayer PostHog ? »
- ❌ « Vous aviez aimé PostHog ? »
Si l'utilisateur a déjà listé les questions dans sa requête initiale, utilisez-les et confirmez. Sinon, posez explicitement : « Quelles questions voulez-vous que l'agent pose ? »
Si l'utilisateur n'en peut pas penser, suggérez 3-5 questions ouvertes tirées du topic et proposez-les pour examen avant de créer.
Le champ est techniquement facultatif dans l'API, mais ne le sautez pas silencieusement — un entretien sans questions est rarement utile.
Modèles de questions par objectif de recherche :
- Pourquoi les utilisateurs ont abandonné / churné :
- « Parlez-moi de la dernière fois que vous avez essayé [fonctionnalité] — qu'essayiez-vous de faire ? »
- « Expliquez-moi ce qui s'est passé étape par étape. »
- « Qu'attendiez-vous par rapport à ce qui s'est réellement passé ? »
- « Qu'est-ce qui vous a fait arrêter ou décider de ne pas continuer ? »
- « Qu'est-ce qui devrait changer pour que vous utilisiez [fonctionnalité] régulièrement ? »
- Pourquoi les utilisateurs intensifs adorent une fonctionnalité :
- « Parlez-moi de comment vous utilisez [fonctionnalité] — quel problème résout-elle pour vous ? »
- « Expliquez-moi votre flux de travail typique. »
- « Que feriez-vous si [fonctionnalité] n'existait pas ? »
- « Qu'est-ce qui a presque vous fait ne pas l'utiliser quand vous l'avez essayée en premier ? »
- « Qu'est-ce qu'une chose que vous aimeriez qu'elle fasse différemment ? »
- Pourquoi quelqu'un n'a pas encore essayé une fonctionnalité :
- « Avez-vous remarqué [fonctionnalité] dans le produit ? »
- « Qu'est-ce qui vous a empêché d'essayer ? »
- « Qu'est-ce qui devrait être vrai pour que ça vaille la peine d'essayer ? »
Toujours offrir : du contexte supplémentaire pour guider l'entretien
agent_context est facultatif, mais quelques phrases ici rendent la conversation dramatiquement meilleure. Offrez toujours à l'utilisateur la chance de le fournir, par ex. :
« Voulez-vous donner à l'agent un contexte supplémentaire ? Des choses comme le ton, ce à éviter, ou le contexte sur l'interviewé aident à guider la conversation. C'est facultatif. »
Genres utiles de contexte :
- Ton : « chaleureux et conversationnel », « ignorez les politesses — c'est un appel de 10 minutes »
- Contraintes : « ne promettez pas la livraison des fonctionnalités », « ne discutez pas des tarifs »
- Contexte que l'agent devrait connaître : « l'utilisateur a churné du plan Scale ; soyez empathique », « cette personne a essayé PostHog il y a 6 mois et a rebondi »
- Persona : « vous êtes Sam, un chercheur produit PostHog »
Si l'utilisateur décline, c'est bien — laissez agent_context vide et continuez.
Appeler user-interview-topics-create
Une fois que vous avez les pièces :
{
"topic": "Pourquoi les utilisateurs d'essai ont churné la deuxième semaine",
"interviewee_emails": ["paul@acme.com", "alex@beta.com"],
"interviewee_distinct_ids": ["distinct-id-with-no-email"],
"agent_context": "Soyez chaleureux. L'interviewé vient de churner — ne vendez pas.",
"questions": [
"Qu'espériez-vous que PostHog vous aide à faire ?",
"Où vous êtes-vous bloqué ?",
"Qu'est-ce qui vous aurait fait rester ?"
]
}
Après la création, capturez l'ID du topic retourné — vous en aurez besoin pour l'étape 5 et pour la remise à l'agent vocal.
Étape 5 : Optionnellement attacher du contexte par-interviewé
Le agent_context au niveau du topic s'applique à chaque interviewé. Si l'utilisateur sait quelque chose de spécifique sur des interviewés individuels qui devrait façonner cette conversation, attachez-le comme une ligne par-interviewé via user-interview-topics-interviewees-create. C'est facultatif — la plupart des topics n'en auront pas besoin.
Chaque ligne associe un interviewee_identifier (doit correspondre à l'un des e-mails ou ID distincts du ciblage du topic parent) avec une chaîne agent_context. Au maximum une ligne par (topic, interviewé). Un utilisateur peut avoir zéro ligne.
Le contexte par-interviewé utile ressemble à :
- « utilise le produit de relecture mais n'a jamais utilisé la synthétisation »
- « churné du plan Scale le mois dernier — soyez empathique, ne vendez pas »
- « fondateur, très technique, ignorez les explications de produit basiques »
Après la réussite de l'étape 4, demandez à l'utilisateur : « Voulez-vous ajouter un contexte par-interviewé ? Utile quand les personnes individuelles ont très différents contextes. Vous pouvez soit dicter les lignes soit coller un CSV. »
Si vous avez trouvé l'audience via une requête comportementale à l'étape 2, vous avez déjà du contexte par-personne (comptes d'utilisation, fenêtres de dormance). Utilisez-le : par ex. « utilisé checkout 47 fois dans les 60 derniers jours ; vu pour la dernière fois il y a 2 jours » pour les utilisateurs intensifs, « a essayé checkout une fois il y a 18 jours, jamais revenu » pour les abandons.
Accepter l'entrée CSV
Si l'utilisateur colle un CSV, attendez-vous à deux colonnes : identifier,context. Avec ou sans une ligne d'en-tête. Exemples :
paul@acme.com,utilise relecture mais jamais synthétisation
steve@apple.com,fondateur; très technique; ignorez les bases du produit
Ou avec une en-tête :
identifier,context
abc-distinct-id-1,churné du plan Scale le mois dernier — soyez empathique
Analysez le CSV, puis créez les lignes avec le topic_id capturé. Pour plus que quelques lignes, préférez user-interview-topics-interviewees-bulk-create — il prend un tableau items de (interviewee_identifier, agent_context) et crée jusqu'à 500 lignes en une requête, rapportant inserted_count, skipped_count, et skipped_identifiers pour les paires qui existent déjà. Retombez sur user-interview-topics-interviewees-create pour une ligne unique. Ignorez les lignes vides. Échappez les guillemets-les virgules à l'intérieur de la cellule de contexte — les règles CSV standard.
Si l'identifiant d'une ligne n'est pas présent dans le interviewee_emails ou interviewee_distinct_ids du topic parent, avertissez l'utilisateur avant de créer — l'agent vocal cherche le contexte par correspondance exacte de chaîne, donc un identifiant non-correspondant est juste ignoré lors de l'exécution.
Cas limites
- Aucun utilisateur ne correspond à la requête comportementale. Raisons possibles : l'événement ne se déclenche pas, la plage de dates est trop étroite, ou aucun utilisateur n'a d'adresses e-mail capturées comme propriétés de personne. Offrez d'élargir la plage de dates, d'essayer un événement différent, ou de retomber sur des cohorts / des e-mails explicites.
- Les utilisateurs correspondent mais peu ont d'e-mails. PostHog stocke ce que le SDK capture. Si seule une poignée d'utilisateurs correspondants ont des adresses e-mail sur leur profil de personne, présentez le compte et posez : prendre le plus petit échantillon, retomber sur
interviewee_distinct_ids(l'agent peut toujours les joindre via la livraison in-app), ou ignorer la requête comportementale et laisser l'utilisateur coller les e-mails directement. - Nom d'événement ambigu. Si
read-data-schemaretourne plusieurs candidats (par ex.checkout_started,checkout_completed,checkout_abandoned), listez-les avec les comptes et laissez l'utilisateur choisir le comportement qu'il veut comprendre. Ne choisissez pas silencieusement. - L'utilisateur demande d'interviewer seulement les abandons (ou seulement un segment). Cela fonctionne, mais signalez le compromis : interviewer seulement les abandons vous dit ce qui est cassé sans vous dire ce qui fonctionne. Recommandez d'inclure 2-3 utilisateurs réussis pour le contraste à moins que l'utilisateur n'ait une raison pour l'échantillon plus étroit.
Ce que cette skill n'est pas
- Télécharger un entretien enregistré — c'est le modèle
UserInterviewséparé (user_interviews_createavec un fichier audio). Flux différent, modèle différent. - Lister les topics existants —
user-interview-topics-listgère cela directement avecsearch,limit, etoffset. Aucune skill requise. - Analyser les transcriptions après l'entretien — hors portée ici ; c'est du côté du flux
UserInterviewenregistré.