Engineering note
知识库与检索增强:先让答案可追溯
这是「Agent 工程实战」的第 16 篇。专题从一个能聊天、能调工具的 .NET Agent 出发,逐步补齐可靠性、安全、测试与发布能力。
本篇要解决的问题: 从本地关键词检索出发,理解分块、来源和召回评估,再决定是否引入向量检索。
本章定位:本章从文件搜索开始介绍知识库和 RAG。你会学习文档清洗、分块、来源元数据、召回评估,以及检索工具与直接读文件的区别。
建议阅读方式:先通读原理,再对照当前项目源码,最后完成本章实践。先做可解释的本地关键词检索,再考虑向量数据库;能说清来源比先接复杂基础设施更重要。
本章导读
本章从文件搜索开始介绍知识库和 RAG。你会学习文档清洗、分块、来源元数据、召回评估,以及检索工具与直接读文件的区别。
本章采用“源码观察 → 概念拆解 → 工程改造 → 实践验证”的顺序。示例中的接口和代码骨架用于说明设计方向,真正提交代码时应结合项目当前状态逐步落地。
16.1 为什么需要 RAG
模型本身不知道你的项目文档、业务规则和最新数据。RAG 的基本流程是:把资料切分并建立索引,用户提问时检索相关片段,再把片段放入上下文。
文档 -> 清洗 -> 分块 -> 向量化 -> 索引
问题 -> 向量化 -> 检索 -> 相关片段 -> 模型
16.2 先做简单的本地检索
项目早期不必立即引入复杂向量数据库。可以先实现:
- 扫描 workspace 内的 Markdown 和 C# 文件;
- 按标题或固定长度切块;
- 用关键词倒排索引;
- 注册
search_knowledge工具; - 返回文件路径、标题、片段和相关度。
先把数据流和引用格式做对,再替换检索算法。
16.3 RAG 的质量问题
- 分块太大,召回内容难以使用;
- 分块太小,语义被切断;
- 检索结果没有来源;
- 把低相关内容塞满上下文;
- 用户问题需要结构化查询,却只做文本搜索。
每一段知识都应该带来源,最终回答尽量能够引用文件和章节。
16.4 本章交付物
DocumentLoader;Chunker;ISearchIndex;search_knowledge工具;- 检索质量样例集。
16.5 文档进入知识库前要做什么
检索质量通常在向量化之前就已经决定了一半。原始文档需要先清洗:去掉生成文件、二进制内容和明显重复内容,保留标题层级、代码块语言、文件路径和更新时间。
一个知识块至少应该带这些元数据:
public sealed record DocumentChunk(
string Id,
string SourcePath,
string Title,
int StartLine,
int EndLine,
string Content,
DateTimeOffset IndexedAt);
没有来源和行号的检索结果很难验证,也很难在最终回答中给用户可信引用。
16.6 分块不是简单截字符串
按固定字符数切分容易把一个方法从中间截断。代码仓库可以优先按类、方法和 Markdown 标题切块,再为过长块设置最大长度。
重叠窗口能避免边界信息丢失,但会增加索引大小和重复召回。初始参数应该通过样例任务调整,而不是直接照搬某个教程中的数字。
16.7 检索工具与直接读文件的区别
ReadFile 回答“我知道要看哪个文件”;search_knowledge 回答“我不知道答案在哪,请帮我找相关内容”。二者的输入和返回值不同,不应让一个万能工具同时承担。
检索工具返回的内容还要告诉模型:这是候选证据,不是绝对事实。最终回答应优先基于检索片段,遇到证据不足时明确说无法确认。
16.8 评估召回而不是只看回答
准备一组问题,每个问题标记应该召回的文件或章节。先测召回结果是否包含目标证据,再测模型能否根据证据回答。否则回答错了时,你无法判断是检索错还是生成错。
可以记录:
- top-k 结果中是否出现正确来源;
- 正确来源的排名;
- 返回片段是否覆盖必要上下文;
- 最终回答是否引用来源。
16.9 练习:给本书做本地搜索
把本书和项目 C# 文件作为第一批知识源,实现一个关键词搜索工具,支持 query、maxResults 和文件扩展名过滤。先不追求向量检索,重点练习来源、行号、截断和结果排序。
16.10 本章产出
完成本章后,Agent 不只是“能读指定文件”,还能够在未知位置的项目资料中寻找证据,并把证据来源交给用户。
单篇实战作业
实践:为本书建立关键词检索,返回文件名、标题、行号和片段,并用十个问题检查召回质量。
建议把作业拆成一个独立提交,并在提交说明中写清楚:改动前的行为、改动后的行为、验证命令、尚未解决的风险。先做可解释的本地关键词检索,再考虑向量数据库;能说清来源比先接复杂基础设施更重要。
章节复盘
复盘问题:检索结果是否包含可验证来源?如果回答错误,你能否判断是没召回还是没用对证据?
本章的完成标准不是把所有设计一次性做完,而是能把它变成项目中的一个明确边界,并为下一章留下可验证的接口。
下一篇:第 17 篇《计划、执行与反思:把多步任务变成可恢复过程》
如果你正在把 Agent 放进真实工作流,建议完成本篇的实战作业后再继续:每一步都应留下可验证的代码、测试或运行记录。