读完这篇,你能做什么
能让笔记问答附上可核对引用,资料不足时说明限制,并避免读取或引用越权资料。
学习理由、准备要求与知识点
为什么学它
接上向量库只是开始。RAG 回答还要能找到支持结论的原文,引用是否真实、资料是否有权读取,都要由服务端核对。
先读这些内容
知识点清单
- RAG 检索与生成分工
- 文档章节与版本元数据
- 租户和权限过滤
- 候选片段进入上下文
- 引用 ID 与来源映射
- 断言与证据支持
- 空上下文拒答
- 检索与生成分别验收
运行前先确认完整算法使用 Java 17 标准库;JDK 源码基线为 OpenJDK 17 GA。示例是内存中的机制模型,外部服务接入需要另外配置和验证。
01先弄懂它是什么
要让模型依据自己的文档回答,可以先检索授权资料,再把相关片段交给模型组织答案,这叫 RAG。它能提供依据,但不会自动消除编造:文字看起来相似,也不一定支持当前结论。例如回答某个接口的行为,应能指出具体来源片段和版本,让读者核对每个重要说法。
引用最好由应用先分配 ID,并对应到真实文档位置,模型只从本次提供的 ID 中选择。检查时要分三步:引用格式写对了吗,ID 真的是这次提供的吗,片段内容真的能支持这句话吗?前两步通过仍不代表第三步通过。这样才能分别发现捏造来源,以及引用了真文档却把意思用错的问题。
资料不足时,系统应指出缺少哪类证据或请用户补充,不强行补成确定答案。无答案问题是正常任务类型,需要独立测试。涉及多个版本时保留分歧与适用条件,不能把互相冲突的片段拼成看似统一的结论。
文中这几个词,先认一认
- 证据覆盖
- 候选资料中有没有出现回答所需的信息点。信息出现了,也还要检查它是否真正支持结论。
- 引用映射
- 应用保存的对应关系,把答案里的引用 ID 找回具体文档、章节、版本和片段。
- 断言支持
- 检查证据内容是否足以说明答案中的某个具体说法成立,而不只是关键词相似。
02看看它怎么工作
先在检索前确定租户、资料范围和版本,再将有限片段及ID放入上下文。模型输出答案与引用,应用检查所有ID都在允许集合中,并按断言逐项核对。缺引用或资料不足应保留为失败或不确定状态,而不是用一个相关链接装饰答案。
本题用最短连续窗口演示“为回答收集足够证据标签”。输入片段标签A、X、B、A,要求A和B,最短窗口是B、A。滑动窗口维护每种所需标签的出现次数,覆盖齐后收缩左边界,保留最短候选。标签由题目预先给定,算法不理解自然语言。
最短标签覆盖只是预算选择模型。某段出现“索引”一词,不等于它回答了“联合索引为什么失效”;同样,最短窗口可能删掉重要限定。正式RAG应把文档结构、来源和语义支持共同检查,算法结果只是帮助减少无关上下文,不能冒充蕴含判断器。
正在加载流程图…
查看流程图源码(Mermaid)
flowchart LR
Q["问题和可信身份"] --> R["授权检索"]
R --> C["片段 ID 与版本"]
C --> G["生成断言和引用"]
G --> I["引用存在性检查"]
I --> S["逐断言支持核对"]
S --> A["答案或资料不足"]按顺序看,每一步做了什么
- 根据可信身份和版本确定授权资料范围。
- 检索候选并附稳定片段ID、章节和原文位置。
- 选择覆盖问题所需信息的有限证据。
- 生成断言与引用后,检查ID存在性及具体支持。
- 对无证据、冲突和过期场景明确说明边界。
03对照实现代码
OpenJDK 17 GA,jdk-17+35 · HashSet.add / contains
下方为原创 Java 教学片段,调用已核验的 JDK API 说明局部机制;不是该类原样源码,也不实现神经网络。完整程序见算法模块。
Set<String> allowedIds = new HashSet<>();
for (Chunk chunk : suppliedChunks) allowedIds.add(chunk.id()); // 只允许当前授权片段。
for (String citation : answerCitationIds) {
if (!allowedIds.contains(citation)) throw new IllegalArgumentException("unknown citation");
}
// ID存在性通过后,仍需核对该片段是否支持答案断言。HashSet通过映射维护成员关系,add和contains提供去重与成员检查。它只能回答某ID是否在集合,无法判断引用文本的语义。
集合必须来自本次已授权并实际提供的片段,不能使用全站所有文档ID作为允许集合,否则模型可能引用未读取或无权访问的资料。
稳定ID帮助映射与去重,但文档更新后仍要绑定版本和内容。相同ID指向已变化正文时,旧回答的证据链可能失效,需要版本化引用。
这个 Java 示例按固定规则检查引用是否落在允许范围内,不会判断一段自然语言是否真的证明了某个结论。因此完整应用应分别报告:引用 ID 是否存在、检索是否找对资料,以及人工核对后证据是否支持答案,不能把第一项通过当作三项都通过。
代码先调用谁,再调用谁
- 授权检索返回片段
- 构造当前允许引用集合
- 模型输出引用ID
HashSet.contains检查存在性- 再按断言核对证据支持
04动手写一个例子
覆盖证据标签的最短连续窗口
输入标签序列与所需不同标签集合,返回最短覆盖窗口的闭区间索引;并列取最早起点。无覆盖或空需求返回[-1,-1],空需求不需要证据。Java17程序内置自测。
- 输入 1
序列A,X,B,A,需求A/B- 输出 1
[2,3]
- 输入 2
序列A,需求A/B- 输出 2
[-1,-1]
右指针增加一个标签,只对需求集合中的标签计数;某标签从零变一时,已覆盖种类加一。无关标签保留在窗口里,但不增加覆盖种类。
全部种类覆盖后,不断移动左指针尝试缩短。只有左侧需求标签计数从一变零,窗口才失去覆盖;在失去覆盖前记录最短候选。
左右指针都只向前移动,每项最多进出窗口一次。发现同长度窗口不替换,保留最早起点。这个证明基于离散标签,不包含真实语义匹配成本。
为什么这样写是对的counts记录当前窗口内各需求标签的准确频次,covered等于正频次需求种类数;每次收缩前窗口覆盖全部需求,已保存答案是所有已检查有效窗口中最短且最早者。
n为序列长度,r为需求标签数;每个元素最多进入和离开一次,哈希查询平均常数。若标签为长字符串,还需计入哈希与比较字符成本。
保存为 Main.java,运行 javac --release 17 -encoding UTF-8 Main.java,再运行 java Main。程序包含固定输入自测,断言失败时会抛出错误。
import java.util.*;
public class Main {
static int[] window(List<String> tags,Set<String> required){
if(required.isEmpty())return new int[]{-1,-1}; // 空需求无需提供证据窗口。
Map<String,Integer> counts=new HashMap<>();int covered=0,left=0,bestL=-1,bestR=-1;
for(int right=0;right<tags.size();right++){
String x=tags.get(right);
if(required.contains(x)){int old=counts.getOrDefault(x,0);counts.put(x,old+1);if(old==0)covered++;}
while(covered==required.size()){
if(bestL<0||right-left<bestR-bestL){bestL=left;bestR=right;} // 只接受更短,保留最早并列。
String y=tags.get(left++);
if(required.contains(y)){int next=counts.get(y)-1;counts.put(y,next);if(next==0)covered--;}// 最后一个副本移出才失去覆盖。
}
}
return new int[]{bestL,bestR};
}
static void eq(int l,int r,int[] got){if(got[0]!=l||got[1]!=r)throw new AssertionError(Arrays.toString(got));}
public static void main(String[] args){
eq(2,3,window(List.of("A","X","B","A"),Set.of("A","B")));
eq(-1,-1,window(List.of("A"),Set.of("A","B")));
eq(-1,-1,window(List.of(),Set.of("A")));
eq(-1,-1,window(List.of("A"),Set.of()));
eq(0,1,window(List.of("A","B","A"),Set.of("A","B")));
eq(1,2,window(List.of("A","A","B"),Set.of("A","B")));
System.out.println("PASS 6 tests");
}
}这些特殊情况也要试一试
- 空需求返回无窗口而非任意片段。
- 重复标签必须计数,不能简单删除集合成员。
- 标签覆盖不证明语义支持或事实正确。
进阶选读 · 后续再读:跨片段最小证据集合
场景答案需要多个分散章节,连续窗口包含大量无关资料。
做法把每个候选片段覆盖的信息点表示成集合,在小规模信息点下用位掩码动态规划;大规模用贪心或启发式,并保留证据支持核对。
复杂度一般最小集合覆盖是NP-hard;m个信息点的小规模位掩码DP可用O(n2^m),不适用于任意巨大m。
好处与代价非连续选择节约预算,但更容易失去上下文和条件;应保留章节锚点并检查跨版本冲突。
05项目里怎么用
引用数据需要可追溯而非只可点击。保存文档版本、章节、片段内容摘要和读取权限范围,展示时再核对用户仍有访问资格。文档撤回后,旧回答可以保留“来源已撤回”的状态,不能静默改链接到另一份不同内容。
把检索和生成分别验收。先看正确资料是否进入候选与上下文,再看模型是否引用正确片段并忠于原意。相关资料未召回时,继续修改提示往往不能解决根因;资料已经齐全却回答错误,则需要研究生成约束与证据使用。
无答案集应包括语料外问题、权限外问题和缺少版本条件的问题。它们可能都无法回答,但用户提示与内部原因不同。对外说明可提供的信息边界,对内记录可复核分类,不泄露用户无权知道的文档存在性。
容易踩的坑
- 引用ID存在就认定答案被支持。
- 用全站文档集合验证本次引用,放宽读取范围。
- 把关键词覆盖算法叫作语义蕴含判断。
- 将资料不足当成需要反复逼模型补答案。
几种做法,怎么选
表格有四列,窄屏可左右滑动查看代价和适用条件。
| 方案 | 优势 | 代价与限制 | 适用条件 |
|---|---|---|---|
| 连续证据窗口 | 保留局部顺序与条件 | 可能包含无关片段 | 同章连续论证 |
| 离散片段选择 | 节约上下文并覆盖多来源 | 需要恢复上下文与冲突关系 | 跨章节综合问题 |
| 明确资料不足 | 减少无依据结论 | 部分请求无法直接满足 | 证据缺失或权限受限 |
06检验是否读懂了
先自己想、自己写,再展开答案核对。场景题是假设的练习情境;遇到还没学过的内容,可以做完基础后再回来。
先用自己的话解释
01引用存在与引用支持有什么区别?
展开参考答案与推导
存在是ID能映射到本次资料,支持是内容足以证明具体断言;前者可集合检查,后者需要语义核对。
02RAG为什么仍会幻觉?
展开参考答案与推导
检索可能漏证据、带入过期或错误片段,模型也可能误读或补充无根据内容,各层都需验收。
03为何标签重复需要计数?
展开参考答案与推导
移出一个A时窗口可能还有另一个A;只有计数降到零才真正失去该需求的覆盖。
换个情况,还会处理吗
01答案有链接但解释与原文相反怎么办?
展开参考答案与推导
记录为证据使用或断言支持失败,核对版本和限定条件;增加引用格式约束无法单独修复这种语义错误。
02用户问权限外内容,应说找到了但不能看吗?
展开参考答案与推导
避免泄露无权资源存在性,按产品授权策略说明可用范围;内部保留安全原因以便审计。
03检索为空时是否用模型常识继续答?
展开参考答案与推导
取决于明确产品模式。若要求仅依据资料,应说明不足;若允许常识,应清楚标识来源模式和不确定性,不能伪造引用。
写代码试一试
01重复标签怎样收缩?
- 输入 / 条件
A,A,B,需求A/B- 输出 / 预期
[1,2]
提示 第一个A移出后还有A。
展开参考答案与推导
初始覆盖后左移一次,A计数从二到一仍覆盖;再左移才失去覆盖,因此最短是第二个A到B。
02同长窗口如何选择?
- 输入 / 条件
A,B,A,需求A/B- 输出 / 预期
[0,1]
提示 只在长度严格更小时替换。
展开参考答案与推导
后续[1,2]同长但起点更晚,不更新答案;稳定规则便于复现。
03为何不能直接用于长文事实核验?
- 输入 / 条件
片段都含关键词但结论不同- 输出 / 预期
算法可能覆盖,仍需语义检查
提示 输入标签是题目给定。
展开参考答案与推导
程序只操作符号计数,不知道否定、版本和条件;需要额外标注或语义模型并通过人工校准。
商户项目 · 本篇加练
只用 FAQ 真正提供的依据回答
核查日期:2026-10-11。状态:新增教学练习未运行。
目标与前置知识
分别检查检索候选、真正传入模型的上下文和最终结论。
前置:只读商户工具已验收;理解资料标识、版本和租户归属。
按顺序完成
-
建立自写 FAQ A1:只证明商户 1001 支持自取,不包含停车或配送信息。为每个片段保存标识、租户、商户、版本和正文。租户范围由服务端身份构造并强制保留,不能让问题或模型替换过滤条件。
-
固定比较三种输入:A1 正常命中、检索结果为空、只找到讲自取却不能回答停车的无关片段。后两种均应说缺少停车依据;没有停车资料不能推断“不能停车”,也不能回答“可以停车”。空上下文提示只是一个约束,必须实际测回答。
-
检索候选经过重排、截断或去重后可能改变,因此分开记录命中的片段 ID/版本与真正送入模型的片段 ID/版本及顺序。教学模式用虚构材料可额外保存当次实际文本;生产默认只保存必要元数据,正文需按权限单独留存。不能把候选列表当成实际上下文。
-
将回答拆成单独结论,例如“支持自取”关联 A1 的支持语句,“09:00–18:00”关联本轮工具结果。逐项检查:引用 ID 是否存在且本轮确实可用、正文是否支持结论、依据是否挂错了结论、任何事实性结论是否漏掉依据。JSON 能解析或 Schema 校验通过不保证这些条件成立。
-
区分证据不足和证据矛盾:A1 没有停车信息是资料不足;第 10 题的今日工具 16:00 与旧资料 18:00 才是明确冲突。本题预先规定以成功获取的今日工具结果为准,并说明旧资料过时。这个规则只属于该题,不意味着工具在所有问题上永远正确。
验收与交付
- 交付三种检索输入下的候选、实际上下文与最终回答对照
- 每条事实结论都有支持它的当次证据;把 A1 错挂到营业时间、引用不存在的 A9、漏引或从自取推配送都应判失败
- 无资料与有冲突分开记录;未拿到成功工具结果时不凭空选 16:00
FAQ 与十题是虚构教学材料,尚未运行检索或模型;不声称有任何准确率。
原始来源
商户项目 · 延伸练习 · 未运行
文档换版与证据启用批次
资料核查:2026 年 10 月 14 日 12:12 JST。来源版本为 Spring AI 2.0.1,页面未标明发布日期。以下是教学设计,导入、删除和评测均未运行。
先完成文档抽取与切分及本篇的片段引用核验。已有的文档标识、版本和权限字段继续沿用;这组练习进一步检查换版尚未完成时,哪些片段能够进入回答。
VectorStore 文档提供按 ID 或元数据条件删除的接口,并用先删除旧版、再添加新版演示版本管理;示例没有给这两次调用提供原子切换保证。ETL 文档说明,原文元数据会复制到派生片段。版本选择和启用批次仍需应用自己设计。
把三种时间分开:来源发布于何时、业务规则从何时生效、程序何时采集。今天重新抓取旧网页,并不意味着规则今天才生效。沿用稳定的 sourceId,同时保存来源版本、原始 URL、采集时间、片段标识和切分配置版本;版本来自受控采集流程,不由模型猜测。内容摘要可以识别变化,不能单独证明来源真实或规则有效。
检索之后、组装上下文之前,用受控版本记录或已启用批次检查片段状态。新版未齐时,预先选择“明确标注仍在使用旧版”或“暂不可用”;不要把新旧片段混在一个“最新”标签下。版本缺失或状态读取失败也要有明确处理。这个流程不是框架自动提供的功能。
独立练习:更新、中断与撤下
- 自写同一虚构 FAQ 的两个版本,保留相同 URL,但改变一项业务规则;另加同名、不同
sourceId的文件。先记录应启用的版本及预期片段集合,再检查实际上下文和逐项引用,不能仅看回答恰好正确。 - 用本地假存储模拟旧版已失效、新版只写入部分片段,然后重跑同一导入批次。保留预期与实际片段集合、批次状态和重复记录。若采用先暂存再切换,另模拟切换失败;不要假定
add自动幂等或跨系统原子。 - 在假状态表撤下一个来源,故意让检索仍返回其旧片段。检查旧片段是否被排除在新上下文之外;没有其他有效证据时保留资料不足状态。不要用旧答案缓存或会话摘要替代新来源。
交付输入版本、事件顺序、切分配置、预期与实际片段集合、候选版本、最终使用版本和引用映射。读者应先写预测,再填实际结果;未执行字段留空。这里的撤下只模拟停止使用,未验证物理删除或保留政策;一次检索无命中不能证明彻底删除。实际存储可见性、缓存及会话联动、同步延迟和恢复时间仍需项目实测。
商户项目 · 延伸练习 · 未运行
表头、单位与例外的三阶段保留
资料核查:2026 年 10 月 14 日 18:09 JST。Spring AI ETL 文档版本为 2.0.1,页面未标明发布日期。以下练习未运行,也未制作 PDF 夹具或调用嵌入模型。
先完成文档抽取与切分,理解 DocumentReader、TokenTextSplitter 和片段元数据。本组在已有完整性检查上,分别定位抽取、切分、上下文组装丢失条件的情况。
ETL 文档中的 chunkSize 以 token 为单位,minChunkSizeChars 以字符计,minChunkLengthToEmbed 控制短片段是否收录;这些参数不能混作一种长度。中文标点与换行可以配置,2.0 起的小文本不会再因标点被额外截断。依赖 PDF 目录切段的 Reader 也不适用于所有 PDF。这些功能没有承诺自动保留表格与脚注的业务关系。
先比原文与抽取文本,再比片段,最后检查真正传入模型的上下文。原文表头若已在抽取时丢掉,增加候选数或重叠不能把它找回来。需要时把表名、列名、单位和适用条件与行内容组织成可独立理解的证据;标题只存在 metadata 中还不够,组装时也必须带入必要信息。
独立练习:定位条件在哪一步丢失
- 自写两个虚构商户的同名费用表,设置不同数值、会员档位及明确单位。用相同内容制作 Markdown 和跨页 PDF,运行前写下各问题需要的证据字段,再对照抽取结果。只保留孤立数字时,不允许猜单位或借另一商户补齐。
- 自写一条一般规则和一条改变其适用范围的短例外,故意把边界设在两者之间。比较最短片段阈值,检查例外有没有被过滤,以及相关问题能否取得它。生成的邻段摘要不能冒充原始条款。
- 让候选集同时含正确行、表头和脚注,再在组装预算处模拟脚注被截掉。分别保存候选片段 ID 与最终入模内容,区分“没有召回”和“召回后丢失”。另外使用边界附近的中文长文本检验配置,不能把文档默认值当作中文语义完整的保证。
交付原文位置、抽取文本、配置与计量单位、各块长度、表头/单位/例外的保留情况,以及候选、实际上下文和最终主张的对应表。先检查可确定的字段保留,再评估回答。token 未超限、引用能够打开,都不能单独证明证据完整。没有准确率或最佳切块长度结论;实际 Reader、编码器和模型预算仍须与项目版本核对。
商户项目 · 延伸练习 · 未运行
重复片段合并顺序与必要条款覆盖
资料核查:2026 年 10 月 16 日 06:12 JST。Spring AI RAG 文档版本为 2.0.1,发布日期未标明。检索、重排与生成实验均未运行。
先读混合检索与重排和检索评测。已有课程说明去重与候选预算的关系;这里进一步核对具体合并组件的保留顺序,并检查一般规则和例外是否仍成套存在。
Spring AI 的 Document Join说明,ConcatenationDocumentJoiner 遇到重复文档时保留首次出现项,分数原样保留;DocumentPostProcessor 可用于重排、去冗余或压缩。具体重复判断仍需核对项目实现,不能把该接口当作语义近似副本识别器。
分别记录候选数、去重后的片段数、不同来源数和必要条款覆盖。不同 URL 转载同一条款,不算多份独立证据;同一来源中的一般规则与例外,也不能因文字相近而只留其一。来源数量本身不是质量目标,授权和版本范围始终保留。
独立练习:副本、例外与输入顺序
- 自写一条一般规则及其例外,用确定的检索替身把一般规则的三份副本排在前面、例外排在第四。固定候选上限为三,分别检查不去重和取回后去重;再只改变候选上限为四,记录必要证据覆盖怎样变化。最终上下文最多放两个证据单元。数字只用于夹具,不是推荐参数;结论应区分取回范围与后处理作用。
- 为同一业务对象构造肯定、否定、例外及另一个商户的相似条款,同时保留一组完全重复项。自行声明去重判据,检查它既能处理真重复,也不会抹掉否定词、对象、版本或例外。压缩后的证据仍需保留出处和适用条件。
- 让两路检索返回同一文档但携带不同分数,交换输入顺序,检查保留项、最终次序和引用变化。记录各路原分数及后续重排分数;不要把首次保留策略写成自动分数融合,或把重复引用计作两份独立支持。
交付各分支、候选预算、片段顺序、重复判据、保留与丢弃原因、必要条款覆盖及最终入模内容。先检查确定候选的合并,再接真实检索;候选本来缺少例外和组装时丢掉例外应分别归因。目前没有召回率、token 节省、最佳 topK 或性能结论。更大的候选预算需要另测资源与延迟,去重和排序策略也需登记版本。
商户项目 · 延伸练习 · 未运行
查询改写前后的条件保持
资料核查:2026 年 10 月 16 日 12:08 JST。Spring AI RAG 文档版本为 2.0.1,发布日期未标明。以下查询改写、检索及评测练习均未运行。
先完成本篇的来源与证据记录,以及服务端授权练习。准备固定问题、必要对话历史和已经确认的商户、日期、排除条件;这里检查查询语义,不重新定义授权或时间契约。
Spring AI Query Transformation 与 Query Expansion分别提供查询改写、历史追问压缩及多查询扩展。扩展默认包含原查询,也可关闭。文档建议低温度,但低温度或保留原问题都不能保证每个分支仍保有正确条件。
把检索措辞和已确认条件分开核对。允许同义改写,但不能静默删除商户、扩大日期或丢掉“不含”。服务端继续独立附加可信授权范围,改写结果不负责生成权限。无法确定指代时,澄清或走预先声明的保守路径;不要仅为了产生一条可检索字符串而猜测。
独立练习:条件变化和历史指代
- 自拟一个同时含商户、固定日期范围及排除条件的问题,先声明日期两端的含义。用本地改写替身分别删掉商户、扩大日期、丢掉排除条件,再加一个保留全部条件的同义改写。运行前建立逐条件验收表;对多查询扩展逐分支检查,不能因列表仍含原问题就放行其他错误分支。
- 历史先查询一个商户,当前明确改查另一个、保持已确认日期不变;另设历史讨论两店、当前仅说“它呢”的歧义变体。核对独立查询、真正发给检索器的条件以及最终证据,而非只看改写日志。查询目标改变不会扩大权限:沿用本课程 A 只可读 1001 的夹具时,改查 1002 后仍应由应用按既有约定拒绝读取。
交付原问题、必要历史、已确认条件、改写/扩展文本、逐分支差异、实际检索范围、处置和证据。先用确定替身验证检测与路由,再对真实改写模型做固定用例回归,分开记录改写、检索和生成错误。最终验收以原始问题及已确认条件为准,不能拿已经漂移的查询作正确性标准。
自然语言等价不能完全靠关键词匹配判断,结构化条件抽取也需要校验。没有准确率或低温度稳定性结论;真实模型、提示和检测规则版本留待运行时记录。
商户项目 · 延伸练习 · 未运行
跨来源冲突:记录转载关系与选源理由
原核查:2026 年 10 月 18 日 00:08 JST;2026 年 10 月 20 日复核下列官方文档的来源关系、文档合并及后处理段落。W3C PROV-O 为 2013 年 4 月 30 日 Recommendation;Spring AI 文档标 2.0.1,页面未标明发布日期。以下检索、模型与回归练习均未运行。
适用:已经能处理 FAQ 冲突、来源版本与重复片段,准备组合多个来源时。先完成文档换版、重复片段合并和成对证据验收。已有练习说明转载不等于独立支持;这里继续记录转载关系的依据,并检查选择某条规则的理由。
W3C PROV-O提供派生、引用、修订和原始来源关系;引用与修订都是派生的特例,原始来源的判定仍需遵循应用领域约定。这套词汇能表达材料怎样形成,不能自动判定真假。Spring AI RAG中的文档合并与后处理用于组合、去重、排序或压缩;不能把这些处理结果直接当作业务条款冲突的裁决。
在现有 sourceId、版本和生效范围之外,只为已经取得依据的关系增加记录。例如 C 明确转载 B,就在 C 上记录 derivedFromSourceId = B,并保存支持这项关系的原文位置;关系未知就保留未知。同名域名、相似文字或不同 URL,都不足以单独证明两份材料独立或互相转载。字段名是本练习的设计,不要求部署 OWL 或知识图谱。
按具体结论列出支持、反对、适用门店、渠道、日期,以及采用或排除的理由。检索相似度、出现次序、转载数量和采集时间,都不能单独决定业务规则的效力。需求变化与产物依赖讨论的是计算结果如何依赖输入;这里检查的是不同来源之间的引用关系,两种关系需要分别记录。
独立练习:增加转载与改变适用范围
- 假设正式条款 A 写“仅限工作日”,摘要 B 误写“每天可用”,C 和 D 明确转载 B。先固定本题规则:A 已核实、适用于目标商户与日期,且没有其他有效例外。分别输入 A+B、A+B+C+D,并交换排列;预期结论不因转载增加或顺序改变而翻转。记录 C、D 各自派生自 B 的依据,以及采用 A 的理由。再移除 A 的适用范围或版本证据,预期转为待确认,不能仅凭“官方”标签继续裁决。
- 假文档 A 适用于东京站店线下,B 适用于上野店线上。先按用户已经确认的门店、渠道和日期选择规则,不能把不同范围的相反说法直接合并成冲突。再把 B 改为同门店、同渠道、同有效期,且没有明确优先依据:预期分别引用并指出冲突未解决,不能平均金额或拼出折中规则。最后补入明确修订关系及生效依据,再判断旧条款是否应排除;较晚采集本身不代表较新修订。
交付问题、候选证据、可核实的来源关系、适用性判断、保留或排除理由、最终逐项引用及剩余冲突。分别检查“选对适用材料”和“回答忠实表达”,避免偶然答对掩盖选源错误。先写预期,实际字段留待运行填写。
本节没有证明应用能自动识别转载关系;来源标注本身也可能出错,需要回到原文复核。仅使用虚构商户条款,没有真实商户结论、检索成绩或模型结果。
商户项目 · 延伸练习 · 未运行
数值过滤:让元数据门槛与正文规则一致
原核查:2026 年 10 月 19 日 00:08 JST;2026 年 10 月 20 日复核 Spring AI Vector Databases 的 SearchRequest 与 Metadata Filters。文档标 2.0.1,准确发布日期未标明。以下向量库、检索和模型练习均未运行。
适用:商户 RAG 开始按金额等数值条件筛选条款时。前置为查询条件保持、文档版本和表头、单位与例外。先固定币种、单位、商户授权范围及假文档版本;金额传输精度另行验收,这里检查过滤条件与正文规则是否一致。
Spring AI Vector Databases把 topK 作为最多返回的文档数量,similarityThreshold 限制相似度;它不是订单金额门槛。Filter.Expression 的大小比较作用于 Document 的 metadata 键值,并不会自动理解正文数字。文档还提醒 IS NULL 与 IS NOT NULL 尚未由所有向量存储实现。统一表达式接口不能证明项目后端的数字类型、缺失值和转换规则已经一致。
假条款写明:“1001 店,JPY,单笔订单金额至少 1000 日元且低于 2000 日元,适用优惠 A。”本练习固定其他资格条件满足,金额 a 的范围就是 1000 ≤ a < 2000。若 metadata 保存条款下界 minAmount 与上界 maxAmount,查询需核对 minAmount ≤ a 且 maxAmount > a;不能把用户金额与文档门槛的位置颠倒。边界值、是否包含端点、币种及原文位置都应对应同一有效版本。这是候选数据模型,不是框架自动抽取的结果。
独立练习:端点、类型与元数据漂移
- 对同一条款分别询问 999、1000、1999 和 2000 日元,按固定正文预期为不适用、适用、适用、不适用。先写这张期望表,再检查生成的过滤表达式、实际候选 ID 与回答。数字
1000、字符串"1000"、缺下界、缺币种分别留例;不假设后端自动数值转换,也不把未知下界补为零。资格过滤排除文档后,“无匹配候选”只能说明这次检索未找到;要解释不符合哪项条款,仍需取得该商户有效规则的证据。 - 保持正文下界 1000,故意把 metadata 下界改成 100,再问 500 日元。预期不能只因过滤命中就回答可用。随后交换新旧版本的 metadata 与正文,要求指出版本、原文位置和差异,将不一致材料标为待核实。再把 metadata 门槛设得过高,观察本应命中的材料可能被提前排除;这种漏召回不能只靠检查模型看见的片段发现,应通过固定文档的检索断言定位入库映射或过滤阶段。
交付原问题、已确认数值与单位、原文边界及包含关系、metadata 实际类型、后端过滤表达式、预期和实际候选 ID、入模证据及回答依据。相似度分数另列,不作为金额条件通过的凭证。实际候选和回答字段目前留空,不填写召回率或正确率。
一次 topK 检索不保证枚举全部合资格优惠;需要精确列全时,应先明确是否使用结构化规则查询。空检索也不能证明全库不存在。数值条件合法不改变授权、商户与版本范围;本节没有验证真实数据库的数值比较、模型判断或入库一致性。
读完之后,独立完成
课后作业:自己做一遍
本篇共 12 道作业,先完成 9 道基础与综合任务,再按前置知识挑战进阶题。其中包含 2 道思维拓展,试着换个条件,看看原来的办法是否还管用。不附参考答案。
能让笔记问答附上可核对引用,资料不足时说明限制,并避免读取或引用越权资料。
本篇重点加练
资料权限与断言支持同时决定回答能否交付,检索到片段只是验证链路的一部分。
- 租户和权限过滤
- 断言与证据支持
重点内容会多练几次。先说清楚怎么做,再试试空数据、出错或条件改变时会发生什么。
先自己做,卡住时记下问题,再回来查。问答题写清“为什么、什么时候适用”;动手题留下输入、输出和运行步骤,方便下次重做。
基础必做
- 作业 01原理问答
为两份同名但版本不同的Java笔记定义来源模型;解释检索负责什么、生成负责什么,以及如何让引用指向具体章节版本。
- 提交内容
- 一份独立书面回答或标注图,包含自造例子、概念边界及判断依据。
- 怎样算完成
- 逐项回应题目要求,区分事实、假设与个人判断。
- 能用自己的例子解释适用条件,记录尚未弄懂的点。
练到的知识点RAG 检索与生成分工 · 文档章节与版本元数据
- 作业 02代码推演
语料含租户A的两段和租户B的一段。按用户身份推演候选检索、过滤、截断与上下文组装,记录每一步可以出现哪些片段。
- 提交内容
- 手工推演记录,写明输入约定、中间状态、最终判断;可运行时附程序对照记录。
- 怎样算完成
- 推演包含中间过程,数据形状、单位、顺序或状态前后一致。
- 主动检查至少一个边界或异常条件,能解释手算与运行差异。
练到的知识点租户和权限过滤 · 候选片段进入上下文
- 作业 03原理问答
为一句同时引用两段资料的合成结论定义证据规则:每段允许支持哪些断言,读者对来源的权限如何参与最终验收?
- 提交内容
- 概念或合同说明、关系图与自造案例,明确事实、假设和适用条件。
- 怎样算完成
- 关键概念有明确边界,能用案例检验声明。
- 未获证据支持的假设单独标注。
练到的知识点租户和权限过滤 · 断言与证据支持
综合应用
- 作业 04面试场景
一段回答有三项断言却只附一个引用ID,其中一项来自另一版本笔记。设计人工审核表,区分引用存在、位置正确与内容支持。
- 提交内容
- 场景分析与决策记录,包含信息缺口、约束、备选方案和验证计划。
- 怎样算完成
- 方案回应给定约束,列出至少一种替代方案及代价。
- 每项关键结论说明所需证据,不能核实的部分明确标注。
练到的知识点引用 ID 与来源映射 · 断言与证据支持
- 作业 05编程实践
制作含有答案、没有答案和跨权限诱导的本地小语料,用假生成器跑RAG;分别提交检索结果与回答验收记录,不能仅用最终文本判断检索正确。
- 提交内容
- 可复现的最小程序或实验材料、自写测试、环境说明与运行记录;题目允许纸面实验时提交完整案例表。
- 怎样算完成
- 提交物按说明可以重现;测试覆盖正常、边界与失败场景。
- 运行证据与断言能核验声明的行为,注明模拟与真实执行范围。
练到的知识点空上下文拒答 · 检索与生成分别验收
- 作业 06排错实验
删除一份被引用的文档并重新导入同名文件,检查旧引用是否仍然可追溯;记录文档ID、版本、片段ID和访问状态。
- 提交内容
- 最小故障输入、复现步骤、观测记录、定位依据及回归用例。
- 怎样算完成
- 其他人可按记录复现故障,并区分现象与已验证原因。
- 定位过程有观测依据,回归用例可以再次暴露原问题。
练到的知识点文档章节与版本元数据 · 引用 ID 与来源映射 · 断言与证据支持
- 作业 07编程实践
构造同一主题的公开片段与私有片段,只让假生成器返回句子和引用ID;编写接收端校验测试,分别检验断言支持与引用访问范围。
- 提交内容
- 可复现的小程序或题目允许的离线实验、自写测试、输入和运行记录。
- 怎样算完成
- 输入、环境和运行过程可重现,测试覆盖声明的重点条件。
- 验证目标由合同确定,模拟结果不冒充真实服务证据。
练到的知识点租户和权限过滤 · 断言与证据支持
- 作业 08排错实验
模拟检索后权限被撤回、生成后来源内容被修订的时间线,检查最终交付时使用了哪一份权限与资料快照,记录不可验证的结论。
- 提交内容
- 最小故障序列、观测记录、原因核对与可再次触发原问题的测试。
- 怎样算完成
- 故障可以稳定重现,现象与已验证原因分开。
- 观测记录足以判断声明的合同是否被违反。
练到的知识点租户和权限过滤 · 断言与证据支持
- 作业 09面试场景
产品希望回答可以展示结论但隐藏出处。对公开摘要、内部规则和个人记录分别评审这种要求,提出可测试的交付政策而非统一默认放行。
- 提交内容
- 场景评审记录,包含约束、备选方案、未决信息和验证计划。
- 怎样算完成
- 方案回应题目约束,取舍能对应到可核验的事实。
- 给出失败或条件变化时的检查方式。
练到的知识点租户和权限过滤 · 断言与证据支持
进阶挑战 · 掌握前置后选做
- 作业 10设计评审
在相同标注集上比较两种上下文预算策略,记录漏召回、片段被截断和生成忽略证据的数量,说明实验中哪些变量保持不变。
- 提交内容
- 设计评审文档或对照实验报告,包含前置条件、方案取舍、验收证据与尚未验证的范围。
- 怎样算完成
- 比较使用一致条件与事先声明的标准,记录失败与未知结果。
- 说明方案的适用前提、未覆盖风险及后续验证方法。
练到的知识点租户和权限过滤 · 候选片段进入上下文 · 检索与生成分别验收
思维拓展
先写出你的猜想,再用例子或实验验证。答案可以不同,但要说清依据、适用情况,以及还有什么没弄懂。
- 作业 11思维拓展 · 反例构造
构造一个“引用ID全部存在、用户也能读取来源,但结论仍无充分支持”的例子,解释该例子推翻了哪个过强的验收假设。
- 提交内容
- 具体反例、原主张的适用前提、复现或逻辑证明及结论边界。
- 怎样算完成
- 反例满足原主张所声称的前提,确实针对其结论。
- 说明一个反例能推翻什么、不能进一步证明什么。
练到的知识点租户和权限过滤 · 断言与证据支持
- 作业 12思维拓展 · 跨域迁移
将RAG证据验收迁移到代码审查:限定本地小仓库,定义结论、文件版本、行位置与权限之间的关系,并设计资料更新后的复核实验。
- 提交内容
- 原场景与目标场景的对应表、可迁移的机制、不能迁移的前提及验证设计。
- 怎样算完成
- 逐项核对两种场景的前提,不只比较相似术语。
- 至少一个不能直接迁移的边界有具体检验方法。
练到的知识点租户和权限过滤 · 断言与证据支持
完成后,再检验一次
给每题标记“独立完成 / 查阅后完成 / 尚未完成”。查过资料或没做出的题,记下卡在哪里。隔一天换一组输入再试,能解释结果和出错原因,再把这个知识点标为掌握。
继续阅读
先看能帮你完成当前练习的部分。例子跑通后,再读更深入的解释。
- 必读实践指南英文
Spring AI:Retrieval Augmented Generation (新标签页)↗
阅读检索、查询增强、过滤和空上下文处理,按阶段设计带证据与明确失败出口的 RAG 流程。
- 实践参考文档英文
Spring AI:ETL Pipeline (新标签页)↗
先阅读
DocumentReader、Transformer、Writer 和TextSplitter,抽查提取与切分结果,再做批量入库。 - 深入参考文档英文
Sentence Transformers:Evaluation (新标签页)↗
查阅
InformationRetrievalEvaluator的 queries、corpus、相关标注与指标,建立可重跑的检索评测。 - 实践实践指南中文
动手学知识库问答:先找资料,再让模型回答 (新标签页)↗
先读第一部分的知识库搭建、问答与评估;本条只补基础流程,混合检索与重排另学。小练习:只用自己的三篇笔记准备五个问题,先检查找到的段落是否正确,再检查回答;记下“没找到”和“找到了却答错”的差别。 仓库和正文公开;部分模型接口或云环境需账号且可能收费。进阶部分仍在创作。
- 实践实践指南中文
阿里云中文:关键词结果与向量结果怎样一起看 (新标签页)↗
先读“方案介绍”,再看“添加数据”和“查询”的小例子。自拟一个型号词查询和一个意思相近的查询,分别列出希望关键词路、向量路找到的资料,并画两路合并图;这些是预期,不能伪称实测排名。首轮跳过购买、控制台配置与模型服务,保留“混合未必更好”的评测问题。 中文正文无需账号即可阅读。真正操作涉及阿里云实例和可能付费的服务;本资源只安排纸上练习,未购买、登录或部署。文中配置属于阿里云产品,不能当成其他同名项目的 API。
- 实践实践指南英文
Sentence Transformers:先找候选,再重新排队 (新标签页)↗
先看流程图及 Retrieval、Re-Ranker 两节。画五张候选卡,先移走其中唯一能支持答案的一张,再尝试只重排剩余卡;交出候选缺失和排序靠后两类失败记录。首轮跳过整套 Wikipedia 向量化与模型下载,不承诺换上重排器就能提高每个任务的效果。 文档与图公开可读。代码需要相应库、模型或语料,完整 Wikipedia 示例并非轻量本地练习。重排分数不应直接当成答案正确概率。
- 深入参考文档英文
OpenJDK 17 HashSet 源码 (新标签页)↗
按指定版本定位
HashSet.add/ contains;对照源码分析理解实际调用边界。