两大应用范式
大语言模型有两种主要的应用范式:
- RAG(检索增强生成):让模型"查资料"后回答
- Agent 系统:让模型"使用工具"完成任务
RAG 架构
核心思想
传统 LLM:
用户问题 → 模型 → 回答 (可能过时/幻觉)
RAG:
用户问题 → 检索相关文档 → 模型 + 文档 → 回答 (准确/有据)
完整流程
RAG Pipeline:
┌─────────────────────────────────────┐
│ 索引阶段 │
│ 文档 → 分块 → 向量化 → 存储 │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ 检索阶段 │
│ 问题 → 向量化 → 相似度搜索 → Top-K │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ 生成阶段 │
│ 问题 + 检索结果 → LLM → 回答 │
└─────────────────────────────────────┘
文档分块策略
# 固定大小分块
def fixed_size_chunk(text, chunk_size=512, overlap=50):
chunks = []
for i in range(0, len(text), chunk_size - overlap):
chunks.append(text[i:i + chunk_size])
return chunks
# 语义分块
def semantic_chunk(text, model):
sentences = split_sentences(text)
embeddings = model.encode(sentences)
# 基于语义相似度分块
chunks = []
current_chunk = [sentences[0]]
for i in range(1, len(sentences)):
similarity = cosine_similarity(
embeddings[i], embeddings[i-1]
)
if similarity < 0.5: # 阈值
chunks.append(' '.join(current_chunk))
current_chunk = [sentences[i]]
else:
current_chunk.append(sentences[i])
return chunks
向量数据库
# Chroma (轻量级)
import chromadb
client = chromadb.Client()
collection = client.create_collection("docs")
# 添加文档
collection.add(
documents=["doc1", "doc2"],
ids=["id1", "id2"]
)
# 查询
results = collection.query(
query_texts=["query"],
n_results=5
)
# Pinecone (云服务)
import pinecone
pinecone.init(api_key="xxx")
index = pinecone.Index("my-index")
# 向量化并存储
vectors = model.encode(documents)
index.upsert(vectors)
# 查询
results = index.query(vector=query_embedding, top_k=5)
检索策略
1. 稠密检索 (Dense Retrieval):
- 使用向量相似度(余弦、点积)
- 捕捉语义相似性
- 例: "猫" 和 "小猫" 相似度高
2. 稀疏检索 (Sparse Retrieval):
- 使用 BM25 等关键词匹配
- 精确匹配关键词
- 例: 搜索 "Python" 精确匹配
3. 混合检索 (Hybrid Retrieval):
- 结合稠密和稀疏检索
- 取长补短,效果最好
- 例: 语义搜索 + 关键词过滤
重排序
# 检索后重排序
def rerank(query, documents, model):
# 计算 query-document 相关性分数
scores = []
for doc in documents:
score = model.score(query, doc)
scores.append(score)
# 按分数排序
ranked = sorted(
zip(documents, scores),
key=lambda x: x[1],
reverse=True
)
return ranked
# 交叉编码器重排序
from sentence_transformers import CrossEncoder
reranker = CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2')
scores = reranker.predict([(query, doc) for doc in documents])
Agent 系统
核心思想
Agent = LLM + 工具 + 记忆 + 规划
用户任务 → Agent 规划 → 选择工具 → 执行 → 观察 → 调整 → 完成
架构设计
Agent 系统架构:
┌─────────────────────────────────────┐
│ 规划模块 │
│ 任务分解、策略选择、反思调整 │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ 执行模块 │
│ 工具调用、代码执行、API 调用 │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ 记忆模块 │
│ 短期记忆、长期记忆、工作记忆 │
└─────────────────────────────────────┘
ReAct 框架
ReAct (Reasoning + Acting):
思考 (Thought): 分析当前状态,决定下一步
行动 (Action): 选择并执行工具
观察 (Observation): 获取工具返回结果
循环直到完成
示例:
Thought: 我需要查找今天的天气
Action: search_weather("北京")
Observation: 北京今天晴,25°C
Thought: 我已经获取了天气信息,可以回答用户
Action: respond("北京今天晴,25°C")
工具调用
# LangChain Agent 示例
from langchain.agents import initialize_agent
from langchain.tools import Tool
from langchain.llms import OpenAI
# 定义工具
tools = [
Tool(
name="Search",
func=search_web,
description="搜索网页信息"
),
Tool(
name="Calculator",
func=calculate,
description="数学计算"
)
]
# 创建 Agent
llm = OpenAI(temperature=0)
agent = initialize_agent(
tools, llm, agent="react-docstore"
)
# 执行任务
result = agent.run("今天北京的天气怎么样?")
多 Agent 协作
# AutoGen 多 Agent 示例
from autogen import AssistantAgent, UserProxyAgent
# 创建 Agent
assistant = AssistantAgent(
name="assistant",
llm_config={"model": "gpt-4"}
)
user_proxy = UserProxyAgent(
name="user_proxy",
human_input_mode="NEVER"
)
# 注册工具
user_proxy.register_for_execution(
name="search",
func=search_web
)
# 对话
user_proxy.initiate_chat(
assistant,
message="帮我分析这个数据集的趋势"
)
RAG vs Agent 对比
| 特性 | RAG | Agent |
|---|---|---|
| 核心能力 | 检索 + 生成 | 规划 + 工具使用 |
| 数据来源 | 预定义文档库 | 实时工具调用 |
| 可控性 | 高(基于文档) | 中(依赖工具) |
| 延迟 | 低(一次检索) | 高(多轮交互) |
| 适用场景 | 知识问答、文档检索 | 复杂任务、动态决策 |
混合架构
RAG + Agent:
1. Agent 规划阶段:
- 分析任务需要什么信息
- 决定是否需要检索
2. RAG 检索阶段:
- 检索相关文档
- 返回给 Agent
3. Agent 执行阶段:
- 基于检索结果决策
- 可能调用其他工具
4. 迭代优化:
- 如果信息不足,再次检索
- 直到任务完成
面试常见问题
RAG 如何处理幻觉问题?
- 检索真实文档作为依据
- 要求模型引用来源
- 后处理验证事实性
Agent 如何处理工具调用失败?
- 重试机制
- 备选工具
- 反思和调整策略
如何评估 RAG 系统?
- 检索指标: Recall@K, MRR
- 生成指标: BLEU, ROUGE
- 端到端: 人工评估
多 Agent 协作的挑战?
- 通信开销
- 决策一致性
- 错误传播
实战: 搭建 RAG 系统
from langchain.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings
# 加载文档
loader = TextLoader("docs.txt")
documents = loader.load()
# 分块
splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50
)
chunks = splitter.split_documents(documents)
# 向量化存储
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(
chunks, embeddings
)
# 检索
query = "什么是 Transformer?"
results = vectorstore.similarity_search(query, k=3)