# AI 意图规划器 ## 功能一句话 把用户一句自然语言先交给大模型识别成“动作和步骤”的结构化计划,再由前端/后端确定性执行器逐步校验和执行;规则只作为模型不可用或结构非法时的兜底。 ## 背景 用户真实表达往往不是一个简单关键词,而是一个目标: ```text 去上海出差,辅助国网仿生产服务器部署,交通火车,直接提交 ``` 这句话包含至少四层语义: - 业务对象:差旅费用申请。 - 已给字段:地点、事由、交通方式。 - 用户动作:直接提交,不只是生成草稿。 - 执行步骤:生成申请核对表、校验必填字段、查重、提交审批。 如果继续用前端规则直接判断,会越来越像关键词路由;正确方向是让大模型先拆成结构化计划,系统只执行经过白名单校验的步骤。 ## 目标 - 大模型作为复杂意图的主识别器,输出结构化 `intent plan`。 - `intent plan` 明确描述用户要执行的动作、业务字段、缺失字段和步骤列表。 - 执行器只认计划中的白名单步骤,不直接相信模型文本。 - 字段齐全且用户明确“直接提交”时,系统自动走完整链路。 - 字段缺失、风险阻断、重复申请或低置信度时,系统停在核对表或风险提示。 - 本地规则只作为 `rule_fallback`,不得伪装成模型判断。 ## 非目标 - 不让大模型直接写数据库、提交审批或绑定附件。 - 不引入 LangChain 高层 Agent 来替代现有业务服务。 - 不让 LangGraph 直接接管模型供应商密钥、数据库写入或审批副作用。 - 不绕过已有申请预览、规则测算、重复申请核查和提交接口。 - 不把所有财务场景一次性改完;第一阶段先覆盖个人工作台 AI 模式里的差旅申请链路。 ## 结构化计划契约 前端执行器消费统一结构: ```json { "source": "llm_function_call", "intent": "create_travel_application", "requestedAction": "submit", "confidence": 0.91, "sourceText": "去上海出差,辅助国网仿生产服务器部署,交通火车,直接提交", "slots": { "location": "上海", "reason": "辅助国网仿生产服务器部署", "transportMode": "火车" }, "missingFields": [], "steps": [ "build_application_preview", "validate_required_fields", "run_duplicate_precheck", "submit_application" ] } ``` ## 步骤白名单 - `build_application_preview`:生成申请核对表,复用现有申请预览能力。 - `validate_required_fields`:用确定性代码校验必填字段和字段格式。 - `run_duplicate_precheck`:提交前查询同日期或重叠申请单。 - `submit_application`:调用现有申请提交动作;只有用户明确要求提交且前置校验通过才执行。 - `save_application_draft`:调用现有申请草稿保存能力。 - `create_reimbursement_draft`:调用现有报销草稿创建能力。 - `associate_attachments`:调用现有附件关联 runner;缺少 `receipt_ids` 或匹配不唯一时阻断,不能假成功。 - `link_existing_application`:调用现有报销草稿创建链路并写入申请关联 flag;申请单不存在、未审批或已被报销时阻断。 ## 数据流 ```text 用户输入 ↓ steward LLM function calling ↓ 模型计划归一化与白名单校验 ↓ 可执行 intent plan ↓ 申请/报销/附件等确定性执行器 ↓ 核对表、风险提示、草稿或提交结果 ``` 当模型不可用、超时或返回不可执行结构时: ```text 模型失败 ↓ 本地 rule_fallback 生成保守计划 ↓ 同一个执行器继续处理 ``` ## 安全边界 - 模型只负责“理解”和“拆步骤”,不拥有副作用权限。 - 执行器必须校验 `intent` 和 `steps` 是否在白名单内;未知 action 必须阻断,不能调用业务服务。 - 提交前必须走 `readyToSubmit` 和重复申请 precheck。 - 提交类副作用必须带用户确认和 precheck 通过证据。 - 地点、日期、事由等字段仍由现有申请预览和规则校验模块判断。 - 模型置信度低、流程冲突或必填字段缺失时,不自动提交。 ## 第一阶段落地 - 新增前端 planner model,把后端 `StewardPlanResponse` 映射成前端 `intent plan`。 - 个人工作台 AI 模式在命中差旅申请候选时,优先调用现有 `/steward/plans` 获取模型计划。 - 模型计划可执行时,按 `steps` 生成申请核对表并在条件满足时自动提交。 - 模型不可用或计划不可执行时,使用本地 `rule_fallback` 保持体验不倒退。 - 保留既有普通小财管家路径,用来处理无法直接执行或更复杂的多任务场景。 ## LangGraph 迁移方向 后端小财管家的规划入口、槽位决策入口和运行时动作决策入口已经开始迁入 LangGraph。 后续不再继续把感知、规划、补字段、运行时动作判断堆进自研 `if/else` 编排,而是按 node 拆分: - `model_intent_node`:模型 function calling 规划。 - `slot_tool_decision_node`:字段缺口与追问判断,失败时进入规则兜底。 - `runtime_memory_context_node`:合并前端运行时状态和持久化 `steward_state`。 - `runtime_tool_decision_node`:用户补充、确认、取消、继续执行等运行时判断。 - `runtime_action_decision_node`:已选流程确认等不需要模型的确定性行动路由。 - `action_plan_node`:生成白名单 `StewardActionStep`,当前已覆盖申请预览、保存草稿、直接提交和报销草稿。 - `human_review_node`:保存草稿、提交审批、关联申请单前的确认点。 - `action_execute_node`:调用现有确定性业务服务;当前已由 `/steward/actions/execute`、`StewardGraphActionRuntime` 和 `StewardActionExecutor` 提供 checkpoint、pending interrupt 和幂等重放。 - `persist_state_node`:合并 conversation state 和 steward state。 当前 `plans` 已返回服务端 `action_steps`,`slot-decisions` / `runtime-decisions` 已默认走 `StewardGraphRuntime`。 如果 LangGraph 图节点异常,服务端会退回原有 Agent 和规则兜底,避免框架层故障影响用户会话。 详细迁移计划见 `LANGGRAPH_RUNTIME_MIGRATION.md`。 ## 测试策略 - planner model 单元测试:模型计划归一化、rule fallback、政策咨询排除。 - 前端静态接线测试:主流程必须先请求 steward plan,再 fallback。 - 申请预览回归测试:`直接提交` 不得污染事由;缺日期不得伪造字段。 - 构建验证:`npm --prefix web run build`。