docs: organize product documentation by domain

Replace the flat features directory with document-type and functional-domain navigation, update repository-wide links, and add a top-level documentation index.

Define Task, Conversation, Job, Subjob, Run, Scheduled Task, Goal Task, and Task Center in one canonical document set. Keep Smart Heartbeat ownership separate and leave future partitioned memory explicitly undesigned.
This commit is contained in:
mesalogo
2026-08-19 07:52:43 +08:00
parent 3935f50017
commit ccaab25d11
28 changed files with 1980 additions and 590 deletions
@@ -0,0 +1,762 @@
# 通用助手工作栏与执行空间 PRD
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 状态 | 设计中 |
| 版本 | 0.3 |
| 日期 | 2026-08-19 |
| 适用产品 | GoodBuddy 桌面端 |
| 相关设计 | [统一界面设计系统](../../../UI-DESIGN.md) |
| 相关能力 | [会话监督](../supervision/conversation-supervision-prd.md)、[自动化平台](../../architecture/automation-platform-architecture.md)、[长期助手路线图](../../roadmap/long-term-assistant-roadmap.md) |
## 1. 背景
GoodBuddy 已经在聊天右侧提供上下文、工作区、浏览器和成果面板,也已经具备
Runtime 事件、Git 变更、文件预览、成果存储、受控浏览器和专家 Job 等基础能力。后续还
计划增加:
- Conversation 和 Task/Job Run 的独立监督。
- OpenCode、Continue 和 DeepSeek Harness 的 Runtime 生命周期监督。
- 用户可直接使用的终端和受管进程。
- HTML 等成果的即时安全预览。
- 本机与 SSH 远程主机上的工作区和 Agent Runtime。
这些能力不能被收束为只面向编程的工作台。监督、Runtime、终端、进程、浏览器、成果和
上下文都可以服务于普通问答、内容分析、自动化、数据处理、远程运维、知识整理和软件开发。
同时,能力目录也不能根据当前页面、项目类型或 Runtime 能力无提示地变化,否则用户无法在
需要时主动打开面板并选择目标、主机或运行环境。
本设计把右侧区域定义为应用级的“助手工作栏”,并把本机或远程的目录、终端、进程和
Runtime 统一抽象为“执行空间”。
## 2. 产品定义
### 2.1 助手工作栏
助手工作栏是 GoodBuddy 中始终可访问的应用级工具容器。它提供稳定能力目录,用户从中
查看任务中心,并按需打开一个或多个监督、Runtime、终端、进程、工作区、浏览器、成果和
上下文面板实例。稳定的是能力的可发现性,不是九个同时占据界面的固定面板。
工作栏不是:
- 只在编程项目中出现的 IDE 面板。
- 当前聊天消息的附属详情框。
- 根据能力探测结果自动增删入口的动态菜单。
- 绕过 Main、Preload、Ask/Execute 或审批边界的控制台。
- 全系统进程管理器、任意文件浏览器或无边界远程管理工具。
### 2.2 执行空间
执行空间描述工作区、终端、受管进程和 Agent Runtime 实际运行的位置:
```ts
type ExecutionSpace =
| {
kind: 'local'
rootPath?: string
}
| {
kind: 'ssh'
hostId: string
remoteRootPath?: string
}
```
执行空间可以来自当前项目,也可以由用户在工作栏中临时选择。临时选择不会静默修改项目
设置,只有用户显式保存时才成为项目默认值。
## 3. 核心产品原则
### 3.1 能力目录稳定,面板实例由用户控制
工作栏能力目录提供以下标准能力:
```text
任务中心
监督
Runtime
终端
进程
工作区
浏览器
成果
上下文
```
- 应用不得根据当前项目、会话、Runtime、主机或探测结果无提示地增删能力目录项。
- 用户主动打开、关闭、排序和停靠面板实例;应用不默认同时挂载全部能力。
- Task Center 是 Task 的单例应用级索引。每个 Task 与唯一 Conversation 一对一;Task
Center 不复制会话内容,也不显示普通 Conversation、Job、Run 或心跳事项。
- 当前能力、连接、数据和空状态可以动态变化。
- 能力不可用时,目录项或已打开面板显示原因、影响和可执行的配置或切换入口,不能只通过隐藏表示。
- 用户可以在设置中调整目录顺序;恢复默认布局恢复标准目录与默认打开面板,不强制打开全部能力。
- 同一能力需要并排比较不同目标时可以创建多个实例,每个实例拥有独立身份和范围绑定。
### 3.2 当前上下文只提供默认值
任务中心作为全局索引不跟随当前会话,也不支持为同一列表打开多个目标实例。其他可绑定
目标的能力使用当前会话、项目、Runtime 和主机帮助新面板实例初始定位,但这些上下文不是
使用门槛:
- 监督默认选择当前会话,用户可以改选其他 Conversation、Task、Job/Run 或实验 Run。
- Runtime 默认跟随当前会话,用户可以固定到其他活动或历史 Run。
- 终端默认使用当前项目执行空间,用户可以新建本机或远程终端。
- 工作区默认显示当前项目目录,用户可以打开其他本机目录或远程目录。
- 成果和上下文默认使用当前范围,用户可以切换到项目、全局或其他允许范围。
每个可切换目标的面板实例都提供一致的范围模式:
```text
跟随当前上下文
固定到指定对象
```
固定目标失效时,面板显示“目标不可用”和修复入口,不静默回到其他目标。
### 3.3 用户控制打开、切换和介入
- 后台事件可以更新目录徽标、面板状态和通知,但不得无条件抢占当前面板。
- 只有用户刚刚发起且明确需要面板完成的交互,才可以打开对应面板。
- 浏览器画面、审批、监督警告、Runtime 失败和终端退出默认通过徽标或通知提示。
- 高风险状态必须持续可见,但不以自动切页代替用户选择。
- 用户切换页面、会话或项目时,已固定的面板目标保持不变;跟随模式才更新目标。
### 3.4 入口稳定不等于虚假能力
稳定能力目录和已打开面板必须准确呈现能力差异:
- 当前 Runtime 不支持后台 Job 时,Runtime 能力仍可发现;打开后说明当前可监督的内容。
- 当前执行空间没有 Git 仓库时,工作区文件功能仍可使用,Git 区域显示不可用原因。
- 没有活动进程时,进程面板提供创建终端或启动 Runtime 的入口。
- 没有项目时,终端和工作区允许用户选择本机目录或远程主机。
- 监督未启用时,监督面板提供目标、模式和“开始监督”,而不是隐藏能力。
不得渲染成排没有解释的禁用按钮,也不得把“进程连通”描述为已经支持完整原生监督。
### 3.5 通用能力与领域能力分层
- 监督判断目标、证据、矛盾、遗漏、质量和风险,不假设目标一定是编程。
- Runtime 监督展示运行生命周期,不假设 Runtime 一定是 OpenCode。
- 终端和进程是通用执行能力,不只服务代码构建。
- 工作区可以是文档、数据、知识或代码目录;Git 是可选区域。
- HTML 预览属于通用成果能力,不只用于网页开发。
- SSH 主机可以承载 Agent、自动化、数据处理和工作区,不只代表远程代码仓库。
## 4. 目标
### 4.1 用户目标
- 从任意主要页面随时发现同一组稳定能力,并按需打开所需面板。
- 自主选择每个可绑定目标的面板实例跟随当前上下文还是固定到指定目标。
- 在不中断主任务的情况下观察监督意见、Runtime、进程和成果。
- 随时创建本机或远程终端,并理解其执行位置和权限。
- 查看 GoodBuddy 管理的进程及其来源、输出和停止状态。
- 对生成的 HTML、Markdown、JSON、图片等成果进行即时安全预览。
- 管理 SSH 主机,并在远程执行空间中运行受控 Agent Runtime。
### 4.2 产品目标
- 建立不依赖具体页面和 Runtime 的应用级工作栏、能力目录和面板实例壳层。
- 建立统一范围、执行空间、生命周期、成果和控制契约。
- 复用现有 Project、Conversation、Task、Artifact、Activity 和 Approval 数据。
- 保持 Renderer 无任意文件、进程、PTY、SSH 或 Electron API 能力。
- 保持 Ask 只读、Execute 审批、取消、超时、输出边界和活动审计。
- 为本机与远程能力提供一致 UI,同时准确表达能力差异。
## 5. 非目标
- 不把 GoodBuddy 改造成完整 IDE。
- 不提供全系统进程枚举和任意 PID 终止。
- 不默认扫描用户全部目录、远程主机或 SSH 配置。
- 不允许 Agent 未经现有 Runtime 边界直接向用户终端注入输入。
- 不自动执行 HTML 中的脚本或访问网络。
- 不让监督器自动替用户发言、批准工具、扩大范围或修改安全策略。
- 不在首期承诺网络断开后远程任务一定可恢复。
- 不在首期支持任意 ProxyCommand、任意端口转发或 SSH Agent Forwarding。
- 不要求所有 Runtime 提供相同的 Subagent、Job、Hook 或会话能力。
## 6. 信息架构
### 6.1 应用级位置
助手工作栏位于主窗口右侧,但不归属于聊天页面。聊天、知识、魔法笔记、自动化、活动记录
等主要页面都可以打开它。各页面可以提供默认范围,不能维护互不相容的右栏副本。
```text
┌──────────────┬──────────────────────────────┬────────────────────────┐
│ 主导航 │ 当前主任务 │ 助手工作栏 │
│ │ │ │
│ 会话 / 知识 │ 聊天、文档、自动化或数据视图 │ 稳定能力目录 │
│ 自动化 / 活动│ │ 用户打开的面板实例 │
│ 设置 │ │ 各实例范围与执行空间 │
└──────────────┴──────────────────────────────┴────────────────────────┘
```
### 6.2 能力目录与面板实例
能力目录不等于同时打开九个面板。推荐使用工作栏内的纵向能力导航,并在旁边或停靠区域管理
用户已经打开的面板实例:
- 每项始终显示稳定图标,并提供可见标签或可持续查看的工具提示。
- 目录使用与其交互模型匹配的列表、工具栏或菜单语义;单实例切换使用 `tablist``tab`
`tabpanel`,多实例停靠区使用有名称的区域和明确面板标题。
- 支持方向键、Home、End、Enter、Space、关闭面板和正确焦点恢复。
- 徽标显示未解决数量、等待审批或失败状态,并同时提供文字或可访问名称。
- 用户调整目录顺序、打开实例、停靠位置和尺寸后持久化;关闭实例后能力仍可从目录重新打开。
- 默认布局只恢复经过产品确认的少量常用面板,不自动打开全部标准能力。
- 每个实例显示稳定实例 ID、能力名称、跟随或固定状态与当前目标;同能力多实例不能只靠位置区分。
当前聊天右栏过渡实现保留 Task Center、上下文、工作区、浏览器和成果五个横向页签时,必须
单行横向滚动,不能自动隐藏或缩写到不可辨认。Task Center 继续作为 Task 的现有入口;
审批定位到所属 Task、Job 或 Runtime。智能心跳不作为工作栏页签,其报告、建议、历史和完整配置统一归属
“智能心跳”菜单入口。当前阶段不新增独立自动化中心。
### 6.3 工作栏尺寸
- 宽窗口:工作栏停靠右侧,支持键盘和指针调整宽度。
- 中等窗口:可停靠或覆盖主内容,保持用户上次选择。
- 窄窗口:以全屏或接近全屏抽屉显示。
- 终端、宽日志和大型成果允许用户切换到底部停靠或独立窗口。
- 应用只建议适合的布局,不因面板内容自动改变用户已经选择的停靠位置。
## 7. 能力与面板定义
### 7.1 Task Center
Task Center 保留为工作栏中的稳定入口,并在现有基础上适度完善:
- 只索引 Task;每个 Task 与唯一 Conversation 一对一绑定。
- 显示名称、Global 或 Project 范围、状态、最近进展、真实活动时间和需要关注信息。
- 点击 Task 直接打开其 Conversation。
- 完整消息、Job、Run、工具、Subagent、审批和成果分别留在 Task Conversation、Runtime、活动记录和
成果查看器中,不在窄栏复制。
- 智能心跳的报告、建议、历史和配置不进入任务中心。
任务中心是单例索引,不使用其他能力的“跟随 / 固定目标”多实例模型。后台状态可以更新
徽标和排序,但不能自动打开面板或抢占用户当前工作。
详细产品边界以 [Task Center PRD](../task-and-job/task-center-prd.md) 和
[Task 与 Job 统一领域模型](../task-and-job/task-and-job-model.md) 为准。
### 7.2 监督
监督是通用观察与评论入口,详细行为以
[会话监督 PRD](../supervision/conversation-supervision-prd.md) 为准。
监督能力在目录中稳定可发现;用户打开面板实例后可以选择:
- 普通会话。
- Task 或 Job/Run。
- 实验 Run 或实验整体。
- 后续支持的文档分析和其他可监督对象。
监督面板包含:
- 当前目标与范围。
- 开启状态、监督模式、触发方式和预算。
- 评论、警告、人工复核请求和证据。
- 未解决、已查看、已解决、忽略和误报状态。
- “带入输入框”“查看证据”“追问”“停止当前回复”等用户介入操作。
“采纳”只生成可编辑草稿或显式会话操作,不自动发送、执行、切换 Execute 或批准工具。
### 7.3 Runtime
Runtime 能力统一监督直连模型、OpenCode、Continue、DeepSeek Harness 和后续 Runtime。
能力在目录中稳定可发现,打开的面板实例依据所选 Runtime 的真实能力显示状态。
共同区域:
- Runtime、模型连接、会话或 Run 身份。
- 活动请求、状态、耗时、用量和取消。
- 工具、审批、问题、上下文压缩和错误。
- 跳转完整活动记录和持久设置。
可选区域:
- Subagent 父子关系和取消。
- 后台 Job 队列、进度、结果和终止。
- Todo、Workflow 和 Hook 运行。
- 原生会话、暂停、恢复、压缩或释放。
可选区域不可用时,用一段有操作路径的状态说明替代空卡片。用户可以在面板中切换 Runtime
或目标 Run,不要求先回到聊天 Composer。
### 7.4 终端
终端面板允许用户主动创建和管理本机或 SSH 终端:
- 新建、重命名、切换、关闭和重新连接终端。
- 选择执行空间、工作目录和 Shell。
- 显示本机或远程主机、目录、Shell 和连接状态。
- 支持复制、粘贴、搜索、清屏、滚动和调整终端尺寸。
- 支持将终端切换到右侧、底部或独立窗口。
终端属于用户交互表面。Agent 工具调用可以产生独立受管进程和日志,但不能伪装成用户终端,
也不能在没有明确授权的情况下向现有终端发送按键或命令。
### 7.5 进程
进程面板只展示 GoodBuddy 创建、托管或明确接管的进程:
- 用户终端 Shell。
- Runtime Host、Server、Utility 和远程 Helper。
- Runtime 后台 Job。
- 用户通过工作栏显式启动的长运行命令。
- 浏览器或自动化中属于 GoodBuddy 的受管子进程摘要。
每项显示:
- 名称和有界命令摘要。
- 来源、执行空间、项目或会话归属。
- 启动时间、状态、退出码和资源摘要。
- 有界 stdout/stderr 或结构化日志。
- 正常终止、必要时强制终止和打开关联对象。
Renderer 不接收任意系统 PID 控制能力。控制动作引用 Main 签发的受管进程 ID,并由 Main
重新验证所有权、当前状态和允许操作。
### 7.6 工作区
工作区面板允许用户选择:
- 当前项目目录。
- 其他本机目录。
- 已配置 SSH 主机上的远程目录。
面板提供:
- 有界目录树和文本文件预览。
- 当前选择、规范化路径和执行空间。
- 可选 Git 状态、Diff 和仓库信息。
- 显式打开、下载副本或在终端中打开。
- HTML 文件的源码与安全预览。
本机和远程访问都必须由 Main 或远程 Helper 在对应文件系统上执行路径规范化、相对路径和
符号链接边界检查。Renderer 只能提交受约束的相对路径和已授权范围 ID。
### 7.7 浏览器
浏览器能力在目录中稳定可发现,打开面板后允许用户:
- 创建新的 GoodBuddy 隔离浏览器会话。
- 选择当前会话或其他受控浏览器会话。
- 查看状态、当前 URL、有界画面和错误。
- 进入明确的交互模式或停止会话。
没有浏览器会话时显示“新建浏览器会话”,而不是隐藏能力。模型或后台浏览器活动可以更新
徽标,但不得无条件打开面板或切换用户当前面板。
浏览器面板只管理 GoodBuddy 受控浏览器,不表示可以控制用户已安装的浏览器。
### 7.8 成果
成果面板统一显示全局、项目、Conversation、Task/Job Run 和监督显式产生的独立成果:
- Markdown、纯文本和 JSON。
- 图片和图表。
- HTML 安全预览。
- 后续的 PDF、Office、表格和其他受支持格式。
普通聊天回复只保留在会话消息流中,不自动复制为成果。只有 Runtime 或受管工具显式声明的
Artifact、自动化和监督生成的独立输出,以及用户手动导入或明确保存的内容进入成果面板。
升级前已经自动保存的普通对话 Markdown 可以从成果列表中隐藏,但不应通过升级迁移物理
删除用户数据库内容。
用户可以切换范围、搜索、预览、查看来源、导出或打开关联对象。成果必须保留项目、会话、
Conversation、Run、创建者、MIME、大小、校验值和时间等可用归属。
#### HTML 即时预览
- Runtime 或受管工具通过显式 Artifact 事件声明成果,不能让 Renderer 猜测任意路径。
- Main 验证成果属于当前授权执行空间,限制大小、类型和读取范围后再持久化。
- HTML 使用 `iframe sandbox=""` 和严格 CSP 进行脚本关闭、网络关闭的静态预览。
- 清理脚本、事件属性、嵌套 frame、object、embed、base、link、meta refresh、表单和活动 URL。
- 提供“预览 / 源码”切换,并持续标注“静态安全预览,脚本和网络已禁用”。
- 不使用 `dangerouslySetInnerHTML`,不启用 Electron `webviewTag`
- 外部打开是明确的用户操作,并说明外部浏览器可能执行脚本或联网。
### 7.9 上下文
上下文面板显示用户已选择或系统准备送入下一次模型请求的内容:
- 附件、图片和文档提取结果。
- 知识库、引用和检索范围。
- 已确认记忆。
- 浏览器、工作区文件和授权目录。
- Runtime、监督或自动化显式绑定的其他上下文。
每项显示来源、范围、大小、发送状态和用途。用户可以预览、移除或清空。固定到历史 Run
时,上下文只读展示不可变快照;跟随当前 Composer 时才允许编辑下一次请求的上下文。
## 8. 范围和选择模型
### 8.1 通用目标引用
各面板实例使用不包含敏感内容的目标引用:
```ts
type WorkbarCapabilityId =
| 'supervision'
| 'runtime'
| 'terminal'
| 'processes'
| 'workspace'
| 'browser'
| 'results'
| 'context'
type WorkbarTargetRef =
| { type: 'conversation'; id: string }
| { type: 'run'; id: string }
| { type: 'project'; id: string }
| { type: 'workspace'; id: string }
| { type: 'runtime-session'; id: string }
| { type: 'terminal'; id: string }
| { type: 'managed-process'; id: string }
| { type: 'browser-session'; id: string }
| { type: 'artifact'; id: string }
```
Renderer 选择目标后,Main 必须重新验证对象存在、归属范围和当前用户可见性。不能把目标 ID
直接转换为文件、进程或远程控制权限。
### 8.2 跟随与固定
```ts
type WorkbarScopeBinding =
| { mode: 'follow'; source: 'active-context' }
| { mode: 'pinned'; target: WorkbarTargetRef }
type WorkbarPanelInstance = {
id: string
capability: WorkbarCapabilityId
binding: WorkbarScopeBinding
dock: 'right' | 'bottom' | 'window'
}
```
- 每个面板实例独立保存绑定方式;同一能力的多个实例不能共享可变选择状态。
- 绑定只包含公开 ID,不包含路径、凭据、Token 或日志。
- 删除固定目标后保留失效状态,直到用户选择新目标或恢复跟随。
- 工作栏重新打开、页面切换和窗口重建后恢复用户打开的实例与选择。
## 9. 主机管理与远程执行空间
### 9.1 设置入口
设置中心增加“主机与远程执行”分类,管理:
- 主机名称、地址、端口和用户名。
- 认证方式和凭据配置状态。
- Host Key 算法与 SHA-256 指纹。
- 连接测试、远程系统和架构。
- Helper、Runtime 和能力状态。
- 删除、重新验证或更新 Host Key。
主机配置是全局资源。项目或工作栏只引用主机 ID,不能复制凭据。
### 9.2 凭据和主机验证
- 优先支持系统 SSH Agent 或 OpenSSH 证书。
- 导入私钥或密码时使用 Electron `safeStorage` 加密。
- 凭据绑定主机 ID、地址、端口、用户名和认证类型。
- Renderer 只接收 `credentialConfigured`、来源和错误状态。
- 首次连接展示 Host Key 算法和 SHA-256 指纹,必须由用户显式接受。
- Host Key 变化硬失败,并通过独立高风险流程替换。
- 禁止 `StrictHostKeyChecking=no` 和默认 SSH Agent Forwarding。
- 命令参数、URL、日志、SQLite 和 IPC 中不得出现私钥或密码。
### 9.3 远程 Helper
远程能力通过版本化 GoodBuddy Helper 提供:
- 使用 SSH exec 或受控通道启动,不依赖字符串拼接 Shell 命令。
- 安装到远程用户级受管目录,不要求 root。
- 上传内容使用固定版本、大小和 SHA-256 校验,临时写入后原子替换。
- 握手报告协议版本、系统、架构和能力。
- 在远程执行路径规范化、Git、文件、PTY、进程组和 Runtime 管理。
- 对事件、日志、文件、帧、超时、并发和总传输量设置上限。
- 断开或租约过期后终止孤儿进程。
首期断线后把活动运行标记为 `interrupted`,撤销短期能力并要求用户重试;在事件序列、租约、
重放和幂等附加完成前,不宣称可以无损恢复。
### 9.4 远程 Runtime
- Runtime 在远程执行空间内运行,不能让本机 Runtime 对远程路径进行伪本地操作。
- Main 保持可信控制面,远程 Helper 只接受有范围、有期限的请求。
- Ask 的只读限制在远程 Helper 和 Runtime 适配层共同强制。
- Execute 继续经过 Runtime 工具策略、审批、取消、超时和审计。
- 模型凭据优先留在 Main,通过仅绑定远程回环的 SSH 隧道和请求级代理提供。
- 不向远程 Runtime 暴露通用本机 MCP、浏览器、文件系统或其他未分配能力。
## 10. Runtime 与进程统一生命周期
需要新增统一、受限的生命周期模型:
```ts
type ManagedLifecycleState =
| 'starting'
| 'running'
| 'waiting_approval'
| 'paused'
| 'stopping'
| 'completed'
| 'failed'
| 'cancelled'
| 'interrupted'
```
每个 Runtime 会话、Job、终端或受管进程公开:
- GoodBuddy 受管 ID。
- 类型、来源和父子关系。
- 执行空间和范围。
- 状态、开始与结束时间。
- 支持的控制动作。
- 有界进度、用量和日志游标。
控制动作按能力声明:
```ts
type ManagedControl =
| 'cancel'
| 'terminate'
| 'force-terminate'
| 'pause'
| 'resume'
| 'reconnect'
| 'release'
```
界面不能因为状态枚举中存在某个动作就假设所有 Runtime 都支持。Main 根据当前受管对象和
能力重新验证动作。
## 11. 数据与契约建议
### 11.1 共享 Zod 契约
建议新增:
- `workbar-contracts.ts`
- `managed-process-contracts.ts`
- `terminal-contracts.ts`
- `remote-host-contracts.ts`
- 通用 Artifact Event 和 Preview 契约
- Runtime Inspector Snapshot 和 Control 契约
所有输入严格限制字符串、数组、日志、帧、路径、端口和事件数量。公开快照不得包含:
- 凭据和认证头。
- 完整环境变量。
- 任意本机或远程绝对路径,除非该路径本身是用户当前可见对象。
- 未经限制的 stdout/stderr、文件或 Runtime 响应。
- 可直接传给系统 kill、spawn、Shell 或 SSH 的自由参数。
### 11.2 持久化
建议增加:
```text
workbar_preferences
remote_hosts
terminal_sessions
managed_processes
runtime_sessions
runtime_jobs
```
其中:
- 工作栏偏好只保存能力目录顺序、面板实例、停靠布局、尺寸和目标引用。
- 主机表只保存非敏感元数据和加密凭据引用。
- 活动终端和进程在应用重启时标记为中断,除非对应远程租约可验证恢复。
- 日志使用有界环形缓冲或分页持久化,不能无限写入 SQLite。
- Artifact 继续作为成果的权威实体,不把完整成果复制进工作栏状态。
- 当前 Renderer `localStorage` 活动记录不能作为 Runtime、监督或进程的权威来源。
### 11.3 IPC 与 Preload
Renderer 只通过显式方法访问:
- 工作栏偏好和目标绑定。
- 主机 CRUD、测试和 Host Key 确认。
- 终端创建、输入、调整大小、关闭和有界输出订阅。
- 受管进程列表、日志和允许的控制动作。
- Runtime Inspector 快照、事件和允许的控制动作。
- 工作区、成果、浏览器、监督和上下文的既有或扩展服务。
每个 Main Handler 都必须验证可信发送者、Zod 输入、对象归属和当前状态。不得暴露 raw
Electron、ChildProcess、PTY、SSH Client、Socket 或文件句柄。
## 12. 安全边界
1. 工作栏能力目录项和面板实例不授予任何能力;权限只由 Main 中的范围和控制契约产生。
2. Ask 在本机和远程 Runtime 边界保持只读。
3. Execute 继续经过现有 Runtime 和审批控制,工作栏不能直接放宽。
4. 用户终端和 Agent 工具执行使用不同身份和事件来源。
5. 进程面板只控制 GoodBuddy 受管对象,不接受任意 PID。
6. 本机和远程路径分别在对应文件系统上 canonicalize 并验证符号链接边界。
7. HTML 默认静态、无脚本、无网络、无 Electron API。
8. Supervisor 不接收授权回调,不能批准工具或替用户发送消息。
9. SSH Host Key 必须固定,凭据保留在 Main 加密存储。
10. 远程端只获得请求级、可撤销、最小范围能力。
11. 关闭面板或切换目标、主机或 Runtime 时,旧订阅必须取消;其他固定实例的订阅明确保留。
12. 通知、徽标和日志不得包含密钥、私人正文或未脱敏提供商响应。
## 13. 状态、错误和恢复
每个面板实例区分:
- 尚未选择目标。
- 目标为空。
- 正在连接或加载。
- 正常可用。
- 部分可用。
- 当前能力不支持。
- 连接失败。
- 权限不足或只读。
- 目标已失效。
- 操作已取消或中断。
错误必须保留用户选择、终端缓冲、输入草稿、范围和可重试上下文。短期成功和非局部错误使用
应用通知;预览失败、终端断线、Host Key 变化、监督证据失效等需要本地恢复的错误留在面板
内。同一事件不得同时重复显示为面板警告和应用通知。
## 14. 性能与资源边界
- 工作栏关闭或面板实例关闭时停止对应非必要画面和高频日志推送,但保留 Main 中的受管运行。
- 每个打开的面板实例只订阅其跟随或固定目标,不进行全局无界监听。
- 终端和日志使用增量序号、环形缓冲和背压。
- HTML、文件、目录、浏览器画面和远程传输沿用或收紧现有大小限制。
- Runtime Snapshot 与事件流分离,重新打开时先取权威快照,再接增量事件。
- 监督使用独立低优先级并发池和预算,不延迟前台回答。
- 应用退出时停止新操作,取消订阅,关闭终端、隧道和 Helper,并在期限内标记未完成对象。
## 15. 无障碍与响应式
- 能力目录、所有面板实例、目标选择器、终端控制和进程操作可用键盘完成。
- 能力目录与面板标题具有稳定可访问名称,徽标不是唯一状态信号。
- 终端需要独立可访问说明,并允许关闭动画和声音提示。
- 进程和 Runtime 高频日志不逐行进入实时区域,只播报重要状态变化。
- 监督证据定位后将焦点移动到对应对象,并提供返回监督记录的方式。
- HTML iframe 有明确标题、静态安全说明和源码替代视图。
- 窄窗口下能力目录仍完整可达,不因空间不足隐藏能力。
- 文字缩放到 200% 时,当前目标、执行空间、风险状态和停止操作不能被裁切。
## 16. 分阶段实施
### 阶段 0:应用级工作栏壳层
- 将当前聊天专属右栏提升为应用级壳层。
- 建立稳定能力目录和用户打开、关闭、排序、停靠的面板实例模型。
- 建立实例级跟随、固定和失效目标语义。
- 保留现有任务中心、上下文、工作区、浏览器和成果行为。
- 将 Task Center 明确为 Task 的单例索引,并补齐范围、状态、最近进展、需要关注和直接打开 Conversation。
- 审批在所属任务或 Runtime 中持续可见,不新增独立审批面板。
- 智能心跳菜单入口承接完整配置和范围后,再从任务中心移除重复表单;不得移除任务中心本身。
### 阶段 1:成果与 Runtime 可观测性
- 通用 Artifact Event。
- HTML 工作区和成果的静态即时预览。
- Runtime Inspector Snapshot 与事件。
- OpenCode 会话、子会话、Todo、工具、用量和取消。
- 直连模型及现有 GoodBuddy Subagent 的统一展示。
### 阶段 2:监督、终端与受管进程
- 普通会话手动监督和右栏评论流。
- 本机 PTY 终端。
- 受管进程注册、日志和终止。
- 自动回复后监督、节流和独立预算。
- 用户选择终端停靠位置。
### 阶段 3Runtime 原生长期能力
- Continue 会话级 Host。
- Continue Background Job、Subagent 和 Hook 的有界适配。
- DeepSeek Harness 后续服务的能力握手。
- Runtime Job、Workflow 和会话恢复契约。
### 阶段 4:SSH 主机与远程执行空间
- 主机管理、加密凭据和 Host Key 固定。
- Linux x64/arm64 Helper 安装与握手。
- 远程工作区、Git、终端和受管进程。
- 远程 Runtime 执行、取消、超时和审计。
- 首期断线明确标记中断,不承诺恢复。
### 阶段 5:恢复与扩展
- 远程租约、事件重放和幂等重连。
- 更多远程系统和架构。
- PDF、Office 和数据成果预览。
- Conversation、Task/Job Run 和实验的完整监督。
- 用户可导入导出工作栏布局和主机非敏感配置。
## 17. 验收标准
### 17.1 稳定能力目录与用户控制
- [ ] 九个标准能力在所有主要页面的目录中始终可发现,但不会默认同时打开。
- [ ] Task Center 继续作为 Task 的单例索引,不删除入口、不复制会话,也不混入 Job、Run 或心跳事项。
- [ ] 项目、会话、Runtime 或主机变化不会无提示地增删能力目录项。
- [ ] 用户可以按需打开、关闭、排序和停靠面板实例。
- [ ] 用户可以独立设置每个可绑定目标的面板实例跟随或固定目标,并为同一能力打开多个目标实例。
- [ ] 固定目标失效后显示修复状态,不静默切换。
- [ ] 后台事件不会无条件打开面板或抢占用户当前实例。
- [ ] 用户可一键恢复标准能力目录和默认的少量打开面板。
### 17.2 通用使用
- [ ] 没有项目时仍可创建终端、选择工作区、打开浏览器和查看成果。
- [ ] 监督可以作用于普通 Conversation、Task、Job/Run 和后续实验对象,不假设编程语境。
- [ ] 工作区不是 Git 仓库时仍可浏览文件。
- [ ] Runtime 不支持某项原生能力时仍可从目录打开面板并获得准确说明。
### 17.3 安全与控制
- [ ] Renderer 没有任意文件、Shell、进程、PTY、SSH 或 Electron API。
- [ ] Agent 不能未经授权向用户终端注入命令。
- [ ] 进程面板不能枚举或终止任意系统进程。
- [ ] Ask 在本机和远程执行空间均无法调用写入或外部副作用工具。
- [ ] HTML 预览无法执行脚本、联网、打开窗口、提交表单或访问 Electron API。
- [ ] Supervisor 不能自动发送消息、批准工具、切换工作模式或扩大范围。
- [ ] SSH 首次连接和 Host Key 变化均经过明确验证流程。
- [ ] 凭据不进入 Renderer、日志、SQLite 明文或命令参数。
### 17.4 生命周期与恢复
- [ ] Runtime、终端、Job 和进程具有权威 Main 快照和有序增量事件。
- [ ] 取消、终止、失败、断线和应用退出都有确定终态。
- [ ] 切换跟随目标后不显示上一对象的过期状态。
- [ ] 固定目标的订阅在页面切换后保持,关闭时正确释放。
- [ ] 日志、终端、文件、成果和远程传输均有明确上限和背压。
### 17.5 可用性
- [ ] 宽、中、窄窗口均可访问完整能力目录和用户打开的面板实例。
- [ ] 仅使用键盘可以选择能力、面板实例、目标、执行空间和控制动作。
- [ ] 状态不只依赖颜色,徽标具有文字或可访问名称。
- [ ] 终端、HTML、监督证据和高频日志具有可访问替代或降噪行为。
## 18. 相关文档的职责
- 本文是助手工作栏稳定能力目录、用户面板实例、范围控制和执行空间的产品总契约。
- [Task 与 Job 统一领域模型](../task-and-job/task-and-job-model.md) 定义 Task、Conversation、
Job、Subjob、Run 与 Subagent。
- [Task Center PRD](../task-and-job/task-center-prd.md) 定义应用级 Task 索引。
- [智能心跳 PRD](../smart-heartbeat/smart-heartbeat-prd.md) 定义心跳入口、范围和长期边界。
- [会话监督 PRD](../supervision/conversation-supervision-prd.md) 定义监督判断、证据、预算和介入边界。
- [自动化平台总体设计](../../architecture/automation-platform-architecture.md) 定义 Plan、Job、Run、监督、预算和记忆。
- [长期助手路线图](../../roadmap/long-term-assistant-roadmap.md) 记录整体长期能力与实施背景。
- [DeepSeek Harness Runtime 设计](../../architecture/deepseek-harness-runtime-design.md) 定义该 Runtime 的具体适配边界。
- [统一界面设计系统](../../../UI-DESIGN.md) 定义视觉、语义、响应式和无障碍规则。
若其他文档把工作栏描述为九个同时固定显示的栏目、根据项目或 Runtime 自动裁剪的动态入口,
或仅属于当前聊天的附属区域,以本文“能力目录稳定、面板实例由用户打开、当前上下文只提供
默认值”的产品决策为准。
@@ -0,0 +1,788 @@
# 远程消息通道项目与微信 ClawBot 集成 PRD
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 状态 | 已实施,待真实微信账号联调 |
| 版本 | 1.4 |
| 日期 | 2026-08-09 |
| 适用产品 | GoodBuddy 桌面端 |
| 首期范围 | 微信 ClawBot、企业微信、钉钉的通道项目;微信文字、图片和文件 Ask 与 Execute |
## 1. 背景
GoodBuddy 已将企业微信、钉钉和微信 ClawBot 远程消息通道纳入系统管理的通道项目。该信息架构解决了早期通道仅存在于设置页和后台服务中,远程消息进入任务系统后无法持续、明确识别以下信息的问题:
1. 消息来自哪个平台。
2. 当前正在与哪个发送者或群聊对话。
3. 远程执行任务使用哪个工作目录。
4. 执行请求、处理后端、工具调用和结果归属于哪个范围。
腾讯官方微信 ClawBot 使用扫码授权,不使用 App ID 或 Secret,并由本机独立 Sidecar 持续运行通信服务。文字、图片和文件收发、只读对话与受控执行已经实现;真实微信账号的认证媒体端到端联调仍作为发布前手动验收。
为避免把通道来源、发送者身份和执行范围混在一起,本功能使用“通道项目 + 远程会话”的两级结构:
- 通道项目标识平台并确定默认工作目录、处理后端和默认模式。
- 远程会话标识具体发送者或群聊。
- 消息记录具体发送者和本次实际使用的模式。
- 运行记录覆盖任务执行、工具调用和结果。
## 2. 已确认的产品决策
1. 微信 ClawBot、企业微信、钉钉分别对应一个系统管理的通道项目。
2. 三个通道项目在通道设置服务初始化时幂等创建,不等待用户完成连接配置。
3. Renderer 不直接创建通道项目。Main 进程保证项目存在,设置卡片首次展示时即可引用对应项目。
4. 通道项目默认根目录为当前操作系统用户目录。
5. 同一通道中的不同私聊用户或群聊分别建立独立远程会话。
6. 微信 ClawBot 首期支持个人微信私聊中的文字、图片和文件;语音和视频后续支持。
7. 微信卡片可以配置默认“对话”或“执行”模式。
8. “对话”映射为 GoodBuddy `Ask`;“执行”映射为 `Execute`
9. 每个通道项目默认使用“模型连接”中的默认直连文本模型,也可以显式选择其他直连文本模型、OpenCode 或 Continue。选择 OpenCode/Continue 时,通道只保存 Runtime 类型,并在每次远程请求开始时动态跟随“Agent Runtime”中的对应全局配置,不维护第二套模型来源或 Runtime 配置。
10. 远程 Execute 不显示通道专属请求级或逐工具确认;收到合法消息后立即按所选后端运行。
11. 任务仍受工作目录上下文、Runtime 能力、Ask/Execute 边界、能力开关、直连模型工具安全策略和活动审计约束;Agent Runtime 工具使用当前用户权限。
12. 停用或断开通道不得删除通道项目、远程会话、任务、活动或成果历史。
13. 通道项目由系统管理,用户不能永久删除;用户可以修改其工作目录、处理后端和默认模式。
## 3. 目标
### 3.1 用户目标
- 在项目切换器中一眼识别微信、企业微信和钉钉来源。
- 在通道项目中区分不同发送者和群聊。
- 在设置卡片中完成连接、启停、处理后端、模式和工作目录配置。
- 通过微信进行只读问答或发起受控执行任务。
- 选择可信的执行后端,并查看完整执行记录。
- 保留通道关闭前后的历史上下文和审计记录。
### 3.2 产品目标
- 将远程通道纳入 GoodBuddy 现有 Project、Conversation、Task、Activity 和 Artifact 信息架构。
- 复用现有 ChannelService 的白名单、去重、并发、取消和错误脱敏能力;回复长度与分段由各通道适配器按平台能力控制。
- 保持 Electron Main、Preload、Renderer 和不可信子进程之间的安全边界。
- 为后续语音、视频、多账号和更多通道提供稳定扩展点。
## 4. 非目标
首期不包含:
- 微信群聊。
- 微信语音和视频收发。
- 多个个人微信账号同时绑定。
- 通过微信临时扩大工具权限或安全策略。
- 主动群发、营销消息或任意联系人发现。
- 将微信会话自动合并进普通本地会话。
- 删除或迁移现有企业微信、钉钉历史数据。
- 把完整 OpenClaw Runtime 打包进 GoodBuddy。
## 5. 信息架构
### 5.1 项目分组
项目选择器增加“远程通道”分组:
```text
普通项目
├─ 默认项目
└─ 用户创建的其他项目
远程通道
├─ 微信 ClawBot
├─ 企业微信
└─ 钉钉
```
每个通道项目持续显示连接状态:
- 未配置
- 已停用
- 正在连接
- 等待扫码
- 已连接
- 连接失败
通道状态不得只通过颜色表达。
### 5.2 项目、会话和消息关系
```text
通道项目
└─ 远程会话
└─ 消息
└─ 可选任务 / 活动 / 成果
```
职责划分:
| 层级 | 负责内容 |
| --- | --- |
| 通道项目 | 平台、连接状态、默认根目录、处理后端、默认模式 |
| 远程会话 | 平台账号、私聊用户或群聊、连续上下文 |
| 消息 | 具体发送者、本次实际模式、正文、时间和处理状态 |
| 运行记录 | Runtime、工具调用、执行结果和错误 |
### 5.3 会话命名
- 微信 ClawBot:优先使用已绑定用户昵称;不可用时显示“我的微信”。
- 企业微信私聊:优先使用平台显示名,否则显示脱敏发送者 ID。
- 钉钉私聊:优先使用平台显示名,否则显示脱敏发送者 ID。
- 群聊:使用群名称;每条消息仍显示具体发送者。
- 不得把原始 Token、上下文令牌或完整敏感标识作为会话标题。
## 6. 通道项目生命周期
### 6.1 自动创建
应用初始化通道设置服务时,Main 进程执行 `ensureChannelProjects()`
1. 按稳定通道标识查找 `weixin``wecom``dingtalk` 对应项目。
2. 缺失时创建系统管理项目。
3. 已存在时复用,不重复创建。
4. 如果存在同名普通项目,不得按名称占用或修改该项目。
5. 创建失败时保留其他通道可用,并在设置快照中返回有界错误。
默认值:
| 通道 | 项目名称 | 根目录 | 处理后端 | 默认模式 |
| --- | --- | --- | --- | --- |
| `weixin` | 微信 ClawBot | 用户目录 | 默认直连文本模型 | Ask |
| `wecom` | 企业微信 | 用户目录 | 默认直连文本模型 | Ask |
| `dingtalk` | 钉钉 | 用户目录 | 默认直连文本模型 | Ask |
### 6.2 系统管理约束
- 通道项目不能从普通项目危险区永久删除。
- 停用通道不归档项目。
- 断开微信不删除项目和历史。
- 数据迁移或异常导致项目缺失时,下次初始化自动修复。
- 用户可以修改项目根目录、描述、处理后端和默认模式。
- 项目名称首期由系统管理,避免来源名称被改到不可识别;后续如允许自定义,必须持续显示通道徽标。
### 6.3 默认用户目录
通道项目默认使用操作系统用户目录。设置卡片必须显示完整目录,并在首次启用 Execute 时明确说明该范围可能包含桌面、下载、文档和其他私人文件。
如果根目录不存在、不可访问或不是目录:
- Ask 仍可在不读取本地文件的边界内工作。
- Execute 不得启动。
- 设置卡片显示就近错误和“选择目录”操作。
## 7. 设置页产品需求
### 7.1 导航
设置页标签由“企业通信”改为:
- 标题:消息通道
- 说明:微信 ClawBot、企业微信与钉钉
### 7.2 卡片通用结构
三个通道使用与模型设置一致的分段外观页签,并保留
`tablist``tab``tabpanel`、游标焦点和方向键语义。每次只显示一个
通道面板,窄窗口下页签单行横向滚动。
每个通道面板包含:
1. 通道名称和连接状态。
2. 启用开关。
3. 默认工作目录。
4. 消息处理后端。
5. 默认处理模式。
6. 对应通道项目。
7. 平台特有的连接配置。
8. 最近错误或连接状态。
示意:
```text
微信 ClawBot 已连接
已绑定账号:微信用户 ****8a3f
最近收到消息:今天 14:32
启用微信通道 [开关]
默认处理模式
[ 对话 ] [ 执行 ]
默认工作目录
C:\Users\用户名 [选择目录]
消息处理后端
[默认模型 · sonnet-5 v]
通道项目
微信 ClawBot
[断开本机绑定(危险操作)]
```
“对话 / 执行”是互斥状态,应使用语义化分段控件,不使用两个独立复选框。
### 7.3 模式说明
- 对话:只读回答,不调用工具或修改内容。
- 执行:收到合法消息后立即交给所选后端,可在工作目录内调用已启用工具。
每个通道面板持续显示风险说明,不弹出一次性确认。默认 Ask 时也要说明白名单
发送者仍可通过 `/execute` 临时执行:
```text
远程消息可能要求 GoodBuddy 读取或修改默认工作目录中的内容。
执行消息会立即交给所选后端,不再逐次弹窗确认。
请只连接可信账号,并将工作目录限制在必要范围。
默认工作目录:
C:\Users\用户名
```
### 7.4 消息处理后端
每个通道项目提供相同的后端选择,不提供含义不明确的“自动”选项:
- 直连模型:默认选择“模型连接”中的默认文本连接;列出已配置的文本模型连接,不列出仅支持图像生成的连接。
- OpenCode:使用当前 OpenCode Runtime,并动态跟随“Agent Runtime”中的全局 OpenCode 模型来源、自有配置、程序路径和服务地址。
- Continue:使用当前 Continue Runtime,并动态跟随“Agent Runtime”中的全局 Continue 模型来源、自有配置和程序路径。
选择持久化在通道项目上。旧版本保存的 `auto` 选择在启动时迁移为当前默认
直连文本模型。模型连接删除、改为图片模型或凭据失效后,优先修复为默认或
首个可用文本模型;没有可用文本模型时,UI 明确提示用户完成模型配置或改选
Agent Runtime。OpenCode/Continue 的通道项目只持久化 `provider`,旧版残留的
通道级 `profileId` 在修复时移除;全局 Agent Runtime 配置变更从下一条远程
请求开始生效。远程会话记录通道项目的逻辑后端选择,不复制全局配置或凭据。
Execute 启动前检查解析后的后端是否支持工具执行,并返回可处理的配置错误。
通道面板的后端说明必须明确显示“跟随 Agent Runtime 全局配置”,不得在消息
通道设置中重复展示 OpenCode/Continue 的模型来源、自有配置文件或程序路径。
“Agent Runtime > 高级设置”中的来源选项、条件配置卡和后续路径字段保持
`12px` 区块间距,不能出现卡片边框贴合或内容归属不清。
### 7.5 通道项目会话界面
通道项目是系统管理的远程消息范围,不允许创建普通本地会话:
- 切换到通道项目时,只显示由对应客户端消息创建的远程会话。
- 隐藏“新建对话”和 `Ctrl+N` 提示;收到全局新建会话命令时不创建记录。
- 尚无远程会话时显示等待首条客户端消息的空状态和设置入口。
- 旧版本误建在通道项目中的普通本地会话不参与通道会话列表,但保留其数据。
- 远程会话底部说明客户端联动方式,只显示历史、任务和执行结果,不再提及已移除的审批流程。
- “运行记录”的“任务与会话”视图按“项目 → 任务或会话 → 活动详情”显示远程任务;所有任务或会话首次进入时默认收起,用户可通过原生展开控件查看明细。综合状态以最近一次顶层请求对应的最终 Agent 结果为准,最终结果尚未产生时使用请求当前状态;中间工具或子专家的失败、取消和中断不得覆盖最终成功状态。
### 7.6 微信扫码绑定
未绑定时显示“绑定个人微信”。扫码对话框包含:
- 本地渲染的二维码。
- 扫码和手机确认步骤。
- 二维码剩余有效时间。
- 刷新和取消操作。
- 等待扫码、已扫描、需要验证码、已连接、已过期和失败状态。
二维码过期时不得继续接受旧扫码结果。
需要配对数字时,在同一对话框中显示验证码输入。验证码不得写入日志或持久化。
绑定完成后显示“重新绑定”和“断开本机绑定”。“断开本机绑定”使用共享红色
危险操作样式,并持续说明该操作只清除本机凭据、不保证解除微信服务端授权,
也不删除通道项目、远程会话、任务、活动或成果历史。
### 7.7 企业微信和钉钉
企业微信和钉钉继续使用现有凭据表单、环境变量只读覆盖和连接测试,但增加:
- 通道项目显示。
- 消息处理后端。
- 默认处理模式。
- 默认工作目录。
- 打开通道项目。
现有发送者白名单和群聊提及设置继续有效。
## 8. 远程会话需求
### 8.1 会话创建与复用
收到合法消息后,根据以下稳定键查找会话:
```text
channel + accountId + externalConversationId
```
- 未找到时,在对应通道项目下创建远程会话。
- 已找到时继续使用现有会话。
- 微信私聊的 `externalConversationId` 首期可由绑定账号和发送者稳定标识组成。
- 不得仅按显示名称匹配会话。
- 消息重试不得创建重复会话或重复任务。
### 8.2 新建上下文
首期不提供手动“新建远程会话”入口,也不把通道项目中的全局“新建对话”
命令转为本地会话。客户端首条合法消息按稳定键自动创建远程会话,后续消息
继续复用该会话;未来如增加远程上下文重置命令,需要单独定义协议、去重和
历史保留语义。
### 8.3 展示
最近对话和聊天标题区显示:
- 通道图标和名称。
- 私聊用户或群聊名称。
- 当前连接状态。
- 默认模式。
- 未读状态。
每条远程消息记录实际模式:
- Ask
- Execute
- 执行中
- 已完成
- 失败
收到普通远程消息时不得强制切换当前页面。应增加未读标记和全局通知。
## 9. Ask 与 Execute
### 9.1 模式解析
每条消息的模式按以下优先级确定:
1. 显式 `/ask` 或“对话:”前缀使用 Ask。
2. 显式 `/execute``/exec` 或“执行:”前缀使用 Execute。
3. 没有前缀时使用通道项目的默认模式。
前缀仅用于选择模式,不进入发送给模型的正文。
### 9.2 Ask
- 在 Runtime 边界保持只读。
- 不提供工具授权回调,或所有工具请求返回拒绝。
- 不修改文件、数据库、系统状态或远程状态。
- 结果以有界文字返回原通道并写入远程会话。
### 9.3 Execute
Execute 消息通过身份、长度、去重和并发检查后:
1. 创建并立即启动远程执行任务。
2. 使用通道项目当前保存的逻辑处理后端;OpenCode/Continue 在此时解析“Agent Runtime”中的对应全局配置。
3. 将项目根目录作为本次 Runtime 工作目录。
4. 所选后端不支持工具执行时,不启动任务,并返回设置修复说明。
远程 Execute 不创建 GoodBuddy 通道专属请求确认或逐工具确认。安全边界由
发送者白名单、私聊限制、项目根目录上下文、所选 Runtime、工作模式边界、能力开关和工具
安全策略共同提供。UI 必须持续说明该行为,不能让用户误以为仍会弹窗确认。
通道只回传最终结果或可操作的失败信息,不发送“执行已开始”等无操作价值的
中间状态消息。
### 9.4 工具控制
不同后端按现有行为运行:
- OpenCode 和 Continue 使用各自的工具系统与能力检查,并以 GoodBuddy 客户端当前用户权限运行。
- 直连模型只可调用已启用的内置工作区工具及已分配 MCP 工具。
- “Execute 自动授权已启用的工具”策略无需逐次确认;“禁止所有工具执行”策略拒绝所有直连模型工具调用。
- 平台不提供 Runtime OS 沙箱模式;Ask 的只读边界和各 Runtime 工具策略继续有效。
- 任何工具结果都进入现有任务和活动审计。
### 9.5 结果回传
- 成功:回传有界文字结果。
- 当前任务生成的图片可以随最终结果回传;用户明确要求文件时,将当前任务的
有界文本结果生成为 Markdown 附件。
- 失败:回传经过脱敏、长度受限的用户可处理错误。
- 取消:回传“任务已取消”。
- 结果投递失败时保留发件箱记录并显示通道错误,不重复执行任务。
### 9.6 媒体与文件
- 单条微信消息最多接收或发送 4 个附件,解密后合计不超过 12MB。
- 入站仅处理官方图片和文件消息项。Sidecar 下载腾讯 CDN 内容并完成
AES-128-ECB 解密,Main 只接收有界字节、文件名、MIME 和大小。
- 图片进入现有视觉上下文;文本、代码、PDF 和 Office 文件进入现有不可信
文档上下文。不支持的类型显示可处理提示,不把原始 CDN 地址或密钥传给 Runtime。
- 入站附件元数据和有界预览写入远程会话,原始字节作为任务处理期间的临时上下文。
- 出站生成图片必须来自当前任务的 `generated-image` 事件。
- 出站文件只能由 Main 根据当前任务的最终文本结果生成,不接受 Runtime 路径,
不读取或发送任意现有工作区文件。
- 媒体发件箱在成功投递或达到重试上限后清除二进制负载。
## 10. 微信 ClawBot 通信架构
### 10.1 进程边界
微信通信运行在独立 Node Sidecar 中:
```text
微信
↕ 腾讯 iLink HTTPS / CDN
微信 Sidecar
↕ 严格、有界、可验证的进程协议
Main ChannelDriver
ChannelService
GoodBuddy Runtime 与工具安全策略
```
禁止:
- 在 Renderer 中加载微信通信代码。
- 向 Renderer 暴露 Token、上下文令牌或原始腾讯响应。
- 把腾讯插件直接加载进 Electron Main。
- 运行 `openclaw-weixin-cli` 安装器。
- 仅为微信通道打包完整 OpenClaw。
### 10.2 Sidecar 能力
- 获取和刷新二维码。
- 轮询扫码状态。
- 提交一次性验证码。
- 加载内存中的加密解封凭据。
- 长轮询文字、图片和文件消息。
- 从腾讯 CDN 有界下载并解密图片和文件。
- 调用 `getuploadurl`,加密上传当前任务图片和文件,并发送媒体回复。
- 保持会话 `context_token` 和同步游标。
- 有界重试、退避、停止和异常退出。
### 10.3 协议扩展
现有 `wechat-sidecar-protocol.ts` 需要拆分为两个方向:
Sidecar 到 Main
- `status`
- `qr`
- `verification_required`
- `connected`
- `inbound_message`,可包含有界图片或文件
- `reply_result`
- `fatal_error`
Main 到 Sidecar
- `start_login`
- `submit_verification`
- `start_account`
- `reply`,可包含有界图片或文件
- `cancel_reply`
- `disconnect`
- `shutdown`
所有消息使用严格 Zod Schema、版本号、最大长度和关联 ID。协议拒绝未知字段。Token、Cookie、Session 和上下文令牌不得出现在普通状态或消息事件中。
## 11. 凭据与网络安全
### 11.1 凭据
- 微信 bot token 使用 Electron `safeStorage` 加密后保存在 Main 管理的设置文件。
- 上下文令牌由 Sidecar 运行时持有;如需跨重启保存,必须由 Main 加密持久化。
- 凭据不得出现在命令行参数、普通环境变量、stdout、Renderer IPC、通知或错误消息中。
- Sidecar 通过私有继承管道接收本次运行所需凭据。
- 安全存储不可用时不能完成微信绑定或启用通道。
### 11.2 网络
- 扫码入口固定为已审核的腾讯 HTTPS 主机。
- 服务端返回的 API 主机和重定向主机必须通过腾讯主机允许列表验证后才能携带 Token 请求。
- 不允许明文 HTTP 发送微信凭据。
- 全局“内网兼容模式”不得放宽微信凭据端点的 HTTPS 和主机验证。
- Sidecar 使用独立环境允许列表并显式启用证书验证,不继承
`NODE_TLS_REJECT_UNAUTHORIZED=0`、代理变量、Node 加载钩子或提供商凭据。
- 日志中的 URL 移除查询字符串,响应体对 Token 和上下文令牌脱敏。
- 媒体下载和上传只允许腾讯微信 HTTPS 主机,所有重定向逐跳重新校验。
- CDN 响应按流读取并在解密前后分别执行硬字节限制,不信任 `Content-Length`
文件名、MIME、扩展名或服务端声明的原始大小。
### 11.3 断开与解绑
产品区分:
- 停用:停止收发,保留本地绑定凭据。
- 断开本机绑定:停止收发并清除本地凭据;入口使用红色危险操作样式。
- 微信端解除绑定:只有腾讯提供并验证服务端撤销能力后才可承诺。
当前不得把本地清除描述为“已在微信端彻底解绑”。断开后保留通道项目、
远程会话、任务、活动和成果历史。
## 12. 数据与契约建议
### 12.1 Project
为项目增加可向后兼容的来源字段:
```ts
type ProjectKind = 'user' | 'channel'
type ProjectChannel = 'weixin' | 'wecom' | 'dingtalk'
```
通道项目包含:
- `kind: 'channel'`
- `channel`
- `runtimeSelection`
- 稳定且唯一的通道绑定
现有项目迁移为 `kind: 'user'`。不得通过项目名称推断通道。
### 12.2 Conversation
增加远程会话映射,至少包含:
- `conversationId`
- `projectId`
- `channel`
- `accountId`
- `externalConversationId`
- `conversationType`
- 脱敏显示名
- 创建和最近消息时间
唯一约束:
```text
channel + accountId + externalConversationId
```
### 12.3 Channel Settings
通道公开设置增加:
- `projectId`
- `defaultWorkMode`
- `runtimeSelection`
- `rootPath`
- `status`
微信私有设置增加加密字段:
- bot token
- bot/account ID
- 绑定用户 ID
- 经验证的 API base URL
Renderer 快照只返回是否已配置和脱敏标识。
### 12.4 任务来源
远程任务保留:
- 通道项目 ID。
- 远程会话 ID。
- 通道。
- 脱敏发送者。
- 实际工作模式。
- 实际消息处理后端。
任务队列可以复用 delegation 调度分类,但 UI 和活动审计必须依据通道项目与
远程会话持续显示真实通道来源,不得呈现为普通本地任务。
## 13. IPC 与 Preload
建议增加窄接口:
- 获取通道设置快照。
- 保存通道项目配置。
- 开始微信扫码。
- 刷新微信扫码。
- 提交微信验证码。
- 断开微信本地连接。
- 订阅微信连接状态。
- 打开对应通道项目。
所有 IPC
- 使用共享 Zod Schema 验证。
- 验证可信 Renderer sender。
- 不接收 Renderer 提供的项目类型或通道身份作为可信事实。
- 不返回凭据。
## 14. 关键异常流程
### 14.1 项目重名
存在名为“微信 ClawBot”的普通项目时,仍创建独立通道项目,并通过通道类型而非名称识别。UI 可以显示同名,但必须有“远程通道”分组和微信徽标。
### 14.2 通道项目缺失
如果数据库异常或旧版本操作导致绑定项目缺失,Main 初始化时重新创建并修复设置引用。历史会话无法安全迁移时保留原归属并给出诊断,不静默丢弃。
### 14.3 连接中退出
- 取消二维码轮询。
- 清除内存验证码。
- 停止 Sidecar。
- 不保存未确认凭据。
### 14.4 执行期间断线
通道断开后不得启动新的 Execute。已开始的任务按现有取消策略处理,结果进入本地审计;恢复连接后不得自动重复执行。
### 14.5 重复消息
使用稳定平台消息 ID 去重。平台消息 ID 缺失时,使用账号、会话、发送者、时间和内容摘要构造有界稳定键。任务创建和回复必须共用同一个去重声明。
## 15. 可访问性与响应式
- 通道状态同时使用文字和图标。
- 三个通道使用共享 `PageTabs``segmented` 外观,保留页签语义和方向键切换。
- 模式选择使用语义化单选/分段控件和方向键。
- 消息处理后端使用持久标签和分组选项,并说明当前选择的实际行为。
- 二维码提供状态文字和备用刷新操作,但不把敏感二维码链接作为可复制文本。
- 验证码错误与输入框建立 `aria-describedby` 关联。
- 关闭对话框后焦点返回触发按钮。
- 窄窗口下卡片单列,二维码对话框保留 16px 外边距。
- 浅色、深色和 200% 文字缩放下可完成绑定、后端选择和保存。
## 16. 验收标准
### 16.1 通道项目
- [ ] 新安装首次启动后存在微信 ClawBot、企业微信和钉钉三个通道项目。
- [ ] 重启应用不会重复创建通道项目。
- [ ] 同名普通项目不会被占用或修改。
- [ ] 通道项目默认根目录为当前用户目录,默认模式为 Ask。
- [ ] 通道项目在项目选择器的“远程通道”分组中显示。
- [ ] 停用或断开通道不会删除项目和历史。
- [ ] 普通项目删除流程不能永久删除通道项目。
### 16.2 设置卡片
- [ ] 设置标签显示为“消息通道”。
- [ ] 三个通道使用与模型设置一致的分段外观页签,并保留完整页签键盘语义。
- [ ] 三个面板均显示项目、根目录、消息处理后端、默认模式和连接状态。
- [ ] 微信卡片可以完成扫码、过期刷新、验证码和连接状态展示。
- [ ] “断开本机绑定”使用共享红色危险操作样式,并明确说明只清除本机凭据、不删除历史或承诺服务端解绑。
- [ ] 不显示“自动”后端;首次创建和旧版 `auto` 配置均落到默认直连文本模型。
- [ ] 直连模型只列出文本连接,OpenCode 与 Continue 可直接选择。
- [ ] 选择 OpenCode/Continue 时只保存 Runtime 类型,每次远程请求动态跟随“Agent Runtime”中的对应全局配置,通道页不出现第二套 Runtime 配置。
- [ ] Agent Runtime 高级设置的来源选项、条件配置卡和路径字段之间保持 `12px` 间距且无横向溢出。
- [ ] 默认 Execute 时持续显示目录范围和无逐次确认的风险说明。
- [ ] Renderer 无法读取任何微信 Token 或上下文令牌。
### 16.3 会话
- [ ] 不同通道的消息进入不同通道项目。
- [ ] 不同发送者或群聊进入独立远程会话。
- [ ] 重复平台事件不会创建重复会话、消息或任务。
- [ ] 最近对话、聊天标题和消息均能识别通道与发送者。
- [ ] 收到普通消息不会强制切换当前页面。
- [ ] 切换到通道项目不会创建普通本地会话。
- [ ] 通道项目隐藏“新建对话”和 `Ctrl+N`,全局快捷命令也不创建会话。
- [ ] 没有远程会话时显示等待客户端首条消息的空状态。
- [ ] “运行记录”的任务或会话分组默认收起;综合状态使用最近一次顶层请求的最终 Agent 结果,中间工具或子专家失败不得覆盖最终成功状态。
- [ ] 微信图片和文件显示在对应远程消息中,附件消息无需附带文字。
- [ ] 支持的附件进入所选后端现有图片或文档上下文;不支持和超限附件返回明确提示。
### 16.4 Ask
- [ ] 普通消息默认按卡片配置进入 Ask。
- [ ] Ask 在 Runtime 边界拒绝所有工具。
- [ ] 有界结果回传原通道并写入远程会话。
### 16.5 Execute
- [ ] 默认 Execute 或显式执行前缀会立即使用通道项目所选后端。
- [ ] 不显示通道专属请求级或逐工具确认。
- [ ] 直连模型、OpenCode 和 Continue 均按各自能力正确路由。
- [ ] 通道不发送“执行已开始”等中间占位消息,只发送最终结果或可操作失败。
- [ ] 任务使用对应通道项目根目录。
- [ ] Runtime、工作模式边界、能力和直连模型工具安全策略继续生效。
- [ ] 任务、活动、工具、成果和最终结果关联到通道项目与远程会话。
### 16.6 生命周期与安全
- [ ] Sidecar 异常退出不会导致 Main 崩溃,并有有界重启限制。
- [ ] 应用退出会取消长轮询并停止 Sidecar。
- [ ] 微信凭据使用系统安全存储加密。
- [ ] 任何普通日志、IPC、错误和通知中不存在凭据。
- [ ] Token 只发送到已审核的腾讯 HTTPS 主机。
- [ ] CDN 下载、上传和每次重定向只访问腾讯微信 HTTPS 主机。
- [ ] 入站和出站媒体最多 4 个、合计不超过 12MB,AES 密钥和 CDN URL 不跨越 Sidecar 边界。
- [ ] 只有当前任务生成图片或 Main 从本次最终文本生成的文件可以作为出站附件。
## 17. 实施阶段
### 阶段一:通道项目基础
- Project 数据迁移与通道类型。
- 三个通道项目幂等创建。
- 项目选择器“远程通道”分组。
- 三张设置卡片接入项目、目录和模式配置。
- 企业微信、钉钉消息建立独立远程会话。
### 阶段二:微信文字通道
- 微信 iLink Sidecar。
- 扫码、验证码、加密凭据和生命周期。
- 微信文字收发与稳定去重。
- 微信远程会话。
- Ask 模式。
### 阶段三:受控 Execute
- 通道项目处理后端选择与失效修复。
- OpenCode/Continue 通道后端动态跟随全局 Agent Runtime 配置。
- Execute Runtime 接入。
- 直连模型工具安全策略和活动关联。
- 结果回传、取消、超时和失败恢复。
### 阶段四:微信媒体
- 图片和文件 CDN 下载、AES 解密与有界上下文。
- 生成图片和 Main 生成的任务结果文件加密上传与回复。
- 远程会话附件展示和媒体发件箱清理。
### 阶段五:后续扩展
- 有界语音和视频。
- 多微信账号。
- 更细的项目路由。
- 已验证的微信端解除绑定。
## 18. 测试要求
至少覆盖:
- 数据迁移和通道项目幂等创建。
- 同名普通项目隔离。
- 设置 Schema 与 Renderer 脱敏快照。
- QR 状态机、过期、验证码和非法转换。
- Sidecar 双向协议未知字段、超长字段和凭据泄漏拒绝。
- 腾讯主机允许列表和重定向校验。
- CDN 媒体 AES 加解密、流式大小限制、声明大小校验和恶意重定向拒绝。
- 附件持久化展示、现有上下文接入、生成图片回传和任务成果目录隔离。
- 消息去重、会话映射、并发和取消。
- Ask 工具拒绝。
- Execute 使用直连模型、OpenCode 和 Continue 的路由。
- OpenCode/Continue 通道只保存 Runtime 类型,并在 Ask 与 Execute 开始时解析当前全局 Agent Runtime 配置。
- Execute 不创建通道专属审批,直连模型禁止工具策略仍然生效。
- 模型连接删除后的通道后端选择修复。
- 发件箱投递失败不重复执行。
- 项目选择器、分段页签、后端选择、设置面板和扫码对话框的键盘与无障碍行为。
- Runtime 高级设置区块间距、微信断开危险按钮和任务活动默认折叠的 UI 回归。
- Windows、macOS、Linux 的默认用户目录和 Sidecar 关闭行为。
实现完成后运行:
```text
npm test
npm run typecheck
npm run lint
npm run build
```
## 19. 发布条件
满足以下条件后才可默认向用户提供微信 Execute:
1. 微信文字 Ask 全流程稳定。
2. UI 明确说明远程 Execute 会立即运行,且默认工作目录和处理后端始终可见。
3. 凭据不会进入 Renderer、日志或普通子进程参数。
4. Sidecar 网络目标和重定向已实施严格允许列表。
5. 通道项目和远程会话的来源标识在所有入口持续可见。
6. 任务重复投递不会导致重复执行。
7. 应用退出、断线和更新过程中不会留下失控执行,直连模型禁止工具策略不能被远程来源绕过。
8. 腾讯 iLink 独立宿主使用范围和本地断开语义已完成发布前确认。
@@ -0,0 +1,331 @@
# 文档解析与本地 OCR
## 1. 目标
GoodBuddy 需要用同一条可信文档解析链路服务以下场景:
- 聊天附件问答;
- 知识库导入、同步、分块与来源定位;
- 后续的合同审阅、表格分析、演示文稿理解和文档转换。
文档解析不是对话模型的附属功能。它是主进程管理的独立基础能力,设置入口为“设置中心 / 文档解析”。
## 2. 当前基线
原生解析器已经支持:
- UTF-8 文本、代码、配置、HTML;
- 带文本层的 PDF
- DOCX 正文;
- XLSX 工作表 XML 与共享字符串;
- PPTX 幻灯片文字。
现有局限:
- 纯扫描 PDF 没有文本层时无法提取内容;
- DOC、XLS、PPT 等旧版二进制 Office 格式不支持;
- Office 解析主要提取文字,不能完整保留表格、公式、图表和版面;
- 聊天附件和知识库直接调用底层解析函数,缺少可配置的统一工作流;
- 没有本地 OCR 模型状态、真实解析测试和按场景策略。
## 3. 产品原则
### 3.1 双通道解析
PDF 不是所有文档唯一的中间格式。解析应同时保留:
1. 原生语义通道:标题、段落、单元格、公式、备注和对象关系;
2. 渲染视觉通道:页码、版面、图表、图片和 OCR 结果。
两条通道合并为统一文档结构。转换为 PDF 用于补充视觉信息,不得覆盖更可靠的原生语义结果。
### 3.2 场景工作流
| 场景 | 默认预设 | 行为 |
| --- | --- | --- |
| 聊天附件 | 自动解析 | 优先快速提取,文本不足时按需 OCR,有界截断后加入当前请求 |
| 知识库导入 | 完整索引 | 完整解析、按页或工作表定位、按需 OCR、分块与索引 |
| 扫描文档 | OCR | 页面渲染、文字识别、置信度与定位保留 |
| 表格分析 | 语义优先 | 单元格和值优先,PDF 或图片补充图表与打印布局 |
| 高保真审阅 | 视觉增强 | 原生解析、页面渲染、OCR 或视觉理解合并 |
### 3.3 本地优先
- 文本层和本地 OCR 均在设备上处理;
- 本地处理不因 Ask 或 Execute 模式改变;
- OCR 来源必须在“本地模型 / 远程服务”之间明确选择;
- 配置并保存远程服务即表示用户选择该处理路径,不再增加逐场景授权;
- API 密钥只能保存在主进程加密设置中;
- 测试文件不得自动进入聊天或知识库。
## 4. 设置设计
设置中心新增“文档解析”分类,结构如下:
1. 分类页头:“测试解析”“保存设置”;
2. 运行状态:原生解析、文档转换、本地 OCR;
3. 使用场景:聊天附件、知识库导入;
4. 文档转换;
5. OCR 识别;
6. 高级解析设置;
OCR 模型区沿用语音模型管理模式:
- 应用不内置模型权重;
- 用户按需从 ModelScope 下载,下载完成后离线使用;
- 显示来源、语言、运行时、模型体积、安装与校验状态;
- 联网设备可导出已安装模型 ZIP,离线或内网设备可直接导入;
- 支持下载进度、取消、删除、ZIP 导入导出、打开模型仓库和受管目录;
- “打开 ModelScope”直接显示在 OCR 模型卡片右上角,不使用手动导入折叠区;
- 模型操作即时生效,解析策略仍通过分类页头的“保存设置”提交。
### 4.1 第一阶段字段
- 聊天附件预设:`auto``fast-text``high-fidelity`
- 知识库预设:`complete-index``fast-index``high-fidelity`
- PDF OCR 策略:`auto``always``disabled`
- OCR 来源:第一阶段固定为 `local`,远程服务入口禁用;
- 本地 OCR 模型:`pp-ocrv6-tiny``pp-ocrv6-small``pp-ocrv6-medium`
- 单文档最大页数;
- OCR 并发数;
- 单页超时。
OCR 来源使用互斥选择。本地模型选中后才显示模型下拉列表、按需下载、导入和本地 OCR 参数;远程服务计划接入 MinerU、PaddleOCR-VL 等接口,第一阶段保持可读但禁用。来源选择本身就是用户的明确决策,不再显示额外的“隐私与云端处理”授权区。
## 5. 架构
```text
聊天附件 ─┐
├─ DocumentParsingService
知识库导入 ┘ ├─ NativeDocumentParser
├─ PdfTextQualityEvaluator
├─ PdfPageRenderer
├─ LocalOcrProvider
├─ DocumentConversionProvider
└─ ParsedDocument merger
```
`DocumentParsingService` 是唯一场景入口:
```ts
type DocumentParsingPurpose = 'chat-attachment' | 'knowledge-index'
type DocumentParsingService = {
parse(
name: string,
bytes: Buffer,
purpose: DocumentParsingPurpose,
signal?: AbortSignal
): Promise<ParsedDocument>
}
```
聊天上下文管理器与知识库服务依赖该接口,不直接选择 OCR Provider。
## 6. 统一结果
第一阶段兼容现有 `ParsedDocument`,并逐步扩展:
```ts
type ParsedDocument = {
title: string
sourceFormat: string
content: string
sections: Array<{
locator: string
content: string
method?: 'native' | 'ocr' | 'converted' | 'vision'
confidence?: number
}>
warnings?: string[]
}
```
定位字段必须对使用者有意义:
- PDF`第 3 页`
- XLSX`工作表:预算 / A1:F28`
- PPTX`幻灯片 5`
- DOCX:标题路径或页码;
- 文本:`全文`
## 7. 本地 OCR 基线
### 7.1 模型与运行时
全平台功能基线:
- 模型:PP-OCRv6 ONNX/ORT
- 轻量下载档位:Tiny,约 6 MiB,用于低资源设备和六平台离线链路;
- 推荐下载档位:Small,约 30 MiB,官方支持 50 种语言;
- 高精度下载档位:Medium,约 132 MiB,官方支持 50 种语言,但识别较慢且需要更多内存;
- 运行时:ONNX Runtime WebAssembly
- 处理环境:隔离 Worker
- 加速:WebGPU 或平台原生执行 Provider,仅作为可选层;
- 回退:任何加速失败后使用 WASM CPU。
需要覆盖的发布矩阵:
- Windows x64、Windows arm64
- macOS x64、macOS arm64
- Linux x64、Linux arm64。
模型清单必须固定以下信息:
- 上游仓库和不可变 revision;
- 文件名、字节数和 SHA-256
- 模型族、语言、质量和速度;
- 许可证名称、完整许可证和来源;
- 检测模型、识别模型、字符字典的匹配关系。
运行时不得从 `main``latest` 或其他可变地址加载模型。
### 7.2 下载与安装
Tiny、Small 和 Medium 模型均由 PaddlePaddle 官方 ModelScope 仓库提供。Small 是默认推荐档位;Medium 面向更高识别质量,但具有更高内存占用和延迟。每个档位的检测模型、识别模型与字符字典配置分别使用固定提交,并在应用内记录文件字节数和 SHA-256。
下载流程:
1. 主进程从固定 ModelScope `resolve/<revision>/...` 地址读取文件;
2. 禁用凭据与缓存,限制重定向次数和单文件大小;
3. 写入受管目录下的随机临时安装目录;
4. 边下载边计算 SHA-256,并核对完整字节数;
5. 三个文件全部通过校验后写入安装清单;
6. 原子重命名为正式模型目录;
7. 失败、取消或退出时删除临时文件。
模型只在下载或用户显式打开仓库时访问网络。OCR 推理从受管目录读取已校验文件,不发起网络请求。
### 7.3 离线 ZIP 迁移
语音模型和 OCR 模型使用同一种离线迁移流程:
1. 联网设备完成受信任来源下载和校验;
2. 在模型卡片选择“导出 ZIP”;
3. 将 ZIP 通过组织批准的介质传输到离线或内网设备;
4. 在相同模型的卡片选择“导入 ZIP”;
5. 主进程按当前应用内置目录重新校验,并在全部通过后原子安装。
ZIP 根目录包含模型文件和 `goodbuddy-model.json`。清单格式为 `goodbuddy-model-archive`,当前版本为 `1`,记录:
- 模型类型:`speech``document-ocr`
- 内置模型 ID 和显示名称;
- 文件名、角色、原始字节数和 SHA-256;
- 导出时间。
导出不能直接信任已有安装清单,必须重新读取并校验每个文件。导入不能只信任 ZIP 自声明内容,模型 ID、文件角色、字节数和哈希必须再次与当前应用内置目录完全匹配。导入通过后复用普通本地安装的受控临时目录和原子重命名路径。
归档处理使用有界流式读写,不把大型模型或整个展开结果复制到内存。主进程限制压缩包大小、条目数、清单大小、单文件大小和总展开大小,并拒绝:
- 绝对路径、`..`、目录或嵌套路径;
- 大小写不敏感的重复条目;
- 未声明、缺失或角色不匹配的文件;
- 模型类型或模型 ID 不匹配;
- 解压后大小或 SHA-256 不匹配;
- 超过边界的压缩包和压缩炸弹。
取消文件对话框不会改变安装状态。导入和导出也不会切换当前语音/OCR 模型,不会隐式保存文档解析设置。
### 7.4 PDF 流程
1. 使用 PDF.js 读取每页文本层;
2. 评估有效字符数、乱码率和图片占比;
3. `auto` 模式只渲染文本不足的页面;
4. `always` 模式渲染所有页面;
5. Worker 将页面限制在配置的最大边长内;
6. OCR 返回文字、坐标和置信度;
7. 按页合并原生文本与 OCR,不重复可靠文本;
8. 达到页数、超时、取消或输出限制时停止并返回明确错误。
受密码保护、损坏或超限的 PDF 不得进入 OCR。
## 8. Office 与转换
### 8.1 新格式
- DOCX:正文、标题、表格、批注和图片关系;
- XLSX:工作表、单元格地址、值、公式、合并关系和图表;
- PPTX:幻灯片、文字对象、备注、图片和阅读顺序。
Office 内嵌图片 OCR 属于增强流程,不能替代原生结构解析。
### 8.2 旧格式
DOC、XLS、PPT 通过 `DocumentConversionProvider` 转换:
1. 转换为 DOCX、XLSX 或 PPTX,供语义解析;
2. 转换为 PDF,供页码、版面和视觉解析;
3. 合并结果并记录转换警告。
本地 LibreOffice Provider 必须:
- 在隔离子进程中运行;
- 禁用宏和网络;
- 使用单任务临时目录;
- 限制输入大小、输出大小、内存和超时;
- 在成功、失败、取消和退出时清理;
- 不接受用户提供的任意命令参数。
## 9. 安全边界
- 文件路径解析、读取、大小检查和格式校验在主进程完成;
- OCR Worker 只接收当前任务所需的有界页面图像和只读模型;
- 不向 Worker 暴露文件系统、Electron API、凭据或任意网络访问;
- 文档内容视为不可信数据,不解释其中的提示词为系统指令;
- 模型和转换程序必须固定版本并校验哈希;
- OCR 输出受字符数限制,错误不得包含绝对路径或未脱敏文档内容;
- 取消、超时和应用关闭必须终止待处理页面并释放模型会话。
## 10. 错误与回退
必须区分:
- 不支持的格式;
- 文档损坏或受密码保护;
- 文本层为空但 OCR 未启用;
- OCR 模型不可用;
- OCR 超时或取消;
- 文档页数、大小或输出超限;
- 本地转换服务未配置;
- 所选远程 OCR 服务不可用或配置不完整。
`auto` 工作流可以从 OCR 回退到可靠的原生文本,但不能把空结果标记为成功。知识库导入失败时保留来源和可重试上下文。
## 11. 实施阶段
### 阶段一
- 新增文档解析设置分类和持久化契约;
- 建立 `DocumentParsingService`,供聊天和知识库共用;
- 将无文本 PDF 识别为可触发 OCR 的明确状态;
- 接入 PP-OCRv6 Tiny、Small、Medium 的 ModelScope 下载、校验、ZIP 离线迁移、删除与 WASM Worker
- 实现真实文件测试和六平台验证入口。
### 阶段二
- 增强 DOCX、XLSX、PPTX 语义结构;
- 实现按页混合文本层与 OCR
- 增加版面、表格和阅读顺序。
### 阶段三
- 增加 LibreOffice 和 API 转换 Provider
- 支持 DOC、XLS、PPT
- 增加 MinerU、PaddleOCR-VL 等远程 OCR 服务连接配置;
- 增加高保真工作流和解析结果预览。
## 12. 验收
- 同一份扫描 PDF 可从聊天附件和知识库得到一致的逐页文本;
- 文本型 PDF 在 `auto` 模式下不运行 OCR
- 本地 OCR 在六个平台和两种架构上完全离线运行;
- 模型文件损坏时拒绝加载并显示可恢复错误;
- 未安装模型时扫描文档提示用户前往“文档解析”下载,文本型文档仍可原生解析;
- 下载中可显示文件与总进度并允许取消,失败或取消后不留下已安装状态;
- ModelScope 下载与 ZIP 导入均经过同一大小和 SHA-256 校验;
- 语音和 OCR 模型可在联网设备导出 ZIP,并在离线设备导入后完成真实推理;
- 路径穿越、未知条目、错误模型 ID、篡改文件和超限 ZIP 均被拒绝;
- 超页数、超时、取消和关闭不会留下运行任务;
- 测试解析不会创建聊天消息或知识库文档;
- 选择本地模型时没有任何文档上传;
- 文档中的提示词不会改变系统、模式或工具权限。
@@ -0,0 +1,388 @@
# 并行实验工作台 PRD
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 状态 | 设计中 |
| 版本 | 0.1 |
| 日期 | 2026-08-13 |
| 依赖 | [自动化平台总体设计](../../architecture/automation-platform-architecture.md)、[Task 与 Job 统一领域模型](../task-and-job/task-and-job-model.md) |
## 1. 背景
GoodBuddy 已能把一个请求并行委派给最多三个只读专家,再综合结果。这适合“一次请求,
多种专业视角”,但不等同于实验:当前没有结构化变量、重复运行、统一指标、结果晋升和
Run 级记忆隔离。
本功能借鉴 MesaLogo ParallelLab 中变量隔离、批量 Run、失败结算、指标比较和运行证据
的思想,但不引入其 Action Space、服务端队列或重型仿真平台。
## 2. 产品定义
并行实验是在冻结的研究问题和执行协议下,生成多个相互隔离的候选 Run,以相同评估标准
比较结果,并将结论追溯到运行证据。
```text
Experiment
├─ Question / Hypothesis
├─ Protocol
├─ Variables and Variants
├─ Objectives and Evaluators
├─ Budget and Stop Conditions
└─ ExperimentRun × N
├─ Isolated Conversation
├─ Isolated Run Memory
├─ Tasks and Artifacts
├─ Metrics
└─ Evidence
```
## 3. 已确认的产品决策
1. 实验 Run 复用现有 Task、Runtime、Artifact 和审批机制。
2. 每个 Run 有独立变量、会话、运行记忆、任务和成果。
3. 默认实验是只读 Ask;写工作区的实验后续使用每 Run 独立沙箱。
4. 多个 Run 不能并发修改同一个用户工作区。
5. 失败、取消、预算耗尽或结果不完整的 Run 不参与最佳结果选择。
6. 没有成功 Run 时实验为失败或无结论,不能报告成功。
7. 模型生成的实验协议必须可审查、编辑和版本化。
8. 评估优先使用确定性指标;模型 Rubric 显示评估器版本和不确定性。
9. “最佳”只针对声明的目标和约束,不代表普遍最好。
10. 最佳结果只能创建候选,不能直接覆盖计划、记忆或工作区。
## 4. 目标
- 把问题转为可审查的实验问题、变量、候选和指标。
- 比较不同提示、模型、专家组合、参数或方案。
- 监控每个 Run 的状态、成本、证据和失败原因。
- 查看结果表、差异、稳定性和评估依据。
- 从候选创建普通任务、计划草稿或记忆候选。
- 为持续学习提供回放和非退化评估基础。
## 5. 非目标
- 第一阶段不模拟数千 Agent 或社会群体涌现。
- 不实现任意连续参数的自动贝叶斯优化。
- 不在样本不足时宣称统计显著性。
- 不把模型的自报置信度直接作为跨模型比较指标。
- 不允许实验自行增加样本数、预算或能力范围。
- 不允许自动部署结果或修改安全策略。
- 不把专家团队的一次回答自动包装成科学实验。
## 6. 实验类型
| 类型 | 变量示例 | 用途 |
| --- | --- | --- |
| Prompt 对比 | 系统说明、输出格式、示例 | 比较自动化协议 |
| 模型对比 | 已配置文本模型 | 质量、速度和 Token 权衡 |
| 专家组合 | 专家集合、综合策略 | 多视角研究 |
| 参数扫描 | 检索模式、Top K、轮数 | 寻找有限参数组合 |
| 方案候选 | 多个用户或模型方案 | 按统一 Rubric 比较 |
| 回放评估 | 历史脱敏案例集合 | 验证学习候选是否退化 |
后续多轮情景模拟需要单独定义角色、环境和状态变量。
## 7. 创建流程
### 7.1 研究问题
用户填写:
- 实验名称。
- 问题和可选假设。
- 探索、比较、优化或回放验证类型。
- 项目范围。
- 期望输出。
- 禁止行为。
### 7.2 协议
`ExperimentProtocol` 包含:
- 基准输入或案例集。
- 固定提示和步骤。
- 变量与候选。
- Runtime、模型和专家。
- 工具、知识库和记忆范围。
- 工作模式。
- 每 Run 预算。
- 指标、评估器和停止条件。
- 重复次数。
模型生成协议草稿时必须标明用户字段、模型建议、确定性指标和模型判断指标。
### 7.3 变量
```ts
type ExperimentVariable =
| { name: string; type: 'enum'; values: JsonValue[] }
| {
name: string
type: 'range'
start: number
end: number
step: number
}
| { name: string; type: 'boolean' }
| { name: string; type: 'prompt_variant'; values: string[] }
| {
name: string
type: 'model_profile'
profileIds: string[]
}
| {
name: string
type: 'expert_set'
expertIdSets: string[][]
}
```
第一阶段只支持有限、确定生成的组合。保存前展示组合数、重复后 Run 总数、最大模型调用、
Token 和耗时范围,以及最大并发。超过上限时要求缩小变量,不静默抽样。
### 7.4 基准与候选
- 至少一个 Variant。
- 对比实验建议设置 Baseline。
- Baseline 与 Candidate 使用相同案例和评估器。
- 评估器不能读取 Variant 标签和模型名称作为质量信号。
- 模型评分时随机化候选顺序并保存实际顺序。
## 8. Run 隔离
### 8.1 数据隔离
每个 Run 独立拥有:
- `experimentRunId` 和运行会话。
- 变量快照和临时上下文。
- Run 记忆分区。
- Task、Job、Subjob 和成果。
- 指标、证据和 Runtime 会话标识。
禁止:
- Run A 读取 Run B 的消息、临时记忆或中间成果。
- 多个 Run 共享可变变量对象。
- Run 候选记忆在实验结算前进入其他 Run。
- 通过全局列表误取其他项目或实验数据。
### 8.2 工作区隔离
阶段 1 只支持 Ask 和只读工具。阶段 2 的 Execute Run 使用独立临时沙箱或版本化工作树,
结果以 Patch 或成果展示,用户选择候选后再进入单独应用流程。
### 8.3 记忆隔离
Run 只读取冻结的 Global、Project、Automation 记忆快照和自己的 Run 分区,
不读取其他 Run 或实验期间新产生的候选记忆。
## 9. 调度与预算
- 默认最大并发 3,与现有子专家调度能力一致。
- 还需遵守全局后台并发和模型连接并发。
- 每个 Variant 使用相同的单 Run 预算。
- 不因候选暂时领先而静默给它更多预算。
- 提前停止必须来自预先声明的规则。
- UI 显示运行、排队、成功、失败和取消数量。
停止条件:
```ts
type ExperimentStopCondition =
| { type: 'all_runs_terminal' }
| { type: 'successful_run_count'; count: number }
| {
type: 'metric_threshold'
metric: string
operator: string
value: number
}
| { type: 'budget' }
| { type: 'deadline'; at: string }
| { type: 'manual' }
```
触发停止后不启动新 Run;是否取消正在运行的 Run 必须在条件中明确。保存停止原因,
未运行 Variant 不参与最终比较。
## 10. 评估与指标
### 10.1 指标类型
| 类型 | 示例 |
| --- | --- |
| 确定性结果 | Schema 有效、测试通过、文件存在、检查项完成 |
| 运行指标 | 耗时、模型调用、Token、工具调用、成果大小 |
| 检索指标 | 召回、引用覆盖、降级状态 |
| 人工评分 | 正确性、可用性、偏好 |
| 模型 Rubric | 结构、完整性、表达、风险 |
### 10.2 模型 Rubric
必须保存 Rubric 版本、评估模型、输入证据摘要、候选展示顺序、分项得分、结构化理由和
格式修复。它不能覆盖确定性失败,也不能在缺少证据时编造事实正确性判断。
### 10.3 多目标
```ts
type ExperimentObjective = {
metric: string
direction: 'maximize' | 'minimize' | 'target'
weight?: number
target?: number
hardConstraint?: boolean
}
```
结算先排除非成功和违反硬约束的 Run,再计算其余指标。存在明显权衡时展示 Pareto 候选,
不强行选唯一最佳。
## 11. 结算规则
Run 成功要求:
- Runtime 正常结束。
- 必填成果存在。
- 必填评估器成功。
- 未违反硬约束。
- 没有结果未知的副作用。
Experiment 结算:
| 情况 | 状态 |
| --- | --- |
| 至少一个成功 Run,所需 Run 已结算 | `completed` |
| 所有 Run 失败或无有效结果 | `failed` |
| 提前停止且已有可比较结果 | `stopped_with_results` |
| 提前停止且无可比较结果 | `cancelled` |
| 指标冲突或证据不足 | `inconclusive` |
最佳结果展示 Variant、参数、成功和失败数量、重复运行原始值与聚合、目标分项、硬约束、
证据和限制。只有一个成功 Run 时使用“当前最高分候选”,不使用“稳定最佳”。
## 12. 重复与复现
- 每个 Variant 默认重复 1 次,波动敏感实验建议至少 3 次。
- 重复 Run 使用相同变量和独立运行会话。
- Runtime 支持种子时保存种子,否则明确标注不可完全复现。
- 聚合展示原始值、中位数或均值,并说明计算方式。
- 样本不足时不展示统计显著性结论。
## 13. 会话监督接入
Supervisor 可以检查偏离协议、遗漏必填输出、证据不足和候选间协议不一致;
确定性预算或权限违规可以暂停 Run,模型判断默认只警告或请求人工复核。
Supervisor 不能:
- 根据其他候选结果提示当前 Run。
- 临时修改某个候选协议。
- 自动提高预算或批准工具。
## 14. 信息架构
实验工作台页签:
1. **设计**:问题、协议、变量、指标和预算。
2. **运行**:总体进度、Run 表和状态。
3. **比较**:指标表、图表、差异和 Pareto 候选。
4. **证据**:按结论、指标和 Run 查看证据。
5. **结论**:总结、限制和后续操作。
Run 详情展示参数、协议版本、时间线、消息、任务、成果、监督记录、指标、评估理由、
上下文和记忆快照、Token、耗时与错误。
## 15. 后续操作
允许:
- 用候选参数创建普通任务。
- 创建自动化计划草稿。
- 保存实验模板。
- 创建记忆候选。
- 追加确认 Run。
- 导出脱敏结果摘要。
不得自动启用新计划、覆盖现有计划、确认长期记忆、应用工作区 Patch 或扩大权限。
## 16. 数据模型建议
```ts
type Experiment = {
id: string
projectId?: string
name: string
question: string
status:
| 'draft'
| 'queued'
| 'running'
| 'paused'
| 'completed'
| 'failed'
| 'stopped_with_results'
| 'inconclusive'
| 'cancelled'
protocolVersion: number
totalRuns: number
successfulRuns: number
failedRuns: number
}
type ExperimentRun = {
id: string
experimentId: string
variantId: string
repetition: number
automationRunId: string
variables: Record<string, JsonValue>
status: string
goalStatus: 'met' | 'not_met' | 'inconclusive'
}
```
建议表:
- `experiments`
- `experiment_protocol_versions`
- `experiment_variants`
- `experiment_runs`
- `experiment_run_metrics`
- `experiment_evidence`
- `experiment_conclusions`
## 17. 安全与隐私
1. 协议、案例、输出和评估输入都视为不可信数据。
2. Renderer 不能指定其他项目的 Run 或记忆分区。
3. 每个 Run 使用唯一 Runtime conversation ID,并在结束后释放。
4. 实验默认不能写用户工作区。
5. 模型对比不能传递其他供应商的凭据或隐藏配置。
6. 导出默认不包含完整私人案例、提示、消息或文件内容。
7. 取消实验传播到排队和运行任务,但不伪装撤销已有副作用。
8. 实验删除不能误删已由用户独立保存的成果或计划候选。
## 18. 实施顺序
1. 建立 Experiment、Variant、Run 聚合实体和只读 Ask Run。
2. 实现有限组合、预算估算、并发调度和运行监控。
3. 增加确定性指标、失败结算和结果比较。
4. 增加模型 Rubric、人工评分和证据工作台。
5. 增加重复运行和回放评估。
6. 最后评估独立工作树中的 Execute 实验。
## 19. 验收标准
- [ ] 保存前显示变量组合、重复后 Run 总数和最大预算。
- [ ] 每个 Run 的会话、变量、记忆、任务和成果相互隔离。
- [ ] 默认实验无法写用户工作区。
- [ ] 最大并发和全局后台预算同时生效。
- [ ] 各 Variant 使用相同单 Run 预算。
- [ ] 失败、取消、预算耗尽和不完整 Run 不参与最佳选择。
- [ ] 全部 Run 失败时实验不报告成功或最佳结果。
- [ ] 模型 Rubric 显示版本、模型、分项和证据。
- [ ] 多目标冲突时可以展示多个 Pareto 候选。
- [ ] 用户可从候选创建草稿,但不会自动部署或确认记忆。
- [ ] 结论能追溯到具体 Run、指标、成果和证据。
@@ -0,0 +1,591 @@
# 知识库检索与分块增强 PRD
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 状态 | 实施中 |
| 版本 | 0.1 |
| 日期 | 2026-08-11 |
| 适用产品 | GoodBuddy 桌面端 |
| 实施范围 | 第一阶段:可用、可见、可诊断;第二阶段:可调、可优化、可维护 |
## 1. 背景
GoodBuddy 已具备本地多知识库、文件与目录同步、网页导入、SQLite FTS5、
OpenAI 兼容向量模型、RRF 混合检索、知识图谱、任务状态和来源引用。现有实现
优先建立了本地数据主权、安全边界和跨 Runtime 工具授权,但用户仍难以稳定
获得“导入资料后即可准确问答”的体验。
当前主要问题不是缺少知识图谱,而是基础 RAG 链路缺少完整闭环:
1. 在对话中启用知识库只会开放搜索工具,是否检索仍由模型自行决定。
2. 默认向量检索关闭,中文全文检索对自然语言问法和同义表达的召回不足。
3. 向量请求失败会降级为全文检索,但知识库页面仍可能显示索引完成。
4. 大于 5,000 个向量分块的知识库会跳过向量召回。
5. 用户不能独立测试召回、查看各通道得分或确认实际送入模型的上下文。
6. 分块参数固定,缺少结构化、父子分块、分块预览和人工修正。
7. 引用只能阅读片段,不能查看完整上下文或打开原始来源。
本项目先完成稳定性和可观测性,再增加高级分块、重排与维护能力。知识图谱
继续作为可选召回通道,但不替代全文和向量检索的基础质量。
## 2. 已确认的产品决策
1. 保持本地优先,不引入必须联网的托管知识库服务。
2. 保持 Electron Main、Preload、Renderer 的安全边界,Renderer 不直接读取
数据库、原文件或向量。
3. 保留“模型按需检索”,并新增“每次先检索”模式。后者必须由 Main 进程
预检索,不能只依赖提示词要求模型调用工具。
4. 知识库新建后不默认启用全部已有知识库;对话中的范围继续由用户显式选择。
5. 向量服务不可用时保留全文检索,但必须返回明确降级状态。
6. 中文召回使用应用内可控的 CJK n-gram 索引,不新增远程服务依赖。
7. 混合检索保留 RRF 候选融合,并增加本地确定性重排、可选的
Cohere/Jina 兼容学习型重排、最低相关度和上下文预算。学习型重排失败时
安全降级,不影响全文、向量和图谱召回。
8. 向量搜索取消 5,000 分块静默失效,使用有界内存的分页扫描。在没有稳定
跨平台向量扩展前,接受本地 CPU 线性扫描,并持续显示性能诊断。
9. 向量索引兼容性同时校验 Provider、Model、维度和 Provider Fingerprint。
同名模型切换端点后,旧向量不能继续参与召回。
10. 失败或取消的重建不能停用上一版已就绪索引。新索引只有完整校验成功后才
原子替换当前服务版本。
11. 分块设置属于知识库,修改后不会伪装为立即生效。用户需要显式重建索引。
12. 分块允许预览、编辑、启用、停用和删除。来源再次同步可能覆盖人工修改,
UI 必须在修改前持续说明该行为。
13. 第一阶段和第二阶段均不新增付费或外部模型调用。现有 Embeddings 调用仍由
用户配置决定。
14. Ask 的运行时边界保持只读。知识库内容始终被标记为不可信证据,
不能成为系统指令。
## 3. 目标
### 3.1 用户目标
- 明确知道本次回答是否检索、检索了哪些知识库,以及是否发生降级。
- 在知识库页面输入真实问题,查看命中分块、通道、得分和最终上下文。
- 为不同文档选择适合的分块模式,并在导入前理解影响。
- 查看和修正错误分块,不需要删除并重新导入整个来源。
- 从回答引用查看完整上下文,并打开对应本地文件或网页。
- 在向量、解析或图谱失败时获得可恢复的状态和明确操作。
### 3.2 产品目标
- 默认中文问法在没有向量模型时仍具有可用的关键词召回。
- 向量服务故障、大知识库和模型变更不再产生静默空结果。
- 建立可复现的检索调试入口,支持固定问题进行回归测试。
- 将解析、全文、向量和图谱状态拆分,避免“索引完成”误导。
- 为后续元数据过滤、远程 Rerank Provider 和自动评测保留稳定契约。
### 3.3 质量目标
- 中文同义改写测试集的 Recall@5 相比现有全文检索基线提升至少 30%。
- 检索测试结果必须在本机重复执行时保持稳定排序。
- 任意向量失败都必须在检索诊断或任务状态中可见。
- 10,000 个分块的知识库不得因固定上限返回空向量结果。
- 每条展示引用都能找到仍存在且属于已授权知识库的分块和文档。
- 检索输出和上下文拼装均遵守字符、结果数和 IPC 大小上限。
## 4. 非目标
本项目不包含:
- 团队共享知识库、SSO、SCIM 或跨设备同步。
- 企业级 ACL、文档级角色继承和远程权限同步。
- 云端网站爬虫、Notion、飞书、语雀等第三方连接器。
- MinerU、PaddleOCR-VL 或其他远程文档解析服务。
- 专用向量数据库、外部 Elasticsearch 或打包平台原生向量扩展。
- 托管重排服务账户、计费或供应商绑定;仅提供通用兼容接口配置。
- 自动问题生成、FAQ 生成和训练数据标注平台。
- 完整 RAG 离线评测平台。第二阶段只提供手动检索测试与可导出的诊断信息。
- 在应用内高保真渲染所有原始 Office 和 PDF 文档。
## 5. 竞品基线与 GoodBuddy 定位
截至 2026-08-11Dify、FastGPT 和 RAGFlow 的公开文档均把检索测试、可配置
分块和可调检索参数作为知识库基础能力:
| 能力 | Dify | FastGPT | RAGFlow | GoodBuddy 本期 |
| --- | --- | --- | --- | --- |
| 检索测试 | 支持 | 支持 | 支持 | 第一阶段支持 |
| Top K / 阈值 | 支持 | 支持 | 支持 | 第一阶段支持 |
| 全文 + 向量 | 支持 | 支持 | 支持 | 已有,第一阶段增强中文 |
| Rerank | 模型 Rerank | 模型 Rerank | 模型 Rerank | 本地确定性与可选兼容模型重排 |
| 父子分块 | 支持 | 可通过索引与大分块组合 | 支持多种切分策略 | 第二阶段支持 |
| 分块维护 | 支持内容维护 | 支持数据维护 | 支持块级检查 | 第二阶段支持 |
| 深度文档理解 | 中等 | 中等 | 强 | 继续复用本地解析与 OCR |
| 本地目录监听 | 非核心 | 非核心 | 非核心 | GoodBuddy 差异化能力 |
| 本地可编辑图谱 | 非核心 | 非核心 | 部分版本支持 GraphRAG | GoodBuddy 差异化能力 |
本期不复制竞品的云端工作流平台,而是将其成熟 RAG 交互映射为桌面、本地、
受控的数据链路。
参考公开文档:
- Dify Knowledge
<https://docs.dify.ai/en/use-dify/knowledge/readme>
- Dify 检索测试:
<https://docs.dify.ai/en/use-dify/knowledge/test-retrieval>
- Dify 分块设置:
<https://docs.dify.ai/en/use-dify/knowledge/create-knowledge/chunking-and-cleaning>
- FastGPT 知识库搜索方案和参数:
<https://doc.fastgpt.io/docs/introduction/guide/knowledge_base/dataset_engine>
- RAGFlow Dataset 配置:
<https://ragflow.io/docs/configure_knowledge_base>
- RAGFlow 检索测试:
<https://ragflow.io/docs/run_retrieval_test>
## 6. 信息架构
知识工作区继续使用主从布局和现有四个页签:
```text
知识库
├─ 文档与来源
│ ├─ 来源管理
│ ├─ 检索测试入口
│ ├─ 文档状态
│ └─ 分块查看与维护
├─ 知识图谱
├─ 任务中心
└─ 设置
├─ 检索设置
├─ 分块设置
└─ 图谱设置
```
“检索测试”是当前知识库的高频诊断操作,通过知识库标题区次操作打开独立
工作台,不新增第五个一级页签。
对话输入区的知识范围弹层包含:
1. 已启用知识库多选。
2. 检索方式:模型按需检索、每次先检索。
3. 当前范围为空、索引降级或向量未配置时的短说明。
## 7. 第一阶段:可用、可见、可诊断
### 7.1 检索方式
新增请求级 `knowledgeRetrievalMode`
| 值 | 用户文案 | 行为 |
| --- | --- | --- |
| `auto` | 模型按需检索 | 保留当前 `knowledge_search` 工具,由模型决定是否调用 |
| `always` | 每次先检索 | Main 在启动 Runtime 前使用原始用户问题检索一次,再把有界证据作为不可信上下文提供给 Runtime |
规则:
- 没有启用知识库时不显示为“已检索”。
- `always` 预检索后仍保留 `knowledge_search`,模型可以改写查询再次检索。
- 预检索零结果不阻止回答,但必须显示“已检索,未找到相关内容”。
- 预检索失败不得自动扩大范围或访问未选知识库。
- 图片生成能力不执行知识预检索。
- Ask 和 Execute 使用相同的只读检索范围。
### 7.2 中文全文检索
在现有 `unicode61` FTS 之外增加本地 CJK n-gram 检索文本:
- 连续汉字生成二元词组,保留必要的单字符短查询回退。
- 拉丁字母和数字使用 NFKC、大小写归一化和现有 FTS。
- 多个查询词使用召回优先的 OR 候选,再通过覆盖率和短语命中重排。
- 不把整句中文问题转换成“所有汉字必须同时出现”的条件。
- 索引更新、分块编辑、停用和删除必须同步更新 CJK 索引。
- 数据库迁移必须为已有分块有界回填,不要求用户重新导入。
### 7.3 检索设置
每个知识库保存以下设置:
| 字段 | 范围 | 默认值 |
| --- | --- | --- |
| `topK` | 1 至 20 | 6 |
| `minimumVectorSimilarity` | 0 至 1 | 0(不过滤低相似度结果) |
| `ftsWeight` | 0 至 2 | 1 |
| `vectorWeight` | 0 至 2 | 1 |
| `graphWeight` | 0 至 2 | 0.8 |
| `candidateMultiplier` | 2 至 10 | 4 |
| `contextMaxCharacters` | 2,000 至 48,000 | 16,000 |
| `adjacentChunkCount` | 0 至 2 | 0 |
| `localRerankEnabled` | 布尔值 | false |
至少一个召回通道权重大于 0。图谱未启用时,图谱权重只读显示为不可用。
向量模型未启用或索引不兼容时,向量权重保留但当前请求降级。
### 7.4 检索测试工作台
用户输入最多 4,000 字符的问题,工作台显示:
- 当前知识库和生效设置。
- 总耗时、各通道耗时和候选数。
- 请求通道、实际使用通道和降级原因。
- 最终结果序号、文档、定位、片段和最终相关度。
- FTS、CJK、向量、图谱的独立排名与向量相似度。
- 本地重排前后排名。
- 相邻分块或父块合并后的实际上下文。
- “查看分块”“打开来源”操作。
检索测试不创建聊天消息、不写入会话历史、不调用 LLM,也不改变知识库内容。
### 7.5 可扩展向量搜索
移除“超过 5,000 个候选则返回空结果”的逻辑:
1. 按稳定游标分页读取同一知识库、Provider、Model 和维度的向量。
2. 每批计算余弦相似度。
3. 内存中只保留候选上限所需的最佳结果。
4. 支持取消和应用关闭。
5. 维度、校验和或索引状态不匹配的向量不参与结果。
6. 诊断返回扫描数量和向量耗时。
7. Provider Fingerprint 不匹配时标记索引不兼容,不回退到同名旧模型向量。
线性扫描是本期跨平台保底实现。后续接入稳定向量扩展时不得改变上层契约。
### 7.6 状态与降级
文档状态拆分为:
| 状态 | 含义 |
| --- | --- |
| 解析 | 等待、运行、完成、失败 |
| 全文索引 | 等待、完成、失败 |
| 向量索引 | 未启用、等待、运行、完成、失败、不兼容 |
| 图谱 | 未启用、按需、等待、运行、完成、失败 |
知识库汇总不得仅以“文档 metadata 不是 failed”计算完成。UI 至少显示:
- 可用于全文检索的文档数。
- 已完成向量化的文档数。
- 失败文档数。
- 当前向量模型与索引是否兼容。
降级事件包括:
- 未配置向量模型。
- 查询向量生成失败。
- 当前模型没有匹配索引。
- 部分文档向量失败。
- 图谱关闭或没有证据。
- 结果被相关度或上下文预算过滤。
### 7.7 引用查看
每条引用增加稳定 `chunkId`、最终相关度和检索通道。用户展开引用后可以:
1. 查看命中分块。
2. 查看相邻分块或父块形成的完整上下文。
3. 查看知识库、文档、来源和定位。
4. 对本地文件调用 Main 校验后的 `shell.openPath`
5. 对 HTTP(S) 来源调用 Main 校验后的外部打开。
Renderer 不能提交任意路径或 URL。Main 必须根据 `libraryId``documentId`
`chunkId` 重新读取已保存来源并验证归属。
界面把该列表描述为“本次检索证据”或“已查阅来源”,不把仅被召回的片段
自动宣称为回答中某个句子的精确出处。后续只有经过稳定 Citation ID 校验的
句级标注才能使用更强的“该句引用”语义。
## 8. 第二阶段:可调、可优化、可维护
### 8.1 分块模式
每个知识库选择一种模式:
| 模式 | 行为 | 适用内容 |
| --- | --- | --- |
| 固定分块 | 按目标长度、重叠和自然边界切分 | 普通文本、日志、代码 |
| 结构分块 | 优先保持解析 section、Markdown 标题和段落结构 | 手册、制度、长文档 |
| 父子分块 | 小块用于召回,大块用于模型上下文 | 长篇说明、合同、研究资料 |
设置:
| 字段 | 范围 | 默认值 |
| --- | --- | --- |
| `mode` | `fixed` / `structure` / `parent-child` | `structure` |
| `targetCharacters` | 400 至 8,000 | 1,600 |
| `overlapCharacters` | 0 至目标长度的 40% | 160 |
| `parentCharacters` | 1,600 至 16,000 | 4,800 |
| `childCharacters` | 300 至 4,000 | 900 |
父子分块要求:
- 父块只作为上下文,不进入 FTS、CJK 或向量候选。
- 子块用于召回,并保存父块关联。
- 引用默认突出子块,同时允许查看父块全文。
- 父块和子块总输出仍受上下文预算限制。
### 8.2 本地与学习型重排
第二阶段提供不调用外部模型的可选本地重排。评分特征包括:
- 原始 RRF 排名。
- 中文和拉丁词覆盖率。
- 完整短语命中。
- 文档标题、分块标题和路径命中。
- 向量相似度。
- 同文档重复结果惩罚。
重排结果必须:
- 归一化为 0 至 1 的 `relevance`
- 对相同输入和索引保持确定性。
- 保留重排前排名和各特征得分用于诊断。
- 在关闭时完全保留原有 RRF 排序。
学习型模式使用 Main 进程中的 Cohere/Jina 兼容客户端,凭据只进入加密设置和
Main 进程。请求限制为 100 个候选、每个候选 8,000 字符,并具有 15 秒默认
超时、取消传播和有界响应。失败时可回退本地重排或 RRF,并只返回脱敏诊断。
### 8.3 相邻分块合并与上下文预算
- 对最终候选按文档和 ordinal 合并相邻分块。
- 不把同一分块重复放入上下文。
- 保留每个命中分块的引用定位。
- 按相关度从高到低消耗 `contextMaxCharacters`
- 单个超长父块按安全边界截断并标记 `truncated`
- 不允许低排名结果挤掉已经选中的高排名证据。
### 8.4 分块管理
文档行提供“查看分块”,打开分块管理对话框:
- 显示 ordinal、角色、标题、定位、字符数、启用状态和内容预览。
- 支持分页和文档内搜索。
- 支持编辑内容。
- 支持启用或停用。
- 支持删除,并说明来源同步可能重新创建分块。
- 编辑后更新 FTS 和 CJK 索引,并使旧向量失效。
- 已配置向量模型时,编辑操作完成后为该文档重建向量。
- 删除最后一个可检索分块时,文档显示“无可检索内容”,不能显示完全就绪。
高影响删除使用具体确认文案。普通启停使用共享 Switch,并声明
`role="switch"`
### 8.5 单文档与全库重建
- 单文档重建重新读取来源、解析、分块、全文索引、向量和图谱。
- 全库重建按来源顺序执行,并显示文档级进度。
- 修改分块模式或关键参数后,知识库显示“设置已更新,等待重建”。
- 重建采用文档级原子替换,失败时保留上一版可用分块和向量。
- 用户可以取消全库重建;已经成功替换的文档保持可用。
- 文件不存在、网页失败或 OCR 不可用时保留可重试错误。
- 单来源允许的 2,000 个文件必须全部参与增量同步、删除检测和校验和跳过,
不受普通页面 500 项列表上限影响。
## 9. 数据模型与兼容性
### 9.1 KnowledgeBase
知识库增加版本化设置:
```ts
type KnowledgeRetrievalSettings = {
version: 1
topK: number
minimumVectorSimilarity: number
ftsWeight: number
vectorWeight: number
graphWeight: number
candidateMultiplier: number
contextMaxCharacters: number
adjacentChunkCount: number
localRerankEnabled: boolean
}
type KnowledgeChunkingSettings = {
version: 1
mode: 'fixed' | 'structure' | 'parent-child'
targetCharacters: number
overlapCharacters: number
parentCharacters: number
childCharacters: number
}
```
SQLite 使用 JSON 列保存设置,读写均经过共享 Zod Schema。迁移后的旧知识库使用
与当前行为接近的兼容默认值,不自动重建已有分块。
### 9.2 Chunk
分块增加以下语义:
```ts
type KnowledgeChunkRole = 'standalone' | 'parent' | 'child'
type KnowledgeChunkState = {
enabled: boolean
role: KnowledgeChunkRole
parentChunkId?: string
manuallyEdited: boolean
updatedAt?: string
}
```
实现可以使用显式列或受校验 metadata,但查询必须为旧数据提供默认值:
- 缺少 `enabled` 时视为 `true`
- 缺少 `role` 时视为 `standalone`
- 父块不参与召回索引。
### 9.3 检索响应
```ts
type KnowledgeRetrievalResponse = {
query: string
durationMs: number
settings: KnowledgeRetrievalSettings
diagnostics: {
requestedChannels: KnowledgeRetrievalChannel[]
usedChannels: KnowledgeRetrievalChannel[]
degradedChannels: Array<{
channel: KnowledgeRetrievalChannel
reason: string
}>
candidateCounts: Partial<Record<KnowledgeRetrievalChannel, number>>
}
results: KnowledgeRetrievalResult[]
context: {
characterCount: number
truncated: boolean
groups: KnowledgeContextGroup[]
}
}
```
错误、诊断和引用不得包含 API Key、Authorization Header、完整私人文档或未经
限制的 Provider 响应。
## 10. IPC 与安全边界
新增或扩展的 IPC
- `knowledge:retrieve`
- `knowledge:settings:update`
- `knowledge:document:rebuild`
- `knowledge:library:rebuild`
- `knowledge:chunks:list`
- `knowledge:chunk:update`
- `knowledge:chunk:delete`
- `knowledge:reference:context`
- `knowledge:reference:open`
要求:
- 所有输入由共享 Zod Schema 校验。
- 所有处理器校验可信 Renderer sender。
- ID 必须重新检查知识库、来源、文档和分块归属。
- 列表使用有界分页,单次最多返回 200 个分块。
- 内容编辑限制单块最大字符数。
- 外部打开只接受数据库已保存的本地普通文件或 HTTP(S) URL。
- 不向 Preload 暴露原始数据库、Electron `shell` 或文件系统 API。
- 更新与重建遵守取消、超时、应用关闭和有界错误规则。
## 11. 交互与无障碍
- 复用 `PageTabs``SegmentedControl`、共享 Switch 和应用通知。
- 检索方式是互斥选项,使用 `SegmentedControl` 或语义化单选组。
- 分块启停是持久二元状态,使用 `role="switch"`
- 检索结果列表使用可访问名称,得分不得只用颜色表达。
- 检索工作台打开后焦点进入问题输入框,关闭后返回触发按钮。
- 分块编辑和删除对话框遵守焦点陷阱、Escape 和焦点恢复。
- 异步成功使用应用通知;字段错误、检索进度和可就地恢复错误保留在工作台。
- 窄窗口下检索结果改为单列,配置摘要保持可读,不隐藏降级状态。
## 12. 失败与恢复
| 场景 | 行为 |
| --- | --- |
| 向量查询失败 | 继续全文和图谱检索,显示降级原因 |
| 部分文档无向量 | 使用可用文档,显示完成数和失败数 |
| CJK 索引迁移失败 | 回滚迁移,不损坏旧 FTS |
| 重排失败 | 回退 RRF 排序并显示诊断 |
| 分块编辑后向量失败 | 保留编辑和全文索引,标记向量失败 |
| 单文档重建失败 | 保留上一版可用索引 |
| 同名模型端点变化 | 旧 Fingerprint 索引标记不兼容,等待重建 |
| 新向量重建失败 | 保留上一版就绪向量继续服务,单独记录失败尝试 |
| 原文件已移动 | 显示来源不可用,提供重试或移除 |
| 引用对象已删除 | 显示引用已失效,不打开任意替代路径 |
| 上下文超预算 | 按排名截断并明确标记 |
| 请求取消或应用关闭 | 停止新批次,释放句柄,不留下半替换索引 |
## 13. 埋点与评测
GoodBuddy 不上传私人检索查询或文档内容。本地诊断至少记录有界统计:
- 检索模式。
- 启用知识库数量。
- 各通道候选数和耗时。
- 是否发生降级。
- 最终结果数和上下文字符数。
- 重建文档数、成功数、失败数和取消状态。
手动验收使用仓库内不含私人内容的固定样例集,覆盖:
- 中文自然语言改写和同义词。
- 中英文混合产品名。
- 精确编号、路径和代码标识。
- 多文档冲突信息。
- 无答案问题。
- 10,000 个以上分块。
- 向量服务断开和模型维度变化。
## 14. 实施顺序
### 14.1 第一阶段
1. 共享设置、请求和检索响应契约。
2. SQLite 迁移和 CJK 索引。
3. 可扩展向量扫描、检索诊断和状态模型。
4. 检索设置与工作台。
5. 对话“每次先检索”。
6. 引用上下文和打开来源。
7. 第一阶段单元、IPC 和 Renderer 测试。
### 14.2 第二阶段
1. 结构分块和父子分块。
2. 本地重排与相关度。
3. 相邻块合并和上下文预算。
4. 分块预览、编辑、启停和删除。
5. 单文档与全库重建。
6. 第二阶段回归、性能和生产构建验证。
## 15. 验收标准
### 15.1 第一阶段
- 用户可在对话中选择“模型按需检索”或“每次先检索”。
- “每次先检索”在 Runtime 启动前产生检索诊断和引用,即使模型未调用工具。
- 未配置向量模型时,中文改写问题仍能通过 CJK 索引召回相关分块。
- 向量查询失败时回答可继续,界面明确显示已降级。
- 10,000 个分块的向量测试能够返回正确 Top K,不出现固定上限空结果。
- 同名模型切换端点后,不会读取 Fingerprint 不匹配的旧向量。
- 重建失败时,上一版已就绪向量仍能继续召回。
- 包含 2,000 个文件的目录同步能够处理第 501 至 2,000 个文档的修改与删除。
- 检索测试展示通道、候选数、排名、相关度、上下文和降级原因。
- 引用可以查看完整上下文并打开 Main 校验后的来源。
- 查询长度在共享契约、IPC、MCP 和数据库层保持一致。
### 15.2 第二阶段
- 用户可选择固定、结构或父子分块并显式重建。
- 父块不参与召回,子块命中后可提供父块上下文。
- 本地重排可以开启或关闭,并显示重排前后排名。
- 上下文严格遵守字符预算,重复和相邻片段按规则合并。
- 用户可预览、编辑、启停和删除分块。
- 分块修改后 FTS、CJK 和向量状态保持一致。
- 单文档重建失败不会破坏上一版可用索引。
- 所有新增操作可用键盘完成,并在浅色、深色和窄窗口下可用。
### 15.3 工程验证
所有源代码变更完成后必须通过:
```text
npm test
npm run typecheck
npm run lint
npm run build
```
外部或付费模型调用不属于自动验证,只有获得明确授权后才运行。
@@ -0,0 +1,523 @@
# 知识库检索与分块增强 User Stories
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 状态 | 实施中 |
| 版本 | 0.1 |
| 日期 | 2026-08-11 |
| 关联 PRD | [知识库检索与分块增强 PRD](./knowledge-rag-enhancement-prd.md) |
## 1. 角色
### 1.1 普通知识使用者
已经导入公司制度、产品手册或项目资料,希望直接提问并得到稳定、带来源的回答,
不需要理解向量、RRF 或分块算法。
### 1.2 知识库维护者
负责导入、同步和清理资料,需要知道哪些文档成功、哪些索引失败,以及如何修复
错误解析或错误分块。
### 1.3 RAG 调试者
需要用真实问题验证召回,比较不同参数和通道,定位“文档里有但没有命中”的
原因。
### 1.4 本地与内网用户
不能把资料上传到外部知识库服务,希望全文检索、分块、重排和诊断均在本机
完成,只在显式配置 Embeddings 后发送有界文本。
## 2. Epic A:明确控制是否检索
### US-A1 模型按需检索
作为普通知识使用者,我希望保留由模型判断是否需要检索的模式,以便一般闲聊
不会产生不必要的知识搜索。
验收:
- Given 当前启用了至少一个知识库并选择“模型按需检索”
- When 用户发送问题
- Then Main 只向本次请求开放已选知识库的只读搜索能力
- And 模型没有调用知识搜索时,不显示虚假的“已检索”
- And 未选中的知识库不可被工具参数扩大范围
### US-A2 每次先检索
作为普通知识使用者,我希望选择“每次先检索”,以便模型不能跳过已启用的
知识库。
验收:
- Given 当前启用了至少一个知识库并选择“每次先检索”
- When 用户发送文本问题
- Then Main 在 Runtime 启动前使用原始问题执行一次有界检索
- And 命中证据以不可信上下文进入 Runtime
- And 模型仍可通过只读工具执行后续改写检索
- And 页面明确显示“已预检索”“零结果”或“已降级”
- And 图片生成请求不执行知识预检索
### US-A3 请求级范围
作为普通知识使用者,我希望每次请求只使用我勾选的知识库,以免不相关资料
干扰回答。
验收:
- 新建知识库后只新增该知识库到当前选择,不自动重新启用已取消的知识库
- 删除知识库后从当前范围中移除对应 ID
- 同一请求最多启用 20 个知识库
- 对话输入区持续显示已选数量和检索方式
- 范围为空时检索方式不产生误导状态
## 3. Epic B:检索可见、可诊断
### US-B1 打开检索测试
作为 RAG 调试者,我希望在当前知识库直接输入问题并测试,以便不通过聊天模型
也能验证索引。
验收:
- 知识库标题区提供“测试检索”次操作
- 工作台打开后焦点进入查询输入框
- 查询最多 4,000 字符
- 测试不创建聊天消息、任务成果或模型调用
- 关闭工作台后焦点返回触发按钮
### US-B2 查看通道诊断
作为 RAG 调试者,我希望看到每种检索通道的结果和降级原因,以便判断问题来自
全文、向量还是图谱。
验收:
- 结果显示请求通道和实际使用通道
- 结果显示 FTS/CJK、向量和图谱候选数
- 结果显示总耗时和有界通道耗时
- 向量未配置、请求失败或索引不兼容时显示明确原因
- 不在错误或诊断中显示 API Key、Authorization 或完整文档
### US-B3 查看排名与上下文
作为 RAG 调试者,我希望看到候选排名、最终相关度和送入模型的上下文,以便
解释最终回答为什么使用这些资料。
验收:
- 每条结果显示文档、定位、片段和最终排名
- 可用时显示全文、向量、图谱独立排名和向量相似度
- 启用本地重排后显示重排前排名
- 展示相邻块或父块合并后的上下文
- 展示上下文字符数、预算和截断状态
### US-B4 零结果诊断
作为普通知识使用者,我希望零结果时获得具体原因,而不是只有空列表。
验收:
- 区分“知识库为空”“索引不可用”“查询无命中”“被阈值过滤”
- 提供修改关键词、检查状态或调整阈值的下一步说明
- 零结果不显示为首次使用空状态
- 检索测试保留原查询和设置,方便再次执行
## 4. Epic C:中文与混合检索
### US-C1 中文自然语言召回
作为中文用户,我希望不用输入原文中的连续短语,也能找到表达相同意思的内容。
验收:
- 中文索引生成连续二元词组
- 中文查询不会要求所有不同汉字同时出现
- 短查询具有有界单字回退
- 中英文、数字和产品标识混合查询仍能召回
- 相同查询和索引产生稳定排序
### US-C2 向量服务降级
作为本地与内网用户,我希望向量服务断开时仍可使用全文搜索,同时清楚知道
语义召回不可用。
验收:
- 查询向量失败不阻止 FTS/CJK 和图谱检索
- 检索响应包含向量降级原因
- 文档状态不把向量失败显示成全部完成
- 同名模型切换端点后,Fingerprint 不匹配的旧向量不得参与召回
- 重建失败时,上一版已就绪向量继续服务
- 修复配置并重建后,降级状态消失
- 故障信息经过脱敏
### US-C3 大知识库向量检索
作为知识库维护者,我希望超过 5,000 个分块后语义搜索仍然工作。
验收:
- 向量分批扫描没有固定 5,000 分块空结果
- 只保留所需最佳候选,内存不会随全库候选等比例增长
- 扫描支持取消和应用关闭
- 10,000 个以上分块的测试返回正确 Top K
- 诊断显示扫描数量与耗时
### US-C4 大目录完整同步
作为知识库维护者,我希望包含 2,000 个文件的目录也能完整增量同步,以免后半
部分文档长期保留旧内容。
验收:
- 第 501 至 2,000 个文档参与校验和比较
- 未变化文档不会重复解析和向量化
- 已删除文件对应文档会被移除
- 页面分页上限不影响后台同步完整性
### US-C5 调整召回参数
作为 RAG 调试者,我希望调整 Top K、最低相关度和通道权重,以便适配不同知识
类型。
验收:
- Top K、阈值、候选倍数和权重具有明确范围和默认值
- 至少一个召回通道权重大于 0
- 图谱关闭时图谱权重不可生效并说明原因
- 设置持久化到当前知识库,不影响其他知识库
- 非法输入不能跨 IPC
## 5. Epic D:真实索引状态
### US-D1 查看分阶段状态
作为知识库维护者,我希望分别看到解析、全文、向量和图谱状态,以便准确判断
文档能否使用。
验收:
- 文档不再用单个“ready”代表所有索引完成
- 全文完成但向量失败时,明确显示“全文可用、向量失败”
- 向量未启用与向量失败是不同状态
- 图谱按需、未启用和失败是不同状态
- 汇总显示全文可用数、向量完成数和失败数
### US-D2 修复失败文档
作为知识库维护者,我希望单独重建失败文档,而不是重新同步整个目录。
验收:
- 文档行提供“重建文档”
- 重建重新执行解析、分块、全文、向量和图谱
- 失败时保留上一版可用索引
- 完成后更新任务和状态
- 原文件不存在时保留可重试错误
### US-D3 修改设置后重建
作为知识库维护者,我希望分块设置修改后明确提示需要重建,以免误以为旧文档
已经使用新设置。
验收:
- 保存关键分块设置后显示“等待重建”
- 设置保存本身不删除现有索引
- 用户可选择全库重建
- 全库重建可取消
- 已成功替换的文档继续可用
## 6. Epic E:高级分块
### US-E1 固定分块
作为知识库维护者,我希望配置目标长度和重叠,以便处理日志、代码或简单文本。
验收:
- 目标长度为 400 至 8,000 字符
- 重叠不超过目标长度的 40%
- 优先在自然边界切分
- 每个块保留来源 section、定位和 ordinal
- 旧知识库迁移后不自动改变已有分块
### US-E2 结构分块
作为知识库维护者,我希望分块尽量保持标题和段落结构,以便命中片段保留语义。
验收:
- 优先保持解析 section
- Markdown 标题能够成为分块 heading
- 标题随子段落进入索引元数据
- 超长 section 仍按有界规则继续切分
- 空标题和空段落不创建分块
### US-E3 父子分块
作为 RAG 调试者,我希望小块负责准确召回、大块负责完整上下文,以便兼顾精度
和完整性。
验收:
- 父块和子块具有稳定关系
- 父块不直接进入 FTS/CJK/向量候选
- 子块命中后可返回父块上下文
- 引用突出实际命中的子块
- 父块输出仍受上下文预算和截断限制
## 7. Epic F:重排与上下文
### US-F1 本地重排
作为本地与内网用户,我希望在不调用外部模型的情况下改善候选排序。
验收:
- 本地重排默认关闭并可按知识库开启
- 使用 RRF、词覆盖、短语、标题、路径、向量和重复惩罚等确定性特征
- 结果相关度归一化到 0 至 1
- 检索测试显示重排前后排名
- 关闭时保持原 RRF 行为
- UI 不把本地算法描述为 AI Rerank 模型
### US-F1.1 学习型重排
作为需要更高排序质量的用户,我希望可选择兼容的学习型重排模型,并在服务
不可用时继续获得本地结果。
验收:
- 模式明确区分关闭、本地规则和学习型重排
- Main 最多发送 100 个候选,每个候选不超过 8,000 字符
- API Key 仅通过环境变量或 Main 加密存储使用,不进入 Renderer
- 超时、无效响应和服务错误回退本地重排,并显示脱敏诊断
- 用户取消和应用关闭必须终止请求,不得按普通降级吞掉
### US-F2 相邻分块合并
作为普通知识使用者,我希望命中片段包含必要的上下文,而不是孤立半句话。
验收:
- 可配置向前、向后相邻 0 至 2 个块
- 只合并同文档且 ordinal 连续的启用分块
- 同一块不会重复输出
- 每个原命中仍保留引用定位
- 合并结果遵守上下文预算
### US-F3 上下文预算
作为普通知识使用者,我希望低质量内容不会挤占模型上下文。
验收:
- 按最终相关度从高到低选择上下文
- 已选择的高排名证据不会被低排名证据替换
- 超预算时明确标记截断
- 预算范围为 2,000 至 48,000 字符
- IPC 和 Runtime 输入继续受总大小限制
### US-F4 上下文索引
作为知识库维护者,我希望检索可以利用文档结构,而引用仍忠于原文。
验收:
- 可按知识库启用上下文索引,并在修改后提示显式重建
- 标题、标题层级、页码和块类型使用有界确定性前缀进入 FTS、CJK 和向量文本
- 原始分块、引用、模型上下文和图谱证据不显示生成前缀
- FTS、CJK、向量和内容校验使用同一规范索引文本
## 7.1 Epic F+:受控本体与检索评估
### US-F5 每库受控本体
作为知识库维护者,我希望控制可用实体和关系类型,以便图谱保持一致。
验收:
- 每库保存实体类型、关系类型、双语名称、别名和可选端点约束
- 手工编辑使用受控选择器并拒绝未知类型或不兼容端点
- 图谱抽取按类型解析实体,保留人工锁定字段和跨类型边界
- 证据保存原文偏移、置信度、抽取来源和有界 provenance
- 本体或启用中的图谱策略变化标记需要重建
### US-F6 离线检索评估
作为 RAG 维护者,我希望用固定双语样本检测召回回归,而不读取用户数据或调用
网络服务。
验收:
- `npm run eval:retrieval` 使用临时 SQLite 和确定性内存 Provider
- 报告 Recall@5/10、MRR@10、nDCG@10、上下文精度/召回、无答案误报和延迟
- 提供词法、确定性向量、混合及本地重排消融
- 质量门槛按中英文分别检查,报告不包含原文、查询、端点、模型名或凭据
- 可选报告路径仅允许工作区内非符号链接文件
## 8. Epic G:分块维护
### US-G1 查看分块
作为知识库维护者,我希望查看某篇文档实际生成的分块,以便确认解析和切分质量。
验收:
- 文档行提供“查看分块”
- 列表显示序号、角色、标题、定位、字符数和启用状态
- 支持有界分页和文档内搜索
- 可查看完整单块内容
- 父子块关系可辨认但不只靠颜色表达
### US-G2 编辑分块
作为知识库维护者,我希望修正错误文本,以便问答使用正确内容。
验收:
- 编辑限制单块最大字符数
- 保存后同步更新全文和 CJK 索引
- 旧向量立即失效并触发当前文档重建
- 编辑块标记为人工修改
- UI 说明来源再次同步可能覆盖修改
- 保存失败保留用户草稿
### US-G3 启停分块
作为知识库维护者,我希望暂时停用有害或无关片段,而不永久删除它。
验收:
- 使用共享 Switch 和 `role="switch"`
- 停用块不参与任何召回通道
- 重新启用后恢复全文索引,并按需重建向量
- 状态更新失败时保留最后确认状态
- 引用已停用块时显示引用已失效
### US-G4 删除分块
作为知识库维护者,我希望删除确定无用的分块,以便避免错误召回。
验收:
- 删除前说明来源同步可能重新创建该块
- 删除使用具体动作和对象文案
- 删除联动清理全文、CJK、向量和图谱证据
- 删除最后一个可检索块后文档显示“无可检索内容”
- 不删除原始文件
## 9. Epic H:引用和来源
### US-H1 查看完整引用上下文
作为普通知识使用者,我希望从回答引用查看完整上下文,以便验证回答是否忠于
资料。
验收:
- 引用携带稳定 `libraryId``documentId``chunkId`
- 点击引用由 Main 重新校验对象归属
- 展示命中分块、相邻块或父块
- 展示知识库、文档、来源和定位
- 对已删除对象显示明确失效状态
### US-H2 打开原始来源
作为普通知识使用者,我希望从引用打开原文件或网页,以便继续阅读。
验收:
- 本地来源只通过数据库保存的普通文件路径打开
- 网页来源只允许数据库保存的 HTTP(S) URL
- Renderer 不能传入任意待打开路径或 URL
- 文件已移动时显示可恢复错误
- 不能跨平台精确跳页时仍显示原定位信息
### US-H3 引用与回答一致
作为普通知识使用者,我希望引用列表只显示本次实际检索到的内容。
验收:
- Main 只收集本次 capability token 产生的引用
- 预检索和模型后续检索引用去重
- 引用顺序遵循最终相关度和首次使用顺序
- 单消息引用数和序列化大小有明确上限
- 不把未检索文档显示为来源
## 10. Epic I:迁移、安全和兼容
### US-I1 无损迁移
作为现有用户,我希望升级后保留知识库、来源、分块、图谱和向量。
验收:
- SQLite 迁移在事务中执行
- 旧分块默认启用并视为 standalone
- 旧知识库获得兼容检索和分块设置
- CJK 索引回填失败时回滚迁移
- 升级不自动删除或重建原有内容
### US-I2 安全边界
作为本地用户,我希望新增功能不扩大 Renderer 和子 Runtime 权限。
验收:
- 新增 IPC 全部校验可信 sender 和共享 Schema
- Main 重新检查知识库、文档、分块和来源归属
- Renderer 不访问 SQLite、文件系统、Electron shell 或凭据
- 知识内容标记为不可信证据
- Ask 不获得写工具
- 错误和日志不包含密钥、授权头和未限制正文
### US-I3 取消和关闭
作为用户,我希望大库检索或重建可以停止,不留下损坏索引。
验收:
- 长向量扫描、单文档重建和全库重建响应 AbortSignal
- 应用关闭停止新批次并等待有界清理
- 文档级替换成功前继续使用上一版索引
- 取消状态区别于失败
- 取消不会删除原文件或用户维护的其他文档
## 11. 优先级映射
### 第一阶段
- US-A1、US-A2、US-A3
- US-B1、US-B2、US-B3、US-B4
- US-C1、US-C2、US-C3、US-C4、US-C5
- US-D1
- US-H1、US-H2、US-H3
- US-I1、US-I2
### 第二阶段
- US-D2、US-D3
- US-E1、US-E2、US-E3
- US-F1、US-F2、US-F3
- US-G1、US-G2、US-G3、US-G4
- US-I3
## 12. Definition of Done
每个 User Story 只有在以下条件全部满足时才完成:
1. Main、Preload、Renderer 和共享契约保持明确边界。
2. 行为有聚焦的单元、IPC 或组件回归测试。
3. 中英文文案同时更新。
4. 浅色、深色、键盘和窄窗口核心流程可用。
5. 失败、取消、空结果和降级状态均有独立表现。
6. 不覆盖用户现有未提交或未跟踪文件。
7. `npm test``npm run typecheck``npm run lint``npm run build`
全部通过。
@@ -0,0 +1,410 @@
# 持续学习与评估门 PRD
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 状态 | 设计中,远期能力 |
| 版本 | 0.3 |
| 日期 | 2026-08-19 |
| 依赖 | [自动化平台总体设计](../../architecture/automation-platform-architecture.md)、[并行实验 PRD](../experiments/parallel-experiments-prd.md)、[分区记忆 PRD](../memory/partitioned-memory-prd.md) |
## 1. 背景
智能心跳可以生成摘要、后续任务和记忆候选,但这还不是完整学习。其长期“未来分区记忆”
方向尚未设计,也不承担持续学习、模式挖掘或自动改进:
- 候选是否改善未来行为没有评估。
- 一条反思是否会被检索和使用并不确定。
- 没有 Baseline、回放集、Shadow、晋升和回滚。
- 没有持续监控候选生效后的收益与退化。
- 如果允许系统直接修改 Prompt、Skill 或规则,可能发生静默劣化。
持续学习必须建立为可观察、可评估、可批准、可回滚的闭环,而不是“让模型自动改自己”。
## 2. 产品定义
```text
Observe
→ Propose candidate
→ Validate structure and safety
→ Evaluate against baseline
→ Shadow
→ Promote with approval
→ Monitor
→ Keep, revise, rollback or archive
```
学习产物只有在改变未来行为后才算生效;只保存一条 Reflection 仍属于记忆候选。
## 3. 已确认的产品决策
1. 评估门必须先于任何自动应用能力上线。
2. 新候选默认 `candidate`,通过离线评估后先进入 `shadow`
3. 第一阶段只允许人工晋升。
4. 每次晋升必须记录 Baseline、候选、评估结果、作用域和回滚版本。
5. 学习不能修改安全边界、工具审批、目录权限、沙箱或 Electron 配置。
6. 失败案例和用户负反馈只作为评估数据,不直接成为新规则。
7. 回放案例必须脱敏、版本化,并得到用户明确选择或来自仓库公开样例。
8. 模型评估不是唯一真值,优先使用确定性验收和人工反馈。
9. 生效后的候选继续监控,发生退化可自动停用,但不能自动换上另一个候选。
10. 没有足够证据时保持 `inconclusive`,不强行晋升。
## 4. 学习产物
首期只支持:
| 产物 | 作用 | 是否可自动应用 |
| --- | --- | --- |
| Memory | 改善相关上下文召回 | 否,人工确认 |
| Automation Template | 改善目标、步骤、提示或预算默认值 | 否,创建新草稿 |
| Prompt Variant | 用于实验比较 | 否 |
| Rubric | 改善评估标准 | 否 |
| Retrieval Preference | 调整特定 Automation 的检索配置候选 | 否 |
后续评估:
| 产物 | 风险 |
| --- | --- |
| Skill | 可能扩大行为和工具使用 |
| Procedure | 可能长期影响多个任务 |
| Non-security Rule | 可能阻断或改变行为 |
| Agent Preference | 可能产生难以解释的个性漂移 |
永久禁止自动学习修改:
- 工具权限和审批策略。
- 工作区根目录和文件访问范围。
- 网络、远程消息和电脑控制权限。
- Electron 安全设置。
- API Key、凭据和 Provider Endpoint。
- 删除、支付、发布和生产操作政策。
## 5. 候选来源
- 用户对回答、任务或 Supervisor 意见的显式反馈。
- 用户对心跳报告或建议的显式反馈。
- Task/Job Run 的成功与失败比较。
- 并行实验结论。
- 回放评估发现的稳定差异。
- 用户手动创建。
候选必须包含:
- 作用域。
- 产物类型。
- 来源证据。
- 预期改善的指标。
- 可能影响的行为。
- 风险级别。
- Baseline 引用。
- 建议的评估集。
模型不能仅凭一条成功案例宣称“已学习”。
## 6. 状态机
```text
candidate
→ evaluating
→ rejected
→ inconclusive
→ shadow
→ awaiting_approval
→ promoted
→ paused
→ rolled_back
→ archived
```
| 状态 | 含义 |
| --- | --- |
| `candidate` | 尚未评估 |
| `evaluating` | 正在运行离线评估 |
| `rejected` | 明确退化、安全不合格或无效 |
| `inconclusive` | 证据不足 |
| `shadow` | 计算候选决策但不影响真实行为 |
| `awaiting_approval` | 达到晋升标准,等待用户 |
| `promoted` | 已作为指定作用域的当前版本 |
| `paused` | 暂停影响,保留版本 |
| `rolled_back` | 已恢复前一版本 |
| `archived` | 不再评估和使用 |
## 7. 评估案例
### 7.1 案例来源
优先级:
1. 仓库内公开、无隐私的固定评测样例。
2. 用户手动创建的案例和期望。
3. 用户明确选择并脱敏的历史会话或任务。
4. 实验中产生、经用户批准保留的案例。
禁止默认采样所有私人会话用于学习。
### 7.2 案例结构
```ts
type EvaluationCase = {
id: string
suiteId: string
input: EvaluationInput
assertions: EvaluationAssertion[]
forbiddenBehaviors: EvaluationAssertion[]
source: EvaluationCaseSource
sensitivity: 'public' | 'private_local'
version: number
}
```
断言可以是:
- 输出符合 Schema。
- 包含或不包含确定文本模式。
- 引用来自允许知识库。
- 不调用工具。
- 任务状态和成果存在。
- 测试命令通过。
- 人工评分。
- 模型 Rubric 分项。
### 7.3 冻结
一次评估冻结:
- 案例版本。
- Baseline 版本。
- Candidate 版本。
- Runtime 和模型。
- 知识、记忆和工作区快照。
- 预算。
- 评估器版本。
设置变化不改变已开始的评估。
## 8. 评估门
### 8.1 判定
```ts
type GateVerdict = {
decision: 'reject' | 'inconclusive' | 'shadow'
baselineMetrics: MetricValue[]
candidateMetrics: MetricValue[]
regressions: Regression[]
caseIds: string[]
evaluatorVersions: string[]
notes: string
}
```
最小规则:
1. 任何安全、权限或硬约束退化立即 Reject。
2. 确定性质量指标不能低于配置阈值。
3. 成本和延迟退化必须在允许范围。
4. 开放质量指标至少非退化,或收益足以覆盖明确成本。
5. 案例数或评估器不足时 Inconclusive。
6. 通过离线门只进入 Shadow,不直接 Promote。
### 8.2 Baseline
Baseline 是当前已生效版本或明确的无候选行为。不能用另一个同时变化的实验配置充当 Baseline。
### 8.3 多模型评估
模型 Rubric 可使用与被评候选不同的模型,但必须:
- 固定版本和提示。
- 隐藏候选身份。
- 随机化顺序。
- 保存分项和证据。
- 在关键晋升中结合确定性或人工评估。
## 9. Shadow
Shadow 模式:
- 接收与当前真实行为相同的有界输入。
- 计算候选会做出的选择或输出。
- 不调用有副作用工具。
- 不替换用户看到的结果。
- 不写入长期记忆。
- 保存与实际结果可比较的指标。
对于成本较高的候选:
- 只对抽样的已授权案例运行。
- 用户可设置月度调用上限。
- 系统繁忙时延后。
Shadow 达到配置的最小观察数且无安全退化后进入 `awaiting_approval`
## 10. 晋升
晋升对话框必须显示:
- 候选将改变什么。
- 作用域和受影响计划。
- 来源。
- Baseline 与 Candidate 指标。
- 失败案例和不确定性。
- 额外成本。
- 回滚版本。
用户可以:
- 晋升。
- 继续 Shadow。
- 拒绝。
- 缩小作用域后重新评估。
晋升采用原子版本切换。不能在一半对象上成功、一半失败。
## 11. 上线后监控
监控:
- 使用次数。
- 成功、失败和无结论。
- 确定性指标。
- 用户采纳、撤销和负反馈。
- Token、耗时和工具调用变化。
- Supervisor 警告变化。
自动暂停条件:
- 安全或权限硬约束失败。
- 确定性错误率超过阈值。
- 连续崩溃或格式失败。
- 成本超过批准上限。
自动暂停只恢复到上一已批准版本,并通知用户。系统不能自行选择新候选替代。
## 12. 回滚
- 每个 Promoted 产物有不可变版本。
- 保存前一版本和作用域绑定。
- 一键回滚使用原子切换。
- 回滚不删除失败版本,保留指标和原因。
- 当前有运行使用该版本时,只影响下一次 Run;紧急安全暂停可取消尚未开始的 Run。
- 被回滚候选再次晋升必须重新评估。
## 13. 衰减与归档
- 长期未使用的候选和 Shadow 可归档。
- Promoted 产物不因时间静默删除。
- Memory 类型遵守分区记忆的衰减规则。
- 评估案例变化后,相关候选标记为“评估过期”。
- 模型或 Runtime 大版本变化时,可要求重新回放。
- 归档保留不含私人正文的指标和版本元数据。
## 14. 信息架构
若远期验证确有集中学习管理需求,应提供独立且可审计的“学习”视图,而不是放入智能心跳、
任务中心或一个尚未确认的自动化中心:
1. **候选**:来源、作用域、预期收益和风险。
2. **评估中**:进度、案例和预算。
3. **Shadow**:观察数、差异和成本。
4. **待批准**:晋升摘要。
5. **已生效**:当前版本、使用量和健康状态。
6. **历史**:拒绝、回滚和归档。
候选详情页签:
- 概览。
- 变更 Diff。
- 评估案例。
- 指标和失败。
- Shadow。
- 版本与回滚。
## 15. 数据模型建议
```ts
type LearningArtifact = {
id: string
scopeKind: 'global' | 'project' | 'automation' | 'agent'
scopeId?: string
kind:
| 'memory'
| 'automation_template'
| 'prompt_variant'
| 'rubric'
| 'retrieval_preference'
status:
| 'candidate'
| 'evaluating'
| 'rejected'
| 'inconclusive'
| 'shadow'
| 'awaiting_approval'
| 'promoted'
| 'paused'
| 'rolled_back'
| 'archived'
payload: JsonValue
sourceRefs: LearningSourceRef[]
baselineVersionId?: string
promotedVersionId?: string
createdAt: string
updatedAt: string
}
```
建议表:
- `learning_artifacts`
- `learning_artifact_versions`
- `evaluation_suites`
- `evaluation_cases`
- `evaluation_runs`
- `evaluation_results`
- `shadow_observations`
- `promotion_events`
- `rollback_events`
## 16. 安全与隐私
1. Apply 层拒绝没有 Gate Verdict 的候选。
2. 产物类型和目标作用域使用代码白名单。
3. 安全与权限配置不在可学习目标白名单中。
4. 私人评估案例只在本地使用,不导出或发送到未授权 Provider。
5. Shadow 不调用有副作用工具。
6. Candidate 内容和评估输出都视为不可信数据。
7. Renderer 不能直接设置 Promoted 状态,Main 验证评估与审批。
8. 删除私人评估案例后清理派生缓存和 Embedding。
9. 日志不记录完整案例、Prompt、回答、文件或凭据。
10. 自动暂停采用确定性条件,不依赖模型自由判断。
## 17. 实施顺序
严格顺序:
1. 建立版本化评估案例和确定性断言。
2. 复用并行实验运行 Baseline 与 Candidate。
3. 实现 Gate Verdict,只有 Reject、Inconclusive 和 Shadow。
4. 实现 Shadow,但不允许 Apply。
5. 实现人工晋升和原子回滚。
6. 实现上线监控和确定性自动暂停。
7. 首先开放 Memory 和 Automation Template。
8. 经过长期验证后再评估 Skill、Procedure 和非安全规则。
不能先做自动改 Prompt,再补评估门。
## 18. 验收标准
- [ ] 没有评估结果的候选无法晋升。
- [ ] 安全、权限或硬约束退化必定 Reject。
- [ ] 评估不足时显示 Inconclusive,不强行选优。
- [ ] Baseline、Candidate、案例、Runtime 和评估器都被冻结和版本化。
- [ ] Shadow 不影响用户结果、不调用副作用工具、不写长期记忆。
- [ ] 晋升前展示收益、退化、成本、作用域和回滚版本。
- [ ] 第一阶段只有用户可以批准晋升。
- [ ] 晋升和回滚采用原子版本切换。
- [ ] 生效后出现确定性严重退化时自动暂停并恢复上一批准版本。
- [ ] 系统不会自动选择另一个候选替代。
- [ ] 私人会话不会默认进入评估集。
- [ ] 安全策略、权限、目录、凭据和 Electron 配置不属于可学习产物。
+494
View File
@@ -0,0 +1,494 @@
# 分区记忆 PRD
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 状态 | 设计中 |
| 版本 | 0.3 |
| 日期 | 2026-08-19 |
| 依赖 | [自动化平台总体设计](../../architecture/automation-platform-architecture.md)、[智能心跳 PRD](../smart-heartbeat/smart-heartbeat-prd.md)、[Task 与 Job 统一领域模型](../task-and-job/task-and-job-model.md) |
## 1. 背景
GoodBuddy 当前记忆已经支持:
- `global``project``conversation` 三种作用域。
- `preference``fact``summary``procedure` 四种类型。
- `proposed``confirmed``rejected` 三种状态。
- 智能心跳提出 Global 或 Project 记忆候选,由用户确认;其长期“未来分区记忆”方向尚未设计。
但当前能力仍不足以支撑自动化和并行实验:
1. 交互请求会把已加载列表中的最多 20 条已确认记忆直接拼入提示,缺少查询相关度和明确的
会话级过滤契约。
2. 数据库有会话作用域,但旧版心跳候选与未来唤起需求混在同一产品概念中。
3. 缺少 Automation、Experiment 和 Run 分区。
4. 来源字段存在于表结构,但普通创建和心跳候选尚未完整保存来源关系。
5. 缺少事实的有效时间、冲突、替代、访问记录和衰减。
6. 实验 Run 若共享可变记忆,会造成候选互相污染。
本设计先完成分区、来源、检索和生命周期,再评估时间知识图谱。
## 2. 核心产品判断
### 2.1 分区是权限和隔离边界
分区不是搜索标签。每次读取先根据运行快照确定允许分区,再在这些分区中检索。
模型不能请求任意分区 ID,Renderer 也不能把任意 ID 作为可信范围。
### 2.2 作用域和记忆种类是两个维度
- 作用域回答“谁可以读取”。
- 类型回答“这是什么信息”。
不能用 `summary` 表示会话范围,也不能用 `project` 表示事实类型。
### 2.3 记忆和知识库分离
| 记忆 | 知识库 |
| --- | --- |
| 用户偏好、项目约定、过程经验、会话摘要 | 文档、网页、文件和外部资料 |
| 小规模、动态、可确认和可遗忘 | 大规模、按来源同步和引用 |
| 强调作用域、来源、时态和行为影响 | 强调检索、分块和证据引用 |
不能把整个文档或长工具输出保存为记忆。
### 2.4 第一阶段不需要图数据库
SQLite 显式字段、FTS、来源关系和可选本地 Embedding 足以支持首期。时间图谱只有在以下
需求经过验证后再建设:
- 实体关系的多跳查询。
- 事实有效期和关系演变。
- 同一实体跨大量会话的别名消歧。
- 可解释的关系证据链。
### 2.5 未来分区记忆尚待设计
已确认智能心跳的长期方向是“未来分区记忆”,但当前尚未定义其数据结构、唤起条件、状态、
生命周期、与长期记忆的关系或迁移方式。本 PRD 不新增 `FutureMemory` 类型、表或检索规则。
## 3. 目标
- 为会话、自动化和并行 Run 提供严格隔离。
- 每条记忆显示范围、类型、状态、来源、时间和敏感度。
- 在允许分区内按相关性、重要性、新鲜度和预算检索。
- 保留冲突事实和时态,不静默覆盖。
- 让候选记忆经过确认或评估后再晋升。
- 支持编辑、移动、合并、拒绝、归档、删除和要求忘记。
- 记录哪些 Run 实际读取了哪些记忆。
- 为现有智能心跳配置建立 Global 或指定 Project 范围,并保持当前候选记忆流程。
## 4. 非目标
- 不保存完整聊天、文档、工具日志或隐藏推理作为记忆。
- 不自动确认敏感个人信息。
- 不默认跨项目共享 Project、Conversation 或 Run 记忆。
- 不允许模型自行创建新分区或跨分区移动记忆。
- 不承诺记忆中的事实永远正确。
- 第一阶段不建设 Memory Palace 五层空间隐喻。
- 不把向量相似度作为权限判定。
## 5. 分区模型
### 5.1 分区类型
```ts
type MemoryNamespaceKind =
| 'global'
| 'project'
| 'conversation'
| 'automation'
| 'experiment'
| 'run'
| 'agent'
```
| 分区 | 内容 | 生命周期 |
| --- | --- | --- |
| Global | 用户长期偏好和跨项目通用约定 | 长期,严格确认 |
| Project | 项目术语、目标、决策和流程 | 随项目 |
| Conversation | 当前会话摘要、局部约定和待澄清信息 | 随会话或短期 |
| Automation | 某计划的稳定协议经验和运行约定 | 随计划 |
| Experiment | 实验设计、结论和限制 | 随实验 |
| Run | 单次运行观察、中间状态和临时经验 | 短期、严格隔离 |
| Agent | 某专家或角色的个性化经验 | 后续,默认关闭 |
首期实现 Global、Project、Conversation、Automation 和 Run。Experiment 可复用
Automation 机制后增加;Agent 必须在专家长期身份明确后再开放。
### 5.2 分区标识
```text
global
project:{projectId}
conversation:{conversationId}
automation:{planId}
experiment:{experimentId}
run:{automationRunId}
agent:{expertId}
```
数据库使用 UUID 外键和显式 `kind`,上述字符串只用于日志和展示,不作为未经验证的访问凭据。
### 5.3 读取链
交互会话推荐:
```text
Conversation → Project → Global
```
Task/Job Run
```text
Run → Automation → Conversation(可选)→ Project → Global
```
实验 Run
```text
Run → Experiment frozen snapshot → Project frozen snapshot → Global frozen snapshot
```
各层使用独立结果数和字符预算。Run 层不能覆盖权限更高层,只能提供更具体上下文。
## 6. 记忆条目
```ts
type MemoryItem = {
id: string
namespaceId: string
kind:
| 'preference'
| 'fact'
| 'summary'
| 'procedure'
| 'decision'
| 'constraint'
| 'reflection'
content: string
status:
| 'candidate'
| 'confirmed'
| 'rejected'
| 'superseded'
| 'archived'
confidence: number
salience: number
sensitivity: 'normal' | 'sensitive' | 'restricted'
validFrom?: string
validTo?: string
expiresAt?: string
sourceId: string
supersedesId?: string
createdAt: string
updatedAt: string
}
```
兼容映射:
- 当前 `proposed` 对应 `candidate`
- 当前 `confirmed``rejected` 保留。
- 当前四种类型保留,并按真实需求增加 `decision``constraint``reflection`
## 7. 来源与证据
### 7.1 来源类型
```ts
type MemorySource =
| { type: 'user_entry'; createdBy: 'user' }
| {
type: 'message'
conversationId: string
messageId: string
}
| { type: 'task'; taskId: string; eventId?: string }
| { type: 'heartbeat'; heartbeatRunId: string; entryId: string }
| { type: 'supervisor'; supervisorRecordId: string }
| { type: 'automation_run'; automationRunId: string }
| {
type: 'experiment_conclusion'
experimentId: string
conclusionId: string
}
| { type: 'artifact'; artifactId: string }
```
### 7.2 来源规则
- 每条非用户手动记忆必须有来源。
- 来源被删除时记忆不一定删除,但显示“来源不可用”并降低可信度。
- 来源内容不复制进记忆表,只保存有界证据摘要和引用。
- 用户确认只表示允许后续使用,不表示事实已被外部验证。
- Supervisor 判断只能生成候选,不能直接生成确认事实。
## 8. 候选生成
候选来源:
- 用户明确“记住这个”。
- 会话结束总结。
- Task/Job Run 结束反思。
- 实验结论。
- Supervisor 建议后用户采纳。
- 智能心跳。
候选生成必须:
- 限制数量和长度。
- 检查同分区近似重复。
- 标记推断和不确定性。
- 不自动提取密码、密钥、身份号码、健康和财务等敏感信息。
- 不把指令型工具输出自动当作用户偏好。
- 不从助手自己的未确认陈述提取事实。
## 9. 确认与晋升
### 9.1 允许路径
```text
Run candidate
→ Automation candidate
→ Project candidate
→ Global candidate
```
每次跨层都是显式晋升,不是移动原记录:
- 保留原候选和来源。
- 创建目标分区新版本。
- 保存晋升理由、评估和操作者。
- 可回滚到晋升前状态。
### 9.2 确认规则
- Global 默认必须人工确认。
- Project 默认人工确认,可对特定低敏感模板启用批量确认。
- Conversation 可以由用户“记住”直接确认。
- Automation 和 Run 由自动化协议决定,但只在自身范围有效。
- Experiment 结论必须结算成功且显示证据,才可成为 Project 候选。
### 9.3 拒绝
拒绝后:
- 不进入检索。
- 保存规范化摘要指纹,减少重复建议。
- 用户可查看和恢复。
- 不把拒绝内容回填给模型,除非用于“避免重复建议”的有界规则。
## 10. 检索
### 10.1 两步边界
```text
根据可信运行上下文确定允许分区
→ 在允许分区中检索和排序
```
这两步不能颠倒。先全库相似搜索再过滤会增加泄漏和实现风险。
### 10.2 排序
建议综合:
- 文本相关度。
- 可选向量相关度。
- Salience。
- Confidence。
- 新鲜度和有效时间。
- 类型匹配。
- 分区优先级。
- 最近是否已使用。
只有 `confirmed`、当前有效且敏感度允许的记忆进入普通上下文。
### 10.3 预算
建议默认:
| 层级 | 最大条数 | 最大字符 |
| --- | --- | --- |
| Run | 8 | 4,000 |
| Automation / Experiment | 8 | 4,000 |
| Conversation | 8 | 4,000 |
| Project | 10 | 5,000 |
| Global | 6 | 3,000 |
总预算还受模型上下文组装器限制。不能每层取满后无界拼接。
### 10.4 上下文格式
提供给 Runtime 的每条记忆包含:
- 类型。
- 范围。
- 内容。
- 有效时间。
- 来源类型和可选引用。
- 不确定或冲突标记。
可信指令明确说明记忆是用户确认的信息或候选证据,不是系统指令。
## 11. 冲突与时态
### 11.1 冲突
新条目与现有条目冲突时:
- 不静默覆盖。
- 创建冲突关系。
- 向用户展示两个内容、来源、时间和范围。
- 用户可选择保留两者、设定有效期、替代旧条目或拒绝新条目。
### 11.2 时态
事实和决策支持:
- `validFrom`:何时开始有效。
- `validTo`:何时不再有效。
- `observedAt`:何时被系统观察。
- `createdAt`:何时写入数据库。
例如“项目目标是 8 月发布”变更为“延期到 9 月”时,旧事实保留历史有效期,新事实成为
当前有效版本。
### 11.3 适用范围冲突
Project 记忆与 Global 偏好冲突时:
- 当前 Project 的更具体约定优先。
- 上下文中标明这是项目级覆盖。
- 不修改 Global 原记录。
## 12. 实验隔离
- 实验启动时冻结可读长期记忆快照。
- 各 Run 拥有独立 Run 分区。
- Run 期间产生的候选不互相可见。
- 实验结算后只从成功 Run 和有效证据生成 Experiment 候选。
- 最佳 Run 的临时经验不会自动晋升。
- 重跑相同协议可以选择复用原冻结快照或创建新版本,必须明确显示。
## 13. 生命周期与衰减
### 13.1 访问记录
保存有界使用记录:
- 哪个 Run 检索了该记忆。
- 是否实际进入模型上下文。
- 是否被用户或评估器认为有用。
- 最近使用时间和命中次数。
不保存完整请求副本。
### 13.2 衰减
- Preference、Constraint 和 Procedure 不仅因时间自动失效。
- Conversation、Run Summary 和 Reflection 可配置过期时间。
- 长期未命中、低 Salience 的候选可归档。
- 衰减先影响排序,再进入归档,不直接硬删除。
- Restricted 记忆可采用更短保留期。
### 13.3 删除与忘记
- 删除记忆后立即停止检索。
- “忘记”同时清理派生索引、Embedding 和缓存。
- 来源消息是否删除由其自身生命周期决定,不能反向静默删除用户会话。
- 删除 Project 时清理其分区、自动化和 Run 记忆,不影响 Global。
- 审计只保留不含原内容的删除事件和 ID 摘要。
## 14. 敏感信息
| 敏感度 | 行为 |
| --- | --- |
| Normal | 按普通确认和检索规则 |
| Sensitive | 必须人工确认,UI 持续标记 |
| Restricted | 默认不允许模型自动生成;仅用户手动创建,读取需要显式启用 |
禁止自动长期记忆:
- 密码、密钥、Token、Cookie。
- 完整身份证件、银行卡和账户凭据。
- 未经用户明确要求的健康、财务和高度私密信息。
- 工具输出中的认证数据。
## 15. 信息架构
记忆中心建议页签:
1. **记忆**:按范围、类型、状态和敏感度浏览。
2. **待确认**:候选、冲突和晋升请求。
3. **分区**Global、Project、Conversation、Automation、Run 的统计和访问策略。
4. **使用记录**:哪些 Run 使用了哪些记忆。
5. **设置**:候选生成、保留期、敏感信息和检索预算。
每条记忆展示内容、类型、范围、来源、状态、时间、置信度、重要性和冲突。
智能心跳的完整配置仍在“智能心跳”菜单中管理;未来分区记忆完成独立设计前,不加入记忆
中心信息架构。
## 16. 数据模型建议
建议表:
- `memory_namespaces`
- `memory_items`
- `memory_sources`
- `memory_relations`
- `memory_access_events`
- `memory_promotion_events`
- `memory_embeddings`,可选
现有 `memory_items` 可渐进迁移:
1. 增加 Namespace 并回填现有 Scope。
2. 回填来源为空的旧记录为 `legacy_unknown`
3. 增加状态和类型兼容映射。
4. 上线新检索器后再停止旧的列表拼接方式。
## 17. 安全与隐私
1. 分区解析只在 Main 进行。
2. 所有 ID 重新验证对象归属和项目范围。
3. Renderer 无法指定任意分区进行搜索。
4. Runtime 只能获得有界记忆文本和来源摘要。
5. Embedding 只能发送用户已配置允许的记忆,Restricted 默认不发送外部服务。
6. 记忆内容和来源不出现在普通日志与通知。
7. 跨分区晋升需要明确操作和审计。
8. Ask 和 Execute 使用同一只读记忆检索边界。
9. 记忆不能绕过系统指令、工具审批和工作区权限。
## 18. 实施顺序
1. 修正当前交互请求的范围过滤,确保只读 Global、当前 Project 和当前 Conversation。
2. 增加来源记录和“实际进入上下文”的诊断。
3. 为现有智能心跳配置增加 Global 或指定 Project 范围,保持候选记忆行为不变。
4. 建立 Automation 和 Run Namespace。
5. 上线有界相关检索,替换简单列表前 20 条拼接。
6. 增加冲突、时态、替代和归档。
7. 增加实验冻结快照与 Run 隔离。
8. 增加可选本地 Embedding 和混合排序。
9. 未来分区记忆和时间知识图谱都必须在明确需求与独立设计后再实施。
## 19. 验收标准
- [ ] 普通会话只读取 Global、当前 Project 和当前 Conversation 的允许记忆。
- [ ] 智能心跳配置只能属于 Global 或 Main 已验证的一个、多个 Project。
- [ ] 未来分区记忆完成独立设计前,不新增相关表、状态或检索行为。
- [ ] Task/Job Run 只读取运行快照绑定的分区。
- [ ] 实验 Run 不能读取其他 Run 的消息或记忆。
- [ ] 每条非手动记忆都有可追溯来源。
- [ ] 候选和被拒绝记忆不进入普通上下文。
- [ ] Global 和 Project 晋升需要明确确认或评估。
- [ ] 冲突事实不被静默覆盖。
- [ ] 当前有效事实可通过有效时间正确选择。
- [ ] 上下文组装遵守各层和总字符预算。
- [ ] UI 能显示某次 Run 实际使用的记忆。
- [ ] 删除或忘记后,文本、索引和缓存不再可检索。
- [ ] Restricted 记忆不会自动生成或发送给外部 Embedding 服务。
@@ -0,0 +1,244 @@
# 智能心跳 PRD
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 状态 | 入口与范围已实现;未来分区记忆待独立设计 |
| 版本 | 0.5 |
| 日期 | 2026-08-19 |
| 适用产品 | GoodBuddy 桌面端 |
| 文档角色 | 智能心跳当前能力、权威入口、范围和长期边界 |
| 相关设计 | [统一界面设计系统](../../../UI-DESIGN.md) |
| 相关架构 | [自动化、监督与记忆平台总体设计](../../architecture/automation-platform-architecture.md) |
| 相关界面 | [通用助手工作栏与执行空间 PRD](../assistant-experience/assistant-workbar-and-execution-spaces-prd.md) |
| Task 模型 | [Task 与 Job 统一领域模型](../task-and-job/task-and-job-model.md) |
> 本文区分近期实施与长期方向。未完成设计的“未来分区记忆”不得转写为数据结构、状态机、
> 页面、迁移或验收条件。
## 1. 已确认的产品边界
### 1.1 智能心跳是独立能力
- “智能心跳”菜单入口是心跳配置、报告、建议和运行历史的权威位置。
- 任务中心和设置中心不复制完整心跳配置表单。
- 智能心跳不并入通用自动化中心,也不作为任务中心条目。
- 现有心跳报告、记忆建议、行动建议和审计历史在本轮继续保留。
### 1.2 长期方向:未来分区记忆
已确认的方向只有:
> 智能心跳未来应成为按范围隔离的未来记忆。
以下内容尚未设计:
- “未来记忆”的数据结构与存储方式。
- 与当前长期记忆、心跳报告和建议的关系。
- 唤起条件、状态和生命周期。
- 到期后的页面和交互。
- 是否以及如何创建 Task。
- 旧版心跳数据如何迁移。
本轮不得实现 `FutureMemory`、新增未来记忆数据库表,或制作“未来记忆 / 即将唤起 /
已唤起”等页面。后续需要独立 PRD 和用户确认。
## 2. 本轮实施范围
### 2.1 目标
1. 完整心跳配置统一到“智能心跳”菜单入口。
2. 心跳配置支持 `Global` 或指定一个、多个 Project。
3. 保留现有概览、待处理建议、运行历史和报告能力。
4. 新入口完整可用后,再移除任务中心和设置中心中的重复心跳配置。
5. 旧心跳配置、运行、报告、建议、记忆和任务数据不丢失。
### 2.2 非目标
- 不设计或实现未来分区记忆。
- 不修改 Task、Job 或 Task Center 模型。
- 不新增独立 Automation Center。
- 不移除定时任务现有入口。
- 不扩大智能心跳的工具、目录、网络或 Execute 权限。
- 不让智能心跳跨越配置范围读取数据。
- 不将现有心跳建议静默转换成 Task。
## 3. 智能心跳范围
### 3.1 范围选择
每条心跳配置必须明确选择:
| 范围 | 当前执行语义 |
| --- | --- |
| `Global` | 回顾所有 Project 中允许读取的有界会话和任务,并读取 Global 已确认记忆 |
| 指定 Project | 只回顾选中 Project 的有界会话和任务,并读取 Global 与选中 Project 的已确认记忆 |
指定 Project 可以选择一个或多个项目:
```text
范围
(•) Global
( ) 指定项目
[✓] 网站重构
[ ] 内容运营
[✓] 客户研究
```
- `Global` 与指定 Project 互斥。
- 指定 Project 时至少选择一个项目。
- 多项目使用 Checkbox,不使用 Switch。
- 当前项目只可以作为创建表单的建议默认值,不能在保存时隐式覆盖用户选择。
- 切换当前项目不会改变已经保存的心跳范围。
- Main 必须重新验证所有 Project IDRenderer 不能扩大范围。
### 3.2 多项目执行
多项目配置的一次心跳仍然是一次运行和一份报告:
- 将选中项目中允许读取的会话、任务和记忆汇总后,再执行现有全局输入上限。
- 不为每个 Project 分别创建 Run、报告、建议或 Task 副本。
- 心跳报告成果以无项目归属保存,并在成果元数据中冻结本次配置范围。
- 心跳产生的项目级记忆建议或行动建议必须明确目标 Project。
- 目标 Project 不明确时,只能生成 Global 记忆建议或不绑定项目的行动建议,不能猜测。
### 3.3 兼容现有配置
旧配置按现有 `projectId` 非破坏映射:
- `projectId` 为空的配置迁移为 `Global`
- `projectId` 有值的配置迁移为“指定 Project”,且只绑定原项目。
- 迁移不修改启停状态、重复规则、时间、回顾窗口、保留期限、下次运行或历史。
- 项目删除时,只有该项目的配置按现有规则删除;多项目配置移除被删除项目并保留其他范围。
## 4. 权威入口
| 操作 | 权威入口 | 其他位置 |
| --- | --- | --- |
| 创建或编辑心跳配置 | 智能心跳 > 心跳计划 | 不复制表单 |
| 选择 Global / Project 范围 | 智能心跳 > 心跳计划 | 不依赖当前项目推断 |
| 暂停、恢复、立即心跳或删除 | 智能心跳 > 心跳计划 | 不复制操作 |
| 查看报告与待处理建议 | 智能心跳 | 主导航徽标和通知可触达 |
| 查看运行历史和失败 | 智能心跳 > 心跳轨迹 | 活动记录仅作审计补充 |
| 管理平台级默认值 | 设置中心 | 不显示单条计划 CRUD |
移除重复入口的顺序:
1. 先在智能心跳中支持完整创建、编辑、范围、暂停、恢复、立即运行和删除。
2. 验证旧数据与新范围均可管理。
3. 再从任务中心移除 `HeartbeatSettings`
4. 再从设置中心移除重复 `HeartbeatSettings`,必要时保留“打开智能心跳”链接。
5. 任一步失败都不得造成用户没有可用配置入口。
## 5. 智能心跳页面
保留现有四个页面:
- **成长概览**:状态、成功率、记忆、洞察和行动统计。
- **待处理建议**:记忆建议和行动建议。
- **心跳轨迹**:报告与 Run 审计。
- **心跳计划**:唯一完整配置入口。
### 5.1 心跳计划
创建和编辑至少显示:
- 名称。
- `Global` 或指定 Project 范围。
- 每日或每周重复规则。
- 本地时间、星期与 IANA 时区。
- 回顾窗口。
- 保留期限。
- 启停状态。
- 下次运行与上次状态。
交互要求:
- 使用持久标签,不以 placeholder 代替。
- 编辑进入明确状态,支持保存或放弃。
- 保存失败保留草稿。
- 删除继续使用共享破坏性确认。
- 运行中禁用重复操作。
- 保存成功后由计划列表直接反映结果;失败保留草稿并在编辑区就地提示。
### 5.2 范围呈现
- 页面标题不再根据当前 Project 伪装成心跳实际范围。
- 每张计划卡片显示 `Global` 或完整 Project 摘要。
- 多项目过多时显示“项目 A、项目 B 等 N 个”,并提供完整可访问名称。
- 报告成果元数据保存配置冻结范围;计划卡片始终显示计划自身范围,不根据当前项目重新解释。
- 项目失效或删除后,界面准确显示剩余范围或配置已被移除。
### 5.3 响应式与无障碍
- 宽窗口使用 `dashboard` 壳层,创建和编辑区域保持单列。
- 窄窗口下计划列表和表单转为单列卡片。
- `Global / 指定项目` 使用共享分段选择控件,Project 多选使用 Checkbox。
- 范围、状态和失败不能只依赖颜色。
- 表单错误与字段程序化关联。
- 对话框或编辑区关闭后,焦点返回触发按钮。
## 6. 数据与安全要求
目标合同只扩展现有心跳范围,不引入 Future Memory
```ts
type HeartbeatScope =
| { kind: 'global' }
| { kind: 'projects'; projectIds: string[] }
```
-`projectId` 只用于迁移兼容,不继续作为目标范围合同。
- Main 在创建、编辑、列出和执行时验证 Project 归属。
- Global 读取所有 Project 的有界会话和任务,但长期记忆仍只读取 Global。
- 指定 Project 读取选中项目的有界会话和任务,以及 Global 与选中项目记忆。
- 现有输入条数、字符预算、输出大小、超时、重试、租约和工具禁用边界继续生效。
- 多项目汇总后统一应用上限,不能按项目倍增预算。
- 心跳结果默认不在系统通知中暴露私人正文。
- 数据迁移必须使用 SQLite 事务,保留外键、级联删除和现有历史。
## 7. 实施状态与后续顺序
### 已完成:入口和范围
- 扩展共享 Schema、Preload 与 Main 数据合同。
- 增加 Global / 多 Project 持久化与旧数据迁移。
- 让心跳执行按冻结范围构建有界输入。
- 在“心跳计划”中完成创建、编辑和全部计划操作。
- 补齐范围、迁移、权限和界面测试。
### 已完成:移除重复配置
- 从 Task Center 移除心跳完整表单,保留 Task 和 Scheduled Task 现有行为。
- 从设置中心移除单条心跳 CRUD。
- 如需要,设置中心仅保留“打开智能心跳”导航。
- 验证应用内仍只有一个完整配置入口。
### 后续:独立设计
- 未来分区记忆。
- 与长期记忆的关系。
- 唤起模型与生命周期。
- 与 Task 的关系。
这些内容需要新的 PRD 和明确确认,不属于本轮实现。
## 8. 验收状态
- [x] 智能心跳菜单是完整配置的唯一权威入口。
- [x] 用户可以创建和编辑 `Global` 心跳。
- [x] 用户可以创建和编辑绑定一个或多个 Project 的心跳。
- [x] 切换当前 Project 不会改变已保存范围。
- [x] Main 拒绝不存在、已归档或超出配置范围的 Project ID。
- [x] Global 与多项目输入遵守现有总上限,不按项目倍增。
- [x] 多项目一次运行只产生一份 Run 和报告。
- [x] 旧 Global 和单 Project 配置无损迁移。
- [x] 旧运行、报告、建议、记忆和任务仍可查看。
- [x] 心跳计划支持创建、编辑、暂停、恢复、立即运行和删除。
- [x] 任务中心不再包含完整心跳配置表单。
- [x] 设置中心不再包含单条心跳 CRUD。
- [x] 任务中心本身以及定时任务现有行为没有被删除。
- [x] 智能心跳仍保持只读、禁用工具和有界输入输出。
- [x] 没有新增 Future Memory 表、状态机或未确认页面。
- [x] 加载失败、空状态、字段错误和危险操作满足统一设计与无障碍要求。
@@ -0,0 +1,416 @@
# 会话监督 PRD
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 状态 | 设计中 |
| 版本 | 0.2 |
| 日期 | 2026-08-18 |
| 依赖 | [自动化平台总体设计](../../architecture/automation-platform-architecture.md) |
| 界面归属 | [通用助手工作栏与执行空间](../assistant-experience/assistant-workbar-and-execution-spaces-prd.md) |
| 体验参考 | GoodBuddy 魔法笔记 AI 评论流 |
## 1. 背景
GoodBuddy 的魔法笔记已经提供一种有价值的交互:用户持续写作,AI 在右侧以长评、建议和
警告进行评论,用户可以选择综合、扩展、润色、质疑或发散方向。该能力是内容分析,不是
会话监督:
- 只分析当前笔记或待办文本。
- 不观察聊天任务、工具调用、目标、预算或成果。
- 不参与任务状态机。
- 不引用具体会话步骤。
- 不支持关注、暂停和解决流程。
随着目标任务和并行实验出现,用户需要一个与执行 Agent 相互独立的观察者,帮助发现偏题、
遗漏、矛盾、证据不足、循环、成本失控和潜在风险。
## 2. 产品定义
会话监督是在明确范围和策略下,对普通 Conversation、Task、Job/Run 或 ExperimentRun
的可见事件进行独立观察,产生带证据的评论、告警和人工介入请求。一个 Task 与唯一
Conversation 一对一绑定;Job/Run 是内部执行和审计对象。
它不是:
- 第二个替用户发言的聊天 Agent。
- 隐藏推理查看器。
- 工具审批器。
- 可以绕过安全边界的“总管理员”。
- 自动修正执行过程的通用控制器。
## 3. 核心产品判断
建议增加会话监督,首期采用“魔法笔记式右侧评论流”,但只开放以下能力:
```text
观察
→ 评论 / 警告
→ 用户查看证据
→ 用户忽略、采纳、询问、暂停或调整任务
```
首期模型监督不自动暂停。只有现有确定性安全规则、预算和用户显式配置的硬门禁可以自动暂停。
## 4. 已确认的产品决策
1. 监督默认关闭,由用户对 Conversation、Task、Job/Run 或实验显式启用。
2. 监督只读取用户可查看的消息、工具事件、状态、指标、成果摘要和目标。
3. 不读取、推断或保存模型隐藏推理链。
4. 每条重要判断必须引用具体消息、工具、步骤、指标或成果。
5. 模型监督默认只评论、警告或请求人工复核。
6. 确定性监督负责权限、预算、Schema、幂等和硬停止条件。
7. 监督器不能自动批准工具、扩大范围、修改安全策略或替用户发送消息。
8. 监督评论不是长期事实,默认不进入记忆。
9. 监督调用使用独立预算和低于前台对话的优先级。
10. 同一个事件不能同时产生重复页内警告、评论和全局通知。
## 5. 目标
### 5.1 用户目标
- 在重要会话旁获得不中断主对话的独立评论。
- 及时发现目标偏移、缺少证据、相互矛盾、重复循环和遗漏要求。
- 点击监督意见查看对应证据,而不是接受无来源判断。
- 对监督意见进行采纳、忽略、标记误报或追问。
- 对 Scheduled/Goal Task 设置更严格的监督策略和人工检查点。
### 5.2 产品目标
- 为普通会话、目标任务和实验提供统一监督契约。
- 让确定性安全门禁与模型质量判断保持分层。
- 保存有界、可审计的监督事件,而非复制完整会话。
- 将用户反馈用于调整规则和评估监督器,但不自动训练或改策略。
## 6. 非目标
- 不展示内部 Chain of Thought。
- 不持续监控其他应用、键盘、麦克风或屏幕。
- 不把 Supervisor 设为拥有所有工具的超级 Agent。
- 不自动修改用户消息或助手回答。
- 不保证识别所有事实错误、偏见或安全风险。
- 不把一次模型警告作为任务失败的确定性依据。
- 不在首期支持 Supervisor 与执行 Agent 自主多轮辩论。
- 不让 Supervisor 读取未授权项目、会话、知识库或记忆。
## 7. 监督对象
| 对象 | 观察内容 | 典型用途 |
| --- | --- | --- |
| 普通会话 | 用户消息、助手回答、引用、工具事件 | 质量和证据评论 |
| Task | 目标、状态、Conversation、成果 | 偏离、循环和失败分析 |
| Job/Run | 触发、步骤、协议、预算、审批、指标 | 无人值守或内部执行关注 |
| 实验 Run | 协议、变量、指标、证据 | 协议一致性 |
| 实验整体 | 各 Run 结算和比较 | 评估公平性与无结论提示 |
每个监督会话只能绑定一个主对象,并继承其项目范围。
## 8. 监督模式
### 8.1 评论方向
借鉴魔法笔记,普通会话支持:
| 模式 | 行为 |
| --- | --- |
| 综合 | 平衡总结目标、进展、风险和下一步 |
| 质疑 | 检查逻辑跳跃、前提、反例和证据 |
| 证据 | 检查重要结论是否有可追溯依据 |
| 目标 | 检查是否回应用户目标和约束 |
| 风险 | 检查权限、隐私、外部影响和不可逆行为 |
自动化和实验可组合多个检查维度,不用方向单选替代确定性规则。
### 8.2 触发方式
| 方式 | 说明 |
| --- | --- |
| 手动 | 用户点击“检查当前会话” |
| 每次回复后 | 助手一轮完成后异步分析 |
| 每 N 步 | 自动化或实验按有界步骤间隔分析 |
| 关键事件 | 工具失败、预算 80%、等待审批、指标异常 |
| Run 结束 | 进行最终监督回顾 |
首期优先手动和每次回复后。草稿输入不发送给监督器,除非未来明确增加类似魔法笔记的
草稿评论模式。
### 8.3 干预级别
```ts
type SupervisorAction =
| 'continue'
| 'comment'
| 'warn'
| 'request_review'
| 'pause'
| 'stop'
```
- 模型 Supervisor 首期只可产生前四种。
- `pause``stop` 只来自确定性门禁或用户操作。
- 后续若允许模型建议暂停,仍需确定性策略把建议转换为 `request_review` 或经过用户预授权。
## 9. 观察输入
### 9.1 可见输入
- 当前对象的名称、目标和约束。
- 最近有界消息。
- 工具名称、状态、参数摘要和输出摘要。
- Task、Job 和 Subjob 状态。
- 成果标题、类型、大小和有界摘要。
- 引用和知识检索诊断。
- 预算使用。
- 明确配置的监督规则。
- 已解决或被忽略的近期监督意见摘要。
### 9.2 禁止输入
- API Key、Token、Cookie 和认证头。
- 模型隐藏推理。
- 未授权文件和完整私人文档。
- 其他项目、会话或实验 Run 的数据。
- 原始无限长度工具输出。
- 已删除或用户要求忘记的记忆。
### 9.3 上下文窗口
- 普通会话默认最近 12 条消息和最多 24,000 字符。
- 任务按最近 20 个关键事件和当前目标组装。
- 长会话先使用确定性提取,再由监督器处理有界输入。
- 不能把 Supervisor 自己的旧评论无限回填,最多保留近期未解决摘要。
## 10. 监督输出
```ts
type SupervisorDecision = {
action:
| 'continue'
| 'comment'
| 'warn'
| 'request_review'
category:
| 'goal_drift'
| 'missing_requirement'
| 'evidence_gap'
| 'contradiction'
| 'repetition'
| 'quality'
| 'risk'
| 'budget'
severity: 'info' | 'low' | 'medium' | 'high'
title: string
content: string
evidence: SupervisorEvidenceRef[]
confidence: number
suggestedActions: SupervisorSuggestedAction[]
}
```
证据引用可以指向:
- `messageId`
- `toolCallId`
- `taskEventId`
- `artifactId`
- `metricId`
- `approvalId`
没有有效证据时,严重度最多为 `low`,且必须显示“推测”。
## 11. 确定性监督
以下检查由代码执行:
- Ask 出现写工具请求。
- 工具或路径超出计划快照。
- 未经批准的跨项目或跨分区读取。
- Token、时间、工具、Job/Subjob 和成果预算。
- 幂等键冲突或结果未知。
- 输出 Schema 不匹配。
- 实验 Run 读取其他 Run 数据。
- 硬停止条件和必填成果。
确定性监督可以阻止、暂停或终止运行。结果必须包含规则 ID、实际值、阈值和触发事件,
不通过模型重新解释才能生效。
## 12. 模型监督
适合判断:
- 回答是否偏离用户问题。
- 计划是否遗漏明确要求。
- 重要结论是否缺少证据。
- 当前回答与前文是否矛盾。
- 是否重复尝试而没有进展。
- 是否存在值得用户注意的模糊风险。
模型监督输出严格经过 Schema 校验。格式错误最多修复一次;失败不阻塞普通前台会话,
但在配置为自动化门禁时必须明确记录“监督不可用”,不能假装检查通过。
## 13. 用户交互
### 13.1 工作栏监督栏目评论流
监督是助手工作栏中固定且始终可访问的栏目,不是只在聊天页面出现的附属面板。栏目默认
跟随当前会话,用户也可以固定到其他普通 Conversation、Task、Job/Run 或 ExperimentRun。
切换页面不会改变固定目标;目标失效时必须显示修复状态,不能静默回到当前会话。
复用魔法笔记的体验方向:
- 长评卡。
- 建议卡。
- 警告卡。
- 证据链接。
- 评论方向和时间。
每条意见操作:
- 查看证据。
- 采纳建议。
- 追问。
- 忽略。
- 标记误报。
- 对自动化请求暂停。
“采纳”只是把建议带入输入框、计划草稿或任务操作,不让 Supervisor 直接执行。
### 13.2 会话输入区
会话输入区可以提供当前会话监督的快捷入口,但不是监督能力的唯一入口,也不控制工作栏中
已经固定到其他对象的监督目标:
```text
监督:关闭 / 综合 / 质疑 / 证据 / 目标 / 风险
```
这是持久二元启用加方向选择:
- 是否启用使用共享 Switch`role="switch"`
- 方向使用 `SegmentedControl` 或上下文单选菜单。
- 不把开关和方向做成一组含义不清的页签。
### 13.3 关注状态
会话或任务列表显示未解决意见数量和最高严重度,不能只用颜色。
只有 `request_review`、高风险警告或确定性暂停触发全局通知。
## 14. 解决流程
```text
open
→ acknowledged
→ resolved
→ dismissed
→ false_positive
```
- `acknowledged`:用户已查看,尚未解决。
- `resolved`:用户或后续运行说明已处理。
- `dismissed`:不采纳,但不一定是误报。
- `false_positive`:明确标记判断不正确。
后续监督输入可以包含未解决意见摘要,已解决意见默认不重复提醒。
## 15. 与任务控制的关系
Supervisor 建议“暂停”时:
1. 创建 `request_review`
2. 在任务自身的会话界面显示原因和证据。
3. 用户选择继续、暂停、调整目标或取消。
4. 用户操作进入任务审计。
确定性门禁暂停时:
1. Run 进入 `paused``waiting_approval`
2. 显示规则、阈值和实际值。
3. 只有满足规则或用户完成对应审批后才能恢复。
4. 模型评论不能覆盖门禁。
## 16. 与记忆的关系
- 监督评论默认保存在监督记录,不属于长期记忆。
- 用户采纳后可以手动创建记忆候选。
- “事实错误”“用户偏好”等监督判断不能自动写入 Project 或 Global。
- 多次被用户标记误报的模式进入监督评估数据,不直接改变 Prompt。
- 监督器可以读取绑定范围内的已确认记忆,但必须在证据中标明记忆来源。
## 17. 数据模型建议
```ts
type SupervisorSession = {
id: string
projectId?: string
targetType: 'conversation' | 'task' | 'automation_run' | 'experiment'
targetId: string
enabled: boolean
mode: 'general' | 'challenge' | 'evidence' | 'goal' | 'risk'
triggerPolicy: SupervisorTriggerPolicy
budget: SupervisorBudget
}
type SupervisorRecord = {
id: string
sessionId: string
source: 'deterministic' | 'model'
decision: SupervisorDecision
status:
| 'open'
| 'acknowledged'
| 'resolved'
| 'dismissed'
| 'false_positive'
createdAt: string
resolvedAt?: string
}
```
证据关系建议独立表或有界结构化 JSON,并在读取时重新验证对象归属。
## 18. 安全与隐私
1. Supervisor 使用独立可信系统指令,所有观察输入视为不可信数据。
2. 默认不给 Supervisor 任何工具。
3. 即使后续提供只读证据工具,也只能读取绑定对象和明确范围。
4. Supervisor 不接收 Runtime 授权回调,不能请求工具批准。
5. 普通会话监督失败不影响主回答;自动化配置的强制监督失败进入明确关注状态。
6. 评论和通知不包含完整私人消息,证据点击后才在原对象中查看。
7. Renderer 传入的 Evidence ID 必须由 Main 重新验证归属。
8. 删除会话时按产品数据保留策略删除或匿名化监督记录。
9. 用户关闭监督后停止新分析,但保留历史,除非用户明确删除。
## 19. 性能与预算
- Supervisor 使用独立后台并发池,默认全局并发 1。
- 前台回复完成后异步运行,不延迟主回答呈现。
- 同一会话同时只运行一次监督分析,新事件合并为下一次分析。
- 普通会话每 30 秒最多自动分析一次。
- 自动化按步骤或关键事件节流。
- 达到 Supervisor 预算时显示“监督已暂停”,不继续产生费用。
## 20. 实施顺序
1. 定义监督会话、记录、证据和解决状态。
2. 上线普通会话手动检查和右侧评论流。
3. 增加每次回复后异步监督、节流和预算。
4. 接入任务和自动化的确定性观察。
5. 增加目标、证据和无进展模型检查。
6. 接入实验协议一致性监督。
7. 建立误报和有用性评估,不自动改 Prompt。
## 21. 验收标准
- [ ] 监督默认关闭,用户可对单个会话显式启用。
- [ ] Supervisor 只读取当前对象的有界可见事件。
- [ ] 隐藏推理、密钥和未授权内容不进入监督输入。
- [ ] 每条中高严重度意见都有可点击证据。
- [ ] 无证据推测不会显示为高严重度事实。
- [ ] 模型监督不能自动暂停、终止、批准工具或替用户发言。
- [ ] 确定性门禁不依赖模型判断即可阻止越权和超预算行为。
- [ ] 主会话回答不等待后台 Supervisor 完成。
- [ ] 用户可采纳、忽略、标记误报和解决意见。
- [ ] 监督评论默认不进入长期记忆。
- [ ] 自动化强制监督不可用时明确请求关注,不假装检查通过。
- [ ] Supervisor 预算耗尽后停止新调用并显示状态。
+16
View File
@@ -0,0 +1,16 @@
# Task 与 Job 文档集
本目录定义 GoodBuddy 的工作对象、内部执行单元和调度关系。
## 权威文档
1. [Task 与 Job 统一领域模型](./task-and-job-model.md):术语、身份和对象关系。
2. [Task Center PRD](./task-center-prd.md)Task 的应用级索引。
3. [Scheduled Task PRD](./scheduled-task-prd.md):时间或事件触发的 Task。
4. [Goal Task PRD](./goal-task-prd.md):围绕可验证结果有界推进的 Task。
5. [Job 与 Subjob PRD](./job-and-subjob-prd.md):Task 内部串行、并行和委派执行。
## 阅读顺序
先阅读统一领域模型。其他三份文档不得重新定义 Task、Conversation、Job、Run 或 Subagent。
若实现与文档出现冲突,应先修正统一模型,再同步功能 PRD。
+53
View File
@@ -0,0 +1,53 @@
# Goal Task PRD
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 状态 | 设计中,未来能力 |
| 版本 | 0.1 |
| 日期 | 2026-08-19 |
| 依赖 | [Task 与 Job 统一领域模型](./task-and-job-model.md) |
## 1. 产品定义
Goal Task 是围绕可验证结果持续推进的 Task。它仍然只有一个 Task Conversation;每轮观察、
计划、行动和评估由 Job/Run 表达,不创建一串顶层 Task。
## 2. 必要配置
- 目标描述。
- 至少一个成功标准。
- 约束和停止条件。
- 最大轮数、截止时间或预算。
- 每轮评估方式。
- 无进展处理。
- Project、Runtime、知识、记忆、目录、工具和审批范围。
## 3. 有界循环
```text
Observe Job
→ Planning Job
→ Permission and budget check
→ Action Job / parallel Jobs
→ Evaluation Job
→ Complete, pause, revise or continue
```
循环内的所有 Job 共享 Task Conversation。只有协调器把有意义的阶段进展写入消息时间线,
避免每个内部步骤产生一条顶层任务或杂乱消息。
## 4. 完成和无进展
- 模型声明不能单独证明目标完成。
- 成功标准必须可计算或可人工审查。
- 连续两轮没有指标改善、重复下一步、连续失败、权限不可用或预算不足时暂停。
- 修改范围、预算、Runtime、工作模式或权限必须用户确认。
## 5. 验收原则
- [ ] Goal Task 只有一个 Task Conversation。
- [ ] 循环步骤以 Job 表达,不创建顶层子 Task。
- [ ] 没有成功标准和停止条件时不能启用。
- [ ] 无进展和预算耗尽不会伪装为成功。
@@ -0,0 +1,98 @@
# Job 与 Subjob PRD
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 状态 | 设计中,未来能力 |
| 版本 | 0.1 |
| 日期 | 2026-08-19 |
| 依赖 | [Task 与 Job 统一领域模型](./task-and-job-model.md) |
## 1. 目标
在不创建额外顶层 Task 或 Conversation 的前提下,让一个 Task 能够分解、串行、并行和委派
多个执行单元,并将进展和结果有序汇入 Task 的同一 Conversation。
## 2. Job 类型
首期只使用有限类型:
- `step`Task 内一个明确步骤。
- `scheduled_occurrence`Scheduled Task 的一次到期执行。
- `delegated`:交给 Subagent 或远程执行器。
- `parallel_branch`:并行方案或分工。
- `aggregation`:汇总多个前置 Job。
类型描述执行方式,不创造新的产品对象层级。
## 3. 并行模型
```text
Task Conversation
└─ Coordinating Job
├─ Parallel Job A
├─ Parallel Job B
├─ Parallel Job C
└─ Aggregation Job
```
- 并行 Job 使用同一个 `taskId``conversationId`
- 每个 Job 有独立输入快照、状态、Run、预算和输出缓冲。
- 并行 Job 不直接同时追加助手消息。
- Aggregation Job 或 Task 协调器按确定顺序生成一条进展或结果消息。
- 用户可以查看每个 Job 的详细活动,但主 Conversation 保持可读。
## 4. Subjob
Job 可以创建有界 Subjob
- 默认最大深度 2。
- 默认最大并发 3。
- 默认最大子项数、模型调用、Token、耗时和输出大小由父 Job 预算限制。
- 子级只能使用父级已授权能力的子集。
- 父级取消、失败或超时后,活动子级必须取消。
## 5. Subagent
Subagent 是 Job 的执行者:
- 专家选择和路由记录在 Job 上。
- Subagent 的原始流式输出进入有界 Job 缓冲和活动记录。
- 完成、失败和部分输出都返回父 Job。
- Subagent 不获得独立 Task Center 条目或 Conversation。
## 6. 状态与恢复
Job 状态至少包括:
```text
queued → running → waiting_approval → completed
↘ failed | cancelled | interrupted | budget_exceeded
```
- 重试创建新 Run,不覆盖失败 Run。
- 应用退出将活动 Job 标记为 `interrupted`
- 有外部副作用且结果未知的 Job 不自动重试。
- 聚合 Job 必须明确处理部分成功、全部失败和取消。
## 7. 界面
Task Conversation 显示:
- 当前总体进展。
- 并行 Job 数量和聚合状态。
- 需要审批或用户输入的 Job。
- 完成后的统一结果。
详细活动视图显示 Job 树、执行者、Runtime、耗时、预算、Run、错误和成果。Task Center 只显示
Task 聚合状态,不展开 Job 树。
## 8. 验收标准
- [ ] 并行 Job 共享所属 Task 的 Conversation。
- [ ] Job 不创建顶层 Task。
- [ ] 并行输出不会无序污染消息时间线。
- [ ] Subjob 深度、并发、预算和输出有界。
- [ ] Subagent 失败能够返回部分输出和明确状态。
- [ ] 父级取消传播到所有活动子级。
+226
View File
@@ -0,0 +1,226 @@
# Scheduled Task PRD
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 状态 | 当前基础能力已存在,扩展调度设计中 |
| 版本 | 0.4 |
| 日期 | 2026-08-19 |
| 依赖 | [Task 与 Job 统一领域模型](./task-and-job-model.md) |
| 相关架构 | [自动化平台总体设计](../../architecture/automation-platform-architecture.md) |
## 1. 产品定义
Scheduled Task 是带时间或事件触发器的 Task。它不是 Schedule 定义与临时 Task 的松散组合,
也不创建第二条 Conversation。
创建 Scheduled Task 时:
1. 创建一个 Task。
2. 为该 Task 创建唯一 Conversation。
3. 保存 Schedule/Trigger Binding。
4. 每次触发在同一 Task 内创建新的 Job 和 Run。
5. 将面向用户的进展和结果持续写回同一 Task Conversation。
因此,一个每日任务在 Task Center 中始终是一条 Task,而不是每天新增一条 Task。
## 2. 当前能力
GoodBuddy 当前支持单次、每日和每周触发固定 Ask 提示,并持久化计划、Task、运行状态和成果。
近期改进不得破坏现有数据、错过执行结算、暂停、立即运行和应用退出行为。
## 3. 目标
- 支持单次、每日、每周、每月、工作日和受限 Cron。
- 支持 Task 完成、失败、Conversation 完成等内部事件触发。
- 允许自然语言生成结构化草稿,但必须由用户检查后启用。
- 提供时区、错过执行、幂等、租约、重试、恢复、取消、预算和审计。
- 让所有重复触发复用同一 Task Conversation。
- 为一次触发建立清晰 Job/Run,而不是创建新的顶层 Task。
## 4. 非目标
- 不提供任意脚本和循环的通用 DAG 编辑器。
- 不允许模型生成并直接执行任意 Shell、SQL 或无限频率 Cron。
- 不承诺应用退出后继续运行。
- 不允许计划静默扩大权限、目录、知识或记忆范围。
- 不把 Smart Heartbeat 变成 Scheduled Task。
- 不把每次触发或重试显示为新的 Task。
## 5. 创建与配置
用户可以输入自然语言意图:
```text
每周五下午 5 点总结本项目本周完成和失败的工作,
列出下周三个优先事项,不要修改文件。
```
模型只生成草稿:
- 名称和说明。
- 时间或事件触发器。
- 工作模式和 Runtime 建议。
- Project、知识、记忆、目录和工具范围。
- 输入、输出和通知。
- 预算、并发和错过执行策略。
用户确认后,系统一次性创建 Task、Conversation 和 Schedule Binding。编辑计划只影响后续
Job;已启动 Run 使用冻结快照。
## 6. 触发器
### 6.1 时间触发
```ts
type TimeTrigger =
| { type: 'once'; at: string; timezone: string }
| { type: 'daily'; localTime: string; timezone: string }
| {
type: 'weekly'
weekdays: number[]
localTime: string
timezone: string
}
| {
type: 'monthly'
day: number | 'last'
localTime: string
timezone: string
}
| {
type: 'cron'
expression: string
timezone: string
}
```
受限 Cron 使用五字段,不支持秒、年份、宏、`L``W``#` 或供应商扩展。Main 负责解析,
默认最小间隔为 15 分钟,并展示未来五次触发时间。
### 6.2 事件触发
后续支持:
- `conversation.completed`
- `task.completed`
- `task.failed`
- `artifact.created`
- `knowledge.sync.completed`
- `magic_note.updated`
事件触发配置来源范围、确定性过滤、去重窗口、冷却时间和并发上限。基础匹配不调用模型。
### 6.3 手动触发
“立即运行”在当前 Task 内创建独立 Job 和 Run,不改变下一次计划时间,不创建新 Task。
重复点击使用调用级幂等键去重。
## 7. 一次触发的对象关系
```text
Scheduled Task
├─ Conversation(持续复用)
├─ Schedule Binding
└─ Job: scheduled_occurrence
└─ Run
```
- `scheduledFor` 和计划版本形成幂等键。
- 同一 Scheduled Task 默认最多一个活动 occurrence Job。
- 若允许并行 occurrence,它们仍属于同一 Task Conversation,并由协调器有序汇总。
- 重试产生新 Run,不产生新 Task 或新 Job。
## 8. 错过执行
| 策略 | 行为 |
| --- | --- |
| `skip` | 记录跳过,不补跑 |
| `run_once` | 无论错过多少次,只在当前 Task 内补一个 Job |
| `catch_up_bounded` | 在数量和时间窗口上限内创建多个有界 Job |
默认补跑最多 3 次、最多回溯 7 天。补跑同样受 Task 的并发、权限和预算控制。
## 9. 时区和夏令时
- 保存 IANA 时区,不保存固定 UTC 偏移。
- 春季不存在的本地时间在当日第一个有效分钟触发。
- 秋季重复时间只触发一次。
- 系统时区变化不自动修改计划时区。
- UI 显示计划时区、本机时区差异和未来触发时间。
## 10. Ask、Execute 与审批
第一阶段保持 Ask
- Runtime 边界只读。
- 不写文件、不执行命令、不发送消息、不修改远程数据。
- 输出写回 Task Conversation;独立交付物才进入成果。
Execute 按顺序开放:
1. 有人值守,沿用逐工具审批。
2. 预批准低风险工具和参数范围。
3. 经过专项验证的内置无人值守模板。
高风险、越界或未预授权动作进入 `waiting_approval`,不能因定时触发而绕过策略。
## 11. 预算与背压
每个 Scheduled Task 配置:
- 最大 Job 耗时。
- 最大模型、Token 和工具调用。
- 最大成果大小。
- 最大活动 Job 数。
- 后台优先级。
前台请求优先。后台达到上限时延后并记录 `deferred`,不能挤占用户正在等待的请求,也不能
在恢复空闲时一次释放全部积压。
## 12. 重试、恢复和取消
- 瞬时、无副作用失败可以有界重试。
- 配置、权限和范围错误不重试。
- 外部副作用结果未知时进入 `outcome_unknown`,不自动重试。
- 应用退出将活动 Job/Run 标记为 `interrupted`
- 暂停计划只阻止新 Job,不假装取消已发生的外部操作。
- 取消 Task 必须传播到活动 Job、Subjob 和 Runtime。
## 13. 界面
Task Center 显示 Scheduled Task 的范围、状态、最近进展、需要关注和下次触发时间。点击条目
打开同一 Task Conversation。
Task 内可查看:
- 计划和触发器。
- 下次执行和未来预览。
- 每次 occurrence Job。
- Run、审批、活动和成果。
不新增平行 Automation Center。
## 14. 兼容迁移
现有 Schedule、Schedule Run、Task 和 Conversation 数据渐进关联:
- 保留现有计划 ID、启停状态、下次时间和历史。
- 为每个现有计划建立或绑定一个持续 Task Conversation。
- 历史每次执行映射为该 Task 下的 occurrence Job/Run。
- 迁移不得复制消息、成果或顶层 Task。
## 15. 验收标准
- [ ] 创建 Scheduled Task 只创建一个 Task 和一个 Conversation。
- [ ] 重复触发始终复用该 Task Conversation。
- [ ] 每次触发创建 Job/Run,不创建新的顶层 Task。
- [ ] 支持单次、每日、每周、每月、工作日和受限 Cron。
- [ ] UI 显示计划时区和未来五次触发时间。
- [ ] 夏令时不会造成漂移或双跑。
- [ ] 错过执行按配置跳过、补一次或有界补跑。
- [ ] 手动运行不改变下次计划时间。
- [ ] Ask 在 Runtime 边界拒绝写操作和外部副作用。
- [ ] 应用重启不自动重放结果未知的副作用。
- [ ] Task Center 不因重复触发新增条目。
+151
View File
@@ -0,0 +1,151 @@
# Task 与 Job 统一领域模型
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 状态 | 产品边界已确认,部分能力待实施 |
| 版本 | 0.1 |
| 日期 | 2026-08-19 |
| 适用产品 | GoodBuddy 桌面端 |
| 文档角色 | Task、Conversation、Job、Run 与 Subagent 的权威定义 |
## 1. 核心定义
### 1.1 Task
Task 是用户明确创建或由已启用计划创建的工作单位,也是 Task Center 的顶层对象。
- 创建 Task 就创建一条新的 Conversation。
- Task 的内容载体是这条 Conversation,不再维护第二份任务正文或消息时间线。
- 打开 Task 就打开其 Conversation。
- Task 的目标、状态、范围、计划、Job、审批、活动和成果都围绕同一 Conversation 组织。
- 一个 Task 在生命周期内保持同一个 `taskId``conversationId` 绑定。
普通 Conversation 不自动成为 Task。用户只是聊天时,不应因为存在模型调用或工具步骤就
产生顶层 Task。
### 1.2 Conversation
Conversation 是 Task 的交互和内容载体:
- 保存用户消息、助手消息和面向用户的进展。
- 承载同一 Task 内多个 Job 的可理解汇总。
- 不让并行 Job 直接无序写入同一消息流;由 Task 协调器合并进展和结果。
- 删除、归档和切换范围时遵循 Task 的生命周期规则。
### 1.3 Job
Job 是 Task 内部的执行单位,不是新的顶层 Task:
- 一次计划触发、一个执行步骤、一项专家委派或一组并行工作都可以是 Job。
- 一个 Task 可以串行或并行运行多个 Job。
- 所有 Job 仍属于同一个 Task 和同一条 Conversation。
- Job 可以有自己的状态、预算、Runtime、执行者、输入快照和成果引用。
- Job 不进入 Task Center;它显示在 Task 的时间线、活动或 Runtime 视图中。
### 1.4 Subjob
Subjob 是 Job 的子执行单元。它用于分解和并发,不创建新的 Task 或 Conversation。
- 父 Job 负责合并 Subjob 结果。
- 取消父 Job 必须传播到仍活动的 Subjob。
- Subjob 不能扩大父 Job 的项目、目录、工具、知识、记忆或审批范围。
- 深度、数量、并发、时间、Token 和输出大小必须有界。
### 1.5 Run
Run 是 Task 或 Job 的一次执行尝试和审计记录,不是用户工作对象:
- 重试、恢复或手动重新运行可以产生新的 Run。
- Run 冻结当次配置、范围、预算和 Runtime。
- Run 进入活动记录和审计,不进入 Task Center。
- `completed` 只表示该次执行按协议结束,不必然表示 Task 目标达成。
### 1.6 Subagent
Subagent 是执行 Job 或 Subjob 的受限执行者,不是对象层级:
- 专家、Agent Runtime 或其他执行器可以承担 Job。
- Subagent 不自动拥有独立 Task 或 Conversation。
- Subagent 输出先回到所属 Job,再由 Task 协调器写入同一 Conversation。
## 2. 对象关系
```text
Task 1 ── 1 Conversation
├─ Schedule / Trigger Binding(可选)
├─ Job 1
│ ├─ Run 1..N
│ └─ Subjob 0..N
├─ Job 2(可与 Job 1 并行)
└─ Artifact / Approval / Activity / Notification
```
不允许:
```text
Task → 第二条 Conversation
Job → 新建顶层 Task
Subagent → 自动新建 Conversation
Run → 出现在 Task Center
```
## 3. Scheduled Task
Scheduled Task 仍然是 Task,而不是独立的自动化对象:
1. 用户创建 Scheduled Task。
2. 系统创建一个 Task 和一个 Conversation,并保存 Schedule/Trigger Binding。
3. 到期时在该 Task 内创建新的 Job 和 Run。
4. 每次触发的进展和结果汇入同一个 Task Conversation。
5. 编辑计划影响后续 Job,不修改已经启动的 Run。
同一 Scheduled Task 默认串行触发。需要并行时,应显式允许多个 Job 并发,并继续使用同一
Conversation,而不是复制 Task。
## 4. 状态分层
| 层级 | 典型状态 | 用户在哪里看到 |
| --- | --- | --- |
| Task | queued、running、waiting_approval、paused、completed、failed、cancelled、interrupted | Task Center、Task Conversation |
| Job | queued、running、waiting、completed、failed、cancelled | Task 时间线、活动、Runtime |
| Run | claimed、running、completed、failed、cancelled、interrupted、budget_exceeded | 活动与审计 |
Task 状态由当前目标和所属 Job 聚合得出,但不能用“任一 Job 完成”直接推断 Task 完成。
## 5. 兼容映射
当前代码和旧文档中的对象按以下方式收敛:
| 旧概念 | 目标概念 |
| --- | --- |
| 自动任务 | Scheduled Task、Event Task 或 Goal Task |
| 自动会话 | 删除该独立概念,使用 Task Conversation |
| 子任务、Child Task | Job 或 Subjob |
| 专家子任务 | 由专家 Subagent 执行的 Job/Subjob |
| 多任务并行 | 一个 Task 内多个并行 Job;确实独立的用户目标才创建多个 Task |
| Schedule Run | Scheduled Task 内的 Job Run |
| Automation Run | Task 或 Job 的 Run |
数据库字段可以在兼容期保留旧名称,但新产品文案、PRD 和新增契约必须使用本模型。
## 6. 安全和数据要求
- Main 验证 Task、Conversation、Job、Run 和 Project 的归属链。
- Renderer 不能把任意 Job 绑定到其他 Task 或 Conversation。
- Job/Subjob 继承父级能力上限,只能缩小,不能扩大。
- 并行输出先有界持久化,再按确定顺序汇总到 Conversation。
- 取消、超时、审批和应用退出必须沿 Task → Job → Subjob → Runtime 传播。
- 用户删除 Task 时,先处理活动 Job,再按数据保留规则清理关联对象。
## 7. 验收原则
- [ ] 创建 Task 时只创建一条对应 Conversation。
- [ ] Scheduled Task 的重复触发复用同一 Task Conversation。
- [ ] 一个 Task 可以在同一 Conversation 下运行多个并行 Job。
- [ ] Job、Subjob、Run 和 Subagent 不进入 Task Center。
- [ ] 并行 Job 不直接无序写入 Conversation。
- [ ] 取消和权限范围能够沿层级正确传播。
- [ ] 新文档不再把 Job/Subjob 定义为新的顶层 Task。
+59
View File
@@ -0,0 +1,59 @@
# Task Center PRD
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 状态 | 设计中 |
| 版本 | 0.1 |
| 日期 | 2026-08-19 |
| 依赖 | [Task 与 Job 统一领域模型](./task-and-job-model.md) |
| 界面归属 | [通用助手工作栏与执行空间](../assistant-experience/assistant-workbar-and-execution-spaces-prd.md) |
## 1. 产品定义
Task Center 是所有 Task 的应用级单例索引。它不是第二份任务数据,也不是 Automation
Center。点击条目直接打开 Task 自身的 Conversation。
## 2. 收录边界
收录:
- 用户明确创建的 Task。
- Scheduled Task、Event Task 和 Goal Task。
- 未来由用户确认创建的其他顶层 Task。
不收录:
- 普通 Conversation。
- Job、Subjob、Run、工具步骤或 Subagent。
- Smart Heartbeat 配置、报告和建议。
- 仅用于审计的活动记录。
## 3. 列表信息
每条 Task 至少显示:
- 名称和 Global / Project 范围。
- Task 类型和触发来源。
- 当前聚合状态。
- 最近一次面向用户的进展。
- 最近活动时间。
- 等待审批、失败或需要关注数量。
- 下次计划时间(如适用)。
## 4. 交互
- 点击条目打开 Task Conversation。
- 支持按需要关注、进行中、已暂停、已结束筛选。
- 支持暂停、恢复、取消和打开详情,但不在窄栏复制完整 Job 时间线。
- 后台变化更新状态和徽标,不自动抢占当前页面。
- Task 的计划、Job、Run、审批和成果在 Task 自身或对应活动视图管理。
## 5. 验收标准
- [ ] Task Center 只展示 Task。
- [ ] 点击 Task 不会跳转到另一条内容相同的附属 Conversation。
- [ ] Job/Subjob/Run 不会重复成为顶层条目。
- [ ] Scheduled Task 显示下次时间,但每次触发不新增 Task 条目。
- [ ] Smart Heartbeat 不进入 Task Center。