docs: 巡检简报+todo 回写(2026-06-15 第2轮)
巡检发现:
- 2196c77 workflow 整文件替换回退破坏(AiChat+Ideas 12项功能)
- B-260615-03 truncated 标志已落地
- AR-8-scroll scrollToBottom smooth 已补
- CR-260615-09 .ai-md 残余:4详情页各21处 scoped .ai-md
(全局 ai-md.css 75行已建,旧副本待清理但非阻塞)
This commit is contained in:
282
docs/02-架构设计/aichat授权体验改进方案-2025-07-15.md
Normal file
282
docs/02-架构设计/aichat授权体验改进方案-2025-07-15.md
Normal file
@@ -0,0 +1,282 @@
|
||||
# AIChat 授权功能体验改进方案
|
||||
|
||||
> 创建: 2025-07-15 | 状态: 待讨论
|
||||
|
||||
## 一、当前授权机制概览
|
||||
|
||||
### 1.1 核心流程
|
||||
|
||||
```
|
||||
用户发送消息
|
||||
→ Agentic Loop (最多 10 轮)
|
||||
→ LLM 流式响应
|
||||
→ 解析 tool_calls
|
||||
→ 按风险等级分流:
|
||||
├─ Low Risk → 自动并行执行(join_all)
|
||||
├─ Medium → 暂停循环,等待人工审批
|
||||
└─ High → 暂停循环,等待人工审批
|
||||
→ 审批通过 → 执行工具 → try_continue_agent_loop 恢复循环
|
||||
→ 审批拒绝 → tool_result="用户拒绝了此操作" → 恢复循环让 LLM 自行决策
|
||||
```
|
||||
|
||||
### 1.2 工具风险分级矩阵
|
||||
|
||||
| 风险等级 | 工具 | 执行方式 |
|
||||
|---------|------|---------|
|
||||
| **Low** | `list_projects`, `list_tasks`, `list_ideas`, `list_trash`, `read_file`, `list_directory` | 自动执行,并行 `join_all` |
|
||||
| **Medium** | `create_project`, `create_task`, `create_idea`, `update_project`, `update_task`, `bind_directory`, `write_file` | 需人工审批 |
|
||||
| **High** | `delete_project`, `restore_project`, `purge_project`, `delete_task`, `run_workflow`, `run_command` | 需人工审批 |
|
||||
|
||||
### 1.3 已实现的亮点
|
||||
|
||||
- **审计留痕**:`ai_tool_executions` 表完整记录每次工具调用的状态、风险等级、决策者、请求时间和执行时间
|
||||
- **断点恢复**:应用重启后通过 `restore_pending_approvals()` 从数据库重建内存中的待审批状态
|
||||
- **审批卡片可读化**:`build_approval_reason()` 解析工具参数,拼接人类可读的审批理由
|
||||
- **generating 状态 RAII 守护**:`GeneratingGuard` 确保无论正常退出还是 panic,`generating` 标志都能复位
|
||||
- **数据变更联动刷新**:工具执行成功后自动 emit `df-data-changed` 事件,前端自动刷新列表
|
||||
- **安全防护**:API Key 存 OS keyring、文件路径双层校验、write_file 覆盖前自动 .bak 备份 + 原子写
|
||||
|
||||
### 1.4 关键代码位置
|
||||
|
||||
| 模块 | 文件 | 职责 |
|
||||
|------|------|------|
|
||||
| 工具注册表 | `src-tauri/src/commands/ai/tool_registry.rs` | 工具定义 + 风险等级 + handler 同源 |
|
||||
| 审批处理 | `src-tauri/src/commands/ai/audit.rs` | 工具调用审计 + pending 审批恢复 + 审批后状态回填 |
|
||||
| Agentic 循环 | `src-tauri/src/commands/ai/agentic.rs` | 流式接收 → 工具执行 → 结果回传 LLM → 循环 |
|
||||
| IPC 命令 | `src-tauri/src/commands/ai/commands.rs` | `ai_approve` / `ai_chat_send` / `ai_chat_stop` 等 |
|
||||
| 审批卡片 UI | `src/components/ToolCard.vue` | 卡片渲染 + 参数展示 + 批准/拒绝按钮 |
|
||||
| 卡片列表 | `src/components/ToolCardList.vue` | 多卡片折叠管理 |
|
||||
| 聊天面板 | `src/components/AiChat.vue` | 消息列表 + 审批转发 + 输入区 |
|
||||
| AI Store | `src/stores/ai.ts` | 模块级单例 state |
|
||||
| 发送/审批 | `src/composables/ai/useAiSend.ts` | `approveToolCall` 乐观更新 + IPC 调用 |
|
||||
|
||||
---
|
||||
|
||||
## 二、用户体验痛点分析
|
||||
|
||||
### 痛点 1:逐个审批,无法批量操作
|
||||
|
||||
**现象**:当 AI 一次返回多个 Medium/High 工具调用时(比如同时创建 3 个任务 + 写 2 个文件),用户需要逐个点批准/拒绝。
|
||||
|
||||
**根因**:`process_tool_calls`(audit.rs)把每个待审批工具都推入 `pending_approvals` HashMap,前端为每个 pending 渲染独立的 ToolCard,每个卡片只有自己的"批准/拒绝"按钮。`ToolCardList.vue` 没有批量操作入口。
|
||||
|
||||
**影响**:高频交互场景下审批变成体力活,用户体验疲劳。
|
||||
|
||||
### 痛点 2:审批阻塞整个对话,期间无法输入
|
||||
|
||||
**现象**:审批等待期间 `generating=true`,用户虽然能上滑看历史,但无法发送新消息(`sendMessage` 会入队),也无法预知还有多少审批在排队。
|
||||
|
||||
**根因**:`ai_chat_send`(commands.rs:46)检查 `session.generating` 为 true 时拒绝新消息。审批等待期间 `generating` 保持 true(`agentic.rs` 的 `guard.disarm()` 保持 true 以便 `try_continue` 续生成)。
|
||||
|
||||
**影响**:用户处于"被动等待"状态,无法并行做其他事。
|
||||
|
||||
### 痛点 3:Medium 和 High 体验无差异
|
||||
|
||||
**现象**:两者都弹同样的审批卡片、同样的按钮,交互流程完全一致。
|
||||
|
||||
**根因**:`process_tool_calls`(audit.rs:103-120)中 Medium 和 High 走同一个 `pending_approvals.insert` 分支,区别仅在 `build_approval_reason` 的文案后缀("请确认是否执行" vs "高风险,需人工批准")。
|
||||
|
||||
**影响**:High 操作(如 `purge_project` 不可恢复)缺乏足够的警示力度,容易误操作。
|
||||
|
||||
### 痛点 4:write_file 审批信息不够直观
|
||||
|
||||
**现象**:`write_file` 是 Medium 风险,审批卡片只展示 path 和 content 参数。content 可能是几百行代码,在审批卡片里以 `formatArgValue` 截断到 300 字符展示。
|
||||
|
||||
**根因**:`ToolCard.vue` 的 `toolArgsEntries` → `displayArgValue` → `formatArgValue` 对超长值统一截断到 300 字符。
|
||||
|
||||
**影响**:用户无法看清要写入的完整内容,只能盲目批准。尤其覆盖已有文件时,用户不知道会改什么。
|
||||
|
||||
### 痛点 5:审批后无进度反馈
|
||||
|
||||
**现象**:点击"批准"后,卡片乐观置 `running`,但用户不知道:
|
||||
- 工具正在执行还是已执行完等待 LLM 续生成
|
||||
- 还有多少待审批在排队
|
||||
- 整个 agentic 循环进行到第几轮
|
||||
|
||||
**根因**:前端没有全局的 agentic 循环进度指示器。`AiAgentRound` 事件虽然通知了轮次,但没有在 UI 上持久化展示。
|
||||
|
||||
**影响**:用户对系统状态缺乏掌控感,尤其在多轮工具调用时。
|
||||
|
||||
### 痛点 6:审批卡片可能被滚出视口
|
||||
|
||||
**现象**:当消息很多时,审批卡片可能被新消息推到上方滚出视口。
|
||||
|
||||
**根因**:`AiChat.vue` 的 `collapseInactive` 不会收起 `pending_approval` 卡片,但也不会自动滚动到 pending 卡片。没有全局徽标提醒。
|
||||
|
||||
**影响**:用户可能看不到待审批项,对话看起来"卡住了"但不知道在等什么。
|
||||
|
||||
---
|
||||
|
||||
## 三、改进方案
|
||||
|
||||
### P0 — 快速改善体感
|
||||
|
||||
#### 3.1 批量审批
|
||||
|
||||
**方案**:当同一轮有多个 pending 时,在 ToolCardList 顶部显示"全部批准(N) / 全部拒绝"按钮。
|
||||
|
||||
**改动范围**:
|
||||
- `ToolCardList.vue`:新增批量操作栏,监听 toolCalls 中 pending_approval 数量
|
||||
- `useAiSend.ts`:新增 `approveAll(rejectAll)` 方法,循环调用 `ai_approve`
|
||||
|
||||
**交互**:
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ ⏳ 3 项待审批 │
|
||||
│ [✓ 全部批准] [✕ 全部拒绝] │
|
||||
├─────────────────────────────────┤
|
||||
│ [工具卡片 1 - pending] │
|
||||
│ [工具卡片 2 - pending] │
|
||||
│ [工具卡片 3 - pending] │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 3.2 审批计数器 + 跳转
|
||||
|
||||
**方案**:在输入框上方或 header 显示 `⏳ 2 项待审批`,点击跳转到第一个 pending 卡片。
|
||||
|
||||
**改动范围**:
|
||||
- `AiChat.vue`:header 区域增加审批徽标
|
||||
- `ToolCardList.vue`:暴露 `scrollToFirstPending` 方法
|
||||
|
||||
**交互**:
|
||||
```
|
||||
┌──────────────────────────────────┐
|
||||
│ 🤖 助手 ⏳2 [+][×] │ ← 徽标在 header
|
||||
├──────────────────────────────────┤
|
||||
│ ...消息列表... │
|
||||
│ ┌─ 工具卡片 (pending) ──┐ │ ← 点击徽标滚动到此
|
||||
│ │ 创建任务:XXX │ │
|
||||
│ │ [批准] [拒绝] │ │
|
||||
│ └────────────────────────┘ │
|
||||
├──────────────────────────────────┤
|
||||
│ [输入框] │
|
||||
└──────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 3.3 write_file diff 预览
|
||||
|
||||
**方案**:write_file 审批时,如果文件已存在,展示前后对比 diff 而非裸 content。
|
||||
|
||||
**改动范围**:
|
||||
- 后端 `tool_registry.rs`:write_file handler 在执行前读取旧文件内容,返回 diff 信息(或前端请求 diff)
|
||||
- `ToolCard.vue`:pending_approval + name=write_file 时渲染 diff 视图
|
||||
|
||||
**交互**:
|
||||
```
|
||||
┌─ 写入文件 src/main.rs (待审批) ──────┐
|
||||
│ │
|
||||
│ - fn main() { │ ← 红色:删除行
|
||||
│ - println!("hello"); │
|
||||
│ + fn main() { │ ← 绿色:新增行
|
||||
│ + println!("hello, world"); │
|
||||
│ + setup_logging(); │
|
||||
│ │
|
||||
│ ⚠ 覆盖已有文件 (23→45 行) │
|
||||
│ [查看完整内容] [批准] [拒绝] │
|
||||
└───────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### P1 — 增强控制力
|
||||
|
||||
#### 3.4 自动审批策略(信任模式)
|
||||
|
||||
**方案**:Settings 中增加"自动审批"配置,用户可选择对特定风险等级或工具类型自动放行。
|
||||
|
||||
**配置项**:
|
||||
```
|
||||
Settings → AI → 自动审批策略
|
||||
○ 严格模式(默认):所有 Medium/High 需人工审批
|
||||
○ 宽松模式:Medium 自动放行,High 需人工审批
|
||||
○ 自定义:按工具类型选择
|
||||
☑ write_file(workspace 内自动放行)
|
||||
☑ create_task / create_idea(自动放行)
|
||||
☐ delete_*(始终需审批)
|
||||
☐ run_command(始终需审批)
|
||||
```
|
||||
|
||||
**改动范围**:
|
||||
- `df-storage`:`app_settings` 表存储配置(KV 已有 V13 表)
|
||||
- `audit.rs`:`process_tool_calls` 读取配置,决定 Medium 工具是否进 pending 或直接执行
|
||||
- `Settings.vue`:新增配置面板
|
||||
|
||||
#### 3.5 High 二次确认
|
||||
|
||||
**方案**:delete/purge/run_command 等高风险操作,批准后弹出二次确认。
|
||||
|
||||
**改动范围**:
|
||||
- `ToolCard.vue`:High 风险 + approved=true 时,先弹 inline 确认("确定要永久删除?此操作不可恢复")
|
||||
- 或用现有 `ConfirmDialog` 组件
|
||||
|
||||
**交互**:
|
||||
```
|
||||
第一次点击"批准":
|
||||
→ 卡片内弹出确认提示
|
||||
→ "确定要永久删除项目「XXX」?此操作不可恢复"
|
||||
→ [确认删除] [取消]
|
||||
|
||||
第二次点击"确认删除":
|
||||
→ 才真正执行 ai_approve
|
||||
```
|
||||
|
||||
#### 3.6 审批超时
|
||||
|
||||
**方案**:可配置超时自动拒绝(默认 5 分钟),避免对话永久卡住。
|
||||
|
||||
**改动范围**:
|
||||
- 后端:`AiSession` 增加 pending 审批的 `created_at` 时间戳,定时检查超时
|
||||
- 或前端:`useAiSend.ts` 在 pending 时启动定时器,超时自动调 `ai_approve(id, false)`
|
||||
|
||||
---
|
||||
|
||||
### P2 — 信息透明度
|
||||
|
||||
#### 3.7 Agentic 进度条
|
||||
|
||||
**方案**:在消息区域底部显示循环进度。
|
||||
|
||||
**改动范围**:
|
||||
- `AiChat.vue`:底部增加进度指示条
|
||||
- `useAiEvents.ts`:处理 `AiAgentRound` 事件时更新进度
|
||||
|
||||
**交互**:
|
||||
```
|
||||
┌──────────────────────────────────┐
|
||||
│ ...消息列表... │
|
||||
│ │
|
||||
│ 🔄 循环 3/10 · ⏳2待审批 · ✅5完成 │ ← 底部进度条
|
||||
├──────────────────────────────────┤
|
||||
│ [输入框] │
|
||||
└──────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 3.8 审批历史面板
|
||||
|
||||
**方案**:独立页面展示 `ai_tool_executions` 表的审计记录。
|
||||
|
||||
**改动范围**:
|
||||
- 后端:新增 `list_tool_executions` IPC 命令(查询审计表)
|
||||
- 前端:新增 `AuditLog.vue` 视图,表格展示历史记录
|
||||
|
||||
**展示字段**:
|
||||
| 时间 | 工具 | 风险 | 状态 | 决策者 | 参数摘要 | 结果摘要 |
|
||||
|------|------|------|------|--------|---------|---------|
|
||||
|
||||
---
|
||||
|
||||
## 四、实施优先级建议
|
||||
|
||||
| 优先级 | 改进项 | 预估工作量 | 用户价值 |
|
||||
|--------|--------|-----------|---------|
|
||||
| **P0** | 3.1 批量审批 | 0.5 天 | 🔥🔥🔥 |
|
||||
| **P0** | 3.2 审批计数器 + 跳转 | 0.5 天 | 🔥🔥🔥 |
|
||||
| **P0** | 3.3 write_file diff 预览 | 1 天 | 🔥🔥 |
|
||||
| **P1** | 3.4 自动审批策略 | 1.5 天 | 🔥🔥🔥 |
|
||||
| **P1** | 3.5 High 二次确认 | 0.5 天 | 🔥 |
|
||||
| **P1** | 3.6 审批超时 | 0.5 天 | 🔥 |
|
||||
| **P2** | 3.7 Agentic 进度条 | 0.5 天 | 🔥🔥 |
|
||||
| **P2** | 3.8 审批历史面板 | 1 天 | 🔥 |
|
||||
|
||||
**建议第一批落地**:P0 三项(批量审批 + 计数器 + diff 预览),总计约 2 天工作量,覆盖最高频的体验痛点。
|
||||
Reference in New Issue
Block a user