planning-user-interviews

Par posthog · skills

Planifier un sujet d'interview utilisateur dans PostHog — choisir qui cibler (cohorte, e-mails ou distinct IDs PostHog), rédiger les thèmes à aborder, et préparer le contexte de l'agent vocal ainsi qu'une liste de questions. À utiliser lorsque l'utilisateur souhaite « parler aux utilisateurs », « savoir ce que les utilisateurs pensent de X », « interviewer des clients », « configurer une interview utilisateur », « organiser un appel de recherche utilisateur », « trouver des utilisateurs à interroger sur Y », ou qu'il cherche plus généralement à recueillir des retours qualitatifs via une conversation. Guide l'utilisateur à travers le ciblage (cohorts-list, persons-list, ou acceptation directe d'e-mails / distinct IDs), capture le sujet, et demande le contexte de l'agent ainsi que les questions avant d'appeler `user-interview-topics-create`. NE PAS déclencher lorsque l'utilisateur téléverse un fichier audio d'interview enregistrée (c'est le flux distinct UserInterview/transcript) ou qu'il consulte simplement des sujets existants via `user-interview-topics-list`.

npx skills add https://github.com/posthog/skills --skill planning-user-interviews

Planifier les entretiens utilisateurs

Utilise cette compétence quand quelqu'un demande de mettre en place un entretien utilisateur — pour parler à des clients, vérifier le sentiment ou recueillir des retours qualitatifs lors d'une conversation vocale. Le plan est capturé comme une UserInterviewTopic qu'un agent vocal exécutera plus tard.

Ce qu'un sujet complet doit contenir

Avant d'appeler user-interview-topics-create, rassemble ceci :

  1. Qui interviewer — au moins un de :
    • interviewee_cohort — un ID de cohorte existant
    • interviewee_emails — liste d'adresses e-mail
    • interviewee_distinct_ids — liste d'ID distincts PostHog
  2. Ce qu'il faut demandertopic (texte libre obligatoire)
  3. Comment l'agent doit encadrer la conversationagent_context optionnel (prompt système supplémentaire)
  4. Les questions à traiter — liste questions ordonnée optionnelle

L'API rejette les sujets sans ciblage, donc au moins l'un des trois champs d'audience doit être défini. Ils peuvent être combinés — une cohorte plus quelques e-mails supplémentaires, c'est acceptable.

Étape 1 : Clarifier l'intention

Si la demande est vague, demande :

  • Quelle fonctionnalité ou quel comportement ? « checkout » pourrait être le clic sur le bouton, l'affichage de la page ou la soumission du paiement — affine-le à un seul événement.
  • Qu'est-ce que tu veux apprendre ? Pourquoi ils ont abandonné ? Qu'est-ce qui les a confondus ? Quelles alternatives ont-ils essayées ? L'objectif façonne à la fois l'audience et les questions.
  • Quel type d'utilisateurs ? Utilisateurs actifs (ce qui fonctionne), abandons (ce qui bloque l'adoption), utilisateurs à risque (ce qui casse la rétention) ou un mélange.

Saute ces questions seulement si l'utilisateur y a déjà répondu.

Étape 2 : Choisir l'audience

Mappe ce que l'utilisateur a dit à l'un de ces chemins :

  • Ils ont nommé une cohorte (« nos utilisateurs puissants », « inscriptions d'essai la semaine dernière ») — utilise cohorts-list filtrée par nom pour trouver la cohorte, confirme la correspondance et transmet l'ID de la cohorte comme interviewee_cohort.
  • Ils ont décrit le type de personne mais aucune cohorte n'existe — propose soit de créer la cohorte d'abord (cohorts-create), soit de revenir à la recherche de personnes par comportement (voir ci-dessous).
  • Ils ont donné des adresses e-mail ou des ID distincts — accepte-les directement. Saute la recherche de cohorte.
  • Ils ont décrit un comportement, pas une cohorte (« utilisateurs qui ont essayé checkout mais n'ont pas terminé », « personnes qui utilisaient le mode sombre et ont arrêté ») — trouve-les en interrogeant leurs événements (voir ci-dessous).
  • Ils étaient vagues (« quelques clients », « certains utilisateurs puissants ») — demande lequel ils préfèrent :
    • Choisir une cohorte existante → cohorts-list
    • Chercher des personnes spécifiques par nom ou e-mail → persons-list avec une requête de recherche
    • Trouver des utilisateurs par comportement → voir ci-dessous
    • Coller une liste d'adresses e-mail

Chaque e-mail passe par la validation d'e-mail DRF (le format avec nom d'affichage Paul D'Ambra <paul@x.com> est accepté aux côtés du simple paul@x.com).

Trouver des utilisateurs par comportement

Quand l'utilisateur décrit qui il veut interviewer en termes de comportement, trouve-les dans les données du projet :

  1. Trouve le bon événement. Appelle read-data-schema pour lister les événements qui existent réellement dans le projet. Ne devine pas les noms d'événements à partir des données d'entraînement — les taxonomies d'événements PostHog sont spécialisées. Apparie la description de l'utilisateur à un ou deux événements candidats ; s'il existe plusieurs correspondances plausibles, liste-les et demande quel comportement l'intéresse.
  2. Interroge les utilisateurs. Appelle execute-sql avec HogQL. Filtre par l'événement choisi au cours des 60 derniers jours, groupe par personne — préfère person.properties.email (directement utilisable comme interviewee_emails), reviens à distinct_id (pour interviewee_distinct_ids). Conserve les deux types de lignes. Les agrégats dans chaque modèle (event_count, last_seen, days_since_last_seen) sont ce qui alimente le contexte par interviewé de l'étape 5. Remplace <event_name> par l'événement choisi, et <id> par person.properties.email ou distinct_id :
    • Utilisateurs actifsSELECT <id> AS id, 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> HAVING count() >= 5 ORDER BY count() DESC LIMIT 20
    • Abandons (essayé une ou deux fois et jamais revenu) — SELECT <id> AS id, 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> HAVING count() <= 2 AND dateDiff('day', max(timestamp), now()) > 14 ORDER BY count() ASC LIMIT 20
    • À risque (était actif, maintenant inactif) — SELECT <id> AS id, 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> HAVING count() >= 3 AND dateDiff('day', max(timestamp), now()) > 14 ORDER BY days_since_last_seen DESC LIMIT 20
  3. Construis un échantillon équilibré. À moins que l'utilisateur n'ait demandé un segment spécifique, mélangeant 5 utilisateurs actifs + 3 abandons + 2 utilisateurs à risque donne les entretiens les plus exploitables : tu apprends ce qui fonctionne, ce qui bloque l'adoption et ce qui casse la rétention. Ajuste les nombres à ce que l'utilisateur veut réellement.

Transmet les lignes d'e-mail comme interviewee_emails et les lignes d'ID distincts comme interviewee_distinct_ids — les deux peuvent être définis sur le même sujet. Conserve event_count et days_since_last_seen par personne afin que l'étape 5 puisse synthétiser un contexte comme « a utilisé checkout 47 fois au cours des 60 derniers jours ; vu pour la dernière fois il y a 2 jours ».

Étape 3 : Capturer le sujet

topic est une ou deux phrases décrivant ce que l'entretien concerne. Déduis du contexte quand c'est possible — ne demande 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 dans les 14 premiers jours".

Étape 4 : Préparer l'agent vocal

Deux champs façonnent ce que l'agent fait réellement lors de l'appel. Demande toujours les deux avant de créer le sujet.

Toujours demander : quelles questions veulent-ils poser ?

questions est une liste ordonnée que l'agent suit. Des ancrages, pas un script — l'agent adoptera son langage. Garde-les ouverts :

  • ✅ « Qu'est-ce qui t'a décidé à essayer PostHog ? »
  • ❌ « T'as aimé PostHog ? »

Si l'utilisateur a déjà listé des questions dans sa demande originale, utilise-les et confirme. Sinon, demande explicitement : « Quelles questions veux-tu que l'agent pose ? »

Si l'utilisateur ne peut pas en penser, suggère 3–5 questions ouvertes tirées du topic et propose-les pour examen avant de créer.

Le champ est techniquement optionnel dans l'API, mais ne le saute pas silencieusement — un entretien sans questions est rarement utile.

Modèles de questions par objectif de recherche :

  • Pourquoi les utilisateurs ont abandonné / churné :
    • « Parle-moi de la dernière fois que tu as essayé [fonctionnalité] — qu'essayais-tu de faire ? »
    • « Marche-moi à travers ce qui s'est passé étape par étape. »
    • « Qu'attendais-tu vs ce qui s'est réellement passé ? »
    • « Qu'est-ce qui t'a fait arrêter ou décider de ne pas continuer ? »
    • « Qu'est-ce qui devrait changer pour que tu utilises [fonctionnalité] régulièrement ? »
  • Pourquoi les utilisateurs actifs adorent une fonctionnalité :
    • « Parle-moi de comment tu utilises [fonctionnalité] — quel problème résout-elle pour toi ? »
    • « Marche-moi à travers ton flux de travail typique. »
    • « Qu'est-ce que tu ferais si [fonctionnalité] n'existait pas ? »
    • « Qu'est-ce qui a presque fait que tu ne l'utilises pas quand tu l'as essayée pour la première fois ? »
    • « Y a-t-il une chose que tu aimerais qu'elle fasse différemment ? »
  • Pourquoi quelqu'un n'a pas encore essayé une fonctionnalité :
    • « As-tu remarqué [fonctionnalité] dans le produit ? »
    • « Qu'est-ce qui t'a empêché de l'essayer ? »
    • « Qu'est-ce qui devrait être vrai pour que ça vaille la peine de l'essayer ? »

Toujours proposer : contexte supplémentaire pour guider l'entretien

agent_context est optionnel, mais quelques phrases ici rendent la conversation dramatiquement meilleure. Offre toujours à l'utilisateur la chance de la fournir, p. ex. :

« Veux-tu donner à l'agent un contexte supplémentaire ? Des choses comme le ton, ce à éviter ou des informations sur l'interviewé aident à guider la conversation. C'est optionnel. »

Sortes utiles de contexte :

  • Ton : « chaleureux et conversationnel », « saute les politesses — c'est un appel de 10 minutes »
  • Contraintes : « ne promets pas de livraison de fonctionnalité », « ne discute pas de tarification »
  • Contexte que l'agent devrait connaître : « l'utilisateur vient de churner du plan Scale ; sois empathique », « cette personne a essayé PostHog il y a 6 mois et a abandonné »
  • Persona : « tu es Sam, chercheur produit PostHog »

Si l'utilisateur refuse, c'est bien — laisse agent_context vide et continue.

Appeler user-interview-topics-create

Une fois que tu as les éléments :

{
  "topic": "Pourquoi les utilisateurs d'essai ont churné en semaine 2",
  "interviewee_cohort": 42,
  "interviewee_emails": ["paul@acme.com"],
  "agent_context": "Sois chaleureux. L'interviewé vient de churner — ne fais pas de pitch.",
  "questions": [
    "Qu'espérais-tu que PostHog t'aide avec ?",
    "Où t'es-tu bloqué ?",
    "Qu'est-ce qui t'aurait fait rester ?"
  ]
}

Après la création, capture l'ID du sujet renvoyé — tu en auras besoin pour l'étape 5 et pour le transmettre à l'agent vocal.

Étape 5 : Optionnellement joindre du contexte par interviewé

Le agent_context au niveau du sujet s'applique à chaque interviewé. Si l'utilisateur sait quelque chose de spécifique sur des interviewés individuels qui devrait façonner cette seule conversation, joigne-le comme une ligne par interviewé via user-interview-topics-interviewees-create. C'est optionnel — la plupart des sujets n'en auront pas besoin.

Chaque ligne associe un interviewee_identifier (doit correspondre à l'un des e-mails ou des ID distincts du ciblage du sujet parent) à une chaîne agent_context. Au maximum une ligne par (sujet, interviewé). Un utilisateur peut avoir zéro ligne.

Un bon contexte par interviewé ressemble à :

  • « utilise le produit replay mais n'a jamais utilisé la résumérisation »
  • « a churné du plan Scale le mois dernier — sois empathique, ne fais pas de pitch »
  • « fondateur, très technique, saute les explications produit basiques »

Après la réussite de l'étape 4, demande à l'utilisateur : « Veux-tu ajouter du contexte par interviewé ? Utile quand des personnes individuelles ont des antécédents très différents. Tu peux soit dicter les lignes, soit coller un CSV. »

Si tu as trouvé l'audience via une requête comportementale à l'étape 2, tu as déjà du contexte par personne (compteurs d'utilisation, fenêtres d'inactivité). Utilise-le : p. ex. "a utilisé checkout 47 fois au cours des 60 derniers jours ; vu pour la dernière fois il y a 2 jours" pour les utilisateurs actifs, "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, attends-toi à deux colonnes : identifier,context. Avec ou sans ligne d'en-tête. Exemples :

paul@acme.com,utilise replay mais jamais la résumérisation
steve@apple.com,fondateur; très technique; saute les bases du produit

Ou avec un en-tête :

identifier,context
abc-distinct-id-1,a churné du plan Scale le mois dernier — sois empathique

Analyse le CSV, puis appelle user-interview-topics-interviewees-create une fois par ligne avec le topic_id capturé. Saute les lignes vides. Échappe les virgules à l'intérieur de la cellule context — règles CSV standard.

Si l'identifiant d'une ligne n'est pas présent dans les interviewee_emails ou interviewee_distinct_ids du sujet parent, avertis l'utilisateur avant de créer — l'agent vocal recherche le contexte par correspondance de chaîne exacte, donc un identifiant mal assorti est juste ignoré au runtime.

Cas limites

  • Aucun utilisateur ne correspond à la requête comportementale. Raisons possibles : l'événement n'est pas déclenché, la plage de dates est trop étroite, ou aucun utilisateur n'a d'adresses e-mail capturées comme propriétés de personne. Propose d'élargir la plage de dates, d'essayer un événement différent ou de revenir aux cohortes / e-mails explicites.
  • Les utilisateurs correspondent mais peu ont d'e-mails. PostHog stocke ce que le SDK capture. Si seulement une poignée d'utilisateurs correspondants ont des adresses e-mail sur leur profil de personne, signale le compte et demande : prendre l'échantillon plus petit, revenir à interviewee_distinct_ids (l'agent peut quand même les atteindre via la livraison in-app), ou sauter la requête comportementale et laisser l'utilisateur coller les e-mails directement.
  • Nom d'événement ambigu. Si read-data-schema retourne plusieurs candidats (p. ex. checkout_started, checkout_completed, checkout_abandoned), liste-les avec des compteurs et laisse l'utilisateur choisir le comportement qu'il veut comprendre. Ne choisis pas silencieusement.
  • L'utilisateur demande d'interviewer seulement les abandons (ou seulement un segment). Ça fonctionne, mais signale le compromis : interviewer seulement les abandons te dit ce qui est cassé sans te dire ce qui fonctionne. Recommande d'inclure 2–3 utilisateurs réussis pour contraste sauf si l'utilisateur a une raison pour l'échantillon plus étroit.

Ce pour quoi cette compétence n'est pas

  • Télécharger un entretien enregistré — c'est le modèle UserInterview séparé (user_interviews_create avec un fichier audio). Flux différent, modèle différent.
  • Lister les sujets existantsuser-interview-topics-list gère directement avec search, limit et offset. Pas besoin de compétence.
  • Analyser les transcriptions après l'entretien — hors de portée ici ; ça vit avec le flux UserInterview enregistré.

Skills similaires