51 订单 Tool:Mock、鉴权、状态解析与脱敏
订单 Tool:Mock、鉴权、状态解析与脱敏
订单 Tool 是只读工具,但它涉及真实用户数据,必须处理 Mock、鉴权、状态解析和脱敏。
[TOC]
1. 先把 Agent 想清楚
很多人一听到 Agent,就会想到“让大模型自己决定下一步”。这个理解只对了一半。
在真实项目里,Agent 更像是一个被工程规则约束住的任务执行器:
模型负责理解自然语言、提出候选动作
代码负责权限校验、状态流转、工具执行
业务接口负责最终事实和写操作
日志审计负责事后追踪
订单查询不能因为用户说出一个订单号就返回详情。必须确认订单属于当前用户,且返回字段经过脱敏。
所以这一阶段的博客不要写成“模型越来越聪明”。更准确的写法是:我们正在学习如何把模型的灵活性放进一个可控的工作流里。
2. 一个业务场景
用户说“查一下 ORD-1001”。系统要确认用户身份,再查询订单归属。如果订单属于别人,对外不要泄露订单是否存在。
这个场景里面最重要的不是模型能不能说出一段好听的话,而是:
它选了哪个工具
为什么能调用这个工具
参数从哪里来
权限在哪里校验
失败后状态怎么变
用户确认前会不会产生真实写入
把这些问题问清楚,Agent 项目才不会变成一个不可解释的聊天黑盒。
这一节要先把订单工具定义成只读事实工具。
判断顺序可以这样写:
1. 先确认用户是否已经提供订单号,没提供就进入澄清
2. 查询订单必须校验当前用户是否有权访问该订单
3. 返回结果要适合售后判断,例如状态、商品、物流、支付、售后记录
4. 查不到、无权限、订单已关闭等情况要有明确失败分支
5. 最后用本人订单、他人订单、不存在订单和缺订单号样例验证
它解决的是业务事实问题:售后 Agent 不能靠用户描述判断订单状态,必须查真实订单数据。
3. 核心概念
1. Mock 数据
Mock 要覆盖正常、取消、退款、无权限和不存在,不能只有成功样本。
这一点在项目里要落到具体规则:Mock 也要像业务。
2. 鉴权
按当前登录用户查询,不信任模型传来的 userId。
这一点在项目里要落到具体规则:身份来自系统。
3. 状态解析
把底层状态码转换成稳定领域状态和允许动作。
这一点在项目里要落到具体规则:状态要业务化。
4. 脱敏
手机号、地址、姓名、订单号按场景脱敏。
这一点在项目里要落到具体规则:少给模型敏感信息。
4. 整体流程
graph TD;
A["接收订单号"] --> B["校验登录身份"];
B["校验登录身份"] --> C["查询订单归属"];
C["查询订单归属"] --> D["映射领域状态"];
D["映射领域状态"] --> E["脱敏字段"];
E["脱敏字段"] --> F["返回摘要"];
F["返回摘要"] --> G["写审计日志"];
这张图里,模型只是其中一个节点。工具、状态、权限、确认和审计同样重要。
如果一个 Agent 图里只有“用户 -> 模型 -> 答案”,那它还只是 Chat,不是能进入业务系统的 Agent。
5. 落地步骤
1. 设计最小响应
只返回 Agent 决策需要的字段。
完成后应该能看到:订单摘要 DTO。
2. 区分内部错误
内部区分不存在和无权限,对用户提示可统一。
完成后应该能看到:错误映射表。
3. 实现契约 Mock
Mock 和真实 API 使用同一 DTO。
完成后应该能看到:Mock 服务。
4. 测试状态矩阵
每种状态对应可展示字段和可执行动作。
完成后应该能看到:状态测试表。
6. 状态、接口或工具字段
| 项目 | 说明 |
|---|---|
| displayOrderId | 脱敏订单号 |
| state | 领域状态 |
| items | 商品摘要 |
| availableActions | 允许动作 |
| maskedContact | 脱敏联系方式 |
字段设计要尽量结构化。不要让下游通过一段自然语言去猜“成功了没有”“下一步要干什么”。
7. 示例
{
"status": "success", "order": { "displayOrderId": "ORD-****1001", "state": "DELIVERED", "items": [{"name": "智能设备", "quantity": 1}],
"availableActions": ["CREATE_SUPPORT_TICKET"] }}
示例里的字段不一定照搬,但思想要保留:输入、状态、输出、错误和审计信息要分开。
8. 哪些事不能交给模型自由发挥
模型不能传 userId 来指定查谁的订单,也不能根据状态字符串自行决定是否允许售后。
这一节特别重要。Agent 项目最容易踩坑的地方,就是把“理解意图”和“执行业务动作”混成一件事。
模型可以建议动作,但最终执行必须经过代码和业务系统的规则。
9. 测试路径
建议至少准备下面几类测试:
正常路径:输入完整,工具正常返回
缺字段路径:订单号、联系方式、问题描述不完整
权限路径:查询别人的订单、访问无权知识库
失败路径:工具超时、模型输出非法、检索为空
恢复路径:等待确认时服务重启、重复确认、超时确认
Agent 的测试不能只看最终回答。你要检查状态、工具调用、审计日志和是否产生真实副作用。
10. 工程取舍
- 返回字段越少越安全,但可能需要更多后续查询。
- Mock 覆盖越全,开发越稳。
- 对外提示越模糊,越能防枚举,但用户体验要平衡。
取舍讲清楚以后,读者才能知道你为什么这样设计,而不是以为所有问题都要上 Agent。
11. 常见坑
- 万能 Mock 永远成功。
- 返回完整收货地址给模型。
- 只校验订单号,不校验归属。
- 模型自己解释底层状态码。
这些坑本质上都和一个问题有关:没有把模型输出当成“不可信的候选结果”。
12. 验收清单
- ☐ 订单按当前用户过滤
- ☐ 响应字段脱敏
- ☐ Mock 覆盖失败场景
- ☐ 领域状态由服务端映射
- ☐ 访问有审计
如果这些检查项没过,先不要急着加更多工具。工具越多,边界越乱,排查越难。
13. 落地清单
- ☐ 设计订单摘要响应
- ☐ 准备 6 条 Mock 订单
- ☐ 写无权限场景
- ☐ 列出订单状态和允许动作
练习时可以先用 Mock,不要一开始就连真实订单或工单系统。等状态、权限和幂等设计清楚后,再接真实接口。
14. 小结
只读工具也有安全边界。订单 Tool 的重点不是查得出来,而是只能查该查的,并且只返回需要的信息。
Agent 的价值来自灵活性,但安全来自边界。能把这两件事同时讲清楚,才算真正理解 Agent 工程化。