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

Langchain PDF加载器丢失超链接问题求助

解决LangChain加载PDF时超链接丢失的问题

LangChain默认PDF加载器仅提取纯文本,不会保留超链接的关联关系,以下是几种可行的解决方法:


1. 自定义PyMuPDF加载器提取并嵌入超链接

基于PyMuPDF(fitz)的原生能力,可以直接提取页面中的超链接,并将其与文本内容绑定,比如以Markdown链接格式附加到对应页面文本中:

from langchain.document_loaders import PyMuPDFLoader
from langchain.schema import Document
import fitz

class PyMuPDFWithLinksLoader(PyMuPDFLoader):
    def load(self) -> list[Document]:
        docs = []
        with fitz.open(self.file_path) as doc:
            for page_num, page in enumerate(doc):
                # 提取页面基础文本
                text = page.get_text()
                # 获取页面所有超链接
                links = page.get_links()
                link_entries = []
                for link in links:
                    # 获取超链接对应的文本内容
                    link_text = page.get_textbox(link["from"]).strip()
                    if link_text and "uri" in link:
                        # 生成Markdown格式的链接
                        link_entries.append(f"[{link_text}]({link['uri']})")
                
                # 将超链接信息附加到页面文本末尾
                if link_entries:
                    text += "\n\n### 页面超链接:\n" + "\n".join(link_entries)
                
                # 构建包含超链接元数据的Document对象
                metadata = {
                    "source": self.file_path,
                    "page": page_num + 1,
                    "hyperlinks": link_entries
                }
                docs.append(Document(page_content=text, metadata=metadata))
        return docs

使用自定义加载器:

loader = PyMuPDFWithLinksLoader("example_data/layout-parser-paper.pdf")
data = loader.load()

2. 基于UnstructuredPDFLoader提取链接元素

Unstructured支持按元素类型提取PDF内容,可单独筛选出超链接元素并与文本合并:

from langchain.document_loaders import UnstructuredPDFLoader
from langchain.schema import Document

# 以元素模式加载PDF
loader = UnstructuredPDFLoader(
    "example_data/layout-parser-paper.pdf",
    mode="elements",
    strategy="fast"
)
elements = loader.load()

# 分离文本元素和链接元素
text_elements = [elem for elem in elements if elem.metadata["category"] == "NarrativeText"]
link_elements = [elem for elem in elements if elem.metadata["category"] == "Link"]

# 合并文本与超链接信息
full_content = "\n".join([elem.page_content for elem in text_elements])
if link_elements:
    full_content += "\n\n### 文档超链接:\n"
    for link in link_elements:
        full_content += f"- [{link.page_content}]({link.metadata['url']})\n"

# 生成最终的Document对象
final_doc = Document(page_content=full_content, metadata=elements[0].metadata)

3. 调整RetrievalQA链保留超链接格式

将带超链接的文本存入向量索引后,需通过自定义提示词引导LLM在回答中保留Markdown链接格式:

from langchain.prompts import PromptTemplate
from langchain.chains import RetrievalQA

# 自定义提示词,明确要求保留超链接格式
prompt_template = """使用以下上下文回答问题。上下文包含Markdown格式的超链接([文本](URL)),请在回答中完整保留该格式。

上下文:
{context}

问题: {question}
答案:"""
PROMPT = PromptTemplate(
    template=prompt_template, input_variables=["context", "question"]
)

# 构建带自定义提示的RetrievalQA链
chain = RetrievalQA.from_chain_type(
    llm=foundation_model,
    chain_type="stuff",
    retriever=index.vectorstore.as_retriever(),
    input_key="question",
    chain_type_kwargs={"prompt": PROMPT}
)

注意事项

  • 若PDF包含内部锚点链接(跳转到文档内其他页面),需额外处理链接的dest字段,记录目标页码
  • 文本分割时推荐使用RecursiveCharacterTextSplitter,避免拆分Markdown链接格式
  • 也可选择将超链接单独存储在Document的metadata中,检索时从metadata提取并附加到答案

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 02:58:21