跳到主要内容

458 篇博文 含有标签「ai-engineering」

查看所有标签

空洞解释问题:当模型的推理只是装饰而非证据

· 阅读需 12 分钟
Tian Pan
Software Engineer

一个贷款审查工具标记了一份申请。审查员点击“解释”,得到了四个整齐的要点:过去六个月的收入波动、信用额度使用率超过 70%、最近的地址变更、两个信用记录较少的被抚养人。这些理由读起来就像一位细心的核保人员写的。审查员批准了覆盖操作并继续。

令人不安的部分是:模型从未利用这些信号做出决定。它们出现在解释中,是因为它们是那种 可以 证明标记合理性的因素——而不是因为标记源自它们。实际的计算是一种模型无法表达的狭窄潜在特征模式,加上一些解释中从未提及的相关性。这些要点是事后合理化(post-hoc rationalization),其编写目的是为了可信,而不是为了真实。

这就是空洞解释问题(hollow explanation problem),它与幻觉(hallucination)不同。该解释中的每一个单独主张在事实层面可能都是正确的。但用户的问题——你为什么这么决定?——被虚假地回答了。

Token 间抖动:你的 p95 仪表盘看不见的流式传输 UX 失败

· 阅读需 13 分钟
Tian Pan
Software Engineer

你的延迟仪表盘显示一切正常。p95 的首字延迟(TTFT)低于 800ms 的目标。p99 的总生成时间也在 4 秒的预算之内。然而,一位资深 PM 转发了一个支持线程:“助手在回答中途卡住了大约三秒钟”,“它停顿了一下,然后突然吐出一整段文字”,“我以为它死机了”。本周有三位用户因为同样的投诉卸载了应用。团队中没人能在笔记本电脑上重现这个问题,而且你记录的每一项指标都显示系统运行健康。

能解释这个 Bug 的指标正是你没在测量的那个:连续 Token 之间时间间隔的分布。一个看起来很完美的 p95 总时长可能会掩盖这样一种流:其中 8% 的响应在生成中途包含一个 2.5 秒的停顿。对于一个看着字符实时出现的用户来说,这种停顿意味着系统出故障了,而不仅仅是慢。你的仪表盘测量的是电影的总时长,而你的用户正在观看电影。

倒置智能体:当用户是规划者,模型是步骤执行者时

· 阅读需 13 分钟
Tian Pan
Software Engineer

当今大多数智能体 (agent) 产品都达成了一个简单的契约:模型决定做什么,用户点击“批准”。对于低风险的消费者聊天场景 —— 预订餐厅、摘要收件箱、起草非正式回复 —— 这确实是正确的形式。但对于法律起草、财务咨询、医疗分诊和事件响应来说,这却是灾难性的错误。在这些场景中,用户承担着模型永远无法承担的问责,而且错误 计划 的成本远高于任何单个 步骤 的成本。

反向智能体翻转了这种极性。用户将计划构思为一系列命名的、可重新排序的步骤。模型按需执行每个步骤 —— 拥有完整的上下文、工具访问权限和推理能力 —— 但绝不决定下一步该做什么。模型可以提供建议,但建议仅供参考,不具有自主性。这并不是一个更糟糕的自主智能体;它是一个完全不同的产品,虽然其成本和延迟表现绝对更差,但信任度绝对更高,专门针对那些否则会完全拒绝采用自主版本的用户。

团队一直在犯的错误是将“自主性”视为默认的努力方向。它其实是一个你在每个界面上选择的 UX 维度。如果搞错了极性,你交付的功能就会被那些承担最高风险的用户悄悄拒绝使用。

评估困局:当你的 LLM 评测器比被评分的模型更聪明时

· 阅读需 11 分钟
Tian Pan
Software Engineer

一个回归告警在周一早晨响了。你的留出评估集的忠实度(Faithfulness)在周末从 0.86 掉到了 0.78。没人发布新模型,没人动过提示词,也没人改过检索索引。值班工程师花了三个小时排查才发现,唯一改变的是裁判模型——自动评估器静默滚动到了一个更新的快照,它捕捉到了旧版本放过的细微委婉语。同样的答案,同样的模型,更低的分数。真实的数字,虚假的回归。

这就是评估困境:随着你的 LLM-as-judge(以 LLM 作为裁判)变得更敏锐,你在固定系统上的得分会下滑,而那个本应检测回归的仪表盘开始制造回归。没注意到这一点的团队会花上几个季度去追逐完全存在于“尺子”里的“质量偏移”。

知识图谱的时效性与向量索引的时效性具有不同的 SLA

· 阅读需 12 分钟
Tian Pan
Software Engineer

向量索引即便有约 10% 的误差,也没人会惊慌。但知识图谱如果缺失了一条边,就可能导致有人向监管机构提交一份错误的答案。从数据工程组织的架构图来看,这两种故障模式如出一辙——都被归类为“索引陈旧”——并且它们共用同一个变更数据捕获(CDC)流水线,具有相同的延迟容忍度。流水线的规格是根据向量负载确定的,因为向量是更“大声”的消费者。图谱默默地继承了这些默认设置,而这种沉默本身就是 bug。

向量检索和图谱检索在数据陈旧时的失败表现截然不同。将它们视为同一种延迟问题,会导致你构建出的系统虽然在 RAG 基准测试中得分很高,但在多跳查询中却会产生隐蔽的错误——当然,这种“隐蔽错误”往往是用户最后才会察觉到的。解决方案不是更快的流水线,而是要认识到“陈旧”具有两种不同的含义,为每种边类别设计新鲜度分层,并在监管机构发现之前,通过评估机制捕捉到这种差异。

你的 LLM Judge 存在长度偏见、位置偏见和格式偏见 —— 且无人审计你的模型

· 阅读需 13 分钟
Tian Pan
Software Engineer

我上个季度合作的一个团队看着他们的 LLM-as-judge 分数在六周的提示词(prompt)迭代中从 78% 飙升至 91%。他们发布了产品。但用户却非常讨厌它。新的提示词产生了更长、格式更丰富、听起来更自信的回答 —— 而评委(judge)爱死了每一个回答。团队并没有构建出更智能的提示词。他们只是对评委的偏见进行了逆向工程。

这是团队中没人审计的失败模式。LLM-as-judge 有据可查的系统性偏见:无论质量如何,更长的回答得分更高;在两两比较中,第一个选项胜出的概率高于随机概率;且看起来像评委自身训练分布的输出得分高于不符的。如果你在十二个月前接入了一个 LLM 评委,且从未针对人类进行重新验证,那么你的分数就不是质量信号 —— 它们衡量的是你的提示词学会如何操纵其评估器的程度。

令人沮丧的是,捕捉这一点的审计方法很直接,防止它的校准纪律也很廉价,但几乎没有团队会执行其中任何一项。

你的 SRE 复盘模板遗漏了决定每次 LLM 故障的六个关键字段

· 阅读需 12 分钟
Tian Pan
Software Engineer

当你第一次用经典的 SRE 复盘(Postmortem)模板来分析 LLM 事故时,模板赢了,而事故输了。时间线、诱因、缓解措施、预防措施 —— 每个字段都填好了,每个复选框都勾选了,但在文档的最后,没人能回答唯一重要的问题:究竟是哪个变量发生了变动?不是部署事件。不是基础设施故障。不是代码变更。而是 Prompt 的修订、路由选择的模型切片、未触发报警的 Eval 评分所用的 Judge 配置、质量投诉发生时的检索索引状态、规划器(Planner)正在组合的工具 Schema 版本,或者是异常时间段内的流量组合。这些在模板里都没有对应的一行。

SRE 模板并不是为那些“事实来源是观察到的行为而非代码路径”的系统设计的。在 LLM 技术栈中默默变动的变量,正是模板从未需要列举的变量。强行借用模板,只会产生那种被归类为“持续调查中”的“我们不知道发生了什么变化”的复盘报告。

2026 年的长上下文 vs RAG:为什么它是基于功能的决策,而非架构信仰

· 阅读需 14 分钟
Tian Pan
Software Engineer

长上下文与 RAG 的经济学在两年内翻转了两次,而在那两个窗口期中选择了某种架构的团队,现在正处处支付着错误的代价。在 2024 年,趋势是将一切都塞进上下文窗口,因为窗口在不断扩大,而每 token 的价格在持续下降,因此检索流水线被斥为过时的繁琐工作。在 2025 年,共识发生了反转:关于“上下文腐烂”的研究表明,在百万级 token 的提示词中,窗口中部的有效召回率大幅下降,全窗口调用的延迟变成了用户体验问题,且账单变得非常惊人,于是检索技术重新得到了重用。到 2026 年,正确的答案不再是任何一种口号。它是一个在设计阶段做出的基于单个功能的决策,并记录下四个维度的权衡,因为为整个产品选择单一架构,是让每个功能同时出错的低成本方式。

一直困扰着团队的思维模型是将长上下文 vs RAG 视为路线图上的承诺,而不是针对每个界面的选择。你阅读了一篇有影响力的博客,选边站队,雇佣了擅长那一边的工程师,编写了一份将其规范化的平台文档,现在每个新功能无论是否合适,都采用了相同的架构。需要新鲜数据的功能忍受着陈旧的上下文。需要可扩展语料库的功能为他们永远不会使用的检索基础设施买单。需要引用来源的功能在发布时却缺失了这一项。这些都不是 bug。它们是将功能级决策视为产品级决策所带来的必然代价。

30 天 Prompt 见习计划:当“阅读代码”失效时,如何入职工程师

· 阅读需 13 分钟
Tian Pan
Software Engineer

一位资深工程师在周一加入你的团队。到了周五,他们已经交付了一个涉及 11 个文件的 TypeScript 重构,并在通过评审时仅有两个小细节(nits)需要修改。两周后,这位工程师打开了路由智能体(routing agent)的系统提示词——240 行指令、三个编号的示例块、四个“绝不允许”子句,以及底部一段读起来像道歉的段落——然后盯着它看了一个小时。他们无法告诉你如果删除第 87–94 行会发生什么。六个月前写下这些内容的工程师也无法告诉你。

这是没人会写在入职文档里的鸿沟。一个重度依赖提示词的代码库看起来像是个代码库:它存在于同一个仓库中,运行相同的 CI,并在相同的 PR 中接受评审。但它的语义却存在于别处:存在于一个团队中没人构建的模型观察到的行为中,针对的是一个没人能完全枚举的输入分布,其失败模式表现为添加一句话的 PR,而不是错误报告。传统的代码阅读工具——类型、签名、测试、命名——几乎不起作用。一个试图“阅读代码”的新员工无法了解为什么每一行都在那里,而一个只交给他们 Notion 文档和 Slack 频道的团队,实际上是在默认将入职培训“外包”给提示词的最初作者。

提示词资产贬值:你团队中缺失的 AI 维护时间表

· 阅读需 10 分钟
Tian Pan
Software Engineer

工程主管们对“代码腐烂”这一概念已经习以为常。依赖项需要更新,基础设施有生命周期管理,证书会在无人质疑的日期过期。然而,提示词仓库(prompt repository)却往往被视为一种“一次编写,多次读取”的产物——尽管它定义了你的产品如何与一个每六周就发布一次行为变更的概率引擎进行对话。

六个月前针对当时主流模型调优的系统提示词,现在依然在生产环境中使用。针对早已变更的分词器(tokenizer)挑选的 Few-shot 示例,仍在每次调用时被注入。重排序提示词是针对供应商上季度已废弃的嵌入端点调优的。没有人安排审查。也没有人打算去安排。

这并非假设性的失效模式。当一个团队将其精心针对 GPT-4-32k 稳定化的提示词套件迁移到 GPT-4.1 和 GPT-4.5-preview 时,其回归测试的通过率分别仅为 95.1% 和 97.3%。在生产环境中,3-5% 的隐性质量退化绝非可以忽略的误差;在任何具有一定规模的场景下,这都是一种用户可见的退化,而团队中没人是有意发布这种退化的。而且,这些还是拥有回归测试套件的团队。中等水平团队的“回归测试”,不过是值班工程师在处理上一次事故时凭感觉形成的印象。

我们缺失的范畴是提示词资产折旧(prompt asset depreciation):这是一种维护纪律,它将每个生产环境中的提示词视为具有已知寿命的折旧资产,而非一成不变的常数。

Prompt Bisect:通过二分查找定位破坏 Eval 的修改

· 阅读需 12 分钟
Tian Pan
Software Engineer

评测榜单的分数一夜之间掉了两分。在绿色运行(通过)和红色运行(失败)之间,唯一发布的内容就是上周的提示词 PR —— 那个包含了 17 处修改的 PR。两个章节调整了顺序。三个新的 few-shots。一个更严厉的拒绝条款。一个更换过的角色描述。还有一些人称之为“润色”的单词级改动。当复盘开始时,有人说了句显而易见的话:“肯定就是其中之一。”然后他们花接下来的两天时间去搞清楚到底是哪一个。

这两天时间是寻找单一回归最昂贵的方式。而另一种只需几分钟的方法则完全借用了一个有着 40 年历史的内核调试技巧:对补丁进行二分查找 (bisect)。将提示词视为一系列可回滚的变动块 (hunks),将评测套件作为断言条件,让二分查找隔离出导致分数波动的代码行。其中的数学原理与 git bisect 在提交记录上运行的原理一致,而且它强制要求的提示词管理规范,其带来的收益甚至超过了二分查找本身。

Prompt-Eligibility:数据分类中缺失的那一列

· 阅读需 13 分钟
Tian Pan
Software Engineer

调出你公司的数据分类政策。公开、内部、机密、受限——四个整齐的层级,每一个都映射到一组访问控制和一份批准的存储位置清单。现在问一个该政策从未准备回答的问题:这些层级中,哪些允许以发送给第三方模型 API 的 Token 序列的形式离开公司边界?

答案几乎总是沉默。这并非因为政策本身有误,而是因为它是不完整的。当今使用的每种分类方案都是为一种访问向量设计的,即询问“该员工是否被允许读取这一行?”Prompt 层引入了一个完全不同的向量:一个获得授权的服务读取了该行,将其转换为 Prompt,并将其跨网络传输给一个供应商,而该供应商可能会记录它、在其上进行训练,或将其以明文形式保存三十天。这些都不属于读取权限范畴。这些都不在覆盖范围内。

这就是缺失的一列。在你添加这一列之前,你的数据分类文档只是在自信地宣称一种你实际上并不具备的控制态势。