RAG落地测评:回答与检索片段对应追踪精选

2026-05-29阅读 0热度 0
ai 人工智能

在 RAG(检索增强生成)系统中,将模型输出与检索到的片段(Chunk)建立精确映射,是实现可解释推理、事实核查与错误归因的核心能力。尤其在金融、医疗等强监管领域,这种溯源机制几乎是基础设施级别的刚需。

先看最终呈现效果——大模型生成的每条回答都附带像 [1][2] 这样的来源标记。今天我们就手把手拆解,如何借助 LlamaIndex 框架落地这一能力。

RAG工程落地:回答内容和检索片段(chunk)对应关系追踪

为什么必须追踪回答与检索片段的对应关系?

  • 事实校验:确保答案内容源于可信的检索块,杜绝大模型“幻觉”(捏造虚假信息)。
  • 可解释性:向用户亮出回答的证据链,增强系统公信力(如金融投资建议、临床诊断辅助等合规场景)。
  • 调试与优化:精准定位检索或生成环节的短板(比如片段相关性不足、关键信息被遗漏)。
  • 合规审计:满足数据来源追溯要求(例如法律文书中需记录每一条引用的原始段落)。

这四点看似抽象,实际落地时你会发现,每一项都直接决定 RAG 系统在生产环境中的可用性和用户信任度。

代码实现

我们通常基于 LlamaIndex 构建 RAG 应用,它内置了专门的引文查询引擎——CitationQueryEngine。官方文档提供了完整教程与示例。

首先安装必需的依赖包:

pip install llama-index
pip install llama-index-embeddings-openai
pip install llama-index-llms-openai

创建带有默认参数的 CitationQueryEngine:

query_engine = CitationQueryEngine.from_args(
    index,
    similarity_top_k=3,
    # here we can control how granular citation sources are, the default is 512
    citation_chunk_size=512,
)

res = query_engine.query("宋集薪是谁?")
print(res.response)              # LLM 输出回答
print("------来源---------------")
for node in res.source_nodes:
   print("相关片段:", node.text)
   print("片段分数:", node.score)
   print("片段元数据:", node.metadata)
   print("="*40)

运行后,大模型合成的答案里会带上标签 [1][2][3],这些标签依次对应检索到的 Chunk 块。注意标签从 1 开始计数,但 Python 数组索引从 0 开始,这一点极易踩坑。

核心参数解读

参数 citation_chunk_size 默认值为 512,决定引用 Chunk 的 token 上限。这里有几个要点:

  1. 该值与文本切割 Node 的 chunk_size 无关,两者相互独立。
  2. citation_chunk_size > chunk_size,则以 chunk_size 为准;反之,CitationQueryEngine 会按 citation_chunk_size 重新切分,生成新的 Chunk 块。
  3. citation_chunk_size 不宜过大,若超过源文档长度,实际引用的片段反而会被截断,失去溯源效果。
  4. 引用内容通过 response.source_nodes 查看,每个节点包含文本、分数和元数据。

完整示例

下面是一段可直接运行的完整代码,包含模型初始化、文档加载、分割、建索引与查询的完整链路:

from llama_index.core import VectorStoreIndex, Settings, SimpleDirectoryReader
from llama_index.llms.openai_like import OpenAILike
from llama_index.core.node_parser import SentenceSplitter
from llama_index.embeddings.openai_like import OpenAILikeEmbedding

# ================== 初始化模型 ==================
def init_models():
    """初始化模型并验证"""
    # Embedding模型
    embed_model = OpenAILikeEmbedding(
        model_name="BAAI/bge-m3",
        api_base="https://api.siliconflow.cn/v1",
        api_key="sk-xxxxx",
        embed_batch_size=10,
    )

    llm = OpenAILike(
        model="DeepSeek-ai/DeepSeek-V3",
        api_base="https://api.siliconflow.cn/v1",
        api_key="sk-xxxx",
        context_window=128000,
        is_chat_model=True,
        is_function_calling_model=False,
    )

    Settings.embed_model = embed_model
    Settings.llm = llm

    # 验证模型
    test_embedding = embed_model.get_text_embedding("测试文本")
    print(f"Embedding维度验证:{len(test_embedding)}")

    return embed_model, llm

init_models()

# load documents, split into chunks
documents = SimpleDirectoryReader(r"D:Testaiyoyo\\data2").load_data()
# 2. 文档切分为 chunk,添加 chunk_id
sentence_splitter = SentenceSplitter(
    chunk_size=400,
    chunk_overlap=100,
    separator="。!?!?.n¡¿",  # 适配中文,英语,西班牙语三种语言的分隔符
)

# 3. 分割文档
nodes = sentence_splitter.get_nodes_from_documents(documents)

index = VectorStoreIndex(nodes)

from llama_index.core.query_engine import CitationQueryEngine

query_engine = CitationQueryEngine.from_args(
    index,
    similarity_top_k=3,
    citation_chunk_size=512,
)

res = query_engine.query("宋集薪是谁?")
print(res.response)              # LLM 输出回答
print("------来源---------------")
for node in res.source_nodes:
    print(node.get_text())
    print("="*40)

前后端对接

后端逻辑完成后,可通过 FastAPI 将其封装为 Web API,把回答与 source_nodes 一并返回给前端。接口返回的 JSON 示例结构如下:

{
    "code": 0,
    "message": "",
    "data": {
        "answer": "宋集薪是一个少年,居住在毗邻陈平安的院落中,并拥有一名婢女(被称为“稚圭”)[1][3]。他性格有些顽劣,喜欢戏弄他人,比如在与锦衣少年的对话中先是提出高价卖婢女,后又改口抬价[1][2]。此外,他与婢女关系似乎较为亲近,能心有灵犀地配合[3]。他还计划下个月离开当地[3]。",
        "reference": {
            "total": 3,
            "chunks": [
                {"id": "d5f7457f79be3e2d", "content": "略"},
                {"id": "476769d43a003fb9", "content": "略"},
                {"id": "a8194d208880c1a0", "content": "略。"}
            ],
            "doc_aggs": [
                {"doc_name": "jianlai.txt", "doc_id": "5864b70c475f11f08a6042010a8a0006", "count": 81}
            ]
        },
        "prompt": "略",
        "created_at": 1750215867.10315,
        "id": "47d55175-bede-4d83-b42a-e1296c09ff16",
        "session_id": "8e9345563cee49af95ad6d75072b200a"
    }
}

前端依据返回的 answer 文本中的标签与 reference.chunks 字段,即可渲染出带超链接或悬浮提示的溯源效果。

总结:追踪机制的价值

通过回答与 Chunk 的对应关系追踪,RAG 系统完成了从“黑盒生成”到“白盒可解释”的质变。这不仅显著提升用户信任,还为系统优化提供了精确的数据反馈。实际落地时,需根据业务场景选择追踪粒度——段落级、句子级甚至 token 级,并结合工具链集成降低开发成本。

一句话:装上这套机制,你的 RAG 应用就不再只是“看起来聪明”,而是“每一步推理都有据可查”。

免责声明

本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。

相关阅读

更多
欢迎回来 登录或注册后,可保存提示词和历史记录
登录后可同步收藏、历史记录和常用模板
注册即表示同意服务条款与隐私政策