ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

AI产品白盒化:从黑盒到可解释的Agent实践

AI产品白盒化:从黑盒到可解释的Agent实践 这个系列写到第二十六弹我自己都有点恍惚。当初第一弹只是想证明一件事AI产品不应该是黑盒。我们作为开发者不应该只能输入一句“再帮我看看”然后对着玄学的输出发呆。这两年圈子里聊的不再只是模型刷分而是怎么把AI产品拆开看透。今天这一弹我把一个旅行推荐Agent从黑盒改造成白盒的完整过程复盘一遍包括黑盒蒸馏、链路观测、回归门禁和一堆踩坑记录。无论你是自己做AI应用还是做测试开发、AI Agent工程这篇应该能给你一套直接能抄的骨架。AI产品的“黑盒化”最可怕的不是不透明而是没法复盘。用户说“你推荐的是什么鬼”你只能挠头产品经理问“为什么线上效果差了”你只能靠猜。白盒化就是把这些“猜”变成“看”每一步推理有记录每个判断有依据每次改动有对比。下面是实操全过程。1. 为什么AI产品必须白盒化从盲盒到开卷考1.1 黑盒的代价错误不可定位交付只能靠玄学黑盒这个词本来是控制论里的概念指的是我们只关心系统的输入和输出不关心内部结构。放在AI产品里就是用户发一句“推荐一个适合带娃的海边行程”模型返回一段推荐你只看到两头中间发生了什么一概不知。这种模式在demo阶段没问题一旦上线麻烦就来了。我给你讲个真实的例子。我们第一版旅行推荐Agent上线后有用户吐槽“我明明说的是带娃你怎么给我推荐夜游项目”我们当时的第一反应是改prompt在prompt里加上“必须考虑亲子场景”。改完上线问题没了。但过了两天新用户又来了“我说的是情侣出行你怎么把夜游给我去掉了”后来才发现根本原因是意图识别模块对“带娃”“情侣”“亲子”这几个标签的边界没分清楚改了prompt只是让模型倾向于输出亲子内容结果把其他场景误伤了。这中间没有任何日志能告诉你意图识别到底把用户请求分到了哪个标签。黑盒的代价就是这个没法定位只能试错。试错的成本不只是人力还有用户的耐心。一个AI产品如果连续三次答非所问用户基本不会再给第四次机会。更麻烦的是如果你是在给企业做交付客户一句“为什么这么答”你会非常被动。你总不能说“因为模型是这么想的”吧。1.2 白盒化不是把权重贴出来而是让每一步都被看见很多人听到“白盒”就问是不是要把神经网络的权重都可视化不是。对工程实践来说白盒化是四个层面的可感知模型层白盒能说清楚“为什么输出这个结果”比如蒸馏出一个可以解释的小模型或者用注意力分析工具看到模型读了哪些输入。流程层白盒能回答“每一步发生了什么”也就是Agent的每一步工具调用、每一次LLM请求、每一次重试都留下记录。数据层白盒能说明“用什么数据评估的”评估集、badcase、标注规范都是公开可查的。门禁层白盒能证明“这次改动为什么敢上线”回归测试跑没跑、对比结果如何、有没有达到准入标准。做一个类比黑盒的AI产品就像外卖你只能看到包装好的餐盒出了问题不知道是食材不新鲜还是后厨不规范。白盒化就是把后厨做成透明厨房洗菜、切菜、炒菜、装盒每个环节都在你眼前。这样万一餐里有沙子你能一眼看出是哪一步漏出来的。1.3 这个系列为什么值得“见证历史”六年前AI产品的主流交付方式就是“模型训练完接口一包文档一句‘本模型可能产生幻觉请谨慎使用’”。用户只能在黑盒外面等结果开发者也不知道模型为什么在某个样本上抽风。这个系列对我来说是在记录一个转向AI产品正在从“不可知”走向“可知”。社区里已经出现了一些苗头大模型厂商开始公开训练方法和智能体构建细节不少开源模型把推理过程中的思维链放出来团队也开始把评估集放到Git仓库里。这些动作放到五年前是难以想象的。当时各家都把模型细节当成商业机密现在越来越多的团队意识到不透明带来的信任成本比技术泄露的损失大得多。这个系列做到第二十六弹真正想见证的不是某个模型分数多高而是AI产品圈子的共识正在从“包装”转向“透明”。2. 白盒化四把钥匙黑盒蒸馏、链路观测、评估数据、回归门禁2.1 黑盒蒸馏让大模型的“内功”转移到看得见的小模型上先解释一下黑盒蒸馏。蒸馏原本是模型压缩领域的技术用一个强大的“教师模型”教一个轻量的“学生模型”。在黑盒场景下我们没有教师模型的权重和内部特征只能用它的输出当监督信号。教师模型收到输入后不仅输出最终答案还输出一段推理解释我们把这些“答案解释”作为训练数据去训练学生模型。这么做的好处是学生模型是白盒的。你可以存下它的权重可以继续微调可以导出每一层的特征甚至可以观察到它在某个输入上为什么给出“亲子游”而不是“情侣游”。我们在项目中用DeepSeek作为教师模型因为它生成的长文本结构和推理过程相对清晰。蒸馏时我们要求教师模型输出“先分析后结论”比如“用户提到‘带娃’和‘海边’所以核心需求是亲子游又提到‘三天’和‘不累’所以还需要低强度的行程。结论推荐三亚亚龙湾理由沙滩平缓、亲子设施多。”然后我们拿这些数据去微调一个轻量分类模型让它学会同样的判断逻辑。实际蒸馏时如果只是简单把教师模型的输出当硬标签学生模型很容易学到“答案”但学不到“判断依据”所以我们要求教师模型连思考理由一起写出来。这个细节很关键。2.2 链路观测给Agent装上全景记录仪Agent和单次模型调用最大的区别是多步决策。一个Agent接收用户请求后会先做意图识别再拆解成多个子任务然后依次调用工具、汇总结果、生成回答。任何一个环节出问题最终表现都会异常。缺少链路观测你就只能看到“终态错误”没法看到“哪一步错了”。我们给Agent做的第一层白盒设施是trace链路。每个用户请求进来时生成一个request_id然后所有步骤都带着这个ID写日志。日志字段包括步骤名、调用的模型版本、prompt模板版本、输入输出、耗时、token数、错误信息。这些日志统一进日志中心支持按request_id搜索。一开始团队觉得这样有点重直到有一次线上出现“用户投诉推荐结果完全不对”我们直接复制request_id查trace发现用户在第四步“检索酒店”时工具返回了一个空列表Agent没有处理空结果直接把兜底话术“我们为你推荐以下酒店”接上了于是输出了一段没有酒店名的废话。整个过程只用了几分钟就定位了放在以前至少要半天。2.3 评估数据不要再用“我点几下觉得还行”来验收白盒化必须依赖评估数据否则一切“改进”都只是感觉。我们项目里建了一个核心评估集专门用来度量Agent整体表现。评估集分为三块第一块是常规用例覆盖产品定义好的各类意图比如“亲子海边游”“情侣城市漫步”“独自爬山”等等每个意图至少十条不同的表达方式。第二块是边界用例包括超长输入、歧义表达、多轮上下文切换、用户中途反悔等。第三块是违规用例用来验证Agent不会给出危险、不当或不符合规定的回答。这些用例不是静态的。每次线上收集到badcase我们都会做一次标注如果确认是模型或流程的错误就把这个badcase补进评估集。这样评估集就像一个不断重叠的“错题本”每次跑评估时不仅看总分还要看“上次错过的题这次有没有做对”。2.4 回归门禁让模型更新像代码发布一样可控代码仓库有CI有单元测试有分支保护但很多AI产品团队没有。结果就是模型版本和prompt版本经常乱成一团谁改了什么全靠回忆。白盒化的收尾工作就是把评估变成门禁挂在发布流水线上。具体做法很简单写一个评估脚本把它插进CI流程。每次有人改prompt、换模型、调系统参数都要先跑一遍评估集。如果候选版本的“核心用例准确率”低于线上版本流水线直接失败不允许合并。这样团队里对“效果是否变好”的争论就少了因为衡量标准是客观的。门禁里还可以加一些专项检查比如“违规用例必须100%拒绝”“工具调用失败率不能超过某个阈值”。我们把这些检查分成P0和P1。P0项不通过直接拦截P1项作为预警不阻塞上线但会记录到发布确认单里。3. 完整实操把一个旅行推荐Agent白盒化3.1 实操前状态这是一个“能用但不可查”的Agent我们拿一个具体的旅行推荐Agent作为案例。改造前的架构长这样用户输入文本先调用大模型做意图识别再调用一个“目的地搜索”工具再调用“酒店查询”工具最后用大模型生成一段推荐文案。每个环节都是黑盒意图识别用什么模型、prompt里写了什么规则、工具调用失败时怎么兜底统统没有记录。有一次用户问“带娃去三亚住哪里方便”Agent推荐了三亚湾某酒店理由是“距离海滩近”。用户实际需要的可能是“离儿童乐园近”但Agent没有查询“亲子设施”相关的信息。这种错误如果没有trace你根本不知道是检索工具漏了字段还是大模型在生成推荐时自己脑补了“方便”。所以我们定改造目标让每一次推荐都能回答出“为什么是这个结果”。3.2 第一步埋点与日志规范先解决“能看到什么”给Agent加上trace是最基础的操作。我们把入口统一封装每个请求进来都分配一个request_id然后在所有关键节点写结构化日志。下面是一个简化的JSON日志格式{ request_id: req_20250107_abc123, session_id: sess_0001, user_intent: 海边带娃三日游, steps: [ { step: intent_parse, llm_model: deepseek-v3, prompt_version: prompt/intent/v3, input: 带娃去海边三天不要太累, output: 亲子游, confidence: 0.94, latency_ms: 320 }, { step: search_hotel, tool: hotel_api, params: { destination: 三亚, family: true, duration_days: 3 }, result_count: 12, latency_ms: 180 } ], final_output: 推荐三亚亚龙湾附近亲子酒店... }这段JSON看起来简单但它帮我们回答了很多关键问题。比如“用户意图被识别成了什么”“工具真的返回了结果吗”“哪一步耗时最长”“token消耗是多少”。实际落地时我会建议直接用云原生的trace系统或者自研一个只有几个接口的日志服务。重要的是不要把日志格式设计得太复杂否则团队没有精力维护很快就不写了。3.3 第二步prompt版本管理让“改坏了”不再是常态这个坑我踩过很多次。prompt直接写在代码里改完上线出了bug谁都不知道当前线上版本和上一个版本有什么区别。后来我们把所有prompt模板抽出来放到独立目录每个文件都有版本号代码里只引用模板ID。prompts/ intent/v3.prompt recommend/v2.prompt safety/v1.prompt每次修改prompt都要走评审变更记录里写明改动点。比如recommend/v2到v3的改动写的是“增加了一个规则推荐结果必须符合用户显式声明的出行人数”。这样以后如果线上效果出现波动可以先查“最近有没有prompt变更”再看trace里的prompt_version两者一对比问题就缩小到一个文件。3.4 第三步黑盒蒸馏小模型把高成本黑盒调用换成白盒小模型改造中期我们发现意图识别这一步其实不需要每回都调用大模型又贵又慢。于是我们对意图识别模块做了黑盒蒸馏目标是产出一个白盒小模型。具体操作是这样的先收集两万条脱敏用户请求然后用DeepSeek作为教师模型逐条生成标注结果。每条标注不只是标签还包括判断理由比如“用户提到‘带娃’和‘三天’所以是亲子游”。生成完成后我们会做人工抽检大概抽查五百条凡是有幻觉、信息缺失的样本整批返工重跑。清洗后的数据用来微调一个通义千问级别的分类小模型微调命令大概是python train_classifier.py \ --model_path qwen/Qwen2.5-0.5B-Instruct \ --train_data data/intent_distill_v1.jsonl \ --output_dir models/intent_distill_v1蒸馏后的模型体积很小推理延迟从原来的400毫秒降到80毫秒准确率也从之前大模型的88%提到了91%。更重要的是这个小模型能输出判断依据产品同学可以直接读它为什么这么分类。这样一来意图识别这块就从“黑盒大模型”变成了“白盒小模型”。3.5 第四步落地回归门禁用自动化评估兜底白盒化的最后一步是建评估门禁。我们整理出80条核心用例分成了三类50条常规意图、20条边界场景、10条必须拒答的违规内容。然后写了一个评估脚本python eval_agent.py \ --config configs/online.yaml \ --suite core \ --output results/compare_0112.html这个脚本会把线上版本和候选版本各跑一遍评估集输出对比报告。报告中会列出每一条用例的“通过/失败”以及候选版本相比线上版本的整体变化。我们设置了门槛P0用例准确率不得下降违规用例必须全过。如果候选版本有任何一个P0用例不过流水线就会失败。这样prompt改动和模型更新都被纳入代码评审流程而不是靠“我先上线试试”。上线后如果发现badcase我们把它补进评估集作为下一个版本的必测项。4. 白盒化途中踩过的坑与排查实录4.1 坑日志埋点把prompt污染了第一次给Agent加trace时我图省事直接让日志模块把调试信息写进system prompt。结果模型开始回复一些奇怪的、像日志一样的内容比如“以下是JSON日志请忽略”。后来排查发现日志字符串混进了prompt上下文模型把它当成待处理任务的一部分。这个坑的教训很简单埋点代码必须放在API调用之外任何调试信息都不能进入发给模型的输入。日志系统的职责是记录不是参与生成。后来我们做了一个约定代码里所有“log_xxx”函数都只能往日志中心写谁也不允许把它拼到prompt里。违反这条的人留在评审会上讲两句。4.2 坑蒸馏数据清洗不彻底学生模型学会“废话”第一次蒸馏出的意图分类模型准确率很高但我们打开它的判断依据一看全是“首先用户的需求是……其次我需要考虑……最后所以我认为……”这类废话。原因是教师模型生成的思考链太啰嗦学生小模型把这种风格当成标准了。虽然分类结果对但产品同学看到这种依据会觉得不放心。解决方法是加数据清洗规则过滤掉超过80字的推理样本并且修改教师模型的生成prompt要求它“直接说明核心理由最多两句话”。重新蒸馏后判断依据的干净度明显提升例如“用户提到带娃和三天所以是亲子游且需要低强度行程”。这个小改动对线上可信度影响很大。4.3 坑badcase不闭环测试集三个月不变我们团队一开始也建立了badcase清单但只是记录没人跟进。结果三个月后同一个问题又出现了。原因是那些badcase没有被转成自动化测试用例也没有人验证它们是否已修复。后来我们定了一个固定节奏每周五下午由测试开发把本周新增badcase逐一复现能稳定复现的直接加入评估集不能稳定复现的放进“退化观察区”下个版本继续盯。从那以后类似问题基本没有再漏过。4.4 坑蒸馏模型测试集分数高线上业务却下降有一个阶段我们优化了意图分类小模型评估集准确率提升到91%但线上业务指标反而下降了。百思不得其解后来分析线上日志发现近两个月用户的真实请求已经偏向“亲子徒步”“自然探索”而我们的评估集还停留在“海边度假”“城市漫步”。评估集的分布和线上分布严重不一致蒸馏出来的模型自然在新场景上表现不佳。这个坑提醒我评估集不是建完就一劳永逸的它应该跟着线上数据流动。现在我们的做法是每个月从线上日志随机抽样两千条人工复核一遍意图分布然后用新分布去微调评估集再重新跑一轮回归。蒸馏训练集也按这个节奏动态更新旧数据按半衰期权重下降新数据逐步加入。4.5 坑多模型多版本协同现场成了一锅粥当黑盒大模型和白盒小模型同时在线再加上多个prompt版本出问题时很难快速区分是哪个环节引起的。有一次用户反馈推荐酒店不准确我们查trace发现prompt_version是recommend/v3但去看Git仓库时发现v3已经被改成v4了线上怎么还用的v3原来是因为没有把模型版本和prompt版本打成一个整体制品部署时各自拉各自的导致线上数据滞后。解决方法是引入“制品”概念每一次发布都生成一个唯一的制品号包含模型ID、模型版本、prompt版本集合、评估结果、部署时间。上线时记录这个制品号所有trace和日志都带上它。这样每个线上问题都能精确对应到“哪组代码和哪个模型”排查时间大幅缩短。4.6 白盒化常见问题速查表这里整理一张日常排查表适合团队内部贴墙现象可能原因排查动作输出不稳定prompt版本不一致或temperature过高查request_id对应的制品记录确认使用了哪个模型和pompt版本意图识别准确率高但业务效果差评估集分布和线上不一致用线上日志采样更新评估集小模型蒸馏后效果退步教师模型输出噪声大或清洗不足过滤过长样本要求精简判断依据Agent中途报错工具调用失败或上下文超限查看trace中steps的异常信息线上用户投诉推荐不靠谱新改动没有跑回归门禁强制CI评估禁止跳过门禁4.7 白盒化不是一步到位先把“看得到”做完我见过不少团队上来就想做“全可解释”比如给每个Agent输出都附一个可解释性报告结果被复杂度卡死连最基础的日志都没做完。我的建议是分阶段来先做链路观测让每个错误都能被追踪再做评估数据让效果有标尺再做回归门禁让上线有底线最后才碰蒸馏和可解释模型。这个顺序在这个系列里反复验证过是最稳的。做完这一轮白盒化改造之后我再也不怕用户问“为什么这么答”了。我可以直接打开trace告诉他意图识别把“带娃”分到了“亲子游”工具检索到了哪些酒店大模型基于什么理由生成了最终推荐。哪怕到后面模型效果仍然有波动至少每一次波动都可回溯、可分析、可优化。这本身就是AI产品从“黑盒”走向“白盒”最实在的一步。
返回列表