Skip to content

架构规划:补齐领域扩展点,明确扩展机制与生命周期内核的解耦边界 #131

Description

@M09Ic

关联 #129#127#123#122;外部协议接入与 Inbox 分别关联 #124#126

本 Issue 承接 #129 的静态装配和生命周期约定,进一步分析业务扩展点的缺口,并明确“扩展机制本身是否应该成为 ext”。以下为设计建议与待实施范围,不表示相关重构已经完成。现状依据当前工作区代码,部分装配文件仍有未提交修改,实施时应以届时主线复核。

问题与目标

目前已经可以贡献 Skill、IOA、Flags、Config、Tool、Command、AOP 和 Hook,但这些概念属于不同层次。继续向中央 Extension API 添加 RegisterX,会使新领域反过来耦合生命周期框架。

目标是:新增 Provider、压缩算法或资源解析器时,只需增加领域实现并调整 Profile 装配,无需修改 core/extension,也不要求其他 ext 实现新方法。

1. 区分四类职责

层次 示例 接入方式
声明与配置 Flags、Config、静态 Skill、模板 普通值和声明函数,入口在运行资源启动前收集
业务能力 Provider、IOA、Tool、Command、存储 构造注入、小接口、领域注册方法
执行干预与观察 Hook、AOP typed 控制点、事实发布与消费者
生命周期 Extension、Set、Scope 初始化、完整图发布、回滚、取消、排空与释放

一个 ext 可以贡献多个领域。只有需要初始化、订阅、后台任务或资源清理的部分才接入 Extension;纯声明和纯算法不增加空 Load/Close。

2. 扩展点现状与优先级

优先级表示设计与实施顺序,不表示能力完全缺失。

机制 当前边界 建议 优先级
Provider 构造与模型路由 调用已有 Provider 接口;默认构造仍通过 switch 选择协议 打通 Profile 到 App/Runtime 的构造注入;确有按名称选择需求时才增加领域工厂表;重试和路由用组合实现
Prompt / Context 组合 已有 SystemPromptFn、TransformContext、BeforeRun 和 Context Hook;产品 Runtime 仍集中构建提示词 复用现有入口,定义提示词段和动态上下文贡献的顺序、来源、预算、失败行为与求值时机
压缩和历史裁剪 BeforeCompact 可以取消执行,自动压缩仍直接调用 compactHistory 注入压缩算法,自动压缩与 /compact 共用;历史提交和会话一致性继续由 Runtime 管理
输入引用解析 Expander 可注入文件和 Skill 读取函数,但引用类型固定为 file/skill 按引用类型接入 Resolver,支持 finding、traffic、session 等;明确取消、大小限制和错误语义
权限、审批和执行策略 typed Hook 已有执行控制点和错误策略 策略通过现有 Hook 接入;需要交互审批时定义宿主无关的请求/响应契约
存储与恢复 Web Service 依赖具体 SQLiteStore;Agent 恢复直接读取历史文件 按消费需求提取 Session/Event/Artifact 等小接口;连接、迁移和关闭归实现所有者
执行环境 Files、Terminal、Proxy 已有资源边界 有本地、容器、远程等真实替换需求时开放文件和进程执行接口,保持执行控制点覆盖真实 IO
外部输入渠道与协议绑定 已有 Inbox、IOA、AOP namespace 和宿主绑定 渠道负责转换及投递,Runtime 负责准入,渠道所有者负责连接、认证和排空
展示、输出与诊断 已有 Console Bindings、timeline renderer、EventOutput、Probe Registry 完善各宿主的贡献接口,事实继续使用现有事件流 按需
Loop、工作流和调度 agent.Loop 已可替换,并已有调度机制 新算法复用 Loop;调度和工作流通过具体能力接入,保持 Session 生命周期单一所有者 按需

Hook 适合介入执行,Provider 接口适合替换能力。不要通过 Hook 隐式接管整套模型调用、压缩或存储,否则返回值、错误传播和所有权会难以追踪。

代码核查入口:

  • agent/provider/provider.goNewProviderFromResolved
  • pkg/app/app.goDependenciesinitProvider 及初始化路径。
  • agent/types.goagent/hooks/points.go:已有 Loop、Prompt、Context、压缩前置契约。
  • pkg/exts/agent/runtime.go:产品提示词与 Agent Config 装配。
  • agent/loop.goagent/compact.go:自动和手动压缩路径。
  • agent/inbox/expand.go:固定引用类型解析。
  • pkg/web/service/service.go:具体 SQLiteStore 依赖。
  • pkg/console/api/bindings.goweb/frontend/src/lib/chat-extensions.tsx:已有展示接入点。

3. 扩展机制本身是否做成 ext

所指的机制 建议 理由
Set、Scope、依赖排序、回滚和关闭 保留独立的最小内核 必须有外部所有者负责启动与关闭;内核不能依赖由自己加载的 ext 才完成自举
Tool Registry、Prompt 组装器、Provider 路由器等领域机制 独立领域模块;需要生命周期时接入 ext 分离业务契约与默认实现即可实现解耦,纯声明和算法不需要额外生命周期包装
发现、配置驱动装配、扩展管理界面 可以独立为模块,暂不引入动态 Loader 当前静态 Profile 足够;未来发现模块可返回候选装配描述,由外层宿主负责图的建立和替换

当前 Tool/Command Registry 已作为图中的生命周期节点加载并排空调用,可直接复用;无需增加仅转发生命周期的 tool-system-ext 或 command-system-ext。

Flags/Config 必须遵守:声明选项 → 解析及校验 → Profile 选择与构造 → Set.Load → 发布。普通 ext 的 Load 不能成为参数声明和 help 生成的前提。

领域消费者依赖业务能力,生命周期适配器依赖领域实现,Profile 同时知道双方并负责接线。新增领域无需在 core/extension 中登记中央能力枚举。

4. 方案对比

方案 收益 代价 结论
中央 ExtensionAPI 不断增加 RegisterX 入口集中、易发现 每个新领域都修改中央接口,形成大接口和依赖聚集 不采用
最小生命周期内核 + 领域接口 + 显式 Profile 装配 类型和所有权明确,新领域不改内核 Profile 需要显式接线 推荐,延续 #129
Context 服务容器 + 动态插件树 动态发现、运行时装卸、作用域覆盖 引入动态依赖、撤销、重载及诊断复杂度 有明确动态需求后单独评估

DSH 的 Prompt 贡献、压缩契约/实现/触发器分离值得借鉴;不据此复制通用服务容器和动态作用域树。Cordis 自身也区分核心生命周期与可选 Loader/HMR,并非把全部自举责任交给普通插件。

参考:

5. 建议实施范围与验收

第一阶段优先补齐已有能力的注入路径和明确缺失的替换契约。中优先级领域以真实第二实现需求为触发条件,不一次性预建全部 Registry。

  • 复核主线现状,明确 Provider 构造以及 Prompt/Context 从 Profile 到 Runtime 的注入路径。
  • 确定 Prompt/Context 贡献的组合规则,避免复制造成第二套 Hook 流水线。
  • 抽取压缩算法契约,使自动压缩和 /compact 调用同一实现;覆盖失败时不提交错误历史、取消及消息一致性。
  • 抽取输入引用 Resolver 契约,以一个新增引用类型验证无需修改中央解析分支;覆盖错误、大小限制和取消语义。
  • 用可替换实现验证领域消费者不依赖具体 ext,并保持默认配置下现有行为。
  • 增加或更新针对实际变更的架构检查:core/extension 不导入业务领域、原始领域实现不依赖宿主生命周期、无纯声明空生命周期节点。
  • 涉及资源的实现验证失败回滚、在途调用排空、Close 重试及依赖寿命保护。
  • 更新设计文档,按实际变更执行相关测试和默认/full 构建,单独记录验证结果。

本 Issue 不引入中央 ExtensionAPI、通用 Contribution/Provide/Require、服务定位器、插件自举递归、运行时单节点热替换或第二套 Session 生命周期。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions