45 业务接口设计:订单、工单、确认与日志 API
业务接口设计:订单、工单、确认与日志 API
Agent 最终调用的是业务接口。接口越清楚,模型越容易安全地使用工具。
[TOC]
1. 先把 Agent 想清楚
很多人一听到 Agent,就会想到“让大模型自己决定下一步”。这个理解只对了一半。
在真实项目里,Agent 更像是一个被工程规则约束住的任务执行器:
模型负责理解自然语言、提出候选动作
代码负责权限校验、状态流转、工具执行
业务接口负责最终事实和写操作
日志审计负责事后追踪
如果工具接口设计成“传一段话,后台自己猜”,Agent 就很难稳定。业务接口要结构化、可鉴权、可审计。
所以这一阶段的博客不要写成“模型越来越聪明”。更准确的写法是:我们正在学习如何把模型的灵活性放进一个可控的工作流里。
2. 一个业务场景
Agent 识别到用户想创建售后工单,但它不能直接写数据库。它应该先调用预览接口生成冻结摘要,再等待用户确认,最后用 actionId 执行创建。
这个场景里面最重要的不是模型能不能说出一段好听的话,而是:
它选了哪个工具
为什么能调用这个工具
参数从哪里来
权限在哪里校验
失败后状态怎么变
用户确认前会不会产生真实写入
把这些问题问清楚,Agent 项目才不会变成一个不可解释的聊天黑盒。
这一节要把业务 API 当成事实来源。
判断顺序可以这样写:
1. 先列出 Agent 需要哪些事实:订单状态、物流、售后规则、工单记录
2. 每个事实都应该来自业务 API,而不是让模型猜
3. API 要区分查询和写入,写入接口必须有幂等键、权限校验和确认状态
4. 返回字段要适合模型消费,避免只返回内部码却没有业务含义
5. 最后用模拟工具调用验证:模型给出的参数是否能被 API 明确校验
它解决的是数据可信问题:Agent 的回答可以自然语言组织,但事实必须来自确定的业务接口。
3. 核心概念
1. 订单查询 API
只返回当前用户有权查看的订单摘要,并脱敏。
这一点在项目里要落到具体规则:查询也要鉴权。
2. 工单预览 API
创建前校验字段并冻结参数,返回 actionId 和摘要。
这一点在项目里要落到具体规则:先预览,后执行。
3. 确认 API
确认绑定 actionId,不重新接收可篡改参数。
这一点在项目里要落到具体规则:确认的是冻结动作。
4. 审计日志 API
记录谁在何时基于什么动作调用了哪个业务接口。
这一点在项目里要落到具体规则:写操作必须可追踪。
4. 整体流程
graph TD;
A["Agent 生成候选参数"] --> B["业务 API 鉴权"];
B["业务 API 鉴权"] --> C["预览并冻结参数"];
C["预览并冻结参数"] --> D["用户确认"];
D["用户确认"] --> E["确认接口执行"];
E["确认接口执行"] --> F["写审计日志"];
F["写审计日志"] --> G["返回工单号"];
这张图里,模型只是其中一个节点。工具、状态、权限、确认和审计同样重要。
如果一个 Agent 图里只有“用户 -> 模型 -> 答案”,那它还只是 Chat,不是能进入业务系统的 Agent。
5. 落地步骤
1. 定义错误码
订单不存在、无权访问、状态不允许、重复工单要分开。
完成后应该能看到:领域错误码表。
2. 设计幂等键
创建工单使用幂等键,避免重复确认或超时重试造成重复写入。
完成后应该能看到:Idempotency-Key 规则。
3. 冻结参数
预览时保存不可变 payload,确认时只传 actionId。
完成后应该能看到:pendingAction 记录。
4. 统一响应结构
工具返回 status、data、errorCode、retryable,方便 Agent 路由。
完成后应该能看到:统一 DTO。
6. 状态、接口或工具字段
| 项目 | 说明 |
|---|---|
| orderId | 订单标识,服务端校验归属 |
| actionId | 待确认动作 ID |
| payloadDigest | 冻结参数摘要 |
| idempotencyKey | 幂等键 |
| auditId | 审计事件 ID |
字段设计要尽量结构化。不要让下游通过一段自然语言去猜“成功了没有”“下一步要干什么”。
7. 示例
POST /ticket-actions/preview
{
"orderId": "ORD-1001", "issueType": "PRODUCT_FAULT", "description": "设备反复重启"
}
返回 actionId 和脱敏摘要。
POST /ticket-actions/{actionId}/confirm
Header: Idempotency-Key
示例里的字段不一定照搬,但思想要保留:输入、状态、输出、错误和审计信息要分开。
8. 哪些事不能交给模型自由发挥
模型不能直接拼 SQL、不能传 userId 冒充身份、不能确认后改参数。最终权限和状态由业务 API 判断。
这一节特别重要。Agent 项目最容易踩坑的地方,就是把“理解意图”和“执行业务动作”混成一件事。
模型可以建议动作,但最终执行必须经过代码和业务系统的规则。
9. 测试路径
建议至少准备下面几类测试:
正常路径:输入完整,工具正常返回
缺字段路径:订单号、联系方式、问题描述不完整
权限路径:查询别人的订单、访问无权知识库
失败路径:工具超时、模型输出非法、检索为空
恢复路径:等待确认时服务重启、重复确认、超时确认
Agent 的测试不能只看最终回答。你要检查状态、工具调用、审计日志和是否产生真实副作用。
10. 工程取舍
- 接口越严格,模型越不容易乱用。
- 预览确认增加一次交互,但保护写操作。
- 统一错误模型会增加前期设计成本,但后续路由更稳。
取舍讲清楚以后,读者才能知道你为什么这样设计,而不是以为所有问题都要上 Agent。
11. 常见坑
- 让模型直接调用数据库。
- 确认接口重新接收完整参数。
- 错误统一返回“失败”。
- 工具响应包含过多敏感字段。
这些坑本质上都和一个问题有关:没有把模型输出当成“不可信的候选结果”。
12. 验收清单
- ☐ 订单接口按当前用户过滤
- ☐ 工单创建有幂等
- ☐ 确认绑定冻结参数
- ☐ 错误码可被 Agent 判断
- ☐ 审计能关联 traceId
如果这些检查项没过,先不要急着加更多工具。工具越多,边界越乱,排查越难。
13. 落地清单
- ☐ 设计订单查询响应
- ☐ 设计工单预览接口
- ☐ 写确认接口状态流
- ☐ 列出 8 个领域错误码
练习时可以先用 Mock,不要一开始就连真实订单或工单系统。等状态、权限和幂等设计清楚后,再接真实接口。
14. 小结
工具稳定不稳定,很大程度取决于业务接口设计。接口越结构化,Agent 越可控。
Agent 的价值来自灵活性,但安全来自边界。能把这两件事同时讲清楚,才算真正理解 Agent 工程化。