为什么你的功能总有 Bug?Bug 的本质是过期的世界观
在 Concept 与 Coding 之间补上需求编译层,用语义翻译、角色矩阵、Surface 扫描和反向验收逼出产品边界。
从概念到代码:缺失的语义编译层
核心观点:很多产品 Bug 的本质,不是新代码写错了,而是旧代码继续正确地执行了已经过期的世界观。我们需要在 Concept 和 Coding 之间,补上一个“需求编译”的中间层。
引言:靠流程逼出边界
在软件开发中,我们常常依赖“灵光一闪”来思考边界情况。然而,「靠经验想边界」往往不可靠,更好的方式是「靠流程逼出边界」。
目前的工作流中缺少一个固定的中间层:
Concept Intake → Requirement Compile → Coding
我们需要补上 Requirement Compile(需求编译) 这一环。不要每次都仰仗直觉,而是通过结构化的流程,将抽象的产品概念翻译成严谨的系统语义。
一、问题的本质:过期的世界观
很多线上 Bug 的产生,是因为系统旧的假设不再成立。例如在引入“匿名发布”功能前,系统可能存在以下默认假设:
- Trace 一定可以展示 Author。
- Trace 可以出现在 Author 的主页。
- 通知可以用 Creator Name。
- Profile 可以聚合用户发布内容。
当新功能引入时,如果不去显式地推翻这些旧假设,旧代码就会“正确地”执行错误的逻辑。
二、核心方法:语义翻译与边界收束
1. 把抽象词翻译成行为规则
概念(Concept)不是需求,语义(Semantic)才是需求。
例如,老板说“支持匿名发布”,这是一句废话。废话在需求文档里穿上西装,还是废话。正确的解析应该是:
允许用户发布内容时,隐藏自己在普通用户视角下的身份。
这句话包含了四个关键边界:用户、发布内容、隐藏身份、普通用户视角。
这意味着“匿名”不仅仅是 UI 上不显示昵称,而是普通用户不能通过直接或间接路径知道作者是谁。
面对产品文档中的抽象词汇,我们需要建立一张翻译表:
| 老板说的词 | 你需要追问的语义 |
|---|---|
| 匿名 | 对谁匿名?哪些路径匿名?系统内部是否匿名? |
| 私密 | 谁能看?谁不能看?转发后呢? |
| 推荐 | 推荐依据是什么?用户能否关闭? |
| 关注 | 关注后带来哪些权限 / 通知 / 内容流变化? |
| 删除 | 软删除还是硬删除?别人是否还能看到历史痕迹? |
| 屏蔽 | 谁看不到谁?历史内容是否消失? |
| 精选 | 谁能设为精选?排序权重如何变化? |
2. 角色矩阵(Role Matrix)
任何涉及用户、内容、权限、关系的功能,都必须通过角色矩阵进行扫描。必须回答以下问题:
- 谁能看到?
- 谁能操作?
- 谁能收到通知?
- 谁能在列表里看到?
- 谁能在日志/后台看到?
常见角色模版: 未登录用户、普通登录用户、内容作者、目标用户、被互动用户、管理员/审核员、系统任务。
将“匿名 Trace"放入角色矩阵,问题会自然暴露:
- 作者自己能不能在个人主页看到?
- 别人看作者主页能不能看到?
- 管理员能不能看到真实作者?
- 被评论的人能不能知道是谁评论?
3. 边界收束:Surface 扫描
不要只盯着主页面。一个 Concept 会经过系统的哪些出口?
- 展示层:页面、Profile、推荐流
- 交互层:接口、搜索、分享
- 通知层:Push、站内信、邮件、WebSocket
- 数据层:缓存、日志、埋点、后台、审核
协作项目中常见的 Bug 本质往往是:主发布链路考虑了匿名,但推送出口没有考虑,Profile 出口没有考虑。
因此,每个功能都要问:除了主页面,还有哪些地方会消费这个对象?
三、验收与交付:反向思考
1. 验收反例
每个需求至少写 3 个“不能发生什么”。需求的真正复杂度,往往藏在“不应该发生什么”里面。
- 用户不能从作者主页看到该匿名 Trace。
- Push 不能展示真实作者名。
- 普通用户接口不能拿到真实 Author 信息。
- 搜索结果不能暴露作者。
2. 正确的 Dev Ticket
最后得到的开发任务不应该是模糊的“实现匿名 Trace",而应该是明确的约束列表:
实现匿名发布 Trace:
- 普通用户视角不得暴露作者身份
- 作者本人和管理员可见真实作者
- 他人 Profile 不展示匿名 Trace
- Push / 站内通知不得使用真实作者信息
- 所有普通用户接口返回 viewer-safe trace view
- 验收需覆盖 Feed、Detail、Profile、Notification
四、执行标准:Definition of Ready
不是所有需求都需要走这个流程,但涉及以下类型的需求必须执行:
- 身份类:匿名、实名、马甲、作者、资料页
- 权限类:私密、可见范围、屏蔽、拉黑
- 关系链:关注、好友、群组、邀请
- 通知类:Push、站内信、红点、邮件
- 内容流动:Feed、推荐、搜索、分享
- 审核风控:举报、删除、封禁、降权
- 金钱权益:会员、积分、红包、兑换
- 数据留存:删除、导出、注销、隐私
给开发工作设一个门槛:一个 Concept 只有满足 Definition of Ready,才允许进入开发。
✅ Definition of Ready Checklist
- 能用一句话说清功能意图
- 写出了至少 1 条产品不变量
- 列出了涉及角色
- 列出了主要系统出口
- 写出了至少 3 个反向验收场景
- 明确哪些旧假设会失效
五、AI 的正确用法:语义编译官
在 AI 辅助编程(Vibe Coding)流行的今天,不要把 AI 仅仅当作代码生成器。
错误的用法:
老板:做匿名发布 你:AI,开写
正确的用法:
老板:做匿名发布 你:AI,先帮我做需求编译 AI:列出语义、角色、出口、反例 你:审查并确认 Dev Ticket AI:再写代码
AI 应该依次扮演:产品分析员 → QA → 架构审查员 → 反例生成器 → 最后才是 Coder。
你可以使用以下 Prompt 固定这个流程:
下面是一个老板随口提出的产品 concept:
【填入 concept】
请不要写代码。先帮我把它编译成开发需求。
请输出:
1. 功能意图
2. 这个 concept 改变了哪些旧系统假设
3. 产品不变量
4. 角色矩阵
5. 影响出口,包括页面、接口、通知、profile、搜索、分享、后台、日志、埋点
6. 至少 5 个反向验收场景
7. 最小可实现版本的 dev requirement
要求:
- 不要假设只有主流程
- 特别检查权限、身份、可见性、通知、缓存、数据泄漏
- 对不明确的地方标记为“需确认”
结语
这不是要拒绝 Vibe Coding,而是给 Vibe Coding 加一道语义编译关。通过流程化的需求编译,我们将模糊的概念转化为严谨的系统语义,从而从根本上减少因“过期世界观”导致的系统 Bug。