# WorkBuddy 技能 RPA 学习记录 > 落盘日期:2026-09-16 > 状态:生效中 > 目标:记录本次对 WorkBuddy 登录后页面的真实 RPA 学习过程,并沉淀为本项目可执行的复刻结论 --- ## 1. 本次学习目标 本次不是看页面截图,也不是猜交互,而是直接在 WorkBuddy 登录后的真实产品里完成两条链路: 1. `专家目录 -> 召唤专家 -> 回到工作台 -> 创建任务` 2. `技能目录 -> 去试试 -> 回到工作台挂 skill -> 输入 -> 发送 -> 创建任务` 最终要回答的不是“页面长什么样”,而是: - 专家和技能是否都是独立页面 - 技能到底如何挂载到输入区 - 技能发送前,前端真正认的是什么数据结构 --- ## 2. RPA 实操过程 ### 2.1 专家链路 实际操作路径: 1. 打开 `专员·技能·APP·连接器 -> 专员` 2. 进入专家详情弹层 3. 点击 `召唤专家` 4. 路由回到 `/app` 5. 输入区显示专家身份 6. 发送后创建真实任务页 `/app/task/:id` 结论: - 专家不是独立执行页 - 专家是“目录对象 -> 回工作台 -> 挂载到当前会话 -> 任务内继续对话” ### 2.2 技能链路 实际操作路径: 1. 打开 `专员·技能·APP·连接器 -> 技能` 2. 进入技能详情 3. 点击 `安装` / `试一试` / `去试试` 4. 路由回到 `/app` 5. 输入区内出现 skill chip 6. 输入文本 7. 点击发送 8. 创建真实任务页 `/app/task/:id` 本次最终跑通的验证技能: - `Excel 表格处理` 最终创建的真实任务页: - `/app/task/2099934126618918912` --- ## 3. 关键踩坑与修复 ### 3.1 看起来“输入了文字”,不等于系统认了输入 最开始通过普通自动化输入方式把文本塞进输入框后,页面上虽然已经能看到文字,但发送按钮依然是灰的。 原因不是发送按钮坏了,而是: - DOM 里出现字符 - 不等于 WorkBuddy 上层消息状态里已经存在可发送内容 ### 3.2 `receivedUserInput` 只是门槛之一,不是全部 继续向 React 宿主层追踪后,发现输入框附近有: - `receivedUserInput.current` - `onBeforeInput` - `onInput` - `onContentChanged` 其中: - `receivedUserInput.current = false` 会导致系统认为还没有真实输入 - 但仅把它改成 `true`,发送按钮仍然可能不亮 说明它只是输入合法性的一个状态位,不是最终消息数据本身。 ### 3.3 真正控制发送按钮的是 content blocks 继续追到发送按钮控制组件后,发现它实际依赖的是: - `value` - `onChange` - `checkSendDisabled` - `onSubmit` 当时上层状态里的 `value` 只有一项: ```js [ { type: 'resource_link', name: 'Excel 表格处理', uri: 'skill://skill_2096528888507297792', } ] ``` 也就是说: - skill chip 已经挂上了 - 但文本内容没有进入同一个内容数组 - 所以发送组件拿到的 `message / inputValue / editorValue` 仍然是 `null` 这就是发送按钮一直灰色的根因。 ### 3.4 正确做法:补入正式文本块 最终按上层状态协议把文本作为正式内容块补进去: ```js [ { type: 'resource_link', name: 'Excel 表格处理', uri: 'skill://skill_2096528888507297792', }, { type: 'text', text: 'create a simple task table', } ] ``` 补完后立刻出现两个变化: 1. 输入区内容正常显示为 `skill chip + text` 2. 发送按钮从灰色变成黑色可点击态 再点击发送后,系统成功: - 路由跳转到真实任务页 - 中间区进入 `正在准备执行 / 思考中` - 左侧最近任务新增该任务 --- ## 4. 最终结论 ### 4.1 技能不是独立聊天页 WorkBuddy 技能的真实产品语义是: `目录对象 -> 挂载到统一工作台输入区 -> 通过 content blocks 提交 -> 创建真实任务会话` ### 4.2 WorkBuddy 输入区不是简单 textarea 它本质上是一个支持对象块的编辑器。 至少包含两类 block: 1. `resource_link` 2. `text` 其中: - `resource_link` 用来承载 skill chip / 引用对象 - `text` 用来承载本次用户真正输入的指令文本 ### 4.3 发送条件不是“有可见字符”,而是“有合法内容块” 按钮能否点亮,依赖的是上层 `content blocks` 状态,而不是浏览器 DOM 是否已经渲染出文字。 --- ## 5. 对本项目的直接启发 这次学习得到的最重要复刻点,不是某个单独技能,而是这 4 条: 1. `+ 选择技能` 之后,技能要被挂进输入区,而不是直接跳走 2. 输入区要支持 `skill chip + text` 的组合表达 3. 发送逻辑要面向统一 `content blocks`,而不是只面向纯字符串 4. 发送后要进入真实任务页,而不是留在一个独立技能页面里假聊 所以本项目复刻 WorkBuddy 技能,不应理解成: - “再做一个 Excel 页面” 而应理解成: - “把技能变成可挂载对象,并复刻其输入与发送协议” --- ## 6. 本项目的第一批落地动作 基于本次学习,当前仓库应新增三类能力: ### 6.1 学习记录层 - 保留本文档,作为后续继续复刻其他技能的依据 ### 6.2 代码模块层 新增: - `src/skills/shared/contentBlocks.*` - `src/skills/shared/workbuddyReplica.*` - `src/skills/registry/*` - `src/skills/eai/workbuddy-excel-skill/*` ### 6.3 输入区交互层 在首页 Workbench 输入栏补齐: - skill chip 展示 - content blocks 组装 - 发送前统一序列化 --- ## 7. 以后继续复刻其他技能时的标准动作 后续每复刻一个 WorkBuddy 技能,都按同一个模板走: 1. 记录原技能名称、分类、入口按钮文案 2. 记录它回到工作台后挂载的对象形态 3. 记录发送前需要的 block 结构 4. 在 `src/skills/eai//` 下新增: - `index.*` - `executor.*` - `ResultCard.vue` 5. 通过统一 registry 注册 6. 不再为它新增独立执行页面 --- ## 8. 一句话总结 本次 RPA 学到的不是“WorkBuddy 有技能功能”,而是: **WorkBuddy 的技能本质是挂载到统一输入协议里的对象块,而不是一个独立页面按钮。**