mcpField
P
planning-voice-agent-user-interviews

planning-voice-agent-user-interviews

github.com/posthog设计与 UI9590 次安装今天更新
代码仓库

关于 planning-voice-agent-user-interviews

用于规划由 PostHog AI 语音 Agent 执行的用户访谈,帮助明确研究目标、筛选并解析访谈对象,以及准备主题和问题。

主要功能

  1. 01确认自动访谈意图
  2. 02按群组或行为选择对象
  3. 03将群组成员解析为联系标识
  4. 04设置主题和 Agent 上下文
  5. 05准备有序访谈问题

适用场景

  1. 01规划面向试用用户的自动呼叫
  2. 02访谈放弃结账的用户
  3. 03招募高频、存在流失风险或不活跃用户
  4. 04将群组转换为固定访谈对象

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/posthog/ai-plugin --skill planning-voice-agent-user-interviews

安装后在 Claude Code 中输入/planning-voice-agent-user-interviews确认已加载。

详细介绍

规划语音 Agent 用户访谈

仅当有人希望 PostHog 的 AI 语音 Agent(即“机器人访谈员”)实际为他们开展一轮用户访谈电话时,才使用此技能。计划会记录为 UserInterviewTopic,供语音 Agent 后续执行:逐一联系指定对象,并围绕问题展开访谈。

这是一个特定产品,不是通用的研究助手。如果用户只是想_找出_或_筛选_访谈对象、为人工访谈规划问题,或分析已有的反馈,则不应使用此技能——请按常规受众发现/数据分析流程处理(参见 querying-posthog-data),最多提及语音 Agent 选项即可。

步骤 0:确认这是语音 Agent 流程

在做其他事情之前,先确认用户确实希望 AI 语音 Agent 来开展访谈。许多提到“访谈用户”的请求,实际是想找出_该和谁聊_,而不是把对话交给机器人。

  • 如果用户明确要求语音 Agent/机器人访谈/自动拨打电话,则继续步骤 1。
  • 如果用户只是要求找出或筛选适合访谈的用户(例如“谁适合接受关于收件箱的访谈?”),则按受众发现处理:使用常规查询回答,不要创建主题。之后可以用一句话主动询问,例如:“如果你愿意,我可以把这些用户设为由 PostHog AI 语音 Agent 开展的自动访谈对象——需要我这么做吗?”
  • 如果意图不明确,先询问,例如:“先确认一下你的需求:你要做哪类用户研究?你希望 PostHog AI 语音 Agent 实际开展访谈(它会联系用户并围绕你的问题展开对话)吗?还是只想让我找出合适的访谈对象?”

只有在用户确认希望语音 Agent 开展访谈后,才继续下一步。

完整主题需要包含的内容

调用 user-interview-topics-create 前,请收集以下信息:

  1. 访谈对象——至少提供以下一项:
    • interviewee_emails——电子邮件地址列表
    • interviewee_distinct_ids——PostHog distinct ID 列表
  2. 访谈主题——topic(必填的自由文本)
  3. Agent 应如何引导对话——可选的 agent_context(额外的系统提示词)
  4. 需要讨论的问题——可选的有序 questions 列表

主题会在创建时固定目标受众;不会实时关联群组。如果用户指定了某个群组,你(Agent)需要在调用 user-interview-topics-create 前,将群组成员解析为电子邮件地址/distinct ID。解析流程和 500 人上限的用户体验详见步骤 2。

如果没有目标对象,API 会拒绝创建主题,因此最终必须提供非空的 interviewee_emails 和/或 interviewee_distinct_ids。

步骤 1:明确意图

如果请求含糊,请询问:

  • 要了解哪个功能或行为?“结账”可能指按钮点击、页面浏览或付款提交——请缩小范围,明确为一个事件。
  • **你想了解什么?**他们为什么中途退出?是什么让他们感到困惑?他们尝试过哪些替代方案?目标会影响受众和问题的设计。
  • **想访谈哪类用户?**重度用户(了解哪些方面有效)、中途退出的用户(了解哪些因素阻碍他们采用)、有流失风险的用户(了解哪些因素影响留存),还是混合人群?

只有在用户已经回答这些问题时,才跳过询问。

第 2 步:选择受众

将用户的描述对应到以下路径之一:

  • 用户提到了某个群组(“我们的高级用户”“上周注册的试用用户”)——使用 cohorts-list(或通过 system.cohorts 进行 SQL 搜索)查找群组,确认匹配后,再将群组成员解析为邮箱/distinct_id(参见下方“解析群组”)。
  • 用户描述了某类人,但还没有相应群组——建议先创建群组(cohorts-create),再解析群组;或者退而求其次,根据行为查找用户(见下文)。
  • 用户提供了邮箱地址或 distinct ID——直接使用,无需查找群组。
  • 用户描述的是某种行为,而不是群组(“尝试结账但未完成的用户”“过去使用深色模式、后来停止使用的人”)——通过查询他们的事件查找用户(见下文)。
  • 用户描述含糊(“一些客户”“一些高级用户”)——询问他们更倾向于哪种方式:
    • 选择现有群组 → cohorts-list
    • 按姓名或邮箱查找特定人员 → 使用搜索查询调用 persons-list
    • 按行为查找用户 → 见下文
    • 粘贴邮箱地址列表

每个邮箱都会经过 DRF 邮箱验证(除纯邮箱地址 [email protected] 外,也接受显示名称格式 Paul D'Ambra <[email protected]>)。

解析群组

主题会在创建时对受众进行快照。用户选择群组后,必须先将成员列表写入 interviewee_emails(对于没有邮箱的成员,则写入 interviewee_distinct_ids),然后才能创建主题。

  1. 先统计群组人数。 这是低成本查询,可决定下一步操作:

    SELECT count() FROM persons WHERE id IN COHORT <cohort_id>
    
  2. 如果群组成员不超过 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 存在的成员,请先询问用户,然后再明确执行联接。

  3. 如果群组成员超过 500 人,请停止并询问用户。不要静默截断、抽样或改用其他群组——必须由用户作出选择。说明以下信息:

    • 群组名称和人数(例如:“PostHog Team 有 28,563 名成员,超过 500 人的上限。”)
    • 设置上限的原因(“我们会在创建时对受众进行快照;500 人是 Agent 端设置的护栏,用于控制单次访谈活动的规模——后端本身并不限制数组长度。”)
    • 用户可选择的方案:
      • 缩小群组范围——请用户描述实际需要的子集(例如“仅工程师”“过去 30 天内活跃的用户”)。你可以提出编写更具体的 HogQL 筛选条件,或通过 cohorts-create 创建一个更小的新群组。
      • 随机抽样——确认抽样人数(例如 200),并在群组查询中使用 ORDER BY rand() LIMIT <n>。明确说明这是随机抽样,以免用户误以为选出的是“排名靠前”的成员。
      • 粘贴整理好的列表——由用户接手并直接提供邮箱。

    与用户选定方案后,再次解析群组。在用户明确作出决定之前,绝不继续操作。

  4. 告知用户解析结果。 解析完成后,在创建前确认:“群组‘X’有 N 名成员,已解析为 E 个邮箱和 D 个 distinct ID(快照——群组之后发生变化也不会更新)。”这样可以让用户了解快照的含义。

按行为查找用户

当用户用行为描述他们想交谈的对象时,请在项目自己的数据中查找:

  1. 找到合适的事件。 调用 read-data-schema 列出项目中实际存在的事件。不要根据训练数据猜测事件名称——PostHog 的事件分类体系因项目而异。将用户的描述与一两个候选事件匹配;如果有多个合理的匹配项,请列出并询问用户关心的是哪种行为。
  2. 查询用户。 调用 execute-sql 并使用 HogQL。筛选过去 60 天内所选的事件,并使用 coalesce(person.properties.email, distinct_id) AS id 按用户分组——这样一条查询就能包含两类行:有邮箱的用户按邮箱分组(可直接用于 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
    • 流失用户(试过一两次后就再也没回来)— 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
  3. 构建均衡的样本。 除非用户指定了某个细分群体,否则混合 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 是一两句话,用于描述访谈内容。尽可能根据上下文推断——不要让用户重复说明。

示例:“询问试用用户为何没有转化” → topic: "Why trial users didn't convert in the first 14 days"。

第 4 步:准备语音 Agent

有两个字段会决定 Agent 在通话中实际执行的操作。创建主题前,务必询问这两项。

始终询问:他们想问哪些问题?

questions 是 Agent 依次询问的问题列表。它们是引导方向,而不是照本宣科的脚本——Agent 会灵活调整措辞。问题应保持开放式:

  • ✅「是什么让你决定试用 PostHog?」
  • ❌「你喜欢 PostHog 吗?」

如果用户在原始请求中已经列出问题,就使用这些问题并向用户确认。否则,明确询问:「你希望 Agent 问哪些问题?」

如果用户一时想不出问题,就根据 topic 提出 3–5 个开放式问题,供用户审核后再创建。

该字段在 API 中实际上是可选的,但不要默默跳过——没有问题的访谈往往没什么用。

按研究目标划分的问题模板:

  • 了解用户为何流失:
    • 「说说你上次尝试 [feature] 的情况——你当时想做什么?」
    • 「请按步骤说说当时发生了什么。」
    • 「你预期的情况和实际发生的情况有什么不同?」
    • 「是什么让你停止使用或决定不再继续?」
    • 「需要做出哪些改变,你才会定期使用 [feature]?」
  • 了解重度用户为何喜欢某项功能:
    • 「说说你如何使用 [feature]——它帮你解决了什么问题?」
    • 「请说说你通常的工作流。」
    • 「如果没有 [feature],你会怎么做?」
    • 「你第一次尝试时,有什么差点让你放弃使用?」
    • 「你希望它在哪一点上有所不同?」
  • 了解用户为何尚未尝试某项功能:
    • 「你注意到产品中的 [feature] 了吗?」
    • 「是什么让你一直没尝试它?」
    • 「要满足什么条件,你才会觉得值得一试?」
始终提供选项:为访谈提供额外背景信息

agent_context 是可选的,但在这里补充几句话能显著改善对话。始终让用户有机会提供这些信息,例如:

「想给 Agent 提供一些额外背景信息吗?例如语气、需要避免的内容,或受访者的背景,都有助于引导对话。此项为可选。」

有用的背景信息类型:

  • 语气:「亲切、自然地交流」「省去寒暄——这是一次 10 分钟的通话」
  • 限制:「不要承诺交付功能」「不要讨论定价」
  • Agent 应了解的背景:「该用户刚从 Scale 套餐流失,请保持体谅」「此人 6 个月前试用过 PostHog,后来就不再使用了」
  • 角色设定:「你是 Sam,一名 PostHog 产品研究员」

如果用户拒绝,也没关系——将 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 和交接给语音 Agent 时都需要它。

Step 5:可选择添加每位受访者的背景信息

主题级别的 agent_context 适用于每位受访者。如果用户了解某位受访者的具体情况,且这些信息应影响与该受访者的对话,请通过 user-interview-topics-interviewees-create 将其作为每位受访者对应的行附加。这是可选步骤——大多数主题都不需要这样做。

每行包含一个 interviewee_identifier(必须与父主题定向对象中的某个电子邮件地址或唯一 ID 相符)和一个 agent_context 字符串。每个(主题、受访者)组合最多对应一行。用户可以不添加任何行。

适用于每位受访者的背景信息示例:

  • 「使用回放产品,但从未使用过摘要功能」
  • 「上个月从 Scale 套餐流失——请保持体谅,不要推销」
  • 「创始人,技术能力很强,跳过基础产品介绍」

Step 4 成功后,询问用户:「要添加每位受访者的背景信息吗?当不同受访者的背景差异很大时,这会很有用。你可以口述各行内容,也可以粘贴 CSV。」

如果你在 Step 2 中通过行为查询找到了受众,就已经掌握了每个人的背景信息(使用次数、休眠时间段)。请利用这些信息:对于重度用户,例如填写 "used checkout 47 times in last 60 days; last seen 2 days ago";对于流失用户,例如填写 "tried checkout once 18 days ago, never returned"。

接受 CSV 输入

如果用户粘贴了 CSV,预期其中有两列:identifier,context。可以包含或不包含表头。示例:

[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 创建各行。对于超过两行的情况,优先使用 user-interview-topics-interviewees-bulk-create——它接受由 (interviewee_identifier, agent_context) 组成的 items 数组,并在一个请求中最多创建 500 行;对于已存在的配对,会报告 inserted_count、skipped_count 和 skipped_identifiers。单行时则使用 user-interview-topics-interviewees-create。跳过空行。对于 context 单元格中包含的逗号,按标准 CSV 规则使用引号转义。

如果某行的 identifier 不在父主题的 interviewee_emails 或 interviewee_distinct_ids 中,创建前请提醒用户——语音 Agent 会按完全匹配的字符串查找上下文,因此 identifier 不匹配时,运行期间会直接忽略该行。

边缘情况

  • 没有用户符合行为查询条件。 可能的原因:事件没有触发、日期范围太窄,或没有用户的 person 属性中记录了电子邮件地址。可以建议扩大日期范围、尝试其他事件,或改用 cohorts / 明确指定的电子邮件地址。
  • 匹配到用户,但其中很少有人有电子邮件地址。 PostHog 会存储 SDK 捕获的内容。如果匹配用户中只有少数人在个人资料里有电子邮件地址,请说明人数,并询问用户是选择较小的样本、改用 interviewee_distinct_ids(Agent 仍可通过应用内推送联系这些用户),还是跳过行为查询并让用户直接粘贴电子邮件地址。
  • 事件名称不明确。 如果 read-data-schema 返回多个候选项(例如 checkout_started、checkout_completed、checkout_abandoned),请列出这些候选项及其数量,让用户选择想要了解的行为。不要自行决定。
  • 用户只想访谈流失用户(或只访谈一个细分群体)。 可以这样做,但请说明取舍:只访谈流失用户能告诉你哪里出了问题,却无法告诉你哪些地方有效。除非用户有理由缩小样本,否则建议加入 2–3 名成功用户以供对比。

此技能不适用于

  • 上传已录制的访谈——这属于单独的 UserInterview 模型(user_interviews_create,附带音频文件)。流程和模型都不同。
  • 列出现有主题——user-interview-topics-list 可通过 search、limit 和 offset 直接处理此操作。无需技能。
  • 访谈后分析转录内容——这不在此范围内;相关操作由已录制的 UserInterview 流程负责。

评论

支持 Markdown