技术实现文档(TRD)写作规范(架构视角、模块边界)
适用范围
- 适用对象:架构师、技术组长、核心开发、实际落地开发者(默认读者具备技术背景,需要知道架构边界,也需要理解最终怎么改)
- 适用场景:
- PRD评审通过后,技术方案设计阶段
- 跨团队/跨模块协作前的接口对齐
- 复杂业务的技术方案评审(需要架构决策时)
- 遗留系统的模块重构/技术债务梳理
- 执行前需要收束最终实现方案,或执行后需要把实际操作记录回 TRD
与PRD的关系
| 维度 | PRD(业务向) | TRD(技术向) |
|---|---|---|
| 读者 | 业务、产品、运营 | 架构师、技术组长、核心开发 |
| 回答的问题 | "做什么"、"业务规则是什么" | "怎么做"、"模块如何划分"、"边界在哪里"、"最终为什么这么落地" |
| 内容来源 | 业务需求、运营规则 | PRD + 技术约束 + 架构演进规划 |
| 评审目标 | 业务可行性、规则完整性 | 技术可行性、扩展性、风险点 |
关键原则:TRD 必须在 PRD 定稿后编写,以PRD为输入,不篡改业务规则,只补充技术实现方案。
写作定位(先纠偏)
TRD 不是"把实现写成代码",而是让读者快速建立心智模型,并能无负担地往下看。初版 TRD 应包含一版可执行的最终落地方案,避免评审后再补一份脱离主文档的实现说明。
- 1分钟:知道当前现状、方案主链路、切入点、最终决策、关键风险
- 5分钟:知道模块如何协作、接口如何对齐、关键决策为何这么选
- 15分钟:可以参与评审、任务拆分,并理解第一版代码落地路径
读者体验原则(必须遵守)
- 结论先行:先给总结性内容,再展开;不要让读者"读到最后才知道重点"
- 先讲现状:修改型需求必须先说明当前链路与改造切入点;新增需求也要说明挂载到哪个既有业务上下文
- 先收束再落地:最终落地方案必须说明"最终选什么、不选什么、为什么",再列修改项
- 图+表优先:关系用图,清单用表;段落只解释"为什么/取舍/风险"
- 渐进式披露:越往后越细,但不跨越 TRD 红线;同一信息不要重复出现
- 降低心理负担(默认约束):
- 主体章节单段 ≤ 5 行;最终落地章节可放宽到 ≤ 8 行,但必须服务于决策说明
- 单列表 ≤ 9 条(超过就分组/合表/拆文档)
- 单张图 ≤ 12 个节点(超过就分层)
- 话术精简/精准/简洁:一句话只表达一个结论;避免长段叙述
颗粒度红线(写到这里就停)
TRD 只回答这些问题(写清楚即可):
- 现状与切入点:当前业务/技术链路是什么,本期从哪里接入、扩展或替换,哪些边界保持不变
- 模块划分:系统拆分为哪些模块/服务/子系统,每个的职责范围
- 接口契约:模块间交互的接口定义(入参/出参/错误码/调用方式),但不写具体字段校验逻辑
- 数据流向:核心业务数据如何在模块间流转(可结合时序图)
- 状态与事件:业务状态迁移由谁负责、通过什么机制(事件/消息/状态机)
- 非功能性需求:性能指标、并发预期、容错策略、降级方案
- 依赖与风险:外部系统依赖、技术债、潜在阻塞点
- 最终落地实现方案:最终决策、代码架构/实现细节、实际修改点、风险是否真实成立、不改范围
- 外部变更项:哪些落地动作需要在代码之外人工执行(数据库结构、外部编排、配置等),允许写到字段级细节
以下内容默认 不属于 TRD(应迁出到其他文档):
- 完整代码实现:大段代码、完整 SQL、ORM 配置细节、逐行算法逻辑
- 完整数据库设计:全量字段定义、索引设计、建表 DDL(属于详细设计或DB设计文档);但外部变更项中可以点名涉及的表和字段,不做整表设计即可
- 接口的逐字段校验逻辑:如"字段A长度不能超过50"这类规则(若PRD未规定,应在开发阶段确定)
- 单元测试用例:测试策略可以提,具体用例在测试文档中
- 部署脚本/配置项:属于运维文档或配置中心管理内容
允许在"最终落地实现方案"中点名必要的类、方法、常量、配置项、表或接口,但必须满足两个条件:它们是最终修改清单的一部分;点名是为了说明决策和边界,而不是做代码逐行讲解。
判断是否"写得太细"的快速标准:
- 如果一段内容可以直接被开发人员复制粘贴成完整代码,就写得太细了。
- 如果一段内容是在解释"每一行代码怎么写",而不是"为什么最终只改这些点",就应该从 TRD 迁出。
- 如果修改型需求直接从目标方案开始写,没有说明当前链路和改造切入点,就写得太跳跃。
禁止项(不要写)
- 不要出现:与最终修改无关的类名、方法签名、SQL语句、框架注解、配置项key名
- 不要画:代码调用链路图、类图(UML Class Diagram)、ER图(除非用于表达模块间关系而非数据结构)
- 不要罗列:接口的每一个字段校验规则、每一个错误码对应的提示文案
- 不要写:具体的部署IP、密码、密钥等敏感信息
- 不要重复:PRD中已经详细描述的业务场景(只引用,如"见PRD第X章场景Y")
- 不要扩散:不要因为理论风险新增配置、抽象层、兼容分支或重构,除非已经证明风险在当前业务链路中真实成立
文档顶部固定结构(必须有,一屏读完)
- 标题:
# <模块/功能> 技术实现文档 - 元信息(四行):
- 文档类型:技术实现文档
- 关联PRD:[链接到对应PRD文档]
- 适用对象:架构师、技术组长、核心开发
- 评审状态:草稿/评审中/已批准/已归档
- 版本记录表(必须放顶部,便于追溯):
| 版本号 | 更新时间 | 作者 | 备注 |
|---|---|---|---|
| v1.0 | yyyy-MM-dd | 姓名 | 初版/架构对齐后更新 |
- 变更摘要(与上一版本相比的关键变化,3-5条bullet):
- 模块X职责调整:原本负责A,现拆分为X负责A1,Y负责A2
- 接口变更:新增接口Z用于支持PRD中的XX场景
推荐章节结构(强制渐进式)
0)一屏摘要(必须有,优先级最高)
按"总结 → 图 → 表"的顺序组织,读者扫一遍就能继续往下读:
- 一句话方案:用 1 句描述主链路(建议格式:
入口 → 认证/鉴权 → 核心处理 → 隔离/一致性 → 输出) - 系统交互图(1张):只画"外部系统/入口/核心模块/存储",不画细碎内部组件
- 3张表(必填)+ 1个落地摘要(修改型/落地型需求建议保留):
- 关键决策(ADR)表:决策点 + 前提(现状/目标/约束)+ 结论 + 依据(3-7行)
- 每行必须读得通一条"因为前提如此 → 所以这么选"的推理;前提不限于现状,也可以是性能、可维护性、迁移成本等技术指标与目标——从哪个前提出发都行,但推理必须成立
- 自检:遮住结论只看前提,读者应能大致推出同样结论,推不出就是依据没写实
- 依据必须具体可核对:现状就写链路事实(数据形态、调用方式、既有机制边界),目标就写可衡量的点(量级、成本、频率);不接受"更合理/更成熟/更优雅"类形容词
- 新增需求没有现状链路时,前提写"现有上下文缺什么/本期要达到什么",不硬凑问题
- 确实权衡过的备选,在依据里自然带出不选的原因;没认真考虑过就不写,不凑数
- 模块职责表:模块、职责一句话、输入/输出、边界(5-9行)
- 接口清单表:接口/事件、调用方向、方式、目的、鉴权/隔离、幂等/重试、失败策略(不展开字段)
- 落地修改摘要:最终改什么、不改什么、是否存在外部变更项、为什么不扩散(≤5行;完整内容放第6节)
- 关键决策(ADR)表:决策点 + 前提(现状/目标/约束)+ 结论 + 依据(3-7行)
图的要求(为了"好读",不是为了"全")
- 默认 1 张图足够;只有"难理解的流程"才补第 2 张关键流程图
- 节点 ≤ 12;超过就分层拆图
- 图里只放名词与方向箭头;解释放图下 3 行内
graph TB
External[外部调用方] -->|HTTP| Entry[入口/适配层]
Entry --> Auth[认证/鉴权]
Entry --> Biz[核心业务编排/委托]
Biz --> DB[(主库)]
Auth --> Cache[(缓存/会话)]
1)现状与切入点(修改型需求必填,新增型需求可简写)
目的:让读者先理解"当前怎么跑、为什么不够、本期从哪里切入、哪些边界不动"。这不是背景铺垫,而是开发者建立存量系统心智模型的入口。
先判断需求类型:
| 类型 | 写作重点 | 最少要交代 |
|---|---|---|
| 新增需求 | 新能力挂载到哪个既有业务上下文 | 上游入口、下游消费者、复用的公共能力 |
| 修改需求 | 当前链路如何被改变 | 现状、当前不足、本期切入点、不改范围 |
| 混合需求 | 先写被修改的主链路,再写新增能力 | 修改边界、新增边界、二者协作关系 |
推荐使用 1 张表:
| 当前场景/既有机制 | 当前不足 | 本期切入点 | 不改范围 |
|---|---|---|---|
| 现有查询由权限模块统一注入范围 | 不支持按有效期裁剪 | 在范围计算层补充有效期口径 | 不重写查询入口和鉴权模型 |
写作要求:
- 只写业务链路和模块承载,不写类名、方法名、SQL 或配置 key
- 优先说明"复用什么、扩展什么、不改什么"
- 修改型需求不要只写"新增模块 X",要说明它接入哪条现有链路
- 新增需求不要假设系统是白纸,要说明它挂载到哪个既有上下文
- 如果当前事实来自代码、配置或历史文档,但不确定是否仍有效,要标记为待确认风险
2)需求-技术映射(可选,建议保留但要短)
- PRD核心点:3-5条(只写关键词)
- 技术策略:每条 1 句话(只写策略/机制/边界,不写实现细节)
| PRD需求 | 技术实现要点 |
|---|---|
| 销售只能看到自己负责的客户 | 查询统一加"客户范围"过滤,由权限模块提供范围 |
| 指派关系支持有效期 | 范围计算时按有效期裁剪,过期自动失效 |
3)模块划分与职责边界(必须短)
优先用"模块职责表",然后只对关键 1-3 个模块补充说明(每个模块 ≤ 12 行)。
模块X:[模块名称]
- 职责:一句话(负责什么)
- 边界:一句话(不负责什么)
- 对外能力:1-3条(接口/事件名 + 用途 + 调用方)
- 依赖:依赖谁做什么
4)接口契约(必须表格化)
| 接口/事件 | 调用方向 | 方式 | 目的 | 鉴权/隔离 | 幂等/重试 | 失败策略 |
|---|---|---|---|---|---|---|
| XXX | A → B | 同步HTTP/RPC | 做什么 | 依赖什么身份 | 是否幂等 | 降级/告警/返回 |
5)NFR 与风险(合并为一页)
用表格表达 NFR;风险用 3-7 条 bullet 表达(每条包含"影响 + 缓解")。
| 维度 | 要求 | 实现策略 |
|---|---|---|
| 性能 | 目标:P99/吞吐 | 缓存/并发/超时/降级 |
| 安全 | 不越权/可审计 | 统一鉴权 + 审计日志 |
| 稳定性 | 依赖故障不拖垮主链路 | 限流/熔断/降级 |
风险评估必须区分"理论风险"和"实际风险":
- 实际风险:在当前业务链路、数据形态、调用方式中真实可能发生,需要进入方案
- 理论风险:只在抽象模型里成立,但与当前链路前提冲突,不应驱动新增封装或拆分
- 对理论风险要写清楚"为什么实际不成立",然后收束方案,不要为了显得稳妥扩散需求
6)最终落地实现方案(必须有)
目的:把评审后的最终动作前置到 TRD 初版里,让读者知道"最终怎么改、为什么只这么改、哪些不改"。这一节可以比前文更贴近代码架构和实现细节,但必须服务于决策,不写成代码教程。
6.1 最终决策
用 3-5 行说明:
- 最终选型:选择哪个实现方式
- 放弃方案:明确不采用哪些备选方案
- 选择理由:为什么当前方案最贴合真实链路
- 不扩散理由:为什么不新增配置、抽象层、兼容分支或重构
6.2 落地修改清单
优先使用表格,修改项必须收束,不要把"顺手优化"写进来。
| 修改点 | 动作 | 为什么这样改 | 不改边界 |
|---|---|---|---|
| 某常量/某配置/某方法 | 改值/复用/删除/新增 | 对应哪个最终决策 | 哪些链路、接口、文案、结构保持不变 |
写作要求:
- 可以点名必要的类、方法、常量、配置项、表或接口
- 不贴完整代码;如必须展示,只展示关键 1-3 行差异
- 修改项控制在 3-9 行;超过时先判断是否需求扩散
- 如果最终实际只改 1 行,就明确写"改动范围:1 个文件,1 行"
- 如果用户是在执行后要求记录,以实际执行结果为准,更新版本记录、变更摘要和本节;不要重新展开已经放弃的备选方案
6.3 外部变更项(必须有,无则写"无")
列出需要在代码之外人工执行的变更:数据库结构、外部编排 DAG、配置、中间件资源等。这类变更不体现在代码 diff 里,容易被遗漏,必须显式声明。本节允许写到字段级细节。
| 变更项 | 变更内容 |
|---|---|
客户表 customer |
新增字段 assign_expire_time(指派有效期) |
| 数据同步 DAG | 新增清洗节点,过滤过期指派关系 |
- 与 6.2 分工:代码内改动写 6.2,代码外人工动作写本节
- 没有外部变更项时,写一句"无外部变更项,纯代码变更",不要省略本节
- 同样受收束原则约束:不要把"顺手加索引""顺手补配置"写进来
6.4 风险复核
用表格审查风险是否真实成立,避免因为理论风险过度设计。
| 风险/顾虑 | 是否实际成立 | 判断依据 | 最终处理 |
|---|---|---|---|
| 异常后锁僵持 | 不成立/成立 | 当前链路是否会复用同一标识、是否有清理机制 | 不拆分/拆分/监控/兜底 |
判断原则:
- 先看当前代码链路和业务操作是否真的满足风险前提
- 如果风险前提在实际链路中不成立,直接说明并拒绝为它增加设计
- 如果风险成立,再选择最小可行缓解,不默认引入新抽象
6.5 不改范围
列出 3-7 条明确不改项,帮助开发者停止扩散:
- 不改接口契约
- 不改错误文案
- 不改数据结构
- 不改调用链路
- 不引入新配置
- 不新增持久化层
7)演进规划(可选,但要短)
- 当前版本(MVP):一句话说明最小可用
- 后续迭代:3-5条方向(不写实施细节)
与PRD的衔接检查清单
在提交TRD评审前,确认以下事项:
- 已关联对应的PRD文档,且PRD状态为"已批准"
- TRD中的技术方案能完整支撑PRD中的所有业务规则
- 已判断需求类型:新增、修改或混合,并按类型写清现状上下文
- 若为修改型需求,已明确当前主链路、当前不足、本期切入点和不改范围
- 对于PRD中的约束条件(如有效期、权限范围),TRD中有对应的技术实现策略
- 未在TRD中重复描述PRD的业务场景(只引用)
- TRD中提到的接口/能力与PRD中的角色/操作能对应上
- 已写"最终落地实现方案",说明最终决策、修改清单、外部变更项、风险复核和不改范围
- 已列出外部变更项(可写到字段级);若无外部变更项,已明确写"无"
- 已审查风险是否真实成立,未因理论风险引入不必要封装、配置或重构
- 修改项已收束,没有扩散到 PRD 未要求的接口、数据结构、文案或流程
话术与表达(让人读得快)
- 先立原则:下面示例只示范"因为→所以对得上"的语气;按自己的实际推理写,不套句式、不填空
- 推荐表达:
- "当前链路由 X 承载,本期只扩展 Y 口径,不重写入口"
- "这是修改型需求:切入点在 X,保持 Z 的既有边界不变"
- "入口层只做适配与鉴权,业务仍由既有服务处理"
- "隔离维度为公司;所有查询必须带 company 条件(由统一能力注入)"
- "失败策略:降级为 X,不阻塞主链路,并告警"
- "所有查询都收口在范围计算层,有效期口径只改这里即全链路生效,入口不动"
- "想过让下游各自处理过期逻辑,但七处调用难免有漏,作罢"
- "日增量两百万行,全量刷新扛不住,改走增量同步"
- "最终落地选择 A,不采用 B;B 的风险前提在当前链路中不成立"
- "改动范围收束为 X 个文件/Y 个修改点,不改接口、文案和数据结构"
- "本期含 2 项外部变更:客户表新增有效期字段、同步 DAG 新增清洗节点"
- "无外部变更项,纯代码变更"
- 避免表达:
- "使用
@Service注解定义类CustomerServiceImpl" - "SQL语句为:
SELECT * FROM customer WHERE id IN (...)" - "字段
createTime使用@JsonFormat格式化" - "缓存key为
customer:range:{userId},过期时间3600秒" - "为了后续扩展,顺便抽一层通用能力"
- "选择 A 因为 A 更合理、更成熟"(形容词当理由,没有事实或指标支撑)
- "理论上可能有风险,所以新增一套配置和兜底链路"
- "使用
字数与拆分建议(弹性约束)
- MVP TRD 建议 ≤ 220 行:包含最终落地方案后不再强压到 150 行以内
- 复杂修改型 TRD 可放宽到 280 行左右:前提是新增内容集中在现状切入点、外部变更项、风险复核和最终落地方案
- 超出时优先"合表/删重复叙述/拆非核心细节",不要删掉最终决策依据
- 需要字段级/实现级细节时,拆出独立文档:
- 详细设计(DD):字段级契约、校验规则、异常码、边界Case
- DB 设计:表结构/索引/迁移
- 对接文档:第三方联调、示例请求响应、签名/加密细节