关于 planning-voice-agent-user-interviews
用于规划由 PostHog AI 语音 Agent 执行的用户访谈,帮助明确研究目标、筛选并解析访谈对象,以及准备主题和问题。
主要功能
- 01确认自动访谈意图
- 02按群组或行为选择对象
- 03将群组成员解析为联系标识
- 04设置主题和 Agent 上下文
- 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确认已加载。
详细介绍
规划语音 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 前,请收集以下信息:
- 访谈对象——至少提供以下一项:
interviewee_emails——电子邮件地址列表interviewee_distinct_ids——PostHog distinct ID 列表
- 访谈主题——
topic(必填的自由文本) - Agent 应如何引导对话——可选的
agent_context(额外的系统提示词) - 需要讨论的问题——可选的有序
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),然后才能创建主题。
-
先统计群组人数。 这是低成本查询,可决定下一步操作:
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 Team 有 28,563 名成员,超过 500 人的上限。”)
- 设置上限的原因(“我们会在创建时对受众进行快照;500 人是 Agent 端设置的护栏,用于控制单次访谈活动的规模——后端本身并不限制数组长度。”)
- 用户可选择的方案:
- 缩小群组范围——请用户描述实际需要的子集(例如“仅工程师”“过去 30 天内活跃的用户”)。你可以提出编写更具体的 HogQL 筛选条件,或通过
cohorts-create创建一个更小的新群组。 - 随机抽样——确认抽样人数(例如 200),并在群组查询中使用
ORDER BY rand() LIMIT <n>。明确说明这是随机抽样,以免用户误以为选出的是“排名靠前”的成员。 - 粘贴整理好的列表——由用户接手并直接提供邮箱。
- 缩小群组范围——请用户描述实际需要的子集(例如“仅工程师”“过去 30 天内活跃的用户”)。你可以提出编写更具体的 HogQL 筛选条件,或通过
与用户选定方案后,再次解析群组。在用户明确作出决定之前,绝不继续操作。
-
告知用户解析结果。 解析完成后,在创建前确认:“群组‘X’有 N 名成员,已解析为 E 个邮箱和 D 个 distinct ID(快照——群组之后发生变化也不会更新)。”这样可以让用户了解快照的含义。
按行为查找用户
当用户用行为描述他们想交谈的对象时,请在项目自己的数据中查找:
- 找到合适的事件。 调用
read-data-schema列出项目中实际存在的事件。不要根据训练数据猜测事件名称——PostHog 的事件分类体系因项目而异。将用户的描述与一两个候选事件匹配;如果有多个合理的匹配项,请列出并询问用户关心的是哪种行为。 - 查询用户。 调用
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
- 重度用户 —
- 构建均衡的样本。 除非用户指定了某个细分群体,否则混合 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流程负责。