构建能在生产环境中真正运行的 LLM 系统的七种模式
演示总是有效的。用精选的例子提示模型,获得清晰的输出,将截图发给利益相关者。六周后,系统面对真实用户,而演示中的例子却一个都没有出现在生产流量中。
这是每个LLM产品团队最终都会遇到的鸿沟:从“它在我的输入上有效”到“它在我未曾预料的输入上都有效”的飞跃。弥合这一鸿沟的模式并非关于模型选择或提示词的巧妙,而是关于系统设计。七种模式解释了功能原型与可靠生产系统之间的大部分差异。
1. 评估先行,而非滞后
LLM产品开发中最常见的错误是,将评估视为系统建成之后才进行的事情。团队花费数周时间迭代提示词和模型配置,却没有一个稳定的衡量基线,然后才意识到他们无法判断上周二的改变是让事情变得更好还是更糟。
评估需要先行——在提示工程之前,在模型选择之前,在部署之前。 其机制并不复杂:定义任务,收集代表性示例(即使是50-100个精心挑选的案例也远胜于零),并编写一个在每次更改时运行的自动化评分器。这就是“评估驱动开发”,它与传统软件中的测试驱动开发是LLM工程中最接近的实践。
像MMLU或HELM这样的通用基准测试是为了对基础模型进行排名,而不是为了衡量你的产品。一个客户服务机器人如果用研究生级别的科学问题来评估,对你毫无意义。从真实流量中构建特定任务的评估数据集。记录系统失败的例子、用户重新生成响应的例子以及负面反馈的例子。这些将成为你的评估集。
对于许多中间任务,将LLM作为评估器已成为人工标注的实用替代方案。使用更强的模型,结合思维链推理来评估输出,可以在大规模上产生合理校准的分数。关键的限制是:精确地定义评估标准。“这个回答有帮助吗?”太模糊了。“这个回答是否在不幻化产品细节的情况下回答了用户的具体问题?”则是可评估的。
2. 检索优先于再训练
对于任何需要访问事实、文档或随时间变化的知识的系统,检索增强生成(RAG)应该是你的第一个架构选择——而不是微调。
直觉很简单:RAG改变了模型当下能看到的内容。微调改变了模型每次倾向于表现的方式。大多数生产知识问题都与前者有关。
早期RAG实现中的失败模式是将其视为一个简单的向量搜索问题。你将文档分块,嵌入它们,构建FAISS索引,通过余弦相似度检索,然后将结果粘贴到提示词中。这对于演示是有效的。但在生产环境中 ,它会在专有名词、产品代码、缩写词和稀有字符串上失败——而这些正是企业应用中最关键的token。
生产环境的解决方案是混合检索:将基于关键词的检索器(BM25或等效方法)与密集嵌入配对,然后使用倒数排名融合(Reciprocal Rank Fusion)结合排名。关键词搜索捕获精确的token;语义搜索捕获含义。两者都无法单独处理真实查询的完整分布。将混合搜索作为RAG系统首批升级之一的团队,一致报告了相对于纯向量方法的大幅召回率提升。
除了检索本身,分块策略的重要性超出大多数团队的预期。简单的固定大小分块会跨越段落边界、表格行和列表项,从而降低检索精度。句子感知或结构感知的分块——尊重文档边界——能产生更清晰的检索片段。为大多数RAG管道添加一个交叉编码器重排序器作为第二遍(在传递给LLM之前根据查询对检索到的候选进行评分)是一种高回报、低风险的改进。
3. 微调用于行为,而非知识
如果RAG处理知识,那么微调则处理行为。这种区分很重要,因为它决定了何时微调是正确的工具。
微调适用于:
- 难以仅通过提示词强制执行的语气、格式或结构的一致性
- 小型专用模型可以媲美大型通用模型的分类和路由任务
- 输出模式遵循(结构化JSON,特定领域格式)
- 需要内置而非通过提示词遵循的策略和约束
微调作为知识存储器效果不佳。模型不会可靠地记忆训练中的事实数据——它们是进行插值。 通过微调注入产品目录、政策文档或频繁更新的信息会产生幻觉和过时。这正是RAG的作用。
在实践方面,像LoRA和QLoRA这样的参数高效方法使微调变得易于实现。QLoRA的4位量化可以使大型模型的内存需求降低一个数量级,使得单GPU微调对于大多数团队来说是可行的。对于大多数产品用例,完全微调是过度的——LoRA适配器以更少的计算量和更快的迭代速度提供可比的任务性能。
一个让团队头疼的法律问题是:大多数前沿模型提供商禁止使用他们的API输出训练竞争模型。如果你正在从专有模型中提炼能力,请务必核实许可。开源基础模型(Llama、Mistral、Falcon系列)完全避免了这一限制,并提供了在受监管行业中很重要的审计追踪。
4. 谨慎缓存
语义缓存——通过嵌入相似性作为键存储之前的LLM响应——极具诱惑力。它承诺通过对“足够相似”的问题提供缓存答案来大幅降低延迟和成本。但在实践中,它比大多数实现都需要格外小心。
核心风险在于:语义相似性不等于语义等价性。“50美元以下订单的退货政策是什么?”和“500美元以上订单的退货政策是什么?”具有很高的嵌入相似性,但正确的答案却截然相反。将第一个查询的缓存响应提供给第二个查询,是一个产品缺陷,甚至可能引发法律问题。
安全的缓存模式比通用语义搜索更狭窄:
- 基于项目的缓存:预先计算并缓存特定已知实体(产品、文章、用户资料)的摘要。输入受限于已知集合。
- 基于对的缓存:对于已知对之间的比 较查询,当两个实体都被识别时缓存结果。
- 受限输入缓存:当LLM封装了参数化查询(例如,”总结工单 #{id}”),则根据结构化键进行缓存,而非自然语言形式。
- 离线预计算:对于高流量、可预测的输出,批量生成并静态提供。
通用语义相似性缓存对于流量高度集中的查询效果良好——即少量问题变体占据了大部分流量。在将其作为延迟优化策略之前,请根据真实的流量样本测量你的缓存命中率。
5. 将安全防护设计为架构,而非事后补丁
安全防护通常在首次生产事故之后才被添加到LLM系统中——比如用户诱导出了离题的回复,模型幻觉了某个数字,或者输出格式破坏了下游解析器。这种被动的方法意味着安全防护最终成为补丁而非架构。
有四个层面值得明确设计:
结构性安全防护强制执行输出格式。最可靠的技术是受限解码——Guidance或Outlines等库在生成时注入token,强制输出符合有效的JSON Schema、正则表达式模式或语法。这比提示模型“以JSON格式响应”更可靠,因为它是在token层面操作,而非依赖于指令遵循。
语法性安全防护在执行前检查生成的代码、SQL或URL的正确性。在将生成的SQL发送到数据库之前,通过解析器进行检查。在显示URL之前验证它们。这些都是直观的,对于任何执行模型生成代码的系统都应是非可选的。
语义性安全防护评估响应是否相关、准确或与源文档一致。SelfCheckGPT——多次对模型进行采样并检查一致性——是一种实用的幻觉检测技术。可以通过验证声明是否得到检索到的上下文支持来检查基于检索的响应。
安全防护处理内容政策。无论你使用审核API还是经过微调的分类器,此层都需要覆盖输入和输出。输入审核在恶意注入和违反政策的请求到达模型之前将其捕获。输出审核捕获通过模型但仍存在问题的失败。
6. 为不确定性设计用户体验(UX)
大多数LLM产品失败并非模型失败——而是期望失败。期望LLM具有确定性行为的用户会持续感到惊讶。为这种不确定性进行设计是一个工程问题,而不仅仅是设计问题。
在实践中行之有效的一些原则:
对置信度保持透明。 Bard、Bing和Perplexity都展示免责声明和来源引用,这不仅出于法律原因,更是为了设定准确的期望。知道响应可能错误的用户更有可能去验证。而那些假定响应具有权威性的用户则不会。
让拒绝变得容易。 GitHub Copilot的幽灵文本界面具有启发性——建议内联出现,但需要明确的接受操作。接受操作带来的摩擦是故意的。需要主动拒绝而非主动接受的AI功能会得到更仔细的评估。
在可能的情况下限制输入空间。 基于槽的界面(下拉菜单、自动补全、结构化表单)比开放式聊天更容易构建可靠的系统。聊天具有更高的感知能力,但失败面 也大得多。聊天应在产品中赢得其一席之地;不要仅仅因为它似乎是LLM的明显界面就将其作为默认选择。
提供归属。 用户更信任有引用、有来源的回复,而非没有来源的回复——即使他们不查看引用来源。引用表明系统是基于外部信息,而非凭空生成。
7. 将反馈循环融入产品
LLM产品中最持久的竞争优势不是模型或提示——而是数据飞轮。系统地从实际使用中收集信号的系统可以持续改进;而那些不这样做的系统则停留在基线水平。
反馈收集需要融入产品交互设计中,而不是事后附加。行之有效的模式:
显式反馈:点赞/点踩、重新生成按钮、纠正流程。这些直接生成可用于评估和微调的带标签示例。挑战在于响应率——大多数用户不留下显式反馈。优化交互,使提供反馈成为阻力最小的路径。
隐式信号:代码接受率(Copilot的核心指标)、对话继续、被忽略的建议、会话放弃。这些需要埋点,但产生的信号量远高于显式反馈。
故障模式日志记录:每一次错误、异常、安全防护触发和用户报告的问题都是一个训练信号。严格的事件分类——哪里出了问题,为什么,以及正确的输出应该是什么——将生产故障转化为数据集。
当收集到的数据改进了评估,评估又指导了微调和提示迭代,从而改进了产品,产品又产生了更多的使用和更多的信号时,这个飞轮就闭合了。早期部署此循环的团队相比将数据收集视为发布后问题的团队, 拥有复合优势。
从何开始
这七种模式无需同时实现。对大多数团队而言,实用的顺序是:
- 评估:在其他一切之前进行 — 你需要一个衡量基线来判断改变是否有效。
- RAG:用于知识依赖型用例 — 在微调之前,在扩展提示之前。
- 混合检索:作为 RAG 的首次升级 — 关键词加语义,并结合 RRF。
- 护栏:从结构和语法层面开始,随着系统成熟再添加语义层面。
- 反馈机制的埋点:从上线伊始就要做 — 而不是在你意识到需要更多数据之后才做。
- 微调:一旦你有了稳定的评估基线,并且有足够的特定任务数据来支持它,就可以进行。
- 缓存:只有在你了解了你的流量分布,并且可以安全地为你的领域进行缓存时,才进行。
演示很容易。产品是一个系统设计问题。重要的模式不在于找到合适的模型 — 而在于其周围的配套体系。
