业务工具与售后工作流 DAG:从「每意图一张图」的弯路到「审批是事件」

发布时间:2026/9/26 4:04:40

业务工具与售后工作流 DAG:从「每意图一张图」的弯路到「审批是事件」 业务工具与售后工作流 DAG从「每意图一张图」的弯路到「审批是事件」语言 / Language中文 系列第七章目录 上一章决策层、持久化与闸门硬化项目Agentdemo007 —— 电商智能客服 Agent技术栈Java 17 / LangGraph4j固定工作流子图/ LC4j 工具前向 / HITL L2 三级持久化周期2026-09-12设计 方向纠偏→ 09-15工作流冲刺→ 09-19~20提交制 对账修复验证规模workflow 74 例 HITL 84 例 业务工具 36 例单测全量回归随各 Phase 交付源码github.com/Gavincui123/Agentdemo007前言业务工具层要回答的问题是当对话需要真的办事——查订单、办退款、建工单——怎么把 LLM 的不确定性关进确定性系统的笼子。这一章的主线不是设计展示是弯路和事故清单我先在每意图动态生成 DAG上犯了一次系统性过度设计设计推演阶段自己否决了自己落地后又接连踩到 LangGraph4j 的迭代预算陷阱、一个被用户看成系统说谎的小写订单号、一次管理台必现的 409 对账故障。最后靠两次原则级收口定型——审批是事件、建单走四态幂等门——每一段弯路的尽头都站着一条现在还立着的规矩。一、方向纠偏「每意图动态 DAG」被否决的经过业务工具层的第一份设计per-intent-dag雄心勃勃每个意图动态生成一张 DagSpec 图按需编排节点。这个方向在设计推演阶段就被我自己否决了回滚记录就写在计划文档的开头RoutePlan 只是每请求的结构化路径计划本身无 DAG低风险意图靠现有固定 Order 链加 #135 自跳过也无 DAGDAG 的落点只有一处——高风险操作时在 LangGraph 构建固定工作流子图。否决的理由今天看依然成立动态图的拓扑随 LLM 输出漂移。不可测——每个输入都可能长出一张新图用例没法写不可审计——事后说不清当时到底跑了哪张图不可回归——golden 用例锚不住拓扑。固定子图加明确的进入条件售后动作 订单号把要不要跑图交给上游决策层第六章图本体保持死板。死板是特性不是缺陷。同一份设计里还埋着一个运行时坑MAX_ITERATIONS从 10 放大到 20。原因很反直觉——LangGraph4j 的迭代预算按 generator yield 计数不是按节点数每个节点内部的多次 yield、条件边的重入都计数10 在 deny-retry 边界就会 trip。这类框架计量单位与直觉不符的坑属于不写进文档就一定会有人再踩一次的。二、售后工作流图五个节点与两种裁决机械事实不符ORDER_NOT_FOUND / ORDER_NOT_OWNED或 Agent 裁决 INELIGIBLE政策资格 → Agent 裁决 pass / uncertain进入refund_request / return_requestquery_user用户信息query_order订单信息query_policy政策召回RAG 单通道validateRejected业务驳回·非系统失败submit_ticket建 HITL 工单挂起等审批决议 管理台状态事件APPROVED / REJECTED / TIMEOUT落地的工作流子图很克制五个节点、一条条件边。查用户、查订单、查政策是三步串行取证validate 是唯一的裁决点submit_ticket 把通过者送进 HITL 工单挂起等审批Rejected 是业务驳回出口。关键设计在 validate 节点里两种裁决的分工// capability/workflow/AfterSaleWorkflowGraph.java —— 机械事实与政策资格分层// 机械事实校验存在/归属——非政策判断保留代码内短路即驳if(ordernull){ReasonfailReason.ORDER_NOT_FOUND;returnMap.of(FAIL_KEY,fail,OUTCOME_KEY,(AfterSaleWorkflowOutcome)newAfterSaleWorkflowOutcome.Rejected(…));}StringuidresolveUserId(ctx);if(uid!null!uid.equals(order.userId())){ReasonfailReason.ORDER_NOT_OWNED;returnMap.of(FAIL_KEY,fail,OUTCOME_KEY,(AfterSaleWorkflowOutcome)newAfterSaleWorkflowOutcome.Rejected(…));}// 政策资格 → Agent 裁决2026-09-19 用户裁决政策知识query_policy 召回 实时事实//订单记录 当前日期一并交模型三态裁决裁决器内部全降级失败UNCERTAIN fail-safe// 到人工绝不冒充业务驳回、绝不盲目放行机械事实订单在不在、是不是你的留在代码里——确定性判断不需要模型意见短路即驳政策资格7 天无理由适不适用这一单交给模型三态裁决——它需要读召回的政策、比对订单记录和当前日期。裁决失败的落点既不是拒绝也不是放行而是UNCERTAIN进人工审批且管理员重点复核。不确定是一种合法输出fail-safe 到人模型意见永远不可能单独驳回或放行一笔业务。业务驳回还有一层语义收口Rejected是业务终态话术直接答复这单不符合条件不是DegradationScenario——系统没坏是业务说不。把业务结果混进降级枚举监控就会把正常业务拒绝算成故障率。三、一次误拒的两个教训小写订单号与空表对账3.1 用户说 “ord-001”入口归一化实测用户小写输入 “ord-001” 原样进OrderQueryService的精确键查找 → miss → 误判ORDER_NOT_FOUND答复订单不存在。订单明明就在 mock 里用户视角这就是系统说谎。修复在服务端入口做防御性归一化// capability/business/OrderQueryService.java —— mock 三笔订单覆盖 validate 全部分支publicOptionalOrderRecordfindByOrderId(StringorderId){if(orderIdnull){returnOptional.empty();}// 防御性归一化trim大写调用方可能传用户原话里的 ord-001精确键会 missreturnOptional.ofNullable(ORDERS.get(orderId.trim().toUpperCase(java.util.Locale.ROOT)));}教训一句话标识符在系统边界处归一化一次而不是要求每个调用方记得归一化。这条后来写进了订单号提取的统一契约raw 优先、standardQuery 兜底《决策层、持久化与闸门硬化》§2.4。3.2 更疼的一个mock 与 DB 各说各话2026-09-20 联调管理台点批准退款必然 409「订单不存在」——而工作流校验明明通过了。排查结论写在BizOrderSeedRunner的 javadoc 里是一教科书级的数据源分裂数据源分裂根因工作流图校验订单存在/归属走 OrderQueryService 内存 mock……而 HitlBusinessGate 对账走 biz_order 表——表只有 DDL 无种子运行时恒空 → 管理台 confirm 必然 fail-closed「订单不存在」。两条链路各自正常校验查内存 mock查得到对账查 biz_order 表按 fail-closed 拒绝——单看都对合起来必坏。修复是启动时BizOrderSeedRunner写入与 mock同源对齐的三笔演示订单配两条铁律fill-if-absent只补空缺不覆盖——业务表是对账锚点种子绝不回写业务状态否则测试数据会污染真实审批结果app.biz-order.seed.enabledfalse可关生产接真数据。mock↔DB 对齐由BizOrderSeedRunnerTest断言钉死——对齐不是口头约定是测试。四、审批是事件一次原则翻转最初的设计是请求内等待工作流发起审批后请求线程挂起等管理台决议桥唤醒机制恢复执行。语义直观但三个毒副作用很快显形请求线程被审批时长绑架Tomcat 线程池会被审批队列占满审批等待与超时语义纠缠HITL_TIMEOUT 话术发出去之后决议才到算谁的恢复路径复杂桥的状态机要处理进程重启。2026-09-20 将裁决整体翻转管理台人工hitl_ticket 表售后工作流管理台人工hitl_ticket 表售后工作流请求线程到此结束——不存在请求内等待决议不受任何请求超时影响等待窗口/桥唤醒已整体退役建单幂等键 wfa:{action}:{orderId}即返回1话术「已提交等待人工审批」短路收尾2confirm / reject纯状态变更事件3confirm 批准 → AfterSaleBusinessExecutor 执行wfa 单不经 resumeresume 属 hitl: 检查点单恢复通道4原则的原话落在代码注释里原则审批是事件、Agent 最小权限——建单即返回无请求内等待。……决议 状态事件Agent 只查询进度。……等待窗口/桥唤醒已整体退役超时不可能影响决议。——TicketApprovalSubmitter / AfterSaleWorkflowGraph翻转后的世界简单了很多请求线程生命周期到建单为止WORKFLOW_APPROVAL_TIMEOUT场景保留只为指标兼容决议语义上已不可能超时恢复是显式管理动作——先过HitlBusinessGate业务对账再 CAS 消费检查点第六章的三级持久化正好接住。等待一个人类从来就不该发生在请求线程里这一条适用于一切带人工环节的系统。三个环节的实测截图正好凑成一次完整闭环五、建单幂等四个状态的门高风险动作的幂等要答两个问题幂等键怎么选命中之后每个状态去哪。工单按业务幂等键查询工作流审批单wfa:{action}:{orderId}、L2 检查点单hitl:{action}:{entity}两套单的分派口径同构只有一处刻意不同——这正是本节最想讲清的地方。先看 L2 检查点单HitlStep610的四个去向// capability/hitl/HitlStep.java —— 建单幂等2026-09-18 L2OptionalHumanTicketexistingticketService.findByIdempotencyKey(idempotencyKey);if(existing.isPresent()){HumanTicketpriorexisting.get();switch(prior.status()){casePENDING-{// 复用挂起单重复请求/网关重试/重开会话不再爆单checkpoint 缺失则补挂重启丢失兜底context.setHitlTicketId(prior.id());ensureCheckpoint(context,prior,idempotencyKey);// …省略 log/metricsreturnnewStepOutcome.ShortCircuit(DegradationScenario.HITL_TIMEOUT);}caseAPPROVED-{// 幂等放行人工已批准过该业务动作恢复锚定的放行语义带外预批准同语义// …省略 setHitlTicketId/log/metricsreturnnewStepOutcome.Proceed();}caseREJECTED-{// 人工已驳回该业务动作不再重审防驳回后换会话重提绕过审批// …省略 log/metricsreturnnewStepOutcome.ShortCircuit(DegradationScenario.HITL_TIMEOUT);}caseTIMEOUT-{// 超时单人工未决议允许重新建单键索引指向新单走下方正常流程// …省略 log无 return——落到方法下方的正常建单流程}}}四个去向各有一个为什么PENDING 复用是防重复轰炸——重复请求、网关重试、重开会话都不再爆单checkpoint 缺失还要补挂兜住重启丢失APPROVED 放行是审批语义的兑现——这笔钱人工批过了再问一遍不能再执行一遍TIMEOUT 重建是给人改口的机会键索引指向新单REJECTED这一格两套单刻意走了两个方向检查点单上面这段HitlStep代码驳回后不再重审而退款退货真正走的工作流审批单TicketApprovalSubmitterwfa:键工作流审批单的幂等键javadoc 写明差异REJECTED 不封禁再申请——PENDING 复用同单、APPROVED 已受理不重建防重复业务动作、REJECTED/TIMEOUT 重建新单。驳回是那张工单的终局事件不是对用户的永久禁令重建的是一张新工单照样要人工审审批权始终在人手里放开重建不构成绕过。幂等门真正要堵的是已批准的工单被重复兑现和同一申请轰炸出十张挂起单——这两条两套门都堵死了。六、这一章带走的六条动态图是系统性过度设计的典型症状。LLM 决定要不要进图图内部保持固定——灵活性与可测试性的边界画在图的门口而不是图里面。框架的计量单位要先核实再设预算。LangGraph4j 的 yield 计数坑属于不记录必复发类。机械事实归代码价值判断归模型不确定归人。validate 节点的三态裁决pass / rejected / uncertain让模型的意见永远不可能单独驳回或放行一笔业务。数据源分裂是集成事故的第一大来源。两条链路各自测试全绿照样联调必坏对齐要用种子加断言钉死且种子不得回写业务状态。带人工环节的流程等待必须发生在请求之外。审批是事件建单即返回、决议是状态变更、恢复是显式管理动作——超时语义才可能与审批语义彻底解耦。幂等门的每个状态都是一个产品决策。复用、放行、不重审检查点单、允许重建工作流单——枚举不全的幂等只是防重复提交枚举全了才防得住重复执行。七、已知边界诚实清单userId 客户端声明订单归属校验的uid来自ChatRequest.userIdnull 兜底 baked 10086 供演示真鉴权接入后 per-request 注入收口。单实例语义工单状态机与检查点消费为单实例口径多实例需 DB 乐观锁第六章已登记。演示身份与 mock 数据ORD-001/002/003 覆盖 validate 全部分支是演示口径真实接入后 mock 退役、对账链路不变。本文机制出处capability/workflow/AfterSaleWorkflowGraph / WorkflowExecutionStep / TicketApprovalSubmitter、capability/hitl/HitlStep / HitlResumeService、capability/business/OrderQueryService / BizOrderSeedRunner设计沿革见 business-tools-workflow-dag 与 per-intent-dag。相关阅读系列目录 · 第六章·决策层、持久化与闸门硬化 · 第四章·L0 业务键注册表 · 下一章全链路延迟与稳定性调优
延伸阅读

更多相关文章

2026/9/26 4:04:40

if constexpr:C++17 编译期分支,为什么它能取代 SFINAE

写模板函数时最常见的困境是:一个逻辑,但对不同类型的处理方式不一样——指针要解引用,非指针直接用;容器要遍历,标量直接打印。C11 时代这事只能靠 SFINAE 把逻辑拆到多个重载里,或者写 std::enable_if 的…

2026/9/26 4:04:40

Simulink电机控制仿真面试指南:从FOC建模到工程落地

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/26 5:24:45

数据中心U位资产管理:从人工台账到自动识别方案

1. 机房里的头等大事:U位管理到底是什么1.1 一个真实场景带出痛点先说个我亲自踩过的坑。前几年接手一个中型机房,总共四十多个机柜,设备大概八百多台。前任运维离职时留下一个Excel表,里面登记了每台服务器的U位、IP、序列号、维…

2026/9/26 5:24:45

树莓派picamera与PC实时视频传输:Socket协议设计与性能优化

1. 项目缘起与整体方案设计1.1 为什么会有这个需求手里攒了一块树莓派和几个摄像头模块,最开始只是想做个简单的监控,看看家里没人时猫在干什么。但真正动手之后发现,树莓派本地存视频、本地看画面这件事限制太多——SD卡写入寿命有限&#x…

2026/9/26 5:24:45

华为擎云L420X/L540X装Windows实战:ARM64跨架构迁移的坑与解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/26 5:19:45

AC交流电

导航 (返回顶部) 1. AC 1.1 Alternating current1.2 简谐交流电1.3 频率1.4 峰值和有效值 2. 交流电相位分类 2.1 单相电2.2 三相电2.3 比较2.4 220v交流电的3个电压值2.5 相电压与线电压图示 3. 入户接线 3.1 单相二线制3.2 单相三线制 4. 电压 4.1 电压标准4.2 北美地区4.3 欧…

2026/9/25 21:00:17

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/25 20:59:52

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/26 0:04:28

画质修复APP怎么选?Wink影像修复能力与产品实力解析

现如今手机拍摄场景愈发丰富,演唱会直拍、漫展记录、老视频翻新、日常vlog录制,都会遇到画面模糊、噪点多、曝光失衡等问题,不少用户在挑选工具时比较在意一款画质修复APP能够兼顾修复效果与自然质感。Wink作为美图公司推出的全球化AI影像增强…

2026/9/26 0:04:28

超低能耗建筑K值要求能否满足?浙东铝业建筑型材解析

核心摘要浙东铝业的超低能耗系统门窗产品,资料显示保温性能可达 K≤1.4W/(㎡K),能够对应上海地区超低能耗住宅对门窗保温性能的应用需求。判断建筑是否满足超低能耗要求,不能只看铝型材本身,还需要结合玻璃、隔热条、密封系统、开…

2026/9/25 20:55:38

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/25 18:41:36

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/25 18:34:56

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑