# 构想:对话 AI 异步审批 — 2026-06-14 > 性质:功能升级构想,未实现。记录用户提出的方向 + 可行性评估。 ## 构想 对话 AI 的对话与审批改成**异步审批**:审批 pending 时不卡住整个对话,用户可继续聊别的,审批挂着随时处理。 ## 痛点:当前同步审批卡住对话 当前审批是同步阻塞模型: 1. LLM 返回 Medium/High `tool_calls` → `process_tool_calls`(`audit.rs:170-191`)推 `pending_approvals` + 占位 `tool_result`("需要用户审批,等待确认")→ agentic loop `return`(`agentic.rs:184-192`),**`generating` 保持 true**。 2. 等待期间:`session.generating = true` → 新 `ai_chat_send` 直接 `Err("AI 正在生成中")`(`commands.rs:45`)→ 前端 `sendMessage` 把新消息入队(`useAiSend.ts:36`),`streaming = true` 输入框变停止按钮。 3. 用户必须先审批(或 stop)才能继续对话。**整个对话被审批阻塞。** 典型困扰:AI 提出待审批操作,用户想先问个别的(比如"等等,这个项目之前是不是建过?"),被阻塞,必须先处理审批。 ## 难点分析 异步审批的真正难点不在 UI,而在 **agent loop 的语义**: - 同步模型:LLM 发 tool_call → 占位 tool_result → loop 挂起 → 审批后 tool_result 替换为真实结果 → LLM 据真实结果生成下一步。上下文连贯。 - 异步模型:若审批 pending 时对话继续,LLM 已基于"占位结果"生成后续 → 审批结果回流时上下文已前进 → 不一致。 核心瓶颈是 `AiSession` 单例 + `generating` 单标志互斥(防并发混乱)。异步审批 + 并发对话需要 AiSession 多实例化或 sub-session——正是 [[aichat-arch-extensibility]] 记录的"剩四空壳/AiSession 单例未动"部分,属 B 路线。 ## 方案分两档 ### 档位一:轻量 — 跨对话异步(推荐先做) 审批 pending 的对话挂起(释放 generating 锁),用户**切到别的对话**继续聊,审批在原对话挂着,通过后结果回流原对话。 - 触及:AiSession 从单例 → 多对话独立状态(每对话一个活跃 loop 槽)。 - 不触及:同对话内 agent loop 语义不变(同对话内审批仍阻塞)。 - 复杂度:中等,是 B 路线(AiSession 多实例化)的一部分。 - 价值:解决"审批时想干别的"主诉求(切对话即可),不破坏 agent 语义。 ### 档位二:完整 — 同对话异步 审批不阻塞同一对话,用户在同一对话里继续发消息,审批通过后工具结果作为新上下文回流。 - 触及:agent loop 语义重设计——LLM 上下文如何处理"待执行工具"(标记转审批?LLM 基于"已转人工"假设继续?)。 - 可能形态:审批转独立审批队列/通知中心,对话流遇到待审批工具不阻塞,告知"有 N 个待审批"后继续;审批通过后台执行工具,结果追加为新消息。 - 复杂度:高,接近重做 agent loop。 - 风险:LLM 上下文一致性、工具结果时效性、多任务并发安全。 ## 评估 | 维度 | 档位一(跨对话异步) | 档位二(同对话异步) | |------|---------------------|----------------------| | 解决主诉求 | ✅ 切对话即可继续 | ✅ 同对话继续 | | 架构改动 | AiSession 多实例化 | agent loop 语义重设计 | | 与 B 路线 | 一部分 | 接近独立重做 | | 风险 | 中(并发状态管理) | 高(上下文一致性) | | 建议 | 先做 | 评估后定 | **建议**:作为 B 路线一部分,先做档位一(跨对话异步),需先完成 AiSession 多实例化。档位二待 agent 能力升级时再评估。 ## 关联 - 触及 [[aichat-arch-extensibility]] 记录的 AiSession 单例瓶颈。 - 与 [[aichat-roadmap-ab-split]] B 路线(补决策/并发能力)相关。 - 当前同步审批的其他问题(审批态 stop 卡死、新建对话破坏 session)见 `aichat审查报告-2026-06-14.md` H2/H3,异步化时一并解决。