name: domain-modeling description: "建立并打磨项目领域模型。讨论代码库术语、编写或修改 CONTEXT.md,或记录、编辑 ADR 时使用。"
把混用的词变成可共同判断的概念
领域建模的目标是消除业务理解冲突。当前规范把 CONTEXT.md 明确限制为领域词典。
还不清楚 Skill、Agent、安装和调用?先读 从零开始的6节入门课。
在关系图中查看 domain-modeling 与其他技能的关联 →
先把必要的概念讲清楚
领域建模是在澄清业务世界中的概念与关系。它与画数据库表有关,但比数据库设计更早:先弄明白“课程”“课时”“完成”是什么意思,再决定怎样保存和计算。
下面是老师补充的入门说明;原作者的要求保留在中英对照正文中。所有例子均为帮助理解而构造的教学情境。
domain glossary|业务领域术语表
规定项目的重要概念叫什么、指什么。domain 在这里是业务领域,不是互联网域名。课程是一组课时,课时是一份学习内容;混用会把“收藏课程”实现成“收藏某一课时”。统一语言不仅统一拼写,还统一概念边界。
ADR|架构决策记录
Architecture Decision Record 的缩写,记录一个重要技术决定、当时为什么选择它,以及接受了什么代价。例如规定所有写入经过后端权限检查。遵循相关 ADR,是在适用范围内延续已确认决定;新需求与之冲突时,应说明冲突和修改理由,而不是默默绕过。
schema|数据结构与约束
描述数据有哪些字段、类型、关系和限制。例如收藏包含用户 ID、课程 ID、创建时间,并要求同一用户与课程组合唯一。改 schema 可能影响存储、接口和旧数据,因此它是工程决定,不只是给变量换名字。
repo / repository|项目代码仓库
保存项目源代码、配置、测试和文档,并通常用 Git 记录修改历史的地方。把它理解为“可追溯的项目工作档案”。探索仓库就是查看现有系统,不等于开始改代码。例如新增课程收藏前,应先看已有课程数据、用户身份和保存接口,避免另造一套。
读原文,理解每一步为什么这样做
左右内容按小节对应;窄屏先中文、后英文。两种语言均完整展示,对应讲解紧接在小节之后。译文传达原文要求;老师讲解补充概念、原因、例子与适用边界。
name: domain-modeling description: Build and sharpen a project's domain model. Use when discussing codebase terminology, writing or editing a CONTEXT.md, or recording or editing an ADR.
在设计过程中澄清业务概念
一边设计,一边主动建立和完善项目的业务领域模型。这里强调主动工作:质疑含糊名称,构造特殊场景检查概念,一旦词义和决定明确,就及时写下来。
仅仅读取 CONTEXT.md 以复用已有词汇,还不算在执行本技能;那是其他技能也可以做到的习惯。本技能用于你正在改变或澄清业务模型的时候。
Domain Modeling
Actively build and sharpen the project's domain model as you design. This is the active discipline: challenging terms, inventing edge-case scenarios, and writing the glossary and decisions down the moment they crystallise. (Merely reading CONTEXT.md for vocabulary is not this skill: that's a one-line habit any skill can do. This skill is for when you're changing the model, not just consuming it.)
文件怎样组织
大多数仓库只有一套业务上下文。原文示意的文件位置如下:
| 位置 | 放在这里的内容 |
|---|---|
/CONTEXT.md |
整个项目共用的业务术语与定义 |
/docs/adr/0001-event-sourced-orders.md |
第一份架构决策记录,示例主题为订单采用事件溯源 |
/docs/adr/0002-postgres-for-write-model.md |
第二份架构决策记录,示例主题为写入模型采用 Postgres |
/src/ |
项目的源代码目录 |
如果根目录存在 CONTEXT-MAP.md,就表示这个仓库有多个业务上下文。该映射文件会指出每一套上下文位于哪里。原文的目录示例可以对应为:
| 位置 | 所属范围 |
|---|---|
/CONTEXT-MAP.md |
指向各业务上下文的总索引 |
/docs/adr/ |
影响整个系统的架构决定 |
/src/ordering/CONTEXT.md |
订单业务上下文自己的术语表 |
/src/ordering/docs/adr/ |
只针对订单业务上下文的架构决定 |
/src/billing/CONTEXT.md |
账单业务上下文自己的术语表 |
/src/billing/docs/adr/ |
账单业务上下文自己的架构决定 |
真正有内容可写时再创建文件。第一个术语确定时才需要创建缺失的 CONTEXT.md;第一份架构决定确实需要记录时,再创建 docs/adr/。
File structure
Most repos have a single context:
/
├── CONTEXT.md
├── docs/
│ └── adr/
│ ├── 0001-event-sourced-orders.md
│ └── 0002-postgres-for-write-model.md
└── src/
If a CONTEXT-MAP.md exists at the root, the repo has multiple contexts. The map points to where each one lives:
/
├── CONTEXT-MAP.md
├── docs/
│ └── adr/ ← system-wide decisions
├── src/
│ ├── ordering/
│ │ ├── CONTEXT.md
│ │ └── docs/adr/ ← context-specific decisions
│ └── billing/
│ ├── CONTEXT.md
│ └── docs/adr/
Create files lazily: only when you have something to write. If no CONTEXT.md exists, create one when the first term is resolved. If no docs/adr/ exists, create it when the first ADR is needed.
一个词的含义,必须知道在哪个业务范围内成立
原文的 context 在这里主要指一组共享业务语言的范围,不是简单等同于聊天上下文窗口。一个小项目可能只需一份 CONTEXT.md;大项目的教学、计费等部分可能各有词典,用 CONTEXT-MAP.md 指明位置。
例如教学中的“完成”可能是学生达到学习条件,计费中的“完成”可能是账单结清。同一个字面名称在不同范围可以有不同定义,但交换信息时必须知道彼此含义。地图负责说明范围,不强求全公司只用一个含糊定义。
目录示例说明文件位置,不要求一开始就创建全部目录。原文强调有真实术语或决定才创建,避免空文档给人制度很完善的错觉。
讨论过程中怎样做
During the session
将用户的用词与现有词汇表核对
用户使用的词与 CONTEXT.md 中已有定义冲突时,立即指出。例如:“词汇表将‘取消’定义为 X,但你刚才似乎指 Y,这里以哪种含义为准?”
Challenge against the glossary
When the user uses a term that conflicts with the existing language in CONTEXT.md, call it out immediately. "Your glossary defines 'cancellation' as X, but you seem to mean Y. Which is it?"
不是纠正措辞,而是在找业务矛盾
假如词典定义“完成课时”为答题通过,用户却说“打开页面就算完成”,AI 应指出两者冲突并请用户决定。把两种说法都记下而不解决,会使显示、统计和提醒各用一套规则。
“account 是 Customer 还是 User”同样在区分客户主体与登录身份。一个家庭客户可能有多个登录用户;把二者混成一个字段,后面权限和归属就容易出错。
老师要你掌握的是:发现同名不同义、同义不同名,以及一个术语承载了多种职责时,能说出具体区别。不是为了使用更多英文。
把模糊名称说准确
遇到含糊或同时承载多个含义的词,提出更准确的统一名称。例如:“你说的‘账户’,指客户这个业务对象,还是登录用户?它们是不同的东西。”
Sharpen fuzzy language
When the user uses vague or overloaded terms, propose a precise canonical term. "You're saying 'account': do you mean the Customer or the User? Those are different things."
用具体情形检查概念
讨论业务关系时,用具体场景检验它。构造边缘情形,促使用户说清相关概念之间的范围和区别。
Discuss concrete scenarios
When domain relationships are being discussed, stress-test them with specific scenarios. Invent scenarios that probe edge cases and force the user to be precise about the boundaries between concepts.
用具体反例检验定义是否真的清楚
抽象说“允许取消”很容易获得同意。问“订单已有一件发货,另一件未发货,取消指整单还是剩余一件”,边界才会显现。在学习项目里可以问“课时已读完但测验未通过,是完成还是待巩固”。
随后核对代码:实现现在如何处理,与用户描述是否一致。代码是当前行为的证据,但也可能有 bug,不能因为代码这样做就自动把它升格为正确业务规则。
场景讨论的产物是明确的概念或关系,例如“已阅读和已掌握是两个独立状态”。这会影响界面、统计和数据设计,正是软件工程中的需求分析。
不要只定义“完成”,要问什么情况下算完成
业务模型是你们对项目中的事物及其关系的共同理解。 它还没有决定数据库用哪种技术,但会直接影响功能怎样实现。
假设学习网站里,“完成课时”可能表示打开过页面,也可能表示读完译文,还可能要求答对练习。你和 AI 如果各自默认一种含义,就会得到不同的学习进度系统。
可以用场景追问:“用户打开页面两秒就离开,算完成吗?”“已经读完,但练习答错了,算完成吗?”通过这些情形,你们能把‘完成’的定义说准确。确定后写进词汇表,下一位 Agent 才会使用同一含义。
事实与目标要区分。 当前代码按打开页面计完成,只说明系统现状;用户希望练习达标后才完成,是目标变化。AI 应指出差别,而不是悄悄把现状当成正确规则。
为什么不是所有决定都写 ADR? 按钮暂时用蓝色,通常很容易改,也无需长期解释。选择某种会影响迁移成本的数据保存方式,如果有明确取舍,就可能值得记录。ADR 应保存未来真正需要知道的理由。
词汇表记录“课时、完成、复习”等概念;功能规格记录本次要实现什么;ADR 记录重要技术取舍。分清用途后,文件就不会变成什么都放、什么都难找的大杂烩。
与实际代码相互核对
用户描述系统怎样工作时,检查代码是否如此。发现不一致就指出,例如:“现有代码会取消整张订单,但你刚才说允许部分取消,哪一个是应当遵循的规则?”
Cross-reference with code
When the user states how something works, check whether the code agrees. If you find a contradiction, surface it: "Your code cancels entire Orders, but you just said partial cancellation is possible. Which is right?"
术语确定后立即更新 CONTEXT.md
一个术语明确后,当场写入,不要攒到最后统一整理。格式参见 CONTEXT-FORMAT.md。
CONTEXT.md 不应包含实现细节。不要将它当作功能规格、临时草稿本,或者实现决定的汇总仓库;它在这里专门是一份业务词汇表。
Update CONTEXT.md inline
When a term is resolved, update CONTEXT.md right there. Don't batch these up: capture them as they happen. Use the format in CONTEXT-FORMAT.md.
CONTEXT.md should be totally devoid of implementation details. Do not treat CONTEXT.md as a spec, a scratch pad, or a repository for implementation decisions. It is a glossary and nothing else.
词典与架构决定分别记录什么
词典记录术语定义,不应混入明天要改哪个文件、目前做到哪一步。进度放任务记录,功能要求放规格,架构取舍放 ADR;各文档负责不同类型的信息,更新时才不会互相矛盾。
例如“掌握:能够在新情境独立判断适用性”属于词典;“用哪种存储保存学习记录”可能属于架构决定;“本周完成第 3 课”只是任务进度。
作者要求术语确定后当场记录,目的是让后续交流立刻使用同一版本,而不是对话结束时凭记忆补写。
有选择地建议记录 ADR
只有同时满足以下三个条件,才建议创建架构决策记录:
- 以后不容易撤销:改变主意会产生明显成本。
- 缺少背景会令人困惑:未来读者会问“当初为什么这样做”。
- 确实经过取舍:存在其他可行选择,而你们因具体原因选择了这一项。
缺少任何一个条件,都跳过 ADR。需要记录时,使用 ADR-FORMAT.md。
Offer ADRs sparingly
Only offer to create an ADR when all three are true:
- Hard to reverse: the cost of changing your mind later is meaningful
- Surprising without context: a future reader will wonder "why did they do it this way?"
- The result of a real trade-off: there were genuine alternatives and you picked one for specific reasons
If any of the three is missing, skip the ADR. Use the format in ADR-FORMAT.md.
什么决定值得留下 ADR
原文要求三个条件同时成立:改变代价明显、后来的人缺少背景会感到意外、当时确实比较过方案。它不是“只要选了一个库就写一篇 ADR”。
例如为方便离线先把学习记录只存本机,但接受暂时不能跨设备同步的代价;如果后续迁移成本显著,这个选择可能值得记录。按钮用蓝色且随时能改,通常不满足这些条件。
好的 ADR 会让后来的人知道当时在什么约束下选择、放弃了什么。它不是证明当初选择永远正确,而是让未来改变时有理由可追溯。
配套参考资料(英文)
先作答,再看参考思路
用自己的话说明:它解决什么问题,完成后会留下什么?
请各用一句话回答。若它只做规划或解释,不要把“已开发”“已部署”写成产物。
把“使用某数据库”的理由放进 CONTEXT.md 合适吗?
我已思考,查看参考思路
不合适。词典说明领域概念;有真实重大取舍时,技术决定及其原因放 ADR。普通配置可从配置文件读取。
原文中哪条要求在你的环境下可能不成立?
说出具体一句及其前提,例如工具不可用、资料缺失、已有项目约定冲突,或它只是作者偏好。把你的答案带回课堂,我们据此继续讨论。
把方法放进一个具体情境
教学案例:“策略完成”可能是回测结束,也可能是研究通过审查。把它们分成“回测运行完成”和“研究验收通过”,之后状态报告才不会用一个绿色标记混淆两个结果。
边界与容易误读的地方
词典不要塞通用编程知识和实现细节;老师举的领域定义需用户确认,不能直接替换真实项目规则。
讨论后再实践:先判断上述情境是否适用,再选择真实任务。现在无需安装、运行命令或修改现有项目。