Files
pj0235-eai_agentplatform/docs/02_Architecture/AR08_Role_Interaction_Design.md
T
eaiadminandClaude Code 14f303459e refactor: 后端仓库层收口(A1:课程/产品/素材)+ 收进工作区既有对象化重构
本提交含两部分。第一部分是本轮工作;第二部分是此前一直留在工作区、
从未提交的对象化重构,与第一部分在文件上互相咬合(internal/repository
整个包都是未跟踪状态,且 api 层已有文件引用它),无法拆成两个可编译的提交。

一、仓库层收口 A1 批(本轮工作)

把 api 层手写的 store.DB 查询收进具名仓库方法,只给真正获益的对象做方法,
不机械包裹全量。本批迁移 22 处裸查询(courses.go 9 / media.go 12 / products.go 1),
新增方法:

- MediaFileRepo.ListByBind / ListForAudit / MarkExtracted
- KnowledgeChunkRepo.CountByMediaFile
- ProductRepo.GetVisibleByID

两条业务口径改由仓库单点持有,避免各处手写漂移:
「只有 approved 素材出现在课程详情」与「已停用产品不在课程详情露出」。

修掉两个真实缺陷:
- ProductRepo.GetByID 缺 Where 条件。此前 GET /api/products/{id} 对任意 id 都返回
  第一条产品、对不存在的 id 返回 200,且 PUT /api/products/{id} 会覆盖第一条产品
  —— 数据损坏级。全仓扫描确认这是唯一一处同型写法。
- ProductRepo.Delete 写 status="deleted",而 DELETE 处理器文档与回包都声称
  "inactive",接口在说谎;管理员用 status=all 拉列表会看到前端不认识的状态。
  已对齐为 inactive(与 CourseRepo.Delete 一致)。

删除 8 个零调用且列名不存在的死方法(一调即 SQL 报错):
- media_file 上的 file_path / file_type / approval_status 三列并不存在,
  GetByPath / ListByType / UpdateStatus 全废
- knowledge_chunk 上的 space_id 列不存在(模型早已改为 knowledge_space_key),
  List / Total / ListBySpaceIDs / DeleteBySpace / SearchByVector 全废
取舍边界:能对当前 schema 跑通的死方法保留,跑不通的删或修。

CourseRepo.List 补齐 status=all 档(此前传给它会当作 status='all' 过滤出空列表)。
该方法此前零调用,现与产品列表语义对齐。

验证:go build ./... 与 go test ./... 全绿;另用真实 HTTP 请求验证 34 项
(课程 17 / 产品 3 / 素材 14),跑在数据库副本与独立 KB_DATA_DIR 上,
含 multipart 真上传 → 审批 → pdftotext 提取 → 分片入库的完整链路。

二、此前未提交的对象化重构(非本轮工作)

- 新增 internal/repository 仓库层、connectors、skills、specialists、xapps、jsonutil,
  model/task_record|task_run|task_artifact、api/task_runtime|action_definition|chat_message
- 删除 api/app_definition、connectors、my_app_center、notification、office_skill、
  export_docx|pptx|xlsx、official_account_* 等,随 XApp/Skill/Specialist/Connector
  可插拔打包方向(AR10/AR11)调整
- 资产目录归位:backend-go/knowledge_source → assets/knowledge/source、
  training_materials → assets/training/materials;README 内相对路径同步加深两级;
  deploy env 补 ASSET_ROOT_DIR 并改 KNOWLEDGE_SOURCE_DIR / TRAINING_MATERIALS_DIR
- 前端新增 skills/ specialists/ connectors/ xapps/ 目录与对应页面

验证:前端 npm run build 通过(7.26s)。

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-19 01:23:51 +08:00

14 KiB
Raw Blame History

AI 角色与工具统一交互设计

落盘日期:2026-09-16 状态:部分被取代的设计稿 —— 阅读前先看下面的「采纳与废弃」

⚠️ 采纳与废弃(2026-09-17 补注)

本文结论不是「整体作废」,而是一半采纳、一半废弃。请按下表取用,不要整篇照做。

已采纳(现已是实现方向)

本文结论 现落点
对象不跳页,都在同一工作面里挂载 AR05_Workbench_Architecture_Contract.md
专员 / 工具不应该是独立 Vue 页面 已实现:views/workbench/ 无独立工具页
+ 菜单作为统一的对象选择入口 已实现:components/chat/PlusMenu.vue
切换对象 = 更新任务上下文,不跳路由 已实现:store/taskRuntime.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

结构如下:

┌────────────────────────────────────────────────────────────┐
│ 左侧导航                                                   │
├────────────────────────────────────────────────────────────┤
│ 中间:对话主画面                     │ 右侧:上下文面板      │
│                                     │                     │
│ 消息流                              │ [工作流] [产物]      │
│                                     │                     │
│                                     │ 当前对象的执行进度   │
│                                     │ 当前对象的产物列表   │
├────────────────────────────────────────────────────────────┤
│ [+] [当前对象 chip] [附件] [输入框................] [发送] │
└────────────────────────────────────────────────────────────┘

4.2 对象切换方式

所有对象的选择,都从 + 打开:

  • 模式:快速 / 专家
  • 专员
  • 技术员
  • 连接器或其它补充入口

选择结果不再跳页面,而是更新当前任务上下文。

4.3 页面跳转原则

默认原则:

  • 切换对象,不跳页
  • 切换能力,不跳页
  • 切换任务,才可能切上下文

只有管理、配置、市场、控制台这类后台页面,才保留独立路由。


5. 专员与技术员的职责分层

5.1 数字专员

数字专员对应企业中的项目经理,负责:

  • 接收用户目标
  • 把目标拆成多步任务
  • 决定调用哪些技术员
  • 汇总技术员的结果
  • 输出最终交付物

5.2 数字技术员

数字技术员对应企业中的专业执行者,负责:

  • 完成单个技术动作
  • 处理特定格式输入
  • 产出特定类型结果
  • 把结果返回给专员或直接返回给用户

5.3 调用关系

用户
  → 数字专员
      → 调用数字技术员 A
      → 调用数字技术员 B
      → 调用数字技术员 C
  → 汇总结果
  → 输出最终产物

5.4 通用助手的定位

通用助手不是单独体系,而是:

  • 默认专员
  • 未选择任何专员或技术员时的兜底对象
  • 帮用户判断应不应该切到某个专员或技术员

6. 工具的新定义

6.1 工具不再是页面

未来的“工具”只是技术员目录里的一个对象类别。

例如:

旧叫法 新理解
文档翻译工具 文档翻译技术员
文案校对工具 文案校对技术员
语音转写工具 语音转写技术员
批量提取工具 批量提取技术员
合同审查工具 合同条款分析技术员或合同审查专员的下游技术员
报告生成工具 报告生成技术员

6.2 工具在前端的可变部分

一个技术员/工具在前端只允许有 4 类差异:

  1. 对象 chip
  2. 输入提示与输入校验
  3. 设置条
  4. 右栏工作流与产物

除此之外,不再允许复制一整页聊天页。

6.3 工具定义应沉淀为 schema

每个技术员建议定义如下结构:

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. 本稿的用途

这份文档用于后续所有相关改造的判断标准:

  • 评估某个页面要不要保留
  • 判断某个新能力该不该新建页面
  • 判断当前对象该不该在输入区可见
  • 判断导航页与使用页的边界

后续如有实现与本稿冲突,以本稿为准,再逐项修订。