LangChain Retriever使用问题:Pinecone检索报无`text`键错误
问题分析与修复方案
1. Pinecone数据存入的核心问题
- 缺少文本字段存储:存入向量时,metadata仅包含
user_id,未将拆分后的文本内容存入。LangChain的Pinecone VectorStore需要从metadata的text字段读取文档内容,这就是报错Found document with no 'text' key. Skipping.的直接原因。 - 向量ID重复:所有拆分后的文本块都使用同一个
user_id作为ID,会导致后续块覆盖前面的内容,最终每个用户仅保留最后一个文本块的数据。
修复后的存数据代码
def doc_preprocessing(content): doc = Document(page_content=content) text_splitter = CharacterTextSplitter( chunk_size=1000, chunk_overlap=0 ) docs_split = text_splitter.split_documents([doc]) return docs_split def embedding_db(user_id, content): docs_split = doc_preprocessing(content) # 批量准备待插入向量,提升效率 vectors_to_upsert = [] for i, doc in enumerate(docs_split): text = doc.page_content vector = embeddings.embed_query(text) # 生成唯一ID,避免数据覆盖 vec_id = f"{user_id}_chunk_{i}" vectors_to_upsert.append({ 'id': vec_id, 'values': vector, 'metadata': { "user_id": str(user_id), "text": text # 必须存入文本,供检索后读取 } }) # 批量插入向量 upsert_response = index.upsert(vectors=vectors_to_upsert)
2. 检索对话环节的问题
- 过滤器未绑定到Retriever:单独调用的
similarity_search未实际作用于后续的QA流程,且vectorstore.as_retriever()未携带用户过滤条件,导致Retriever无法仅返回当前用户的私有数据,最终机器人只能调用基础模型能力。 - 代码冗余:单独执行的
similarity_search属于无效操作,需将过滤条件整合到Retriever配置中。
修复后的对话代码
def retrieval_answer(user_id, query): text_field = "text" vectorstore = Pinecone( index, embeddings.embed_query, text_field ) # 创建带用户过滤条件的Retriever retriever = vectorstore.as_retriever( search_kwargs={ "k": 10, "filter": {"user_id": str(user_id)} } ) qa = RetrievalQA.from_chain_type( llm=llm, chain_type='stuff', retriever=retriever, return_source_documents=True # 可选,用于调试检索到的源文档 ) result = qa({"query": query}) print("Result:", result['result']) # 可选:打印源文档,确认是否正确获取用户私有数据 # print("Source Documents:", result['source_documents']) return result['result']
额外注意事项
- 确认Pinecone索引的metadata配置允许存储
text和user_id字段(默认允许,除非自定义了schema)。 - 批量插入向量比循环单条插入的性能提升显著,尤其适合大体积数据。
- 调试时开启
return_source_documents=True,可直观验证检索结果是否属于当前用户、文本内容是否正确。
内容的提问来源于stack exchange,提问作者Manoj ahirwar
相关产品推荐
相关产品推荐

