application-reference-contract.md 13 KB

Application Reference Example 验收合同

受众:业务应用团队与框架团队

状态[TARGET / CONTRACT],M1 只定义场景、目录和验收;本阶段不创建可运行代码

未来位置examples/application_reference/

1. 为什么需要这个 example

Application API 只有经过一条真实、跨停止恢复的业务链路验证,才能证明业务无需修改框架内核。这个 example 是 M2/M3 的 walking skeleton 和接入合规测试载体,不是脚本构建第三版,也不追求完整创作产品体验。

它选择一个“证据驱动的创作任务”,因为该场景同时需要:

  • 先验证事实,再产生表达,能检验 Context 和 Artifact 的分层。
  • 同时保留两个候选,能检验归属、血缘和采用。
  • 用确定性规则发现局部产物问题,能检验 Validator 的局部回退。
  • 经父级审核决定下一步,能检验 ValidationResult 与 TaskReview 的权威边界。
  • 停止、重启和回溯,能检验应用身份和版本化状态是否完整恢复。

本文依赖的业务接口仍是未实现草案,见 Application API 0.1。框架状态与业务边界见 M1 设计基线

2. 场景定义

2.1 输入

根目标收到一个主题和一组已登记资料,要求形成一份完整、可发布的短内容。输入固定包含:

  • 一个需要核实的事实概念。
  • 两份可授权的来源资料,其中一份只允许事实核实 Task 使用。
  • 一条创作要求:正文必须基于已验证 Finding,不能保留占位描述。
  • 一条资源约束:只允许一个事实子 Task 和最多两个表达候选。

示例不使用脚本段落、账号人设、Pattern、脚本元素或 SQL branch。未来脚本构建应用可以替换这里的业务对象,但不能把这些概念加入框架公共模型。

2.2 角色

角色 业务职责 框架约束
editor 持有根目标,委派事实核实,比较候选并提交最终内容 只能创建 fact_checkerwriter;不能伪造验证结果
fact_checker 提问、读取获授权资料、形成 Finding 和假设 只读资料工具;不能创建候选或写最终内容
writer 使用已验证 Finding 生成两个候选表达 不能读取未转授的原始事实资料;候选必须进入 Repository

角色名和提示词属于 example。框架只识别应用内角色身份、允许的子角色关系、工具能力和资源限制。

2.3 可替换应用组件

example 必须分别实现并允许在测试中替换:

  • TaskContextProvider:枚举两份来源资料及其版本、hash、继承和授权元数据。
  • 事实核实工具:读取当前 Task 已获授权的资料并产出 ArtifactRef。
  • ArtifactResolver:按精确版本可信读取事实 Finding 和候选正文。
  • CandidateRepository:保存候选内容、fork、修订、归属和采用写回。
  • QualityCheckProvider:提供“正文不得含占位描述”的确定性规则。
  • RunEventProjector:把 Task、候选、验证和采用事件投影到测试业务视图。

测试替身只能替换 Provider/工具实现,不得替换 Runner、TaskProtocol、TraceStore、Validator 或 ResourceBudgetController。

3. 端到端流程

步骤 1:创建根目标 [M3A]

业务入口使用固定 ApplicationRef 创建新 Run。框架解析 editor 根角色,固化应用版本、config hash、角色 hash、工具、质量规则和 RunLimits,并创建 RootTaskAnchor。

验收证据:Trace 的恢复合同能指出精确应用版本;根目标和根约束不可被子角色改写。

步骤 2:事实核实子 Task [M2 + M3A]

editor 委派一个 fact_checker Task。该 Task 通过框架命令记录:

  • 一个待回答 Question
  • 资料之间的一个 Finding,带 ContextRef/ArtifactRef。
  • 一个仍待确认的 Hypothesis 或明确说明没有未决假设。
  • 简短判断依据,不保存模型原始思维链。

TaskContextProvider 只枚举资料;框架决定授权,并阻止该 Task 读取另一个 root 或兄弟 Task 的引用。

验收证据:TaskProgress 绑定当前 TaskBrief revision;事实报告经 Validator 和父级 TaskReview 接受后形成可复用证据,不靠自由文本暗示“已验证”。

步骤 3:生成两个候选 [M2 + M3B]

editor 把已验证 Finding 转授给 writer,但不必重新转授原始事实资料。writer 生成候选 A 和候选 B:

  • 两者都保存为不可变内容版本,并获得 ArtifactRef 和 CandidateRef。
  • CandidateRef 记录 application/root/trace/task 归属和血缘。
  • 候选 A 内容完整;候选 B 故意包含 {待补充事实} 占位描述。

验收证据:两个 CandidateRef 均属于 writer Task;只凭候选 ID 不能从另一应用或另一 root 读取内容。

步骤 4:确定性检查发现局部问题 [M3A + M3B]

QualityCheckProvider 声明稳定、版本化的占位描述检查。框架把它编译进 ValidationPlan:候选 A 通过,候选 B 的 output scope 失败,结果仍覆盖该 scope 计划内的全部 check_id。

验收证据:规则 Provider 不直接写 ValidationResult、TaskProgress 或候选阶段;规则 ID/版本和解析配置已经进入本 Run 的恢复合同。

步骤 5:只退回候选产物层 [M2 + M3B]

Validator 对候选 B 给出 output/candidate 层的回退建议,不让 fact_checker 重新检索已经通过的事实。父级 TaskReview 决定让 writer 从 B fork 修订版 B2,或放弃 B。

验收证据:已接受的 Finding、事实 Artifact 和事实 TaskReport 保持原版本;只新增候选修订和对应验证历史,不覆盖旧 B。

步骤 6:父级采用或继续修订 [M2 + M3B]

editor 比较已通过的 A 与修订后的 B2,通过 TaskReview 选择:

  • 采用一个候选并返回根目标重新判断;或
  • 要求 writer 继续修订;或
  • 在根约束无法满足时失败上行。

只有采用动作可以调用 CandidateRepository 的幂等业务写回。ValidationResult 只表示验收,不能替父级选择候选。

验收证据:最终内容引用被采用的精确 CandidateRef/ArtifactRef;重复投递采用事件或重复写回不会产生两个业务结果。

步骤 7:停止、重启和回溯 [M2 + M3A + M3B]

测试在三个位置执行恢复:事实 Task 完成后停止、人工确认等待期间重启、候选 B 失败后回溯。恢复后必须保持:

  • 相同 ApplicationRef、角色 hash、工具、规则和 RunLimits。
  • 相同 TaskBrief/TaskProgress 历史和 sequence head。
  • 相同 Context/Artifact 授权,不扩大跨 Task 访问。
  • 相同候选内容、归属、血缘和验证结果。
  • 相同业务投影 cursor;事件重放不产生重复数据。

应用版本缺失或 config hash 被修改时,恢复必须失败关闭,不能采用当前默认配置继续。

4. 未来目录合同

M1 不会创建以下目录。M2/M3 实现期间按能力逐步增加,目录名称可在实现评审时小幅调整,但职责不能混合:

examples/application_reference/
├── README.md                    # 运行方式、场景和里程碑状态
├── application.py              # AgentApplication 声明,不包含 Runner 分叉
├── roles/
│   ├── editor.prompt
│   ├── fact_checker.prompt
│   └── writer.prompt
├── skills/                      # example 专属业务技能
├── tools/
│   ├── verify_fact.py           # 事实核实工具
│   └── propose_candidates.py    # 候选生成工具
├── providers/
│   ├── context.py               # TaskContextProvider
│   ├── artifacts.py             # ArtifactResolver
│   ├── candidates.py            # CandidateRepository
│   ├── quality.py               # QualityCheckProvider
│   └── projector.py             # RunEventProjector
├── fixtures/                    # 小型、确定、无外网依赖的业务资料
└── tests/
    ├── test_happy_path.py
    ├── test_context_authorization.py
    ├── test_candidate_ownership.py
    ├── test_local_retry.py
    ├── test_application_restore.py
    └── test_event_projection.py

application.py 只装配公共应用描述和 Provider,不创建自定义 loop。测试使用框架公开入口和可替换 Provider,不访问 TraceStore 的内部文件来伪造状态。

5. 里程碑依赖

能力/步骤 M2 M3A M3B M1 后的可运行状态
Question/Finding/Hypothesis 和 TaskProgress revision 必需 M2 后可做协议级测试
应用身份、Registry/Binding/Runtime、严格恢复 必需 M3A 后可创建应用 Run
AgentRole、ToolSet、TaskContextProvider 必需 M3A 后可替换角色、资料和工具
ArtifactResolver 应用绑定 必需 M3A 后可从应用恢复 Resolver
QualityCheckProvider 与规则版本固化 必需 可随候选联调 M3A 后可跑单 Artifact 规则
CandidateRef 和 CandidateRepository 必需 M3B 后可完成双候选链路
规范事件和 RunEventProjector cursor 必需 M3B 后可验证业务投影
完整七步 example 必需 必需 必需 三个里程碑完成后才可运行

因此,任何文档或 README 都不能在 M2/M3B 完成前把此 example 标记为“可运行的应用模板”。

6. 验收用例

AR-01 应用隔离

同一进程注册 application_reference@1 和一个同名角色/工具但不同应用 ID 的测试应用。两者的角色、工具、Context、Resolver、规则和候选完全隔离;全局 Preset 不参与解析。

AR-02 跨 Task Context 越权

writer 尝试读取只授权给 fact_checker 的原始资料,框架拒绝。父级合法转授已经验证的 Finding 后,writer 只能读取该新 ContextRef/ArtifactRef。

AR-03 应用恢复 hash

停止并重启进程后,相同应用版本和 hash 能恢复。修改 Prompt、工具 schema、规则版本或 RunLimits 后复用旧版本号,旧 Trace 恢复失败;修改 Provider 凭证但行为配置未变时 hash 不变,凭证缺失则装配失败。

AR-04 候选归属与血缘

候选只能由所属 application/root/task 读取或修订。B2 的 parent 指向 B;A 不因 B 的失败而被回退;另一 root 复用 candidate_id 时被拒绝。

AR-05 确定性规则完整性

占位规则只让 B 的 output scope 失败,ValidationResult 的 check_id 与计划严格相等。Provider 异常时也产生计划完整的失败关闭结果,不生成计划外 ID。

AR-06 局部回退

B 失败后只重新执行 writer 的候选修订,事实 Task 的工具调用次数、Artifact 版本和 ValidationResult 不变。父级 TaskReview 是是否修订的唯一决定来源。

AR-07 停止、重启、回溯

在事实完成、工具确认等待和候选失败三个位置分别恢复。应用身份、协议版本、候选、授权和预算一致;回溯形成新历史,不覆盖旧结果。

AR-08 事件幂等

Projector 在同一事件上故障并重放,业务视图只出现一个候选版本和一次采用动作。投影停机不改变 Trace 的 completed/failed 状态。

AR-09 内核零修改

example 的实现提交不得修改以下目录中的运行时代码:

  • cyber_agent/core/runner.py
  • cyber_agent/core/task_protocol.py
  • cyber_agent/trace/store.py
  • cyber_agent/core/validation.py

若 example 必须修改这些文件才能接入,应先判定为框架通用能力缺口,单独设计和测试,不能把业务特例塞入内核。

7. 验收证据格式

最终 reference example 的 CI 必须输出或保存以下可审计证据:

  • 测试所用 ApplicationRef 和解析后 config hash。
  • 根 Trace、事实 Task、writer Task 的 ID 和父子关系。
  • TaskBrief/TaskProgress revision、ValidationResult 和 TaskReview 引用链。
  • ContextRef、ArtifactRef、CandidateRef 的归属和内容 hash。
  • 局部回退前后的工具调用计数和保留版本。
  • Projector 起止 cursor、故障重放次数和最终业务记录数。

证据可由测试 fixture 和结构化断言形成,不要求保存模型原始推理文本,也不应在日志中输出凭证或完整敏感资料。

8. 完成定义

只有同时满足以下条件,reference example 才能从合同升级为“可运行模板”:

  • 七步业务流程和 AR-01 至 AR-09 全部通过。
  • 角色、资料 Provider、工具、候选 Repository 和质量规则可分别替换。
  • 停止、进程重启和回溯均不改变应用身份、Task 合同、候选与验收结果。
  • 业务代码没有直接修改协议 context、TraceStore 文件或 Validator 结果。
  • example 中所有创作概念均留在 example;公共框架仍保持业务无关。
  • 业务团队只阅读公开接入文档即可完成一次同类替换实现。

M1 到此只冻结验收问题,不宣称这些能力已经存在。