Files
pj0235-eai_agentplatform/docs/02_Architecture/AR06_技能封装规范.md
T
eaiadmin 90031b75f3 docs: 重构仓库文档目录并迁移训练素材
按当前架构重组 docs 目录,统一中文命名与目录分层,并将训练原材料迁移到独立目录以保持架构文档边界清晰。
2026-09-22 23:23:16 +08:00

553 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 技能文件规范
> 落盘日期:2026-09-16
> 状态:生效中
> 作用:定义“每个技能在前端代码中应该以什么文件形式存在”
> 关联文档:`AR05_工作台架构约定.md`
---
## 1. 结论
从本规范生效开始:
**技能不再以独立执行页面的形式存在。**
每个技能必须被建模为:
`定义文件 + 执行器文件 + 结果组件 + 可选扩展组件`
而不是:
`一个完整的 xxxPage.vue`
---
## 2. 标准目录
所有技能统一存放在:
`frontend/src/skills/`
目录结构固定为:
```text
src/skills/
registry/
eai.ts
custom.ts
index.ts
shared/
types.ts
schema.ts
runtime.ts
eai/
smart-assistant/
index.ts
executor.ts
ResultCard.vue
document-translate/
index.ts
executor.ts
ResultCard.vue
copy-proofreading/
index.ts
executor.ts
ResultCard.vue
contract-review/
index.ts
executor.ts
ResultCard.vue
audio-transcribe/
index.ts
executor.ts
ResultCard.vue
batch-extract/
index.ts
executor.ts
ResultCard.vue
custom/
adapters/
normalize.ts
executorFactory.ts
```
强约束:
1. `eai/` 只放 EAI 官方内置技能
2. `custom/` 不放每个用户技能的源码页面
3. 用户自定义技能的实例数据应存后端,由前端运行时归一化
4. 前端 repo 里只允许保留 `custom/adapters/*` 这类运行时适配代码
---
## 3. 技能来源必须分开
从本规范生效开始,技能必须强制区分来源:
- `source = 'eai'`
- `source = 'custom'`
### 3.1 EAI 技能
定义:
- 平台内置
- 由 EAI 官方提供
- 随代码仓库交付
- 放在 `src/skills/eai/`
### 3.2 用户自定义技能
定义:
- 由租户 / 用户 / 管理员创建
- 不属于平台内置源码
- 应以数据形式存储在后端
- 由前端在运行时转换成统一 `SkillDefinition`
### 3.3 不允许混放
禁止以下做法:
1. 把用户技能和 EAI 技能放在同一层目录
2. 给用户技能也手工创建一个 `src/skills/eai/*` 目录
3. 把用户技能伪装成内置技能编号
4. 让前端页面层自己判断“这是官方技能还是用户技能”
来源判断必须统一由 registry 和 definition 字段承担。
---
## 4. 每个工具允许的文件
每个 EAI 工具目录下只允许这 4 类文件:
### 4.1 `index.ts`
这是工具主定义文件,必须存在。
作用:
- 定义工具身份
- 定义显示名称
- 定义设置 schema
- 定义开场提示
- 绑定执行器
- 绑定结果渲染组件
### 4.2 `executor.ts`
这是工具执行器,必须存在。
作用:
- 组装请求参数
- 调用后端接口
- 归一化响应结果
约束:
- 不允许依赖页面组件
- 不允许写 DOM 逻辑
- 不允许直接操作路由
### 4.3 `ResultCard.vue`
这是工具结果渲染组件,必须存在。
作用:
- 渲染该工具的结果卡片
- 展示结构化结果
- 展示摘要、状态、附加信息
约束:
- 这是局部结果组件,不是页面
- 不允许包含整个聊天布局
- 不允许自己持有输入框
### 4.4 `SettingsPanel.vue`
这是可选文件,只在 schema 驱动不够时允许出现。
作用:
- 处理复杂设置 UI
约束:
- 默认不创建
- 只有通用 schema 无法表达时才允许新增
---
## 5. 编号与命名规范
每个工具必须同时拥有以下 4 个身份字段:
1. `id`
2. `code`
3. `key`
4. `label`
四者职责不同,禁止混用。
### 5.1 `id`
`id` 是机器标识,必须全局唯一,且不可变。
格式固定为:
- EAI 技能:`eai.<skill-key>`
- 用户技能:`custom.<owner-key>.<skill-key>`
示例:
- `eai.document-translate`
- `eai.audio-transcribe`
- `custom.acme.document-translate-pro`
规则:
1. 全小写
2. 使用 `.` 做命名空间分隔
3. 最后一段必须和 `skill-key` 一致
4. 一经创建不得修改
### 5.2 `code`
`code` 是展示编号,给人看,用于列表、配置页、运营页、审计页。
格式固定为:
- EAI 技能:`EAI-T-001`
- 用户技能:`CUS-T-001`
规则:
1. `EAI-T-xxx` 只保留给官方内置技能
2. `CUS-T-xxx` 只保留给用户自定义技能
3. `xxx` 为三位流水号,从 `001` 开始
4. 用户技能的 `code` 允许在“当前租户 / 当前工作区”范围内顺序编号
5. 全局唯一性由 `id` 保证,不由 `code` 保证
### 5.3 `key`
`key` 是前端目录名和查找键,必须使用 kebab-case。
示例:
- `document-translate`
- `contract-review`
- `batch-extract`
规则:
1. 只能包含小写字母、数字、中划线
2. 不允许空格
3. 不允许中文
4. 必须与目录名一致
### 5.4 `label`
`label` 是用户可见名称,必须是中文产品名。
示例:
- `文档翻译`
- `合同审查`
- `批量提取`
规则:
1. 优先使用中文
2. 不带技术实现词
3. 不在名称里拼接编号
4. 不在名称里拼接来源前缀
错误示例:
- `EAI-T-001 文档翻译`
- `custom_contract_review`
- `合同审查工具V2`
---
## 6. 每个技能必须导出的定义结构
每个技能的 `index.ts` 必须默认导出一个标准对象。
字段固定如下:
```ts
export interface SkillDefinition {
id: string
code: string
source: 'eai' | 'custom'
key: string
label: string
kind: 'skill'
icon: string
description: string
settings: SkillSettingSchema[]
starterPrompts: string[]
executor: SkillExecutor
resultCard: Component
}
```
强约束:
1. `id` 必须全局唯一
2. `code` 必须符合来源对应的编号前缀
3. `source` 只能是 `eai` 或 `custom`
4. `key` 必须与目录名一致
5. `kind` 固定为 `'skill'`
6. `settings` 必须是 schema 数据,不允许把设置 UI 直接写进定义文件
7. `executor` 必须指向当前技能自己的 `executor.ts`
8. `resultCard` 必须指向当前技能自己的 `ResultCard.vue`
---
## 7. 文件职责边界
### 7.1 `index.ts` 负责什么
只负责:
- 元数据
- schema
- 组件与执行器装配
不负责:
- 发请求
- 维护输入状态
- 渲染完整聊天界面
### 7.2 `executor.ts` 负责什么
只负责:
- 把任务上下文和设置值转换成请求
- 调用后端
- 返回标准结果对象
不负责:
- 决定页面跳转
- 直接操作 store 里的 UI 状态
- 渲染文本
### 7.3 `ResultCard.vue` 负责什么
只负责:
- 接收标准结果数据
- 渲染结果
不负责:
- 调接口
- 打开任务
- 切换工具
---
## 8. 严格禁止的文件形式
从本规范生效开始,以下文件形式禁止继续新增:
1. `src/views/tools/*Page.vue` 作为工具执行页
2. 每个工具单独复制一份 `ChatLayout`
3. 每个工具单独复制一份 `ChatInputBar`
4. 每个工具单独维护一份本地 `messages`
5. 每个工具单独维护一份本地 `taskItems`
6. 每个工具单独维护一份右栏面板
7. 每个工具用独立路由页面表达“当前正在使用”
一句话:
**技能可以有自己的定义文件和局部组件,但不能再有自己的执行页面。**
---
## 9. 统一注册方式
技能注册必须按来源拆分:
- `src/skills/registry/eai.ts`
- `src/skills/registry/custom.ts`
- `src/skills/registry/index.ts`
注册形式固定为:
```ts
// registry/eai.ts
import smartAssistant from '../eai/smart-assistant'
import documentTranslate from '../eai/document-translate'
export const eaiSkillRegistry = [
smartAssistant,
documentTranslate,
]
// registry/custom.ts
export async function loadCustomSkillRegistry() {
return fetchCustomSkillsFromBackend()
}
// registry/index.ts
export async function loadSkillRegistry() {
const customSkills = await loadCustomSkillRegistry()
return [...eaiSkillRegistry, ...customSkills]
}
```
约束:
1. EAI 工具只能从 `registry/eai.ts` 注册
2. 用户工具只能从 `registry/custom.ts` 装载
3. `registry/index.ts` 只做合并,不写业务逻辑
4. 页面层不允许自己 import 某个工具目录
5. 工作台只能通过统一 registry 查工具
6. 页面层不允许自己判断来源并做分支
7. 工具排序优先使用 `code` 和显式排序字段,不允许靠文件名碰运气
---
## 10. 工作台与工具的关系
Workbench 是唯一执行面。
因此:
- 输入框属于 Workbench
- 当前对象 chip 属于 Workbench
- 设置条属于 Workbench
- 工作流 / 产物右栏属于 Workbench
- 任务列表属于 Workbench
工具只提供:
- 自己是谁
- 自己能做什么
- 自己有哪些设置
- 自己如何执行
- 自己如何渲染结果
---
## 11. 文件名规范
### 11.1 工具目录名
必须使用 kebab-case:
- `document-translate`
- `audio-transcribe`
- `batch-extract`
### 11.2 文件名
固定如下:
- `index.ts`
- `executor.ts`
- `ResultCard.vue`
- `SettingsPanel.vue`
禁止:
- `DocumentTranslatePage.vue`
- `AudioToolPage.vue`
- `TranslateWorkbench.vue`
### 11.3 组件名
工具局部组件必须使用 PascalCase:
- `ResultCard.vue`
- `SettingsPanel.vue`
- `ArtifactPreview.vue`
### 11.4 目录与 key 的关系
工具目录名必须与 `key` 一致:
- 目录:`document-translate`
- key:`document-translate`
不允许目录名和 key 各写各的。
---
## 12. 迁移结果
`src/views/tools/*.vue` 旧执行页已经完成退出,当前状态如下:
### 已完成
- 旧技能执行路由已删除
- `src/views/tools/*.vue` 中的执行页源码已删除
- 技能配置与执行逻辑已开始收敛到 `src/skills/*`
- `/home` 已成为唯一工作台执行入口
### 仍需继续推进
虽然旧页面已经删除,但下面几类资产还要继续补齐:
- 更完整的 `executor` 接线
- 更统一的 `ResultCard` / `SettingsPanel` 规范
- 用户自定义技能的后端配置接入
- 对象实例化后的运行记录与产物呈现
---
## 13. 特殊情况处理
### 13.1 设置特别复杂的技能
如果某个技能的设置无法由通用 schema 表达,允许新增:
- `SettingsPanel.vue`
但仍然禁止:
- 为此恢复一个完整技能页
### 13.2 结果展示特别复杂的技能
如果 `ResultCard.vue` 不够,可以继续拆分局部组件,例如:
- `ResultSummary.vue`
- `ArtifactPreview.vue`
但这些文件仍然必须放在该技能目录下,且都属于局部组件,不是页面。
---
## 14. 最终硬规范
从现在开始,前端对“技能”的唯一合法表达方式是:
EAI 技能:
`src/skills/eai/<skill-key>/index.ts`
用户技能:
不以源码页面形式存在,统一由后端配置记录 + `src/skills/custom/adapters/*` 运行时适配。
这是技能的主入口。
配套合法文件只有:
- `executor.ts`
- `ResultCard.vue`
- `SettingsPanel.vue`(可选)
除此之外,不再接受任何“每个工具一个执行页”的实现方式,也不接受把用户工具和 EAI 工具混放在同一来源目录里。