跳到主要内容

702 篇博文 含有标签「llm」

查看所有标签

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

· 阅读需 13 分钟
Tian Pan
Software Engineer

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

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

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

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

· 阅读需 14 分钟
Tian Pan
Software Engineer

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

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

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,并将其跨网络传输给一个供应商,而该供应商可能会记录它、在其上进行训练,或将其以明文形式保存三十天。这些都不属于读取权限范畴。这些都不在覆盖范围内。

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

跨区域 Prompt 版本偏差:你的 CDN 误运行了六小时的 A/B 测试

· 阅读需 12 分钟
Tian Pan
Software Engineer

你在 09:14 发布了一个系统提示词(system-prompt)变更。发布仪表盘在 09:31 变绿。到 11:00 时,你的评估追踪器依然显示正常,成本仪表盘也无异常,但一位客户成功工程师联系了团队:仅在亚太地区,解析端的结构化输出错误上升了约 3%。北美无异常。欧洲无异常。

发布在覆盖 67% 的区域时自动暂停了,因为某个 POP 节点上的一个非核心健康检查在切换期间发生了抖动,而当时没人注意到。在六个小时里,us-easteu-west 运行着提示词 v47,而 ap-southap-northeast 仍停留在 v46。你正在运行一个按地理位置划分的实时 A/B 测试——只不过这个测试不是你设计的,你看不到测试过程,而且那个本应捕捉质量回退的评估套件正巧连接到其中一个区域的新版本,然后若无其事地忽略了问题。

这种失败模式并不是单个工具的 bug。它是将提示词通过为不同类型的工件构建的部署系统进行推送时,所产生的可预见的后果。

没人召集的索引策略委员会:超越一次性迁移的 RAG 语料库治理

· 阅读需 11 分钟
Tian Pan
Software Engineer

两年前,一个团队将他们的检索索引指向了 Wiki、Zendesk 导出文件以及公共文档的快照。上周,同一个索引返回了一个已弃用的运行手册(runbook),告诉 SRE 去重启一个已不存在的服务。该运行手册已经废弃了 18 个月。没人负责它的下线工作,所以没人把它删掉。Agent 自信地引用了它。模型没有错;错的是语料库(corpus)。

这是检索评估(retrieval evals)中不会出现的故障模式:语料库被视为一次性的工程决策,而实际上它是一个持续的治理问题。负责初始摄取(ingestion)的团队早已解散。本应标记出客户机密 PDF 的法律审查从未发生,因为没人告诉法务部门存在这个流水线(pipeline)。“新鲜度策略”(freshness strategy)只是一个在第三季度离职的人留下的 Slack 消息。检索索引变成了任何人抓取过的每一份文档的共享收件箱,而纳入标准已逐渐演变为“任何容易摄取的内容”。

推理力度预算编制:当思维 Token 成为财务账单的独立细目

· 阅读需 13 分钟
Tian Pan
Software Engineer

当你的财务团队第一次问,为什么单个用户在回答一个价值 0.1 美分的问题时产生了两美分的账单,那个电话讨论的不会是模型,而是发票上那行十二个月前还不存在的项目:推理 Token (reasoning tokens)。在账单上它们看起来像输出 Token,在大多数服务商那里也按输出 Token 的费率计费,而且它们没有天然的上限。一个在非推理模型上只需产生 400 个 Token 回复的查询,可能会悄无声息地消耗 8,000 个内部思考 Token 才能得出答案——唯一注意到这一点的人是核对支出的人。

在 API 时代的大部分时间里,“使用的 Token 数”是一个诚实的数字。你输入提示词,得到响应,账单是两者的清晰函数。推理模型打破了这种直觉。模型现在在发出调用者将阅读的答案之前,会生成一个隐藏的、可计费的、仅内部可见的思维链,而该链的大小取决于模型自身对问题难度的评估。用户可见的输出可能只有一句话,而账单可能长达十页。

重新规划而非重试:为什么大多数智能体错误并非瞬时性的

· 阅读需 12 分钟
Tian Pan
Software Engineer

一次日历写入返回了 409 Conflict。框架默认的错误处理器开始介入:退避 200ms,重试。同样的冲突。退避 400ms,重试。同样的冲突。退避 800ms,重试。等到智能体放弃并告诉用户“我无法预订会议”时,它已经浪费了三秒钟的延迟预算,去证明第一条响应就已经告诉它的事实:该时段已被占用。世界没有改变。它也不会在 800 毫秒内改变。重试永远不会奏效,因为这个错误中没有任何瞬时性的成分。

这是智能体系统中最为常见的错误处理 bug,而且它就隐藏在当今几乎每一个发布的框架之中。带有指数退避的重试模式是从无状态 HTTP 客户端中照搬过来的——在那里这种模式完全正确——但被引入到有状态的规划循环中时,它就完全错误了。对于智能体中的工具错误,正确的默认处理方式不是重试,而是重新规划。

采样参数继承:当 0.7 的温度从规划器泄露到验证器时

· 阅读需 12 分钟
Tian Pan
Software Engineer

一个在 8% 的情况下会推翻自己答案的验证器(verifier)并不是一个表现不稳定的模型。这是一个由于框架默认采用继承机制而进入生产环境的采样配置 Bug。规划器(planner)需要 temperature=0.7 来头脑风暴子任务的分解。而验证器 —— 其全部工作就是针对答案是否符合评分标准给出低方差的“是”或“否” —— 却是通过同一个 harness 调用实例化的,并默默地沿用了相同的温度设置。没有人故意这么设置。甚至根本没有人去设置它。

这是你的技术栈中最昂贵却无人认领的参数。它在调用树中不断累积:验证器上方的总结器、下方的结构化输出提取器,以及包裹整个流程的重试循环,都像使用全局变量一样沿用着规划器的“保持创意”旋钮。这笔账会同时体现在三个地方:评估的不稳定性、Token 支出,以及资深工程师花半天时间对一个结果发现根本不是退化的“性能退化”进行二分法排查。

AI 功能指标陷阱:为什么 DAU 和留存率在随机化表面 (Stochastic Surfaces) 上会产生误导

· 阅读需 13 分钟
Tian Pan
Software Engineer

一位产品经理(PM)带着一张幻灯片走进 AI 功能评审会,上面写着:“参与度 +12%,会话时长 +8%,留存率上升 3 个百分点。” 房间里的人纷纷点头。而在两个工位之外,客服主管正盯着另一张图表:涉及 AI 界面的工单增加了 22%,最常见的处理逻辑是“用户放弃,由人工客服协助”。这两个数字都是真实的,且都来自同一个产品。PM 的仪表盘建立在这样一个假设之上:AI 功能产生的事件形状与它所取代的按钮完全相同。事实并非如此。仪表盘统计的数据与用户实际体验之间的差距,正是 AI 功能在众目睽睽之下悄然失败的原因。

确定性功能的操作手册将交互视为点击流:用户触发一个事件,系统做出反应,用户继续操作。AI 功能具有不同的事件形状——一个包含阶段、重试、转向人工以及遥测数据永远无法看到的离线判断的“任务弧”(Task Arc)。将确定性仪表盘套用在这个任务弧上,就像是用 2018 年的面试流程来筛选 2026 年的工作职位。数字在上升,但这些数字本应预测的结果却在下降。

你的 stop_reason 在说谎:构建生产环境故障排查真正需要的停止分类法

· 阅读需 14 分钟
Tian Pan
Software Engineer

运维工程师调出一个 trace。模型已返回,span 正常关闭,API 调用显示 stop_reason: end_turn。从平台提供的各种信号来看,这是一次成功的生成。3 分钟后,客户报告说 Agent 煞有介事地写了半个配置文件,宣布操作完成,然后就继续下一步了。Trace 里没有任何预警信号,因为预警信号不在 API 协议里 —— 供应商提供的停止原因只有四到七类,而你的事故排查所需要的答案,恰恰隐藏在这些类别的缝隙之中。

停止原因(Stop reasons)是工程师在故障排查时最先查看的字段,也是最具误导性的字段。这些值是为运行时(runtime)设计的,旨在决定下一步该做什么:这一轮是否完成了?是否请求了工具?是否超出了预算?安全检查是否介入了?它们并不是为了让开发者重建答案出错的原因而设计的,而这两者之间的差异,正是生产团队耗费整个下午的时间所在。

流式 JSON 解析器:Token 与类型化对象之间的鸿沟

· 阅读需 13 分钟
Tian Pan
Software Engineer

模型正在逐个 Token 地输出 JSON。你的 UI 希望在字段出现的那一刻就进行渲染 —— 在冗长的回答正文之前显示置信度得分,或者在模型填充工具调用参数时实时显示它们。接着,有人尝试在每个数据块(chunk)上调用 JSON.parse,结果整个系统就崩溃了,因为 JSON.parse 是“全或无”的。它需要一个结构完整的文档才能返回任何结果。在模型输出闭合括号之前,你什么也显示不出来。

这不是一个可以通过 try/catch 解决的解析器问题。标准 JSON 解析器是针对内容长度已知的 HTTP 响应设计的。部分输入并不是它所建模的状态 —— 而是被视为“输入错误”。当你将 Token 流视为 HTTP 正文处理时,你继承了三十年来“文档要么完整,要么无效”的传统,而你的 UI 则为此付出了代价。