基于LangChain实现带源文件关联的多文本对比式问答方案咨询
解决方案:基于LangChain实现带源文件关联的多文件对比问答
针对你遇到的分块需按文件区分、分块后保留源文件关联的问题,直接用以下步骤解决:
1. 给每个文件绑定专属元数据
加载文件时,给每个文件的Document对象添加source(文件名)和date(对应日期)元数据,这样后续分块时每个片段都会继承这些信息,不会丢失源文件关联。
代码示例:
from langchain.document_loaders import TextLoader # 先定义文件和对应日期的映射 file_date_map = { "file1.txt": "2023-04", "file5.txt": "2023-03", # 其他18个文件按需补充映射关系 } docs_with_metadata = [] for file_path, date in file_date_map.items(): loader = TextLoader(file_path) # 加载单个文件的内容 raw_doc = loader.load()[0] # 给文件添加元数据:源文件名和对应日期 raw_doc.metadata["source"] = file_path raw_doc.metadata["date"] = date docs_with_metadata.append(raw_doc)
2. 按文件独立分块,保留元数据
不要把多个文件混在一起分块,要对每个带元数据的文件单独做分块处理,这样每个文本片段都会携带所属文件的日期和源信息,完全满足按文件区分的需求。
代码示例:
from langchain.text_splitter import RecursiveCharacterTextSplitter # 配置分块参数,可根据token数调整chunk_size text_splitter = RecursiveCharacterTextSplitter( chunk_size=1000, # 每个块的字符数,对应约300-400个token chunk_overlap=200, # 块间重叠字符数,避免上下文断裂 length_function=len, ) split_docs = [] # 遍历每个带元数据的文件,单独分块 for doc in docs_with_metadata: # 对单个文件分块,每个块会继承原文件的元数据 chunks = text_splitter.split_documents([doc]) split_docs.extend(chunks)
3. 构建支持元数据对比的QA链
基于分块后的带元数据片段,使用LangChain的QA链实现对比类问答,推荐用map_reduce或refine链类型,适配大文件分块场景,同时可以自定义提示词强化元数据的利用。
基础实现代码
from langchain.chains.qa_with_sources import load_qa_with_sources_chain from langchain.llms import OpenAI # 初始化QA链,用map_reduce处理分块内容 chain = load_qa_with_sources_chain( OpenAI(temperature=0), chain_type="map_reduce" ) # 示例问题:医疗设备情绪从3月到4月的变化 query = "医疗设备相关的讨论情绪从2023年3月到4月有何变化?" # 筛选出3月和4月的所有分块片段 target_docs = [doc for doc in split_docs if doc.metadata["date"] in ["2023-03", "2023-04"]] # 执行问答 result = chain({"input_documents": target_docs, "question": query}, return_only_outputs=True) print(result["output_text"])
自定义提示词强化对比逻辑
如果默认输出不够精准,可以自定义提示词,明确要求LLM根据每个片段的日期元数据做区分对比:
from langchain.prompts import PromptTemplate # 自定义map阶段的提示词,强制关联日期元数据 map_prompt = PromptTemplate( template="""以下是来自{date}(源文件:{source})的文本内容: {page_content} 请基于这段内容,总结与问题相关的信息:{question} 输出时务必标注对应的日期。""", input_variables=["date", "source", "page_content", "question"] ) # 用自定义提示词构建链 chain = load_qa_with_sources_chain( OpenAI(temperature=0), chain_type="map_reduce", map_prompt=map_prompt )
4. 处理提及次数统计类问题
对于“某主题在各文件中的提及次数”这类需求,直接把统计要求写入提问即可,LLM会结合每个片段的元数据进行分组统计:
query = """请统计"医疗设备"在2023年3月和4月的文件中分别被提及的次数, 并说明两个月份提及内容的核心差异。""" result = chain({"input_documents": target_docs, "question": query}, return_only_outputs=True) print(result["output_text"])
内容的提问来源于stack exchange,提问作者Jay Jung
相关产品推荐
相关产品推荐

