当前位置:首页 > 文章列表 > 科技周边 > 人工智能 > RAG 检索结果附带来源片段的组装方案

RAG 检索结果附带来源片段的组装方案

来源:17golang原创 2026-10-17 11:13:44 0浏览 收藏

RAG 的检索结果不要直接拼成一段无标识的 prompt。更稳妥的做法是先把每个命中切片整理为统一记录:保留原文、来源文档、定位信息和检索分数;组装时再从同一批记录投影出模型上下文与前端引用。这样模型看到的是紧凑文本,读者看到的是可回溯的来源片段,两者不会因为排序或截断发生错位。

参考资料入口:https://huggingface.co/docs/transformers/main/chat_template_tools_and_documents

先把来源当成切片的一部分

一个切片至少要回答三个问题:它来自哪份文档、在文档中的什么位置、为什么被召回。只有正文文本而没有这些字段,后续即使生成了“参考来源”,也只能凭标题猜测,无法定位到真正的段落。

建议把内部记录设计成稳定的数据对象。source_id 用于跨切片归并,chunk_id 用于定位单个切片,locator 可以是页码、章节、段落编号或 URL 片段。score 只用于排序,不应被直接当成答案可信度。

RAG 切片记录、来源元数据和检索结果之间的静态关系说明图
图1:RAG 来源记录说明图,展示切片文本、来源元数据和检索分数如何组成一条可回溯记录。

只拼文本的旧写法为什么容易丢引用

最短的实现通常是遍历命中结果,把每个 text 用换行连接起来,再把连接后的字符串交给模型。这种写法能快速看到回答,却把标题、页码、URL 和切片边界一起丢掉了;当两个切片来自同一文档时,前端还可能展示两条重复来源。

另一个问题是排序与展示各做一遍。上下文层按分数截取前五段,展示层又按文档标题排序,模型回答中的“来源 2”就不一定对应界面上的第二条来源。解决方式不是让模型自己输出编号,而是由组装层先分配稳定的引用编号。

from dataclasses import dataclass
from html import escape

@dataclass
class ChunkRecord:
    # 统一记录让上下文和引用共享同一份来源信息。
    chunk_id: str
    source_id: str
    title: str
    text: str
    locator: str
    score: float

def assemble_sources(hits: list[ChunkRecord], limit: int = 5) -> tuple[str, list[dict]]:
    # 先按分数排序,再用 chunk_id 保证相同分数时结果稳定。
    ordered = sorted(hits, key=lambda item: (-item.score, item.chunk_id))
    chosen: list[ChunkRecord] = []
    seen_sources: set[str] = set()
    for hit in ordered:
        # 同一文档优先保留最高分切片,避免引用列表重复占位。
        if hit.source_id in seen_sources:
            continue
        chosen.append(hit)
        seen_sources.add(hit.source_id)
        if len(chosen) == limit:
            break

    context_parts: list[str] = []
    citations: list[dict] = []
    for index, hit in enumerate(chosen, start=1):
        citation_id = f"S{index}"
        # 编号由组装层产生,模型只需在回答中引用已有编号。
        context_parts.append(f"[{citation_id}] {hit.title}\n{hit.text}")
        citations.append({
            "id": citation_id,
            "source_id": hit.source_id,
            "title": hit.title,
            "locator": hit.locator,
            "snippet": escape(hit.text[:180]),
        })
    return "\n\n".join(context_parts), citations

这段代码刻意把 context 和 citations 放在同一个循环里生成。实际项目中可以按业务需要保留同一文档的多个互补片段,但应让去重规则明确写在组装层,而不是交给模板或前端临时判断。

把一批记录投影成两种结果

检索记录是内部模型,模型上下文和界面引用则是两个不同的投影。上下文需要标题和片段正文,重点是短、清晰、能被模型识别;引用对象需要标题、来源标识、定位信息和短摘录,重点是能让读者回到原文。两者使用同一个 citation_id,但不要把内部所有字段都塞进 prompt。

如果使用支持文档列表的模型模板,可以把每条记录投影为包含标题和内容的文档对象;如果使用普通聊天模板,也可以把编号写进上下文文本。无论采用哪一种形式,编号都应由本地组装逻辑产生,不能依赖模型临时编造。

RAG 同一批记录分别投影为模型上下文和前端引用的静态关系说明图
图2:上下文与引用双投影说明图,查看同一批记录如何共享编号并服务模型与前端。

截断和缺失元数据要有明确规则

上下文预算不足时,应该先减少低分切片,再缩短单个片段,最后才考虑丢弃引用字段。不要先把所有正文截断后再重新编号,否则前端保存的摘录可能已经不是模型实际看到的内容。

缺少标题时可以使用文档 ID 作为临时显示名,缺少定位信息时显示“未提供定位”,但不要虚构页码或 URL。缺少 source_id 的记录不适合进入可回溯引用列表;可以保留在内部调试数据中,或在组装前过滤掉。

还要把“检索分数”和“来源可信度”分开。分数表示当前查询下的相似程度,来源可信度需要由文档级策略、更新时间、权限范围等业务信息决定。把二者混成一个百分比,很容易让用户误以为相似度就是事实正确率。

采用这套组装方式时记住三点

  • 切片记录先完整,模型上下文和界面引用后投影。
  • 去重、排序、截断和编号只在一个组装层决定。
  • 缺失字段要诚实标记,不能为了好看补造定位或可信度。

常见问题

为什么不直接让模型输出来源链接?

模型可以根据上下文复述来源,但不适合负责生成真实链接和稳定编号。链接、定位和权限应来自检索记录,由应用层把模型引用编号映射回来源对象。

同一篇文档的多个切片是否一定要去重?

不一定。若多个切片分别包含定义和例外条件,可以都保留;去重的目标是避免相同来源无意义占位,而不是强行让每篇文档只出现一次。规则应根据上下文预算和引用展示空间决定。

引用摘录要不要和模型上下文完全一致?

核心事实应一致,但展示摘录可以更短,并保留足以定位的标题和位置。若上下文经过了二次裁剪,应该重新生成摘录,避免界面显示一段模型实际上没有读到的文字。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Hugging Face Inference Providers 选择模型路由的接入方式Hugging Face Inference Providers 选择模型路由的接入方式
上一篇
Hugging Face Inference Providers 选择模型路由的接入方式
多模态模型提取表格布局的结果约束
下一篇
多模态模型提取表格布局的结果约束
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    500次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    559次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    587次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    539次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    350次使用