进阶教程更新于 2025-02-09

本地知识库搭建指南

学习如何构建企业级本地知识库,实现私有数据的智能检索与问答

知识库RAG向量数据库数据安全

本地知识库搭建指南

概述

本地知识库(Local Knowledge Base)是企业 AI 应用的核心基础设施。通过将企业私有文档、数据转化为可检索的知识,结合大语言模型的理解能力,实现智能问答、文档分析、知识挖掘等功能。

核心架构

环境准备

系统要求

  • CPU: 4核及以上
  • 内存: 16GB 及以上
  • 存储: 100GB SSD 及以上
  • GPU: 可选,推荐用于 Embedding 加速

依赖安装

bash
1# Python 环境
2python -m pip install langchain langchain-community
3
4# 向量数据库
5pip install pymilvus  # 或 pgvector
6
7# 文档解析
8pip install pypdf unstructured
9
10# Embedding 模型
11pip install sentence-transformers

快速开始

1. 初始化向量数据库

使用 Milvus 作为向量存储:

bash
1# Docker 启动 Milvus
2docker-compose -f milvus-standalone-docker-compose.yml up -d

或使用 PostgreSQL + pgvector:

sql
1-- 创建向量扩展
2CREATE EXTENSION IF NOT EXISTS vector;
3
4-- 创建知识库表
5CREATE TABLE knowledge_base (
6    id SERIAL PRIMARY KEY,
7    content TEXT,
8    embedding VECTOR(768),
9    metadata JSONB,
10    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
11);

2. 文档处理流程

python
1from langchain.document_loaders import PyPDFLoader, DirectoryLoader
2from langchain.text_splitter import RecursiveCharacterTextSplitter
3from langchain.embeddings import HuggingFaceEmbeddings
4from langchain.vectorstores import Milvus
5
6# 加载文档
7loader = DirectoryLoader(
8    "./documents",
9    glob="**/*.pdf",
10    loader_cls=PyPDFLoader
11)
12documents = loader.load()
13
14# 文档分块
15text_splitter = RecursiveCharacterTextSplitter(
16    chunk_size=500,
17    chunk_overlap=50,
18    separators=["\n\n", "\n", "。", ";", " "]
19)
20chunks = text_splitter.split_documents(documents)
21
22# 创建 Embedding
23embeddings = HuggingFaceEmbeddings(
24    model_name="BAAI/bge-large-zh-v1.5"
25)
26
27# 存入向量库
28vector_store = Milvus.from_documents(
29    documents=chunks,
30    embedding=embeddings,
31    connection_args={"host": "localhost", "port": "19530"},
32    collection_name="company_knowledge"
33)

3. 检索与问答

python
1from langchain.chains import RetrievalQA
2from langchain.llms import OpenAI
3
4# 创建检索器
5retriever = vector_store.as_retriever(
6    search_type="similarity",
7    search_kwargs={"k": 5}
8)
9
10# 构建 RAG 链
11qa_chain = RetrievalQA.from_chain_type(
12    llm=OpenAI(),
13    chain_type="stuff",
14    retriever=retriever,
15    return_source_documents=True
16)
17
18# 提问
19result = qa_chain({"query": "公司的年假政策是什么?"})
20print(result["result"])

高级配置

混合检索策略

结合向量检索与关键词检索,提升准确性:

python
1from langchain.retrievers import BM25Retriever, EnsembleRetriever
2
3# BM25 关键词检索
4bm25_retriever = BM25Retriever.from_documents(chunks)
5bm25_retriever.k = 5
6
7# 向量检索
8vector_retriever = vector_store.as_retriever(search_kwargs={"k": 5})
9
10# 融合检索
11ensemble_retriever = EnsembleRetriever(
12    retrievers=[bm25_retriever, vector_retriever],
13    weights=[0.3, 0.7]
14)

重排序优化

使用重排序模型提升检索质量:

python
1from langchain.retrievers import ContextualCompressionRetriever
2from langchain.retrievers.document_compressors import CrossEncoderReranker
3
4# 重排序模型
5reranker = CrossEncoderReranker(model="BAAI/bge-reranker-large")
6
7# 压缩检索器
8compression_retriever = ContextualCompressionRetriever(
9    base_compressor=reranker,
10    base_retriever=vector_retriever
11)

多租户隔离

企业场景下的数据隔离方案:

python
1# 为每个租户创建独立 Collection
2from pymilvus import Collection, FieldSchema, CollectionSchema, DataType
3
4def create_tenant_collection(tenant_id):
5    fields = [
6        FieldSchema(name="id", dtype=DataType.INT64, is_primary=True),
7        FieldSchema(name="content", dtype=DataType.VARCHAR, max_length=65535),
8        FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=768),
9        FieldSchema(name="metadata", dtype=DataType.JSON),
10        FieldSchema(name="tenant_id", dtype=DataType.VARCHAR, max_length=64)
11    ]
12    
13    schema = CollectionSchema(fields)
14    collection = Collection(f"knowledge_{tenant_id}", schema)
15    
16    # 创建索引
17    index_params = {
18        "metric_type": "COSINE",
19        "index_type": "IVF_FLAT",
20        "params": {"nlist": 1024}
21    }
22    collection.create_index("embedding", index_params)
23    return collection

性能优化

1. Embedding 模型选择

模型维度语言适用场景
BAAI/bge-large-zh1024中文通用中文场景
BAAI/bge-m31024多语言多语言混合
text-embedding-31536多语言OpenAI 生态
m3e-base768中文轻量级应用

2. 分块策略优化

python
1# 按语义分块
2from langchain.text_splitter import SemanticChunker
3
4semantic_splitter = SemanticChunker(
5    embeddings,
6    breakpoint_threshold_type="percentile",
7    breakpoint_threshold_amount=95
8)
9
10# 按结构分块(Markdown)
11from langchain.text_splitter import MarkdownHeaderTextSplitter
12
13markdown_splitter = MarkdownHeaderTextSplitter(
14    headers_to_split_on=[("#", "Header 1"), ("##", "Header 2")]
15)

3. 缓存策略

python
1from langchain.cache import InMemoryCache
2import langchain
3
4# 启用缓存
5langchain.llm_cache = InMemoryCache()
6
7# 或使用 Redis 缓存
8from langchain.cache import RedisCache
9import redis
10
11redis_client = redis.Redis(host='localhost', port=6379)
12langchain.llm_cache = RedisCache(redis_client)

安全与隐私

数据脱敏

python
1import re
2
3def desensitize_text(text):
4    # 手机号脱敏
5    text = re.sub(r'1[3-9]\d{9}', lambda m: m.group()[:3] + '****' + m.group()[7:], text)
6    # 身份证号脱敏
7    text = re.sub(r'\d{17}[\dXx]', lambda m: m.group()[:6] + '********' + m.group()[14:], text)
8    # 邮箱脱敏
9    text = re.sub(r'(\w{2})\w+@(\w+)', r'\1***@\2', text)
10    return text
11
12# 处理前对文档进行脱敏
13chunks = [desensitize_text(chunk) for chunk in chunks]

访问控制

python
1from functools import wraps
2
3def require_permission(permission):
4    def decorator(func):
5        @wraps(func)
6        def wrapper(user, *args, **kwargs):
7            if permission not in user.permissions:
8                raise PermissionError("Access denied")
9            return func(user, *args, **kwargs)
10        return wrapper
11    return decorator
12
13@require_permission("knowledge:read")
14def query_knowledge_base(user, query):
15    # 查询逻辑
16    pass

最佳实践

文档预处理清单

  • 扫描件需先 OCR 识别
  • 去除页眉页脚和页码
  • 表格内容转换为结构化数据
  • 图片提取并添加描述
  • 敏感信息脱敏处理

持续优化

  1. 用户反馈收集: 记录问答质量,标记错误回答
  2. 增量更新: 定期处理新增文档,无需全量重建
  3. 监控指标: 检索延迟、回答准确率、用户满意度
  4. A/B 测试: 对比不同 Embedding 模型和参数效果

常见问题

Q: 如何处理扫描版 PDF?

使用 OCR 工具预处理:

python
1import pytesseract
2from pdf2image import convert_from_path
3
4images = convert_from_path("scan.pdf")
5text = "\n".join([pytesseract.image_to_string(img, lang='chi_sim+eng') for img in images])

Q: 知识库更新如何增量处理?

python
1# 计算文档指纹
2import hashlib
3
4def get_doc_fingerprint(filepath):
5    with open(filepath, 'rb') as f:
6        return hashlib.md5(f.read()).hexdigest()
7
8# 只处理新增或修改的文档
9existing_ids = set(get_existing_ids())
10new_docs = [doc for doc in all_docs if doc.id not in existing_ids]

Q: 如何处理超长文档?

采用分层摘要策略:

  1. 段落级摘要
  2. 章节级摘要
  3. 文档级摘要
  4. 构建树状索引结构

总结

本地知识库是企业 AI 应用的基础设施,通过合理的架构设计、性能优化和安全策略,可以构建高效、可靠的智能知识管理系统。

如需技术支持,请通过以下方式联系我们: