非分割类型的文档转换器 - 学习总结

11 阅读6分钟

非分割类型的文档转换器 - 学习总结

概述

本目录展示了 LangChain 中不进行文档分割,而是对整个文档进行转换的处理器。这类转换器不会改变文档数量,而是对文档内容进行增强或转换。

核心概念

非分割类型文档转换器的特点

  1. 不改变文档数量:输入 N 个文档,输出 N 个文档
  2. 内容增强/转换:
    • 问答对提取(用于 RAG 检索增强)
    • 翻译(多语言支持)
    • 总结生成
    • 信息提取
  3. 保持结构:原文内容保留在 page_content,增强信息存储在 metadata

与分割器的区别

类型输入文档数输出文档数主要作用
分割器 (TextSplitter)1多个将长文档切分成小块
转换器 (Transformer)NN对文档内容进行增强或转换

实际应用架构

原始文档 -> 加载器 -> 文档转换器(问答/翻译) -> 向量化 -> RAG 检索

文件详解

1. 问答转换器示例.py

用途:使用 Doctran 库从文档中自动提取问答对

核心功能

  • 使用 DoctranQATransformer 从文档中提取关键信息
  • 自动生成 3-5 个基于文档内容的问答对
  • 问答对存储在文档的 metadata

示例代码

from langchain_community.document_transformers import DoctranQATransformer
from langchain_core.documents import Document

# 构建转换器
qa_transformer = DoctranQATransformer(openai_api_model="moonshot-v1-8k")

# 转换文档
transformer_documents = qa_transformer.transform_documents(documents)

# 获取问答对
for qa in transformer_documents[0].metadata.get("questions_and_answers"):
    print("问答数据:", qa)

使用场景

  • RAG 系统中增强文档检索
  • 自动生成 FAQ
  • 文档知识提取

注意事项

  • 需要安装 doctran 库
  • 依赖 Doctran 服务
  • 可能存在网络连接问题

2. 自定义问答转换器.py(推荐)

用途:使用 LangChain 原生功能实现自定义问答转换器(不依赖 Doctran)

核心功能

  • 使用 ChatOpenAI + ChatPromptTemplate 实现问答提取
  • 支持多种 API(SiliconFlow、Moonshot、OpenAI)
  • 自动根据 API_BASE 选择合适的模型
  • JSON 格式输出,易于解析
  • 完善的错误处理

核心类结构

class CustomQATransformer:
    """自定义问答转换器,使用LLM从文档中提取问答对"""

    def __init__(self, openai_api_model: str = "gpt-3.5-turbo", temperature: float = 0)
    def transform_documents(self, documents: list[Document]) -> list[Document]

关键实现

  1. 提示模板设计:
qa_extraction_prompt = ChatPromptTemplate.from_template("""
你是一个专业的文档分析师。请从以下文档中提取3-5个最重要的问答对。

要求:
1. 的问题应该基于文档内容,能够帮助读者理解文档的核心信息
2. 答案应该简洁明了,直接来自文档内容
3. 问答对应该涵盖文档的主要话题

文档内容:
{document}

请以JSON格式返回,格式如下:
{{
    "questions_and_answers": [
        {{"question": "问题1", "answer": "答案1"}},
        {{"question": "问题2", "answer": "答案2"}}
    ]
}}
""")
  1. 自动模型选择逻辑:
API_BASE = os.getenv("OPENAI_API_BASE", "")
if "siliconflow" in API_BASE.lower():
    DEFAULT_MODEL = "Qwen/Qwen2.5-7B-Instruct"
elif "moonshot" in API_BASE.lower():
    DEFAULT_MODEL = "moonshot-v1-8k"
else:
    DEFAULT_MODEL = "gpt-3.5-turbo"
  1. JSON 解析处理:
# 处理可能包含代码标记的 JSON
content = result.content.strip()
if content.startswith("```json"):
    content = content[7:]
if content.startswith("```"):
    content = content[3:]
if content.endswith("```"):
    content = content[:-3]
content = content.strip()
qa_data = json.loads(content)

使用示例

# 创建转换器
qa_transformer = CustomQATransformer(openai_api_model="moonshot-v1-8k")

# 执行转换
transformer_documents = qa_transformer.transform_documents(documents)

# 访问问答对
for qa in transformer_documents[0].metadata.get("questions_and_answers", []):
    print(f"问题: {qa['question']}")
    print(f"答案: {qa['answer']}")

优势

  • 不依赖第三方 Doctran 库
  • 更灵活的提示词控制
  • 更好的错误处理
  • 支持批量处理
  • 适配多种 LLM API

3. 2 翻译.py

用途:实现文档翻译功能,保持文档结构不变

核心功能

  • 使用 LLM 进行文档翻译
  • 支持任意目标语言
  • 保持原文格式和结构
  • 返回翻译后的新文档

完整实现代码

def translate_documents(documents, target_language="English", model="moonshot-v1-8k"):
    """
    翻译文档内容到目标语言

    Args:
        documents: LangChain Document对象列表
        target_language: 目标语言
        model: 使用的模型名称
    """
    # 初始化LLM
    llm = ChatOpenAI(model=model, temperature=0)

    # 创建翻译提示模板
    prompt = ChatPromptTemplate.from_messages([
        ("system", "你是一个专业的翻译助手。请将以下文本翻译成{target_language},保持原文的格式和结构。"),
        ("human", "{text}")
    ])

    # 创建翻译链
    chain = prompt | llm

    translated_docs = []
    for doc in documents:
        # 调用翻译
        response = chain.invoke({
            "text": doc.page_content,
            "target_language": target_language
        })
        # 创建新的翻译文档
        translated_docs.append(Document(page_content=response.content))

    return translated_docs

使用示例

# 翻译为英文
translator_documents = translate_documents(documents, target_language="English")

# 翻译为日文
translator_documents = translate_documents(documents, target_language="Japanese")

# 翻译为法文
translator_documents = translate_documents(documents, target_language="French")

使用场景

  • 多语言文档处理
  • 跨语言 RAG 系统
  • 本地化文档生成
  • 国际化支持

应用场景

1. RAG 系统增强

在 RAG(检索增强生成)系统中使用问答转换器:

# 原始文档
documents = loader.load()

# 提取问答对增强检索
qa_transformer = CustomQATransformer()
enhanced_docs = qa_transformer.transform_documents(documents)

# 向量化
vectorstore.add_documents(enhanced_docs)

# 检索时可以匹配问题,提高召回率

2. 多语言知识库

构建支持多语言的知识库:

# 加载中文文档
documents = loader.load()

# 翻译为英文
en_docs = translate_documents(documents, target_language="English")

# 合并中英文文档
all_docs = documents + en_docs

# 构建向量库
vectorstore.add_documents(all_docs)

3. 文档预处理流水线

from langchain_core.documents import Document

# 完整的文档处理流程
def process_documents(raw_documents):
    # 1. 提取问答对
    qa_transformer = CustomQATransformer()
    docs_with_qa = qa_transformer.transform_documents(raw_documents)

    # 2. 翻译为英文(可选)
    en_docs = translate_documents(docs_with_qa, target_language="English")

    # 3. 合并所有文档
    final_docs = docs_with_qa + en_docs

    return final_docs

技术要点

1. 文档转换器的设计模式

所有文档转换器都应遵循相同的接口:

class DocumentTransformer:
    def transform_documents(self, documents: list[Document]) -> list[Document]:
        """转换文档列表,返回转换后的文档列表"""
        pass

2. Metadata 使用规范

增强信息应存储在 metadata 中:

new_doc = Document(
    page_content=original_content,  # 保持原文
    metadata={
        **original_metadata,         # 保留原有元数据
        "questions_and_answers": [], # 新增增强信息
        "language": "en"             # 其他元数据
    }
)

3. 错误处理策略

try:
    # 尝试解析和处理
    result = process_document(doc)
except Exception as e:
    print(f"处理失败: {e}")
    # 返回原始文档,确保流程继续
    return doc

4. 批量处理优化

# 可以添加并发处理提高效率
from concurrent.futures import ThreadPoolExecutor

def transform_documents_parallel(self, documents, max_workers=5):
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        results = list(executor.map(self._transform_single, documents))
    return results

依赖项

核心依赖

# LangChain 核心
pip install langchain langchain-openai langchain-community

# 环境变量管理
pip install python-dotenv

# 可选:Doctran(如果使用 DoctranQATransformer)
pip install doctran

环境变量配置

创建 .env 文件:

# OpenAI 兼容 API 配置
OPENAI_API_BASE=https://api.moonshot.cn/v1
OPENAI_API_KEY=your_api_key_here

# 或者使用 SiliconFlow
# OPENAI_API_BASE=https://api.siliconflow.cn/v1
# OPENAI_API_KEY=your_siliconflow_key

学习建议

  1. 理解转换器与分割器的区别
  2. 掌握自定义转换器的实现方法
  3. 学习如何在 RAG 系统中应用转换器
  4. 实践多语言文档处理
  5. 构建完整的文档处理流水线

扩展阅读