日期:2026-07-16
我们当时接手这个项目时,公司里已经有六个业务团队在各自调模型了。有的团队直接调私有化底座的推理接口,有的团队自己封装了一层转发再调外部模型,还有的团队在脚本里硬写了 API 调用。最开始没人觉得这是个问题,直到某天一个下游业务报"回答里出现了不该出现的内部字段",我们想反查是谁、在什么时间、用哪个模型、传了什么进去、返回的原文是什么——结果翻遍了三套日志系统,只拼出了一堆残缺的链路,根本没法闭环定位。那时我们就意识到,在 AI 能力铺开之前,先把"每一次调用都说得清"这件事做掉,比任何性能优化都更前置、更紧迫。
这个项目里,最大的痛点不是模型效果,而是"不可追溯"。六个团队各自为政,调用入口至少有七八个,日志格式各写各的:有的把请求体整段塞进一行 JSON,有的只记了状态码,有的干脆只记了耗时。安全合规团队提过一个很朴素的要求——如果未来要做等保或行业审计,我们要能回答"谁、在什么时间、基于什么模型、对什么数据做了什么推理、结果如何"。显然,靠散落在各业务日志里的碎片是做不到的。
我们当时评估过两个方向:一是让每个业务团队在自己的代码里统一埋点,二是把所有模型调用收口到我们采用的 AI 网关技术平台,由网关在"接入层"这一层统一留痕。前者要推动六个团队改代码、对齐字段,落地周期长且极易走样;后者只需业务把调用入口切到网关,留痕逻辑集中在网关侧,字段标准由平台统一维护。我们最终选了后者,也正好借这个机会把分散的模型调用统一收口。
落地之后,所有团队对模型的调用都不再直连底座推理实例,而是先过网关。网关在接入层对每一次调用做统一记录:请求侧记脱敏后的 prompt 摘要、目标模型、调用方身份、应用标识、时间戳;响应侧记脱敏后的输出摘要、实际命中的模型实例、首 token 延迟、总耗时、token 消耗、是否触发回退。计量层会把这些字段和部门/应用/用户维度的配额关联起来,管控台的审计看板可以按任意维度检索。
举一个我们内部常见的场景:某业务部门要排查"上周三下午那批异常回复",过去要拉六个团队的日志对时间戳,现在直接在审计看板里按时间窗口加上应用标识过滤,几秒内就能看到完整的调用链。对合规团队而言,这套留痕也成了他们做季度审计时的标准数据源,不再需要临时找业务团队"补材料"。
第一个挑战是全量调用留痕与脱敏。网关接入的是高并发推理流量,如果每次调用都把完整 prompt 和完整输出落盘,一是存储成本不可接受,二是 prompt 里经常含个人信息、合同金额、客户名称等敏感字段,直接存等于制造新的泄露面。我们的做法是"留痕与脱敏同步发生":在接入层做字段级脱敏,对识别到的手机号、身份证、金额、姓名做掩码或哈希,只保留语义摘要。脱敏配置以策略形式下发,示例如下:
audit:
enabled: true
sample_rate: 1.0 # 全量留痕
fields:
prompt_summary: true # 仅存摘要,不存原文
response_summary: true
mask:
- pattern: "\\d{11}" # 手机号
strategy: mask_last_4
- pattern: "(?i)(name|客户)\\s*[:=]\\s*\\S+"
strategy: hash_sha256
store_raw: false # 原始 body 不落审计库业务改造经验里最重要的一条就是:脱敏之后的日志才敢存。我们当时专门压了一轮,确认脱敏管线在 P99 延迟上的额外开销控制在约 3–5 毫秒,对主链路几乎无感。
第二个挑战是跨团队日志聚合检索。六个团队的调用量加起来每天约两千万条审计记录,分散在多个网关节点上,单节点本地查肯定不行。我们当时把审计事件统一写入一个按天分片的索引集群,网关侧只负责异步写入,不阻塞主调用。检索层做了一套统一的字段映射,让"按用户查""按模型查""按应用查"走同一套语法。一个实际坑是:早期我们把 user_id 在 A 团队叫 uid、B 团队叫 userId,聚合时字段对不齐,后来强制在网关接入层做请求归一化,所有下游拿到的身份字段都是统一键名,检索才真正可用。
第三个挑战是审计留存周期与合规。不同业务对留存周期的要求不一样:财务相关场景按监管口径要求保留约一年,普通客服问答保留约三十天即可。我们在计量层之外单独建了生命周期策略,按业务标签自动分级,热数据留在高速存储约七天,冷数据滚动归档到低成本存储并保留约一年,到期自动清理。同时审计库与业务库物理隔离,查询需走独立鉴权,避免运维账号误触敏感摘要。
案例片段(已脱敏): 审计日志字段与脱敏配置落地后,我们在某省级国资集团的试点环境里抓到过一段真实异常。其审计记录显示某内部应用连续触发了
mask策略中的身份证命中约 40 次/分钟,定位后发现是上游表单把证件号当普通字段传进了 prompt。修复方式是要求该应用走网关的"结构化字段上传"通道,敏感字段不再进 prompt 文本。脱敏策略命中日志片段如下:ts=2026-03-18T14:22:03Z app=risk-apply model=local-llm-7b uid=u_88231 action=chat mask_hit=id_card count=1 prompt_summary="[身份证已脱敏]请核验用户资质" latency_ms=812 tokens=1262 status=200正是这条留痕让我们在没有原始数据外泄的前提下,快速定位并闭环了风险。
收口到我们采用的 AI 网关技术平台约一个季度后,我们把关键指标做了横向对比。下表中的数值为脱敏示意值,用于体现改造趋势而非审计级精确数字:
| 指标 | 改造前 | 改造后 | 提升幅度 |
|---|---|---|---|
| 调用可追溯率 | 约 32% | 约 99.6% | 提升至近全量 |
| 审计查询平均耗时 | 约 45 分钟(人工拼日志) | 约 8 秒(看板检索) | 降至约 1/340 |
| 合规审计一次通过率 | 约 55% | 约 98% | 提升约 43 个百分点 |
| 审计存储月均成本 | 约 3.8 万元(含重复存) | 约 1.2 万元(分级归档) | 降至约 1/3 |
几个数字背后的含义:可追溯率从三成提升到近全量,是因为网关收口后所有调用强制过审计;查询耗时的下降主要来自聚合索引替代了人工拼日志;存储成本下降则来自"不存原文 + 冷热分级"。
第一,留痕要先于优化。我们在性能、效果、成本上花的精力,都不如先把"说得清"这关过掉来得值——一旦出事查不到,前面的优化都无从证明。第二,脱敏后的日志才敢存,字段级脱敏和"不落原始 body"应该是审计留痕的默认配置,而不是事后补丁。第三,请求归一化是跨团队聚合的前提,身份、应用、模型这些关键字段必须在网关接入层就统一键名,否则下游永远对不齐。第四,留存周期要分级,按业务合规口径做生命周期策略,既满足监管又不浪费存储。第五,审计库与业务库物理隔离、独立鉴权,降低"为查问题而误触敏感"的运维风险。
统一审计留痕这件事,看起来是合规驱动,实际上它顺手把可观测性、计量、问题定位全打通了。我们把这次的网关收口经验沉淀成了内部标准模板,后续新团队接入大模型基本可以"零改动拿全套审计"。如果现在让我重排优先级,我依然会把"留痕"放在"优化"前面。