第 5 篇
工程技术
从设计原则到架构约束:如何记录真正有用的 ADR
结合实际开发项目,讨论从设计原则到架构约束:如何记录真正有用的 ADR,说明设计理由、关键源码、验证方法及适用边界。
本文目录 · 7 节
本文属于 Memory Center:AI 编程上下文与记忆系统工程实践,第 05 篇,位于“问题与设计思想”模块。案例背景统一采用实际开发项目;复现步骤使用脱敏教学样例,不代表特定生产事故。
从实际问题出发
项目越来越大时,“保持低耦合”很难指导一次具体改动。一个新增管理接口应该调用现有用例,还是直接操作底层数据库?设计原则只有转化为依赖方向和明确职责,才能帮助维护者作出一致选择。
记录决策与失效条件
ADR 至少解释背景、备选方案、选择、代价和重新评估条件。常驻服务可以满足当前本机运行需求,但它不自动保证多实例部署;若负载模型改变,需要重新决策,而不是在原架构上悄悄添加假设。

图中展示的是本篇关注的职责和顺序。正常流程之外,还要结合下面的源码与实验检查失败分支;它不是对某次线上调用的运行时追踪。
分层是为了明确变化归属
入口层处理协议与身份,应用层组合用例,引擎处理事实和查询。底层不应反向依赖入口。延迟导入有时只是隐藏循环依赖,不能替代职责调整。代码中的依赖组装可用于审查文档原则是否仍然成立。
关键源码与阅读方法
源码基线为 Memory Center 6e90553(文档标注 5.0.0b24)。定位:memory_center/platform/application.py,函数 __init__,起始行 20。
以下为当前基线中的函数代码;依赖项目模块,不能作为独立脚本执行。
def __init__(self, database, catalog):
self.store, self.catalog = PlatformStore(database), catalog
self.knowledge = Knowledge(self.store, database.data_dir)
self.wiki_sources = WikiSources(self.store, catalog)
self.governance = Governance(self.store, catalog, self.wiki_sources, database.data_dir)
self.access = Access(self.store, catalog)
self.retrieval = Retrieval(self.store, self.knowledge)
self.jobs = Jobs(self.store, catalog, database.data_dir, database.url)
self.knowledge_tasks = KnowledgeTasks(self)
self.jobs.knowledge_tasks = self.knowledge_tasks
initialize_terms(database)
from memory_center.platform.call_traces import CallTraces
self.call_traces = CallTraces(self.store)
阅读时先找输入由谁提供,再区分纯计算、读取和写入;遇到异常或提前返回,追问调用方会得到什么,以及已有状态是否仍然有效。上面的代码只证明展示范围内的实现,跨模块行为应继续查看调用处和相应测试。
用一个小实验核对设计
建议在独立临时目录和隔离数据中操作,使用虚构的接口、文档与项目名称。
- 选一个新增查询需求。
- 写出两种依赖方案。
- 记录选择的代价及何时需要推翻。
**要核对的结果:**评审者应能根据 ADR 判断改动放在哪层,而非只读到口号。
可把观察记录为下表;没有执行的项写“未执行”,不能用设计预期冒充实测结果。
| 核对项 | 应保留的证据 |
|---|---|
| 使用条件 | 源码版本、配置、输入与项目范围 |
| 正常行为 | 实际返回、来源位置或状态变化 |
| 关键失败分支 | 错误码、可见结果与原状态是否保留 |
| 结论范围 | 已覆盖、未覆盖和需要进一步验证的条件 |
适用边界与继续阅读
本篇以静态源码与项目设计为依据,给出可执行的核对方法,未据此宣称已经完成新的性能或生产环境测试。不同版本的入口、默认值和底层实现可能变化,应先核对当前合同,再把方法用于自己的实际开发项目。
理解这一节后,可以回到专题总导航,沿同一模块继续阅读;顺序学习时使用专栏内的上一篇和下一篇。涉及具体技术选择,应连同本篇的代价与限制一起采用。