AI 应用开发 Day4:RAG 检索器的最小可行性实现
本文基于稀土掘金开发者社区的技术分享,系统梳理了 RAG(Retrieval-Augmented Generation)检索环节的最小可行实现路径。核心在于通过关键词加权与 TopK 排序,突破传统 contains() 纯字符串匹配的语义局限。
核心技术演进路径
RAG 流程包含 Retrieve(检索)、Augment(增强)、Generate(生成)三阶段。本文聚焦 Retrieve 环节的实现升级:
- 起点:直接使用 Java 的
contains()进行关键词匹配 - 进阶:将知识库与检索逻辑解耦,支持多词典映射
- 关键升级:引入
KeywordScore加权机制,同义词/相关词多次命中则加分 - 最终架构:遍历全库→计算相关度分数→降序排序→TopK 截取
关键认知转变:关键词命中不等于语义相似。例如问题"为什么这种内存数据库性能这么高"无法被 contains("Redis") 捕获,暴露出纯字符串匹配的本质缺陷。
从单知识召回到多知识 TopK
实现过程中需解决三个实际问题:
知识库结构化存储:使用
Map<String, List<String>> semanticMap建立实体-语义词映射,如 Redis 对应 [“redis”, “缓存”, “内存数据库”, “高性能”, “key-value”]多知识同时召回:问题如"Redis 和 MySQL 有什么区别"需同时命中两个实体,不能找到首个匹配即终止
TopK 排序机制:引入常量
TOP_K = 3控制返回数量,避免超量知识挤占 LLM Prompt 上下文
测试用例显示:问题"Redis和MySQL有什么区别?“中 MySQL 命中 [“mysql”, “sql”] 得分 2,Redis 命中 [“redis”] 得分 1,最终按分数降序返回。
检索器的架构设计
完整检索流程包含五个步骤:
- 用户输入问题后转小写处理(如 “Redis为什么这么快?” → “redis为什么这么快?")
- 遍历知识库中每条知识的语义词典,统计命中次数作为原始分数
- 封装为
KnowledgeScoreDTO 携带知识文本与分数 - 按分数降序排序后截取 TopK 条目
- 提取知识文本拼接到 Prompt 的"已知知识"部分
值得注意的 Bug 反例:contains("sql") 会错误命中 “mysql”(因字符串包含关系),说明关键词方案存在虚假相关性风险。
落地建议
- 适合立即实践:中小规模知识库(< 1000 条)、语义关系明确的垂直场景(如产品文档、FAQ 系统)
- 建议再等等:需要处理多语言、同义词泛化、上下文长依赖的复杂场景,应引入 Embedding + 向量数据库方案
写在最后
当前关键词检索方案本质是"相关度计算"的简化版,其骨架结构(候选→打分→排序→截取)与后续向量检索完全一致。区别仅在于分数计算方式:从简单的字符串匹配计数,升级为语义向量的余弦相似度计算。这为深入学习 Embedding 技术提供了清晰的衔接入口。
