一个游戏智能体由多个程序部分组成:有的看截图,有的模拟规则,有的选择行动。如果每次改识别算法都要修改 AI,开发很快就会互相等待。解决办法是让模块只依赖稳定的公开接口,而不是彼此的内部文件。

现在,识别侧和消费侧已经确认这一规则:内部可以独立演进;改变公开接口之前,先和受影响的模块讨论并留下记录。

flowchart LR
 A[Provider implementation] --> B[Stable public contract]
 B --> C[Consumer implementation]
 D[Contract tests] --> B
 E[Recorded joint review] --> B

图 1:调用者依赖合同,而不是实现。测试检查行为;评审记录解释为什么允许改变合同。

C/C++ 通常用头文件声明外部可用的类型和函数。这里的主要代码是 Python,不需要再手写一套 .h:公开包入口、导出的类型与函数,以及它们承诺的行为,共同构成接口。

接口不只是名字。例如,“伤害未知”不能偷偷变成 0;一个识别框不能突然被解释成可以点击的区域。字段单位、默认值、异常、对象标识、时间顺序、序列化格式和副作用,都属于合同。

from olden_era_perception import export_ui_element_observation_frame
from olden_era_ai.domain import UiElementObservationFrame

调用者使用公开入口。检测器所在文件、缓存实现、内部辅助函数怎么拆分,由 Perception 自己决定。

2. 每个模块负责什么?

模块 负责 不负责
Domain 共享类型、标识、格式与语义 游戏数值、识别或决策算法
Game Knowledge 游戏事实、版本、目录和证据 执行战斗或替 AI 决策
Perception 当前画面中检测到的对象与数值 完整游戏状态、合法行动、点击许可
Simulator 确定性规则、回放与公开查询 把测试通过当作规则真实的证明
Game AI 在允许的信息范围内选择行动 读取隐藏状态或检测器内部数据
Arena App 网页、终端和会话组合 再维护一套游戏事实或规则
Reference App 展示和审核目录 成为第二份事实源
Shared / Integration 少量通用工具 / 跨模块验证 承包不知该放哪儿的业务逻辑

状态解释和执行是另外的职责:前者判断观测之间的关系,后者把意图分解为输入并核对结果。它们还没有完整交付,不因为画在架构图上就算已经存在。

3. 什么时候必须一起讨论?

只更换 OCR、优化缓存或拆分私有文件,同时保持合同和兼容测试不变,可以独立推进。改公开字段、枚举、参数、默认值、校验规则或含义,则必须先通知提供方和所有受影响的消费方。

例如,当前观察协议会拒绝不认识的字段。如果想增加 clickable,不能把它当作无害的附加值:旧读者会拒绝新记录,而且“可点击”也不是识别框本身能证明的结论。

完整流程是:列出使用方 → 写明旧新行为与风险 → 双方讨论 → 决定版本和迁移方式 → 测试旧新组合 → 再提交。没有回复不等于同意。修复偏离既有合同的 bug 则应恢复约定、补回归测试,并通知可能依赖旧行为的使用方。

4. 怎样避免下一次忘记?

代码仓库里的 docs/architecture/DESIGN_INDEX.md 是当前设计入口,MODULE_CONTRACT_GOVERNANCE.md 记录治理规则,具体讨论保存在带日期的 reviews/ 文档中。根目录开发说明会要求先读这些文件。

博客负责解释设计,不替代代码合同。文档分为“当前采用”“待实现提案”和“Deprecated”。旧设计如果仍能解释取舍,就保留并指向替代版本;没有价值的重复内容可以退出博客导航,但不因此删除原始实验或录像。

旧的 B020 总设计 保留了有用的场景与视频审核思路,但已不再作为跨模块合同入口。旧实验的测量也不会因为架构更新而自动失效。

5. 现在可以各自推进什么?

Perception 可以继续改善检测、OCR、候选质量与现有字段适配;消费侧可以围绕已冻结的观察格式开发解释和查询流程。双方通过同一批接口案例验证兼容,不需要互相导入私有实现。

已经交付的是薄观察接口。下一层的主动查询与逐步执行仍是明确标注的提案。这个分界让独立开发成为可能,也让尚未完成的工作保持可见。