qinghuan
← 回到知识探索

AI 直觉 / 可下载小项目

先找证据再回答:做一个本地检索器

用八份虚构材料,亲手检查词项匹配怎样找到原文,以及它在哪些地方会误导人。

展开本文目录
  1. 下载完整练习包
  2. 先写预测,再启动程序
  3. 每一分都能指出出处
  4. 找到原句只是核对的开始
  5. 把失败也当成可观察的结果
  6. 验证规则,再做一次小改动
  7. 记住这三点
  8. 别把例子用过头
  9. 自己试一小步
  10. 查原始资料
  11. 找一份资料继续练
开始前,会这些就够了
  • 会在终端运行 Python 文件
  • 了解字符串、列表和字典
遇到不熟悉的词,先看这 2 个解释
RAG(检索增强生成)
先从外部材料中检索有关内容,再让生成模型结合这些内容回答的做法。它把找到资料与组织答案连接起来,便于利用可更新的材料,无需把每次更新都训练进参数。
引用
在生成答案的具体说法旁标出依据,让读者能返回原文检查。有效引用需要对应真实来源、相关段落和所支持的结论,不能只给一个看起来权威的链接。
打开完整术语小抄 ↗

假设你要从几份学习规则里查“借阅期限”。系统找到两句话:一份说十四天,另一份说二十一天。两句都很像问题,也都有日期。接下来真正需要检查的是:它找到了哪些原文,为什么排序靠前,以及这些材料是否足够支持一个结论。

这个微项目把过程缩小到八份明确虚构的材料,用本地程序返回匹配片段。它不调用大模型、接口或网络,也不生成回答。你可以看清每一分来自哪个词项,再观察近义词、否定句和版本冲突为什么不能只靠字面匹配解决。

把例子带到自己的电脑上

下载完整练习包

需要 Python 3.10 或更新版本。使用标准库,不需要安装第三方包。下载 ZIP 后选择“全部提取”,进入能看到 README.md 的文件夹。

下载 ZIP · 4 个文件
包里有什么
  • search.py:本地词项检索
  • verify.py:自动验证
  • notes.json:八份虚构材料
  • README.md:中文操作步骤

在这个文件夹打开 PowerShell,逐行运行

python --version
python search.py "借阅期限"
python verify.py

先预测会找到哪份材料,再运行查询并核对原文。这个练习不调用大模型、不生成回答;命中分数只用来观察字面匹配。

找不到命令或文件时,先按 README 检查环境和所在目录。文中标出的阅读时间只估算文章篇幅,安装环境和动手练习可按自己的节奏进行。

先写预测,再启动程序

下载并解压后,确认 search.py、verify.py、notes.json 和 README.md 位于同一文件夹。打开 Windows PowerShell,从它的上一级运行 Set-Location .\workshop-retrieval,再运行 python --version,确认使用 Python 3.10 或更高版本;不需要安装第三方库。

先不要急着打开结果。写下三个预测:搜索“借阅期限”会返回哪份材料,搜索“借书”能否找到同义内容,搜索“允许携带饮料”会不会排除否定句。然后运行 python .\search.py "借阅期限",把引号里的文字替换成另外两个查询,逐一对照自己的判断。

  • 使用 python .\search.py "PYTHON 练习" 观察中英文混合查询。
  • 使用 python .\search.py "火星气候" 观察没有命中的情况。
  • 使用 python .\search.py "借阅期限" --json 查看原文位置和完整结构。

每一分都能指出出处

程序给查询和正文使用同一套切分规则:英文按连续字母或数字组成的整词,中文按相邻两个基本汉字组成词项。例如“借阅期限”得到“借阅”“阅期”“期限”。这里的词项只是这个检索器的单位,不是某个语言模型的 Token,也不表示它懂中文分词。

匹配前,程序在文字副本上统一兼容字符与大小写,因此全角大写的 LIBRARY 可以找到原文中的 Library。原文没有被改写。孤立的一个汉字无法组成二元组,会提示补充查询;英文单复数、带重音字母和其他文字也没有完整的语言处理。

正文按少量标点切成片段,命中一种不同查询词项记一分,重复输入同一个词不会多得分。每份文档只保留最高分的一段,同分保留先出现的片段;文档之间同分按编号排。因此三分只表示命中三种词项,不是三成概率或可靠程度。

找到原句只是核对的开始

每条结果显示文档编号、标题、日期、原始片段和命中的词项。JSON 还记录片段在正文中的起止位置。验证程序会回到相同编号的正文,检查相应位置是否恰好等于返回片段,避免出现引用编号与文字各自看似合理、实际却没有对应的情况。

这项检查证明的是“摘录来自哪里”,还没有证明“这句话支持什么结论”。只截取一段可能漏掉后面的条件,所以要打开完整正文继续读。日期也只是材料字段;新版是否适用、旧版是否废止,需要修订记录等依据,不能由排序程序擅自决定。

把失败也当成可观察的结果

“借书”和“借阅”在日常交流中接近,但这里没有相同二元组就可能查不到。反过来,“允许携带饮料”与“不允许携带饮料”含有同样的查询词项,会得到相同分数。两个例子说明,字面重合与语义一致没有必然对应关系,得分高也可能把否定含义带进来。

查“火星气候”时,材料没有匹配项,程序明确返回未找到和空结果,不补出一个听起来合理的答案。空查询也有单独提示。没有结果不证明现实中不存在答案,只表示当前材料与当前规则没有找到匹配;此时应记录缺口,再决定是否补材料或改查询。

验证规则,再做一次小改动

运行 python .\verify.py,十四项检查覆盖中英文、空输入、无匹配、稳定排序、引用对应、日期和否定等边界。本次已在 Python 3.14.0 运行通过,所用语法和接口兼容 Python 3.10;这不等于已经在所有版本实测。看到 OK,也只说明这些既定检查通过。

继续练习时,可以只增加一组近义词映射,先预测哪些结果会改变,再运行旧测试并补充新检查。这个项目没有语义向量、复杂排序或生成步骤,也没有实现完整 RAG。它的用途是把“先找资料”拆成能解释、能核对的小过程,为以后学习更复杂系统保留比较起点。

记住这三点

  • 查询与材料使用相同切分规则,分数可以逐项追溯到原文中的命中词项。
  • 引用确实来自原文、内容与查询相似、结论正确,是需要分别检查的事情。
  • 无匹配、版本冲突和否定句同分都要如实暴露,不能用一段流畅回答掩盖缺口。

别把例子用过头

  • 中文二元组和英文整词不理解近义、语法或否定,也不覆盖所有 Unicode 文字。
  • 日期较新不自动代表适用,词项分数不是概率;片段之外还可能有决定含义的条件。
  • 短语料的粗分句可能切错英文缩写或小数;十四项测试通过不能证明生产环境检索质量。

自己试一小步

为“借书”增加一组显式近义词映射后,怎样证明你只改变了预期行为?

  1. 先记录原查询的词项、结果和无匹配状态,再写出预期变化。
  2. 明确映射作用于查询还是文档,保持返回的引用仍是原始正文。
  3. 运行已有检查,并加入能观察新映射效果及误匹配风险的例子。

做到这些,就算完成

  • 能否解释新增命中的原因,并指出它来自哪个原始片段?
  • 映射是否意外改变英文、否定句或无关问题的结果?
  • 是否仍然保留日期边界、空结果与不生成答案的行为?

查原始资料

想确认一个细节,先看这份资料对应的部分,不必从头读完所有文档。

找一份资料继续练

先选一项,按下面的范围继续学;不必从头读完整门课程。