跳到主要内容

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

查看所有标签

单用户 AI 配额:成本看板无法察觉的 UX 层

· 阅读需 11 分钟
Tian Pan
Software Engineer

一个用户在周二下午 3 点打开了你的 AI 功能。他们已经轻度使用了三周。这次请求卡住了 8 秒钟,然后返回了一个红色的横幅:“出错了。请稍后再试。”他们又试了一次。还是同样的横幅。他们关闭了标签页,回去做之前在做的事情 —— 并在第二天早上的站会上告诉队友,“那个 AI 功能坏了。”

实际发生的情况是:他们触碰到了一个隐形的单用户配额,这是你的成本团队在六个月前为了防止单个重度用户刷爆 GPU 预算而设置的。配额起作用了。支出保持平稳。仪表盘显示绿色。按照你的工程组织追踪的每一个指标来看,这项功能都是健康的。但它也已经名存实亡了,因为看到那个横幅的用户再也不会回来了,而且他们在站会上告知的那三个队友也永远不会去尝试它。

这就是你的成本仪表盘看不见的鸿沟。单用户 AI 配额是一个产品界面(product surface)。那些将其隐藏在 HTTP 429 错误代码中的团队,正任由其成本控制系统默默地塑造用户对产品的认知,而且直到流失率在季度回顾中显现出来且没有明显原因时,他们才会发现这一点。

AI 功能的 PRD:为什么你的旧模板会让你在悬崖边失足

· 阅读需 11 分钟
Tian Pan
Software Engineer

确定性软件的 PRD 模板已经演变成了一种肌肉记忆。问题陈述、用户故事、验收标准、边缘情况、成功指标、范围削减。工程师知道如何阅读它,产品经理(PM)知道如何填写它,设计师知道该从哪些章节提取原型图。这是一个被磨损得恰到好处的产物,它交付了一代又一代的 CRUD 应用、仪表盘和 SaaS 工作流。

它也没有“模型在 5% 的情况下会出错”的字段,没有“我们接受的评估(Eval)合格分”的字段,没有“当模型拒绝回答时用户会看到什么”的字段,也没有“该 PRD 锁定了哪个提示词(Prompt)版本,以及发布后允许谁进行更改”的字段。每一个按照这种模板交付的 AI 功能,都带有一份谁也没写下来的隐性契约。复盘总是让人们在遭遇挫折后才痛苦地意识到这一点。

扼杀 AI 流水线吞吐量的预处理瓶颈

· 阅读需 12 分钟
Tian Pan
Software Engineer

某团队构建了一个 RAG 功能,测量端到端延迟后发现慢得无法接受,随即开始优化模型调用。他们尝试了更小的模型、批量请求,并调整了 temperature 和 token 上限。经过两个迭代周期,延迟下降了 15%,但功能依然太慢。他们从未测量过的是:在 LLM 收到任何提示词之前,文本分块和嵌入生成就已经耗费了 600ms。

这种模式在分布式系统中普遍到有了专有名词:优化了错误的组件。在 AI 流水线中,LLM 调用显而易见且易于测量,而其之前的所有环节都是隐形的——除非你主动做埋点,否则根本发现不了——而吞吐量恰恰死在那里。

没上线新功能的 AI 工程师该如何写晋升材料

· 阅读需 13 分钟
Tian Pan
Software Engineer

你团队中晋升理由最充分的 AI 工程师,其晋升材料(Promotion Packet)看起来却可能是空洞的。两个季度的努力,影响力图表却是一条平线。曾经在每次模型切换时都会飙升至 12% 的评估回退率(Eval-regression rate),现在稳定在 4%。财务部门差点就要介入调查的每月 4 万美元成本飙升从未发生,因为有人在网关中加入了预算守卫(Budget Guard)。本会导致公司状态页(Status Page)挂彩的 P0 级事故从未发生,因为紧急开关(Kill-switch)被触发,将流量导向了之前的 Prompt 版本。

这种材料在“已发布功能 X”一栏无话可说。定级委员会面对两个并排坐着的工程师:一个是这半年发布了两个显性功能的工程师,另一个是默默承担了让这些功能成为可能的负载的工程师。委员会一如既往地给发布功能的工程师打了高分。那位基建型(Infra-shaped)工程师要么拿了一个不应得的“符合预期”评分并在一个季度内辞职,要么学会用委员会真正能听懂的语言来撰写材料。

“什么发生了变化”查询是你的索引无法回答的 RAG 问题

· 阅读需 12 分钟
Tian Pan
Software Engineer

一个用户问你的助手,“这季度我们的退款政策有什么变化?”系统返回了一个当前退款政策的、格式良好的自信总结。用户点点头,关闭聊天,并根据一个与他们提出的问题完全无关的信息采取行动。你的评测套件(eval suite)没有捕捉到这一点。你的忠实度指标(faithfulness metric)没有标记它。检索看起来很完美——它返回了高度相关的分块(chunks)。合成看起来也很完美——它引用了它使用的每个分块。唯一的问题是,问题是关于 变化 的,而你的索引没有变化的概念。

这是向量相似度检索无法通过调优修复的失败模式。同一文档的两个版本具有几乎相同的嵌入(embeddings)——这就是好的嵌入所 的,它们将语义等效的文本折叠到同一个邻域中。因此,当你问“什么改了”时,检索器返回其中一个版本,LLM 总结该版本,而答案在沉默中成为了“什么都没变”的幻觉。用户无法察觉。你的评测集可能也无法察觉,因为你的评测集是围绕“什么是 X”的问题构建的,而不是“现在 X 有什么不同”。

视频会议中的数字人:构建用于视频会议的实时对话头像 AI

· 阅读需 13 分钟
Tian Pan
Software Engineer

拥有面孔的语音智能体并非简单的“带脸的语音助手”。它是一个同步视频 AI 系统,当人类第一次看到口型落后于音频三帧,并下意识地(即使无法准确说出原因)判定屏幕上的东西是假的时候,这种差异就显现出来了。那些构建了 300 毫秒语音流水线,然后又在末尾强行塞入一个渲染模型的纯语音团队,刚刚继承了一个他们在路线图中未曾预料到的实时多模态问题。

这个门槛并不宽松。在音视频偏移低于约 45 毫秒时,观众会认为是完美同步。一旦音频领先超过 125 毫秒或音频滞后超过 45 毫秒,大脑就会将这种不匹配标记为错误,即使观众无法指出具体原因。在一个数字人必须同时倾听、思考、说话和渲染的对话循环中——且在你和用户之间还隔着网络——音频输出和渲染面孔之间没有任何余地来容纳拙劣的衔接。

并非“全员回复”:智能体出站扇出风险

· 阅读需 10 分钟
Tian Pan
Software Engineer

用户要求智能体(agent)“告知 Karen 我们完成了”。智能体调用了 send_email,收件人字段设置为 karen-team@,这是它的联系人查询工具返回的最合理的地址。这条包含三段内部专用项目状态的信息——其中包括一行关于客户续约风险的坦率描述——最终发送到了四十个收件箱。其中一个收件箱恰好属于该客户。事后分析(postmortem)持续了两周。

没有提示词注入。没有模型越狱。工具完全按照规范运行。团队为 send_email 编写的契约是“向收件人发送消息”。而现实世界强制执行的契约是“广播给一个发送者未审计其构成的群体”。这种差距——即工具的命名与其核心实际能力之间的鸿沟——正是大多数出站智能体事故的源头。

电子邮件是显而易见的例子,但同样的风险潜伏在智能体接触的每一个消息工具中。人类为这些渠道建立的三十年肌肉记忆,并未转移到那些正在通过联系人列表进行模式匹配的规划器(planner)中。

你的 AI 功能忘记计入的 SIEM 账单

· 阅读需 12 分钟
Tian Pan
Software Engineer

这里的数学逻辑很简单,但没人去算。在 AI 时代之前,单个用户操作(例如“总结这张工单”或“发送这封邮件”)只会产生一行应用程序日志。而在 AI 时代之后,同样的操作会产生一条请求日志、一个 LLM 调用追踪、代理调用的每个工具的工具调用 span、它读取的每个数据块的检索 span、一条响应日志,如果你采样进行离线评分,还会产生一条评估日志。一次用户点击的扇出(fan-out)现在会在你的可观测性流水线中产生 30 到 50 条记录,这还是在重试、子代理以及会让一切翻倍的规划器-执行器(planner-executor)拆分出现之前。

你在第一季度发布了一个 AI 功能。到了第二季度,你的安全总监拿着一份比上一个周期高出 4 倍的 Splunk 续订合同走进预算审查会议。AI 团队的人都不在现场。接下来的对话——关于谁来承担这笔费用、为什么威胁检测规则失效了,以及是否真的必须对每次对话进行法律保留(legal hold)——是你在设计阶段就应该进行但没有进行的对话,因为这笔成本没有出现在 LLM 的发票上。它出现在下游,出现在一个 AI 团队从未登录过的工具中。

当你的模型具有随机性时,快照测试在撒谎

· 阅读需 12 分钟
Tian Pan
Software Engineer

当你团队中的初级工程师第一次输入 --update-snapshots 并推送到 main 分支时,你的测试套件就不再是测试套件了,它变成了一份记录稿。虽然 Diff 依然显示为红绿颜色,CI 徽章依然会变为通过,但信号已经悄然反转:测试套件不再告诉你代码是否正确,而是告诉你是否有人费心看过输出。对于确定性的代码,这种风险尚在可接受范围内,因为大多数 Diff 确实是符合预期的。但当网络调用的另一端是一个随机模型时,同样的流程会让每一个 PR 变成一场硬币投掷,让每一位评审者变成一个橡皮图章。

快照测试曾是确定性世界里的一个美妙构想。你记录下上周二 render(<Button />) 的生成结果,断言本周二它会生成相同的字符串。从定义上讲,任何 Diff 都是值得人工核查的行为变更。这种模式在 Jest、Vitest、Pytest、整个 React 生态系统以及一代又一代的 UI 快照扩展中得以幸存,是因为底层契约依然成立:相同的输入加上相同的代码等于相同的输出。但这个契约对 LLM 调用并不奏效。相同的输入、相同的代码加上相同的提示词(Prompt),却会产生不同的字符串——而且这种差异并非 Bug,而是产品按设计正常运行的结果。

为什么 Token 预测在上线后会发生偏移 —— 以及如何在财务发现前捕捉到异常峰值

· 阅读需 12 分钟
Tian Pan
Software Engineer

发布前的成本模型通常是一张精美的电子表格。它假设通过代表性的提示词(Prompt)运行模拟流量,并在测试过的缓存命中率和干净的工具调用路径下运行。但发布后的现实是,一旦功能真正开始运作,这些假设都将不复存在。模拟流量未涵盖的意图恰恰是用户最常使用的。工程团队没收到会议通知的营销活动所带来的流量,最终落在了路由树中成本最高的分支上。在第三周,使用量超过中位数 40 倍的重度用户群体才会开始出现。

这类问题在全行业内已屡见不鲜:调查显示,约 80% 的企业对 AI 成本的预测偏差超过 25%,并报告在成功发布后的几个月内,成本通常会增加 5 到 10 倍。这些数字中关键的细节是“成功”二字。失败的 AI 功能才能维持在预算内。成本偏差是由功能的成功运行驱动的,而不是因为团队做错了什么。这使得它成为一个规划产物(planning artifact)问题,而不是工程问题 —— 而大多数团队依赖的规划产物,即每月账单,其实是最糟糕的检测器。

工具 Schema 设计即是你的爆炸半径:当函数定义成为安全边界

· 阅读需 12 分钟
Tian Pan
Software Engineer

你的 Agent 代码库中最危险的文件是你一直当作 API 文档来编写的那个。工具注册表(Tool Registry)——即告诉模型存在哪些函数以及它们接受哪些参数的 JSON 或 Pydantic schema —— 不再仅仅是一个 docstring。它是你的授权层(authorization layer)。如果你像大多数团队那样设计它,你就是把万能钥匙交给了大模型(LLM),并称之为优秀的工程设计。

考虑一个典型的工具初步尝试:query_database(sql: string)。初衷是合理的 —— 让模型根据用户的问题制定正确的 SQL。现实情况是,模型现在成了一个不受信任的客户端,拥有连接字符串所指向的任何数据库的无限 DDL 和 DML 权限。系统提示词说“仅在 orders 表上运行 SELECT” 只是一个建议,而不是控制手段。当一个受到提示注入(prompt-injected)的工具结果 —— 比如邮件正文、网页或 PDF —— 告诉模型运行 DROP TABLE users 时,你的授权模型就变成了对模型指令遵循能力的纪律要求。那不是授权。那是祈祷。

为什么每周会话记录审查优于你的 AI 仪表板

· 阅读需 14 分钟
Tian Pan
Software Engineer

在你的 AI 团队中,被低估最严重的资产是每周一小时,由三个人坐在房间里阅读你的产品实际对用户说了什么。不是综合评分。不是移动平均值。不是仪表盘。而是实际的对话记录。逐字逐句的输出。模型悄然形成的懒散措辞。你的分类体系中未涵盖的意图。用户尝试了三次,用三种不同的方式表达需求,而你的评估准则(eval rubric)却将这三次对话都评为“满意”。

将这一小时制度化的团队,能够建立起仪表盘永远无法呈现的 AI 功能心理模型。跳过这一步的团队,会根据看起来不错的指标发布六个月的产品,然后在下一次季度业务回顾(QBR)中发现,在无人察觉时,中位数体验已经漂移到了令人遗憾的境地。