Files
DevFlow/docs/02-架构设计/构想审查/aichat授权体验改进方案-2026-06-14.md
绝尘 998a2f243d 文档: 架构方案文档(意图识别论证+多主题愿景/论证+文档物理分类+边界清晰化)
squash合并:
- 意图识别层论证(8维度+10业界佐证)
- 多主题上下文管理愿景+并存论证+补充论证(多轮agentic)
- 架构设计文档物理分类(四子目录+INDEX+命名规范+引用同步+边界清晰化)
- 前端架构技术债清单归档
2026-06-19 15:04:04 +08:00

285 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AIChat 授权功能体验改进方案
> 创建: 2026-06-14 | 状态: 待讨论
## 一、当前授权机制概览
### 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` 续生成)。
**影响**:用户处于"被动等待"状态,无法并行做其他事。
### 痛点 3Medium 和 High 体验无差异
**现象**:两者都弹同样的审批卡片、同样的按钮,交互流程完全一致。
**根因**`process_tool_calls`audit.rs:103-120中 Medium 和 High 走同一个 `pending_approvals.insert` 分支,区别仅在 `build_approval_reason` 的文案后缀("请确认是否执行" vs "高风险,需人工批准")。
**影响**High 操作(如 `purge_project` 不可恢复)缺乏足够的警示力度,容易误操作。
### 痛点 4write_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 会话级授权 Session Trust
**方案**:引入会话级信任机制,替代全局宽松模式。用户在当前对话中一次性授权某目录的写/执行权限,后续该对话内同类操作自动放行。切换对话或新建对话时信任清空。
**配置项**
```
当前会话信任目录:
✅ E:/wk-lab/devflow/src (Write + Execute)
✅ E:/wk-lab/devflow/docs (Write)
+ 添加目录...
```
**改动范围**
- 前端Settings 或对话 header 新增「信任管理」入口
- 后端:`AiSession` 增加 `trusted_dirs: HashSet<(PathBuf, TrustLevel)>`
- `audit.rs``process_tool_calls` 先查 session trust命中则跳过 pending
**安全边界**
- 仅纯读取操作list_*/read_*/list_directory保持自动放行
- 所有 create/update/bind/write/delete 操作默认需审批或 session-trust
- bind_directory 归类为修改操作
- 信任仅限当前会话内存,不持久化
#### 3.5 High 二次确认
**方案**delete/purge/run_command 等高风险操作,批准后弹出二次确认。
**改动范围**
- `ToolCard.vue`High 风险 + approved=true 时,先弹 inline 确认("确定要永久删除?此操作不可恢复"
- 或用现有 `ConfirmDialog` 组件
**交互**
```
第一次点击"批准":
→ 卡片内弹出确认提示
→ "确定要永久删除项目「XXX」此操作不可恢复"
→ [确认删除] [取消]
第二次点击"确认删除":
→ 才真正执行 ai_approve
```
#### 3.6 审批超时(前端定时器)
**方案**:前端侧 5 分钟超时自动拒绝,避免对话永久卡住。超时策略独立于 Webhook 等外部动作路径。
**改动范围**
- 前端:`useAiSend.ts` 在 pending 时启动 5min 定时器,超时自动调 `ai_approve(id, false)`
- 不改后端 AiSession 结构(远期 Webhook 走独立路径)
---
### 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 会话级授权 Session Trust | 1.5 天 | 🔥🔥🔥 |
| **P1** | 3.5 High 二次确认 | 0.5 天 | 🔥 |
| **P1** | 3.6 审批超时(前端5min) | 0.5 天 | 🔥 |
| **P2** | 3.7 Agentic 进度条 | 0.5 天 | 🔥🔥 |
| **P2** | 3.8 审计历史面板 | 1 天 | 🔥 |
**建议第一批落地**P0 三项(批量审批 + 计数器 + diff 预览),总计约 2 天工作量,覆盖最高频的体验痛点。