第 23 篇
工程技术
Wiki 为什么需要稳定记录、修订与冲突检测
结合实际开发项目,讨论Wiki 为什么需要稳定记录、修订与冲突检测,说明设计理由、关键源码、验证方法及适用边界。
本文目录 · 8 节
本文属于 Memory Center:AI 编程上下文与记忆系统工程实践,第 23 篇,位于“任务记忆与长期知识”模块。案例背景统一采用实际开发项目;复现步骤使用脱敏教学样例,不代表特定生产事故。
从实际问题出发
两位维护者同时打开一篇 Wiki,分别修改不同段落。若后提交者直接覆盖正文,前一次更新会消失。revision 用于让这种冲突显式发生,而不是静默丢失。
更新携带读取时的版本
客户端提交记录身份和预期修订,存储层只接受仍匹配的更新。版本不符应返回冲突,由使用者读取最新内容再合并。盲目自动重试相同正文,只会把“被拒绝的覆盖”重新变成“成功覆盖”。

图中展示的是本篇关注的职责和顺序。正常流程之外,还要结合下面的源码与实验检查失败分支;它不是对某次线上调用的运行时追踪。
历史与当前读取各司其职
Wiki 修订用于追踪变化,检索需要识别当前有效修订。回退也应该遵循当前接口的修订语义,不能假定复制旧正文就能恢复所有关联状态。知识编辑与索引刷新是相关但不同的操作。
为什么不能在冲突后原样重试
-- 教学示意:revision 比较是更新条件的一部分
UPDATE knowledge
SET content = :new_content, revision = revision + 1
WHERE id = :id AND revision = :expected_revision;
受影响行数为零时,需要区分记录不存在与版本变化。后者应该读取最新正文并重新合并;若直接换成最新 revision 再提交旧正文,技术上避开了冲突提示,业务上仍然丢失了别人的改动。项目实际持久化封装以 Store 为准。
关键源码与阅读方法
源码基线为 Memory Center 6e90553(文档标注 5.0.0b24)。定位:memory_center/platform/knowledge.py,函数 wiki,起始行 101。
以下为当前基线中的函数代码;依赖项目模块,不能作为独立脚本执行。
def wiki(self, actor, workspace_id, title, content, record_id='', revision=None, refs=None):
if record_id:
current = self.store.get('wiki', record_id)
if current.get('readonly'):
raise CatalogError('WIKI_READ_ONLY', '目录接入页面只读,请修改来源文件后同步')
if current['workspace_id'] != workspace_id:
raise CatalogError('FORBIDDEN', '页面不属于当前空间')
histories = [*current.get('versions', []), {'revision': current['revision'], 'title': current['title'],
'content': current['content'], 'refs': current.get('refs', []), 'editor': current['owner']}]
return self.store.update('wiki', record_id, {'title': title, 'content': content, 'refs': refs or [],
'versions': histories[-100:], 'owner': actor, 'status': 'active'}, revision)
return self.store.create('wiki', {'workspace_id': workspace_id, 'owner': actor, 'title': title,
'content': content, 'refs': refs or [], 'versions': [], 'status': 'active'})
阅读时先找输入由谁提供,再区分纯计算、读取和写入;遇到异常或提前返回,追问调用方会得到什么,以及已有状态是否仍然有效。上面的代码只证明展示范围内的实现,跨模块行为应继续查看调用处和相应测试。
用一个小实验核对设计
建议在独立临时目录和隔离数据中操作,使用虚构的接口、文档与项目名称。
- 两个客户端读到同一 revision。
- 先提交一个修改,再提交另一个。
- 读取最新版本后人工合并。
**要核对的结果:**第二个旧版本更新应被拒绝,首次修改应保持完整且可追溯。
可把观察记录为下表;没有执行的项写“未执行”,不能用设计预期冒充实测结果。
| 核对项 | 应保留的证据 |
|---|---|
| 使用条件 | 源码版本、配置、输入与项目范围 |
| 正常行为 | 实际返回、来源位置或状态变化 |
| 关键失败分支 | 错误码、可见结果与原状态是否保留 |
| 结论范围 | 已覆盖、未覆盖和需要进一步验证的条件 |
适用边界与继续阅读
本篇以静态源码与项目设计为依据,给出可执行的核对方法,未据此宣称已经完成新的性能或生产环境测试。不同版本的入口、默认值和底层实现可能变化,应先核对当前合同,再把方法用于自己的实际开发项目。
理解这一节后,可以回到专题总导航,沿同一模块继续阅读;顺序学习时使用专栏内的上一篇和下一篇。涉及具体技术选择,应连同本篇的代价与限制一起采用。