所有文章

LLM 上线之前:我踩过的 7 个坑

· 1 分钟

用 LLM 搭一个能用的原型,可能只需要一个下午。但把它上线,稳定运行,让真实用户用起来满意——这是另一个量级的工程问题。

以下是我在把 RAG 系统推到生产时踩过的真实坑,每一条都有代价。

坑 1:召回了,但 LLM 没用上

RAG 系统里最常见的隐患:向量召回的文档确实相关,但模型输出的答案完全没有利用到它们。

原因通常是 prompt 结构问题。模型倾向于「相信自己的训练知识」,而不是相信你塞进去的上下文,特别是当你的 context 格式混乱、没有明确 instruction 的时候。

解决方案: 在 system prompt 里明确要求模型「只基于以下文档回答,如果文档中没有,说不知道」,并且对 context 使用结构化标记(如 XML 标签),帮助模型定位。

SYSTEM = """
你是一个知识库助手。请严格基于<documents>标签中的内容回答用户问题。
如果文档中没有相关信息,请直接说「文档中没有相关内容」。
不要根据自身知识补充未在文档中出现的内容。
"""

context = "\n".join([f"<doc id='{i}'>{d}</doc>" for i, d in enumerate(docs)])

坑 2:延迟不可预测

同一个 prompt,有时 2 秒返回,有时 30 秒。用户体验极差。

根本原因:大模型的 token 生成速度相对固定(~50 tokens/s),但输出长度差异巨大。一个「写一段 200 字总结」和「写一段 2000 字分析」的价格/时间完全不同。

解决方案:

  1. 在 prompt 中明确限制输出长度(max_tokens
  2. 使用流式输出(SSE),让用户感知到「在生成」而不是「卡住了」
  3. 给 API 调用加超时,触发后给用户友好提示而不是白屏

坑 3:向量数据库的「幻觉召回」

向量相似度高不代表语义相关。Cosine similarity = 0.85 的文档,可能是讲完全不同话题但使用了相似词汇。

解决方案:

  • 加 BM25 倒排索引做混合检索(hybrid search),召回后 RRF 融合
  • 用 cross-encoder reranker 对召回结果重排序(延迟 +50ms,但准确率大幅提升)
  • 设置相似度阈值,低于阈值的文档直接丢弃

坑 4:对话历史的 token 爆炸

多轮对话系统里,不加处理地把全部历史塞进 context,很快就会撞到 token 上限,API 调用失败。

解决方案:

def compress_history(messages, max_tokens=4000):
    # 保留最近 N 轮,超出部分总结为摘要
    recent = messages[-6:]  # 最近 3 轮
    if len(messages) > 6:
        summary = summarize(messages[:-6])  # 用 LLM 总结历史
        return [{"role": "system", "content": f"对话历史摘要:{summary}"}] + recent
    return messages

坑 5:错误处理不够健壮

API 限流(429)、超时、偶发的 5xx,在高并发下比你想象的更常见。一个没有重试和降级的系统,在压力下很容易崩。

import tenacity

@tenacity.retry(
    wait=tenacity.wait_exponential(multiplier=1, min=4, max=10),
    stop=tenacity.stop_after_attempt(3),
    retry=tenacity.retry_if_exception_type(RateLimitError),
)
async def call_llm(messages):
    return await client.chat.completions.create(...)

坑 6:没有可观测性

上线之后出了问题,不知道是 embedding 的问题、召回的问题,还是生成的问题。Debug 全靠猜。

解决方案: 从第一天就接入 tracing。推荐 LangFuse(开源可自托管),记录:

  • 每次 LLM 调用的 prompt / response / token 数
  • 向量检索的查询和召回结果
  • 端到端延迟分解

坑 7:评估体系缺失

没有量化指标,就没有迭代方向。不知道模型究竟在哪些问题上表现差,优化只能靠感觉。

最小可行评估集:

  1. 建立 100-200 条「黄金问答对」(真实用户问题 + 人工标注的理想答案)
  2. 定义指标:Recall@K(召回准确率)、Answer Faithfulness(答案忠实度)、User Satisfaction(用户满意率)
  3. 每次大改之后跑一遍评估集,对比分数

工具推荐:RAGAS(专门评估 RAG 系统,开源)


把 LLM 用好是一个工程问题,和模型本身的质量关系反而没那么大。上面这些坑,每一个都是用线上故障换来的教训。

希望你能跳过它们,直接踩更有趣的坑。