如何用LangChain在Qdrant中保留Points的'tenacity'并实现CV检索
问题解答
一、在LangChain + Qdrant中保留CV分割后Points的关联性(tenacity)
你已在元数据中保存了source(CV文件路径),这是关联同一CV所有Points的核心标识,在此基础上可通过以下方式强化关联性:
写入时固化关联元数据:
分割PDF生成Document对象时,除page和source外,额外添加唯一cv_id(比如用文件名哈希生成),确保同一CV的所有Points携带相同标识。示例代码:from langchain.text_splitter import TokenTextSplitter from langchain.document_loaders import PyPDFLoader import hashlib loader = PyPDFLoader("path/to/cv.pdf") documents = loader.load() # 生成唯一cv_id cv_id = hashlib.md5(documents[0].metadata["source"].encode()).hexdigest() # 按1000token分割文本 text_splitter = TokenTextSplitter(chunk_size=1000, chunk_overlap=100) split_docs = text_splitter.split_documents(documents) # 给每个分割块添加cv_id元数据 for doc in split_docs: doc.metadata["cv_id"] = cv_id写入Qdrant时,同一CV的所有Points会带有相同的
cv_id和source,方便后续聚合。确保元数据完整存入Qdrant:
使用Qdrant.from_documents写入时,指定metadata_payload_key为默认的metadata,保证自定义元数据(cv_id、source、page)全部存入Point:from langchain.vectorstores import Qdrant from langchain.embeddings import OpenAIEmbeddings embeddings = OpenAIEmbeddings() qdrant = Qdrant.from_documents( split_docs, embeddings, url="http://localhost:6333", # 本地Docker部署的Qdrant地址 collection_name="cvs", metadata_payload_key="metadata" )
二、检索软件开发经验最丰富的CV
需结合片段检索+CV层面聚合排序实现,步骤如下:
1. 构造检索查询并获取相关片段
用针对性查询词检索关联片段,示例代码:
query = "具备多年软件开发经验,熟悉编程语言、项目全流程开发、团队协作的CV内容" # 初始化检索器,取前50个最相关片段 retriever = qdrant.as_retriever(search_kwargs={"k": 50}) relevant_docs = retriever.get_relevant_documents(query)
2. 聚合同一CV的片段得分
将同一CV的所有片段相关性得分聚合,计算平均得分(避免片段多的CV占优势):
from collections import defaultdict cv_total_score = defaultdict(float) cv_chunk_count = defaultdict(int) for doc in relevant_docs: source = doc.metadata["source"] # 提取片段的相关性得分(部分嵌入模型支持返回该字段) score = doc.metadata.get("score", 0.0) cv_total_score[source] += score cv_chunk_count[source] += 1 # 计算每个CV的平均得分 cv_avg_scores = { source: cv_total_score[source] / cv_chunk_count[source] for source in cv_total_score }
3. 按得分排序获取Top CV
对平均得分降序排序,得到经验最丰富的CV:
# 按平均得分排序 sorted_cvs = sorted(cv_avg_scores.items(), key=lambda x: x[1], reverse=True) # 输出Top 5结果 print("软件开发经验最丰富的CV:") for cv_path, score in sorted_cvs[:5]: print(f"文件路径:{cv_path},平均相关得分:{score:.4f}")
进阶优化:用LLM精准评估经验程度
若需更精准判断,可拼接同一CV的所有片段,让LLM直接评估经验丰富度:
from langchain.chat_models import ChatOpenAI from langchain.prompts import ChatPromptTemplate llm = ChatOpenAI(temperature=0) prompt = ChatPromptTemplate.from_messages([ ("system", "你是HR评估专家,针对以下CV片段,输出0-10的分数表示软件开发经验丰富程度,分数越高经验越丰富,仅输出数字。"), ("user", "CV片段内容:\n{cv_content}") ]) # 遍历排序后的CV,调用LLM评估 for cv_path, _ in sorted_cvs[:5]: # 从Qdrant取出该CV的所有片段 cv_docs = qdrant.similarity_search(query, filter={"source": cv_path}, k=10) cv_content = "\n".join([doc.page_content for doc in cv_docs]) # 获取LLM评估分数 eval_score = llm.predict(prompt.format(cv_content=cv_content)) print(f"文件路径:{cv_path},LLM评估经验分数:{eval_score}")
内容的提问来源于stack exchange,提问作者Ruby Rain
相关产品推荐
相关产品推荐

