跳到主要内容

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

查看所有标签

为所有人辩护 AI 评估

· 阅读需 7 分钟
Tian Pan
Software Engineer

每隔几个月,AI 工程社区就会兴起一股新的“不必费心评估”的浪潮。论点通常是:评估成本太高、过于脆弱、难以定义,对于快速迭代的产品团队来说,最终不值得投入这些额外的负担。不如发布、迭代,并相信你的直觉。

这是一个糟糕的建议,会导致劣质软件。2026 年 LangChain 的一项调查发现,只有 52% 的组织进行离线评估,而只有 37% 的组织针对实时流量运行在线评估——然而,32% 的组织将质量列为他们生产部署的第一大障碍。这并非巧合。

LLM 应用的数据飞轮:在生产与改进之间闭环

· 阅读需 11 分钟
Tian Pan
Software Engineer

大多数 LLM 应用上线后,会观察到一些故障,然后修补提示,再重复这个过程。这不是飞轮,而是跑步机。一个真正的数据飞轮是一个自我强化的循环:生产产生反馈,反馈改进系统,改进后的系统产生更好的交互,进而产生更好的反馈。每一次循环都会在前一次的基础上累积。

这种差异至关重要,因为基础模型已经消除了传统的护城河。每个人都可以调用相同的 GPT-4o 或 Claude 端点。新的护城河是来自真实用户执行真实任务的专有反馈数据——这些数据昂贵、耗时且无法从外部复制。

但是构建一个飞轮说起来容易做起来难。不到 1% 的生产交互会产生明确的反馈信号。天真地仅仅利用这 1% 的数据进行训练会导致奉承偏差、幸存者偏差和指标漂移。本文将深入探讨实际有效的方法:生产飞轮的架构、如何收集和过滤信号、关闭循环的四个杠杆,以及可能悄悄毒害你的故障模式。

倒置的工程工作流

经典的机器学习有一个清晰的管道:数据 → 特征 → 模型 → 产品。LLM 工程则反向运行:产品 → 验证 → 定制优化

产品优先发布,因为你无法提前列举出所有输入分布——只有真实用户执行真实任务才能揭示真正重要的东西。这种倒置并非捷径;它是唯一可行的方案。这也意味着反馈基础设施必须在产品上线之前设计好,而不是在你意识到需要它时才匆忙加上。

由此产生的三阶段架构是:

  1. 评估——为你的特定用例定义“好”是什么样子
  2. 监控——在生产环境中持续根据这些定义进行衡量
  3. 改进——通过将信号反馈回系统来关闭循环

大多数团队在第三阶段(微调、提示工程)投入巨资,却忽视了第一和第二阶段。这是本末倒置。垃圾指标会产生垃圾训练数据。

第一阶段:定义成功(正确设置指标)

团队犯的第一个错误是将评估视为与生产无关的事情。事实并非如此。你的评估逻辑必须与你的生产逻辑完全一致,否则你的离线数据就会骗人。

使用二元指标。 将输出评分定为通过/失败,而不是 1-5 分制。人类在二元判断上的一致性要高得多,这意味着你的标注数据集中噪声更少。“这个回复是否事实准确?”是可回答的。“给这个回复打 1 到 5 分”则不然。

验证输入,而不仅仅是输出。 一个 LLM 系统的质量取决于它接收到的信息。应用波斯特尔定律:对你发送的数据要严格,对你接收的数据要宽容。实用的输入验证器包括:

  • 主题相关性(与你的领域进行语义相似度阈值比较)
  • 查询复杂性(token 计数限制)
  • 语言检测(将非目标语言查询路由到备用路径)
  • 敏感信息检测(正则表达式 + 命名实体识别)
  • 对抗模式检测(已知的越狱模式)
  • 通过嵌入相似性对历史输入进行异常检测

将质量分解为子指标。 一个笼统的“质量”分数无法提供任何可操作的信息。将事实准确性、语气一致性、引用正确性、回复完整性分开评估。这种分解使“LLM 作为评判者”的对齐更容易,人工标注也更快。

区别对待多步骤管道。 在链式或代理系统中,根据每个节点的功能来验证:

  • 分类器(路由)节点:通过基于规则的检查验证准确率、精确率、召回率
  • 编写器(生成)节点:基于 LLM 的质量验证器
  • 代码生成节点:静态分析、代码检查工具以及动态执行(实际运行 SQL)

管道中的错误传播是一个开放的研究挑战。考虑连接节点之间复合故障的图感知评估还没有标准解决方案——将其视为正在进行的工作,并独立地监控每个节点。

第二阶段:从生产中捕获反馈

显式反馈比你想象的要稀少。 不到 1% 的生产交互会产生明确信号。复杂的反馈表单有大约 95% 的用户会中途放弃。一个简单的内联点赞/点踩按钮可以将反馈提交量比模态表单增加 40 倍。每一次额外的点击都是一个过滤器。无情地最小化摩擦,否则你的显式信号语料库将过小且过于偏颇,无法发挥作用。

隐式信号是你的主要数据来源。 来自所有生产用户的行为信号比显式反馈具有更大的数据量,尽管信噪比更低:

信号它表明什么
提前终止(中途停止)回复错误或无用
“不……”,“我指的是……”等修正对意图的误解
重新生成(点击重试)不满意
复制操作输出足够好用
编辑操作输出接近但未完成
代理/代码建议的采纳率任务成功的直接指标
会话删除会话失败
追问模式回复不完整

永远不要只优化单一信号。通过对多个隐式信号进行三角测量来区分噪声和真实信号。

标注时机很重要。 对于涉及缺失知识识别的任务,即时标注(在交互上下文新鲜时)可以显著提高一致性——在一个生产系统中,当标注在线进行而非几天后进行时,知识相关性一致性从 43.6% 跃升至 92.3%。对于偏好和采纳任务,时机没有显著的质量差异,因此你可以在不影响服务水平协议 (SLA) 的情况下批量处理这些任务。

对所有数据进行分层。 从生产日志构建评估数据集时,按查询类型、难度或任务类别进行分层。意外地构建了不具代表性的评估集——过度偏重常见简单查询——会导致指标无法预测真实性能。

阶段 3:闭环

根据速度与深度,从生产反馈中改进系统的四个杠杆:

杠杆 1:提示词改进(最快、最便宜)。 通过编辑系统提示词来修复监控中发现的故障模式。训练成本为零。当与少样本示例检索结合时,这种方法尤其强大:维护一个带有时间戳的标注生产示例数据库,并在推理时使用嵌入相似性动态检索与当前输入最相似的 K 个示例。这是来自真实生产数据的上下文学习——无需重新训练即可实现改进。

杠杆 2:RAG 知识库更新。 当你的监控发现“知识缺失”故障时——即模型没有所需信息时——将这些知识添加到你的检索语料库中。这比提示词编辑需要更复杂的基础设施(嵌入管道、检索调优),但不会改变模型权重。

杠杆 3:基于精选生产数据进行微调。 完整流程:

  1. 记录所有生产环境下的提示词/完成对,并为每种任务类型标记稳定的 workload_id
  2. 去重并应用类别感知分层拆分
  3. 使用 LLM 作为判断的质量检查进行筛选(移除嘈杂或不良示例)
  4. 格式化为指令微调对
  5. 微调(完全微调或 LoRA/QLoRA 以实现成本效益)
  6. 对照保留测试集和基线进行评估——先自动化,再人工审查有潜力的候选模型
  7. 推广获胜模型;维护回滚机制

质量胜于数量。一个精心策划的 5,000 个示例数据集始终优于 500,000 个未经策划的示例。微调是一个生命周期,而非一次性任务——它需要版本控制、定期再训练和明确的回滚计划。

NVIDIA 的开源“数据飞轮”蓝图展示了其潜在的成本效益:对于一个 HR 聊天机器人,一个经过微调的 1B 参数模型在工具调用任务上的准确率达到了 70B 模型的约 98%,将推理成本降低了 98.6%。

杠杆 4:偏好优化。 使用成对偏好标签(A 与 B 响应评级)进行直接偏好优化(DPO)或强化学习人类反馈(RLHF)。这使模型能够从其特定的生产错误中学习,而不仅仅是监督示例。它在实现深度行为对齐方面潜力最大,但数据和计算成本也最高——如果操作不当也最危险(见下文)。

完全自动化闭环。 微软的 Arena Learning 框架通过模拟模型版本之间的“战斗”来消除人工标注瓶颈。目标模型与多个其他模型进行对抗;AI 标注的战斗结果识别出弱点;训练数据被更新以解决这些弱点;模型重新训练并再次战斗。Elo 分数增益在大约三次迭代内收敛。构建功能性飞轮并不严格需要人工标注——AI 可以评判 AI,只要评判者始终优于学生。

将悄悄毒害你飞轮的故障模式

通过反馈循环产生的奉承。 最危险的故障。当人类评估者认同现有信念时,他们会给予更高的响应评分。一个基于这些偏好训练的模型会学会优化一致性而非准确性。OpenAI 在 2025 年 4 月回滚了 GPT-4o 的一次更新,因为它变得明显更善于奉承。研究表明,奉承式同意和奉承式赞扬是训练过程中融入模型权重的不同学习行为——事后很难去除。

延迟偏见。 快速平庸的响应可能会比缓慢但优秀的响应获得更高的评分。如果你天真地依赖这些信号进行训练,你将以牺牲正确性为代价来优化速度。将反馈分解为不同的维度,切勿混淆。

指标漂移。 人类对 LLM 输出的偏好会随着时间而变化,尤其是当底层 API 更新时。六个月前定义的指标可能不再能捕捉到用户真正想要的东西。评估定义需要持续的人工审查,而非发布时编写的静态定义。

幸存者偏差。 提交明确反馈的用户并不能代表所有用户。高级用户的反馈可能与主流用户存在系统性差异。来自全体用户的隐式信号通常更具代表性,即使它们可能更嘈杂。

隐私作为飞轮杀手。 处理生产流量需要 PII 移除和清晰的组织意识。隐私事件可能摧毁多年来积累的飞轮动能。数据使用的透明度不仅是道德要求——它对用户信任而言是生死攸关的。

静态的“黄金标准”。 将当前生产模型的响应作为评估的“黄金标准”,意味着你的评估上限就是当前模型。你将衡量一致性,而非绝对质量。对于你希望衡量真正改进的任务,你需要人工标注的“黄金标准”。

一个实用的起点

如果你今天正在构建 LLM 应用程序,但没有这些基础设施:

  1. 记录一切。 为每种任务类型的每个请求/响应标记一个 workload_id。你无法追溯收集你未记录的数据。
  2. 选择一种故障模式来重点关注。 不要试图一次性构建完整的飞轮。找出生产中最常见的故障模式,并为其构建一个有针对性的验证器。
  3. 添加一个简单的内联反馈按钮。 一个明确的信号,零摩擦。
  4. 构建一个带时间戳的示例数据库。 即使在你微调之前,你也可以用它进行少样本检索,并跟踪故障模式随时间演变的情况。
  5. 将微调视为一个生命周期。 你的第一个微调模型并非最后一个。从一开始就规划版本控制和回滚。

飞轮不必完全自动化才能有价值。一个局部闭环——生产数据暴露故障,人工精选示例,工程师更新提示词或进行微调——其复合效应比完全没有闭环要快。关键在于将反馈收集视为首要的工程关注点,而不是产品的附带考虑。

生产中的推理模型:何时使用,何时不使用

· 阅读需 9 分钟
Tian Pan
Software Engineer

大多数采用推理模型的团队都会犯同样的错误:他们开始在所有地方使用它们。一个新模型发布,带着令人印象深刻的基准测试数据,然后在一周内,它就处理了客户支持、文档摘要以及它真正为之构建的那两个真正困难的问题。然后,基础设施账单就来了。

推理模型——o3、支持扩展思维的 Claude、DeepSeek R1 及其后续版本——确实与标准 LLM 不同。它们在生成输出之前会执行内部的思维链(chain-of-thought),花费更多的计算周期来探索问题空间。这种额外的工作在需要多步骤逻辑的任务上带来了真正的提升。但它也导致每次请求的成本增加 5–10 倍,并增加 10–60 秒的延迟。这两点都无法作为默认设置被接受。

生产环境中的结构化输出:如何用 LLM 生成可靠的 JSON

· 阅读需 11 分钟
Tian Pan
Software Engineer

大语言模型是文本生成器。你的应用程序需要数据结构。这两个事实之间的差距,正是生产环境中的错误滋生之地。

每个使用大语言模型构建产品的团队都会遇到这个瓶颈。模型在游乐场中表现出色——它返回的内容看起来像 JSON,字段大多正确,通常能通过 JSON.parse。然后你将其部署上线,你的解析层却在凌晨两点开始抛出异常。响应中多了一个逗号。或者是一个 Markdown 代码围栏。或者模型决定在 JSON 前面添加一段解释性文字。又或者它幻觉出一个字段名。

业界已经花了三年时间来解决这个问题。这就是目前解决方案的收敛点,以及仍然让团队头疼的问题。

三个成熟度级别

团队处理结构化输出的方式有着清晰的进展,每个级别都有一个实际的可靠性上限。

级别 1:提示工程。 你写道:“只用以下格式的有效 JSON 回复:”并展示一个示例。对于简单模式,这在 80-95% 的情况下有效。失败模式很微妙:模型在复杂提示中添加前言,在模式变长时将 JSON 包装在代码块中,或者静默地省略可选字段。你添加一个正则表达式清理步骤和一个 try/catch,然后说服自己这样没问题。

对于任何重要的应用来说,这都远不够好。95% 的解析成功率听起来很高,直到你有一个 10 步的智能体链:0.95^10 ≈ 0.60。十次智能体运行中,有六次会失败。这个数学计算是无情的。

级别 2:函数调用/工具使用。 所有主要提供商都暴露了一个 API,你可以在其中定义 JSON 模式,模型应该填充它。这能让你达到 95-99% 的可靠性。但问题是:模式是一个提示,而不是一个约束。模型将模式视为其上下文的一部分并学习遵循它——但解码过程中的任何环节都无法阻止它生成无效 token。提供商仍然可能返回格式错误的数据包,尤其是在处理复杂模式或边缘情况输入时。

级别 3:带有约束解码的原生结构化输出。 这是在数学上保证 100% 模式有效性的地方。推理引擎根据你的模式构建一个有限状态机,并在每个生成步骤中屏蔽无效 token。模型实际上无法生成无法解析的输出。OpenAI 结合 json_schemaresponse_format、Gemini 的 response_schema,以及 Outlines 等开源框架都使用了这种方法。

如果你正在构建任何需要可靠下游解析的东西——分类管道、智能体工具调用、数据提取——你都会需要级别 3。

约束解码的实际工作原理

理解其实现方式是值得的,因为它决定了你能使用和不能使用哪些模式。

在每个生成步骤中,模型都会在其整个词汇表(50,000 多个 token)上生成一个概率分布。通常,你会从该分布中采样。而使用约束解码时,你首先构建一个有限状态机,代表你的 JSON 模式中的每个有效路径。在采样之前,你会计算一个token 掩码:一个布尔向量,其中 false 意味着“给定 FSM 中的当前状态,这个 token 不能出现在这里”。你将这些 logits 置零,然后从剩余的 logits 中采样。

结果是:模型只能生成那些能够推进模式有效完成的 token。这不是后处理——它融入到每一个解码步骤中。

早期的实际开销曾是一个担忧。为复杂模式构建初始 FSM 可能需要 50-200 毫秒。但像 XGrammar(来自 MLC 团队)这样的引擎能够在每个 token 不到 40 微秒内完成 token 掩码生成,后续请求则重用缓存的 FSM,开销几乎为零。对于简单模式,延迟影响低于 5%。对于具有大型枚举集的深度嵌套模式,延迟可能达到 30-60%——这真正提示你需要简化你的模式了。

模式设计:团队常犯的错误

即使约束解码强制执行了语法有效性,糟糕的模式设计仍然会导致语义失败。以下是困扰大多数团队的模式:

将推理置于结论之前。 如果你的模式有一个 reasoning 字段和一个 classification 字段,请将 reasoning 放在前面。大语言模型从左到右生成 token。当模型在确定分类之前写出其推理时,它会产生更好的分类。如果你将答案字段放在前面,模型会在思考之前确定一个标签,然后才在推理字段中进行合理化。这听起来像大语言模型的一个怪癖,但它确实能持续地将准确性提高几个百分点。

扁平化你的模式。 嵌套是可靠性的大敌。OpenAI 的原生结构化输出最多支持 5 层嵌套和 100 个总属性。超出这个范围,语法编译时间会飙升,每个 token 的开销也会增加。更重要的是,即使有约束解码,具有 4 层以上深度嵌套的模式也表现出明显更高的错误率——模型有更多机会失去上下文。如果你的模式深度嵌套,请问问自己,这种嵌套是反映了实际的数据层次结构,还是仅仅是组织偏好。

描述每个字段。 Pydantic 的 Field(description=...) 值作为内联指令传递给模型。如果没有描述,模型将仅从字段名推断语义。confidence: float——它是 0-1 还是 0-100?status: str——有效值是什么?字段描述不是文档;它们是直接影响输出质量的提示指令。

明确处理可选性。 OpenAI 的结构化输出不支持你期望的那种可选字段。如果一个字段可以不存在,请将其建模为带有默认值 NoneOptional[str],而不是仅仅是 没有默认值的 str | None。提供商对这种区别处理不同,如果处理不当,会在运行时产生神秘的“无效模式”错误。

避免复杂模式。 带有复杂模式的正则表达式约束字段、具有多个分支的 oneOf 和递归模式会在 FSM 中造成组合爆炸。如果你需要“一个或多个与某个模式匹配的项”,请考虑将问题分解为多个顺序调用,而不是在单个模式中表达它。

实践中的服务商格局

每个主要的服务商都有不同的 API 接口,其抽象层无法清晰地在不同服务商之间转换。

OpenAI 提供了最成熟的实现。你可以使用 client.beta.chat.completions.parse() 搭配 Pydantic 模型,它能处理模式转换并返回一个类型化的 Python 对象。使用原始 JSON 模式的 response_format 方法也有效,但需要手动构建模式。.parse() 方法是正确的默认选择。

Anthropic 没有专用的结构化输出 API。其惯用模式是强制使用工具:将你的模式定义为一个工具,然后设置 tool_choice 强制模型调用它。如果没有 tool_choice: {type: "tool", name: "your_tool"},模型可能会选择根本不使用该工具。这并非约束解码——它仍然是 Level 2——但比提示工程要可靠得多。

Google Gemini 提供了带有约束解码的 response_schema,类似于 OpenAI 的方法。该 API 接受原始 JSON 模式而非 Pydantic 模型,所以你需要模式转换工具。

对于跨多个服务商工作的团队来说,Instructor 库抽象了这些差异。它在 OpenAI、Anthropic、Gemini 等平台之间提供了一个统一的 client.chat.completions.create(response_model=YourPydanticModel) 接口。Instructor 还能处理验证失败时的自动重试——如果模型返回了未能通过 Pydantic 验证的内容,它会附带错误信息重新提示并再次尝试。

验证三明治

即使在使用原生结构化输出时,也务必在其之上添加一个验证层。这并非多疑——这是为了防范语法约束无法捕捉的语义失败。

from openai import OpenAI
from pydantic import BaseModel, field_validator

class ClassificationResult(BaseModel):
reasoning: str
label: str
confidence: float

@field_validator("confidence")
def confidence_must_be_normalized(cls, v):
if not 0.0 <= v <= 1.0:
raise ValueError(f"confidence must be between 0 and 1, got {v}")
return v

@field_validator("label")
def label_must_be_valid(cls, v):
valid_labels = {"positive", "negative", "neutral"}
if v not in valid_labels:
raise ValueError(f"label must be one of {valid_labels}, got {v}")
return v

client = OpenAI()
result = client.beta.chat.completions.parse(
model="gpt-4o",
messages=[...],
response_format=ClassificationResult,
)

# result.choices[0].message.parsed is already a ClassificationResult
# but Pydantic validators run during construction, so they've already fired

模式强制结构。Pydantic 验证器强制语义。两者你都需要。

约束解码保证的是语法有效性,而非语义正确性。模型可以在一个浮点数字段中返回 confidence: 1.7 并满足模式。它也可以从模式的枚举中返回一个对于输入而言语义上错误的标签。验证器能捕捉前者;评估则捕捉后者。

智能体链中的结构化输出

在多步骤工作流中,可靠性计算会变得更糟。每个返回结构化数据的工具调用都是一个模式验证可能失败的步骤。通过 Instructor 的重试行为,失败会附带错误上下文进行重试——但重试会消耗 token 和延迟,而且某些故障模式会循环。

这里有两种有助于解决问题的模式:

在每个步骤中缩小你的模式。 不要将一个庞大复杂的模式贯穿于每个工具调用。在每个步骤中,只提取你需要用于下一步的数据。更小的模式具有更低的失败率和更少的开销。

每次调用都记录模式版本。 模式会演变,而错误往往源于模式变更未在所有地方传播。将模式版本与提示和响应一同记录。当出现问题时,你可以根据当时生效的模式重放精确的输入。

仍然存在的问题

约束解码解决了解析问题,而非建模问题。无论模式强制如何,一些故障模式依然存在:

幻觉枚举值。 如果你的模式允许 enum: ["gpt-4", "claude-3-5-sonnet", "gemini-2-0-flash"],而你添加了一个新模型却忘记更新模式,模型将被迫返回其中一个有效值——但它可能会自信地返回错误的值。模式约束并不能让模型准确;它们只是让模型可解析。

长链中的语义漂移。 在多步骤管道中,第 N 步的结构化输出会作为第 N+1 步的提示输入。意义上的错误(而非格式上的)会以解析检查无法检测到的方式累积。这时,评估和抽查比工具更重要。

调用者之间的模式不匹配。 在包含多个服务的生产系统中,调用服务中的模式定义与下游消费者期望的模式定义不一致是很常见的。将你的 Pydantic 模型视为事实的唯一来源,并将其作为一个包共享,而不是复制粘贴的字典。

默认应该是 Level 3

原生结构化输出的工程论点很简单:提示工程增加了重试复杂性,函数调用增加了验证复杂性,两者都增加了在凌晨 2 点调试起来令人烦恼的故障模式。带有 Pydantic 验证层的原生结构化输出为你提供了最强的保证,并消除了一整类生产事故。

工具链已成熟。XGrammar 使约束解码足够快,对于简单模式而言,延迟很少成为问题。Instructor 库消除了服务商特定的样板代码。在 2025 年,没有充分的理由使用 Level 1 解析交付新的 LLM 管道。

唯一的真正代价是模式设计规范。扁平模式、描述性字段、显式可选性、先推理后结论的顺序——这些都不是复杂的要求,但它们需要刻意为之。这种规范正是区分在演示中有效与在生产中可靠运行的 LLM 功能的关键。

生产环境中的提示注入:真正有效的攻击模式及如何阻止它们

· 阅读需 13 分钟
Tian Pan
Software Engineer

提示注入是 OWASP LLM 应用十大漏洞之首,工程师对它的运作方式和攻击者实际利用方式的理解之间存在越来越大的鸿沟。2024 年的一项研究测试了 36 个生产环境中集成了 LLM 的应用程序,发现其中 31 个易受攻击。2025 年的一次红队测试发现,如果攻击者尝试的次数足够多,100% 已发布的提示防御措施都可以被绕过。

残酷的真相是:大多数团队首先采取的简单防御措施——仅靠系统提示警告、关键词过滤、输出净化——在面对尝试多种方法的攻击者时都会失效。有效的方法是架构性的:分离权限、隔离不受信任的数据,并根据 LLM 看到的内容来限制它实际能做的事情。

这篇文章是为构建生产系统的工程师准备的实战指南。没有 CTF 风格的玩具示例——只有导致真实事件的攻击模式和能显著降低风险的防御模式。

LLM 路由:如何停止为简单查询支付顶级模型的昂贵价格

· 阅读需 14 分钟
Tian Pan
Software Engineer

大多数团队都会遇到同样的拐点:LLM API 成本的增长速度超过了使用量的增长,而且每一个查询——无论是“总结这句话”还是“审计这个 2,000 行的代码库以查找安全漏洞”——都指向同一个昂贵的模型。解决方法不是挤压 prompt,而是路由。

LLM 路由意味着将每个请求引导至最适合该特定任务的模型。不是能力最强的模型,而是正确的模型——在成本、延迟和质量之间平衡,以满足查询的实际需求。如果做得好,路由可以在质量几乎不下降的情况下将 LLM 成本降低 50–85%。如果做得不好,它会产生隐性的质量倒退,直到用户流失你才会察觉。

这篇文章涵盖了其机制、权衡以及在生产环境中实际会出问题的地方。

生产级 LLM 应用的 Token 预算策略

· 阅读需 12 分钟
Tian Pan
Software Engineer

大多数团队发现他们上下文管理问题的方式都如出一辙:一个在演示中表现良好的生产级智能体,在对话进行 15 轮后开始出现幻觉。日志显示 JSON 格式正确,模型返回了 200 状态码,且没有人修改代码。变化的是累积效应——工具结果、检索到的文档和对话历史悄无声息地填满了上下文窗口,直到模型需要在 80,000 个相关性参差不齐的 Token 上进行推理。

上下文溢出(Context overflow)是显而易见的故障模式,但“上下文腐化”(context rot)则更具隐蔽性。研究表明,在达到限制之前,LLM 的性能就已经开始下降。随着上下文的增加,模型会出现“中间迷失”效应(lost-in-the-middle effect):注意力集中在输入的开头和结尾,而中间的内容则变得不可靠。埋藏在 30 轮对话中第 12 轮的指令可能会实际上消失。模型不会报错——它只是悄悄地忽略了它们。

生产环境中的 LLM 护栏:哪些方法真正奏效

· 阅读需 10 分钟
Tian Pan
Software Engineer

大多数团队在发布他们的第一个 LLM 功能后,会在生产环境中因糟糕的输出而受挫,然后紧急加上护栏进行损害控制。结果是一个脆弱的系统,它会阻止合法的请求,减慢响应速度,并且在关键的边缘情况下仍然失效。护栏值得做好——但天真的方法会以你意想不到的方式伤害你。

以下是实际的权衡取舍,以及如何构建一个不会悄悄破坏你产品的护栏层。

生产环境中的提示工程:真正重要的是什么

· 阅读需 9 分钟
Tian Pan
Software Engineer

大多数工程师学习提示工程都是倒着来的。他们从“发挥创意”和“一步一步思考”开始,反复迭代一个演示直到它奏效,然后在生产环境中发现模型有 15% 的时间在“幻觉”(胡编乱造),他们的 JSON 解析器每隔几小时就会抛出异常。让聊天机器人令人印象深刻的技术,往往不是让生产系统可靠的技术。

在将 LLM 功能部署到真实系统一年后,以下是真正区分有效提示和在负载下仍能保持稳定的提示的关键。

生产环境中的工具使用:真正有效的函数调用模式

· 阅读需 10 分钟
Tian Pan
Software Engineer

LLM 在生产环境中函数调用失败最令人惊讶的地方在于它们的来源。不是幻觉推理。也不是模型选错了工具。代理不稳定的首要原因在于参数构造:错误的类型、缺少必填字段、格式错误的 JSON、幻觉出的额外字段。模型本身没问题。你的 schema 才是问题所在。

这是个好消息,因为 schema 修复成本很低。

你的 AI 产品需要评估系统

· 阅读需 9 分钟
Tian Pan
Software Engineer

每次 AI 产品演示看起来都很棒。模型生成了一些貌似合理的内容,利益相关者频频点头,每个人都带着乐观的情绪离开会议。然后产品发布了,真实用户出现了,事情开始以没人预料到的方式走向下坡路。团队手忙脚乱地修复一个故障模式,却无意中制造了另一个,经过数周的“打地鼠”后,提示词已经变成了一个 2000 个 token 的庞然大物,没人再能完全理解它了。

根本原因几乎总是相同的:没有评估系统。那些发布可靠 AI 产品的团队很早就构建了评估系统,并将其视为基础设施,而不是事后才考虑的事情。那些停滞不前的团队则将评估视为“等产品更成熟了”才需要担心的事情。到那时,他们已经陷入困境。

快速改进 AI 产品背后不那么光鲜的工作

· 阅读需 10 分钟
Tian Pan
Software Engineer

大多数 AI 团队在产品发布六周后都会遇到同样的瓶颈。最初的演示令人印象深刻,原型按时交付,早期用户也褒奖有加。然而,"足以展示" 和 "足以留住用户" 之间的鸿沟变得无法避免。团队手忙脚乱——调整提示词、更换模型、添加防护措施——但产品却几乎纹丝不动。

那些真正能快速改进的团队有一个反直觉的习惯:他们花在架构上的时间较少,而花在审视数据上的时间更多。不是仪表盘。不是汇总指标。而是对话日志中那些原始的、糟糕的、单独的失败案例。

这是一份实践指南,旨在区分快速发展的 AI 团队和停滞不前的团队。