# 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 本身。