146 篇 RFC 译文按 v4 基线(#348)重出:v4 模板+术语表、金标 few-shot、三段协议、切换行后处理;全量机械核对零异常(一处 task id 术语违规已修)。三篇超长 RFC(code-mode 已入,web-seam/ agent-scope/sandbox/cds-core 仍在长文档通道产出)随后补。
3.0 KiB
RFC:将 acp-agent 回放配置改为单一来源
English | 中文
Status: implemented
问题
examples/acp-agent 曾维护两份手写配置:cordis.yml(正式运行树)和 cordis.snapshot.yml(逐条镜像前者,仅替换 LLM(大语言模型)后端)。去掉注释后,全部差异只是八行的 llm-deepseek 段落换成两行的 llm-replay 段落。每次应用结构变更都要改两遍,且没有门禁保障对称性:一旦两份副本漂移,快照层就会悄悄测试一个与实际交付不同的应用——正是快照层本要消除的"单元测试全绿、产品却坏了"这类缺口,在上一层被重新引入,唯一的防线是评审者的警觉。
决策
cordis.snapshot.yml include 正式配置,通过 id 和 name 禁用指定的 DeepSeek 适配器,并插入回放适配器。其余所有条目因此来自正式运行树。回放时选择 overlay;录制仍然启动 cordis.yml,加载守卫允许被有意禁用的条目。
overlay 依赖一个 vendor 插件的事实,这是有意为之:include 在加载文件时应用 patches,其 refresh()/internal/update 路径重读时不会重新打补丁。这恰好满足一次性回放启动的需要(回放应用不加载 hmr,也没有东西在运行中改写配置)。快照套件即为证明:所有场景在 overlay 上原样通过,包括逐字节一致的 golden 文件。
曾考虑的替代方案
为何不采用这些替代方案?
保留完整的双副本并加一道对称性校验门禁是记录在案的退路——它能消除静默漂移这一类问题,但仍保留一份 125 行的近乎复制品,其全部内容只是一个条目的差异,且随应用每增加一个插件而增长。在 bin 侧做替换(解析配置、替换条目、删除文件)则会把 YAML 手术放进发布产物,并把回放差异藏到视线之外;overlay 让差异保持声明式、可读,且紧邻基础配置——这正是双副本支持者真正看重的教学价值。
后果
- 向
cordis.yml添加插件即自动进入回放树,无需第二次编辑;漂移这一类问题从结构上消失,而非靠门禁拦截。 - overlay 依赖条目携带稳定的
id:。禁用补丁上的name断言防止误定位(id 被复用时补丁跳过而非禁用错误的插件)。如果 id 被重命名,补丁退化为跳过,其警告需要一个回放应用有意不具备的 logger——可观测结果是一条无效的无密钥llm-deepseek条目与llm-replay并存,回放输出仍然正确(llm-replay拥有流的短路权);这属于配置腐烂,留给评审发现,不会产生错误的快照。顶层插入一个 id 与既有条目冲突的新条目时,loader 的 id map 以后者为准;当前配置无冲突,新增补丁行才是引入冲突的场所。 - 如果未来回放树需要第二处差异(另一个后端被替换),只需多加一行补丁,而非再 fork 一份文件。