用户访谈与问题挖掘方法论
用户说"我想要一个搜索框"——这不是问题,这是他们猜测的解决方案。PM 的工作是挖到搜索框背后那个真正的问题。
从表面需求到真实问题的挖掘路径
graph TD
A["用户表达的需求\n(表面)"] --> B["5-Why 追问"]
B --> C["JTBD 框架\n用户在完成什么任务?"]
C --> D["情境还原\n上一次遇到这个问题是什么场景?"]
D --> E["行为验证\n用户现在是怎么绕过这个问题的?"]
E --> F["真实问题定义\n有多少人、多高频、多大痛"]
style A fill:#fff3e0,stroke:#ef6c00,stroke-width:2px
style F fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px
四个核心方法
5-Why 追问:每当用户表达一个需求,连续问五次"为什么"。不是审讯,是协作探索。大多数情况下,问到第 2-3 个"为什么"时,真实问题就浮出来了。
JTBD 框架(Jobs-to-be-Done):用户"雇用"你的产品是为了完成什么任务?JTBD 的核心洞察是:人们买的不是产品功能,而是"完成某件事的进度"。把需求翻译成 Job Statement:当[情境],我想[动作],以便[结果]。
区分表达需求 vs 潜在需求:表达需求是用户说出来的,潜在需求是他们没说但实际驱动行为的。前者是症状,后者是病因。访谈时要同时收集两层。
绕行方案(Workaround)挖掘:用户现在怎么解决这个问题?如果他们已经有了笨办法,说明问题真实存在。笨办法的复杂程度直接反映痛点深度。
访谈会话分析器
from dataclasses import dataclass, field
from typing import List, Optional
from enum import Enum
class NeedType(Enum):
EXPRESSED = "表达需求" # 用户直接说出来的
UNDERLYING = "潜在需求" # 挖掘出来的真实动机
JTBD = "JTBD 任务" # Jobs-to-be-Done 格式
@dataclass
class WhyChain:
"""5-Why 追问链"""
initial_statement: str
whys: List[str] = field(default_factory=list)
def add_why(self, answer: str):
self.whys.append(answer)
def root_cause(self) -> Optional[str]:
return self.whys[-1] if self.whys else None
def display(self):
print(f"\n 5-Why 追问链")
print(f" 起点:{self.initial_statement}")
for i, why in enumerate(self.whys, 1):
indent = " " + " " * i
print(f"{indent}→ Why {i}: {why}")
if self.root_cause():
print(f"\n 根本问题:{self.root_cause()}")
@dataclass
class Need:
content: str
need_type: NeedType
frequency: str # "高频" / "中频" / "低频"
pain_level: int # 1-5,痛点强度
workaround: Optional[str] = None # 用户现在的绕行方案
def score(self) -> float:
freq_map = {"高频": 3, "中频": 2, "低频": 1}
return freq_map.get(self.frequency, 1) * self.pain_level
def summary(self) -> str:
wk = f"(绕行方案:{self.workaround})" if self.workaround else ""
return (
f"[{self.need_type.value}] {self.content} "
f"| 频率:{self.frequency} 痛感:{self.pain_level}/5 "
f"优先分:{self.score():.0f} {wk}"
)
@dataclass
class InterviewSession:
user_id: str
user_role: str
interview_date: str
context: str # 受访者的工作场景描述
needs: List[Need] = field(default_factory=list)
why_chains: List[WhyChain] = field(default_factory=list)
key_quotes: List[str] = field(default_factory=list)
def add_need(self, need: Need):
self.needs.append(need)
def add_why_chain(self, chain: WhyChain):
self.why_chains.append(chain)
def top_needs(self, n: int = 3) -> List[Need]:
return sorted(self.needs, key=lambda x: x.score(), reverse=True)[:n]
def report(self):
print(f"\n{'='*64}")
print(f" 访谈记录 | {self.user_role}({self.user_id})")
print(f" 日期:{self.interview_date}")
print(f" 场景:{self.context}")
print(f"{'='*64}")
if self.key_quotes:
print(f"\n 【关键原话】")
for q in self.key_quotes:
print(f' " {q}"')
for chain in self.why_chains:
chain.display()
print(f"\n 【需求清单(共 {len(self.needs)} 条)】")
for need in self.needs:
print(f" {need.summary()}")
print(f"\n 【优先级 Top 3】")
for i, need in enumerate(self.top_needs(), 1):
print(f" {i}. {need.content}(优先分 {need.score():.0f})")
print(f"{'='*64}\n")
# ── Demo ──────────────────────────────────────────────────────
session = InterviewSession(
user_id="U-042",
user_role="电商运营专员",
interview_date="2024-03-15",
context="负责 3 个品类的日常运营,每天需要整理竞品数据和制作周报"
)
session.key_quotes = [
"我希望有个按钮能一键生成周报",
"其实最烦的是找数据,光找数据就要两个小时",
"周报格式我其实不在乎,老板也不怎么看",
]
# 5-Why 追问链
chain = WhyChain("希望有一键生成周报的功能")
chain.add_why("因为每周写周报要花 3-4 小时")
chain.add_why("因为数据分散在 4 个系统里,要手动汇总")
chain.add_why("因为这些系统没有统一的数据导出接口")
chain.add_why("真正的问题是:数据汇聚成本太高,不是周报本身太难写")
session.add_why_chain(chain)
# 需求录入
session.add_need(Need(
content="跨系统数据自动汇聚到一个地方",
need_type=NeedType.UNDERLYING,
frequency="高频",
pain_level=5,
workaround="手动复制粘贴到 Excel,容易出错"
))
session.add_need(Need(
content="竞品价格变化智能预警",
need_type=NeedType.UNDERLYING,
frequency="中频",
pain_level=4,
workaround="每天人工对比,经常漏掉"
))
session.add_need(Need(
content="一键生成周报",
need_type=NeedType.EXPRESSED,
frequency="高频",
pain_level=2,
workaround="套模板手填"
))
session.add_need(Need(
content="当需要汇报运营成果时,能快速组织数据论据",
need_type=NeedType.JTBD,
frequency="中频",
pain_level=4,
))
session.report()
表达需求 vs 潜在需求对比
| 维度 | 表达需求 | 潜在需求 |
|---|---|---|
| 来源 | 用户直接说出来的 | 通过追问和观察挖掘 |
| 形式 | 功能描述("我要一个 X") | 动机描述("我需要实现 Y") |
| 可靠性 | 反映意识层偏好,可能失真 | 反映真实行为驱动,更可靠 |
| 设计价值 | 低(容易被解决方案带偏) | 高(允许创造性解法) |
| 挖掘方法 | 直接记录 | 5-Why、情境还原、绕行方案 |
本章 checklist
- 访谈前是否准备了开放式问题脚本,避免引导性提问("你是否觉得 X 很麻烦?")
- 访谈中是否记录了用户的原话,而不是自己的解读与总结
- 是否对每个表达需求都做了至少 2-3 次 Why 追问,找到背后的真实动机
- 是否询问了用户目前的绕行方案,用以验证问题的真实性和痛点深度
- 访谈结论是否区分了表达需求和潜在需求,而不是把两者混在一起列清单
本章小结
- 用户表达的是解决方案假设,PM 要挖掘的是问题本身——5-Why 和 JTBD 是穿透表象的核心工具。
- 绕行方案是最好的需求验证:用户愿意用笨办法解决的问题,才是真正值得投入的问题。
- 访谈的输出不是需求列表,而是按频率、痛感、潜在价值排好序的问题地图,为下一步优先级判断做准备。
下一节:03-问题优先级与机会判断矩阵 — 访谈发现了一堆问题,怎么判断哪个值得做?用 2×2 机会矩阵和评分模型做出可防御的优先级决策。