尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Java RAG 实战(第 6 篇):Markdown 知识库与 RAG

Java RAG 实战(第 6 篇):Markdown 知识库与 RAG 系列导航所属专栏《Java 开发者从零实现 RAG 知识库》学习位置第 6 篇 / 共 12 篇上一篇《第5篇Embedding 与语义检索》下一篇《第7篇使用 Qdrant 保存和检索向量》本篇先不引入向量数据库只用 Markdown、内存向量检索和 qwen3 跑通完整 RAG重点看清检索资料怎样进入 Prompt。完成进度1. 把 Markdown 按二级标题切成 Chunk2. 使用 bge-m3 检索最相关的 Chunk3. 使用阈值过滤无关资料4. 把命中资料和问题组装成 Prompt5. 调用 qwen3 生成资料内回答为什么要学Embedding 和相似度只能找出“哪段文字更相关”还不会直接生成最终答案。RAG 的关键是把检索结果转换成人类可读的 Prompt再让聊天模型严格依据这些资料回答。先使用内存版可以暂时避开数据库配置把注意力集中在完整主链切分、检索、过滤、组装 Prompt 和生成回答。理解这条链路后再引入 Qdrant 才能清楚知道向量数据库替换了哪一部分。第 1 步运行内存版 Markdown RAG在引入向量数据库前先运行03-markdown-rag确认完整 RAG 并不等于 Qdrant。这个模块把知识放在 Java 内存中适合观察每一步的数据怎样流动。示例知识文件位于03-markdown-rag/knowledge/kubernetes.md程序执行顺序MarkdownKnowledgeLoader 读取 Markdown 并按二级标题切成 Chunk ↓ ChunkSearch 用 bge-m3 计算问题与全部 Chunk 的相似度 ↓ RelevantChunkSelector 过滤低于 0.60 的结果并选择 Top-2 ↓ RagPromptBuilder 把命中资料和原始问题组装成 Prompt ↓ OllamaChatClient 调用 qwen3:14b 生成最终回答运行默认问题mvn-f03-markdown-rag/pom.xml compile exec:java也可以传入自己的问题mvn-f03-markdown-rag/pom.xml compile exec:java\-Dexec.args密码、令牌和证书应该保存在哪里成功时会先打印候选 Chunk 和相似度再打印模型回答。这里的候选向量没有保存到数据库因此每次运行都会重新读取 Markdown并重新为全部 Chunk 生成 Embedding。命中资料不是由 Ollama 自动读取的。RagPromptBuilder会在 Java 中组装类似下面的内容System Prompt只能根据提供的知识库资料回答。 User Prompt 知识库资料 [Service Chunk 的标题和正文] 用户问题 Pod 重建后 IP 变化怎样提供稳定访问地址qwen3 看到的是这个 Prompt不是向量。向量只在“找资料”这一步中使用。关键代码检索结果怎样变成模型回答对应源码03-markdown-rag/src/main/java/com/example/ai/rag/MarkdownRagDemo.java 03-markdown-rag/src/main/java/com/example/ai/rag/RagPromptBuilder.javaMarkdownRagDemo先过滤结果没有合格资料时直接返回为了突出主调用链下面片段缩减了日志打印类名、方法和调用顺序与仓库源码一致。ListChunkSearch.ResultrelevantResultsselector.select(results,MIN_SIMILARITY,TOP_K);if(relevantResults.isEmpty()){System.out.println(根据现有资料无法确定。);return;}RagPromptBuilder.PromptpromptnewRagPromptBuilder().build(query,relevantResults,TOP_K);StringanswerchatClient.chat(prompt);RagPromptBuilder再把最多TOP_K条资料按顺序拼接StringBuilderuserPromptnewStringBuilder(知识库资料);intchunkCountMath.min(maxChunks,results.size());for(intindex0;indexchunkCount;index){MarkdownKnowledgeLoader.Chunkchunkresults.get(index).chunk();userPrompt.append(\n\n[资料 ).append(index1).append().append(chunk.title()).append(]\n).append(chunk.content());}userPrompt.append(\n\n用户问题\n).append(query);这是 RAG 中“检索”与“生成”真正接上的位置。前面的relevantResults来自向量检索后面的prompt才会发给 qwen3。运行这一阶段的测试mvn-f03-markdown-rag/pom.xmltest测试覆盖 Markdown 切分、检索排序、阈值过滤、Prompt 组装和 Ollama 请求解析。完成这一步后再把相同知识迁移到 Qdrant就能清楚看到向量数据库究竟替换了哪一段工作。本篇自测RAG 一定需要向量数据库吗bge-m3 和 qwen3 在这条链路中分别做什么qwen3 最终看到的是向量还是 Prompt没有资料达到阈值时为什么不调用聊天模型参考答案不一定小规模资料可以先做内存检索bge-m3 负责向量化和检索qwen3 根据资料生成回答模型看到的是组装后的 Prompt避免基于无关资料回答并减少无效调用。本篇小结完整 RAG 包含加载切分、向量检索、阈值过滤、Prompt 组装和模型生成。向量只用于寻找相关资料真正发送给 qwen3 的是人类可读的 Chunk 正文。内存版适合学习流程但每次运行都会重新计算全部知识向量。下一篇 本专栏下一篇《第7篇使用 Qdrant 保存和检索向量》完整代码都在 GitHub欢迎 Star ⭐本专栏的全部示例代码都已开源包含 5 个可独立运行的 Maven 模块、自动化测试和完整分篇教程。建议Fork / Clone下来边读边跑 https://github.com/bysbsh/ai-rag-learning-guide代码与教程同步更新对照每一篇动手实践效果最好。如果这份教程帮到了你点个Star就是对我最大的支持也方便你之后找回最新版本。遇到问题或发现错漏欢迎在仓库提 Issue / PR。项目采用 MIT 协议可自由学习与二次创作。
返回列表