跳到主要内容

720 篇博文 含有标签「llm」

查看所有标签

工具 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 时,你的授权模型就变成了对模型指令遵循能力的纪律要求。那不是授权。那是祈祷。

Abandon 原语:为什么你的智能体循环需要一个一等公民的方式来终止计划

· 阅读需 12 分钟
Tian Pan
Software Engineer

看看大多数智能体框架提供的循环原语:continuereturnretry 以及一个硬性终止运行的步数预算。注意缺失了什么。这里有一条表示“工作成功”的路径,一条表示“模型想继续”的路径,还有一条表示“我们耗尽了资金或耐心,于是强行终止循环”的路径。唯独没有一条头等路径来表达“我正在执行的计划是错误的,我想将其丢弃并开始一个全新的计划”。放弃原语(abandon primitive)——即一种让规划器显式、结构化地宣布当前轨迹无望的方式——是智能体循环语法中缺失的动词。它的缺失导致了一类通常被误诊为“模型需要更多推理”的失败。

一个在注定失败的分支上执行了三步的规划器,会不断优化同一个错误的计划,因为循环唯一的出口是成功、重试上一步或耗尽预算。这些路径都不包含“放弃该策略并尝试另一个”。因此,智能体执行了循环所允许的操作:它就地修改计划、再调用一个工具、再请求一次澄清,并在步数预算耗尽前不断收敛到一个非解决方案。当最终撞墙时,用户看到的是一条礼貌的失败消息,而不是问题的答案。这些浪费的步骤所带来的成本是真实的——生产数据表明,智能体系统 5-10% 的 Token 支出都花在了无法产生任何可用结果的重试上,而这一数字主要由长期的“注定失败分支”占据,而非孤立的工具错误。

为什么你的 AI 路线图不应该有 12 个月的计划

· 阅读需 10 分钟
Tian Pan
Software Engineer

我上个季度合作的一个团队花了六周时间构建了一个“智能文档分类器”——微调模型、评估框架、自定义 UI,以及整个生产流水线。它在周二上线。接下来的周一,一个全新的通用模型发布了,在同样的评估中,它以零样本 (zero-shot) 的方式击败了他们的微调模型,且无需任何基础设施投入。他们整个第二季度的 OKR 变成了一个仅包含一行 API 调用的包装器。路线图在 12 个月前承诺要“掌控分类技术栈”。而这项承诺在墨迹未干之前就已经错了。

这并非孤例。行业追踪器记录显示,仅在 2026 年第一季度,各大实验室就发布了 255 个模型,到 3 月份为止,平均每周约有三次意义重大的前沿模型发布。成本已经崩溃:API 定价自 GPT-3 以来下降了 97%,顶级供应商之间的差距在大多数基准测试中已缩小到统计噪声范围内。当底层技术变化如此之快时,一份为期 12 个月的特性路线图就不再是计划——而是一份你无法重新审视的赌注清单,这些赌注是根据在你交付第二个项目之前就会过时的信息做出的。

物理隔离 LLM 蓝图:无出站流量部署的真正需求

· 阅读需 12 分钟
Tian Pan
Software Engineer

云端 AI 的策略通常建立在一个没有人明确写下来的前提之上:出站 HTTPS (outbound HTTPS)。厂商 API、托管评测器、遥测流水线、模型注册表、向量存储、仪表板 SaaS、密钥管理器——其中的每一个都静默地解析到公网上的一个域名。一旦拔掉这根电缆,整个技术栈并不会优雅降级,而是会直接崩溃。

大多数团队直到那一刻才会发现,他们的架构中存在从未考虑过的出站依赖。一个“微小”的提示词更新可能需要调用托管分类器;评估套件需要通过网络访问 LLM 评测器;可观测性代理会向后端发送数据;模型注册表从 CDN 拉取权重。这些都不是恶意的,也并不罕见。当你忽视了那根电缆时,云原生技术栈本就是这个样子的。

澄清预算:你的智能体何时应该询问而非猜测

· 阅读需 12 分钟
Tian Pan
Software Engineer

智能体最糟糕的两种失败模式看起来截然相反,但它们其实源于同一种失效的策略(Policy)。第一种智能体在执行任何操作前都会先问四个后续问题,这让它的用户因为繁琐而最终放弃使用。第二种智能体从不提问,它自信地生成用户不得不推倒重做的输出,这让它的用户对其产生不信任感。同样的策略,只是一个缺失参数的不同设置:即提问的成本相对于错误答案成本的比例。

大多数智能体根本没有任何策略。模型只是被要求“提供帮助”,然后被留下来独自应对模糊性。因为下一个 Token 预测(next-token prediction)机制奖励对答案的确定性,所以智能体倾向于猜测。又因为 RLHF 奖励礼貌,智能体偶尔会为了安全而过度纠偏并提出问题。其结果就是一种毫无原则的行为,这种行为在不同会话之间波动不定,团队层面也无法直观地判断智能体何时会暂停、何时会盲目推进。

澄清预算(Clarification budget)正是那个缺失的参数。它是针对每个任务制定的、允许智能体施加摩擦力的配额,并配有一套判断何时值得花费预算去提问的决策规则。你可以把它看作是对话领域的“延迟预算(latency budget)”——每个产品都有一个,即使没人把它写下来;而那些把它写下来的团队,就能停止交付那种让人困惑的智能体。

将 Eval 作为 Pull Request 评论而非任务:在代码审查中嵌入 LLM 质量门禁

· 阅读需 12 分钟
Tian Pan
Software Engineer

许多自称“有评估(evals)”的团队,其实际情况是:有一个仪表板,某人每周运行一次测试套件,然后将数据粘贴到没人看的 Slack 频道。评审人员批准提示词(prompt)更改时,甚至根本没看过它是否影响了测试套件,而回归问题(regression)两周后才在客户反馈单中显现。评估确实存在,但评估并未进入开发循环。

解决办法在于结构,而非意愿。只有当评估存在于变更发生的地方——即 Pull Request(PR)评论中,紧挨着代码差异(diff),并带有单个 PR 的增量变化和评审员无法忽视的回归提醒时,评估才能真正起到质量把关的作用。在其他任何地方,它们都只是表演性的产物:投入了大量精力构建,却什么也拦截不到。

分层内存压缩:你的智能体内存缺失的四个层级

· 阅读需 12 分钟
Tian Pan
Software Engineer

大多数智能体内存系统将一个四层的问题压缩成两层,然后在出现破绽时表现得大吃一惊。一个是当溢出上下文窗口时会被截断的会话缓冲区(conversation buffer),另一个是旧内容堆放其中的“长期记忆”向量数据库。那不是内存架构。那只是一个队列和一个杂物抽屉。

如果一个智能体连续三个周一向老用户询问同一个新手引导问题,这并不是因为模型不好,而是因为系统中没有一个地方能保存“该用户跨会话告知我的事情”,并且其生命周期不同于“所有用户告知我的关于产品如何运作的事情”。这是不同的记忆。它们有不同的访问模式、不同的隐私契约以及不同的遗忘规则。将它们混为一谈是架构上的错误——而且这是可以修复的。

工具调用顺序是偏序,而非集合

· 阅读需 12 分钟
Tian Pan
Software Engineer

“先创建后通知”的序列在开发阶段运行良好。而“先通知后创建”的序列则会为一个尚不存在的实体触发 webhook,导致消费者返回 404,接着你的团队会花上一周时间来调试这个看起来像是不稳定的集成测试。这种不稳定并非随机。它是确定性的,源于你的工具集拥有而你的规划器(planner)却不知晓的隐藏排序不变性。

这就是生产环境中 Agent 工具调用排序 bug 的常见形态:工具集在底层以偏序(partial order)方式组合——某些操作必须先于其他操作执行,而另一些则可以按任意顺序运行——但在规划器看来,它们只是一个无序的能力集合。模型选择了一个昨天行之有效的顺序。而明天,一次提示词修改、模型升级,甚至只是不同的 temperature 采样,都会选出另一个顺序。对于阅读追踪记录(trace)的人来说,这两种顺序看起来都很合理。但其中只有一个是正确的。

如果不声明顺序,团队交付的就是一个最终会被模型的提示词敏感性(prompt sensitivity)触发的 bug 隐患。

弃权作为一种路由决策:为什么“我不知道”应该属于路由层,而不是提示词

· 阅读需 12 分钟
Tian Pan
Software Engineer

大多数团队通过在系统提示词中加入一句话来处理弃权(abstention)问题:“如果你不确定,就说你不知道。”模型偶尔会遵守,但经常不遵守,而且这种失败模式是不对称的。一个自信的错误答案会以全速发布——它直接落入用户手中,在 Slack 讨论串中被引用,在下游摘要中被采纳。而一个诚实的弃权则会触发客户成功(CS)升级,因为用户期望智能体处理请求,而现在必须有人解释为什么它没有处理。六个月后,团队已经了解到哪种失败的发布成本更低,而那个名义上控制弃权的系统提示词修改,已经被悄悄地调整为倾向于顺从,而非诚实。

解决这个问题的准则不是寻找更好的措辞。而是要认识到,弃权是一个路由决策,而不是一种提示词模式。它理应拥有一个一等公民级别的输出通道、自己的 SLO、自己的评估套件,以及在系统拓扑中的独立位置——位于提示词之外,可以被测试、维护和扩展。

Agent 追踪采样:当 “记录所有内容” 耗费 8 万美元却依然漏掉性能退化时

· 阅读需 11 分钟
Tian Pan
Software Engineer

账单在 3 月份寄达。仅追踪(traces)一项就花费了 8.1 万美元,而 11 月时这一数字仅为 1.2 万美元。团队在 10 月份启用了全量 Agent 追踪,理由是可见性越高越好。到了第一季度,可观测性成本的增速已经超过了推理成本——而当生产环境真正出现性能回归(regression)时,包含故障的追踪记录却被淹没在两千万个无人问津的成功 span 中。

错误并不在于决定进行埋点。错误在于将请求追踪(request-tracing)的心智模型引入了一个行为完全不像传统请求的工作负载中。

一个典型的 Web 请求会生成一个包含少量子节点的 span 树:处理器、数据库调用、缓存查找、下游服务。而一个 Agent 请求生成的树包含 5 个 LLM 调用、3 个工具调用、2 个向量查找、中间草稿(scratchpads),以及一个重新审视其中 3 个步骤的规划器。同样适用于 API 网关的采样策略——头部采样(head-sample)1%,保持其余部分的代表性——在 Agent 场景下会产生一个追踪存储库,其中中位数追踪是拥有 200 个 span 的怪物,长尾效应才是唯一关键的部分,而你发现故障的频率与你花钱的频率完全无关。

你的 Prompt 发布得像个牛仔:为什么代码审查的严谨性没能延伸到 AI 交付物

· 阅读需 13 分钟
Tian Pan
Software Engineer

浏览任何成熟工程团队的 PR 队列,你都会看到同样的现象:一个四行的 Bug 修复会引来三轮关于命名、错误处理和测试覆盖率缺失的评论;而对系统提示词(System Prompt)的四十行修改却能凭借一句 “LGTM, ship it” 轻松过关。作者对此不以为意,因为差异对比(diff)看起来就像文档;审查者也无所谓,因为他们对于那段英文块中什么是“好”没有心理模型。结果是,一个具有功能发布级别影响范围的提示词更改,却仅以修复拼写错误的门槛通过了审查。

这是每个在生产环境中使用 LLM 构建产品的团队所面临的隐秘质量危机。代码库拥有数十年积累的纪律——Linter、类型检查、代码所有者(Code Owners)、测试关卡、发布窗口。而真正引导模型的产物——系统提示词、评估准则(Eval Rubric)、工具描述、少样本示例(Few-shot Exemplars)——虽然存放在同一个仓库中,却通过为英文散文设计的审查流程进行发布。因此,提示词回归、评估准则漂移和工具模式(Schema)损坏,却能以团队永远不会接受的代码质量标准通过。

AI 功能之间隐藏的边:当一次提示词编辑导致其他三个团队的性能回退时

· 阅读需 11 分钟
Tian Pan
Software Engineer

一位平台工程师修改了公司“品牌风格”序言中的开场白——这是用于统一所有面向客户的助手语气的一行代码。这项改动通过 feature flag 发布。到了周二,搜索团队的相关性退化指标激增,支持机器人的评估通过率下降了四个百分点,入职引导 Agent 的重试率翻了一倍。这些团队中没有一个动过自己的代码。他们都没有收到任何预警。平台工程师对这一切一无所知,因为没人收到过类似的警报:“你的修改刚刚搞坏了三个下游功能。”

这就是定义 AI 团队成立第二年后的典型失效模式。第一年,每个团队都在各自的角落闭门造车。第二年,这些角落开始共享产物——这里一个提示词片段,那里一个种子评估集,或者一个被当作协议复用的工具 Schema。当这种共享变得隐性时,AI 功能之间的依赖图就变得不可见了。你现在拥有的是一个没人能叫出其边缘名称的分布式系统。

解决这一问题的方法论(discipline)并不是一个新平台,而是绘制这张图。