mirror of
https://github.com/dataelement/bisheng.git
synced 2026-08-30 17:58:00 +08:00
5.0 KiB
5.0 KiB
Design: <特性名称>
本文档定位 — 现状快照(Why this How)
spec.md回答 做什么(目标、AC、边界)design.md(本文)回答 为什么这么实现:关键决策、运行时不直观的事实、对外契约tasks.md是 流水账:拆了哪些任务、做了什么改动调整原则(详见
docs/SDD-Guide.md§3-§4):
- 实现变化 → 覆盖更新本文档,只留"今天的状态"、不留旧快照;但每个决策保留"为什么 + 被否方案"和坑(护栏,见 §3/§5)
- 偏差分级:推翻已 ★ 确认的决策 → 停下与用户重新确认;纯实现细节 → 直接改 design,不必停
tasks.md「实际偏差记录」只留一行指针(如"T7 偏离 → 更新 design 决策3"),论证在本文档,不重复
关联: spec.md · tasks.md 版本: v<X.Y.Z> 最后更新: YYYY-MM-DD(同步实现变更时一并更新)
1. 目标与非目标
- 目标:1-3 句话讲清这个 feature 在系统里扮演什么角色
- 非目标:明确不做什么(防止后人误扩范围)
2. 关键约束
本功能特有的硬性约束(决定下面方案对比的取舍空间)。
- 全局架构铁律(双 DB / 多租户 / 权限 / 分层 / 错误码)不在此重抄 —— 一句"遵循
docs/constitution.mdC1–C7"带过;本节只写本功能特有的:性能 / 容量 / 部署形态 / 上游数据格式依赖 等。 - 引用上游:
docs/constitution.md(铁律)、release-contract.md(版本契约 / 模块编码)。
3. 方案对比与选定
核心设计决策逐条记录。每条 3 段:备选 / 选定 / 原因。 这一节是 design.md 的最高价值部分 —— agent 接手时,先读这里就知道有哪些"想当然会走但被否决"的路。
决策 1:<决策主题>
- 备选:
- A. <方案 A> — 优点 / 缺点
- B. <方案 B> — 优点 / 缺点
- 选定:A
- 原因:<关键约束 / trade-off / 已知证据>
- 何时该重新考虑:<触发条件,例:QPS > X、双 DB 兼容性松动、上游数据格式变更>
决策 2:…
4. 系统现状(接手必读)
这里写"今天代码长什么样",让接手 agent 不用从 950 行 service 里反推。 不写实现细节代码,写业务话的流程 + 关键文件名 + 关键函数名。
4.1 数据流
<入口> → <处理 A> → <处理 B> → <出口>
每一步一句话:做什么 + 主要文件:行号或函数名。
4.2 关键数据结构 / 字段约定
写对外可见的契约(API request/response、消息字段、文件命名规则、ID 规则)。 内部数据结构不用写(看代码即可)。
| 字段 / 结构 | 类型 / 格式 | 说明 | 谁会消费 |
|---|---|---|---|
xxx.query |
JSON envelope {"query": str, "files": [...]} |
用户输入消息 | 导出 / 历史回放 |
4.3 关键模块职责
| 模块 / 文件 | 职责 | 不做什么 |
|---|---|---|
xxx_service.py |
业务编排 | 不直接写 ORM |
xxx_renderer.py |
输出格式化 | 不取数据 |
5. 已知坑 / 反直觉事实
最防失传的内容。代码里看不出、commit message 里散落、踩过才知道的东西。 每条要带"如果不知道会怎样",让后人知道严重性。
| # | 反直觉事实 | 如果不知道会怎样 | 在哪处理 |
|---|---|---|---|
| 1 | 运行时 parentMessageId 一直是空串,不能用来配对消息 |
配对全错,导出空白 | useMessageSelection.ts:buildPairGroup 改用数组位置 |
| 2 | 答案文本在 v2.5 agent-native 格式下只在 events[] 里,msg 可能为空 |
导出空答复 + RAG 角标残留 | _extract_answer_text 兜底从 events 取 + 重跑 strip |
6. 对外契约与依赖
让"改了我会破坏谁"和"我依赖谁"显式化,跨 feature 重构时能搜到。
6.1 我提供给别人的(Outgoing)
| 契约 | 形式 | 谁在用 |
|---|---|---|
/api/v1/xxx/yyy POST |
HTTP API | platform 前端、external script |
XxxService.do_yyy() |
内部 Python API | <其他 service 名> |
6.2 我依赖别人的(Incoming)
| 依赖 | 形式 | 风险点 |
|---|---|---|
chat 消息 query 字段为 JSON envelope |
隐式数据契约 | chat 模块若改格式会静默坏掉本 feature |
libreoffice 二进制 docx→pdf |
系统依赖 | Docker 镜像必须装 |
7. 测试与可观测
不重复 tasks.md 的测试清单。只写整体策略和怎么手动验证。
- 单元 / 集成 / e2e 各覆盖哪些层
- 真实环境怎么手动跑一遍(命令、URL、账号)
- 关键日志 / 指标 / 报警在哪
8. 后续改进 / 不打算做的事
- 已知短板 + 暂时不投入的理由
- 重写或拆分的触发条件
修订历史
| 日期 | 改动 | 触发原因 |
|---|---|---|
| YYYY-MM-DD | 初版 | feature 完成 |
| YYYY-MM-DD | §5 增坑 X | 用户报障 / e2e 暴露 |