RAG vs Fine-tuning vs Prompt Engineering — 决策框架

RAG vs Fine-tuning vs Prompt Engineering — 决策框架
开场
我做过一个 A/B 测试:同一个客服场景,分别用纯 Prompt Engineering、RAG 和 Fine-tuning 三种方案跑了两周,各处理 1,000 条真实工单。结果——Prompt Engineering 方案的客户满意度 82%,RAG 方案 89%,Fine-tuning 方案 91%。但看成本:Prompt Engineering 花了 $38,RAG 花了 $165,Fine-tuning 花了 $2,400(含训练费用)。满意度差了 9 个百分点,成本差了 63 倍。这不是谁好谁差的问题,而是什么时候用什么。
问题背景
"我有私有数据想让 LLM 用上,该怎么做?"——这是我被问得最多的问题。大部分人的第一反应是 Fine-tuning 或者 RAG,但多数情况下,几个 few-shot examples 放在 prompt 里就已经解决了 80% 的问题。
三种方案的本质区别:
- Prompt Engineering:不改模型,只改输入。用 system prompt、few-shot examples 和指令来引导模型行为
- RAG(Retrieval-Augmented Generation):不改模型,改上下文。运行时从外部数据源检索相关信息塞进 prompt
- Fine-tuning:改模型本身。用你的数据训练模型的权重,让它内化特定的行为模式
核心框架:两维决策矩阵
把你的需求放到两个维度上:
X 轴:知识类型——你要模型知道的东西是什么?
- 静态知识(产品手册、公司政策、FAQ)→ 可以放进 prompt 或通过 RAG 检索
- 动态知识(实时价格、库存、新闻)→ 必须用 RAG,因为模型训练数据是过时的
Y 轴:行为模式——你要模型怎么做?
- 通用行为(总结、分类、翻译)→ Prompt Engineering 够了
- 专有行为(特定语气、专业术语、行业规范)→ 可能需要 Fine-tuning
通用行为 专有行为
┌──────────────┬──────────────┐
静态 │ Prompt │ Fine-tuning │
知识 │ Engineering │ 或高质量 │
│ (最便宜) │ Prompt │
├──────────────┼──────────────┤
动态 │ RAG │ RAG + │
知识 │ (必选) │ Fine-tuning │
│ │ (最贵但最强) │
└──────────────┴──────────────┘
方案一:Prompt Engineering
什么时候用:知识量小(< 8K token 能放进 prompt),行为模式可以用指令描述清楚。
from openai import OpenAI
client = OpenAI()
# 方案一:Few-shot Prompt Engineering
# 把知识和行为模式都编码在 prompt 里
SYSTEM_PROMPT = """你是 ArkTop AI 的客服。遵循以下规则:
## 退款政策
- 7 天内无条件退款
- 7-30 天需审核
- 30 天后不退款
- 年度套餐按比例退款
## 回复风格
- 简洁专业,不用敬语堆砌
- 给出明确答案,不说"请稍等"
- 涉及退款金额时必须精确到分
## 示例
用户: 我买了三天想退款
回复: 可以退。7 天内支持无条件退款,我这就帮你处理。退款将在 3 个工作日内到账。
用户: 我的年度套餐用了两个月想退
回复: 年度套餐按剩余月份比例退款。你已用 2 个月,退款金额为年费的 10/12。确认处理吗?"""
def prompt_engineering_approach(user_message: str) -> str:
response = client.chat.completions.create(
model="gpt-4.1",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_message},
],
temperature=0.3,
)
return response.choices[0].message.content
成本:纯 API 调用费。system prompt 约 500 token,假设用 GPT-4.1,每次请求的 prompt 成本约 $0.001。
优点:零基础设施成本,迭代最快(改 prompt 就行),5 分钟上线 缺点:知识容量受上下文窗口限制,prompt 超过 3000 token 后指令遵循能力下降
方案二:RAG
什么时候用:知识量大(几百到几百万条文档),知识会定期更新,需要引用来源。
from openai import OpenAI
from qdrant_client import QdrantClient
openai_client = OpenAI()
qdrant = QdrantClient(url="http://localhost:6333")
async def rag_approach(user_question: str) -> str:
"""RAG:检索相关文档 → 喂给 LLM 生成回答"""
# Step 1: 把用户问题变成 embedding
embedding = openai_client.embeddings.create(
model="text-embedding-3-small", # $0.02/1M tokens
input=user_question
).data[0].embedding
# Step 2: 从向量库检索最相关的文档(top 5)
results = qdrant.query_points(
collection_name="product_docs",
query=embedding,
limit=5,
score_threshold=0.75 # 相似度阈值,低于此值不返回
)
# Step 3: 组装上下文
context_docs = "\n---\n".join([
f"[来源: {r.payload['source']}]\n{r.payload['content']}"
for r in results.points
])
# Step 4: 带上下文生成回答
response = openai_client.chat.completions.create(
model="gpt-4.1",
messages=[
{"role": "system", "content": """基于提供的参考文档回答问题。
规则:
1. 只基于文档内容回答,不要编造
2. 如果文档里没有答案,明确告知
3. 引用来源文档"""},
{"role": "user", "content": f"参考文档:\n{context_docs}\n\n问题:{user_question}"}
],
temperature=0.2, # RAG 用低温度减少幻觉
)
return response.choices[0].message.content
成本拆解(月均 10,000 次查询):
| 组件 | 月成本 |
|---|---|
| Embedding 生成 | $2.00 |
| Vector DB (Qdrant Cloud) | $45.00 |
| LLM 生成 (GPT-4.1) | $120.00 |
| 文档处理和更新 | $15.00 |
| 合计 | $182.00 |
优点:知识量几乎无上限,更新知识不需要重新训练,可以引用来源 缺点:检索质量直接影响生成质量(garbage retrieval = garbage generation),需要维护 vector store,延迟增加 200-500ms
方案三:Fine-tuning
什么时候用:需要模型内化特定的行为模式(语气、格式、推理方式),且这些模式用 prompt 描述不清楚。
from openai import OpenAI
client = OpenAI()
# Step 1: 准备训练数据(JSONL 格式)
# 至少需要 50-100 条高质量样本
training_data = [
{
"messages": [
{"role": "system", "content": "你是 ArkTop AI 客服。"},
{"role": "user", "content": "我的积分怎么没到账?"},
{"role": "assistant", "content": "查了一下,你的积分已经在 3 月 2 日到账了,当前余额 2,450 分。如果和你预期的不一致,告诉我你觉得应该是多少,我帮你核实。"}
]
},
# ... 至少 50 条类似的样本
]
# Step 2: 上传训练文件
file = client.files.create(
file=open("training_data.jsonl", "rb"),
purpose="fine-tune"
)
# Step 3: 启动 Fine-tuning 任务
job = client.fine_tuning.jobs.create(
training_file=file.id,
model="gpt-4.1-mini", # 基础模型选性价比高的
hyperparameters={
"n_epochs": 3, # 训练轮数
"learning_rate_multiplier": 1.8,
}
)
# GPT-4.1-mini fine-tuning: $3.00/1M training tokens
# 100 条样本约 50K tokens → 训练成本约 $0.15
# 但数据准备的人力成本远高于此
# Step 4: 使用 fine-tuned 模型
def finetuned_approach(user_message: str) -> str:
response = client.chat.completions.create(
model=f"ft:gpt-4.1-mini:arktop-ai:customer-service:xxx",
messages=[
{"role": "system", "content": "你是 ArkTop AI 客服。"},
{"role": "user", "content": user_message},
],
temperature=0.3,
)
return response.choices[0].message.content
成本拆解:
| 项目 | 成本 |
|---|---|
| 数据准备(人力,100 条高质量样本) | $500-$2,000 |
| GPT-4.1-mini Fine-tuning(50K tokens x 3 epochs) | $0.45 |
| 推理费用(和基础模型相同) | 和方案一相同 |
| 每次知识更新重新训练 | $500+ (含数据准备) |
优点:推理速度快(不需要检索步骤),模型行为更一致,system prompt 可以很短(省 token) 缺点:数据准备成本高,每次知识更新需要重新训练,可能出现灾难性遗忘
实战经验
决策树
实际项目中我用这个决策树:
1. 知识量能放进 8K token 的 prompt 吗?
├── 能 → Prompt Engineering(先试这个)
│ 效果够好吗?
│ ├── 够 → 用这个,结束
│ └── 不够 → 下一步
│
└── 不能 → 下一步
2. 知识需要频繁更新吗?(每周以上)
├── 是 → RAG(必选)
│ 行为模式也需要定制吗?
│ ├── 是 → RAG + Fine-tuning
│ └── 否 → 纯 RAG
│
└── 否 → 下一步
3. 你有 100+ 条高质量训练样本吗?
├── 有 → Fine-tuning
└── 没有 → 先用 Prompt Engineering,
同时积累数据,够了再 Fine-tune
三种方案的性能对比(真实数据)
我在客服场景跑的对比测试,1,000 条工单/方案:
| 指标 | Prompt Engineering | RAG | Fine-tuning |
|---|---|---|---|
| 准确率 | 78% | 89% | 91% |
| 客户满意度 | 82% | 89% | 91% |
| 平均延迟 | 1.2s | 2.1s | 1.0s |
| 两周总成本 | $38 | $165 | $2,400 |
| 上线时间 | 1 天 | 1 周 | 3 周 |
| 知识更新速度 | 即时 | 分钟级 | 天级 |
混合方案:实际生产的最佳实践
2026 年大多数生产系统用的是混合方案:
async def hybrid_approach(user_question: str) -> str:
"""混合方案:Prompt Engineering + RAG,必要时 Fine-tuning"""
# 层级 1:先检查是否命中 FAQ(纯 prompt 就能答)
faq_match = check_faq_cache(user_question)
if faq_match and faq_match.confidence > 0.9:
return faq_match.answer # 走缓存,零 API 成本
# 层级 2:RAG 检索
docs = await retrieve_relevant_docs(user_question)
# 层级 3:用 fine-tuned 模型生成(如果有的话)
model = "ft:gpt-4.1-mini:arktop:cs:xxx" if FINETUNED_AVAILABLE else "gpt-4.1"
response = await generate_response(model, user_question, docs)
return response
踩过的坑
坑 1:RAG 的检索质量。用了 RAG 后发现效果不好,以为是 LLM 的问题,花了两周调 prompt。后来发现根本原因是 embedding 检索把不相关的文档塞进了上下文。解决方案:把 similarity threshold 从 0.6 调到 0.78,宁缺毋滥。
坑 2:Fine-tuning 的数据质量。第一次 Fine-tuning 用了 200 条自动生成的训练数据,模型学到了"AI 味"的回复风格。后来换成 100 条人工精编的数据,效果好了一个档次。Fine-tuning 的质量取决于数据质量,而不是数据量。
坑 3:过早 Fine-tuning。一个项目刚上线就花了三周做 Fine-tuning,上线后发现业务需求变了,训练数据白准备了。教训:先用 Prompt Engineering 跑三个月,积累真实用户数据,再考虑 Fine-tuning。
总结
三条 takeaway:
- 80% 的需求用 Prompt Engineering 就够了——先试最简单的方案,效果不够再加码。从 $38 跳到 $2,400 之前,确认这个质量差距值这个价
- RAG 和 Fine-tuning 解决的是不同的问题——RAG 解决"知道什么"(knowledge),Fine-tuning 解决"怎么做"(behavior)。搞清楚你的需求是哪一种
- 混合方案是生产环境的标配——FAQ 缓存 + RAG 检索 + Fine-tuned 模型,分层处理。简单问题走缓存(零成本),复杂问题走 RAG(中等成本),核心场景走 Fine-tuning(高质量)
下次有人问你"该用 RAG 还是 Fine-tuning",先反问:"你有多少知识要加进去?这些知识多久更新一次?你有高质量的训练数据吗?"答案自然就出来了。
你在生产中用的是哪种方案?混合比例怎么分的?来一人独角兽俱乐部交流。