Language:Chinese VersionEnglish Version

每个构建 LLM 的团队最终都会面临相同的问题:我们的模型对领域了解不够,或者它产生不一致的输出——我们应该进行微调、构建 RAG 系统,还是投资于更好的提示词?错误的选择会浪费数月的工程时间和大量的计算资源。正确的选择取决于对每种技术实际作用以及您试图解决的具体故障模式的清晰理解。

本文提供了一个实用的决策框架,基于所有三种方法在实际生产中的经验——不是理论概述,而是针对您特定问题做出正确选择的指南。

理解每种技术改变了什么

在比较三种方法之前,您需要清楚地了解每种方法修改了什么以及它在推理栈中的位置。

提示词工程

提示词工程改变了模型的输入。模型的权重保持不变。您提供上下文、指令、示例和约束,引导模型的现有知识朝着您想要的输出方向。

它可以解决的问题:输出格式、推理风格、语调、任务框架、关于特定用例的上下文、逐步推理(思维链),以及将模型限制在定义的行为集合中。

它无法解决的问题:模型不具备的知识、在许多边缘情况下对复杂规则的一致遵循,以及模型从未遇到过的领域特定词汇或风格。

检索增强生成(RAG)

RAG 改变了模型在推理时可用的信息。模型的权重保持不变。您从知识库中检索相关文档,并在要求模型回答之前将其注入到上下文窗口中。

它可以解决的问题:过时的知识(训练截止后后的信息)、访问模型从未训练过的专有信息、基于特定源文档的响应锚定,以及通过将模型锚定到检索到的事实来减少幻觉。

它无法解决的问题:模型的核心推理能力、对您领域结构的理解,或者需要融入到模型权重中的行为模式。

微调

微调在精选数据集上改变模型的权重。模型学习新的行为模式、领域知识或输出风格,这些在所有推理调用中都能保持一致,无需提示词或检索到的上下文。

它可以解决的问题:一致的输出格式和结构、领域特定术语和惯例、专业推理模式,以及通过将指令融入到权重中来减少系统提示词的冗长性。

它无法解决的问题:频繁变化的知识(微调成本高昂重做)、未在训练集中的文档访问,或基础模型的基本能力差距。

决策框架

按顺序思考这些问题。每一个问题都能在你进入下一个问题前排除一些选项:

问题1:这是知识问题还是行为问题?

这是最重要的区别。知识问题意味着模型没有获取正确信息的渠道。行为问题意味着模型有能力完成你需要的任务,但不够可靠。

  • 知识问题(模型缺乏特定事实、文档或最新数据)→ RAG 可能是正确的工具
  • 行为问题(模型的输出格式、风格或推理模式错误)→ 从提示工程开始;如果提示不足,则升级到微调

示例:”我们的聊天机器人有时会编造产品规格” — 这是知识问题。模型没有你的产品目录。RAG 通过在查询时检索真实规格来解决这个问题。

示例:”我们的代码审查助手生成不一致的评论 — 有时过于冗长,有时过于简短” — 这是行为问题。使用示例(少样本)进行提示工程或针对你偏好的评论风格进行微调可以解决这个问题。

问题2:信息是否经常变化?

如果你的知识库每天、每周甚至每月更新一次,基于该知识进行微调是不切实际的。你需要不断重新训练以保持最新。

  • 经常变化的信息(产品目录、支持工单、新闻、定价)→ 使用定期更新的向量存储的 RAG
  • 稳定的领域知识(医学术语、法律惯例、工程标准)→ 微调是可行的

问题3:仅通过提示工程就能解决这个问题吗?

这个问题经常被跳过,导致团队为那些精心设计的系统提示就能解决的问题投入昂贵的解决方案。在投资 RAG 基础设施或微调计算资源之前,花一周时间专注于提示优化。

在继续前进前应尝试的技术:

  • 少样本示例: 在你的提示中包含 3-5 个理想输入和输出的示例
  • 思维链: 要求模型在给出最终答案前逐步推理
  • 结构化输出指令: 指定确切的 JSON 模式、markdown 结构或格式要求
  • 角色和人格: 明确定义模型的专业水平和视角
  • 负面指令: 明确说明模型不应该做什么

如果在系统性的提示优化后,你在评估集上仍然看到 20%+ 的失败率,根据失败模式升级到微调或 RAG。

何时 RAG 是正确的答案

当核心问题是模型缺乏特定信息访问权限时,RAG是正确的选择。它已成为企业LLM应用的默认首选方法,而且理由充分:实现比微调更快,不需要标记的训练数据,知识库可以在不重新训练的情况下更新。

一个最小化的生产级RAG架构

# 使用LangChain和本地向量存储的基本RAG管道
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.chains import RetrievalQA

# 1. 为文档建立索引
def build_index(documents: list[str]) -> Chroma:
    splitter = RecursiveCharacterTextSplitter(
        chunk_size=512,
        chunk_overlap=64,
        separators=["nn", "n", ".", " "]
    )
    chunks = splitter.create_documents(documents)
    embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
    return Chroma.from_documents(chunks, embeddings, persist_directory="./chroma_db")

# 2. 使用检索进行查询
def query(question: str, vectorstore: Chroma) -> str:
    retriever = vectorstore.as_retriever(
        search_type="mmr",          # 最大边际相关性 — 减少冗余
        search_kwargs={"k": 5, "fetch_k": 20}
    )
    llm = ChatOpenAI(model="gpt-4o", temperature=0)
    chain = RetrievalQA.from_chain_type(
        llm=llm,
        retriever=retriever,
        return_source_documents=True
    )
    result = chain.invoke({"query": question})
    return result["result"], result["source_documents"]

生产中最常见的RAG失败包括分块策略不匹配(块太大失去精确度,太小失去上下文)、嵌入模型不匹配(技术领域使用廉价嵌入会丢失语义含义),以及检索返回无关块导致模型混淆。这些问题中的每一个都是调优问题,而不是根本性限制。

何时微调是正确答案

当你有一个稳定、定义明确的任务,模型在可预测的方式下持续失败,而提示工程无法解决时,微调是合理的。你需要微调的信号是:你已经尝试了所有可能的提示工程,你有正确行为的标记示例,并且失败是关于风格或模式而非知识的问题。

一个真正有效的微调数据集

训练数据的质量比数量更重要。500个高质量示例始终优于5,000个平庸示例。每个示例都必须代表您想要的精确行为:

# 微调数据集格式 (OpenAI 微调 JSONL 格式)
{"messages": [
  {"role": "system", "content": "您是一名代码审查员。请审查提供的 Python 函数并给出简洁、具体的反馈。限制反馈最多3个要点。首先关注正确性,然后关注清晰度。"},
  {"role": "user", "content": "def calculate_average(numbers):n    total = 0n    for n in numbers:n        total += nn    return total / len(numbers)"},
  {"role": "assistant", "content": "- **除零风险**: `len(numbers)` 可能为 0;添加 `if not numbers: return None` 保护条件。n- **类型安全**: 考虑使用 `sum(numbers) / len(numbers)`,这更简洁且符合 Python 风格。n- **缺少类型提示**: 添加 `def calculate_average(numbers: list[float]) -> float | None` 以提高清晰度。"}
]}

按照此确切结构收集300-1,000个示例,请领域专家验证,微调后的模型将可靠地生成此格式和级别的特异性,而无需复杂的提示。

微调成本现实检查

按当前 API 定价(2026年),用500个训练示例微调 GPT-4o-mini 的训练成本约为5-15美元,外加推理成本。微调 GPT-4o 的成本大约高出10倍。对于较小模型(在自己的硬件上微调的 Llama 3.1 8B),计算成本很小,但数据准备、训练运行和评估的工程时间很显著。

结合三种技术:最强大的模式

最高性能的生产系统组合使用所有三种技术。这不是过度工程化——而是为每种不同的故障模式使用合适的工具:

  • 提示工程设置任务框架、输出格式和行为约束
  • RAG从您的知识库中提供相关、最新、事实性的上下文
  • 微调确保模型内化了领域惯例,能够生成一致的结构化输出,而无需冗长的指令

医疗文档助手可能:在临床记录风格和医学术语上进行微调,使用 RAG 检索患者记录和相关临床指南,并使用简洁的系统提示为每种记录类型设置特定任务和输出格式。每一层处理不同的问题,它们能够很好地组合在一起。

先构建评估框架

区分成功使用 LLM 的团队和 struggling 团队的一种模式是:他们在构建系统之前先构建评估。如果没有衡量变化是否带来改进的方法,您就无法对提示工程与 RAG 与微调做出良好决策。

至少,构建一个包含50-100个代表性输入/输出对的数据集,这些数据集应代表你的成功标准。通过这个评估集运行每种方法,并明确衡量改进情况。没有这个,你就是在猜测。

# 最小评估工具
import json
from openai import OpenAI

def evaluate_approach(test_cases: list[dict], system_prompt: str) -> dict:
    client = OpenAI()
    results = {"pass": 0, "fail": 0, "details": []}

    for case in test_cases:
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=[
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": case["input"]}
            ]
        )
        output = response.choices[0].message.content
        passed = case["eval_fn"](output)
        results["pass" if passed else "fail"] += 1
        results["details"].append({"input": case["input"], "output": output, "passed": passed})

    results["score"] = results["pass"] / len(test_cases)
    return results

结论

在微调、RAG和提示工程之间的选择,不在于哪种技术最好,而在于你在解决哪种失败模式。知识缺口需要RAG。行为不一致性需要提示工程或微调。复杂的生产系统通常需要三者结合。

成功的团队是那些首先构建评估基础设施、系统性地诊断失败、并为每个特定问题应用正确工具的团队,而不是默认使用他们最熟悉或最近引起最多炒作的技术。

从提示开始。构建评估。当问题是知识时,采用RAG。当问题是提示无法可靠产生的一致性行为时,采用微调。决策框架很简单;执行才是专业知识所在。

By Michael Sun

Founder and Editor-in-Chief of NovVista. Software engineer with hands-on experience in cloud infrastructure, full-stack development, and DevOps. Writes about AI tools, developer workflows, server architecture, and the practical side of technology. Based in China.

Leave a Reply

Your email address will not be published. Required fields are marked *

You missed