跳到主要内容

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

查看所有标签

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

· 阅读需 14 分钟
Tian Pan
Software Engineer

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

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

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

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

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

RAG 读后写竞争:当你的向量索引引用了一个已不存在的文档

· 阅读需 11 分钟
Tian Pan
Software Engineer

一个用户在 14:32:07 向你的助手提问。你的检索器在 14:32:08 触发,从政策手册中提取了五个分块。模型思考了几秒钟,起草了回复,并在 14:32:12 流式传回了一个答案,自信地引用了第 4.3 节——而管理员在 14:32:10 刚刚删除了这一节,因为它有误。用户读到了一段来自已不存在文档的权威引用,甚至还附带了一个返回 404 的可点击链接。

你的技术栈中没有任何环节报错。检索器返回了有效的命中结果。模型生成了流利、有据可查的文字。引用的分块 ID 在检索发生时确实存在。然而,根据任何合理的定义,这个答案都是一个幻觉——并不是因为模型胡编乱造,而是因为在它观察世界与开口表达的间隙,底层数据已经发生了变化。

这就是 RAG 的“写后读竞争”(read-after-write race),而大多数生产级流水线对此毫无防备。

智能体动作空间的可达性分析:为你从未测试过的分支提供评测覆盖

· 阅读需 13 分钟
Tian Pan
Software Engineer

你的团队第一次意识到 Agent 可以调用 revoke_api_key 是在某个早晨,一位好心的用户输入了:“这个 Token 感觉太旧了,能帮我轮换一下吗?” 这个工具是在六个月前作为认证团队 MCP 服务批量导入的一部分注册的。它通过了 Schema 验证,出现在目录枚举中,然后就一直闲置在那里。没有任何评测(Eval)调用过它,也没有任何生产环境追踪(Trace)触及过它。直到某条提示词(Prompt)、某个规划器(Planner)决策,事件频道(Incident Channel)才发现该工具竟然存在。

这就是隐藏在每一个拥有复杂工具目录的 Agent 中的失效模式。四十个注册函数和一个可以组合它们的规划器,产生了一个你从未观察到的计划可达图的长尾。假设“我们测试了常用路径”掩盖了一个事实:危险的分支几乎从定义上来说就是你从未见过的那一个。

路由即产品:为什么你的低成本分类器比旗舰模型决定了更多行为

· 阅读需 12 分钟
Tian Pan
Software Engineer

我上个季度接触的一个团队上线了一个他们称之为“路由项目”的东西:在他们的旗舰模型前端放了一个微型 BERT 分类器,用来判断查询是否足够简单,以便分流给更便宜、更快速的备选方案。这个项目在三周内就回本了。成本仪表盘上绿光一片。旗舰模型的评估套件——包含三百个对抗性案例、每周的评分运行等等——依然在每个周五稳稳通过。

上线六周后,某个特定产品界面的留存率下降了四个百分点,没人能找到原因。旗舰模型表现正常。延迟也正常。结果发现,路由竟然将 71% 的查询发送到了廉价模型。这种情况从第二周就开始了。对于大多数用户来说,这个廉价模型才是真正的产品,而这个廉价模型根本没有任何评估套件。

这是我在 2026 年看到的采用 LLM 路由进行成本控制的团队中最常见的失败模式:评估规范被绑定在系统的昂贵长尾部分,而廉价的头部部分——即承载大部分请求量、定义了产品体验的部分——却处于盲跑状态。

你的影子评估集是一个合规性定时炸弹

· 阅读需 11 分钟
Tian Pan
Software Engineer

你的 AI 技术栈中最危险的数据存储是那个无人设计的存储。这一切始于一次冲刺期间的 Slack 消息:“真实用户是捕捉真实 Bug 的唯一途径 —— 让我们把一定比例的生产流量接入评估流水线,以便我们可以每晚进行回放。”六名工程师给这条消息点了赞。九个月后,该存储桶包含了 430 万条追踪(traces),当失败率上升时,评估任务会呼叫值班人员,而失败案例会被逐字发送到一个有 40 人阅读的 Slack 频道。这些追踪包含电子邮件地址、公司内部名称、部分信用卡卡号、员工电话号码,以及用户解释其愤怒原因的客户支持对话记录。

没有人梳理过数据流。没有 DPIA(数据保护影响评估)涵盖它。上季度的隐私审查查看了模型供应商的 API;但它没有查看你的评估任务。然后,一份数据主体删除请求送达,团队发现“删除该用户的所有数据”这句话已经无法对应到他们实际能做的任何事情。

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 则为此付出了代价。