我构建了一个 RAG 应用,然后问它我喜欢什么车。它竟然不知道。
我正在开发一个名为 Kenning 的文档聊天工具。它使用 RAG(检索增强生成)技术,让用户可以针对上传的文件进行提问。
我使用以下技术从零开始构建了整个流水线:
- Java 21 和 Spring Boot
- Spring AI
- PostgreSQL (配合 pgvector)
- Ollama (运行 llama3.2:3b 和 nomic-embed-text)
- Docker Compose
该流水线的工作流程如下: 上传文件 → 提取文本 → 文本分块 (Chunking) → 将分块转换为向量 → 存储在 pgvector 中 → 搜索相似分块 → 将分块 + 问题发送给模型 → 获取带有来源的答案。
系统可以运行,但我遇到了两种不同的失败。它们看起来很相似,但原因却截然不同。
失败 1:模型感到困惑。 我问:“这个项目使用了什么嵌入模型 (embedding model)?” 文档中明确给出了答案。模型也检索到了正确的文本。然而,它的回答却是“不知道”,甚至在下一句话中又重复了正确的模型名称。
我的理论:3B 模型太小了。它检索到了正确的数据,但无法给出确定的回答。换用更大的模型可能会解决这个问题。
失败 2:模型什么也没找到。 我问:“我喜欢什么汽车品牌?” 文档中提到了我喜欢 BMW。但系统返回的结果为零。相似度评分太低,未能通过我设置的阈值。
我的理论:分块稀释 (Chunk dilution)。我的测试文档很短,它将 Spring AI、OAuth2 和我的汽车偏好等许多主题混杂在同一个分块中。该分块的向量被这些主题分散(稀释)了。针对汽车的具体问题在面对一个涵盖广泛主题的分块时,其检索强度减弱了。更好的分块策略可以解决这个问题。
经验教训:
- 小模型存在推理能力的局限。
- 简单的分块方式会影响检索准确度。
- 调试“为什么”比仅仅修复错误更重要。
架构是成立的。虽然它运行缓慢,有时还会出错,但整个闭环已经完成了。
来源:https://dev.to/mido-dev/i-built-a-rag-app-then-asked-it-what-car-i-like-it-didnt-know-583n
可选学习社区:https://t.me/GyaanSetuAi
