docs: 工作台设计稿收入 docs 体系,routes.go 更名 ai_routes.go

7 份散落在 frontend/src/views/workbench/ 的设计稿按现有编号体系收入 docs/,
源码目录现在只剩 12 个 .vue 页面:

  PlatformArchitectureRethink       -> docs/01_System_Overall/SY24
  WorkbenchArchitectureContract     -> docs/02_Architecture/AR05
  SkillPackagingSpecification       -> docs/02_Architecture/AR06
  ArchitectureAlignmentAudit        -> docs/02_Architecture/AR07
  RoleInteractionDesign             -> docs/02_Architecture/AR08
  YunQuParityRoadmap_OfficePlatform -> docs/06_Product_Lines/PL04
  WorkBuddySkillRpaLearning         -> docs/09_Research/RS01

14 处交叉引用同步更新(含 SY20/SY21 里指向旧源码路径的两处);三份 README 索引
补齐 SY20-SY24 与 AR05-AR08、PL04;README 顶部「本目录全是历史快照」的说法改精确
(AR05-AR08、PL04 不属于 V1.1 / V1 快照)。

AR08 文首补注「采纳与废弃」,避免它被当成现行设计照做:
- 已采纳:对象不跳页 / 不做独立工具页 / + 菜单挂载 / 切换对象=更新任务上下文
- 已废弃:「数字技术员」第三类对象(SY21 §2.2 已废除 tool 命名)、
  「通用助手 = 默认专员」、§14「与本稿冲突以本稿为准」的自我授权

backend-go: internal/api/routes.go -> ai_routes.go。该文件管的是 AI 模型路由
(LLM provider 列表),与 router.go 的 URL 路由注册同包同名易混,加文件头注释钉死。

验证:go build ./... 通过;go vet ./internal/api/ 无告警;npm run build 通过。

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
eaiadmin
2026-09-17 19:26:26 +08:00
co-authored by Claude Code
parent 24cac4de6e
commit fa6c26ea41
16 changed files with 5735 additions and 55 deletions
@@ -0,0 +1,482 @@
# 数字员工 Workbench 架构合同
> 落盘日期:2026-09-16
> 状态:架构合同
> 作用:作为后续前端重构的强约束,先定模型,再做代码迁移
> 关联文档:`AR08_Role_Interaction_Design.md`
---
## 1. 目标
系统后续只保留一个大的工作台。
这个工作台必须同时满足 4 件事:
1. 用户始终在同一个主工作面里完成任务
2. 专员和工具都不是“去一个页面”,而是“挂到当前任务里的对象”
3. 对象可以被启动、配置、切换焦点、关闭
4. 所有执行上下文都以任务为中心,而不是以路由为中心
一句话定义:
`一个 Workbench + 一条任务上下文 + 多个可挂载对象`
---
## 2. 强结论
### 2.1 保留一个唯一执行工作面
前端只允许一个执行型主工作面:
- 建议沿用 `/home` 作为 canonical page_route
- `/` 直接进入 `/home`
这个页面承载:
- 消息流
- 当前对象 chip
- 设置条
- 工作流 / 产物右栏
- 附件入口
- `+` 菜单
### 2.2 `apps/*` 不再作为使用入口
`/apps/*` 可以去掉“执行页”角色。
以后它只能有两种命运:
1. 被删除
2. 退化成兼容跳转,统一跳回 `/home`
它不能继续承担:
- 打开专员工作台
- 在专员页里执行任务
- 与主工作面并行存在
### 2.3 `tools/*` 不再作为使用入口
`/tools/*` 也可以去掉“执行页”角色。
以后工具不再被建模为一组独立页面,而是:
- 当前任务里被启动的技术员对象
- 由统一工作面承载执行
`/tools/*` 在迁移期只允许做兼容跳转,不允许继续扩散业务逻辑。
---
## 3. 对象模型
### 3.1 三类对象
| 对象 | 本质 | 角色 |
|------|------|------|
| 通用助手 | 默认专员 | 没有显式指定对象时的兜底编排者 |
| 数字专员 | 编排型对象 | 负责拆任务、排步骤、调用工具、汇总结果 |
| 数字技术员 | 执行型对象 | 负责单点能力执行,例如翻译、提取、转写 |
### 3.2 工具的真正定义
“工具”只是数字技术员的展示别名,不再是页面类型。
所以未来语义应该是:
- 文档翻译工具 -> 文档翻译技术员
- 文案校对工具 -> 文案校对技术员
- 批量提取工具 -> 批量提取技术员
如果某个对象既有“专员态”又有“工具态”,必须拆成两个不同 key,禁止复用同一个 key。
例如这类冲突必须消除:
- `contract-review` 不能同时代表专员和工具
- `report-generation` 不能同时代表专员和工具
---
## 4. 状态模型
## 4.1 核心原则
所有运行时状态必须挂在“当前任务”下面。
禁止再出现:
- 专员状态靠任务 store
- 工具状态靠路由
- 右栏状态靠页面推断
这三套并行模型。
### 4.2 迁移期必须新增的状态
第一阶段必须补上:
```ts
type TaskRuntimeContextV1 = {
currentTaskId: string
currentSpecialistKey: string
currentSkillKey: string
}
```
其中:
- `currentSpecialistKey` 表示当前任务挂载的主编排对象
- `currentSkillKey` 表示当前输入区和设置条默认服务的技能对象
`currentSkillKey` 的意义是把技能正式纳入任务上下文,结束“技能只存在于路由页”的旧模型。
### 4.3 最终推荐状态模型
在迁移完成后,建议升级为:
```ts
type TaskRuntimeContext = {
currentTaskId: string
currentSpecialistKey: string
openedSkillKeys: string[]
focusedObjectKind: 'assistant' | 'specialist' | 'skill'
focusedObjectKey: string
mode: 'quick' | 'expert'
}
```
解释:
- `currentTaskId`:当前任务
- `currentSpecialistKey`:这条任务当前的主编排者
- `openedSkillKeys`:这条任务里已启动但未关闭的技能
- `focusedObjectKind` / `focusedObjectKey`:当前输入框、设置条、右栏正在服务哪个对象
- `mode`:当前工作模式
### 4.4 状态约束
必须满足以下约束:
1. 没有任务时,允许预选对象,但只能作为 pending 状态
2. 一旦第一条消息发出,pending 状态必须落入任务上下文
3. `focusedObjectKey` 必须属于:
- `currentSpecialistKey`
- `openedSkillKeys`
- 或默认助手
4. 关闭对象后,焦点必须自动切回:
- 同任务下的其他已打开对象
- 没有则回到当前专员
- 再没有则回到通用助手
---
## 5. 路由收敛原则
### 5.1 执行路由
执行型路由只保留:
- `/home`
### 5.2 目录与配置路由
允许保留的非执行路由只有两类:
1. 目录路由
例如:
- `/catalog/specialists`
- `/catalog/skills`
- `/catalog/connectors`
2. 配置 / 管理路由
例如:
- `/studio`
- `/console`
- 后台管理页
### 5.3 兼容跳转规则
在迁移阶段:
- `/apps/*` -> 跳回 `/home`
- `/tools/*` -> 跳回 `/home`
跳转时要把对象意图带回工作台,例如:
- 原 `/tools/document-translate`
-> `/home` 并恢复 `currentSkillKey=document-translate`
- 原 `/apps/contract-review`
-> `/home` 并恢复 `currentSpecialistKey=contract-review-specialist`
兼容跳转只做迁移兜底,不允许再承载新逻辑。
---
## 6. 工作台交互合同
### 6.1 输入区
输入区固定结构:
`[+] [当前对象 chip] [附件] [输入框] [发送]`
规则:
1. `+` 是唯一启动入口
2. `当前对象 chip` 是唯一上下文可视入口
3. 输入区永远不因为对象类型不同而变成另一套布局
### 6.2 `+` 菜单
`+` 菜单只负责 4 类动作:
1. 切模式
2. 启动 / 切换专员
3. 启动工具
4. 打开连接器相关能力
`+` 菜单不负责跳执行页。
### 6.3 当前对象 chip
规则:
1. 固定显示在 `+` 右边
2. 始终展示当前焦点对象
3. 专员、工具结构统一,只是样式和文案不同
4. 点击 chip 只允许:
- 展开详情
- 切焦点
- 打开配置抽屉
不允许点击后跳到另一套执行页面。
### 6.4 设置条
设置条是“当前焦点对象”的设置条,不是“当前路由页”的设置条。
规则:
1. 只服务 `focusedObjectKey`
2. 改动从下一条消息开始生效
3. 不允许继续根据 `/tools/*` 路由推断工具身份
### 6.5 右栏
右栏固定两个 tab:
- 工作流
- 产物
规则:
1. 右栏服务当前焦点对象
2. 专员焦点时,展示专员级工作流与产物
3. 工具焦点时,展示工具级执行流与产物
4. 右栏不允许只支持专员、不支持工具
---
## 7. 对象生命周期
每个专员 / 工具都必须服从统一生命周期:
### 7.1 启动
启动来源:
- `+` 菜单
- 目录页中的“启动”动作
- 兼容跳转恢复
启动结果:
- 对象进入当前任务上下文
- 成为可聚焦对象
- 在输入区显示为当前对象或可切换对象
### 7.2 配置
配置行为包括:
- 修改模式
- 修改对象设置
- 打开对象详情
- 调整对象参数
配置结果必须记录在任务上下文,而不是记录在页面局部状态。
### 7.3 关闭
关闭对象后:
- 从当前任务的已打开对象列表中移除
- 关闭该对象设置条
- 焦点自动切回其他对象
关闭不是“离开页面”,而是“从当前任务上下文卸载对象”。
### 7.4 重新打开
如果任务里已经存在一个对象,再次点击它时:
- 默认切焦点
- 不再重复创建
---
## 8. 页面职责收敛
### 8.1 `BusinessAppPage` 的状态
`BusinessAppPage` 已从前端仓库移除。
这说明以下约束已经落地:
- 不再承担聊天执行
- 不再承担任务推进主入口
- 不再与 `/home` 形成并行的第二工作台
### 8.2 各 `ToolPage` 的状态
`DocumentTranslatePage`、`CopyProofreadingPage`、`AudioTranscribePage` 等旧工具执行页已从前端仓库移除。
它们留下来的有效资产只剩两类:
1. 已抽离出的 schema / runtime / 组件
2. 历史设计文档中的迁移记录
它们已经不再作为产品形态存在。
---
## 9. 数据层约束
### 9.1 任务是唯一事实来源
以下运行时状态必须最终可从任务恢复:
- 当前专员
- 当前工具
- 已打开工具列表
- 当前焦点对象
- 对象设置快照
- 关键工作流状态
- 产物列表
### 9.2 禁止继续混用演示数据与真实数据
以下情况必须逐步清理:
- 页面本地写死 `messages`
- 页面本地写死 `taskItems`
- 工作台 snapshot 与 live data 混合渲染但界面上不区分
迁移后应满足:
1. 真数据就渲真数据
2. 演示态必须明确标注为模板 / 示例 / 空态
3. 不允许让示例数据冒充真实任务结果
---
## 10. 迁移顺序
### Phase 0:合同冻结
先冻结这份合同,后续改造按它执行。
### Phase 1:补全任务上下文
目标:
- 增加 `currentSkillKey`
- 让技能脱离路由身份,先进入任务 store
结果:
- 选技能不再只是跳页
- 工作台第一次具备“任务 + 专员 + 技能”的统一上下文
### Phase 2:统一当前对象
目标:
- `CurrentObjectChip` 改为真正读任务上下文
- 设置条改为读 `focusedObjectKey`
- 右栏从“专员面板”演进为“对象面板”
结果:
- 输入区、设置条、右栏三者对齐
### Phase 3:路由收敛
目标:
- `/apps/*` 全部改兼容跳转
- `/tools/*` 全部改兼容跳转
结果:
- `/home` 成为唯一执行工作面
### Phase 4:删除重复执行页
目标:
- 删除各类工具执行页中的消息流、输入框、任务逻辑
- 删除各类专员执行页中的聊天职责
结果:
- 页面树明显收缩
- 状态源头回归统一
### Phase 5:命名与对象清洗
目标:
- 拆分专员 key 与工具 key 冲突
- 清理旧命名
- 清理遗留兼容逻辑
结果:
- 模型稳定
- 后续功能可持续扩展
---
## 11. 禁止事项
从这份合同生效开始,以下做法视为逆行:
1. 再新增任何 `/tools/*` 执行页
2. 再新增任何 `/apps/*` 执行页
3. 在页面局部状态里偷偷维护“当前工具”
4. 继续复用同一个 key 同时代表专员和工具
5. 让当前对象由页面 `prefer` 或路由猜测,而不是由任务上下文决定
6. 让右栏只支持专员,不支持工具
---
## 12. 最终产品语义
最终用户感知必须收敛为:
- 我在一个工作台里
- 我当前正在处理一条任务
- 这条任务挂了某个专员
- 这条任务打开了若干工具
- 我现在聚焦在某个对象上
- 我可以启动、配置、关闭这些对象
- 我不需要理解页面切换,只需要理解任务上下文
如果界面上任何一个交互让用户重新产生:
`我是不是又跳进了另一个工具页 / 专员页`
那就说明这次改造没有做完。
@@ -0,0 +1,552 @@
# 技能文件规范
> 落盘日期:2026-09-16
> 状态:生效中
> 作用:定义“每个技能在前端代码中应该以什么文件形式存在”
> 关联文档:`AR05_Workbench_Architecture_Contract.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 工具混放在同一来源目录里。
@@ -0,0 +1,97 @@
# 架构对齐确认与本轮修复范围
> 落盘日期:2026-09-16
> 状态:本轮生效
> 关联文档:
> - `AR05_Workbench_Architecture_Contract.md`
> - `../01_System_Overall/SY24_Platform_Architecture_Rethink.md`
> - `AR06_Skill_Packaging_Specification.md`
---
## 1. 本轮确认结论
当前前端已经出现两套并行模型:
1. `workerRuntime` 开始把 `currentSpecialistKey / currentSkillKey` 收进任务上下文
2. 路由和多个入口仍在继续使用 `/apps/*`、`/tools/*` 当执行页
这两套模型继续并存,会持续制造以下问题:
- 同一个对象,既像“挂在任务上的对象”,又像“跳去一个页面”
- 输入区已经开始对象化,但对象 chip 和首页卡片还在按旧路由跳转
- 兼容路径不只是兼容,而是在继续承载真实业务
所以本轮先不扩技能复刻,先回到我们自己的架构,确认并修复这一层。
---
## 2. 已确认的主要偏差
### 2.1 执行入口没有收敛到 `/home`
当前代码中仍存在:
- `/apps/:key` 专员执行页
- `/tools/:key` 工具执行页
- `/report-gen` 这类独立工具页
这与“只保留一个 Workbench 执行面”的架构合同冲突。
### 2.2 启动对象的入口行为不一致
当前不同入口对“打开专员 / 工具”的处理不一致:
- `+` 菜单一部分已经开始写任务上下文
- 首页卡片仍直接 `router.push(app.pageRoute)` 或使用业务对象旧入口字段
- 市场页“打开工作区”仍直接进入旧路由
- 当前对象 chip 仍会把工具跳到旧工具页
这会导致用户在不同入口触发同一对象时,落点完全不同。
### 2.3 旧执行路由仍残留在产品结构里
根据架构合同,`/apps/*`、`/tools/*` 应该退出执行结构。
此前前端中它们曾直接挂载为执行页:
- `BusinessAppPage.vue`
- `DocumentTranslatePage.vue`
- `CopyProofreadingPage.vue`
- `ContractReviewPage.vue`
- `AudioTranscribePage.vue`
- `BatchExtractPage.vue`
以上旧执行页现已全部从前端仓库移除。
这会继续放大旧页面模型。
---
## 3. 本轮修复范围
本轮只修第一优先级:
1. 所有“打开专员 / 工具”的行为,统一回到 `/home`
2. `/apps/*`、`/tools/*`、`/report-gen` 从路由中直接移除
3. 所有对象启动动作只认新的工作台入口和任务上下文
---
## 4. 本轮暂不处理
以下问题已确认存在,但不在本轮一起动:
1. 后端 `task -> specialist_key` 仍未升级为更完整的 mounted objects 结构
2. 后端专员数据结构命名已升级为 `object_entry_route`,并与普通页面导航 `page_route` 分离;旧 `route / entry_route` 已收缩为启动阶段的一次性数据库迁移逻辑,不再驻留在日常模型与接口中
---
## 5. 本轮达成标准
修完后,系统应满足:
1. 用户从 `+` 菜单、首页、市场页进入时,都会回到同一个 `/home`
2. 当前专员 / 当前工具由任务上下文决定,而不是由页面路由决定
3. `/apps/*`、`/tools/*`、`/report-gen` 不再作为前端执行入口存在
4. 旧执行页源码文件已经从前端仓库移除
@@ -0,0 +1,509 @@
# AI 角色与工具统一交互设计
> 落盘日期:2026-09-16
> 状态:**部分被取代的设计稿 —— 阅读前先看下面的「采纳与废弃」**
> ## ⚠️ 采纳与废弃(2026-09-17 补注)
>
> 本文结论不是「整体作废」,而是**一半采纳、一半废弃**。请按下表取用,**不要整篇照做**。
>
> ### 已采纳(现已是实现方向)
>
> | 本文结论 | 现落点 |
> |----------|--------|
> | 对象不跳页,都在同一工作面里挂载 | `AR05_Workbench_Architecture_Contract.md` |
> | 专员 / 工具不应该是独立 Vue 页面 | 已实现:`views/workbench/` 无独立工具页 |
> | `+` 菜单作为统一的对象选择入口 | 已实现:`components/chat/PlusMenu.vue` |
> | 切换对象 = 更新任务上下文,不跳路由 | 已实现:`store/workerRuntime.js` |
>
> ### 已废弃(不要照做)
>
> | 本文结论 | 废弃原因 |
> |----------|----------|
> | 「**数字技术员**」作为第三类对象,与专员 / 工具并列(§2.1、§5.2) | `SY21` §2.2 已明确**不再把 `tool` 作为正式命名**,对内统一 `expert / skill / app`,对外统一「专家 + 技能」。**没有「技术员」这一类。** |
> | 「通用助手 = 默认专员」这一等式(§5.4) | `SY23` 确认通用助手是**未挂专员时的兜底**,不是一种专员 |
> | §14「后续如有实现与本稿冲突,**以本稿为准**」 | 该自我授权已失效。当前收口文档是 `SY21` / `SY22`,专员改造以 `SY23_Specialist_Rule_File_And_Skill_Binding_Plan.md` 为准 |
>
> 一句话:**「不跳页面」这个判断是对的、也已落地;「数字技术员」这个对象是新造的、已被否定。**
---
## 1. 结论先行
当前前端的核心问题,不是某几个页面细节做得不够像 WorkBuddy,而是**建模错了**:
- **数字专员**不应该是独立业务页面
- **工具**也不应该是一组独立 Vue 页面
- **对话主界面**才应该是唯一主工作面
新的统一模型应是:
- **通用助手** = 默认专员
- **数字专员** = 多步任务编排者,类似企业里的项目经理
- **数字技术员** = 单点技术能力执行者,可被专员调用
- **工具** = 数字技术员的一种表现形式,不再等于页面
也就是说:
**前端不再是“切页面使用能力”,而是“在同一个对话工作面里切换当前挂载对象”。**
---
## 2. 统一对象模型
### 2.1 三类对象
| 类别 | 本质 | 典型职责 | 是否有独立完整页面 |
|------|------|----------|--------------------|
| 通用助手 | 默认专员 | 通用问答、兜底处理、把任务转交给更合适对象 | 否 |
| 数字专员 | 编排型角色 | 拆任务、排步骤、调用技术员、汇总产物 | 否 |
| 数字技术员 | 执行型角色 | 文档翻译、语音转写、批量提取、合同条款分析等单点能力 | 否 |
### 2.2 用户感知
对用户来说,不再是:
`我正在某个工具页里`
而是:
`我正在一条任务里,这条任务当前挂了哪个专员 / 哪个技术员`
### 2.3 当前对象的展示规则
无论选中的是专员还是技术员,都应该出现在输入框左下区域:
`[+] [当前对象 chip]`
其中:
- 选了专员,显示专员 chip
- 选了工具,显示工具 chip
- 两者都没有时,默认显示“通用助手”
- 输入区显性对象始终互斥:`+` 右边一次只显示一个当前对象
- 专员内部调用技术员属于执行链,不升格为第二个显性 chip
这一点非常关键,因为它把“当前上下文”从隐藏状态变成了**持续可见状态**。
---
## 3. 为什么原来的工具页架构是错的
### 3.1 错误的建模方式
原来的建模是:
`一个工具 = 一个完整页面`
例如以前会把工具理解成这些独立页:
- `/tools/document-translate`
- `/tools/copy-proofreading`
- `/tools/audio-transcribe`
- `/tools/batch-extract`
当前这些独立执行页已经退出,工具统一通过 `/home` 工作台挂载。
这会导致前端天然把“工具”理解成“去一个地方”。
### 3.2 实际上工具不需要页面承载
工具真正有差异的地方只有 3 块:
1. **输入要求**
2. **设置条**
3. **右栏中的工作流与产物**
除此之外,绝大多数前端骨架都是一样的:
- 还是同一个聊天区
- 还是同一个输入框
- 还是同一个附件入口
- 还是同一个右栏容器
所以把每个工具做成完整页面,会产生大量无意义分叉:
- 路由分叉
- 状态分叉
- 组件分叉
- 页面骨架重复
### 3.3 正确的建模方式
应该改成:
`一个工具 = 一份能力定义 + 一份设置定义 + 一份工作流定义`
而不是:
`一个工具 = 一个完整页面`
---
## 4. 新的前端总架构
### 4.1 唯一主工作面
系统只保留一个主交互工作面:
`Chat Workspace`
结构如下:
```text
┌────────────────────────────────────────────────────────────┐
│ 左侧导航 │
├────────────────────────────────────────────────────────────┤
│ 中间:对话主画面 │ 右侧:上下文面板 │
│ │ │
│ 消息流 │ [工作流] [产物] │
│ │ │
│ │ 当前对象的执行进度 │
│ │ 当前对象的产物列表 │
├────────────────────────────────────────────────────────────┤
│ [+] [当前对象 chip] [附件] [输入框................] [发送] │
└────────────────────────────────────────────────────────────┘
```
### 4.2 对象切换方式
所有对象的选择,都从 `+` 打开:
- 模式:快速 / 专家
- 专员
- 技术员
- 连接器或其它补充入口
选择结果不再跳页面,而是**更新当前任务上下文**。
### 4.3 页面跳转原则
默认原则:
- **切换对象,不跳页**
- **切换能力,不跳页**
- **切换任务,才可能切上下文**
只有管理、配置、市场、控制台这类后台页面,才保留独立路由。
---
## 5. 专员与技术员的职责分层
### 5.1 数字专员
数字专员对应企业中的项目经理,负责:
- 接收用户目标
- 把目标拆成多步任务
- 决定调用哪些技术员
- 汇总技术员的结果
- 输出最终交付物
### 5.2 数字技术员
数字技术员对应企业中的专业执行者,负责:
- 完成单个技术动作
- 处理特定格式输入
- 产出特定类型结果
- 把结果返回给专员或直接返回给用户
### 5.3 调用关系
```text
用户
→ 数字专员
→ 调用数字技术员 A
→ 调用数字技术员 B
→ 调用数字技术员 C
→ 汇总结果
→ 输出最终产物
```
### 5.4 通用助手的定位
通用助手不是单独体系,而是:
- 默认专员
- 未选择任何专员或技术员时的兜底对象
- 帮用户判断应不应该切到某个专员或技术员
---
## 6. 工具的新定义
### 6.1 工具不再是页面
未来的“工具”只是技术员目录里的一个对象类别。
例如:
| 旧叫法 | 新理解 |
|--------|--------|
| 文档翻译工具 | 文档翻译技术员 |
| 文案校对工具 | 文案校对技术员 |
| 语音转写工具 | 语音转写技术员 |
| 批量提取工具 | 批量提取技术员 |
| 合同审查工具 | 合同条款分析技术员或合同审查专员的下游技术员 |
| 报告生成工具 | 报告生成技术员 |
### 6.2 工具在前端的可变部分
一个技术员/工具在前端只允许有 4 类差异:
1. **对象 chip**
2. **输入提示与输入校验**
3. **设置条**
4. **右栏工作流与产物**
除此之外,不再允许复制一整页聊天页。
### 6.3 工具定义应沉淀为 schema
每个技术员建议定义如下结构:
```ts
type TechnicianDefinition = {
key: string
label: string
summary: string
inputSchema: object
settingsSchema: object[]
workflowSchema: object[]
artifactSchema: object[]
emptyState?: {
title: string
description: string
presets?: string[]
}
}
```
也就是说,新增长一个工具,不应该先想“新建哪个 Vue 文件”,而应该先想“补哪份定义”。
---
## 7. 统一 UI 规则
### 7.1 输入区
输入区固定包含:
- `+`:选择模式 / 专员 / 技术员
- `当前对象 chip`
- `附件`
- `输入框`
- `发送`
### 7.2 当前对象 chip
当前对象 chip 的规则:
- 位置固定在 `+` 右边
- 支持专员与技术员两种样式,但结构统一
- 只负责展示“当前挂了谁”
- 一次只展示一个当前对象,不并排显示“专员 + 技术员”
- 点击 chip 可展开对象详情,或跳到对应配置页
### 7.3 设置条
设置条是工具差异的第一承载位。
原则:
- 只在当前对象有设置时显示
- 位置在消息列表顶部
- 形式统一为一条 sticky 条
- 设置变更默认从**下一条消息**开始生效
- 当前对象是专员时,默认不再额外显示技能设置条
设置条里的内容由对象定义驱动,而不是写死在某个页面里。
### 7.4 右栏
右栏固定 2 个 tab:
- **工作流**
- **产物**
#### 工作流 tab
显示当前对象的:
- 执行步骤
- 进度状态
- 当前节点
- 子任务或检查点
#### 产物 tab
显示当前对象的:
- 文件产物
- 结构化结果
- 中间输出
- 状态标签
### 7.5 空态
空态不再按“工具页”设计,而按“当前对象”设计:
- 默认通用助手有自己的门厅
- 技术员被选中但还没发送第一条消息时,显示该技术员自己的空态说明
- 专员被选中但还没发送第一条消息时,显示该专员的工作流模板预览
---
## 8. 导航的重新定位
### 8.1 一级导航不再承担“使用工具”的职责
一级导航中的:
`专员 / 工具 / 连接器`
应该只承担**浏览配置与管理入口**的职责,而不是使用入口。
### 8.2 使用入口只有一个
真正的使用入口应该只有:
- `新建任务`
- `打开已有任务`
进入任务后,一切对象切换都在对话区完成。
### 8.3 目录页的意义
目录页只做这些事:
- 浏览有哪些专员
- 浏览有哪些技术员
- 浏览有哪些连接器
- 查看其配置摘要
- 进入配置详情
而不是“点卡片后进入某个独立工具页”。
---
## 9. 现有代码应如何收敛
### 9.1 应保留的骨架
这些方向是对的,应保留:
- `ChatLayout`
- `ChatInputBar`
- `PlusMenu`
- `SkillStrip`
- 右栏 `SpecialistPanel` 的工作流 / 产物思路
- “新建任务”作为唯一对话起点
### 9.2 应逐步废弃的结构
这些应视为过渡结构:
- 每个工具一张独立完整 Vue 页
- 每个专员一个独立业务工作台页
- 通过 object entry 切工具
- 通过 object entry 切专员执行面
### 9.3 收敛目标
最终应收成:
| 层级 | 目标 |
|------|------|
| 页面层 | 一个主对话工作面 + 少量管理页 |
| 组件层 | 一套通用聊天骨架 + 一套右栏骨架 |
| 配置层 | 专员定义 / 技术员定义 / 工作流定义 / 设置定义 |
| 数据层 | 当前任务挂载哪个对象,由任务状态驱动 |
---
## 10. 重构原则清单
1. **页面不是能力,页面只是容器。**
2. **能力切换不应导致页面跳转。**
3. **当前上下文必须持续可见。**
4. **专员与技术员共享同一套交互语言。**
5. **工具差异只放在设置条、输入要求、工作流、产物。**
6. **新增能力优先补 schema,不优先建新页面。**
7. **导航页负责浏览与管理,不负责承载使用流。**
8. **任务是主线,对象是挂件。**
9. **右栏始终是执行透明化窗口。**
10. **默认入口只有一个:对话。**
---
## 11. 前端收敛方案
### Phase 1:先统一心智
- 把“工具”统一重新命名为“数字技术员”或在内部按技术员建模
- 明确通用助手 = 默认专员
- 明确 object entry 不再代表能力本体
### Phase 2:统一输入区
- 在 `ChatInputBar` 中把当前对象 chip 收成标准能力
- 专员 chip 与技术员 chip 使用统一插槽或统一组件
- `+` 只负责选对象,不再负责跳到独立工具页
### Phase 3:统一设置条
- 把各工具页差异抽到 `settingsSchema`
- `SkillStrip` 改成真正的对象驱动渲染
- 设置条与当前对象强绑定,不再与路由强绑定
### Phase 4:统一右栏
- 右栏根据当前对象的 `workflowSchema` 和 `artifactSchema` 渲染
- 专员右栏强调多步编排
- 技术员右栏强调执行步骤
### Phase 5:清退独立工具页
- 保留旧工具页一段时间做兼容
- 新能力一律不再新建完整工具页
- 旧工具页逐步收敛为配置详情页或兼容跳板页
---
## 12. 对当前项目最重要的影响
这次不是小修,而是会改变整个前端边界:
- `availableSkills` 不再等于“可跳转的页面列表”
- `businessApps` 不再等于“专员工作台页面列表”
- 路由将从“能力入口”退回成“管理入口 / 兼容入口”
- 真正的执行入口会统一收敛到任务对话面
换句话说:
**我们不再做“很多个 AI 页面”,而是做“一个任务工作面,里面动态挂很多 AI 对象”。**
---
## 13. 未决问题
1. 对外文案最终叫“工具”还是“数字技术员”,是否区分用户可见名和内部模型名
2. 一个任务内部可以有多个技术员执行记录,但输入区始终只显示一个当前对象
3. 专员调用技术员时,只在右栏和执行链里显示下游执行,不在输入区显性双挂
4. 旧工具页是否全部保留兼容路由,还是只保留极少数重度场景
5. 目录页中的“浏览配置”应展示到什么深度,是否允许直接预览 workflow schema
---
## 14. 本稿的用途
这份文档用于后续所有相关改造的判断标准:
- 评估某个页面要不要保留
- 判断某个新能力该不该新建页面
- 判断当前对象该不该在输入区可见
- 判断导航页与使用页的边界
后续如有实现与本稿冲突,以本稿为准,再逐项修订。
+9 -2
View File
@@ -3,7 +3,10 @@
> **命名规则:** `AR{NN}_{描述}.md`
> **用途:** 后端架构、前端架构、数据库架构、部署架构
>
> **⚠️ 本目录 AR 文档为 V1.1 设计期历史快照。** 当前实现已重写为 **Go + Gin + GORM + MySQL 8.0 + FAISS**,以 `docs/changelog.md`、`docs/db_schema.md`、`docs/deploy.md` 为准。
> **⚠️ `AR01`–`AR04` 为 V1.1 设计期历史快照。** 当前实现已重写为 **Go + Gin + GORM + SQLite + Go 原生 brute-force 向量检索**,以 `docs/changelog.md`、`docs/db_schema.md`、`docs/deploy.md` 为准。
> `AR05`–`AR08` 是 2026-09-16 / 17 的工作台设计稿,**不属于 V1.1 快照**,其中 `AR08` 为部分被取代稿,取用前先读其文首补注。
> 当前产品导航与工作台口径,请以 `docs/01_System_Overall/SY22_Role_Skill_App_Unified_Task_Architecture.md` 为准:
> `新建任务 / 项目 / 专员·技能·APP·连接器 / 长程APP / 知识库 / 后台管理 / 我的`
## 文件清单
@@ -12,5 +15,9 @@
| `README.md` | 本索引文件 |
| `AR01_Backend_Arch.md` | 后端架构(V1.1 FastAPI 快照;现为 Go + Gin + GORM) |
| `AR02_Frontend_Arch.md` | 前端架构(Vue3 + Element Plus 三栏布局) |
| `AR03_Database_Arch.md` | 数据库架构(MySQL 8.0 + FAISS 向量检索) |
| `AR03_Database_Arch.md` | 数据库架构(SQLite 单文件 + Go 原生向量检索) |
| `AR04_Deploy_Arch.md` | 部署架构(V1.1 Docker 快照;现为单二进制 + systemd) |
| `AR05_Workbench_Architecture_Contract.md` | 数字员工 Workbench 架构合同(任务为中心、对象挂载到任务,前端重构强约束) |
| `AR06_Skill_Packaging_Specification.md` | 技能文件规范(技能 = 定义文件 + 执行器 + 结果组件,不以独立页面存在) |
| `AR07_Architecture_Alignment_Audit.md` | 架构对齐确认与本轮修复范围(收敛两套并行模型的确认记录) |
| `AR08_Role_Interaction_Design.md` | AI 角色与工具统一交互设计(**部分被取代**:不跳页结论已采纳,「数字技术员」对象已废弃,见文首补注) |