架构与依赖方向
/agent-evolution 是唯一管理界面。
接入内容
一个完整接入通常包含:- 把可进化能力改造成不可变、可校验的声明式 Artifact。
- 实现
EvolutionTargetProvider并声明 Target 的风险与支持阶段。 - 在每次领域 Execution 开始时解析并固定 Capability Execution Plan。
- 在业务事务内写入专用 Evolution Outbox。
- 通过 Managed Queue 异步摄取 Learning Event。
- 上报 Shadow 和 Canary 的运行观测。
- 实现安装、激活和回滚,但不直接修改 Active Pointer。
1. 设计 Evolution Target
一个 Target 应对应一个可以独立版本化、独立评测和独立回滚的决策能力。不要把整个插件定义成一个 Target,也不要为每条业务记录创建 Target。 常见拆分方式:
Target 的
capabilities 必须反映真实实现。例如只支持事件采集的 Target 应把 Candidate、Replay 和发布能力全部设为 false;只支持 Golden Replay 的 Target 不应暴露 releaseProvider。
2. 实现 Provider
从@xpert-ai/contracts 导入稳定契约,从 @xpert-ai/plugin-sdk 导入 Provider 装饰器:
candidateForm 使用 i18n 文本。平台根据该描述生成领域中立的 Change Set 表单,但不会解释字段值。
Provider 各阶段职责
3. 设计不可变 Artifact
Candidate Artifact 应保存到独立版本存储,不能写入生产业务表。一个推荐的 manifest 包含:EvolutionArtifactRef:
- 相同输入产生相同的
buildInputsHash。 - Artifact 内容与哈希一一对应,发布后不可覆盖。
- URI 不包含临时文件路径或当前 Pod 的本地状态。
- Provider 版本和依赖版本必须进入 Candidate 与 Capability Version。
- 对原 Candidate 的任何修改都生成新的 Candidate。
4. 注册 Provider
把 Provider 放入插件服务端模块的providers 中。Xpert 会根据 @EvolutionTargetProviderStrategy() 元数据发现它:
5. 解析并固定执行版本闭包
领域 Execution 开始时,从运行时能力注册表获取 Evolution Runtime:subjectKey 是领域稳定主体标识,例如 Case ID、订单 ID 或文档 ID。Evolution Core 只把它用于确定性分流和审计,不理解其业务语义。
必须持久化完整执行计划或至少持久化以下字段:
bundleId和bundleHash- 每个 Target 的
versionId、Artifact Hash 和 Channel deploymentId和选择原因- Shadow Bundle 与 Shadow Assignment
manualTestOverrideId(如果存在)
6. 在运行时执行 Production、Shadow 和 Canary
读取assignments 决定主执行版本:
production:使用当前生产版本。canary:该主体被确定性分配到 Candidate,Candidate 输出可以成为主结果。manual_test_override:非生产管理员创建的一次性 Candidate 命中,仍按 Canary 执行并带审计标记。
shadowAssignments,用相同输入额外执行 Shadow Candidate,但必须:
- 丢弃 Candidate 的业务输出和副作用。
- 不写入生产业务表。
- 为 Production 和 Candidate 分别记录指标。
- 将两者关联到同一个
executionId和subjectKey。
deploymentId + subjectKey 统一完成。
7. 通过 Outbox 采集 Learning Event
Learning Event 必须源自已经提交的业务事实。推荐链路:targetId、范围、能力版本包和主体引用。predictionSummary 与 finalOutcomeSummary 应是可展示的结构化摘要,不要把任意对象直接 JSON.stringify() 后展示给用户。
8. 使用 Managed Queue 投递事件
插件后台任务必须使用平台 Managed Queue,不要创建插件私有 BullMQ 或 Redis 连接。 入队时带上租户、组织和稳定的 Job ID:deliver() 应在同一租户和组织范围内读取 Outbox,调用 ingestLearningEvent(),成功后再标记已投递。重复执行必须由事件 idempotencyKey 安全去重。
9. 上报运行观测
主执行或 Shadow 执行完成后,上报可聚合的运行指标:10. 实现发布操作
install()、activate() 和 rollback() 必须幂等,并返回 ReleaseProviderReceipt。
推荐语义:
install():验证 Artifact 哈希和 Schema,写入插件不可变版本存储,状态变为可加载。activate():确认版本已安装并允许领域运行时读取;不直接切换平台 Active Pointer。rollback():恢复 Provider 侧的旧版本可用状态;不删除失败版本和审计信息。
11. SDK 版本兼容
仓库源码中的 Evolution 契约位于@xpert-ai/contracts,Provider 装饰器和运行时能力位于 @xpert-ai/plugin-sdk。如果你的插件使用的已发布版本尚未包含这些导出:
- 只创建一个明确命名的兼容文件,例如
evolution-sdk.compat.ts。 - 在该文件中模拟当前需要的最小类型和 token。
- 其他业务代码只能从该兼容文件导入,不能散落重复定义。
- 标注待替换的正式包版本。
- 升级后把兼容文件改为正式 re-export,再删除模拟类型。
12. 安全与治理检查
上线前确认:- 所有查询和唯一键都包含租户,组织级 Target 还包含组织。
- Target 声明的
supportedScopes与真实访问边界一致。 - 机密 Learning Event 在摄取前已经脱敏。
- Candidate Builder 只接受声明字段,拒绝未知键、路径穿越和可执行代码。
- Artifact Hash、Schema Version 和 Provider Version 都经过校验。
- Replay、Shadow 不产生业务副作用。
- Agent 没有审批、发布、扩量、生产激活和主动回滚工具。
- 所有后台任务通过 Managed Queue,并且 handler 不依赖 HTTP Request Context。
- 前端可见文本使用 i18n;后端返回稳定错误码或可本地化消息。
13. 测试清单
至少覆盖以下测试:Provider 契约
- 相同输入产生相同 Artifact Hash 和
buildInputsHash。 - 非法 Change Set、Schema、依赖和哈希被拒绝。
install()、activate()、rollback()幂等。- 未声明的能力不会出现在 Target 操作中。
Runtime
- 同一 Execution 只解析一次版本闭包。
- 同一
deploymentId + subjectKey的 Canary 分配稳定。 - Shadow 输出不改变生产结果和业务表。
- 一次性管理员测试命中只消费一次,并在计划中带审计标记。
- 回滚后新请求使用旧稳定版本,历史执行仍引用原版本。
事件链路
- 业务事务回滚时不会留下 Outbox 事件。
- Dispatcher 崩溃后可以重试。
- 重复投递不会产生重复 Learning Event。
- 跨租户或跨组织事件被拒绝。
- 机密但未脱敏的事件被拒绝。
发布治理
- Candidate 不能直接影响 Production。
- 未通过评测或审批不能创建 Release Package。
- 安装版本不改变 Active Pointer。
- Shadow、Canary 和生产门禁按冻结策略执行。
- 严重错误触发暂停,CAS 冲突阻止激活或回滚。
ORG-001、CASE-001 和 AUTO-MOTOR-001,不要把真实客户或项目名称提交到仓库。
14. 本地部署与验收
按插件开发步骤完成构建和测试后,使用平台的本地插件部署流程刷新插件:- 插件 Target 能在 智能体进化 中同步出来。
- 业务复核通过 Outbox 和 Managed Queue 生成真实 Learning Event。
- Candidate 构建不会修改生产业务表或生产 Artifact。
- Golden Replay 使用相同 Snapshot 比较 Production 和 Candidate。
- 安装后生产 Active Pointer 保持不变。
- Shadow 无业务副作用,Canary 使用运行时分配结果。
- 只有门禁满足并完成人工治理后,新请求才解析到新的 Production Capability Version。