You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过PDF预处理提升LLM聊天机器人的交互智能与问答精准度?

针对含相似子主题PDF的问答机器人优化方案

一、PDF预处理优化:按子主题精准分割

固定长度分割会破坏子主题的语义完整性,导致相似概念的片段混杂,优先采用基于语义/标题层级的分割策略:

  • 基于PDF标题层级拆分:利用PyMuPDF提取文档的标题(如H1、H2层级),将同一标题下的内容作为一个完整片段,避免相似子主题的内容被拆分到不同片段中。

    import fitz  # PyMuPDF
    from langchain.schema import Document
    
    def split_pdf_by_headings(pdf_path):
        doc = fitz.open(pdf_path)
        chunks = []
        current_heading = ""
        current_content = ""
    
        for page in doc:
            blocks = page.get_text("blocks")
            for block in blocks:
                text = block[4].strip()
                # 根据字体位置、样式判断标题(可根据实际PDF格式调整)
                if block[1] < 50 and "bold" in block[5].lower():
                    if current_heading and current_content:
                        chunks.append(Document(page_content=current_content, metadata={"heading": current_heading}))
                    current_heading = text
                    current_content = ""
                else:
                    current_content += text + "\n"
        # 添加最后一个子主题片段
        if current_heading and current_content:
            chunks.append(Document(page_content=current_content, metadata={"heading": current_heading}))
        return chunks
    
  • 语义感知分割:使用LangChain的RecursiveCharacterTextSplitter,通过指定段落、标题分隔符,确保拆分后的片段保留完整语义:

    from langchain.text_splitter import RecursiveCharacterTextSplitter
    
    text_splitter = RecursiveCharacterTextSplitter(
        chunk_size=1000,
        chunk_overlap=100,
        separators=["\n\n", "\n", " ", ""]
    )
    # 传入原始文档对象执行分割
    chunks = text_splitter.split_documents(raw_documents)
    

二、向量库与检索逻辑优化

1. 子主题元数据过滤检索

给每个片段添加子主题标签(从标题提取),检索时先基于元数据筛选相关子主题的片段,再进行语义匹配,减少相似概念的干扰:

from langchain.vectorstores import Chroma
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.chains import RetrievalQA

# 初始化带元数据的向量库
embeddings = OpenAIEmbeddings()
db = Chroma.from_documents(chunks, embeddings)

# 构建指定子主题的检索器
def get_topic_retriever(target_topic):
    retriever = db.as_retriever(
        search_kwargs={"filter": {"heading": {"$contains": target_topic}}, "k": 3}
    )
    return retriever

# 调用时先分析问题对应的子主题,再使用对应检索器生成回答
qa_chain = RetrievalQA.from_chain_type(
    llm=OpenAI(),
    chain_type="stuff",
    retriever=get_topic_retriever("用户问题关联的子主题")
)

2. 混合检索策略

结合关键词检索和语义检索:先用关键词匹配子主题标签缩小范围,再在范围内做语义检索,提升泛化问题的准确性:

from langchain.retrievers import BM25Retriever, EnsembleRetriever

# BM25关键词检索器(基于标题元数据)
bm25_retriever = BM25Retriever.from_documents(chunks)
bm25_retriever.k = 3

# 语义检索器
semantic_retriever = db.as_retriever(k=3)

# 加权融合两种检索结果
ensemble_retriever = EnsembleRetriever(
    retrievers=[bm25_retriever, semantic_retriever],
    weights=[0.4, 0.6]
)

# 构建混合检索的问答链
qa_chain = RetrievalQA.from_chain_type(
    llm=OpenAI(),
    chain_type="stuff",
    retriever=ensemble_retriever
)

三、LLM调用逻辑优化

1. 针对性提示词约束

在提示词中明确要求LLM先识别问题涉及的子主题,再从对应片段提取信息,避免混淆相似概念:

from langchain.prompts import PromptTemplate

prompt_template = """处理用户提问请遵循以下规则:
1. 先明确用户问题指向的具体子主题;
2. 仅从与该子主题匹配的文档片段中提取信息;
3. 不得混淆其他相似子主题的内容,确保回答精准对应问题主题。

文档片段:
{context}

用户问题:{question}

回答:"""

PROMPT = PromptTemplate(
    template=prompt_template, input_variables=["context", "question"]
)

qa_chain = RetrievalQA.from_chain_type(
    llm=OpenAI(),
    chain_type="stuff",
    retriever=ensemble_retriever,
    chain_type_kwargs={"prompt": PROMPT}
)

2. 多文档汇总链

对于需要跨子主题的泛化问题,使用MapReduceDocumentsChain先分别处理各子主题内容,再汇总生成准确回答:

from langchain.chains.summarize import load_summarize_chain
from langchain.chains import RetrievalQA

# 构建Map-Reduce汇总链
map_reduce_chain = load_summarize_chain(
    llm=OpenAI(),
    chain_type="map_reduce",
    return_intermediate_steps=False
)

# 用汇总链作为QA的核心逻辑
qa_chain = RetrievalQA.from_chain_type(
    llm=OpenAI(),
    chain_type="map_reduce",
    retriever=ensemble_retriever
)

内容的提问来源于stack exchange,提问作者Pool Nolasco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 16:48:18