Langchain-Chatchat 数据库加密存储问答系统
在企业知识管理日益智能化的今天,如何让大型语言模型(LLM)真正理解并安全使用私有文档,成为落地 AI 应用的关键挑战。通用大模型虽然能“侃侃而谈”,但面对公司内部制度、产品手册或客户合同这类专有信息时,往往答非所问,甚至因训练数据滞后而给出错误建议。更令人担忧的是,若将敏感资料上传至云端 API,数据泄露风险陡增。
正是在这样的背景下,Langchain-Chatchat这类开源本地知识库问答系统应运而生。它不依赖公有云服务,而是把整个“大脑”——从文档解析到答案生成——全部部署在企业内网中。你上传的 PDF 手册、Word 制度文件,都会被切片、向量化、存入本地数据库,并通过加密手段保护起来。当员工提问“年假怎么休”或“报销标准是多少”时,系统不会去网上搜索,也不会调用远程 API,而是在自己的加密知识库里精准查找,再结合本地运行的大模型生成回答。
这不仅解决了“不知道”的问题,更关键的是解决了“不敢用”的顾虑。尤其对于金融、医疗、制造等对数据安全极为敏感的行业,这种“不出内网”的闭环设计,才是真正可落地的智能助手方案。
那么,这套系统是如何做到既聪明又安全的?它的核心技术链条可以概括为四个环节:读得懂、存得牢、找得快、答得准。
首先是“读得懂”。系统需要能处理各种格式的企业文档,比如扫描版 PDF、排版复杂的 Word 文件。LangChain 提供了丰富的Document Loaders,像PyPDFLoader、Docx2txtLoader等,能够准确提取文本内容。光提取还不够,长篇文档必须切成小块,否则模型无法处理。这里常用RecursiveCharacterTextSplitter,它会按段落、句子递归切分,尽量保留语义完整。一个 500 字左右、重叠 50 字的分块策略,既能保证上下文连贯,又便于后续向量化。
from langchain.document_loaders import PyPDFLoader from langchain.text_splitter import RecursiveCharacterTextSplitter loader = PyPDFLoader("company_policy.pdf") pages = loader.load() splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50) docs = splitter.split_documents(pages)接下来是“存得牢”。这些文本块不能以明文形式躺在服务器上。虽然常用的 FAISS、Chroma 等向量数据库本身不提供原生加密支持,但我们可以在文件系统层面动手脚。一个简单有效的做法是:先用pickle将整个向量库实例序列化,再通过cryptography库中的 Fernet(基于 AES-128-CBC)进行加密,最后保存为.bin文件。密钥单独存放,不在代码中硬编码。启动时自动解密加载,对检索逻辑完全透明。
import pickle from cryptography.fernet import Fernet key = Fernet.generate_key() # 实际使用应持久化保存 cipher = Fernet(key) def save_encrypted_db(db, filepath): serialized_db = pickle.dumps(db) encrypted_db = cipher.encrypt(serialized_db) with open(filepath, "wb") as f: f.write(encrypted_db) def load_encrypted_db(filepath): with open(filepath, "rb") as f: encrypted_data = f.read() serialized_db = cipher.decrypt(encrypted_data) return pickle.loads(serialized_db)这种方式成本低、兼容性好,配合操作系统级的磁盘加密(如 BitLocker 或 eCryptfs),基本能满足等保三级或 GDPR 对静态数据保护的要求。
然后是“找得快”。所有文本块都已转化为高维向量(如 BGE 模型输出的 768 维),存入 FAISS 构建索引。FAISS 的倒排索引 + 乘积量化技术,能在百万级向量中实现毫秒级相似度搜索。用户一提问,问题同样被编码为向量,系统迅速找出最相关的 top-k 个文档片段。这个过程就像是在知识海洋中投下一根带磁性的钩子,精准钓出与问题最匹配的信息碎片。
最后是“答得准”。这才是最关键的一步。有了相关片段,还需要一个“语言专家”来整合信息并生成自然流畅的回答。本地部署的 LLM,如 ChatGLM-6B 或 Qwen-7B,就扮演这个角色。通过 LangChain 的RetrievalQA链,系统自动将检索到的内容拼接成提示词(Prompt),例如:
你是一个企业知识助手,请根据以下内容回答问题:
[检索到的3个相关段落]问题:员工出差住宿标准是多少?
回答:
这种Retrieval-Augmented Generation (RAG)范式,相当于给大模型临时“开卷考试”,极大弥补了其静态知识不足的缺陷。即便是零样本任务,也能快速适应。而且,由于模型运行在本地,无需担心对话内容外泄。
from langchain.chains import RetrievalQA from langchain.llms import HuggingFacePipeline from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline model_path = "THUDM/chatglm3-6b" tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained(model_path, trust_remote_code=True) pipe = pipeline( "text-generation", model=model, tokenizer=tokenizer, max_new_tokens=512, temperature=0.7, do_sample=True ) llm = HuggingFacePipeline(pipeline=pipe) qa_chain = RetrievalQA.from_chain_type( llm=llm, chain_type="stuff", retriever=db.as_retriever(search_kwargs={"k": 3}), return_source_documents=True ) result = qa_chain({"query": "员工出差住宿标准是多少?"}) print(result["result"])整个流程跑通后,你会发现,这套系统远不止是个“问答机器人”。它的架构本质上是一个可扩展的知识中枢:
+------------------+ +---------------------+ | 用户界面 |<----->| LangChain 应用层 | | (Web/API) | | - 提问接收 | +------------------+ | - 构造检索链 | | - 调用 LLM 生成答案 | +----------+----------+ | +---------------v------------------+ | 向量数据库(FAISS/Chroma) | | - 存储加密向量索引 | | - 支持快速语义检索 | +----------------+-------------------+ | +------------------v--------------------+ | 本地嵌入模型 & 大语言模型 | | - BGE / Sentence-BERT(嵌入) | | - ChatGLM / Qwen(生成) | +---------------------------------------+ (所有组件运行于企业内网或私有云环境)所有环节都在内网闭环运行,彻底杜绝数据外传。你可以把它部署在一台配备 RTX 3060 显卡和 32GB 内存的工作站上,用 SSD 加速向量库读写。中文场景优先选择 BGE 和 ChatGLM 系列模型,它们在中文语义理解上表现更佳。如果资源紧张,还可以用 GGUF 量化格式降低显存占用,让 6B 级别的模型在消费级 GPU 上流畅运行。
对比传统方案,它的优势一目了然:
- 不用再担心把合同上传到 OpenAI 导致泄密;
- 不用忍受通用模型“凭空编造”的幻觉回答;
- 不用花几十万采购黑盒商用系统;
- 出现问题还能自己调试日志,定位是分块不合理,还是检索不准。
在金融行业的合规审查、医疗机构的病历查询、制造企业的设备维护指南等场景中,这种高安全性、高准确性的本地化智能助手,正逐渐成为数字基础设施的一部分。未来,随着小型化、高性能模型的普及,我们或许会看到每个部门都有自己的“知识代理”,而 Langchain-Chatchat 这类框架,正在为这一趋势铺平道路。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考