52 工单 Tool:字段校验、创建结果与失败补偿
工单 Tool:字段校验、创建结果与失败补偿
工单 Tool 是写操作,必须比查询工具更严格:字段、权限、确认、幂等和审计一个都不能少。
[TOC]
1. 先把 Agent 想清楚
很多人一听到 Agent,就会想到“让大模型自己决定下一步”。这个理解只对了一半。
在真实项目里,Agent 更像是一个被工程规则约束住的任务执行器:
模型负责理解自然语言、提出候选动作
代码负责权限校验、状态流转、工具执行
业务接口负责最终事实和写操作
日志审计负责事后追踪
如果模型误判或网络超时导致重复创建工单,用户体验和业务数据都会出问题。
所以这一阶段的博客不要写成“模型越来越聪明”。更准确的写法是:我们正在学习如何把模型的灵活性放进一个可控的工作流里。
2. 一个业务场景
用户确认创建售后工单后,服务超时了。系统不能直接再创建一遍,而要先用幂等键查询上次是否已经成功。
这个场景里面最重要的不是模型能不能说出一段好听的话,而是:
它选了哪个工具
为什么能调用这个工具
参数从哪里来
权限在哪里校验
失败后状态怎么变
用户确认前会不会产生真实写入
把这些问题问清楚,Agent 项目才不会变成一个不可解释的聊天黑盒。
这一节要先把工单工具当成高风险写操作。
判断顺序可以这样写:
1. 先收集创建工单所需字段:订单、问题类型、描述、联系方式、附件
2. 字段不完整时进入澄清,不让模型编默认值
3. 创建前必须展示工单草稿并等待用户确认
4. 真正写入时要做权限校验、幂等控制和审计记录
5. 最后用重复提交、取消确认、缺字段和无权限样例验证
它解决的是业务写入安全问题:模型可以整理工单草稿,但不能越过确认直接创建真实工单。
3. 核心概念
1. 必填字段
问题类型、订单、描述、联系方式等字段必须由服务端校验。
这一点在项目里要落到具体规则:字段完整才创建。
2. 创建前校验
身份、订单归属、订单状态、重复工单和确认令牌都要检查。
这一点在项目里要落到具体规则:写前多道门。
3. 幂等
重复确认或重试不能生成多张工单。
这一点在项目里要落到具体规则:同一动作只执行一次。
4. 失败补偿
跨服务写入可能部分成功,要能查询、恢复或补偿。
这一点在项目里要落到具体规则:失败要有状态。
4. 整体流程
graph TD;
A["工单预览"] --> B["冻结参数"];
B["冻结参数"] --> C["用户确认"];
C["用户确认"] --> D["校验确认和幂等"];
D["校验确认和幂等"] --> E["创建工单"];
E["创建工单"] --> F["发布后续事件"];
F["发布后续事件"] --> G["返回工单号"];
这张图里,模型只是其中一个节点。工具、状态、权限、确认和审计同样重要。
如果一个 Agent 图里只有“用户 -> 模型 -> 答案”,那它还只是 Chat,不是能进入业务系统的 Agent。
5. 落地步骤
1. 拆分预览和执行
预览生成 actionId,执行只接收 actionId。
完成后应该能看到:预览接口。
2. 加数据库唯一约束
幂等不能只靠先查后插,必须有唯一约束。
完成后应该能看到:幂等约束。
3. 记录创建状态
CREATING、CREATED、FAILED 等状态便于恢复。
完成后应该能看到:工单创建状态。
4. 处理通知失败
工单创建成功但通知失败,不应回滚工单,而是补偿通知。
完成后应该能看到:补偿任务。
6. 状态、接口或工具字段
| 项目 | 说明 |
|---|---|
| actionId | 冻结动作 ID |
| idempotencyKey | 幂等键 |
| ticketId | 工单编号 |
| createStatus | 创建状态 |
| failureReason | 失败原因 |
字段设计要尽量结构化。不要让下游通过一段自然语言去猜“成功了没有”“下一步要干什么”。
7. 示例
创建前检查
- 用户身份有效
- 订单属于当前用户
- 订单状态允许售后
- 必填字段完整
- actionId 未过期
- idempotencyKey 未被占用
示例里的字段不一定照搬,但思想要保留:输入、状态、输出、错误和审计信息要分开。
8. 哪些事不能交给模型自由发挥
模型不能确认后修改字段,也不能绕过预览直接创建。优先级、归属和状态由业务服务判断。
这一节特别重要。Agent 项目最容易踩坑的地方,就是把“理解意图”和“执行业务动作”混成一件事。
模型可以建议动作,但最终执行必须经过代码和业务系统的规则。
9. 测试路径
建议至少准备下面几类测试:
正常路径:输入完整,工具正常返回
缺字段路径:订单号、联系方式、问题描述不完整
权限路径:查询别人的订单、访问无权知识库
失败路径:工具超时、模型输出非法、检索为空
恢复路径:等待确认时服务重启、重复确认、超时确认
Agent 的测试不能只看最终回答。你要检查状态、工具调用、审计日志和是否产生真实副作用。
10. 工程取舍
- 确认流程增加一步,但保护写操作。
- 幂等设计增加表和约束,但避免重复数据。
- 补偿机制复杂,但比假装所有操作都能回滚更真实。
取舍讲清楚以后,读者才能知道你为什么这样设计,而不是以为所有问题都要上 Agent。
11. 常见坑
- 确认接口重新接收可变参数。
- 幂等键只放内存。
- 超时后盲目重试创建。
- 通知失败就删除已创建工单。
这些坑本质上都和一个问题有关:没有把模型输出当成“不可信的候选结果”。
12. 验收清单
- ☐ 创建前必须确认
- ☐ 幂等由唯一约束保证
- ☐ 失败状态可查询
- ☐ 写操作有审计
- ☐ 重复确认不重复创建
如果这些检查项没过,先不要急着加更多工具。工具越多,边界越乱,排查越难。
13. 落地清单
- ☐ 设计 pendingAction 表
- ☐ 写幂等键规则
- ☐ 模拟重复确认
- ☐ 设计通知失败补偿
练习时可以先用 Mock,不要一开始就连真实订单或工单系统。等状态、权限和幂等设计清楚后,再接真实接口。
14. 小结
写工具的核心是安全和一致性。让模型触发写操作前,必须用业务规则把风险拦住。
Agent 的价值来自灵活性,但安全来自边界。能把这两件事同时讲清楚,才算真正理解 Agent 工程化。