第13章 检索增强提示工程

"让 AI 的回答有根可循,而非凭空杜撰。"

大语言模型的知识受限于训练数据截止日期,且存在幻觉风险。检索增强生成(Retrieval-Augmented Generation, RAG)通过将外部知识库与语言模型相结合,让 AI 能够基于真实、鲜活的文档内容生成回答,从根本上提升了回答的准确性和可信度。

本章将系统性地讲解 RAG 技术与提示词的协同工程,从基本原理到高级优化策略,帮助您构建可靠的检索增强应用。


13.1 RAG 技术的基本原理与工作流程

13.1.1 核心概念

RAG(检索增强生成) 是一种将信息检索系统与文本生成模型相结合的技术架构。核心思路是"先检索、再生成":先从外部知识库中检索与用户问题相关的文档片段,再将这些片段注入到提示词上下文中,最后让大模型基于检索到的上下文生成回答。

scss 复制代码
┌─────────────────────────────────────────────────────────────────┐
│                     RAG 系统工作流程                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌──────────────┐                                               │
│  │  原始文档    │  ──▶ 索引阶段                                  │
│  │ (PDF/网页等) │      ▼                                        │
│  └──────────────┘  ┌────────────────┐                          │
│                     │  文档切块       │                          │
│                     └───────┬────────┘                          │
│                             ▼                                    │
│                     ┌────────────────┐                          │
│                     │  向量化嵌入     │                          │
│                     └───────┬────────┘                          │
│                             ▼                                    │
│                     ┌────────────────┐                          │
│                     │  存入向量数据库 │                          │
│                     │  (Pinecone等)  │                          │
│                     └────────────────┘                          │
│                                                                 │
│  ┌──────────────┐                                               │
│  │  用户查询    │  ──▶ 检索阶段                                  │
│  └──────────────┘      ▼                                        │
│                     ┌────────────────┐                          │
│                     │  查询向量化     │                          │
│                     └───────┬────────┘                          │
│                             ▼                                    │
│                     ┌────────────────┐                          │
│                     │  相似度搜索    │                          │
│                     │  (Top-K)      │                          │
│                     └───────┬────────┘                          │
│                             ▼                                    │
│                     ┌────────────────┐                          │
│                     │  返回相关文档   │                          │
│                     └────────────────┘                          │
│                                                                 │
│  ┌──────────────┐                                               │
│  │  相关文档    │  ──▶ 生成阶段                                  │
│  │  (上下文)    │      ▼                                        │
│  └──────────────┘  ┌────────────────┐                          │
│                     │  构建增强提示   │                          │
│                     │  (RAG Prompt) │                          │
│                     └───────┬────────┘                          │
│                             ▼                                    │
│                     ┌────────────────┐                          │
│                     │  LLM 生成回答   │                          │
│                     └────────────────┘                          │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

13.1.2 RAG 的三大核心阶段

阶段一:索引(Indexing)

将原始文档转换为可检索的向量表示:

python 复制代码
import voyageai  # Anthropic 官方推荐的嵌入模型

vo = voyageai.Client()

documents = [
    "The Mediterranean diet emphasizes fish, olive oil, and vegetables...",
    "Photosynthesis in plants converts light energy into glucose...",
    "Machine learning is a subset of artificial intelligence...",
]

# 嵌入文档(使用 document input_type)
doc_embeddings = vo.embed(
    documents,
    model="voyage-3",
    input_type="document"
).embeddings

# 将向量存入向量数据库(以 Pinecone 为例)
import pinecone
pc = pinecone.Client()

index = pc.Index("knowledge-base")
for i, embedding in enumerate(doc_embeddings):
    index.upsert([(f"doc-{i}", embedding, {"text": documents[i]})])

重要提示 :Anthropic 官方强调,对于检索任务必须使用 input_type 参数区分 querydocument,这通过专门的提示前缀优化了检索质量。

Anthropic Embeddings 指南, docs.anthropic.com/en/docs/bui...

阶段二:检索(Retrieval)

将用户查询转换为向量,并在向量数据库中搜索最相关的内容:

python 复制代码
# 嵌入用户查询
query = "What is machine learning?"
query_embedding = vo.embed(
    [query],
    model="voyage-3",
    input_type="query"
).embeddings[0]

# 在向量数据库中搜索
# Voyage 嵌入已归一化,点积等于余弦相似度
response = index.query(
    vector=query_embedding,
    top_k=5,
    include_metadata=True
)

# 获取检索结果
retrieved_docs = [match["metadata"]["text"] for match in response["matches"]]
print(retrieved_docs)

阶段三:生成(Generation)

将检索到的文档作为上下文,让 LLM 生成回答:

python 复制代码
# 构建 RAG 提示词
rag_prompt = f"""请根据以下参考文档回答用户问题。
如果参考文档中没有包含回答所需的信息,请明确说明"根据已知信息无法回答"。
不要基于训练知识编造答案。

参考文档:
---
{chr(10).join([f'[文档{i+1}] {doc}' for i, doc in enumerate(retrieved_docs)])}
---

用户问题:{query}

回答:"""

# 调用 LLM 生成
response = client.chat.completions.create(
    model="gpt-4",
    messages=[
        {"role": "system", "content": "你是一个基于文档回答问题的助手。"},
        {"role": "user", "content": rag_prompt}
    ],
    temperature=0  # RAG 场景通常使用确定性生成
)

13.1.3 Anthropic 的 Citations 功能

Anthropic Claude 提供原生引用功能,可自动将回答中的声明关联到源文档的具体位置:

python 复制代码
import anthropic

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-opus-4-7",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "document",
                    "source": {
                        "type": "text",
                        "media_type": "text/plain",
                        "data": "The grass is green. The sky is blue."
                    },
                    "title": "My Document",
                    "citations": {"enabled": True},
                },
                {"type": "text", "text": "What color is the grass and sky?"},
            ],
        }
    ],
)

# 响应中自动包含引用信息
print(response.content)
# [{type: "text", text: "According to the document, "},
#  {type: "text", text: "the grass is green", citations: [{cited_text: "The grass is green.", ...}]}]

注意:引用不占用输出 token 计费,这是 Anthropic 原生支持的显著优势。

Anthropic Citations, docs.anthropic.com/en/docs/bui...

13.1.4 RAG 的适用场景与优势

最佳适用场景

  • 需要最新信息的任务:新闻查询、股价、天气
  • 私有知识库问答:企业文档、内部知识库
  • 长文档理解与问答:合同分析、研究报告
  • 减少幻觉:要求回答基于特定文档时

RAG vs 纯 LLM 的优势

维度 纯 LLM RAG
知识时效性 受限于训练数据 可实时更新
幻觉风险 较高 显著降低
可追溯性 可引用来源
隐私安全 无法控制 可限制数据范围
成本 固定 检索+生成

13.2 检索结果的提示词融合方法

13.2.1 基本融合模板

将检索结果注入提示词的核心原则:

python 复制代码
def build_rag_prompt(query: str, retrieved_docs: list[str], 
                     include_citations: bool = True) -> str:
    """
    构建 RAG 提示词
    
    核心设计原则:
    1. 明确告知模型上下文边界
    2. 提供无法回答时的退出路径
    3. 为每个文档块添加来源标识
    4. 控制上下文总量避免注意力分散
    """
    
    # 构建参考文档部分
    docs_section = "\n\n".join([
        f"【来源 {i+1}】\n{doc}" 
        for i, doc in enumerate(retrieved_docs)
    ])
    
    prompt = f"""你是一个专业的问答助手。请根据以下参考文档回答用户问题。

## 参考文档
{docs_section}

## 回答要求
1. 仅基于上述参考文档中的信息进行回答
2. 不要使用文档之外的训练知识
3. 如果文档中没有包含回答问题所需的信息,请明确说明"根据提供的文档无法回答此问题"
4. 在回答中使用【来源X】标注信息来源

## 用户问题
{query}

## 回答
"""
    return prompt

13.2.2 检索结果排序与截断策略

排序策略

python 复制代码
def rank_and_truncate(
    retrieved_docs: list[dict],  # [{"text": ..., "score": ...}, ...]
    max_docs: int = 5,
    min_score: float = 0.7
) -> list[dict]:
    """
    检索结果排序与截断
    
    策略:
    1. 按相似度得分从高到低排序
    2. 设定最低分数阈值过滤低相关结果
    3. 限制返回文档数量
    """
    
    # 按相似度降序排序
    sorted_docs = sorted(retrieved_docs, key=lambda x: x["score"], reverse=True)
    
    # 过滤低分结果
    filtered_docs = [doc for doc in sorted_docs if doc["score"] >= min_score]
    
    # 截断到最大数量
    return filtered_docs[:max_docs]

Token 预算截断

python 复制代码
import anthropic

client = anthropic.Anthropic()

def truncate_by_token_budget(
    query: str,
    retrieved_docs: list[str],
    max_input_tokens: int = 80000,  # 保留一些空间给系统提示和问题
    model: str = "claude-sonnet-4-6"
) -> list[str]:
    """按 token 预算截断文档"""
    
    # 构建测试提示
    test_prompt = f"Query: {query}\n\nDocs:\n" + "\n\n".join(retrieved_docs)
    
    # 计算当前 token 数
    count = client.messages.count_tokens(
        model=model,
        messages=[{"role": "user", "content": test_prompt}]
    )
    
    # 如果超预算,按顺序移除文档直到满足要求
    while count.input_tokens > max_input_tokens and retrieved_docs:
        retrieved_docs.pop()
        test_prompt = f"Query: {query}\n\nDocs:\n" + "\n\n".join(retrieved_docs)
        count = client.messages.count_tokens(
            model=model,
            messages=[{"role": "user", "content": test_prompt}]
        )
    
    return retrieved_docs

13.2.3 上下文位置效应

"Lost in the Middle" 现象:当相关信息放置在输入中间时,模型准确率可能下降超过 30%。研究表明,Transformer 对开头和结尾的信息关注度最高,形成 U 型注意力曲线。

应对策略

python 复制代码
def position_sensitive_rerank(
    query: str,
    retrieved_docs: list[dict],
    top_k: int = 10,
    strategy: str = "interleave"  # interleave | front_weight | back_weight
) -> list[dict]:
    """
    位置敏感的重排序策略
    
    策略说明:
    - interleave: 将文档交替放置,利用首尾效应
    - front_weight: 将高分文档放在前面
    - back_weight: 将高分文档放在后面
    """
    
    sorted_docs = sorted(retrieved_docs, key=lambda x: x["score"], reverse=True)
    
    if strategy == "interleave":
        # 交替放置:高分组、低分组交替
        high, low = sorted_docs[:top_k//2], sorted_docs[top_k//2:top_k]
        result = []
        for i in range(len(high)):
            result.append(high[i])
            if i < len(low):
                result.append(low[i])
        return result
    
    elif strategy == "front_weight":
        return sorted_docs[:top_k]
    
    elif strategy == "back_weight":
        # 翻转:将低分文档放在前面,高分放在后面
        docs = sorted_docs[:top_k]
        return docs[::-1]
    
    return sorted_docs[:top_k]

13.2.4 多样性重排序

避免检索结果过于相似(内容重复),增加多样性:

python 复制代码
def diverse_rerank(
    retrieved_docs: list[dict],
    top_k: int = 5,
    diversity_threshold: float = 0.8
) -> list[dict]:
    """
    多样性重排序:避免返回过于相似的文档
    """
    
    result = []
    remaining = retrieved_docs.copy()
    
    while len(result) < top_k and remaining:
        # 每次选择当前最高分且与已有结果不太相似的文档
        best_idx = 0
        best_score = -float('inf')
        
        for i, doc in enumerate(remaining):
            # 综合相关性得分和多样性
            diversity_penalty = 0
            for selected_doc in result:
                # 简单相似度估计(实际可用嵌入余弦相似度)
                similarity = len(set(doc["text"].split()) & 
                              set(selected_doc["text"].split())) / \
                            len(set(doc["text"].split()) | 
                                set(selected_doc["text"].split()))
                diversity_penalty += similarity * diversity_threshold
            
           综合得分 = doc["score"] - diversity_penalty
            
            if 综合得分 > best_score:
                best_score = 综合得分
                best_idx = i
        
        result.append(remaining.pop(best_idx))
    
    return result

13.3 分块与引用提示:让模型准确引用来源

13.3.1 文本分块策略

策略一:固定大小分块(Fixed-Size Chunking)

最简单的分块方式,按固定 token 数或字符数切分:

python 复制代码
def fixed_size_chunking(
    text: str,
    chunk_size: int = 500,  # tokens
    chunk_overlap: int = 50  # tokens
) -> list[str]:
    """固定大小分块"""
    
    tokens = text.split()  # 简化的 token 化
    chunks = []
    
    start = 0
    while start < len(tokens):
        end = start + chunk_size
        chunk = " ".join(tokens[start:end])
        chunks.append(chunk)
        
        # 移动窗口(考虑重叠)
        start = end - chunk_overlap
    
    return chunks

策略二:递归分块(Recursive Chunking)

LangChain 官方推荐的通用文本分割器,按分隔符优先级递归切分:

python 复制代码
from langchain_text_splitters import RecursiveCharacterTextSplitter

# 中文文本处理
text_splitter = RecursiveCharacterTextSplitter(
    separators=[
        "\n\n",    # 优先按段落切分
        "\n",      # 其次按句子换行
        "。",      # 中文句号
        "!",
        "?",
        ",",      # 中文逗号
        " ",
        "",        # 最后按单词/字符
    ],
    chunk_size=500,
    chunk_overlap=50,
)

chunks = text_splitter.split_text(long_chinese_document)

LangChain Recursive Text Splitter, python.langchain.com/docs/how_to...

策略三:语义分块(Semantic Chunking)

基于嵌入向量的语义相似性对句子进行分组:

python 复制代码
def semantic_chunking(
    text: str,
    sentences: list[str],
    similarity_threshold: float = 0.5
) -> list[str]:
    """
    语义分块:根据句子间语义相似度进行分组
    
    核心思想:当相邻句子的语义相似度低于阈值时,进行切分
    """
    
    if not sentences:
        return [text]
    
    # 计算相邻句子的嵌入相似度
    embeddings = vo.embed(sentences, model="voyage-3", input_type="document")
    
    chunks = []
    current_chunk = [sentences[0]]
    
    for i in range(1, len(sentences)):
        # 计算相似度
        similarity = embeddings[i-1] @ embeddings[i]  # 点积=余弦相似度
        
        if similarity >= similarity_threshold:
            # 相似度高,继续当前块
            current_chunk.append(sentences[i])
        else:
            # 相似度低,保存当前块并开始新块
            chunks.append("".join(current_chunk))
            current_chunk = [sentences[i]]
    
    # 保存最后一个块
    if current_chunk:
        chunks.append("".join(current_chunk))
    
    return chunks

13.3.2 让模型准确引用来源的提示技术

方法一:基于提示词的引用(通用方案)

python 复制代码
citation_prompt = """请根据以下参考文档回答问题。

## 参考文档
{formatted_docs}

## 回答要求
1. 仅基于参考文档中的信息回答,不要编造信息
2. 在回答的每个事实性声明后,使用 [来源X] 的格式标注信息来源
3. 如果某个信息来自多个来源,标注所有相关来源,如 [来源1, 来源3]
4. 如果文档中没有相关信息,请明确说明

## 用户问题
{query}

## 回答(请使用引用标注)"""

方法二:使用 Anthropic Citations API(推荐)

Anthropic 的 Citations 功能提供了比纯提示词方案更可靠的引用机制:

python 复制代码
def rag_with_citations(query: str, documents: list[str]) -> dict:
    """
    使用 Anthropic Citations 实现结构化引用
    """
    
    response = client.messages.create(
        model="claude-opus-4-7",
        max_tokens=1024,
        messages=[
            {
                "role": "user",
                "content": [
                    {
                        "type": "document",
                        "source": {
                            "type": "content",
                            "content": [
                                {"type": "text", "text": doc} 
                                for doc in documents
                            ],
                        },
                        "title": "知识库文档",
                        "citations": {"enabled": True},
                    },
                    {"type": "text", "text": query},
                ],
            }
        ],
    )
    
    # 解析响应中的引用信息
    answer_text = ""
    citations = []
    
    for block in response.content:
        if block.type == "text":
            answer_text += block.text
        if hasattr(block, 'citations') and block.citations:
            citations.extend(block.citations)
    
    return {
        "answer": answer_text,
        "citations": citations
    }

13.3.3 引用格式设计

格式类型 示例 适用场景
编号引用 "...根据研究1,效果提升了30%..." 学术、技术文档
括号来源 "...(来源:产品手册第5页)..." 面向终端用户
脚注引用 "...效果显著提升\^1" 长文档、报告
Claude Citations 自动生成带位置的引用 API 集成应用

13.4 多轮检索与动态提示生成

13.4.1 查询重写(Query Rewriting)

查询重写是将用户原始查询转换为更适合检索的形式:

python 复制代码
def rewrite_query_for_retrieval(query: str, history: list[str] = None) -> str:
    """
    查询重写:优化查询以获得更好的检索结果
    """
    
    rewrite_prompt = f"""你是一个查询优化专家。将以下用户查询重写为更适合信息检索的形式。

重写原则:
1. 识别查询中的核心概念和关键词
2. 补充可能的同义词和相关术语
3. 将模糊问题改写为更精确的检索 query
4. 如果有对话历史,将其整合到当前查询中

{ '对话历史:\n' + '\n'.join([f'- {h}' for h in history]) + '\n' if history else '' }

原始查询:{query}

重写后的查询:"""

    response = client.chat.completions.create(
        model="gpt-4",
        messages=[{"role": "user", "content": rewrite_prompt}],
        temperature=0
    )
    
    return response.choices[0].message.content.strip()

13.4.2 HyDE(Hypothetical Document Embedding)

HyDE 不直接改写 query,而是让 LLM 先根据 query 生成一个"假设性答案文档",然后用这个假设文档的嵌入向量替代原始 query 的嵌入向量进行检索。

python 复制代码
def hyde_retrieval(query: str, documents: list[str]) -> str:
    """
    HyDE 检索:使用假设性文档增强检索效果
    
    核心原理:假设性答案通常比原始问题包含更多领域术语,
    在嵌入空间中与真实相关文档的距离更近。
    """
    
    # 步骤1:让 LLM 生成假设性答案文档
    hyde_prompt = f"""请写一段详细的内容,回答以下问题。
这段内容应该是对问题的全面解答,不需要完全准确,但要有信息量。

问题:{query}

假设性内容:"""

    hypothetical_doc = client.chat.completions.create(
        model="gpt-4",
        messages=[{"role": "user", "content": hyde_prompt}],
        temperature=0.7
    ).choices[0].message.content
    
    # 步骤2:用假设文档的嵌入进行检索
    hypothetical_embedding = vo.embed(
        [hypothetical_doc],
        model="voyage-3",
        input_type="document"  # 注意:使用 document 而非 query
    ).embeddings[0]
    
    # 步骤3:在向量数据库中搜索
    similarities = [hypothetical_embedding @ doc_emb 
                    for doc_emb in doc_embeddings]
    top_indices = sorted(range(len(similarities)), 
                        key=lambda i: similarities[i], 
                        reverse=True)[:5]
    
    # 步骤4:用真实文档生成最终回答
    retrieved_docs = [documents[i] for i in top_indices]
    
    final_prompt = f"""基于以下文档回答问题:

文档:
{chr(10).join([f'{i+1}. {doc}' for i, doc in enumerate(retrieved_docs)])}

问题:{query}

回答:"""
    
    final_response = client.chat.completions.create(
        model="gpt-4",
        messages=[{"role": "user", "content": final_prompt}]
    )
    
    return final_response.choices[0].message.content

Gao et al., "Precise Zero-Shot Dense Retrieval without Relevance Labels", arXiv:2212.09660

13.4.3 多轮检索策略

迭代检索:基于前一轮结果进行补充检索:

python 复制代码
def multi_round_retrieval(
    query: str,
    max_rounds: int = 3,
    initial_k: int = 5,
    expand_k: int = 3
) -> list[str]:
    """
    多轮检索:迭代扩展检索结果
    """
    
    all_docs = []
    seen_ids = set()
    
    for round_num in range(max_rounds):
        if round_num == 0:
            # 第一轮:直接检索
            current_query = query
        else:
            # 后续轮次:基于前一轮回答生成追问
            current_query = generate_followup_query(
                original_query=query,
                previous_docs=all_docs[-initial_k:],
                previous_answer=last_answer
            )
        
        # 检索
        results = retrieve_documents(current_query, top_k=initial_k if round_num == 0 else expand_k)
        
        # 去重合并
        for doc in results:
            if doc["id"] not in seen_ids:
                all_docs.append(doc)
                seen_ids.add(doc["id"])
        
        # 检查是否需要继续
        if round_num > 0 and should_stop(all_docs, query):
            break
    
    return all_docs

13.5 RAG 与提示词工程的协同优化

13.5.1 RAGAS 评估指标体系

RAGAS 是最主流的 RAG 系统自动评估框架:

GitHub: github.com/explodinggr... (10.2k stars) 文档: docs.ragas.io/

python 复制代码
from ragas import EvaluationDataset
from ragas.dataset_schema import SingleTurnSample
from ragas.metrics import Faithfulness, AnswerRelevancy, ContextPrecision

# 构建测试数据集
data_samples = [
    SingleTurnSample(
        user_input="What is Ragas?",
        response="Ragas is an evaluation framework for LLM applications",
        reference="Ragas is an evaluation framework for LLM applications",
        retrieved_contexts=["Ragas provides objective metrics for evaluation."],
    ),
]

dataset = EvaluationDataset(samples=data_samples)

# 运行评估
results = dataset.evaluate(
    metrics=[Faithfulness(), AnswerRelevancy(), ContextPrecision()]
)

print(results)

三大核心指标

指标 含义 衡量内容
Faithfulness 忠实度 生成回答与上下文中事实的一致性
Answer Relevancy 答案相关性 回答与用户问题的相关程度
Context Precision 上下文精确度 相关文档排在前面、不相关文档排在后面的能力

13.5.2 提示词对 RAG 效果的影响

关键因素

  1. 上下文位置:将检索到的文档放在提示词的前部还是后部会影响模型注意力分配
  2. 指令明确性:明确要求"仅基于提供的文档回答"可以显著降低幻觉率
  3. 来源标注要求:要求模型标注来源可以同时提高忠实度和可追溯性
  4. 格式约束:指定回答格式(如结构化输出)可以提升回答的一致性
  5. 不确定性处理:提供"不知道"的退出路径可以减少编造

13.5.3 端到端 RAG 优化框架

python 复制代码
class RAGOptimizer:
    """RAG 系统优化器"""
    
    def __init__(self):
        self.retriever = None
        self.generator = None
        self.evaluator = None
    
    def optimize(self, train_samples: list, n_iterations: int = 5):
        """迭代优化 RAG 系统"""
        
        best_score = 0
        best_config = {}
        
        for iteration in range(n_iterations):
            # 1. 使用当前提示词生成回答
            responses = []
            for sample in train_samples:
                query = sample["query"]
                docs = self.retriever.retrieve(query)
                
                prompt = self.build_prompt(query, docs)
                response = self.generator.generate(prompt)
                responses.append({
                    "query": query,
                    "response": response,
                    "retrieved_docs": docs
                })
            
            # 2. 评估当前性能
            scores = self.evaluator.evaluate(responses)
            avg_score = sum(scores) / len(scores)
            
            print(f"迭代 {iteration+1}: 得分 = {avg_score:.4f}")
            
            # 3. 如果有提升,保存配置
            if avg_score > best_score:
                best_score = avg_score
                best_config = self.get_current_config()
            
            # 4. 基于反馈调整提示词
            self.adjust_prompt_based_on_errors(responses, train_samples)
        
        return best_config, best_score

13.5.4 RAG 与其他技术的融合

RAG + 长上下文:2025 年的主流架构是 Hybrid Context(混合上下文)------ 用 RAG 做宽召回,用长上下文做深推理。

RAG + Agent:RAG 系统作为 Agent 的工具之一,实现自主知识探索:

python 复制代码
def rag_agent_system(user_query: str):
    """RAG + Agent 协作系统"""
    
    agent = Agent(
        instructions="你是知识探索专家,可以自主决定是否需要检索外部知识。",
        tools=[
            retrieve_documents_tool,  # RAG 检索工具
            web_search_tool,          # 网页搜索工具
            # 其他工具
        ]
    )
    
    return agent.run(user_query)

本章小结

核心概念回顾

概念 说明
RAG 检索增强生成,先检索后生成,提升准确性和可信度
索引 将文档切块、向量化,存入向量数据库
检索 查询向量化,在向量库中相似度搜索
生成 将检索结果注入提示词,LLM 基于上下文生成
Citations Anthropic 原生引用功能,不占用输出 token
HyDE 假设性文档嵌入,用假设答案增强检索效果
RAGAS RAG 评估框架,Faithfulness/AnswerRelevancy/ContextPrecision

关键要点

  1. RAG 三大阶段:索引(切块→向量化→入库)→ 检索(查询→搜索→返回)→ 生成(构建提示→调用 LLM)
  2. 检索质量决定上限:RAG 的效果主要由检索质量决定,Anthropic 强调"检索质量比模型大小更重要"
  3. 分块策略影响显著:递归分块兼顾语义完整性和嵌入效果
  4. 引用格式可设计:从提示词标注到 Anthropic 原生 Citations
  5. HyDE 增强检索:通过生成假设性答案来弥合 query-doc 语义鸿沟
  6. RAGAS 量化评估:Faithfulness(忠实度)、Answer Relevancy(相关性)、Context Precision(精确度)

下一章预告:第14章将深入讲解"Prompt 编排与优化技术",探讨 Prompt Chaining、并行提示、DSPy、LLMLingua 等先进提示工程方法。


参考来源

来源 链接
Anthropic Embeddings 指南 docs.anthropic.com/en/docs/bui...
Anthropic Citations docs.anthropic.com/en/docs/bui...
Anthropic Cookbook (GitHub) github.com/anthropics/...
OpenAI Embeddings 指南 platform.openai.com/docs/guides...
LangChain Recursive Text Splitter python.langchain.com/docs/how_to...
RAGAS GitHub github.com/explodinggr...
RAGAS 官方文档 docs.ragas.io/
HyDE Paper arxiv.org/abs/2212.09...
Voyage AI 嵌入文档 docs.voyageai.com/docs/embedd...
相关推荐
小爷毛毛_卓寿杰1 小时前
我把 397B 的「Agentic 大脑」塞进了 Xinference,一键部署 Nex-N2
人工智能·架构·github
smallYoung1 小时前
Vibe Coding 笔记-中
人工智能
米小虾1 小时前
DSpark:让大模型"写得更快"的秘密武器
人工智能·deepseek
JavaGuide2 小时前
比 iTerm2 更适合 Claude Code/Codex 的终端,我换成 Ghostty 了
人工智能·后端
threerocks2 小时前
神级 Skill,作品个个儿爆,我开源了长期自用的手绘风格库
人工智能·aigc
小爷毛毛_卓寿杰3 小时前
我把一个 3B 模型塞进了 Xinference,然后它干掉了 DeepSeek V3.2
人工智能·开源·github
秦先生在广东3 小时前
Agent 闭环才是真正的护城河:Anthropic “300 个 Agent“ 背后被忽视的秘密
人工智能
Bigfish_coding3 小时前
前端转agent-【python】- 14 记忆系统优化:摘要与遗忘
人工智能
Bigfish_coding3 小时前
前端转agent-【python】-13 Ollama Python流式输出教程:stream=True 与 async 实践
人工智能