1180 lines
29 KiB
Markdown
1180 lines
29 KiB
Markdown
# AR11 Skill / Specialist / Connector Removable Packaging Specification
|
||
|
||
> **版本**:V1.3
|
||
> **日期**:2026-09-18
|
||
> **性质**:规范性文件(normative)
|
||
> **适用对象**:`skill`、`specialist`、`connector`
|
||
> **关联文档**:
|
||
> - `AR06_技能封装规范.md`
|
||
> - `AR09_对象命名规范.md`
|
||
> - `AR10_应用可删除封装规范.md`
|
||
|
||
## 1. 目标
|
||
|
||
本文定义 `skill`、`specialist`、`connector` 三类对象的可删除封装方式。
|
||
|
||
本文中的“可删除”指:
|
||
|
||
1. 删除一个对象目录
|
||
2. 删除一条注册项
|
||
3. 不需要全仓手工搜改业务代码
|
||
4. 重新构建后不出现编译错误
|
||
5. 运行卸载脚本后,不残留该对象自有资源
|
||
|
||
在当前单仓工程内,合理目标应为:
|
||
|
||
- 删一个目录 + 删一条注册项 + 跑一次卸载 = 安全移除一个对象包
|
||
|
||
但三类对象的封装深度不同:
|
||
|
||
1. `connector` 是连接插件包
|
||
2. `skill` 是能力插件包
|
||
3. `specialist` 是策略定义包
|
||
|
||
它们不能机械复用同一套“完整业务包”模板。
|
||
|
||
## 2. 与 AR10 的关系
|
||
|
||
`AR10_应用可删除封装规范.md` 定义的是 `xapp` 的可删除封装规范。
|
||
|
||
本文是在 AR10 基础上,对另外三类对象做边界化扩展:
|
||
|
||
1. 复用 AR10 的 `manifest / registry / contracts / own boundary` 思想
|
||
2. 保留“删目录 + 删注册项 + 跑卸载”的工程目标
|
||
3. 明确指出:`xapp` 的“完整业务包”模板不能原样套到 `skill / specialist / connector`
|
||
|
||
换句话说:
|
||
|
||
1. AR10 解决的是“一级业务包如何可删除”
|
||
2. AR11 解决的是“能力包 / 策略包 / 连接包如何可删除”
|
||
|
||
## 3. 对 AR10 的复核结论
|
||
|
||
## 3.1 正确的部分
|
||
|
||
AR10 的大方向是正确的,尤其是以下几点:
|
||
|
||
1. 平台层只能认 `manifest / registry / contracts`
|
||
2. 总路由和总导航不应再手写对象业务路径
|
||
3. 私有对象不应继续停留在平台总 `model` 包
|
||
4. 持久化模型不应直接兼任 API DTO
|
||
5. 统计、画像、后台管理应通过 provider 聚合
|
||
6. “删目录 + 删注册 + 跑卸载”是比“删一个文件”更现实的工程目标
|
||
|
||
这些判断对 `xapp` 是成立的,也应成为其他对象的总体方向。
|
||
|
||
## 3.2 需要收窄的部分
|
||
|
||
AR10 的结构不能原样复用于全部对象,主要因为三类对象的职责不同:
|
||
|
||
1. `skill` 不是业务子系统,通常不 own 大量页面、任务和后台管理
|
||
2. `specialist` 不是业务应用,更不应强制 own 独立表、独立路由、独立后台
|
||
3. `connector` 才最接近真正的可插拔基础设施模块
|
||
|
||
因此:
|
||
|
||
1. 对 `xapp`,“完整业务包”模板基本成立
|
||
2. 对 `connector`,AR10 模板大体可复用,但要加强 auth / webhook / secret / health / job 的 own 边界
|
||
3. 对 `skill`,应改写为“能力包”模板
|
||
4. 对 `specialist`,应改写为“策略定义包”模板
|
||
|
||
## 3.3 最终结论
|
||
|
||
AR10 是对的,但它的适用对象主要是 `xapp`。
|
||
|
||
若把 AR10 原样套用到 `skill / specialist / connector`,会出现两种问题:
|
||
|
||
1. 对 `connector` 还不够彻底
|
||
2. 对 `specialist` 则会明显过度工程化
|
||
|
||
## 4. 三类对象的共同硬规则
|
||
|
||
### 4.0 一对象一目录是最终形态
|
||
|
||
对 `skill / specialist / connector` 三类对象而言,最终封装形态必须满足:
|
||
|
||
1. 一个对象对应一个后端目录
|
||
2. 一个对象对应一个前端目录
|
||
3. 该对象的定义文件、资源边界、可删除元数据都落在自己的目录中
|
||
|
||
因此:
|
||
|
||
1. **允许中心化注册**
|
||
2. **不允许中心化定义**
|
||
|
||
“中心化注册”是指:
|
||
|
||
1. registry 统一列出有哪些对象 manifest
|
||
2. installer / uninstall 统一执行安装和清理
|
||
3. platform core 统一聚合 provider
|
||
|
||
“中心化定义”是指:
|
||
|
||
1. 在一个平台公共文件里集中维护多个 specialist 的 prompt 和绑定
|
||
2. 在一个平台公共文件里集中维护多个 skill 的 schema 和静态定义
|
||
3. 在一个平台公共文件里集中维护多个 connector 的 catalog、能力和实现细节
|
||
|
||
前者允许,后者不是最终封装形态。
|
||
|
||
### 4.0.1 允许中心化 / 禁止中心化
|
||
|
||
| 类型 | 是否允许 | 说明 |
|
||
|---|---|---|
|
||
| `core/registry` 集中列出 manifest | 允许 | 这是注册中心 |
|
||
| `core/uninstall` 统一执行清理 | 允许 | 这是卸载中心 |
|
||
| `specialists/rules.go` 这类集中式多专员定义文件 | 禁止作为最终形态 | 最多只能做迁移期兼容层 |
|
||
| `skills/keys.go` 或全局 skill catalog 承载多个 skill 完整定义 | 禁止作为最终形态 | 这会阻断目录级删除 |
|
||
| `connectors/static_catalog.go` 集中维护多个 connector 完整能力定义 | 禁止作为最终形态 | 该文件承担完整定义中心职责,未收敛到注册中心形态 |
|
||
|
||
### 4.1 平台层只能依赖 registry / manifest / contracts
|
||
|
||
平台层允许依赖:
|
||
|
||
1. `core/registry`
|
||
2. `core/contracts`
|
||
3. 对象包暴露的 `manifest`
|
||
|
||
平台层禁止依赖:
|
||
|
||
1. 对象包内部的 `domain`
|
||
2. 对象包内部的 `repo`
|
||
3. 对象包内部的 `service`
|
||
4. 对象包内部的前端组件和内部运行时实现
|
||
|
||
### 4.2 总路由不得手写对象内部业务入口
|
||
|
||
总路由只能装配对象包,不得继续手写对象内部路径。
|
||
|
||
### 4.3 总导航不得手写对象内部菜单
|
||
|
||
平台导航只能聚合 manifest 暴露的菜单项,不能再认识对象包内部细节。
|
||
|
||
### 4.4 平台 seed 不得直接创建具体对象定义
|
||
|
||
平台总 seed 只允许:
|
||
|
||
1. 加载 registry
|
||
2. 调用对象包自注册 seed
|
||
|
||
平台总 seed 不允许继续硬编码:
|
||
|
||
1. 某个 specialist 的 prompt 和绑定
|
||
2. 某个 skill 的默认定义
|
||
3. 某个 connector 的静态目录项
|
||
|
||
### 4.5 删除对象包后,平台只能“少一个能力”
|
||
|
||
删除某个对象包后,平台允许出现:
|
||
|
||
1. 某个能力不再可选
|
||
2. 某个菜单自动消失
|
||
3. 某个 provider 的结果缺失
|
||
|
||
平台不允许出现:
|
||
|
||
1. 编译错误
|
||
2. 运行时 import error
|
||
3. 路由残留导致启动失败
|
||
4. 平台层空指针
|
||
|
||
### 4.6 一级导航三是对象治理区
|
||
|
||
`skill / specialist / connector` 三类对象,应统一纳入一级导航三进行治理。
|
||
|
||
一级导航三定位为**对象治理区**。
|
||
|
||
它应至少支持:
|
||
|
||
1. 查看对象基础信息
|
||
2. 编辑对象定义
|
||
3. 启停对象
|
||
4. 复制对象
|
||
5. 版本管理
|
||
6. 发布与回滚
|
||
|
||
因此:
|
||
|
||
1. 对象包的默认定义在目录中
|
||
2. 对象包的治理入口在导航三中
|
||
3. 对象包的当前生效状态不应直接依赖源码文件实时变更
|
||
|
||
### 4.7 对象包文件层与运行时持久化层必须分离
|
||
|
||
为了同时满足“目录级可删除”和“在线可编辑”,必须显式区分两层:
|
||
|
||
1. **对象包文件层**
|
||
2. **运行时持久化层**
|
||
|
||
对象包文件层负责:
|
||
|
||
1. 默认定义
|
||
2. 内置模板
|
||
3. manifest
|
||
4. 可导入导出的包资源
|
||
5. 可版本化的静态素材
|
||
|
||
运行时持久化层负责:
|
||
|
||
1. 管理员在导航三中的编辑结果
|
||
2. 草稿版本
|
||
3. 已发布版本
|
||
4. 回滚记录
|
||
5. 审计记录
|
||
|
||
因此:
|
||
|
||
1. 包目录是“对象源码与默认定义”
|
||
2. 数据库是“当前运行时生效定义”
|
||
|
||
### 4.8 在线编辑结果默认不直接回写源码文件
|
||
|
||
管理员在导航三中修改对象时,默认不应直接写回仓库内的 `json / md / js / go` 文件。
|
||
|
||
原因如下:
|
||
|
||
1. 运行中服务不适合直接改仓库源码
|
||
2. 多人协作下,文件写回缺少稳定的审计、并发控制、发布控制
|
||
3. 运行时读取数据库比扫描仓库文件更稳定
|
||
4. “对象包可删除”和“在线治理”是两套不同诉求,不能混为一体
|
||
|
||
因此规范要求:
|
||
|
||
1. 包目录中的 `json / md` 文件用于默认定义、模板、导入导出、离线版本管理
|
||
2. 在线编辑后的结构化结果应写入数据库
|
||
3. 运行时以数据库中的发布版本为准,而不是以仓库文件实时内容为准
|
||
|
||
### 4.9 文件格式建议
|
||
|
||
对象包文件层推荐使用可读、可审阅的静态格式:
|
||
|
||
1. `manifest`:`go / js`
|
||
2. 结构化配置:`json`
|
||
3. 长文本说明:`md`
|
||
4. 资源素材:对象目录内自有资源文件
|
||
|
||
但这些文件的角色是:
|
||
|
||
1. 包定义来源
|
||
2. 默认值来源
|
||
3. 导入导出载体
|
||
4. 开发期版本管理载体
|
||
|
||
它们不是在线治理的唯一真实存储。
|
||
|
||
### 4.10 发布模型建议
|
||
|
||
对象治理区建议统一采用以下发布模型:
|
||
|
||
1. 包默认定义
|
||
2. 运行时草稿
|
||
3. 已发布版本
|
||
4. 回滚版本
|
||
|
||
推荐流程:
|
||
|
||
1. 从对象包默认定义初始化对象
|
||
2. 管理员在导航三中编辑草稿
|
||
3. 发布后生成当前生效版本
|
||
4. 运行时只读取已发布版本
|
||
5. 删除对象目录时,只影响该对象的包来源和后续发布,不影响历史审计记录
|
||
|
||
### 4.11 定义条目也属于对象 own boundary
|
||
|
||
对 `skill / specialist / connector` 而言,own boundary 不能只覆盖代码、表和 storage key,还必须覆盖定义层资源。
|
||
|
||
定义层资源至少包括:
|
||
|
||
1. 对象定义记录
|
||
2. 对象目录页 / 市场页 / 治理页中的对象条目
|
||
3. seed 自动创建的对象默认定义
|
||
4. 对象包发布后形成的对象目录映射
|
||
|
||
如果删除对象目录后,这些定义条目仍然残留,那么就仍会出现:
|
||
|
||
1. 僵尸入口
|
||
2. 失效对象卡片
|
||
3. 后台目录中的死条目
|
||
4. 平台试图按已删除对象继续加载配置
|
||
|
||
因此,定义条目必须被视为对象 own boundary 的一部分。
|
||
|
||
### 4.12 Shared Reference Policy
|
||
|
||
对象删除时,不仅要处理 own resource,还要处理平台共享域中的历史引用。
|
||
|
||
共享引用至少包括:
|
||
|
||
1. 历史任务
|
||
2. 项目绑定
|
||
3. 收藏 / 最近使用
|
||
4. 历史通知
|
||
5. 审计日志
|
||
6. 历史发布版本
|
||
|
||
规范允许以下策略:
|
||
|
||
1. `block_uninstall`
|
||
2. `convert_to_tombstone`
|
||
3. `detach_reference`
|
||
4. `readonly_history`
|
||
|
||
不同对象可选择不同策略,但必须显式声明,不能留给运行时临时猜测。
|
||
|
||
### 4.13 Enforcement / Guard
|
||
|
||
若要保证封装不回退,平台至少应建立以下自动守卫:
|
||
|
||
1. import 边界检查
|
||
2. registry 完整性检查
|
||
3. owned resource audit
|
||
4. 定义条目完整性检查
|
||
5. shared reference dry-run 检查
|
||
6. CI gate
|
||
|
||
## 5. Skill 规范
|
||
|
||
## 5.1 Skill 的工程定义
|
||
|
||
`skill` 的本质是“能力包”,不是“业务子系统”。
|
||
|
||
它回答的是:
|
||
|
||
1. 这件事怎么做
|
||
2. 需要什么输入
|
||
3. 会产生什么结果
|
||
|
||
它通常不应该自带完整后台系统。
|
||
|
||
## 5.2 与 AR06 的关系
|
||
|
||
`AR06_技能封装规范.md` 解决的是“技能文件如何组织”。
|
||
|
||
本文在此基础上进一步定义:
|
||
|
||
1. 技能如何拥有 manifest
|
||
2. 技能如何注册到 platform
|
||
3. 技能如何形成 own boundary
|
||
4. 技能如何达到目录级安全删除
|
||
|
||
所以:
|
||
|
||
1. AR06 是文件组织规范
|
||
2. AR11 是可删除封装规范
|
||
|
||
二者不冲突,而是前后两层。
|
||
|
||
## 5.3 推荐目录结构
|
||
|
||
### 后端
|
||
|
||
```text
|
||
backend-go/internal/skills/
|
||
core/
|
||
contracts.go
|
||
registry.go
|
||
manifest.go
|
||
uninstall.go
|
||
packages/
|
||
document_translate/
|
||
manifest.go
|
||
provider.go
|
||
dto/
|
||
schema/
|
||
tests/
|
||
contract_review/
|
||
manifest.go
|
||
provider.go
|
||
dto/
|
||
schema/
|
||
tests/
|
||
```
|
||
|
||
### 前端
|
||
|
||
```text
|
||
frontend/src/skills/
|
||
core/
|
||
contracts.js
|
||
registry.js
|
||
installer.js
|
||
uninstall.js
|
||
packages/
|
||
document-translate/
|
||
manifest.js
|
||
executor.js
|
||
ResultCard.vue
|
||
composer.js
|
||
schema.js
|
||
assets/
|
||
contract-review/
|
||
manifest.js
|
||
executor.js
|
||
ResultCard.vue
|
||
composer.js
|
||
schema.js
|
||
assets/
|
||
```
|
||
|
||
## 5.4 Skill manifest 必须拥有的内容
|
||
|
||
每个 skill manifest 至少应声明:
|
||
|
||
1. `key`
|
||
2. `label`
|
||
3. `source`
|
||
4. `executor`
|
||
5. `input_schema`
|
||
6. `output_schema`
|
||
7. `artifact_schema`
|
||
8. `result_renderer`
|
||
9. `starter_prompts`
|
||
10. `owned_storage_keys`
|
||
11. `owned_tables`
|
||
12. `owned_definition_keys`
|
||
13. `owned_catalog_entries`
|
||
14. `shared_reference_policy`
|
||
15. `register_providers()`
|
||
|
||
### 5.5 Skill registry 的职责
|
||
|
||
skill registry 只负责:
|
||
|
||
1. 注册 skill manifest
|
||
2. 返回可用技能清单
|
||
3. 安装技能入口
|
||
4. 卸载技能资源
|
||
|
||
skill registry 不负责:
|
||
|
||
1. 业务执行
|
||
2. 页面逻辑
|
||
3. 平台级 fallback 逻辑
|
||
|
||
## 5.6 Skill 的资源归属
|
||
|
||
skill 可以 own:
|
||
|
||
1. 执行器
|
||
2. 输入输出 schema
|
||
3. 结果卡片
|
||
4. 对话挂载块
|
||
5. 可选 provider
|
||
6. 可选 own table
|
||
7. 可选 own localStorage key
|
||
|
||
skill 不应默认 own:
|
||
|
||
1. 一整套业务导航
|
||
2. 大量后台管理页面
|
||
3. 一整套任务系统
|
||
4. 专属业务报表入口
|
||
|
||
## 5.7 Skill 的命名空间建议
|
||
|
||
一个 skill 若拥有自有资源,命名空间应为:
|
||
|
||
1. 表:`skill_<skill_key>_*`
|
||
2. storage key:`skill:<skill_key>:*`
|
||
3. provider key:`skill.<skill_key>.*`
|
||
|
||
## 5.8 Skill 的删除标准
|
||
|
||
一个 skill 只有满足以下条件,才算达到“整包可删除”:
|
||
|
||
1. 删除 `frontend/src/skills/packages/<skill>/`
|
||
2. 删除 `backend-go/internal/skills/packages/<skill>/`
|
||
3. 删除 registry 注册项
|
||
4. 平台页面不直接 import 它的 executor / result card
|
||
5. 平台构建通过
|
||
6. 只是少了这个技能,不影响其他技能和工作台运行
|
||
|
||
## 5.9 当前仓库的主要问题
|
||
|
||
当前仓库中,`skill` 仍存在以下硬耦合:
|
||
|
||
1. 技能静态定义大量停留在全局配置
|
||
2. 后端存在独立的技能 key 硬编码白名单
|
||
3. 工作台页面仍直接感知部分技能运行时细节
|
||
|
||
因此当前的 `skill` 还没有达到目录级安全删除标准。
|
||
|
||
### 5.10 迁移期兼容层判定
|
||
|
||
以下结构只允许作为迁移期兼容层存在,不是最终封装形态:
|
||
|
||
1. 全局静态 `skill catalog`
|
||
2. 后端统一维护的 skill key 白名单
|
||
3. 平台页面直接 import 单个 skill 的内部 executor / result card
|
||
|
||
兼容层若存在,必须满足:
|
||
|
||
1. 只做桥接和转发
|
||
2. 不再新增新 skill 定义
|
||
3. 有明确退场目标
|
||
|
||
### 5.11 Skill 在对象治理区的编辑模型
|
||
|
||
`skill` 应允许在一级导航三中被查看、编辑、复制、启停和发布。
|
||
|
||
但编辑内容应分层:
|
||
|
||
1. 包目录中保留 skill 的默认定义
|
||
2. 导航三中的编辑结果写入运行时持久化层
|
||
|
||
对 `skill` 而言,包目录中适合保留的内容包括:
|
||
|
||
1. `manifest.js / manifest.go`
|
||
2. `schema.js / schema.json`
|
||
3. `starter prompts`
|
||
4. `result renderer` 的默认元数据
|
||
|
||
运行时持久化层适合保存:
|
||
|
||
1. 当前启用状态
|
||
2. 管理员修改后的输入输出 schema
|
||
3. 对话挂载配置
|
||
4. 发布版本与回滚记录
|
||
|
||
因此,`skill` 可以使用 `json` 表达部分默认定义,但导航三中的在线编辑结果不应直接回写 skill 源码目录。
|
||
|
||
## 6. Specialist 规范
|
||
|
||
## 6.1 Specialist 的工程定义
|
||
|
||
`specialist` 的本质是“策略定义包”,不是“业务应用包”。
|
||
|
||
它回答的是:
|
||
|
||
1. 以谁的方式做
|
||
2. 用什么身份说话
|
||
3. 默认挂载哪些技能和连接器
|
||
4. 以什么交互卡片和任务骨架呈现
|
||
|
||
因此,不应把每个 specialist 都设计成自带一整套后端系统的业务模块。
|
||
|
||
## 6.2 推荐目录结构
|
||
|
||
### 后端
|
||
|
||
```text
|
||
backend-go/internal/specialists/
|
||
core/
|
||
contracts.go
|
||
registry.go
|
||
prompt_provider.go
|
||
binding_provider.go
|
||
uninstall.go
|
||
packages/
|
||
contract_review/
|
||
manifest.go
|
||
prompt.md
|
||
bindings.json
|
||
interaction_card.json
|
||
seeds.go
|
||
tests/
|
||
report_generation/
|
||
manifest.go
|
||
prompt.md
|
||
bindings.json
|
||
interaction_card.json
|
||
seeds.go
|
||
tests/
|
||
```
|
||
|
||
### 前端
|
||
|
||
```text
|
||
frontend/src/specialists/
|
||
core/
|
||
contracts.js
|
||
registry.js
|
||
uninstall.js
|
||
packages/
|
||
contract-review/
|
||
manifest.js
|
||
interaction-card.json
|
||
starter-prompts.json
|
||
bindings.json
|
||
assets/
|
||
report-generation/
|
||
manifest.js
|
||
interaction-card.json
|
||
starter-prompts.json
|
||
bindings.json
|
||
assets/
|
||
```
|
||
|
||
## 6.3 Specialist manifest 必须拥有的内容
|
||
|
||
每个 specialist manifest 至少应声明:
|
||
|
||
1. `key`
|
||
2. `label`
|
||
3. `mode`
|
||
4. `prompt_file`
|
||
5. `interaction_card`
|
||
6. `starter_prompts`
|
||
7. `allowed_skills`
|
||
8. `allowed_connectors`
|
||
9. `default_task_template`
|
||
10. `default_action_template`
|
||
11. `owned_seed_keys`
|
||
12. `owned_storage_keys`
|
||
13. `owned_definition_keys`
|
||
14. `owned_catalog_entries`
|
||
15. `shared_reference_policy`
|
||
|
||
## 6.4 Specialist registry 的职责
|
||
|
||
specialist registry 只负责:
|
||
|
||
1. 注册 specialist manifest
|
||
2. 暴露 prompt provider
|
||
3. 暴露 binding provider
|
||
4. 安装 specialist 目录项
|
||
5. 卸载 specialist 自有资源
|
||
|
||
specialist registry 不负责:
|
||
|
||
1. 创建任务实例
|
||
2. 执行技能
|
||
3. 查询 connector 数据
|
||
|
||
## 6.5 Specialist 的资源归属
|
||
|
||
specialist 应 own:
|
||
|
||
1. prompt / rule file
|
||
2. 技能绑定
|
||
3. 连接器绑定
|
||
4. 交互卡片
|
||
5. 默认任务骨架
|
||
6. 默认动作骨架
|
||
7. 自身 seed
|
||
|
||
specialist 不应默认 own:
|
||
|
||
1. 独立业务数据表
|
||
2. 独立后台管理系统
|
||
3. 独立业务路由
|
||
4. 独立统计系统
|
||
|
||
除非未来出现真正“专员子产品”级别的对象,否则不建议突破这条边界。
|
||
|
||
## 6.6 Specialist 的命名空间建议
|
||
|
||
specialist 若拥有自有资源,命名空间应为:
|
||
|
||
1. seed key:`specialist.<specialist_key>.*`
|
||
2. storage key:`specialist:<specialist_key>:*`
|
||
3. provider key:`specialist.<specialist_key>.*`
|
||
|
||
## 6.7 Specialist 的删除标准
|
||
|
||
一个 specialist 只有满足以下条件,才算达到“整包可删除”:
|
||
|
||
1. 删除 `frontend/src/specialists/packages/<specialist>/`
|
||
2. 删除 `backend-go/internal/specialists/packages/<specialist>/`
|
||
3. 删除 registry 注册项
|
||
4. 平台 prompt 组装只通过 provider,不直读具体对象文件
|
||
5. 任务系统遇到历史 `specialist_key` 时可安全 fallback
|
||
6. 平台构建通过
|
||
7. 只是少了这个专员定义,不影响任务系统和其他专员
|
||
|
||
## 6.8 当前仓库的主要问题
|
||
|
||
当前仓库中,`specialist` 仍存在以下硬耦合:
|
||
|
||
1. 平台 API 仍直接组装专员 prompt
|
||
2. 平台种子仍承载专员说明书和技能绑定
|
||
3. 其他模块仍直接感知专员的具体字段结构
|
||
|
||
因此当前的 `specialist` 仍然是“平台共享对象”,还不是可删除的策略定义包。
|
||
|
||
### 6.9 关于集中式 `rules.go` 的判定
|
||
|
||
类似下面这种结构:
|
||
|
||
1. 一个公共文件里集中维护多个 specialist 的 prompt
|
||
2. 同一个公共文件里集中维护多个 specialist 的 skill binding
|
||
3. 同一个公共文件里集中维护多个 specialist 的默认规则草稿
|
||
|
||
它**不算完成封装**。
|
||
|
||
这种文件最多只能算:
|
||
|
||
1. 迁移期种子汇总
|
||
2. 迁移期兼容层
|
||
3. 过渡期桥接实现
|
||
|
||
但它不是最终形态。
|
||
|
||
`specialist` 的最终形态必须是:
|
||
|
||
1. 一个 specialist 一个目录
|
||
2. 每个 specialist 自己拥有 prompt / binding / interaction card / manifest
|
||
3. 平台只通过 registry 和 provider 认识它
|
||
|
||
### 6.10 Specialist 在对象治理区的编辑模型
|
||
|
||
`specialist` 也应允许在一级导航三中被查看、编辑、启停、复制和发布。
|
||
|
||
但其编辑模型应遵守“文件层与持久化层分离”:
|
||
|
||
1. 包目录保留默认 prompt、默认 binding、默认 interaction card
|
||
2. 导航三中的编辑结果写入数据库中的 specialist 草稿与发布版本
|
||
|
||
对 `specialist` 而言,包目录中适合保留的内容包括:
|
||
|
||
1. `prompt.md`
|
||
2. `bindings.json`
|
||
3. `interaction_card.json`
|
||
4. `starter-prompts.json`
|
||
5. `manifest.go / manifest.js`
|
||
|
||
运行时持久化层适合保存:
|
||
|
||
1. 管理员编辑后的 prompt 版本
|
||
2. 管理员编辑后的技能绑定和连接器绑定
|
||
3. 启停状态
|
||
4. 发布版本
|
||
5. 回滚与审计记录
|
||
|
||
因此:
|
||
|
||
1. `specialist` 可以以 `md + json` 作为包定义格式
|
||
2. 但在线编辑后的结果不应直接回写 `backend-go/internal/specialists/packages/...`
|
||
3. 运行时应以数据库中的已发布版本为准
|
||
|
||
## 7. Connector 规范
|
||
|
||
## 7.1 Connector 的工程定义
|
||
|
||
`connector` 的本质是“连接包 / 适配器包”。
|
||
|
||
它回答的是:
|
||
|
||
1. 连谁
|
||
2. 怎么鉴权
|
||
3. 能查什么对象
|
||
4. 能执行什么动作
|
||
5. 健康状态怎么判断
|
||
|
||
在三类对象里,`connector` 最适合做成真正的可插拔插件包。
|
||
|
||
## 7.2 推荐目录结构
|
||
|
||
### 后端
|
||
|
||
```text
|
||
backend-go/internal/connectors/
|
||
core/
|
||
contracts.go
|
||
registry.go
|
||
auth_contract.go
|
||
query_contract.go
|
||
webhook_contract.go
|
||
health_contract.go
|
||
uninstall.go
|
||
packages/
|
||
kingdee/
|
||
manifest.go
|
||
adapter.go
|
||
auth.go
|
||
health.go
|
||
webhook.go
|
||
dto/
|
||
schema/
|
||
tests/
|
||
feishu_bitable/
|
||
manifest.go
|
||
adapter.go
|
||
auth.go
|
||
health.go
|
||
webhook.go
|
||
dto/
|
||
schema/
|
||
tests/
|
||
```
|
||
|
||
### 前端
|
||
|
||
```text
|
||
frontend/src/connectors/
|
||
core/
|
||
contracts.js
|
||
registry.js
|
||
uninstall.js
|
||
packages/
|
||
kingdee/
|
||
manifest.js
|
||
settings.js
|
||
health.js
|
||
assets/
|
||
feishu-bitable/
|
||
manifest.js
|
||
settings.js
|
||
health.js
|
||
assets/
|
||
```
|
||
|
||
## 7.3 Connector manifest 必须拥有的内容
|
||
|
||
每个 connector manifest 至少应声明:
|
||
|
||
1. `key`
|
||
2. `label`
|
||
3. `direction`
|
||
4. `auth_kind`
|
||
5. `supported_objects`
|
||
6. `query_provider`
|
||
7. `webhook_provider`
|
||
8. `health_provider`
|
||
9. `owned_secret_keys`
|
||
10. `owned_tables`
|
||
11. `owned_job_keys`
|
||
12. `owned_storage_keys`
|
||
13. `owned_definition_keys`
|
||
14. `owned_catalog_entries`
|
||
15. `shared_reference_policy`
|
||
|
||
## 7.4 Connector registry 的职责
|
||
|
||
connector registry 只负责:
|
||
|
||
1. 注册 connector manifest
|
||
2. 按 key 路由到 provider
|
||
3. 安装 connector 目录项
|
||
4. 枚举 connector 健康和能力
|
||
5. 卸载 connector 自有资源
|
||
|
||
connector registry 不负责:
|
||
|
||
1. 平台级业务调度
|
||
2. 平台统计拼装
|
||
3. 平台任务决策
|
||
|
||
## 7.5 Connector 的资源归属
|
||
|
||
connector 应 own:
|
||
|
||
1. adapter
|
||
2. auth
|
||
3. query
|
||
4. webhook
|
||
5. health check
|
||
6. secret key 命名空间
|
||
7. own tables
|
||
8. own jobs
|
||
9. own localStorage key
|
||
|
||
connector 不应再把这些能力散在平台通用文件中。
|
||
|
||
## 7.6 Connector 的命名空间建议
|
||
|
||
connector 的命名空间建议如下:
|
||
|
||
1. 表:`connector_<connector_key>_*`
|
||
2. secret key:`connector.<connector_key>.*`
|
||
3. job key:`connector.<connector_key>.*`
|
||
4. storage key:`connector:<connector_key>:*`
|
||
5. provider key:`connector.<connector_key>.*`
|
||
|
||
## 7.7 Connector 的删除标准
|
||
|
||
一个 connector 只有满足以下条件,才算达到“整包可删除”:
|
||
|
||
1. 删除 `frontend/src/connectors/packages/<connector>/`
|
||
2. 删除 `backend-go/internal/connectors/packages/<connector>/`
|
||
3. 删除 registry 注册项
|
||
4. 平台 runtime 不再 `switch key`
|
||
5. 平台控制台 / 统计页只消费 provider 输出
|
||
6. secret / webhook / job / health 状态都在该 connector 命名空间下
|
||
7. 平台构建通过
|
||
|
||
## 7.8 当前仓库的主要问题
|
||
|
||
当前仓库中,`connector` 仍存在以下硬耦合:
|
||
|
||
1. connector registry 仍是平台硬编码 map
|
||
2. runtime 仍直接 import connector 根包并调用具体能力
|
||
3. 前端还没有 connector manifest / registry 分层
|
||
|
||
因此 `connector` 虽然最接近插件化,但仍未达到目录级安全删除标准。
|
||
|
||
### 7.9 关于集中式 connector catalog 的判定
|
||
|
||
类似下面这种结构:
|
||
|
||
1. 一个公共文件里集中维护多个 connector 的 definition
|
||
2. 在同一个 catalog 中继续扩张多个 connector 的能力、对象、动作
|
||
3. 平台 runtime 直接依赖这个 catalog 来判断 connector 行为
|
||
|
||
它也不算完成封装。
|
||
|
||
这种文件最多只能算:
|
||
|
||
1. 迁移期注册表
|
||
2. 迁移期兼容目录
|
||
3. 过渡期桥接实现
|
||
|
||
但它不是最终形态。
|
||
|
||
`connector` 的最终形态必须是:
|
||
|
||
1. 一个 connector 一个目录
|
||
2. 每个 connector 自己拥有 adapter / auth / health / webhook / manifest
|
||
3. 平台只通过 registry 和 contracts 认识它
|
||
|
||
### 7.10 Connector 在对象治理区的编辑模型
|
||
|
||
`connector` 同样应纳入一级导航三治理,但它的在线编辑边界要更谨慎。
|
||
|
||
包目录中适合保留:
|
||
|
||
1. `manifest`
|
||
2. 默认 settings 元数据
|
||
3. 健康检查元数据
|
||
4. 能力声明
|
||
|
||
运行时持久化层适合保存:
|
||
|
||
1. connector 启停状态
|
||
2. 租户级配置
|
||
3. 凭据引用
|
||
4. 健康状态快照
|
||
5. 发布版本与审计记录
|
||
|
||
特别说明:
|
||
|
||
1. connector 的在线治理通常只改配置和启停
|
||
2. 不应允许在导航三中直接改 adapter 源码实现
|
||
3. 凭据应进入独立 secret 存储,不应直接裸写进包定义文件
|
||
|
||
## 8. 三类对象的拥有边界
|
||
|
||
为了避免过度工程化,三类对象的拥有边界必须明确区分。
|
||
|
||
### 8.1 Skill owns
|
||
|
||
1. executor
|
||
2. schema
|
||
3. result card
|
||
4. composer block
|
||
5. capability provider
|
||
|
||
### 8.2 Specialist owns
|
||
|
||
1. prompt
|
||
2. bindings
|
||
3. interaction card
|
||
4. default strategy
|
||
5. default task skeleton
|
||
|
||
### 8.3 Connector owns
|
||
|
||
1. adapter
|
||
2. auth
|
||
3. health
|
||
4. webhook
|
||
5. query
|
||
6. secrets
|
||
7. jobs
|
||
8. own tables
|
||
|
||
因此:
|
||
|
||
1. `skill` 是“做什么”
|
||
2. `specialist` 是“以谁的方式做”
|
||
3. `connector` 是“连谁、取谁、写谁”
|
||
|
||
## 9. 合同接口建议
|
||
|
||
## 9.1 Skill manifest
|
||
|
||
```text
|
||
SkillManifest
|
||
Key()
|
||
Meta()
|
||
Install()
|
||
RegisterProviders()
|
||
OwnedTables()
|
||
OwnedStorageKeys()
|
||
OwnedDefinitionKeys()
|
||
OwnedCatalogEntries()
|
||
SharedReferencePolicy()
|
||
```
|
||
|
||
## 9.2 Specialist manifest
|
||
|
||
```text
|
||
SpecialistManifest
|
||
Key()
|
||
Meta()
|
||
PromptProvider()
|
||
BindingProvider()
|
||
RegisterSeeds()
|
||
OwnedStorageKeys()
|
||
OwnedDefinitionKeys()
|
||
OwnedCatalogEntries()
|
||
SharedReferencePolicy()
|
||
```
|
||
|
||
## 9.3 Connector manifest
|
||
|
||
```text
|
||
ConnectorManifest
|
||
Key()
|
||
Meta()
|
||
RegisterQueryProvider()
|
||
RegisterWebhookProvider()
|
||
RegisterHealthProvider()
|
||
RegisterMigrations()
|
||
OwnedTables()
|
||
OwnedSecretKeys()
|
||
OwnedJobKeys()
|
||
OwnedStorageKeys()
|
||
OwnedDefinitionKeys()
|
||
OwnedCatalogEntries()
|
||
SharedReferencePolicy()
|
||
```
|
||
|
||
## 10. 卸载协议
|
||
|
||
三类对象都必须支持卸载协议,但清理维度不同。
|
||
|
||
### 10.1 Skill uninstall
|
||
|
||
至少应支持:
|
||
|
||
1. 清理 owned storage key
|
||
2. 清理 owned table
|
||
3. 清理 provider 注册
|
||
4. 清理 definition key / catalog entry
|
||
5. 报告 shared reference 的阻塞或降级结果
|
||
|
||
### 10.2 Specialist uninstall
|
||
|
||
至少应支持:
|
||
|
||
1. 清理 owned storage key
|
||
2. 清理 seed 注册
|
||
3. 移除 prompt / binding provider
|
||
4. 对历史任务 key 做 fallback,而不是报错
|
||
5. 清理 definition key / catalog entry
|
||
6. 对历史发布版本和任务引用执行 tombstone / readonly 策略
|
||
|
||
### 10.3 Connector uninstall
|
||
|
||
至少应支持:
|
||
|
||
1. 清理 owned storage key
|
||
2. 清理 owned table
|
||
3. 清理 secret key
|
||
4. 清理 webhook 配置
|
||
5. 清理 job key
|
||
6. 清理 provider 注册
|
||
7. 清理 definition key / catalog entry
|
||
8. 对共享引用执行 block / detach / tombstone 策略
|
||
|
||
### 10.4 卸载的统一 dry-run 输出要求
|
||
|
||
三类对象的卸载都应支持统一的 `dry_run` 输出,至少包括:
|
||
|
||
1. 将被清理的 owned resource
|
||
2. 将被清理的定义条目
|
||
3. 将被阻塞的共享引用
|
||
4. 将被降级为 tombstone / readonly 的历史引用
|
||
|
||
## 11. 迁移顺序
|
||
|
||
推荐按以下顺序实施,避免边搬边炸:
|
||
|
||
1. 先建立 `skills / specialists / connectors` 的 `core/contracts`
|
||
2. 建立三类对象各自的 registry
|
||
3. 先把平台层硬编码改为 registry 消费
|
||
4. 再把默认定义迁成 manifest 注册
|
||
5. 再搬迁对象包目录
|
||
6. 最后补卸载脚本和 owned resource 清理
|
||
|
||
这个顺序的核心原因是:
|
||
|
||
1. 先修正依赖方向
|
||
2. 再修正代码落点
|
||
3. 最后修正资源所有权
|
||
|
||
## 12. 判定红线
|
||
|
||
如果一个 `skill / specialist / connector` 还存在以下任意一条,则不算完成封装:
|
||
|
||
1. 总路由中仍手写它的内部业务路径
|
||
2. 总导航中仍手写它的对象级菜单
|
||
3. 平台配置文件仍硬编码它的完整定义
|
||
4. 平台总 seed 仍直接创建它
|
||
5. 别的模块还能直接 import 它内部包
|
||
6. 统计、控制台、工作台仍直接读取它的内部实现细节
|
||
7. 该对象自己的存储 key / 表 / job / secret 没有进入 own 命名空间
|
||
8. 一个公共定义文件里仍集中维护多个对象的完整定义
|
||
9. 对象定义记录、目录条目、seed 默认定义没有进入 own boundary
|
||
10. 共享引用没有明确降级策略
|
||
11. 缺少 `dry_run`、资源审计或 CI guard
|
||
|
||
### 12.1 集中式定义文件的红线说明
|
||
|
||
以下文件形态,不管名字叫什么,只要内容本质相同,都应视为未完成封装:
|
||
|
||
1. 多 specialist 的集中式规则定义文件
|
||
2. 多 skill 的集中式静态定义文件
|
||
3. 多 connector 的集中式 catalog 定义文件
|
||
|
||
判断标准取决于它是否同时满足:
|
||
|
||
1. 承载多个对象
|
||
2. 承载对象完整定义,而不只是注册引用
|
||
3. 删除单个对象时仍需进入该文件手工删业务细节
|
||
|
||
只要满足这三条,就说明它仍属于“定义中心”,尚未收敛到“注册中心”。
|
||
|
||
### 12.2 Enforcement / Guard 的最低要求
|
||
|
||
若三类对象要长期保持可删除封装,平台至少应实现:
|
||
|
||
1. import boundary lint
|
||
2. registry completeness check
|
||
3. owned definition audit
|
||
4. shared reference dry-run report
|
||
5. CI fail 条件
|
||
|
||
## 13. 验收清单
|
||
|
||
三类对象只有满足以下条件,才算达到“整包可删除”:
|
||
|
||
1. 删除对象目录
|
||
2. 删除 registry 注册项
|
||
3. 前后端构建通过
|
||
4. 平台层没有 import 残留
|
||
5. 卸载脚本只清理该对象 own 的资源
|
||
6. 平台只是少一个能力,不发生整体失败
|
||
7. 对象定义记录、目录条目、seed 默认定义不会残留死入口
|
||
8. `dry_run` 能准确报告 shared reference 的阻塞、解绑与 tombstone 结果
|
||
|
||
## 14. 最终标准
|
||
|
||
三类对象的最终定义应为:
|
||
|
||
1. 一个可注册的对象包
|
||
2. 一个有 manifest 的对象
|
||
3. 一个只通过 contract 暴露能力的模块
|
||
4. 一个可以通过“删目录 + 删注册 + 跑卸载”安全移除的工程单元
|
||
|
||
但三类对象的最终形态不同:
|
||
|
||
1. `skill` 是能力包
|
||
2. `specialist` 是策略定义包
|
||
3. `connector` 是连接插件包
|
||
|
||
只有先承认这种边界差异,所谓“可删除封装”才不会走向两种错误:
|
||
|
||
1. 该做彻底的地方没有做彻底
|
||
2. 不该做成子系统的对象被硬做成子系统
|