共计 2631 个字符,预计需要花费 7 分钟才能阅读完成。
大模型的固有缺陷
大语言模型(LLM, Large Language Model)存在三个关键限制:
1. 事实性错误(Hallucination):模型可能生成看似合理但实际错误的信息
2. 知识滞后性(Knowledge Cutoff):训练数据的时间截断导致无法获取新知识
3. 领域适应性差:通用模型在专业领域表现不稳定

微调 vs RAG 技术路线对比
| 维度 | 微调(Fine-tuning) | RAG(Retrieval-Augmented Generation) |
|---|---|---|
| 知识更新成本 | 需要重新训练模型,成本高 | 仅更新知识库,成本低 |
| 实时性 | 滞后 | 近乎实时 |
| 可解释性 | 黑箱 | 检索结果可溯源 |
| 领域适应性 | 需要大量标注数据 | 灵活切换知识库 |
| 硬件需求 | 需要 GPU 资源 | 主要依赖检索系统 |
RAG 核心组件详解
检索器 (Retriever) 设计
向量数据库选型建议:
- FAISS:Facebook 开源的轻量级方案,适合中小规模数据(<100 万条)
- Pinecone:全托管服务,支持自动扩缩容,适合生产环境
- Weaviate:支持混合搜索(向量 + 关键词),内置数据预处理管道
- Milvus:分布式架构,适合超大规模向量数据(>1 亿条)
关键指标对比(测试环境:AWS c5.2xlarge):
| 数据库 | 查询延迟(ms) | 索引构建时间 | 内存占用 |
|---|---|---|---|
| FAISS | 12 | 2 小时 | 8GB |
| Pinecone | 35 | 无需 | 托管 |
| Milvus | 25 | 6 小时 | 32GB |
生成器 (Generator) 优化
提示工程 (Prompt Engineering) 技巧:
-
上下文窗口管理:
# 限制检索结果总长度不超过模型上下文窗口的 50% max_context_length = model.config.max_position_embeddings // 2 -
指令模板设计:
请基于以下知识回答问题:{context} --- 问题:{question} 要求:若知识不相关请回答 "不知道" -
结果验证机制:
# 检查生成内容是否包含 "根据文档" 等引用短语 def has_citation(text): return any(phrase in text for phrase in ["根据文档", "参考材料"])
完整实现示例(LangChain+FAISS)
from langchain.document_loaders import WebBaseLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import FAISS
from langchain.chains import RetrievalQA
from langchain.llms import OpenAI
# 1. 文档分块(Chunking)
loader = WebBaseLoader(["https://example.com/tech-doc"])
docs = loader.load()
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # 每个块 500 字符
chunk_overlap=50, # 块间重叠 50 字符
length_function=len
)
splits = text_splitter.split_documents(docs)
# 2. 向量化与索引
embedding = HuggingFaceEmbeddings(model_name="paraphrase-multilingual-MiniLM-L12-v2")
db = FAISS.from_documents(splits, embedding)
# 3. 重排序(Re-ranking)
retriever = db.as_retriever(
search_type="mmr", # Maximal Marginal Relevance
search_kwargs={
"k": 10, # 初始检索 10 条
"fetch_k": 20 # 重排序候选池大小
}
)
# 4. 问答链构建
qa_chain = RetrievalQA.from_chain_type(llm=OpenAI(temperature=0),
chain_type="stuff",
retriever=retriever,
return_source_documents=True
)
# 5. 执行查询
result = qa_chain("什么是 RAG 技术?")
print(result["result"])
print("来源:", result["source_documents"][0].metadata["source"])
生产环境注意事项
敏感数据权限控制
-
分级访问:
# 基于用户角色过滤检索结果 def filter_by_role(docs, user_role): return [doc for doc in docs if doc.metadata["access_level"] <= user_role] -
审计日志:
# 记录所有检索操作 def log_query(user_id, query, accessed_docs): audit_log.append({"timestamp": datetime.now(), "user": user_id, "query": query, "docs": [doc.metadata["id"] for doc in accessed_docs] })
冷启动知识库构建
- 种子数据采集:
- 从官方文档、产品手册等结构化数据入手
-
使用爬虫抓取行业白皮书(注意 robots.txt 限制)
-
质量验证流程:
# 自动检测低质量文档 def is_low_quality(text): return len(text) < 100 or "点击查看详情" in text -
增量更新机制:
# 每周自动更新知识库 def scheduled_update(): new_docs = scrape_news() db.add_documents(clean_docs(new_docs))
开放性问题
- 当检索到相互矛盾的证据时,RAG 系统应该如何裁决?
- 如何评估 RAG 系统中检索器与生成器的各自贡献度?
- 在需要复杂推理(如数学证明)的任务中,RAG 的边界在哪里?
通过本文的实践示例可以看到,RAG 技术有效弥补了大语言模型的关键缺陷。但任何技术都有其适用边界,需要根据具体场景进行架构设计。期待读者在实践中探索更优解决方案。
正文完
发表至: 未分类
近一天内
