用户访谈与问题挖掘方法论
High Contrast
Dark Mode
Light Mode
Sepia
Forest
4 min read852 words

用户访谈与问题挖掘方法论

用户说"我想要一个搜索框"——这不是问题,这是他们猜测的解决方案。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

本章小结

下一节03-问题优先级与机会判断矩阵 — 访谈发现了一堆问题,怎么判断哪个值得做?用 2×2 机会矩阵和评分模型做出可防御的优先级决策。