5. 数据交互基础:从文本加载到向量存储的完整流程

引言:数据是AI的“燃料”,但如何炼油?

2025年某法律科技公司因合同处理流程低效,耗时从3小时缩短至10分钟,核心在于构建了自动化数据流水线。本文将手把手教你用LangChain + Deepseek-R1实现从原始文本到向量化存储的全流程,并解决行业级数据处理难题。


一、数据交互四部曲:从混沌到结构化
1.1 核心流程全景图
1.2 工具链选型指南(2025版)
环节推荐工具适用场景
加载TextLoader/UnstructuredLoader多格式文件读取
分块RecursiveCharacterTextSplitter通用文本分割
向量化OllamaEmbeddings本地模型轻量化部署
存储FAISS本地快速检索

二、实战:构建法律合同分析流水线
2.1 文本加载与清洗
from langchain_unstructured import UnstructuredLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
​
# 加载PDF合同
loader = UnstructuredLoader("中华人民共和国合同法.pdf", mode="elements")
documents = loader.load()
​
# 文本分块(法律条款专用参数)
splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000,
    chunk_overlap=200,
    separators=["\n\n第", "条", "\n"]
)
chunks = splitter.split_documents(documents)
2.2 向量化与本地存储(FAISS版)
from langchain_ollama import OllamaEmbeddings
from langchain_community.vectorstores import FAISS
​
# 初始化本地向量模型
embeddings = OllamaEmbeddings(model="deepseek-r1")
​
# 构建FAISS本地索引
vector_db = FAISS.from_documents(
    chunks,
    embeddings
)
​
# 保存索引到本地(无需数据库服务)
vector_db.save_local("./faiss_legal_index")
​
# 检索示例
query = "什么是借款合同?"
results = vector_db.similarity_search(query, k=3)
for result in results:
    print(result.page_content)

输出为:

WARNING: CropBox missing from /Page, defaulting to MediaBox
INFO: HTTP Request: POST http://0.0.0.0:8434/api/embed "HTTP/1.1 200 OK"
INFO: Loading faiss with AVX512 support.
INFO: Successfully loaded faiss with AVX512 support.
INFO: Failed to load GPU Faiss: name 'GpuIndexIVFFlat' is not defined. Will not load constructor refs for GPU indexes.
INFO: HTTP Request: POST http://0.0.0.0:8434/api/embed "HTTP/1.1 200 OK"
法律、行政法规规定的权利和义务订立合同。
府指导价的,按照规定履行。
条款。

2.3 自动化更新策略(FAISS版)
class AutoUpdateFAISS:  
    def __init__(self):  
        self.embeddings = OllamaEmbeddings(model="deepseek-r1")  
        self.db = None  
​
    def load_index(self, path: str):  
        self.db = FAISS.load_local(  
            folder_path=path,  
            embeddings=self.embeddings,  
            allow_dangerous_deserialization=True  # 显式允许本地加载  
        )  
​
    def add_file(self, file_path: str):  
        loader = UnstructuredLoader(file_path)  
        chunks = splitter.split_documents(loader.load())  
        if self.db is None:  
            self.db = FAISS.from_documents(chunks, self.embeddings)  
        else:  
            self.db.add_documents(chunks)  
​
    def delete_by_source(self, source: str):  
        # FAISS需手动过滤删除  
        self.db.index.remove_ids([i for i, doc in enumerate(self.db.docstore._dict.values()) if doc.metadata["source"] == source])
  

三、行业痛点解决方案
3.1 多格式文件兼容
  • 问题:扫描版PDF文字提取混乱

  • 方案:组合使用OCR与版面分析算法

# 使用OCR处理扫描件  
from langchain_community.document_loaders import UnstructuredPDFLoader  
​
loader = UnstructuredPDFLoader(  
    "scanned_contract.pdf",  
    strategy="ocr_only",  # 强制启用OCR  
    infer_table_structure=True  
)  
3.2 长文本语义连贯性
  • 问题:合同条款被错误分割

  • 方案:自定义分割逻辑

class LegalTextSplitter(RecursiveCharacterTextSplitter):  
    def __init__(self):  
        super().__init__(  
            separators=["\n\n第", "条\n", "。\n"],  
            keep_separator=True  # 保留分隔符维持上下文  
        )  

四、性能优化:本地化部署技巧
4.1 多线程加速
from multiprocessing import Pool  
​
def process_file(file_path):  
    loader = UnstructuredFileLoader(file_path)  
    chunks = splitter.split_documents(loader.load())  
    vector_db.add_documents(chunks)  
​
with Pool(8) as p:  
    p.map(process_file, file_list)  

五、避坑指南:FAISS六大陷阱
  1. 版本兼容性:不同版本的FAISS索引文件不兼容 → 固定faiss-cpu==1.7.4

  2. 内存泄漏:未限制分块大小 → 单文件超过1GB时启用分片

  3. 反序列化风险:必须显式声明allow_dangerous_deserialization=True

  4. 多线程冲突:并行写入时加锁保护

  5. 索引污染:删除操作不彻底 → 定期重建索引

  6. 硬件适配:CPU指令集不匹配 → 使用faiss-cpu通用版本


六、下期预告

《链式结构(Chain)的奥秘:从LLMChain到RouterChain》

  • 揭秘:如何像搭积木一样组合AI功能模块?

  • 实战:构建智能合同审查流水线(加载→分析→生成报告)

  • 陷阱:链式调用中的循环依赖与性能瓶颈


优质的数据交互流程,是AI从“玩具”变为“生产力工具”的关键一跃。记住:垃圾数据进,垃圾结果出——你的管道设计决定AI的智商上限!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值