# Application API 0.1 草案 > **受众**:业务应用团队 > > **状态**:`[TARGET / DRAFT]`,尚未实现,不可 import,暂无兼容承诺 > > **目标里程碑**:M3A 提供最小装配能力,M3B 补齐候选和事件投影;真实 reference example 通过后再讨论冻结 API ## 1. 先说明:现在能做什么,本文又是什么 当前框架已经能直接运行 Agent,并提供 Recursive 任务树、TaskProtocol、Context 授权、工具门禁、Artifact 解析、Validator、预算以及停止和恢复。业务也可以通过构造 `AgentRunner` 注入工具注册表、验证策略和 `ArtifactResolver`。 当前尚没有“应用”这一层稳定接口:没有应用 ID/版本、应用级角色隔离、Provider 注册、候选生命周期,也不能只凭一个 Trace 精确找回当初的业务装配。因此本文不是使用手册,而是业务团队和框架团队共同评审的接口合同草案。 本文所有类型都分为三类: - `[CURRENT]`:代码中已经存在,可按现有文档使用。 - `[M2 TARGET]`:M2 计划实现的 TaskProgress 能力。 - `[M3 TARGET]`:M3 计划实现的应用装配、候选或投影能力。 本文中的结构示例是**设计记法**,不是 Python 代码。现在创建同名文件或执行 `from cyber_agent import AgentApplication` 都不会工作。 框架团队的代码证据、状态权威和责任边界见 [M1 应用框架设计基线](./application-framework-m1.md)。 ## 2. 业务接入的心智模型 一套应用由一个不可变描述和若干可替换 Provider 组成: ```text AgentApplication(声明“这是什么应用”) ├─ ApplicationRef(身份和版本) ├─ AgentRole[](角色、Prompt、Skill、模型和子角色边界) ├─ ToolSet[](允许使用哪些业务工具) ├─ TaskContextProvider(有哪些业务资料可供授权) ├─ ArtifactResolver [CURRENT](如何可信地读取产物) ├─ CandidateRepository(候选内容如何存储、分叉和合并) ├─ QualityCheckProvider(有哪些确定性业务规则) ├─ RunEventProjector(如何投影业务数据库和 UI) └─ RunLimits(应用允许的资源上限) ``` 应用只描述业务能力。框架负责校验描述、把它编译成现有 Runner/ToolRegistry/Validator 能理解的配置、固化本次运行的解析结果,并在恢复时验证完全一致。 应用不创建第二个 Runner,不接管 TaskProtocol,不直接修改 Trace,也不通过回调绕过工具确认或 Validator。 ## 3. 公共草案对象 ### 3.1 `ApplicationRef` `[M3 TARGET]` 应用版本的不可变引用,也是启动、恢复和审计时的身份。 | 字段 | 含义 | 约束 | |---|---|---| | `application_id` | 稳定应用 ID,例如 `creative.reference` | 由组织命名,不能依赖本地目录名 | | `application_version` | 可部署、可解析的应用版本 | 同一版本的行为声明不可被原地改写 | | `config_hash` | 解析后行为配置的 SHA-256 | 新 Run 由框架计算;续跑必须精确匹配 | 公共名称不带 `V1`。当它随 Trace 落盘时,序列化对象必须额外包含 `schema_version`。 ### 3.2 `AgentApplication` `[M3 TARGET]` 不可变应用描述对象,回答“这个应用允许框架装配什么”。它不是 Runner,也不保存连接池、Token 或运行时客户端。 草案字段: | 字段 | 含义 | |---|---| | `application_id` / `application_version` | 应用稳定身份 | | `root_role` | 新 Run 的根角色 ID | | `roles` | 应用命名空间内的 `AgentRole` 目录 | | `tool_sets` | 可被角色引用的 `ToolSet` 目录 | | `context_provider` | 业务资料枚举端口及其版本描述 | | `artifact_resolver` | 现有只读 Artifact 解析端口 | | `candidate_repository` | 候选内容和合并端口 | | `quality_provider` | 确定性业务规则端口及其版本描述 | | `event_projector` | 可选业务投影端口 | | `run_limits` | 应用整体资源上限 | 应用描述在注册后不可变。要修改 Prompt、工具能力、规则或资源边界,应发布新的 `application_version`,不能替换相同版本的内容。 ### 3.3 `AgentRole` `[M3 TARGET]` 角色属于应用命名空间,不再写入进程全局的同名 Preset。 | 字段 | 含义 | |---|---| | `role_id` | 应用内唯一角色 ID | | `description` | 给装配器和根角色理解的职责说明 | | `model` / `model_parameters` | 模型及影响行为的生成参数 | | `prompt` / `prompt_hash` | 版本化 Prompt 引用及解析后 hash | | `skills` | Skill ID、版本和顺序 | | `tool_sets` | 角色可见的 ToolSet ID;子 Task 仍受父级能力交集限制 | | `allowed_child_roles` | 此角色允许创建的子角色集合 | | `default_validation_scopes` | 默认要求 Validator 检查的范围 | | `run_limits` | 角色级限制,与应用和框架上限取最严格值 | 角色不能通过 Prompt 放宽工具、Context、预算、Artifact 或子角色门禁。Prompt hash 必须基于框架真正发送给模型的解析后内容,而不是只 hash 文件路径。 ### 3.4 `ToolSet` `[M3 TARGET]` 应用级工具声明。它最终编译进现有 `ToolRegistry`,不会形成第二套注册表或执行器。 每项工具声明至少需要: - 稳定工具名和输入 schema。 - 实现绑定的版本标识。 - 是否需要人工确认、哪些参数允许确认时编辑。 - URL policy;声明 URL pattern 时,调用上下文必须有匹配的 `page_url`。 - 副作用分类和幂等说明,供审计与崩溃恢复判断。 - 工具分组和可被哪些角色引用。 最终可执行集合仍由框架计算:应用声明、角色声明、父级转授、Run 级精确白名单和框架硬禁用项取交集。业务工具实现不得直接调用注册表的内部 dispatch 绕过这一步。 ### 3.5 `TaskContextProvider` `[M3 TARGET]` 业务实现的资料枚举端口。Provider 回答“当前 Task 有哪些候选资料”,框架决定“哪些资料被授权、继承和放入模型上下文”。 Provider 的输入至少包含只读的应用引用、root/trace/task identity、当前 TaskBrief revision、父级已授权 ContextRef 和预算视图。输出的是资料描述,不是直接拼接后的 Prompt: | 元数据 | 用途 | |---|---| | `source_id` / `source_version` | 稳定来源和版本 | | `content_hash` | 内容寻址、去重和恢复校验 | | `kind` / `mime_type` | 裁剪和渲染策略 | | `inheritance` | 建议仅本 Task、允许逐边转授或禁止继承 | | `priority` / `estimated_tokens` | 预算裁剪输入 | | `authorization_metadata` | 供框架策略判断的业务归属,不等于已授权 | 框架把获准资料固化为现有 ContextSnapshot/ContextRef。Provider 不直接写 `TaskBrief.context_refs`,也不能返回另一个 root 或未获授权 Task 的引用。 ### 3.6 `ArtifactResolver` `[CURRENT]` 继续使用现有名称和协议,不新增 `ArtifactReader`。业务实现可信、只读解析;框架负责校验引用、归属和 hash,并把合法材料交给 Validator。 当前权威签名位于 [`cyber_agent/core/artifacts.py`](../core/artifacts.py): ```text async resolve( ref: ArtifactRef, root_trace_id: str, uid: str | None, ) -> ValidationMaterial ``` 业务 Resolver 必须: - 以 `artifact_id + version` 读取不可变版本,不把“最新内容”冒充指定版本。 - 校验 root 和 uid 的访问权;越权使用确定性拒绝语义。 - 返回内容的 hash 与 ArtifactRef 完全一致。 - 区分不存在、暂时不可用和越权,不把所有错误吞成空内容。 上传、ACL 管理、索引和删除仍是业务存储职责,不进入 Resolver。 ### 3.7 `CandidateRef` `[M3 TARGET]` 框架持有的不可变候选引用。候选内容仍在业务存储中。 草案最小信息包括:candidate identity、所属 application/root/trace/task、来源 ArtifactRef、parent candidate、revision、创建原因和生命周期阶段。每次内容变化产生新 revision 或新候选,不覆盖已被 Validator 或 TaskReview 引用的历史版本。 候选阶段只描述业务工作流中的 `draft / proposed / adopted / discarded` 等生命周期,不替代 Trace.status、ValidationResult 或 TaskReview。 ### 3.8 `CandidateRepository` `[M3 TARGET]` 业务实现的候选内容端口,替代含义模糊的 `CandidateStore`。框架通过它执行以下受控能力: - 创建不可变候选版本并返回内容 hash/ArtifactRef。 - 读取某个 CandidateRef 指定的精确版本。 - 从一个候选 fork 新候选并保留血缘。 - merge 候选,返回冲突而不是静默覆盖。 - 将已被父级采用的版本写回业务目标;写回必须幂等。 Repository 必须校验框架传入的 application/root/task 归属,不能仅凭 candidate_id 读写。框架负责 CandidateRef 和生命周期动作的合法性,Repository 负责内容、存储事务、冲突和业务写回。 ### 3.9 `QualityCheckProvider` `[M3 TARGET]` 业务实现的确定性质量规则端口。它声明规则和可执行检查,框架把规则编译进现有 ValidationPlan 并统一调度。 每条规则至少声明:稳定 `check_id`、规则版本、适用 scope、所需材料类型、确定性执行器、失败说明模板和建议的 `retry_from`。例如“候选正文仍含 `{placeholder}`”可以是确定性规则,但“表达是否有感染力”仍应由 LLM Validator 评价。 约束: - Provider 不直接写 ValidationResult;框架统一生成完整结果。 - Provider 不直接修改 TaskProgress 或 Candidate 生命周期。 - 回退建议只是 Validator 结果的一部分,父级仍通过 TaskReview 决定修订、重拆或上行。 - 新 Run 固化规则 ID、版本和配置 hash;续跑不能加载当前默认的新规则替换旧规则。 ### 3.10 `RunEventProjector` `[M3 TARGET]` 业务实现的异步投影端口。它从现有 Trace 事件流按 cursor 消费,把权威状态投影到业务数据库、UI、通知或分析系统。 投影器必须满足: - 以 application/root/trace 和 event_id 作为幂等键。 - 只提交连续 cursor;同一事件重复投递不能产生重复业务写入。 - 能在进程重启后从最后 cursor 重放。 - 对未知的新事件类型安全忽略或存入待升级队列。 - 投影失败只影响业务视图新鲜度,不回滚 Agent Trace,不阻塞已经完成的协议动作。 它不是同步 EventBus。业务不能把“投影成功”当作 Trace 状态转换的前置条件;确实需要参与事务的业务动作应建模为受门禁工具或 Repository 写回。 ### 3.11 `RunLimits` `[M3 TARGET]` 应用可声明:模型轮次、递归深度、孩子数、并发孩子数、Token、成本、墙钟时间和单类资料大小上限。 有效限制为以下各层中最严格的一项: ```text 框架硬上限 ∩ 部署策略 ∩ AgentApplication ∩ AgentRole ∩ 本次 Run 请求可收紧值 ``` 本次 Run 只能收紧,不能放宽已经注册的限制。解析后的限制进入恢复快照;停止、重启和回溯不能重置已消耗资源。 ## 4. M2 的 `TaskProgress` 如何被业务使用 `TaskProgress` 是 `[M2 TARGET]`,不是应用 Provider。业务 UI 可读,Agent 通过框架命令更新,业务代码不能直接写协议 context。 它只记录当前 Task 的推进事实,例如: - `phase`:理解问题、收集证据、形成方案、生成候选、准备提交等推进阶段。 - `questions` / `blockers`:待确认问题和阻塞因素。 - `findings` / `hypotheses`:带 ContextRef/ArtifactRef 的结构化发现与假设。 - `work_items`:已经尝试、待尝试或放弃的工作项。 - `candidate_refs`:本 Task 当前产生或引用的候选。 - `decision_rationale`:简短、可审计的选择理由。 它不拥有 `completed/passed/failed` 终态,不复制 TaskBrief.target、ValidationResult 或 TaskReview.next_action,也不保存模型原始思维链。 ## 5. 新 Run 与恢复合同 ### 5.1 新 Run 框架按以下顺序创建应用 Run: 1. 按 `application_id + application_version` 解析不可变 AgentApplication。 2. 校验根角色、子角色图、工具、Provider 版本和 RunLimits。 3. 解析 Prompt/Skill、工具 schema、质量规则和行为配置。 4. 对规范化后的行为声明计算 `config_hash`。 5. 将完整 ApplicationRef、根角色/角色目录 hash 和解析后的行为配置加入 RunConfigSnapshot。 6. 创建 Trace 后才允许 Runner 进入模型循环。 ### 5.2 续跑、人工确认、回溯和 compact 所有恢复入口都必须: 1. 先读取 Trace 中固化的 ApplicationRef 和 RunConfigSnapshot。 2. 从内部 Registry 解析完全相同的 `application_version`。 3. 重新计算并比对 config hash、角色 hash、工具和规则版本。 4. 一致后恢复 Provider 运行时对象,再进入现有恢复流程。 以下情况失败关闭:应用不存在、版本不存在、hash 不匹配、角色或规则缺失、Provider 无法恢复。框架不得用当前默认应用、最新 Prompt 或新规则继续执行。 业务请求在续跑时不能覆盖已固化角色、工具、模型、质量规则或 RunLimits。一次性的框架动作(例如现有 reflect/compact 的 side branch)仍由框架恢复协议控制。 ### 5.3 config hash 包含与排除 必须进入 hash 的行为配置: - 应用 ID/版本和规范化声明 schema 版本。 - 解析后的角色图、Prompt hash、Skill 版本和模型参数。 - 工具名、schema、实现版本、确认/可编辑参数和 URL policy。 - Provider 的稳定 ID、协议版本和影响行为的公开配置。 - 确定性规则 ID、版本、输入声明和配置。 - RunLimits、默认 validation scopes 和资料继承策略。 不得进入 hash 的运行时秘密: - API key、密码、访问令牌和临时签名 URL。 - 数据库连接池、HTTP client、线程锁和进程对象。 - Provider 当前健康状态、缓存内容和监控指标。 秘密虽不进入 hash,但恢复时凭证缺失仍应启动失败,不能降级成另一数据源。 ## 6. 内部装配概念,不是首版公共 API 下列名称用于框架实现和设计沟通,业务代码不应 import: | 名称 | 内部职责 | |---|---| | `ApplicationRegistry` | 按 ID/版本定位不可变应用声明 | | `ApplicationBinding` | 保存一次解析后的应用依赖、hash 和恢复材料 | | `ApplicationRuntime` | 把 Binding 编译成现有 AgentRunner 的 RunConfig、ToolRegistry、ValidationPolicy 和 Resolver | 业务入口只需要提交应用引用和业务输入。内部结构未来可以重构,不作为 0.1 公共兼容面。 ## 7. 失败语义 | 场景 | 预期行为 | |---|---| | 应用或版本不存在 | 新 Run 拒绝创建;恢复 Run 失败关闭 | | config hash 或角色 hash 不匹配 | 拒绝恢复,报告不匹配对象,不自动迁移 | | Context Provider 暂不可用 | 资料标记 unknown 或 Run 暂停/失败,不能返回伪空资料 | | Artifact 不存在、暂不可用、越权 | 继续使用现有 failed/unknown/error 确定性映射 | | Candidate 归属不匹配 | 拒绝访问并记录审计事件 | | merge 冲突 | 返回结构化冲突,由 Agent/父级决定下一步,不静默覆盖 | | 确定性质量检查异常 | ValidationResult 保持计划完整并失败关闭 | | Event Projector 失败 | 保留 cursor,稍后重放;不修改权威 Trace | | Provider 凭证缺失 | 应用装配失败,不切换到匿名或默认 Provider | ## 8. 业务团队的最小实现面 M3 能力完成后,一套新业务应用预计只需提供: 1. 一个版本化 AgentApplication 描述。 2. 根角色和必要的子角色 Prompt/Skill。 3. 业务工具及其 ToolSet 声明。 4. 一个 TaskContextProvider,将业务资料描述给框架。 5. 一个 ArtifactResolver,让 Validator 可信读取产物。 6. 需要多候选时实现 CandidateRepository。 7. 可确定执行的业务质量规则及 QualityCheckProvider。 8. 可选 RunEventProjector,将 Trace 投影到业务数据库和 UI。 9. 业务入口、最终写回和面向用户的输出解释。 业务团队不应: - 修改 `AgentRunner`、TaskProtocol、TraceStore、Validator 或 ResourceBudgetController。 - 直接读写 `Trace.context.task_protocol` 或伪造 ValidationResult。 - 用全局 `AGENT_PRESETS` 动态注册多个应用的同名角色。 - 把真实业务数据塞进框架 Trace 来替代业务 Repository。 - 绕过 ToolRegistry 直接执行有副作用的工具。 - 将 Projector 当作同步事务钩子。 ## 9. 从当前代码迁移到草案接口 | 当前做法 | 目标做法 | 里程碑 | |---|---|---| | 调用方直接构造 Runner 并注入依赖 | 用 ApplicationRef 解析应用并由内部 Runtime 构造现有 Runner | M3A | | `AGENT_PRESETS` 全局注册角色 | AgentApplication 内的命名空间角色目录 | M3A | | 手工把业务资料塞入 TaskBrief | TaskContextProvider 枚举,框架生成 ContextRef | M3A | | 直接注册一组工具 | ToolSet 声明后编译进 ToolRegistry | M3A | | RunConfigSnapshot 只保存 `project_name` | 同一快照固化 ApplicationRef、角色和解析配置 | M3A | | ArtifactRef 只表示验证材料 | 原协议不变;ApplicationBinding 负责找到对应 Resolver | M3A | | 没有候选权威模型 | CandidateRef + CandidateRepository | M3B | | Validator 主要执行 LLM checks | QualityCheckProvider 增加版本化确定性规则 | M3A/M3B | | 业务订阅开放字典事件 | 稳定事件 envelope + cursor Projector | M3B | ## 10. 接口进入实现前的评审清单 - 同一进程注册应用 A/B 时,角色、工具、Resolver、规则和候选是否完全隔离? - 停止并重启进程后,能否只凭 Trace 解析到同一应用版本和行为配置? - Provider 是否只描述业务资料/规则,所有授权、计划和结果是否仍由框架控制? - CandidateRef 是否能证明 root/task 归属和血缘,Repository 是否校验这些边界? - 确定性规则失败时,是否能只回退产物层而保留已验证证据? - Projector 重放相同事件时,业务数据库是否保持一次效果? - 业务应用是否无需修改 Runner、TaskProtocol、TraceStore 和 Validator? 用于证明这些问题的后续场景见 [reference example 验收合同](./application-reference-contract.md)。在该合同变成可运行测试前,本草案不构成兼容承诺。