11 KiB
技能文件规范
落盘日期:2026-09-16 状态:生效中 作用:定义“每个技能在前端代码中应该以什么文件形式存在” 关联文档:
AR05_工作台架构约定.md
1. 结论
从本规范生效开始:
技能不再以独立执行页面的形式存在。
每个技能必须被建模为:
定义文件 + 执行器文件 + 结果组件 + 可选扩展组件
而不是:
一个完整的 xxxPage.vue
2. 标准目录
所有技能统一存放在:
frontend/src/skills/
目录结构固定为:
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
强约束:
eai/只放 EAI 官方内置技能custom/不放每个用户技能的源码页面- 用户自定义技能的实例数据应存后端,由前端运行时归一化
- 前端 repo 里只允许保留
custom/adapters/*这类运行时适配代码
3. 技能来源必须分开
从本规范生效开始,技能必须强制区分来源:
source = 'eai'source = 'custom'
3.1 EAI 技能
定义:
- 平台内置
- 由 EAI 官方提供
- 随代码仓库交付
- 放在
src/skills/eai/
3.2 用户自定义技能
定义:
- 由租户 / 用户 / 管理员创建
- 不属于平台内置源码
- 应以数据形式存储在后端
- 由前端在运行时转换成统一
SkillDefinition
3.3 不允许混放
禁止以下做法:
- 把用户技能和 EAI 技能放在同一层目录
- 给用户技能也手工创建一个
src/skills/eai/*目录 - 把用户技能伪装成内置技能编号
- 让前端页面层自己判断“这是官方技能还是用户技能”
来源判断必须统一由 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 个身份字段:
idcodekeylabel
四者职责不同,禁止混用。
5.1 id
id 是机器标识,必须全局唯一,且不可变。
格式固定为:
- EAI 技能:
eai.<skill-key> - 用户技能:
custom.<owner-key>.<skill-key>
示例:
eai.document-translateeai.audio-transcribecustom.acme.document-translate-pro
规则:
- 全小写
- 使用
.做命名空间分隔 - 最后一段必须和
skill-key一致 - 一经创建不得修改
5.2 code
code 是展示编号,给人看,用于列表、配置页、运营页、审计页。
格式固定为:
- EAI 技能:
EAI-T-001 - 用户技能:
CUS-T-001
规则:
EAI-T-xxx只保留给官方内置技能CUS-T-xxx只保留给用户自定义技能xxx为三位流水号,从001开始- 用户技能的
code允许在“当前租户 / 当前工作区”范围内顺序编号 - 全局唯一性由
id保证,不由code保证
5.3 key
key 是前端目录名和查找键,必须使用 kebab-case。
示例:
document-translatecontract-reviewbatch-extract
规则:
- 只能包含小写字母、数字、中划线
- 不允许空格
- 不允许中文
- 必须与目录名一致
5.4 label
label 是用户可见名称,必须是中文产品名。
示例:
文档翻译合同审查批量提取
规则:
- 优先使用中文
- 不带技术实现词
- 不在名称里拼接编号
- 不在名称里拼接来源前缀
错误示例:
EAI-T-001 文档翻译custom_contract_review合同审查工具V2
6. 每个技能必须导出的定义结构
每个技能的 index.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
}
强约束:
id必须全局唯一code必须符合来源对应的编号前缀source只能是eai或customkey必须与目录名一致kind固定为'skill'settings必须是 schema 数据,不允许把设置 UI 直接写进定义文件executor必须指向当前技能自己的executor.tsresultCard必须指向当前技能自己的ResultCard.vue
7. 文件职责边界
7.1 index.ts 负责什么
只负责:
- 元数据
- schema
- 组件与执行器装配
不负责:
- 发请求
- 维护输入状态
- 渲染完整聊天界面
7.2 executor.ts 负责什么
只负责:
- 把任务上下文和设置值转换成请求
- 调用后端
- 返回标准结果对象
不负责:
- 决定页面跳转
- 直接操作 store 里的 UI 状态
- 渲染文本
7.3 ResultCard.vue 负责什么
只负责:
- 接收标准结果数据
- 渲染结果
不负责:
- 调接口
- 打开任务
- 切换工具
8. 严格禁止的文件形式
从本规范生效开始,以下文件形式禁止继续新增:
src/views/tools/*Page.vue作为工具执行页- 每个工具单独复制一份
ChatLayout - 每个工具单独复制一份
ChatInputBar - 每个工具单独维护一份本地
messages - 每个工具单独维护一份本地
taskItems - 每个工具单独维护一份右栏面板
- 每个工具用独立路由页面表达“当前正在使用”
一句话:
技能可以有自己的定义文件和局部组件,但不能再有自己的执行页面。
9. 统一注册方式
技能注册必须按来源拆分:
src/skills/registry/eai.tssrc/skills/registry/custom.tssrc/skills/registry/index.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]
}
约束:
- EAI 工具只能从
registry/eai.ts注册 - 用户工具只能从
registry/custom.ts装载 registry/index.ts只做合并,不写业务逻辑- 页面层不允许自己 import 某个工具目录
- 工作台只能通过统一 registry 查工具
- 页面层不允许自己判断来源并做分支
- 工具排序优先使用
code和显式排序字段,不允许靠文件名碰运气
10. 工作台与工具的关系
Workbench 是唯一执行面。
因此:
- 输入框属于 Workbench
- 当前对象 chip 属于 Workbench
- 设置条属于 Workbench
- 工作流 / 产物右栏属于 Workbench
- 任务列表属于 Workbench
工具只提供:
- 自己是谁
- 自己能做什么
- 自己有哪些设置
- 自己如何执行
- 自己如何渲染结果
11. 文件名规范
11.1 工具目录名
必须使用 kebab-case:
document-translateaudio-transcribebatch-extract
11.2 文件名
固定如下:
index.tsexecutor.tsResultCard.vueSettingsPanel.vue
禁止:
DocumentTranslatePage.vueAudioToolPage.vueTranslateWorkbench.vue
11.3 组件名
工具局部组件必须使用 PascalCase:
ResultCard.vueSettingsPanel.vueArtifactPreview.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.vueArtifactPreview.vue
但这些文件仍然必须放在该技能目录下,且都属于局部组件,不是页面。
14. 最终硬规范
从现在开始,前端对“技能”的唯一合法表达方式是:
EAI 技能:
src/skills/eai/<skill-key>/index.ts
用户技能:
不以源码页面形式存在,统一由后端配置记录 + src/skills/custom/adapters/* 运行时适配。
这是技能的主入口。
配套合法文件只有:
executor.tsResultCard.vueSettingsPanel.vue(可选)
除此之外,不再接受任何“每个工具一个执行页”的实现方式,也不接受把用户工具和 EAI 工具混放在同一来源目录里。