资料检索与问答:让模型只读命中的片段
接着真实模型调用,读取本地 JSON 资料、按关键词选出相关片段,再生成带出处的问答草稿。包含无需密钥的检索练习、真实调用、零命中与引用检查。
学习目录与本页目录
阶段 1AI Agent 基础入门阶段 2用 Python 跑通第一个回复草稿 Demo阶段 2用 Python 完成第一次真实模型调用阶段 3资料检索与问答:让模型只读命中的片段阶段 3让回复可核对:资料出处与失败边界阶段 4从本地到上线:部署前要检查什么01目标与流程02下载与文件结构03先跑检索04接入真实模型05拆解实现06验证与练习07排错与限制08下一步与资料
01本课目标:先找到资料,再生成草稿
先完成真实模型调用入门。上一课每次把三条资料全部交给模型;这次先读取本地资料文件,再按问题选出相关片段,只有命中的片段进入模型请求。目标是能分清答错发生在检索、生成,还是事实核对环节。
这里实现检索后辅助生成的最小流程。检索器是明确的关键词规则,不是向量检索、自动理解文档或自主 Agent。我们先保留可解释的基线,后续有真实漏检证据时再决定是否引入语义检索。
验证记录:2026-10-20,在服务器 Python 3.11.13 与真实 DeepSeek 接口验证了试用期限、人工确认和资料修改练习;零命中不请求模型与引用隔离另有离线检查。测试只覆盖本课样例,不代表任意资料都能正确回答。
02下载四个文件,放进同一目录
需要 Python 3.10+ 和终端基础;真实生成步骤需要你自己的 DeepSeek API Key 和可用额度。先检索可以完全离线运行。四个文件请重新下载,旧课下载过的文件也用当前版本替换,避免调用参数不匹配。
① 下载原始资料模块:reply_assistant.py ↓
② 下载模型调用模块:model_reply_assistant.py ↓
③ 下载虚构资料:retrieval_documents.json ↓
④ 下载检索问答程序:retrieval_qa.py ↓
retrieval-demo/
reply_assistant.py
model_reply_assistant.py
retrieval_documents.json
retrieval_qa.py本课实际检索的是 JSON 文件中的 5 个片段。reply_assistant.py 是上一课模型模块的导入依赖,不是检索来源。JSON 按 UTF-8 保存,Windows 请确认没有多余的 .txt 扩展名。程序从自身所在目录读取资料,不依赖你从哪个目录启动。
资料为什么分成片段?
D01 的试用规则与发送边界分别保存为 D01#1、D01#2,让引用定位到具体段落。这里的片段由人工切分,不是程序自动切块。每个片段有 id、title、text 和 keywords:
{
"id": "D01#1",
"title": "产品规则 · 试用",
"text": "体验版试用期为 7 天,包含资料检索和回复草稿。",
"keywords": ["试用", "体验", "几天"]
}这只是其中一条记录;完整文件是 JSON 数组。编号要唯一稳定,不能把两个版本共用一个编号并指望模型自行解决冲突。
03第一步:只运行检索,不需要密钥
在文件目录打开终端,运行:
python retrieval_qa.py --retrieve-onlyWindows 也可以使用 py 替代 python。输入「试用几天?」。应显示 D01#1、片段正文,以及 matched 中的「几天」「试用」;最后明确提示未调用模型。
问题:试用几天?
命中:D01#1
正文:体验版试用期为 7 天,包含资料检索和回复草稿。
命中词:几天、试用上面是阅读用的结果摘录,终端实际输出为 JSON。再运行一次,问「价格是多少?」:命中列表应为 []。先看检索对不对,再决定是否需要调模型提示词。
零命中不等于资料里一定没有答案。也可能是问法与关键词不一致。试问「能免费用多久?」:当前规则会漏掉试用片段,这是已知局限,不是应该让模型凭常识补答案的理由。
04第二步:只把命中片段发给真实模型
python retrieval_qa.py输入「试用几天?」。终端先展示检索结果,再读取你已配置的 DEEPSEEK_API_KEY;未配置时提示输入密钥,输入不回显。请用交互终端运行,密钥不要出现在源码、截图、命令历史或聊天里。文件资料是发给模型服务商的数据,只用本课虚构材料。
有命中时发起一次 DeepSeek 请求,可能计费,无自动重试。没有命中时直接提示资料不足,不读取密钥,也不请求模型。若终端不能隐藏输入,程序会停止,而不是显示明文输入。
正常回复的格式例如:
{
"status": "draft",
"draft": "体验版试用期为 7 天,包含资料检索和回复草稿。",
"sources": ["D01#1"]
}这是本轮真实测试的一次结果,措辞可能随模型变化;验收以事实和出处为准,不要求逐字相同。草稿不会自动发送。只出现模型输出不代表可以直接用于业务。
05拆开实现:检索、上下文与引用分别检查
- 读取与检查:JSON 文件最多 100 KB、1–100 个片段,要求唯一编号、非空正文与关键词。格式不对就停止,不跳过坏资料继续生成。
- 检索:把问题与关键词统一大小写,按子串匹配;按不同命中词数量降序排序,同分按编号排序,最多取 3 条。关键词是人工填写的,不是模型提取的。
- 构建上下文:只取命中项的 id、title、text。matched 用于你观察检索,不作为额外事实发送;未命中的正文不会进入本次请求。
- 生成:复用上一课的固定官方 HTTPS 调用、JSON 输出、响应大小限制和失败处理,没有让模型决定工具或发送动作。
- 校验引用:允许引用的编号集合来自本次命中片段。即便 D04#1 存在于整个资料库,没进入本次请求也不能出现在 sources 中。
hits = retrieve(question, documents)
if not hits:
# 返回资料不足,不请求模型
...
selected = [
{key: hit[key] for key in ('id', 'title', 'text')}
for hit in hits
]
result = generate(question, api_key, selected)这是流程摘录,完整错误处理见下载源码。命中词数量不是正确概率;编号合法也不代表每个事实都得到片段支持。比如引用 D01#1 却回答「试用 30 天」,仍需人工判错。
06验收与练习:记录检索和回答两份结果
建议用「问题|命中编号|是否调用模型|期望事实|实际草稿|是否通过」记录,不保存密钥。逐个重新运行以下测试:
- 试用几天?命中 D01#1;调用模型;回答 7 天,引用 D01#1。
- 部署后会自动发送吗?命中 D01#2 与 D02#1;回答不会自动发送、需人工检查;引用支持该结论的 D01#2,允许不引用无关的部署资源说明。
- 价格是多少?零命中;明确未调用模型,不能出现价格。
- 能免费用多久?当前规则零命中;把它记成检索漏检,不能把 missing 当作业务资料完整性证明。
练习一:补一个同义入口
在 JSON 的 D01#1 的 keywords 中加入「免费用多久」,保留其他字段和 JSON 语法,保存后重新运行 --retrieve-only。再问「能免费用多久?」应命中 D01#1。它只是路由词,不意味着资料承诺免费;回答仍只能依据正文。
练习二:验证资料变化
将 D01#1 的 text 中 7 天改成 14 天,保存并重新运行真实问答。应回答 14 天、引用 D01#1。本轮已实际验证该步骤;完成后改回 7 天。不要改原始 Python 基线中的资料,也不要用固定输出替代模型测试。
练习三:移除资料
备份 JSON,暂时移除 D01#1 整条记录并保持逗号合法,再问「试用几天?」。应零命中且不请求模型;恢复备份后重复检索。资料文件在每次启动时重新读取,没有后台索引更新任务。
自检:检索列表为空,增加提示词能让模型看到文件里的答案吗?
不能。程序在零命中时没有请求模型;应先检查资料文件、问法与关键词。检索到的片段没有覆盖问题时,也不能靠增加语气要求补出事实。先定位失败环节,再决定改资料、检索规则或生成约束。
07排错与工程限制
- No module named:四个文件是否在同一目录?是否漏下原始依赖?
- unexpected argument / 参数数量错误:重新下载模型模块,新版允许传入命中片段,仍兼容上一课的两参数调用。
- 资料格式失败:检查 JSON 数组、双引号、逗号、字段与编号唯一性;不支持 PDF、Word 或任意文件夹自动扫描。
- 有资料却零命中:先运行 --retrieve-only,看问法与关键词;调整资料或检索规则,不先扩大模型上下文。
- 命中但答不全:命中的片段也可能缺少结论依据,模型可返回 missing;组合问题可能只命中一部分,不能默认为已完整回答。
- 401/402/429 或网络错误:沿用上一课的接口排查。源码直接 HTTPS 连接,不自动接入系统代理;不要关闭证书验证。
- 越界引用、坏 JSON 或截断:程序拒绝交付,不把半截文字标成成功。降低问题复杂度、核对模型参数后手动重试。
本课没有权限过滤、恶意文档防护保证、版本冲突处理、向量召回或线上服务。外部材料里的命令仍是资料,不能授权程序执行动作。真实业务需先确认资料授权、访问权限、更新规则和人工审核责任。
08下一步:把引用核对做成习惯
继续阅读资料出处与失败边界,用本课命中记录逐条核对回复事实;再进入部署检查。网站没有开放使用作者密钥的访客问答接口,读者在自己的环境用自己的额度运行。
本课的关键词计数、排序与取 3 条属于教学设计,不是通用最优检索参数。先积累漏检、误检和回答偏离资料的具体样例,再决定是否加同义词、改片段边界,或评估语义检索;不为技术名词增加复杂度。
模型接口与 JSON 输出参数于 2026-10-20 核对官方说明:DeepSeek Chat Completions、JSON Output。示例使用 Python 标准库,无第三方框架依赖。真实调用验证环境为 Python 3.11.13,离线检查环境为 Python 3.14.2。