Files
X-Financial/docs/superpowers/specs/2026-06-24-workbench-intent-frame-design.md

216 lines
9.3 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.
# AI 工作台统一意图识别框架设计
## 背景
AI 工作台当前的输入识别分散在多个前端 flow 中:申请预览、报销草稿、单据查询、草稿删除提示各自判断输入。这样的结构能快速修复单点问题,但会让“删除 3 天前的草稿”“审核合规没有风险的申请”这类组合型请求继续变成关键词补丁。
本设计把自然语言输入先统一解析成结构化 `IntentFrame`,再根据目标是否明确、安全等级和业务边界决定下一步动作。
## 目标
- 让工作台所有自然语言输入先进入统一意图框架,不再在各业务 flow 中散落判断。
- 支持动作、对象、筛选条件、上下文指代、安全等级的组合识别。
- 对删除、审核、驳回等高风险动作固定走“筛选候选 + 详情确认”,禁止自然语言直接执行。
- 保留当前会话内的快速指代能力,例如“删除刚才那个草稿”能定位最近创建的草稿。
- 对带筛选条件的请求,例如“删除 3 天前的草稿”“审核无风险申请”,先展示思考过程和候选列表。
## 非目标
- 第一版不引入 LangGraph也不把前端本地识别迁到后端状态机。
- 第一版不做自然语言直接批量删除、批量审核或批量驳回。
- 第一版不改后端审批、删除接口的权限模型。
- 第一版不重写现有申请预览和报销草稿流程,只把入口识别前置统一。
## 总体架构
统一意图识别分三层:
1. `IntentFrame Parser`:把用户输入解析为结构化意图。
2. `Target Resolver`:结合当前会话、最近动作和筛选条件,判断目标是否唯一。
3. `Action Policy`:根据动作风险决定直接查询、展示候选、要求澄清或阻断。
输入链路应调整为:
```text
用户输入
-> IntentFrame Parser
-> Action Policy
-> Target Resolver
-> 业务 flow
- 查询候选
- 打开详情确认
- 进入申请/报销流程
- 要求补充条件
```
## IntentFrame 数据结构
```js
{
action: 'query' | 'delete' | 'approve' | 'reject' | 'create' | 'update' | 'ask_policy',
objectType: 'draft' | 'application' | 'reimbursement' | 'approval_task' | 'receipt' | 'document',
filters: {
timeRange: null,
status: null,
risk: null,
documentType: null,
amount: null,
keyword: null
},
targetMode: 'current_context' | 'filtered_candidates' | 'ambiguous',
safetyLevel: 'read_only' | 'confirm_required' | 'blocked',
confidence: 0,
normalizedQuery: ''
}
```
### 字段含义
- `action` 表示用户想做什么,例如查、删、审核、驳回、创建或咨询规则。
- `objectType` 表示动作对象,例如草稿、申请单、报销单、待审任务或票据。
- `filters` 表示筛选条件,必须可以复用到单据查询 flow。
- `targetMode` 表示目标定位方式:
- `current_context`:明确指向当前会话最近对象。
- `filtered_candidates`:需要查询候选列表。
- `ambiguous`:条件不足,需要澄清。
- `safetyLevel` 表示动作安全级别:
- `read_only`:可直接查询或解释。
- `confirm_required`:只展示候选或详情入口,不直接执行。
- `blocked`:存在批量破坏性风险或越权风险,必须阻断。
- `normalizedQuery` 是给现有查询 flow 使用的可读查询句,例如“我的 3 天前草稿单据”。
## 识别策略
### 动作识别
- 查询:查、看、列出、有哪些、找一下。
- 删除:删除、删掉、移除、作废、撤销。
- 审核:审核、审批、处理待办、去审批。
- 驳回:驳回、退回、拒绝。
- 创建:新建、发起、申请、我要报销。
- 更新:补充、修改、改成、填入。
- 规则咨询:怎么走、能不能、规则、制度、政策、标准。
### 对象识别
- 草稿:草稿、未提交、刚才保存的单据。
- 申请单:申请、申请单、出差申请、费用申请。
- 报销单:报销、报销单、费用报销。
- 待审任务:待办、待我审核、待审批、审核单。
- 票据:发票、票据、附件、图片。
### 筛选条件识别
- 时间今天、昨天、3 天前、近 7 天、上周、本月、具体日期、日期范围。
- 状态:草稿、审批中、已通过、已驳回、待补充。
- 风险:无风险、低风险、中风险、高风险、合规、异常、超标。
- 金额:超过 1000、500 以下、100 到 300。
- 关键词:地点、事由、人员、部门、单号等自由文本。
## 目标解析规则
### 当前上下文直达
当用户使用“刚才那个”“当前”“这个”“上面那个”这类指代,并且当前会话中能找到最近的可操作对象时,`targetMode``current_context`
例子:
- “删除刚才那个草稿”
- “打开这个申请单”
- “继续刚才的报销草稿”
即便目标唯一,删除、审核、驳回仍然只打开详情页或确认入口。
### 筛选候选
当用户输入包含时间、风险、金额、状态、类型等筛选条件时,`targetMode` 必须为 `filtered_candidates`
例子:
- “删除 3 天前的草稿”
- “审核合规没有风险的申请”
- “找一下上海相关的低风险待审申请”
这类请求必须进入单据查询 flow展示候选结果不能直接套最近草稿。
### 条件不足澄清
当动作高风险但目标既不唯一,也没有足够筛选条件时,`targetMode``ambiguous`
例子:
- “把草稿删了”
- “帮我审核一下”
- “退回这个单”
系统应提示用户选择候选或补充条件。
## Action Policy
| 动作 | 安全等级 | 第一版行为 |
| --- | --- | --- |
| 查询 | `read_only` | 直接查询并展示结果 |
| 规则咨询 | `read_only` | 走政策/规则解释,不进入单据查询 |
| 删除 | `confirm_required` | 展示候选或打开详情页确认,不直接删除 |
| 审核通过 | `confirm_required` | 展示待审候选或打开审核详情,不直接通过 |
| 驳回/退回 | `confirm_required` | 展示待审候选或打开审核详情,不直接驳回 |
| 批量删除/批量审核 | `blocked` | 阻断并要求用户选择具体单据 |
## 用户可见思考过程
筛选型命令必须复用现有查询 thinking events并补充动作意图说明
1. 解析自然语言动作和筛选条件。
2. 判断操作风险和目标定位方式。
3. 查询业务单据接口。
4. 按条件组合筛选候选。
5. 展示候选卡片和下一步入口。
示例:
```text
解析识别到“删除”是高风险动作对象是“草稿”时间条件是“3 天前”。
策略:不会直接删除,将先查询我的草稿候选。
结果:命中 2 张草稿,请打开详情页确认删除目标。
```
## 文件边界
- 新增 `workbenchIntentFrameModel.js`:负责解析用户输入到 `IntentFrame`
- 新增 `workbenchIntentActionPolicy.js`:负责动作安全策略和下一步路由判断。
- 调整 `workbenchAiCommandIntentModel.js`:保留会话内最近草稿解析,但不再单独拥有顶层意图判断。
- 调整 `useWorkbenchAiCommandIntents.js`:基于 `IntentFrame` 分发到当前上下文直达或候选查询。
- 调整 `aiDocumentQueryIntent.js``aiDocumentQueryModel.js`:补充风险筛选、相对日期和筛选摘要。
- 补充前端测试,覆盖组合型输入和安全边界。
## 迁移步骤
1. 先为 `IntentFrame` 解析补测试:
- “删除刚才那个草稿”解析为 `delete + draft + current_context + confirm_required`
- “删除 3 天前的草稿”解析为 `delete + draft + filtered_candidates + confirm_required`
- “审核合规没有风险的申请”解析为 `approve + application + risk:none + filtered_candidates + confirm_required`
- “审批规则怎么走”解析为 `ask_policy`,不进入单据查询。
2. 实现 `workbenchIntentFrameModel.js`,不接入 UI。
3. 实现风险和相对日期筛选能力,让查询 flow 能承接筛选型命令。
4. 接入 `useWorkbenchAiCommandIntents.js`
- 当前上下文直达:生成详情确认入口。
- 筛选候选:调用 `handleAiDocumentQueryIntent(normalizedQuery, pendingMessage)`
- 条件不足:提示补充条件或查询可选候选。
5. 移除或降级旧的散落正则,让顶层输入先走统一框架。
6. 跑定向测试、相邻测试、前端构建和 5173 工作台烟测。
## 验收标准
- 输入“删除刚才那个草稿”时,系统定位当前会话最近草稿,并只打开详情确认入口。
- 输入“删除 3 天前的草稿”时,系统展示筛选思考过程和草稿候选,不使用最近草稿快捷路径。
- 输入“审核合规没有风险的申请”时,系统查询待我审核申请,并筛选无风险候选。
- 输入“审批规则怎么走”时,不进入单据查询。
- 删除、审核、驳回均不通过自然语言直接执行最终动作。
- 新增/调整测试全部通过,前端构建通过,`git diff --check` 无空白错误。
## 后续演进
- 当后端 steward planner 能稳定输出同等 `IntentFrame` 时,可以把 Parser 层迁到后端,前端只保留策略兜底。
- 如果需要跨会话目标记忆,可把最近创建/保存草稿写入会话快照,并附带过期时间和用户确认边界。
- 如果未来引入 LangGraph应把它用于多步状态编排而不是替代 `IntentFrame` schema 本身。