AI合规审计配置先理清要记什么,再决定日志字段与留存
AI合规审计配置要解决的是“发生问题后能不能查清楚”,而不是装一个审计软件就完事。
动手之前先确定三件事:审计哪些事件、每个事件记录哪些字段、日志保留多久。
这三件事定下来,配置才有依据;
否则日志要么记太少查不到,要么记太多既占空间又可能带出敏感信息。
先划审计范围:哪些事件必须留下记录
AI服务的调用链通常包含用户请求、模型推理、工具调用和返回结果。
审计不需要把每一步都完整抄下来,但以下几类事件建议至少留一条记录:
- 用户身份与请求时间:谁在什么时间发起了调用,用于事后追责和统计。
- 模型标识与版本:本次调用使用的是哪个模型、哪个版本,便于复现问题。
- 输入摘要与输出摘要:不建议原样保存完整提示词和完整回答,可保存哈希值或截断摘要,既保留可核验线索,又减少敏感数据落盘。
- 工具或外部接口调用:如果模型调用了数据库、搜索或第三方API,记录调用目标与结果状态。
- 异常与拦截事件:内容被过滤、权限校验失败、超时等,应单独记录原因码。
判断条件:如果一次调用涉及对外承诺、资金操作或个人信息处理,审计字段应更细;
纯内部测试流量可以只记录调用量与错误码,不必保存摘要。
审计字段怎么设计才够用又不冗余
字段设计围绕“能重建事件”来定。
一个最小可用的审计记录通常包含:
{
"event_id": "唯一请求标识",
"timestamp": "ISO8601 时间",
"actor": "调用方标识或用户ID",
"model": "模型名与版本",
"input_hash": "输入内容的哈希值",
"output_hash": "输出内容的哈希值",
"action": "chat / tool_call / filter_block",
"status": "success / error",
"error_code": "可选,失败时填写"
}
几个容易踩的坑:
- 不要用自增ID代替唯一请求标识,分布式环境下容易重复。
- 时间统一用带时区的格式,避免跨机器排查时对不上。
- 哈希值要使用固定算法并记录算法名,否则事后无法核验。
- 如果业务需要还原原文,应把原文存入受控的加密存储,而不是直接写进审计日志。
适用边界:字段不是越多越好。
每增加一个字段,都要问一句“出问题时这个字段能帮我判断什么”,答不上来就不加。
日志落盘与轮转:别让审计日志拖垮服务
审计日志建议与业务日志分开存放,避免业务日志轮转时把审计记录一起删掉。
以常见的应用日志配置为例,可以在日志框架中单独定义一个审计logger,输出到独立文件:
import logging
audit_logger = logging.getLogger("ai.audit")
audit_logger.setLevel(logging.INFO)
handler = logging.FileHandler("/var/log/ai/audit.log")
handler.setFormatter(logging.Formatter("%(message)s"))
audit_logger.addHandler(handler)
写入时只传结构化字段,不要拼接大段自由文本。
文件轮转按天或按大小切分,保留周期根据业务合规要求设定;
如果所在行业有明确的留存期限,按期限配置,没有明确要求时建议至少保留90天并定期归档,不要无限增长。
操作风险:修改日志路径或轮转策略前先确认磁盘余量,审计日志写入失败不应导致主业务崩溃,可将写入失败降级为计数告警。
配置完成后怎么验证记录可用
配置完不要只看文件有没有生成,至少做三步检查:
- 发起一次正常调用和一次被拦截的调用,确认两条记录都写入审计文件,且
status和error_code符合预期。 - 用
event_id在日志中检索,确认能唯一定位到单条记录,没有重复或丢失。 - 检查轮转后的旧文件是否仍可读,归档路径是否与保留策略一致。
如果日志中出现大量空字段,优先检查字段赋值顺序是否在异常分支之前;
如果记录时间与服务器时间偏差较大,检查容器或主机的时区配置。
AI合规审计配置的最终判断标准是:给定一个事件标识,能在合理时间内还原出谁、在什么时候、对哪个模型做了什么、结果如何。
达不到这个标准,就需要回头补充字段或调整落盘方式。