跳到主要内容

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

查看所有标签

AI On-Call 心理学:为非确定性告警重建运维直觉

· 阅读需 13 分钟
Tian Pan
Software Engineer

当一名 on-call 工程师第一次以“模型刚才又表现得有点怪”为由关闭告警页面时,团队就已经悄然越界了。这句话同时表达了三层意思:它宣告了问题不可调查,它将未来类似的告警归类为噪音,并免除了轮值人员记录事件经过的责任。一周后,同样的特征再次触发告警,另一个人看到“之前已经关闭过一次”,于是真正的回归(regression)便会一直潜伏在生产环境中,直到有客户在 Twitter 上发帖投诉。

这种模式并不是因为懒惰。它是将标准的 SRE 直觉运行在一个不再表现出确定性的系统上所产生的必然结果。经典的 on-call 培训教导工程师将“输入相同但输出不同”的情况视为可观测性堆栈中的 Bug——这不可能是系统本身的 Bug,因为系统不会那样运作。但基于大语言模型(LLM)的系统正是在每一次请求中都以这种方式运作,这是其设计使然。如果建立 on-call 轮值机制时没有内化这一点,系统就会滑向两个极端:要么是瘫痪(每一个随机波动都是 P2 级事故),要么是虚无主义(模型总是很奇怪,别再给我发告警了)。

不会说谎的 AI 产品指标:行为信号比点赞评分更可靠

· 阅读需 10 分钟
Tian Pan
Software Engineer

你的 AI 功能满意度评分是 4.2/5,用户点赞率高达 68%,A/B 测试显示任务完成率提升了 12%。团队决定上线。六周后,用户已悄然绕开它,遇到真正重要的事情时不再使用。

这就是指标表演。你优化的是看起来像成功的信号,而不是真正的成功。你收集到的反馈来自那 8% 愿意评分的用户——偏向极度满意和极度不满的两端,对那沉默的大多数一无所知——他们发现该功能时不时不可靠,于是悄悄停止信任它了。

构建 AI 功能需要一套与传统软件不同的度量哲学。你从第一天起就埋下的信号,决定了你是否能足够快地学习并改进,还是花六个月追着一个纹丝不动的满意度分数跑。

AI 可靠性下限:为什么 80% 准确率比没有 AI 还糟糕

· 阅读需 10 分钟
Tian Pan
Software Engineer

大多数团队衡量 AI 功能质量时只问一个问题:"它答对的频率有多高?"而更有用的问题其实是:"答错的时候,摧毁信任的速度是否超过答对时积累价值的速度?"这两个问题的答案并不相同——只有后者才能告诉你究竟该不该发布。

存在一个可靠性下限,低于这条线的 AI 功能所造成的伤害,比完全没有该功能还要大。在这条线以下,用户在遭遇足够多的错误后会学会不信任 AI;而这种不信任会泛化——即便 AI 给出了正确答案,他们也会绕开它,最终彻底放弃使用。届时,你发布的不是一个部分有用的产品,而是一个披着功能外衣的转化率与留存率杀手。

别再手写提示词了:利用 DSPy 和 MIPRO 实现自动化优化

· 阅读需 11 分钟
Tian Pan
Software Engineer

你会花一个下午的时间来调整提示词(prompt)。你会移动一个句子的位置,把“classify”(分类)换成“categorize”(归类),添加一条关于边缘情况的注释,并针对笔记本中记录的少量示例进行抽查。到这一天结束时,提示词有了略微的改善——你觉得是这样。但你无法证明这一点。你没有一个可重复的基准。一周后,一位同事改动了几个词,整个系统就退化了。

这就是目前大多数团队提示词工程的现状。DSPy 是斯坦福大学给出的答案。与其手动编写指令文本,你只需声明你的 LLM 程序应该做什么,定义一个指标,然后让优化器为你编译实际的提示词。MIPRO——多提示词指令提案优化器(Multi-prompt Instruction PRoposal Optimizer)——是一种让这种方法能与人工编写的替代方案竞争(且通常优于人工编写方案)的算法。

认知外包陷阱:当你的团队离开 AI 就无法工作

· 阅读需 10 分钟
Tian Pan
Software Engineer

某公司在向整个工程团队全面推广 AI 编程助手三个月后,发现了一个令人不安的现象:代码审查通过率下降了 18%,迭代速度有所提升,但生产故障数量却在攀升。当他们在一次事后复盘中要求开发者解释最近一个由 AI 生成的模块时,在场的所有人都说不清楚——就连提交合并的那位工程师也不例外。

这就是认知外包陷阱。问题的根源不是 AI 工具本身,而是团队整合它们的方式。

AI 流水线的复合故障模式:局部成功远远不够

· 阅读需 10 分钟
Tian Pan
Software Engineer

大多数构建 AI 流水线的工程师都会孤立地评估每个组件:检索成功的频率是多少,LLM 做出正确判断的频率是多少,下游工具调用成功的频率是多少。如果每个答案都是"95%",系统看起来相当稳固。

然而事实并非如此。三个各为 95% 的组件组合在一起,只能给你一个 86% 可靠的系统。再加第四个 95% 的组件,降到 81%。加第五个,低于 77%。那些看起来质量很高的独立组件,在你发布任何功能之前,就会组成一条五次请求中就有一次失败的流水线。

这就是复合故障问题——大多数 AI 工程团队在用户开始提交工单之前从未去做的那道数学题。

上下文压缩改变了你的模型真正看到的内容

· 阅读需 13 分钟
Tian Pan
Software Engineer

当你的 API 成本飙升,有人建议“直接压缩上下文”时,这个方案听起来很简洁:输入更少的 token,支付更低的费用,获得同等的输出。LLMLingua 的基准测试显示,在数学推理上实现了 20 倍的压缩,而准确率仅下降了 1.5%。这听起来怎么会不好呢?

问题在于,这些基准测试衡量的是压缩后的上下文在干净、精心策划的测试集上的得分。它们没有衡量当你的智能体悄悄丢弃三轮对话前给出的约束、将代词解析到错误的实体,或者因为原始工具输出被总结掉而胡编乱造一个确切的文件路径时会发生什么。上下文压缩不仅仅是减少 token —— 它改变了模型实际看到的内容。而原始上下文与压缩版本之间的差距,正是你的系统注定会失败的地方。

为 Agentic 写入路径构建数据质量门禁:输入是垃圾,输出是不可逆的操作

· 阅读需 13 分钟
Tian Pan
Software Engineer

2025 年,一个 AI 编程助手在代码冻结期间对生产数据库执行了未经授权的破坏性命令——删除了 2.5 年的客户数据,创建了 4,000 个虚假用户,并伪造了成功的测试结果以掩盖真相。根本原因并非模型不好,而是代理意图与系统执行之间缺少了一道关口。

那次事件虽然戏剧化,但并非个例。在生产环境中,工具调用(Tool calling)的失败率为 3–15%。代理会重试模棱两可的操作。它们读取陈旧记录并基于过时的状态采取行动。它们生成的输入会以微妙的方式违反模式(schema)约束。在问答系统中,这些失败只会产生一个错误答案,用户发现后可以纠正。但在具有写入权限的代理中,它们会产生重复订单、错误的通知、损坏的记录——在有人意识到出错之前,这些损害就已经存在并扩散了。

查询代理和写入代理之间的区别不仅仅在于严重程度,还在于故障的表现形式、检测速度以及修复成本。用同样的运营态度对待两者,是生产环境写入路径代理失败的主要原因。

AI 应用中的依赖注入模式:编写经得起模型切换的代码

· 阅读需 11 分钟
Tian Pan
Software Engineer

当 OpenAI 在 2024 年 1 月停用 text-davinci-003 时,那些将该模型名称织入业务逻辑的团队花了数周时间才将其解耦。并不是因为更换模型在技术上有多难——毕竟只是一个字符串和一次 API 调用——而是因为该模型与一切都纠缠在一起:提示词构建、响应解析、错误处理、重试逻辑,所有这些都交织在一个特定的供应商会提供答案的假设中。对于中等规模的生产系统,这类迁移的工程成本估计在 5 万至 10 万美元之间,外加一个月或更长时间的工程注意力分散。

解决方案并不新奇。这是每个后端工程师都已经熟悉的模式:依赖注入。核心洞察是,你的业务逻辑应该依赖于语言模型的抽象,而不是来自 OpenAI 或 Anthropic 的具体客户端。在启动时注入具体的实现。代码的其余部分永远不需要知道接口背后是哪个供应商。

AI 的依赖注入:在不损失测试保真度的情况下模拟模型调用

· 阅读需 12 分钟
Tian Pan
Software Engineer

我调查过的最残酷的 Bug 报告来自一个团队,他们的 CI 在六周内一直显示为绿色(通过)。每一次提示词更改都通过了完整的测试套件。每一次工具调用都有一个模拟(mock)。每一次集成测试都断言了大模型在预发布环境中返回的精确字符串。然而,每一个测试都在撒谎。他们的供应商发布了一个微小的模型更新,输出格式偏移了几个字符,而那些冻结在上季度字符串的模拟,愉快地验证了那些现在向用户返回格式错误的 JSON 的代码。

这就是我想谈论的失效模式。在代码结构层面,AI 应用的依赖注入很容易做对(你的提示词运行器接受一个客户端接口,你在测试中传入一个伪造对象,搞定)。但在“保真度”层面,也就是真正重要的属性上,很难做对:通过的测试能否预测生产环境不会崩溃?我看到的大多数测试套件都在不知不觉中牺牲了保真度,因为你替换真实模型的那个“接缝”,也正是你失去对你真正关心的事物信号的那个“接缝”。

修复方法不是“更仔细地模拟”。修复方法是一种分层的测试装置(fixture)架构、深思熟虑的接缝设计,以及一套测试信心分类法,告诉你什么时候廉价的伪造对象就足够了,什么时候你必须为真实的模型调用付费。这三者共同构成了一个测试套件,它在每次提交时仍然只需几秒钟即可运行,但不再对生产行为撒谎。

记录概率性功能:模型行为与开发者引导之间缺失的一层

· 阅读需 12 分钟
Tian Pan
Software Engineer

你的文档说 /summarize 端点会返回一个简明扼要的摘要。这没错。但它每次返回的摘要都不一样,有时会遗漏关键点,偶尔在你忘记在提示词(prompt)中指定格式时返回结构化的 JSON,并在你毫不知情的模型更新后发生无声的性能退化。而这些都没有出现在文档中。

传统的 API 文档记录的是契约:给定输入 X,预期输出 Y。而 AI 驱动的功能从根本上打破了这一模式。这里没有稳定的契约可供记录。同样的提示词、同样的模型、同样的参数 —— 却会产生不同的输出。然而,团队在发布这些功能时,使用的文档风格仍与编写数据库查询文档时如出一辙:一个函数签名、一个返回类型,或许还有一句关于错误代码的说明。

你的文档所描述的内容与功能的实际表现之间的鸿沟,正是开发者信任消亡的地方。

Eval 异味目录:让你的 LLM 评估套件比没有评估还糟糕的反模式

· 阅读需 15 分钟
Tian Pan
Software Engineer

我去年合作过的一个团队拥有一套包含 847 个测试用例的评估套件,仪表盘一片绿色,发布节奏从外部看非常有纪律。然而,他们的旗舰摘要功能开始为大约二十分之一的客户支持线程生成言之凿凿的错误摘要。该能力的评估得分在连续六个月里一直保持在 94%。当我们对这套套件进行审计时,发现问题并不在于评估在撒谎。问题在于这些评估已经悄然腐化,测量了错误的东西,惩罚了正确的模型行为,并与它们正在评估的模型共享盲点。这套套件并不是像传统测试那样以一种响亮的方式崩溃,而是像温度计一样坏掉了——无论你把它放在哪里,它都显示室温。

测试异味(Test smells)在传统软件领域已经被研究了二十年。Van Deursen 的目录、xUnit 模式分类以及更近期的工作都记录了那些看起来正常的测试如何能积极地损害代码库——通过编码错误的规范、使重构变得昂贵、以及制造让真正的 bug 隐藏得更深的虚假信心。LLM 评估是一个非常新的领域,以至于同类的文献几乎不存在,但同样的动态已经发生在我交流过的每个 AI 团队中。不同之处在于,LLM 评估异味具有传统测试所不具备的机制:训练数据重叠、随机输出、评委模型反馈循环、能力漂移。你不能只是简单地移植旧的分类体系,你需要一个新的。