Friction as Design Signal(摩擦作为设计信号)

定义

Friction as Design Signal 是一种工程判断:开发中的困难、停顿和理解阻力不一定是浪费,它们可能是在提示架构、抽象、数据模型或团队协作方式有问题。

为什么 AI 时代更重要

Vibe Coding 的吸引力在于消除摩擦:更快生成代码、更快看到产品、更少手动查资料。Harris 的反向提醒是,摩擦本身常常携带信息。

当开发者逐行阅读陌生代码、写 ADR、暂停实现、出门散步、重新审视架构时,他们不是低效,而是在让系统的真实约束浮上来。LLM 可以帮助执行,但如果它直接把所有阻力都“编码穿过去”,团队可能错过更早的设计信号,最后留下只有 prompt 历史、没有设计理由的系统。

Why I Don’t Vibe Code 的重点不是反对 LLM,而是反对把设计判断、抽象选择和责任承担交给 LLM。摩擦作为设计信号,就是这条边界的操作化版本:AI 可以帮你跨过偶然复杂性,但不能替你判断哪些阻力正在暴露 本质复杂性

摩擦分类

不是所有摩擦都值得保留。治理这个概念时,先要区分摩擦类型。

摩擦类型例子处理方式
偶然摩擦API 参数难查、格式转换、样板代码、环境命令交给工具或 Agent 自动化
本质摩擦概念边界不清、行为难测试、领域例外变多暂停、建模、补测试和 ADR
社会摩擦责任归属、团队协作、用户后果、合规风险明确 owner、升级路径和验收标准
认知摩擦读不懂历史代码、命名混乱、抽象过早close reading,重命名,清理概念模型

好的 Agentic Engineering 不是消灭全部摩擦,而是把不同摩擦放进不同处理路径。

何时保留摩擦

出现以下信号时,摩擦通常值得被认真读取。

  • 代码“能写出来”,但测试难写,因为行为边界没有说清。
  • 类名、函数名和领域词反复换,说明概念模型不稳定。
  • Agent 连续生成多个可运行方案,但每个方案都让系统更难理解。
  • 开发者必须解释一串历史例外,才能说明一个小需求。
  • 需求牵涉真实人的损失、公共服务失败、合规或法律后果。
  • 团队想跳过 ADR、review 或用户验证,只因为 AI 已经生成了代码。

这些摩擦不是速度问题,而是系统在提示:当前抽象、边界或责任模型不够好。

何时消除摩擦

以下摩擦通常应被工具消除,而不是被浪漫化。

  • 机械查文档、找参数、转换格式、补样板代码。
  • 低风险、可回滚、可自动验证的小改动。
  • 明确重复的命名清理、文件拆分和测试补齐。
  • 环境配置和工具链噪音,只要不会掩盖真实设计问题。

这里可以放心使用 Agent。技术债务避免 的核心就是让 coding agent 处理概念简单但人工耗时的清债任务,同时保留测试、review 和责任边界。

操作流程

把摩擦当作设计信号时,可以按五步处理。

停下
  -> 命名摩擦
  -> 分类:偶然 / 本质 / 社会 / 认知
  -> 决定:自动化 / 记录 / 重构 / 升级
  -> 用测试、ADR 或代码变更固化学习

这个流程的关键是留下可复用证据。只是在脑中“感觉哪里不对”不够;要把判断写成测试、ADR、命名、边界、约束或删除代码的决定。

与 Vibe Coding 的边界

Vibe Coding 的风险不是“用了 AI”,而是把速度和流畅感误认为理解。LLM 可以把难写的代码快速写完,但如果开发者不知道为什么这段代码难写,就可能把结构性警报包进更多生成代码里。

因此,摩擦作为设计信号要求人类保留三项工作:

  • Close reading:读懂系统为什么已经长成这样。
  • Design record:用 ADR、测试和注释记录关键选择。
  • Accountability:承认最终后果仍由团队承担,而不是由模型承担。

这也连接 YAGNIAI-Restraint:有些时刻正确动作不是继续生成,而是少做、删除、推迟或请人审。

注意力和承诺层面的摩擦

20260531-thoughts-hmmz 把“摩擦作为信号”从代码设计扩展到个人注意力和产品承诺。作者的问题不是 AI 不能生成软件,而是它太容易把一个“快速脚本”扩张成无人维护、无真实需求、无市场路径的项目。

这说明有些摩擦不只是在提示架构问题,也在测试人的承诺:

  • 我真的需要这个东西吗?
  • 我愿意维护它吗?
  • 它解决的是原始问题,还是只是生成过程给了我即时奖励?
  • 如果没有 AI 的流畅反馈,我还会做它吗?

这类摩擦被完全消除后,就会进入 零摩擦范围蔓延:每个新增动作都局部合理,但整体注意力和维护责任被拖向低价值方向。

关键数据点

  • 作者把 close reading 视为理解代码选择、语言惯用法和约束来源的必要过程。
  • 当写代码变难时,作者把它当作当前架构路径可能错误的信号,而不是单纯的生产力问题。
  • 作者用 ADR 固化当下假设、设计理由和后果,以便未来团队能重建“当时为什么这么做”。
  • source summary 明确提醒:并非所有摩擦都值得保留,环境配置、API 参数和样板代码常常只是浪费认知带宽。
  • 迁移判断:AI Coding 的正确目标不是消灭开发者思考,而是把人的判断力放在更高杠杆位置。

前提与局限性

  • 前提: 摩擦来自真实复杂性,而不是文档缺失、工具损坏或重复劳动。
  • 前提: 团队愿意把停顿视为理解系统的机会,而不是只用速度衡量工程价值。
  • 局限: 低价值摩擦仍应被工具消除,例如机械查参数、重复格式转换、可完全自动验证的小改动。
  • 局限: 摩擦不能被浪漫化;没有验证、没有记录、没有设计产出的停顿也可能只是拖延。
  • 局限: 资深工程师更容易从摩擦中读出设计信号;新手可能需要 LLM 和导师先帮助跨过入门门槛。
  • 误用风险: 把“保留摩擦”当成拒绝工具、拒绝自动化或拖慢团队的借口。

关联概念

  • Essential-Complexity — 摩擦经常是本质复杂性显形的方式。
  • Ownership — 愿意面对摩擦,是对系统后果负责的一部分。
  • Judgment — 判断哪些摩擦该消除、哪些摩擦该保留。
  • Agentic-Engineering — 好的 Agentic Engineering 应保留关键设计反馈,而不是只追求生成速度。
  • Technical-Debt-Avoidance — 提前识别摩擦可避免把结构问题沉淀为技术债。
  • Vibe-Coding — 如果只追求流畅生成,容易绕过设计信号。
  • YAGNI — 少做和推迟实现是保留判断空间的一种方式。
  • AI-Restraint — 高风险和不确定场景中,停止行动本身是能力。
  • Code-as-Conceptual-Infrastructure — 摩擦常常暴露代码背后的概念模型问题。
  • Zero-Friction-Scope-Creep — 当筛选摩擦被 AI 消除,项目和功能会无边界扩张。