9.3 KiB
9.3 KiB
AI 工作台统一意图识别框架设计
背景
AI 工作台当前的输入识别分散在多个前端 flow 中:申请预览、报销草稿、单据查询、草稿删除提示各自判断输入。这样的结构能快速修复单点问题,但会让“删除 3 天前的草稿”“审核合规没有风险的申请”这类组合型请求继续变成关键词补丁。
本设计把自然语言输入先统一解析成结构化 IntentFrame,再根据目标是否明确、安全等级和业务边界决定下一步动作。
目标
- 让工作台所有自然语言输入先进入统一意图框架,不再在各业务 flow 中散落判断。
- 支持动作、对象、筛选条件、上下文指代、安全等级的组合识别。
- 对删除、审核、驳回等高风险动作固定走“筛选候选 + 详情确认”,禁止自然语言直接执行。
- 保留当前会话内的快速指代能力,例如“删除刚才那个草稿”能定位最近创建的草稿。
- 对带筛选条件的请求,例如“删除 3 天前的草稿”“审核无风险申请”,先展示思考过程和候选列表。
非目标
- 第一版不引入 LangGraph,也不把前端本地识别迁到后端状态机。
- 第一版不做自然语言直接批量删除、批量审核或批量驳回。
- 第一版不改后端审批、删除接口的权限模型。
- 第一版不重写现有申请预览和报销草稿流程,只把入口识别前置统一。
总体架构
统一意图识别分三层:
IntentFrame Parser:把用户输入解析为结构化意图。Target Resolver:结合当前会话、最近动作和筛选条件,判断目标是否唯一。Action Policy:根据动作风险决定直接查询、展示候选、要求澄清或阻断。
输入链路应调整为:
用户输入
-> IntentFrame Parser
-> Action Policy
-> Target Resolver
-> 业务 flow
- 查询候选
- 打开详情确认
- 进入申请/报销流程
- 要求补充条件
IntentFrame 数据结构
{
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,并补充动作意图说明:
- 解析自然语言动作和筛选条件。
- 判断操作风险和目标定位方式。
- 查询业务单据接口。
- 按条件组合筛选候选。
- 展示候选卡片和下一步入口。
示例:
解析:识别到“删除”是高风险动作,对象是“草稿”,时间条件是“3 天前”。
策略:不会直接删除,将先查询我的草稿候选。
结果:命中 2 张草稿,请打开详情页确认删除目标。
文件边界
- 新增
workbenchIntentFrameModel.js:负责解析用户输入到IntentFrame。 - 新增
workbenchIntentActionPolicy.js:负责动作安全策略和下一步路由判断。 - 调整
workbenchAiCommandIntentModel.js:保留会话内最近草稿解析,但不再单独拥有顶层意图判断。 - 调整
useWorkbenchAiCommandIntents.js:基于IntentFrame分发到当前上下文直达或候选查询。 - 调整
aiDocumentQueryIntent.js和aiDocumentQueryModel.js:补充风险筛选、相对日期和筛选摘要。 - 补充前端测试,覆盖组合型输入和安全边界。
迁移步骤
- 先为
IntentFrame解析补测试:- “删除刚才那个草稿”解析为
delete + draft + current_context + confirm_required。 - “删除 3 天前的草稿”解析为
delete + draft + filtered_candidates + confirm_required。 - “审核合规没有风险的申请”解析为
approve + application + risk:none + filtered_candidates + confirm_required。 - “审批规则怎么走”解析为
ask_policy,不进入单据查询。
- “删除刚才那个草稿”解析为
- 实现
workbenchIntentFrameModel.js,不接入 UI。 - 实现风险和相对日期筛选能力,让查询 flow 能承接筛选型命令。
- 接入
useWorkbenchAiCommandIntents.js:- 当前上下文直达:生成详情确认入口。
- 筛选候选:调用
handleAiDocumentQueryIntent(normalizedQuery, pendingMessage)。 - 条件不足:提示补充条件或查询可选候选。
- 移除或降级旧的散落正则,让顶层输入先走统一框架。
- 跑定向测试、相邻测试、前端构建和 5173 工作台烟测。
验收标准
- 输入“删除刚才那个草稿”时,系统定位当前会话最近草稿,并只打开详情确认入口。
- 输入“删除 3 天前的草稿”时,系统展示筛选思考过程和草稿候选,不使用最近草稿快捷路径。
- 输入“审核合规没有风险的申请”时,系统查询待我审核申请,并筛选无风险候选。
- 输入“审批规则怎么走”时,不进入单据查询。
- 删除、审核、驳回均不通过自然语言直接执行最终动作。
- 新增/调整测试全部通过,前端构建通过,
git diff --check无空白错误。
后续演进
- 当后端 steward planner 能稳定输出同等
IntentFrame时,可以把 Parser 层迁到后端,前端只保留策略兜底。 - 如果需要跨会话目标记忆,可把最近创建/保存草稿写入会话快照,并附带过期时间和用户确认边界。
- 如果未来引入 LangGraph,应把它用于多步状态编排,而不是替代
IntentFrameschema 本身。