为方便排查 AI 接口,保留服务商原始响应很自然。但图像接口可能返回 Base64 图片,一份看似普通的 JSON,就包含整张图的数据。
如果原样写进请求审计,用户没有多生成内容,数据库却多保存了一份大载荷。页面成功与否看不出这个问题,审计链路却在持续承担存储和处理成本。
原始响应不等于审计数据
审计要回答的是:调用了什么模型、状态如何、花了多少积分、为什么失败。图片正文和这些问题并不是同一种数据。
这次修复在写入审计前递归处理 JSON:过滤已知 Base64 字段,识别 data URL 并替换成省略标记,同时保留其他可诊断信息。数组和嵌套对象也需要处理,不能只检查最外层字段。
展示给用户的图片仍需要保留可用数据。审计清理不能误伤结果展示,因此两条路径要分开处理。
新数据和历史数据要分别治理
只修改 Java 代码,只能约束之后的请求。已有审计记录还需要清理,所以同次提交补充了数据库迁移脚本。
这也是一个常见的检查遗漏:修了写入逻辑,不代表已经写入的数据会自动变小。
留下的检查点
- 服务商响应里是否包含图片、音频或视频正文。
- 调试审计是否真的需要保留完整内容。
- 清理逻辑是否覆盖嵌套对象、数组和不同字段写法。
- 历史记录是否需要单独迁移。
- 结果展示是否仍然完整。
后面本地历史重复存图的修复又提醒了同一件事:对象能被序列化,不代表值得完整持久化。媒体内容、业务状态和排查信息应各有保存策略。
请求审计修复对应 2026-07-20 的提交 d19fb2679;本地历史去重对应 2026-07-15 的 d67ad1692。