了解如何通过从路由和组件中提取真实应用行为,用代码为 Claude Code 生成特性规范,并产出可维护的活文档规范与差距清单。

人们对应用的功能会有分歧,因为他们记住的是不同版本。支持团队记得最后一张愤怒的工单。销售记得演示路径。工程师记得功能最初的设计。问三个人,你会得到三种自信的答案,而没有一种与当前构建相符。
随着时间推移,代码成了唯一保持最新的来源。文档会漂移,工单会关闭,临时修复会堆积。某个路由增加了新的校验规则。界面开关改变了默认值。处理器开始返回不同的错误。没人更新规范,因为看起来可有可无,而且每次改动又太小,不值得记录。
这会产生可预见的问题。团队会发布破坏他们不知道存在的边缘情况的改动。QA 只测试顺利路径,错过了隐藏在处理器里的规则。新同事从 UI 复制行为,却不了解实际约束。利益相关者争论各自的观点,而不是指向约定的行为。
好的结果不是完美的文档,而是共享的清晰认知。每个人都应该能回答:"如果我做 X 会发生什么?" 和 "系统保证了什么?",而无需猜测。这样你会遇到更少的意外,审查周期更短,也会减少“等等,它已经能做了”那种时刻,因为团队看的是真实的事实。
当规范与代码一致时,就可以更安全地规划变更。你可以在发布前看出哪些是稳定的、哪些是偶然的、哪些是缺失的。
活文档规范是一段简短、可编辑的说明,描述应用目前实际的行为。它不是一次性文档,而是在行为改变时随之更新,让团队可以信任它。
当人们谈到从代码生成特性规范(例如使用 Claude Code)时,目标很简单:从路由、处理器和界面读取真实行为,然后用通俗语言记录下来。
有用的活文档规范关注用户可见的行为与系统的承诺,应该覆盖:
不应包含的是代码如何组织的细节。如果你开始命名文件或重构计划,那就是进入了实现细节。避免:
差距清单是单独的。它是一小段在编写规范过程中发现的不匹配和未知项的列表。
示例:某个路由拒绝超过 10MB 的文件,但 UI 说是 25MB。在团队决定哪个规则为准并更新代码或规范之前,这都是一个差距。
从小处开始。如果你试图记录整个应用,你会得到一堆没人信任的笔记。选一个用户能用一句话描述的切片,例如“邀请队友”、“结账”或“重置密码”。理想的范围是一块功能区域、一个模块或从入口点到结果的一条用户旅程。
根据事实所在选择入口:
在读代码之前,收集一些输入以便快速发现不一致:现有的 API 文档、旧的产品说明、支持工单,以及人们抱怨的“已知痛点”。这些并不覆盖代码,但能帮你注意到缺失的状态,如错误、边缘情况和权限问题。
保持规范格式枯燥且一致。团队在每份规范读起来相同的时候更容易达成一致。
反复使用此结构,你的特性规范将保持可读、可比较且易于更新。
从服务器入口点开始。路由和处理器以具体的方式展示“应用做了什么”:谁可以调用、他们必须发送什么、返回什么以及系统中发生了哪些变化。
列出范围内的路由并将每个路由映射到一个用户意图。不要写“POST /api/orders.”,而要写“下单”或“保存草稿”。如果你无法用通俗语言命名这个意图,那已经是一个规范差距。
在阅读每个处理器时,把输入和校验规则记录为面向用户的需求。包括必填字段、允许的格式以及会导致真实错误的规则。例如:“Email 必须合法”,“数量至少为 1”,“开始日期不能是过去时间”。
以同样方式记录认证和角色检查。不要写“middleware: requireAdmin”,而是记录:“只有管理员可以取消任意订单;普通用户只能在 10 分钟内取消自己的订单。”如果代码检查所有权、功能开关或租户边界,也要把这些包含进去。
接着记录输出和结果。成功返回什么(创建的 ID、更新的对象)?常见失败是什么样的(401 未登录、403 无权限、404 未找到、409 冲突、422 校验错误)?
最后记录副作用,因为它们也是行为的一部分:创建或更新的记录、发送的邮件或通知、发布的事件、入队的后台任务,以及任何触发其他流程的操作。这些细节可以防止团队在后续依赖规范时遭遇意外。
路由告诉你应用能做什么。组件告诉你用户实际体验到了什么。把 UI 当作契约的一部分:展示什么、什么被阻止、以及出错时发生什么。
先找到功能的入口界面。查找页面组件、布局包装器和几个决定性组件(控制获取、权限和导航)。真实行为通常就藏在这些地方。
阅读组件时,捕获用户能感受到的规则:何时动作被禁用、必需步骤、条件字段、加载状态、错误如何显示(字段下方内联错误还是 toast,是否自动重试、是否显示“重试”按钮)。还要记录状态与缓存行为,例如先显示过期数据、乐观更新或“最后保存时间”戳。
注意那些悄悄改变用户所见的隐藏流程。搜索功能开关、实验桶、仅管理员可见的门控。记录静默重定向,例如把未登录用户送到登录页,或把无访问权限的用户送到升级页。
一个具体例子:在“修改邮箱”界面,记录 Save 按钮在邮箱合法前保持禁用,请求期间显示加载 Spinner,请求成功后触发确认横幅,后端校验错误在输入框下方显示。如果代码有像 newEmailFlow 的开关,记录两个变体及其差异。
把每个 UI 流写成简短步骤(用户做什么,界面如何响应),并把条件与错误放在影响的步骤旁边。这样规范更可读,也更容易发现差距。
从路由和组件得到的原始笔记虽然有用,但难以讨论。把观察到的内容改写成 PM、设计师、QA 和工程师都能阅读并达成一致的规范。
一个实用做法是每个路由或界面写一条用户故事。保持小而具体。例如:“作为已登录用户,我可以重置密码以便重新获得访问权限。”如果代码显示按角色(管理员与普通用户)有不同行为,把它分成不同的故事,而不是藏在脚注中。
然后编写与真实代码路径相对应的验收标准,而不是理想化的产品行为。如果处理器在缺少 token 时返回 401,那就是一个验收标准。如果 UI 在字段有效前禁用提交按钮,那也是一个验收标准。
以通俗语言包含数据规则,尤其是那些会导致意外的规则:限制、排序、唯一性、必填字段。“用户名必须唯一(在保存时检查)”比“唯一索引”更清晰。
边缘情况往往决定文档是好是有用。标出空状态、null 值、重试、超时以及 API 调用失败时用户会看到什么。
当遇到未知项时,标注而不是猜测:
这些标注会变成快速的团队问题,而不是无声的假设。
差距清单不是第二个 Jira。它是一份基于证据的简短记录,指出代码与期望行为的不匹配,或无人能清楚解释“正确”行为的地方。做好后,它是达成一致的工具,而不是规划争论的战场。
严格定义什么算差距:
记录差距时包含三部分以保持依据:
证据能防止清单变成意见。例如:“POST /checkout/apply-coupon 接受过期优惠券,但 CouponBanner.tsx 在 UI 上阻止过期券。影响:收入与用户混淆。类型:bug 或 缺失决策(需确认意图)。”
保持简短。为第一次评审设定上限,例如最多 10 项。如果你发现 40 个问题,将它们归类为模式(校验不一致、权限检查、空状态),并只保留最重要的示例。
避免在差距清单中安排日期或排期。如果需要归属,只需轻量记录:谁应做决定(产品)或谁能验证行为(工程),真正的计划移到你的待办列表中。
选一个小而高流量的范围:带促销码和配送选项的结账。目标不是重写整个产品,而是捕捉应用今天的行为。
从后端路由开始。这通常是规则首先出现的地方。你可能会看到 POST /checkout/apply-promo、GET /checkout/shipping-options 和 POST /checkout/confirm 之类的路由。
从这些处理器中,用通俗语言写出行为:
然后检查 UI 组件。PromoCodeInput 可能只在成功响应后刷新总价,错误在输入下方内联显示。ShippingOptions 组件可能在首次加载时自动选择最便宜的选项,并在用户更改时触发完整的价格明细刷新。
现在你有了一份可读的规范和一个小的差距清单。例如:促销接口和 UI 的错误消息不同(“Invalid code” vs “Not eligible”),且没人能说明税费舍入规则(按行 vs 按订单总额)。
在规划时,团队先就现实达成一致,再决定要改哪一处。与其争论意见,不如审阅有证据的行为,选择一个不一致修复,其余保留为“当前已知行为”,直到值得重访。
规范只有在团队同意它符合现实时才有用。与一名工程师和一名产品人员进行一次简短的过目。保持紧凑:20–30 分钟,关注用户能做什么以及系统如何响应。
在过目过程中,把陈述转为是/否 问题。“当用户访问此路由时,我们是否总是返回 403(未授权)?”,“这个空状态是刻意设计的吗?”这样可以把意图行为和历史遗留的偶发行为区分开来。
在编辑前先统一词汇。优先使用界面上的术语(按钮标签、页面标题、错误消息),仅在有助于工程师定位代码时加入内部名称(路由名称、组件名称)。这能避免产品称之为“Workspace”而规范写成“Org”之类的不匹配。
为保持其最新,明确归属与节奏:
如果你使用像 Koder.ai 这样的工具,快照和回滚能帮助你在大规模重构后比较“变更前”和“变更后”的行为,这尤其有用。
丢失规范信任的最快方式是描述你想要的产品,而不是你已有的产品。坚持一条硬规则:每一条陈述都应该能指向代码或真实界面中的证据。
另一个常见陷阱是把代码结构直接照搬进文档。一份读起来像 “Controller -> Service -> Repository” 的文档不是规范,而是文件夹映射。用面向用户的语言写:是什么触发了操作,用户看到了什么,保存了什么,错误是什么样子。
权限和角色常被忽略直到最后,然后一切都崩掉。早期就添加访问规则,即便它们很混乱。列出哪些角色可以查看、创建、编辑、删除、导出或批准,以及规则在哪被强制(仅 UI、仅 API、或两者)。
不要跳过非顺利路径。真实行为藏在重试、部分失败和基于时间的规则中,例如过期、冷却、计划任务或“每天只能一次”的限制。把这些当作一等公民行为。
快速揭示差距的办法是检查:
最后,让差距清单保持流动性。每个差距应被标为:"unknown/needs decision"、"bug/fix" 或 "missing feature/plan"。如果没有标注,这个清单就会停滞,规范也会停止成为“活”的文档。
做一次快速校对,关注清晰度、覆盖面和可操作性。没有写这份文档的人应该能理解这个功能今天做什么,以及哪些地方不明确。
像新同事第一天那样阅读规范。如果他们能在一分钟内总结出功能,你就接近目标了。如果他们不断问“从哪开始?”或“什么是顺利路径?”,就需要收紧开头部分。
检查:
每个差距应具体且可测试。不要写“错误处理不明确”,要写:“当支付提供商返回 402 时,UI 显示通用 toast;确认期望消息和重试行为。”为每个差距添加一个下一步动作(询问产品、添加测试、检查日志)并标明谁应回答。
选一个功能区域并限定 60 分钟。选一个小但真实的功能(登录、结账、搜索、某个管理界面)。写一句范围说明:包含什么、不包含什么。
端到端运行一次流程:略读关键路由/处理器,跟踪主要 UI 流程,记录可观察的行为(输入、输出、校验、错误状态)。如果卡住了,就把问题记录为差距并继续。
完成后,把规范分享给团队供评论,并设一条规则:任何发布的行为变更必须在同一交付周期内更新规范,即便只是五行改动。
把差距与待办分开。将它们归类为 “unknown behavior”、“inconsistent behavior” 和 “missing tests”,然后每周简短审阅一次以决定当下重要的事项。
如果起草与迭代感觉缓慢,像 Koder.ai 这样的聊天生成工具可以帮助你快速得到第一版。描述功能、粘贴关键代码片段或路由名称、在对话中细化措辞并在需要时导出源码。重点是速度与共享的清晰,而不是更大的流程。
从一个小且对用户可见的片段开始(例如“重置密码”或“邀请成员”)。先阅读 routes/handlers 捕获规则和结果,然后阅读 UI 流程 捕获用户实际看到的内容(禁用状态、错误、重定向)。用一致的模板整理,并把不确定项记录到单独的差距清单里。
默认把当前代码行为当作事实来源并记录下来。
如果行为看起来是偶然的或不一致,不要在规范里把它“修正”——把它作为带证据的 差距 标注(说明在哪看到的以及它的表现),然后由团队决定是更新代码还是更新规范。
保持格式无聊且可复用。一个实用模板:
这种结构能让规范保持可读性,并更容易发现不一致。
把校验和权限检查写成面向用户的规则,而不是代码注释。
示例:
记录触发错误的条件以及用户看到的表现。
关注可观察到的输出:
侧面影响会影响其他功能以及支持/运维预期,所以必须记录清楚。
如果 UI 阻止了后端允许的操作(或反之),把它记录为 差距,直到达成决定。
记录内容应包括:
然后统一成一条规则并同时更新代码和规范。
保持差距清单简短并基于证据。每项应包含:
避免把差距清单变成另一个待办排期表。
明确记录这些情况,而不是掩盖它们。
包括:
这些通常是惊喜和 Bug 的来源,应该被优先记录。
简短验证:与一名工程师和一名产品人员进行 20–30 分钟的快速过目。
把陈述转换为是/否 问题(例如,“当未授权时我们总是返回 403 吗?”)。使用界面上的词汇(按钮标签、页面标题、错误消息)统一术语,确保大家说的都是同一件事。
把规范放近代码并把更新当作发布流程的一部分。
实用默认做法:
目标是小而频繁的修改,而不是一次性大改。