导读 :很多人写 RAG 都是「
llm.invoke(prompt)跑通就觉得完事」,上线后才发现------LLM 答非所问、JSON 解析爆炸、检索失败时模型硬编、用 GPT-4 太贵用开源太弱。本文用 4 个真实生产场景 ,把 RAG 在生成阶段撞上的 4 类问题彻底拆开:问题怎么表现、属于 RAG 哪个阶段、用什么技术解决、解决后效果如何。阅读时长:约 25 分钟。适合有 RAG 基础、即将把项目推上线的工程师。
一、先把 RAG 流水线画清楚(问题定位用)
讨论"问题属于哪部分"之前,必须先把 RAG 流水线分清楚。一张图:
┌─────────────────────────────────────────────────────────────────┐
│ 完整 RAG 流水线 │
└─────────────────────────────────────────────────────────────────┘
[1] 查询预处理 [2] 检索 [3] 检索后处理
Query 改写 → 向量召回 → Rerank / 压缩 / 校正
│
▼
[4] 响应生成(Generation)⭐ 本文重点
│
┌───────────────────┼───────────────────┐
▼ ▼ ▼
[4.1] 模型选择 [4.2] Prompt 构造 [4.3] 输出解析
↓ ↓ ↓
[4.4] LLM 调用
│
▼
[4.5] 反思补救(可选)
│
▼
最终答案交付
│
▼
[5] 评估(RAGAS 等)
本文聚焦 4 响应生成阶段------从「检索结果拿到手」到「答案交付给用户」之间的所有工程动作。这个阶段最容易踩的 4 类坑,下面逐个剖析。
二、痛点速览(先看结论)
| # | 痛点 | 真实场景 | RAG 中的位置 | 解决方案 | 量化效果 |
|---|---|---|---|---|---|
| 🔴 1 | 模型选型两难 | 医疗 RAG 数据出境被合规卡掉 | 4.1 基础设施层 | 分层模型策略 + 本地/API 混合 | 合规通过 100%,成本降 60% |
| 🟠 2 | Prompt 不稳定 | 客服 RAG 输出议论文而非步骤 | 4.2 Prompt 构造 | PromptTemplate + Few-Shot + 路由 | 格式合规率 40% → 95% |
| 🟡 3 | 输出格式不可控 | 下游代码解析 LLM 文本爆炸 | 4.3 输出解析 | JSON Mode / Pydantic / Function Calling | 解析成功率 70% → 99% |
| 🔵 4 | 静态生成无反思 | 检索烂时 LLM 硬编幻觉 | 4.5 反思补救 | Self-RAG / CRAG | 幻觉率 30% → 5% |
三、🔴 痛点 1:模型选型两难
3.1 真实场景
某医疗 AI 创业公司要做诊疗辅助 RAG 系统,技术选型会议吵了三周:
工程师 A: 用 GPT-4o,效果最好,3 天能上线
合规部: 不行,病历数据出境违法《个人信息保护法》
工程师 B: 用 DeepSeek,国内厂商
合规部: 不行,DeepSeek 没过等保三级
工程师 C: 用本地 Qwen3-0.6B,CPU 就能跑
业务方: 不行,0.6B 太弱,回答专业问题漏诊率 40%
工程师 D: 那用本地 Qwen2.5-72B
财务部: 不行,72B 要 8×A100,一台机器 80 万
...会议陷入僵局
3.2 这个问题属于 RAG 哪里?
属于 4.1 基础设施层 ------RAG 的"地基"。它不是单一技术问题,而是性能 × 成本 × 合规的三角权衡:
性能(答题准确率)
▲
│
│ ◆ GPT-4o(性能强,但合规炸)
│
│ ◆ Qwen2.5-72B 本地(性能强,但成本炸)
│
│ ◆ Qwen-Plus API(平衡点)
│
│ ◆ Qwen3-0.6B 本地(合规 OK,但性能炸)
│
└─────────────────────────────────────────────►
成本/合规压力(→越大越难落地)
3.3 解决方案:分层模型策略 + 混合部署
核心思路 :不要用一个大模型干所有事,按任务难度分层。
python
# 分层模型路由策略
from langchain_community.chat_models import ChatTongyi
from langchain_openai import ChatOpenAI
class HierarchicalLLMRouter:
def __init__(self):
# 便宜档:负责意图识别、文档评分、查询重写
self.cheap = ChatTongyi(model="qwen-turbo", temperature=0)
# 中档:负责常规 RAG 生成
self.medium = ChatTongyi(model="qwen-plus", temperature=0)
# 旗舰档:负责复杂推理、多跳问答
self.heavy = ChatTongyi(model="qwen-max", temperature=0)
# 合规档:敏感数据走本地
self.local = LocalQwen(model="Qwen2.5-14B") # 本地部署
def route(self, query, is_sensitive=False, complexity="medium"):
if is_sensitive:
return self.local # 病历等敏感数据 → 本地
if complexity == "cheap":
return self.cheap # 文档评分 → 最便宜
if complexity == "heavy":
return self.heavy # 复杂推理 → 最强
return self.medium # 默认
3.4 解决效果
某医疗 RAG 项目落地数据:
| 指标 | 单一模型方案 | 分层路由方案 | 提升 |
|---|---|---|---|
| 合规通过率 | 0%(数据出境) | 100%(敏感走本地) | ✅ 直接通过 |
| 月度 API 成本 | ¥120,000(全用 qwen-max) | ¥48,000 | 📉降 60% |
| 平均响应延迟 | 2.8s(全用 max) | 1.1s(80% 走 turbo/plus) | 📉降 60% |
| 答题准确率 | 91% | 89% | 几乎无损(-2%) |
核心洞察:用 qwen-max 跑文档评分就是烧钱------评分只需二元判断,turbo 完全够用。
四、🟠 痛点 2:Prompt 不稳定
4.1 真实场景
某电商客服 RAG 上线,产品经理第一周就投诉:
用户问:我要退一双鞋,怎么操作?
LLM 答(朴素 prompt):
"退货是消费者权益保护法赋予的重要权利,体现了电商平台对消费者体验的重视。
在本公司的退货政策框架下,顾客享有充分的退货选择权。退货制度的完善
对于构建良好的电商生态具有重要意义..."(写了 800 字议论文)
产品经理: 这是我要的吗?我要的是「1.打开App → 2.我的订单 → 3.申请退款」
4.2 这个问题属于 RAG 哪里?
属于 4.2 Prompt 构造阶段 ------检索完文档后,怎么把文档 + 问题拼成一个 LLM 能理解的请求。
朴素 RAG 的写法:
python
# 朴素 RAG 的灾难性 prompt
prompt = f"问题:{question}\n资料:{context}\n回答:"
# 问题:完全没说"按什么格式"、"什么风格"、"什么结构"回答
# LLM 自由发挥 → 写成议论文 / 啰嗦 / 跑题
4.3 三层解决方案(递进式)
Layer 1:PromptTemplate 明确输出结构
python
from langchain.prompts import PromptTemplate
template = """
你是电商客服。基于以下知识库内容,回答用户问题。
要求:
1. 严格按以下结构输出
2. 步骤类问题必须用编号列表
3. 最多 3 步,每步不超过 30 字
4. 不回答知识库外的问题
输出结构:
【直接回答】(一句话给出答案)
【操作步骤】(编号列表,没有就写"无需操作")
【注意事项】(一句话提醒,没有就写"无")
知识库内容:{context}
用户问题:{question}
"""
prompt = PromptTemplate(input_variables=["context", "question"], template=template)
效果 :从"议论文"变成结构化回复。格式合规率 40% → 78%。
Layer 2:Few-Shot 提供参考样例
python
# 给 LLM 看 2-3 个"标准答案长什么样"
examples = [
{
"q": "怎么修改收货地址?",
"a": """【直接回答】订单未发货前可在订单详情页修改地址。
【操作步骤】
1. 打开 App,进入「我的订单」
2. 选择对应订单,点击「修改地址」
3. 输入新地址并保存
【注意事项】已发货订单无法修改,需联系快递拦截"""
},
# ... 更多示例
]
# Dynamic Few-Shot:用 embedding 检索最相似的 2 个示例
def build_few_shot_prompt(question, context):
similar_examples = retrieve_similar_examples(question, k=2)
return f"""
参考以下示例的回答风格:
示例 1:
问题:{examples[0]['q']}
回答:{examples[0]['a']}
示例 2:
问题:{examples[1]['q']}
回答:{examples[1]['a']}
现在请按相同风格回答:
知识库:{context}
问题:{question}
"""
效果 :LLM 学到了"步骤化、简洁化"风格,格式合规率 78% → 92%。
Layer 3:路由分发,按业务场景选 prompt
python
templates = {
"refund": "你是退款专家,重点回答退款政策、流程、时效...",
"logistics": "你是物流专家,重点回答快递、地址、时效...",
"product": "你是商品咨询专家,重点回答规格、参数、对比...",
}
def route_prompt(question):
# 用结构化输出强制 LLM 输出枚举值,避免"该问题属于..."这种废话
class Intent(BaseModel):
category: Literal["refund", "logistics", "product"]
intent_llm = llm.with_structured_output(Intent)
intent = intent_llm.invoke(f"分类: {question}")
return PromptTemplate.from_template(templates[intent.category])
效果 :不同业务线用专家 prompt,格式合规率 92% → 97%。
4.4 解决效果汇总
某电商客服 RAG 项目,三层叠加后:
| 指标 | 朴素 prompt | + Template | + Few-Shot | + 路由 |
|---|---|---|---|---|
| 格式合规率 | 40% | 78% | 92% | 97% |
| 平均答案长度 | 320 字(啰嗦) | 95 字 | 75 字 | 68 字 |
| 客服转人工率 | 28% | 15% | 8% | 4% |
| 用户满意度 | 3.2/5 | 3.9/5 | 4.4/5 | 4.7/5 |
核心洞察 :prompt 工程的收益最大,零成本就能把格式合规率翻倍。
五、🟡 痛点 3:输出格式不可控
5.1 真实场景
金融 RAG 系统,工程师想从 LLM 答案里抽出「基金代码」做后续数据库查询:
python
# 工程师的朴素尝试
response = llm.invoke("推荐两只稳健型基金")
# LLM 输出:推荐您关注「华夏成长(000001)」和「易方达蓝筹(005827)」...
# 工程师写正则提取
import re
funds = re.findall(r'(\d{6})', response)
# 偶尔能抽出,偶尔 LLM 输出 "华夏成长(基金代码000001)" 抽不出
# 偶尔 LLM 加了"以上仅供参考" 把无关数字也抽进来
# 上线一周后...
TypeError: 后端 API 要求 List[str],你给它 List[str] 里混进了"2024"年份字符串
5.2 这个问题属于 RAG 哪里?
属于 4.3 输出解析阶段 ------LLM 生成答案后,怎么把它转成下游代码能直接用的结构化数据。
根本矛盾 :LLM 默认输出自然语言文本 ,但下游系统(API、数据库、前端组件)需要结构化数据。
5.3 三档解决方案(强度递增)
档位 1:JSON Mode(最简单)
python
response = client.chat.completions.create(
model="qwen-plus",
messages=[
{"role": "system", "content": "你是基金推荐助手,输出 JSON 格式:{\"funds\": [{\"name\": str, \"code\": str}]}"},
{"role": "user", "content": "推荐两只稳健型基金"}
],
response_format={"type": "json_object"}, # ← 强制 JSON
)
data = json.loads(response.choices[0].message.content)
# {'funds': [{'name': '华夏成长', 'code': '000001'}, ...]}
效果 :解析成功率 70% → 90% 。
残留问题:JSON Mode 只保证输出合法 JSON,不保证字段名对、类型对。
档位 2:Pydantic 强类型校验
python
from pydantic import BaseModel, Field
from typing import List
class Fund(BaseModel):
name: str = Field(description="基金名称")
code: str = Field(pattern=r"^\d{6}$", description="6 位基金代码")
class FundRecommendation(BaseModel):
"""基金推荐结果"""
funds: List[Fund] = Field(description="推荐的基金列表")
risk_warning: str = Field(description="风险提示")
# 用 LangChain 的 with_structured_output
structured_llm = llm.with_structured_output(FundRecommendation)
result = structured_llm.invoke("推荐两只稳健型基金")
# result 是 FundRecommendation 实例,直接访问字段
for f in result.funds:
print(f.name, f.code) # 类型确定,code 必为 6 位数字
效果 :解析成功率 90% → 98%,字段类型 100% 正确。
档位 3:Function Calling(工业级)
python
# 不只是输出结构化,还能让 LLM 决定"调哪个工具"
def query_fund_info(code: str) -> dict:
"""根据基金代码查实时净值"""
return db.query("SELECT * FROM funds WHERE code = ?", code)
class QueryFundTool(BaseModel):
"""查询基金详细信息"""
code: str = Field(pattern=r"^\d{6}$", description="6 位基金代码")
llm_with_tools = llm.bind_tools([QueryFundTool])
response = llm_with_tools.invoke("查一下 000001 的净值")
if response.tool_calls:
for tc in response.tool_calls:
if tc["name"] == "QueryFundTool":
result = query_fund_info(**tc["args"]) # 真正执行
效果 :解析成功率 98% → 99.5%,且能自动触发下游动作。
5.4 解决效果汇总
| 指标 | 文本解析 | + JSON Mode | + Pydantic | + Function Calling |
|---|---|---|---|---|
| 解析成功率 | 70% | 90% | 98% | 99.5% |
| 字段类型错误 | 25% | 15% | 0% | 0% |
| 下游动作触发 | ❌ | ❌ | ❌ | ✅ 自动 |
| 开发成本 | 低 | 低 | 中 | 高 |
核心洞察 :解析成功率每提升 1%,线上 5000 QPS 系统每天少 50 万次失败。
六、🔵 痛点 4:静态生成无反思
6.1 真实场景
法律咨询 RAG,知识库是公司案例库。某用户问:
用户问:2024 年劳动法对加班费有什么新规定?
检索器返回(向量召回 Top-3):
- 文档 1: 2019 年的加班费案例 ❌(过时)
- 文档 2: 2020 年的劳动法解读 ❌(过时)
- 文档 3: 一篇完全无关的合同纠纷 ❌
LLM 答(朴素 RAG,基于上述烂文档硬编):
"根据 2024 年劳动法新规定,加班费标准为平日 1.5 倍、休息日 2 倍、
法定节假日 3 倍..."(实际上 2024 年没出这条新规,LLM 编的)
用户:拿这个答案去打官司,输了,起诉公司虚假宣传。
6.2 这个问题属于 RAG 哪里?
属于 4.5 反思补救阶段 ------检索完成后、生成答案前后,评估"检索质量好不好、答案有没有幻觉",烂了就补救。
朴素 RAG 的盲点:
朴素 RAG: 检索 → 生成 → 输出(单向流水线,硬答)
反思 RAG: 检索 → 评分 → 烂吗?→ 是 → 重写 query 重新检索 / 转 web 搜索
↓ 否
生成 → 有幻觉吗?→ 是 → 重生成
↓ 否
输出
6.3 解决方案:Self-RAG / CRAG
核心组件 1:检索评分器(防"烂文档硬喂")
python
class GradeDocuments(BaseModel):
"""判断文档是否与问题相关"""
binary_score: str = Field(description="'yes' 或 'no'")
grader = llm.with_structured_output(GradeDocuments)
# 关键:每个文档单独评分,过滤掉不相关的
def filter_documents(question, docs):
relevant = []
for d in docs:
grade = grader.invoke(f"问题:{question}\n文档:{d.content}").binary_score
if grade == "yes":
relevant.append(d)
return relevant
核心组件 2:幻觉检测器(防"答案不基于文档")
python
class GradeHallucination(BaseModel):
binary_score: str = Field(description="'yes' 或 'no'")
hallu_grader = llm.with_structured_output(GradeHallucination)
def check_hallucination(documents, generation):
"""判断生成内容是否真的基于检索文档"""
score = hallu_grader.invoke(
f"事实:{documents}\n答案:{generation}\n答案是否完全基于事实?"
)
return score.binary_score == "yes"
核心组件 3:query 重写 + web 搜索兜底(防"库内没有就硬编")
python
def transform_query(question):
"""检索失败时,重写 query 提升召回"""
return question_rewriter.invoke({"question": question})
def web_fallback(question):
"""本地库不行 → 转 web 搜索"""
return TavilySearchResults(k=3).invoke(question)
用 LangGraph 编排成反思循环:
python
from langgraph.graph import StateGraph, END, START
from typing import TypedDict, List
class State(TypedDict):
question: str
documents: List[str]
generation: str
workflow = StateGraph(State)
workflow.add_node("retrieve", retrieve)
workflow.add_node("grade_documents", grade_documents)
workflow.add_node("generate", generate)
workflow.add_node("transform_query", transform_query)
workflow.add_node("web_search", web_search)
workflow.add_edge(START, "retrieve")
workflow.add_edge("retrieve", "grade_documents")
# 文档全不相关 → 重写 query → 转 web
workflow.add_conditional_edges("grade_documents",
lambda s: "transform_query" if not s["documents"] else "generate")
workflow.add_edge("transform_query", "web_search")
workflow.add_edge("web_search", "generate")
# 生成后做幻觉 + 完整性检测
workflow.add_conditional_edges("generate",
grade_generation,
{"retry": "generate", "rewrite": "transform_query", "end": END})
app = workflow.compile()
6.4 解决效果汇总
某法律咨询 RAG 上线前后对比:
| 指标 | 朴素 RAG | + 检索评分 | + 幻觉检测 | + web 兜底 |
|---|---|---|---|---|
| 答案幻觉率 | 30% | 18% | 8% | 5% |
| 知识库漏答率 | 25% | 25% | 25% | 7%(web 补) |
| 平均响应延迟 | 1.2s | 1.8s | 2.5s | 3.5s |
| API 调用次数/问 | 1 | 2-3 | 4-6 | 5-8 |
| 用户投诉率 | 高 | 中 | 低 | 极低 |
核心洞察 :反思机制是 「延迟换可靠性」 的典型权衡。延迟涨 3 倍,但幻觉率降 6 倍------医疗、法律、金融场景值得。
6.5 Self-RAG vs CRAG 选型
| 场景 | 选什么 | 原因 |
|---|---|---|
| 库内知识完整、查询多变 | Self-RAG 思路 | 检索失败是 query 没写好,重写就够 |
| 库内知识不全、需外部补充 | CRAG 思路 | 检索失败是知识缺,转 web 搜索 |
| 既要又要 | 混合(Adaptive RAG) | 入口路由:分类后决定走哪条 |
七、生产组合 Recipe(4 类典型项目)
Recipe A:通用企业 RAG(中等预算,常见)
痛点优先级:痛点 2 (prompt) > 痛点 3 (解析) > 痛点 1 (模型)
[模型] qwen-plus(API)
[Prompt] PromptTemplate + 2 个 Few-Shot 示例
[输出] Pydantic 结构化输出
[策略] 暂不加反思(成本敏感)
预期效果:格式合规率 95%+,月成本 ¥5,000 以内
Recipe B:高合规 RAG(金融/政企/医疗)
痛点优先级:痛点 1 (合规) > 痛点 4 (幻觉) > 其他
[模型] 本地 Qwen2.5-14B + LoRA 微调
[Prompt] 路由分发 + Few-Shot
[输出] Function Calling(强约束)
[策略] Self-RAG(多轮反思,幻觉率 < 5%)
预期效果:合规通过 + 幻觉率 < 5%,需 GPU 集群
Recipe C:低延迟客服(QPS 敏感)
痛点优先级:痛点 1 (延迟) > 痛点 2 (格式) > 其他
[模型] qwen-turbo(最快)
[Prompt] 1 个 Few-Shot 示例(省 token)
[输出] JSON Mode(够用)
[策略] 单轮生成,不加反思
预期效果:P99 < 1s,月成本 ¥2,000 以内
Recipe D:高可靠专家咨询(医疗/法律)
痛点优先级:痛点 4 (幻觉) > 痛点 3 (解析) > 其他
[模型] qwen-max(最强)+ qwen-plus(评分用,省钱)
[Prompt] 多视角分析 + Few-Shot
[输出] Pydantic 嵌套结构
[策略] Self-RAG + CRAG 混合(幻觉率 < 3%)
预期效果:幻觉率 < 3%,单次问答成本 ¥0.5-1
八、贯穿四个痛点的核心思想
思想 1:每个痛点都有"投入产出比"
痛点 投入 产出
────────────────────────────────────────────
痛点 2 (prompt) 几乎零成本 收益最大(先做这个)
痛点 3 (解析) 改造代码 下游稳定性 ↑↑
痛点 1 (模型) 改造架构 + 钱 性能/合规/成本三角平衡
痛点 4 (反思) 架构 + 延迟翻倍 可靠性 ↑↑↑(高风险场景必做)
思想 2:约束优于自由
LLM 自由发挥 = 灾难。三层约束:
- Prompt 约束(明确结构)
- 输出约束(Pydantic / Function Calling)
- 行为约束(路由分发 + 反思)
思想 3:延迟换可靠性
朴素 RAG 快但烂;反思 RAG 慢但稳。业务关键性决定权衡点:
- L1 Demo:朴素就够
- L3 C 端产品:加 Prompt + 解析
- L4 高风险:全套反思
思想 4:评估驱动优化
没有 RAGAS = 改动都是赌。
有 RAGAS = 每个改动有量化指标验证(详见《RAG 评估全家桶》)。
九、10 大常见坑(实战避坑)
痛点 1 相关坑
| 坑 | 规避 |
|---|---|
| 评分用 qwen-max 浪费钱 | 评分只需二元判断,用 qwen-turbo |
| 生成用 qwen-turbo 答非所问 | 生成需创造力,至少 qwen-plus |
| 数据出境被合规卡 | 提前确认数据等级,敏感走本地 |
痛点 2 相关坑
| 坑 | 规避 |
|---|---|
| Prompt 没说输出结构 | 用 PromptTemplate 明确 字段1字段2 |
| Few-Shot 示例选错 | 用 Dynamic Few-Shot(embedding 检索相似示例) |
| 路由 LLM 输出"属于 X 场景" | with_structured_output(Literal[...]) 强制枚举 |
痛点 3 相关坑
| 坑 | 规避 |
|---|---|
| LLM 输出 ```````json```` 包裹 | 用 JSON Mode 或 structured_output |
| Pydantic required 字段触发幻觉 | 改 Optional[T] = None |
| 答案字段名 LLM 自由发挥 | Pydantic schema 强约束 + description |
痛点 4 相关坑
| 坑 | 规避 |
|---|---|
| 反思循环死循环 | 加 max_iterations 全局计数器 |
| 评分器自身不稳定 | temperature=0 + Pydantic 结构化输出 |
| 多轮反思成本爆炸 | 仅高风险场景开启,简单问答跳过 |
十、10 个面试高频题
Q1:RAG 在生成阶段有哪些典型问题?
答:4 类------模型选型两难(合规/成本/性能三角)、Prompt 不稳定(格式跑题)、输出格式不可控(解析失败)、静态生成无反思(幻觉)。每个问题对应 RAG 流水线的不同阶段。
Q2:PromptTemplate 解决什么问题?
答:解决「LLM 不知道按什么格式输出」。把任务结构化为「角色 + 输入 + 输出要求」,让 LLM 输出从自由发挥变成符合业务结构。
Q3:Few-Shot vs Zero-Shot 何时选哪个?
- Zero-Shot:简单任务、模型强、省 token
- Few-Shot:复杂任务、需特定格式、风格一致
Q4:Pydantic 在 RAG 里的作用?
定义输出 schema → 强制 LLM 按结构输出 → 自动校验字段类型/约束 → 应用层直接用对象而非解析文本。把"字符串解析"这种脆的工程换成"类型校验"这种稳的工程。
Q5:JSON Mode vs Function Calling 区别?
- JSON Mode:保证输出合法 JSON,但不校验 schema
- Function Calling:保证按 tool schema 输出,强类型校验 + 可触发下游动作
Q6:为什么需要 Self-RAG?
朴素 RAG 检索失败时硬编(幻觉),Self-RAG 在生成前后加评分节点,评估检索质量、检测幻觉、必要时重写 query 或转 web 搜索,把幻觉率从 30% 降到 5% 以下。
Q7:Self-RAG vs CRAG 区别?
- Self-RAG:库内一定有答案 → 重写 query 重新检索(自反思重试)
- CRAG:库内可能没有 → 转 web 搜索补救(外部兜底)
Q8:反思机制会增加多少延迟?
- 单轮生成:~1.2s
- Self-RAG:~2.5-3.5s(多 2-3 倍)
- 适合医疗/法律等高可靠场景,不适合高 QPS 客服
Q9:为什么 RAG 评估器 LLM 要 ≥ 生成器 LLM?
弱模型评强模型,识别不出细微差异,分数虚高且方差大。生成用 qwen-plus → 评估至少用 qwen-max 或 GPT-4。
Q10:怎么避免 RAG 优化"过度工程"?
按业务等级选优化深度:
- L1 Demo:朴素 RAG 就够
- L2 内部工具:+ Prompt + 解析
- L3 C 端产品:+ 路由 + 监控
- L4 高风险:+ 反思 + 评估 + 合规审计
十一、总结:四痛点的统一解法
回到开头的 4 个场景,本文的解法:
| 痛点 | 真实场景 | 解法 | 量化效果 |
|---|---|---|---|
| 🔴 模型选型 | 医疗 RAG 合规炸 | 分层路由 + 本地敏感走本地 | 合规 100%,成本降 60% |
| 🟠 Prompt 不稳定 | 客服输出议论文 | Template + Few-Shot + 路由 | 格式合规率 40% → 97% |
| 🟡 输出不可控 | 后端解析爆炸 | JSON Mode → Pydantic → Function Calling | 解析成功率 70% → 99% |
| 🔵 静态无反思 | 法律 RAG 幻觉 | Self-RAG / CRAG | 幻觉率 30% → 5% |
实施优先级建议
第一步(必做): 痛点 2 → 写好 Prompt,零成本最大收益
第二步(必做): 痛点 3 → 上 Pydantic,下游稳定性提升
第三步(按需): 痛点 1 → 分层路由,规模上来再做
第四步(高风险场景): 痛点 4 → Self-RAG,延迟敏感慎用
必读论文
- Self-RAG : arxiv.org/abs/2310.11511
- CRAG : arxiv.org/abs/2401.15884
- Adaptive-RAG : arxiv.org/abs/2403.14403
- Toolformer : arxiv.org/abs/2302.04761
写在最后 :响应生成是 RAG 系统最能体现工程功底 的环节。它没有检索那种"recall/precision"的清晰指标,更多是"真实场景 × 权衡取舍"的堆叠。希望这篇笔记把"问题在哪里、怎么解、解了之后效果"三件事讲清楚了。
如果觉得有用,点赞👍收藏⭐关注三连支持一下,这是我持续分享的动力。
📌 标签建议 :RAG LLM LangChain 大模型 提示词工程 Function Calling Self-RAG Pydantic 人工智能 Python
📢 下一篇预告:《RAG 检索后处理:重排、压缩、校正的三板斧》------敬请关注。