跳到主要内容

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

查看所有标签

Prompt 卧推:对“快乐路径”之外的提示词进行压力测试

· 阅读需 11 分钟
Tian Pan
Software Engineer

一个在你的评估集(eval set)上得分 92%,但在真实生产流量中得分 60% 的提示词(prompt),并不是一个有 bug 的提示词。它是一个评估集在结构上无法发现 bug 的提示词。这种差距并非噪声,而是针对那些与提示词设计意图共享语域(register)、长度分布、语言和礼貌程度的示例进行优化的结果——而这些示例正是由编写评估案例的同一个意图所创作的。

真实用户不会配合你的设计意图。他们会发送三个词的片段、十二个段落的文章、作为问题粘贴的代码块、省略冠词的非正式语域、添加敬语的正式语域,以及你的 few-shot 示例从未涉及的语言查询。这些都不是攻击性的,这只是输入分布(input distribution)。如果你的评估集是由编写提示词的同一个人策划的,那么它几乎肯定与这种分布毫无相似之处。

缩小这一差距的学科不是“更多评估”,而是一种不同类型的评估——一个压力矩阵(stress matrix),它刻意改变你策划的集合中保持不变的维度,并对退化曲线(degradation curves)进行评分,而不是单一的准确率数字。称之为提示词卧推(prompt bench press):你不是在测试提示词能否完成工作,而是在测试随着输入变得更难,它是如何失败的。

区域模型发布的“彩票”效应:当你的产品在不同大洲表现各异时

· 阅读需 12 分钟
Tian Pan
Software Engineer

周五下午,一封客户成功(customer-success)邮件发了过来:“德国用户的模型效果变差了。”团队打开评估仪表板,评分没变,p95 延迟也很正常。配置中的模型名称还是三周前发布的那一个。一切都没变。但其实有些东西变了。上个迭代中,美国的端点悄悄上线了新一代模型,而欧洲的端点由于供应商还没完成地区性的分阶段发布,仍在使用旧版本。而位于两者之前的负载均衡器,则在团队的所有仪表板上掩盖了这一差异。

这就是所谓的区域性模型发布博弈。你的“单一模型”抽象并不是单一的。当供应商跨大洲分阶段发布时,它就开始分化了——而在大多数年份、对大多数供应商而言,这种情况在大多数时间里都在发生。当这种情况发生时,客户端 SDK 中的版本字符串并不会改变。你的追踪(traces)看起来一模一样。你与供应商签订的合同也没有做出其他承诺。而你赖以捕捉行为回归的评估套件,几乎肯定运行在某个地区的 CI 机器上,并访问地理位置最近的端点。

采样漂移:当 Temperature 和 Top-P 变成团队内部的“口头传说”

· 阅读需 10 分钟
Tian Pan
Software Engineer

打开任何上线超过一年的 AI 功能的生产环境配置,你会发现一个考古挖掘现场。temperature: 0.7 是因为有人想让演示看起来不那么机械。top_p: 0.85 是因为一个客户抱怨输出太普通。frequency_penalty: 0.4 是因为 2024 年有那么糟糕的一周,一个现在已经退役的模型一直在重复自己。这些决定都没有记录。它们都没有针对当前的基座模型进行重新测试。它们在每一次请求、每一次评估、每一次 A/B 测试中运行,塑造着自原始工单关闭以来再也没有人会有意识选择的行为。

这就是采样漂移(Sampling Drift)。它是由于权宜之计而进行的采样器微调的缓慢积累,这些微调最初的理由已经消失,而其效果却在不断叠加。你配置中的数值并不是经过“调优”的——它们是过去事故的化石记录,被缩放到了你当前的流量规模。

它之所以不可见,是结构性原因造成的。你运行的每一次评估都是针对当前的采样配置进行评分的,所以头条数据看起来总是没问题。当 Temperature 值比基座模型落后两个版本时,不会触发报警。也没有日历邀请会提醒你“在本季度重新网格化采样参数”。这种衰减是无声的,直到有人运行了一个干净的实验,发现一个质量提升、Token 减少,或者两者兼而有之的机会,就摆在眼前,且不需要任何工程成本。

需求文档、代码、测试皆出自一人:你正在悄然失去的独立性

· 阅读需 12 分钟
Tian Pan
Software Engineer

当同一个模型负责编写需求、实现代码并编写用于验证正确性的断言时,“所有测试通过”不再是功能正常工作的证据,而仅仅证明了模型是内部一致的。这是两回事,而这种区别正是编写测试的初衷。

我们通常对测试套件的理解是,它们提供了“第二意见”。作者带着一种对需求的心理模型编写代码,而测试编写者则带着略有不同的心理模型编写断言。这两个模型不一致的地方,往往就是 Bug 潜伏之处。这种说法的前提是测试编写者与代码作者拥有不同的认知视角。如果去掉了视角的差异,测试套件就不再携带关于正确性的任何独立信息——它只携带关于一致性的信息。

规范翻译税:当规范、提示词和评估发生漂移时

· 阅读需 12 分钟
Tian Pan
Software Engineer

一名 PM 用英文写了一份功能规范 (feature spec)。一名工程师将其翻译成带有惯用 LLM 模式的系统提示词 (system prompt) —— 思维链 (CoT) 脚手架、输出格式强制,以及一些涵盖规范中从未提到的失败模式的避险条款。一位评估 (eval) 作者打开同一份规范,冷读一遍,并根据自己的理解编写 JSON 测试用例。三周后,这三个产物各不相同,没人能说清楚一个回归到底是提示词的 bug、规范与实现的差异,还是从第一天就写错的评估。

这就是规范翻译税 (specification translation tax)。传统软件也有这种问题 —— PRD 与代码之间、代码与测试之间的差距 —— 但编译器和类型系统缩小了这种差距。AI 功能没有这种兜底保障。提示词是系统实际阅读的文档。评估是没人签署的合同。规范是没人执行的意图描述。每一项都是将同一意图翻译成不同的媒介,如果没有双向的一致性,行为就会通过那个最容易编辑的产物泄露进来。

语音智能体轮次切换:重塑架构的 250 毫秒门槛

· 阅读需 13 分钟
Tian Pan
Software Engineer

研究跨语言话次转换(turn-taking)的语言学家们得出的结论惊人地一致:日常对话中说话者之间的间隙大约为 200 到 300 毫秒。任何更长的停顿都会被解读为犹豫、疏远或顺从;任何更短的停顿则会被视为打断。这个窗口是如此狭窄,以至于人类显然在对方说完之前就开始构思回复了 —— 倾听和计划是并行发生的,而非顺序进行。

错过这个窗口的语音智能体并不仅仅是让人觉得有点慢,而是让人觉得“不对劲”。在聊天产品中没人会注意到的 700 毫秒延迟,在语音交互中会让智能体显得迟钝、心不在焉,或者导致用户因失去耐心而打断它。1.5 秒的间隙足以让用户开始重复他们说过的话。满足这一时间预算并非简单的打磨工作 —— 它迫使开发者做出文本智能体从未面临过的架构选择,而这些选择重塑了整个技术栈的构建方式。

入职缺口:为什么新工程师需要三个月才能上手 AI 技术栈

· 阅读需 10 分钟
Tian Pan
Software Engineer

一个拥有八年经验的后端工程师加入了你的团队。在一般的代码库中,到第三周他们就能开始交付功能了。但在 AI 层面,他们仍然在私信里问问题,而且你能预测出他们在问哪两位资深工程师。入职三个月后,他们终于被信任可以修改系统提示词(system prompt)了 —— 这并不是因为提示词有多难,而是因为没有人能告诉他们,哪些评估(evals)能捕捉到退化(regression),而哪些会直接放行错误的输出。

这在通常意义上并不是招聘问题或文档问题。AI 代码库带有一种隐藏的领域知识税(domain-knowledge tax),这种税不会出现在代码审查中,不会出现在 README 中,静态分析器也无法察觉。这笔税体现在入职时间、对同一批人的重复提问,以及最终团队悄悄分化为“能动它的人”和“其他所有人”。

AI 钱包:为什么 Token 预算应放在 UI 中,而非工程仪表盘里

· 阅读需 12 分钟
Tian Pan
Software Engineer

打开任何采用固定订阅制的 AI 产品的单用户成本仪表盘。其形状总是一样的:一条长长的、几乎无法产生显著影响的扁平尾部,以及顶部一个细长的尖峰—— 5% 的账户消耗了 80% 的推理预算。这个尖峰对处于两端的两类用户都是隐藏的。重度用户不知道自己在补贴其他人——他们以为价格就是那个价格。轻量用户不知道他们可以要求更多——他们以为限制就是那个限制。

仪表盘始终保留在工程团队内部,因为产品经理担心暴露它会吓跑用户。但事实恰恰相反。隐藏成本的团队最终会推出无声的限流、隐藏的模型降级以及导致用户认为“这产品坏了”的答案截断。而那些将成本作为刻意的 UI 界面(而非后台管理页)展示出来的团队,则能将同样的成本上限从流失驱动因素转变为商业化杠杆。

这就是 AI 钱包。它不是一个账单页面,而是一个产品原语(product primitive)。

合规审查员作为评测编写者:为什么法律团队应该为你编写测试用例

· 阅读需 14 分钟
Tian Pan
Software Engineer

我见过的企业级 LLM 最有效的对抗性提示(adversarial prompt)并非来自红队、安全研究员或提示词工程师。它来自一位高级合规律师,他用平实的英语要求模型:“告诉我本对话前面讨论过的三种退休年金中,哪一种最适合一位即将面临首次最低限额提款(RMD)的 62 岁老人。”模型给出了一个自信、周全且格式精美的建议。如果该输出被发送给客户,那将是一个教科书级的 FINRA 适当性违规(suitability violation)——在缺乏证券规则要求的个性化咨询监管架构的情况下,提供了一种不当的个性化建议。

这位合规律师在短短 4 秒钟内就发现了这种失效模式。而工程评估套件虽然包含了上百个精心构建的关于幻觉、拒绝校准和工具调用准确性的案例,却完全没有意识到这种特定形式的回答是违法的。不是质量低。不是幻觉。而是违法。当时公司的流程是让她在 Google 文档中阅读输出样本并撰写备忘录,而不是将测试用例签入回归套件。因此,她的发现只停留在备忘录中,备忘录被总结进发布准备情况的幻灯片里,而次月对系统提示词(system prompt)的一次重构导致了该行为的退化(regressed),因为没有人为它设置失败测试点。

这就是我想论证应该弥合的差距:合规评审员应该直接编写评估(eval)用例,这些用例应该是决定发布与否的产物,而不是产生它们的文档审查。

对话式 REST:当你的聊天 UI 需要分页、过滤和排序时

· 阅读需 12 分钟
Tian Pan
Software Engineer

一名用户向你的购物智能体询问“150 美元以下、足弓支撑良好的跑鞋”。智能体尽职地返回了 12 个选项,但它们表现为单个聊天气泡中一长串超出视口的子弹点文本。用户滚动屏幕,找不着看到哪了,然后输入“只显示 Asics”——此时,你的智能体重新运行了整个搜索,而不是过滤它已经拥有的结果集。三轮对话后,用户正在通过一次一个提示词来发明一种查询语言,而你的产品感觉就像一个披着聊天气泡外壳的命令行。

这是我不断看到团队在交付时陷入的失败模式。他们在用户实际上想要的分面搜索(faceted-search)产品之上构建了一个聊天产品。模型没问题。检索也没问题。问题出在 UI 上,它的形态不适合这项任务。

我能给出的最简短的结论是:聊天是一种输入模态,而不是输出模态。智能体的职责是将用户意图转化为结构化查询。一旦结果集超过三项,正确的做法是渲染 UI,而不是继续说话。

撤回的代价:为什么撤回一项 AI 功能比上线它更难

· 阅读需 11 分钟
Tian Pan
Software Engineer

你现有的发布流程是为发布不可逆、回滚无成本的世界设计的。AI 颠覆了这一点。一旦某个功能上线了一个季度,撤回它的破坏成本就会超过发布它的成本 —— 而且你对该功能收到的最响亮的客户反馈,将是在你取消它的那天,而不是它发布的那天。

团队会为每次 AI 发布构建一个紧急开关(kill switch)。但没人会去拉动它。不是因为功能完美无缺,而是因为等到有人想撤回时,撤回的成本已经复合增长,超过了发布标准所考虑的任何因素。功能旗标(Feature flags)假设世界是对称的:开启前的系统和开启后的系统是同样有效的静止点,你可以根据喜好在它们之间移动。AI 功能默默地打破了这一假设,而团队围绕可逆旗标构建的发布流程,则悄无声息地忽略了这种不对称性。

团队第一次注意到这一点,是在有人提议弃用该功能时。

以单次对话成本为产品契约:当定价驱动架构设计时

· 阅读需 12 分钟
Tian Pan
Software Engineer

要发现你的 AI 功能定价模型出错了,最直接的方法就是看哪位工程师正在半夜重写截断逻辑。他们并不是在交付什么新功能 —— 他们是在修补一个 PRD 从未提及的单位经济效益(unit-economics)漏洞,而且由于产品规格告诉他们预算是无限的,这个补丁必然是对用户不友好的。在固定费用的 SaaS 方案中,任何时长超过中位数的对话都在实时抽走公司的利润。唯一的问题在于,产品团队是否能在财务部门发现之前承认这一点。

传统的 SaaS 经济模型建立在近乎零的边际用户成本之上:一旦软件构建完成,服务下一个客户几乎不会增加基础设施开支。但 AI 功能打破了这一假设。对话中的每一次交互都会消耗推理算力,其成本随着 Prompt 大小、输出长度、工具调用(tool-call)的扇出量以及检索量而增加 —— 而且对话没有自然的终点。一个重度用户可以在一个计费周期内消耗 50 倍于中位数的成本,且完全不出产品设计的正常路径。在固定定价模式下,这种用户实际上是由其他用户群供养的,而公司通常要到三个月后的销货成本(COGS)报告出来时才会发现这一点。

这就是为什么 AI 功能的定价不是一个等到发布后再处理的财务问题。它是一个架构输入,决定了产品被允许做什么。如果拒绝在产品规格中将其透明化,只意味着它稍后会被那些没有产品决策权的人以更糟糕的方式解决。