本地知识库搭建指南
概述
本地知识库(Local Knowledge Base)是企业 AI 应用的核心基础设施。通过将企业私有文档、数据转化为可检索的知识,结合大语言模型的理解能力,实现智能问答、文档分析、知识挖掘等功能。
核心架构
环境准备
系统要求
- CPU: 4核及以上
- 内存: 16GB 及以上
- 存储: 100GB SSD 及以上
- GPU: 可选,推荐用于 Embedding 加速
依赖安装
bash1# 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 作为向量存储:
bash1# Docker 启动 Milvus 2docker-compose -f milvus-standalone-docker-compose.yml up -d
或使用 PostgreSQL + pgvector:
sql1-- 创建向量扩展 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. 文档处理流程
python1from 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. 检索与问答
python1from 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"])
高级配置
混合检索策略
结合向量检索与关键词检索,提升准确性:
python1from 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)
重排序优化
使用重排序模型提升检索质量:
python1from 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)
多租户隔离
企业场景下的数据隔离方案:
python1# 为每个租户创建独立 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-zh | 1024 | 中文 | 通用中文场景 |
| BAAI/bge-m3 | 1024 | 多语言 | 多语言混合 |
| text-embedding-3 | 1536 | 多语言 | OpenAI 生态 |
| m3e-base | 768 | 中文 | 轻量级应用 |
2. 分块策略优化
python1# 按语义分块 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. 缓存策略
python1from 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)
安全与隐私
数据脱敏
python1import 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]
访问控制
python1from 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 识别
- 去除页眉页脚和页码
- 表格内容转换为结构化数据
- 图片提取并添加描述
- 敏感信息脱敏处理
持续优化
- 用户反馈收集: 记录问答质量,标记错误回答
- 增量更新: 定期处理新增文档,无需全量重建
- 监控指标: 检索延迟、回答准确率、用户满意度
- A/B 测试: 对比不同 Embedding 模型和参数效果
常见问题
Q: 如何处理扫描版 PDF?
使用 OCR 工具预处理:
python1import 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: 知识库更新如何增量处理?
python1# 计算文档指纹 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: 如何处理超长文档?
采用分层摘要策略:
- 段落级摘要
- 章节级摘要
- 文档级摘要
- 构建树状索引结构
总结
本地知识库是企业 AI 应用的基础设施,通过合理的架构设计、性能优化和安全策略,可以构建高效、可靠的智能知识管理系统。
如需技术支持,请通过以下方式联系我们:
- 邮箱:c@m9ai.work
- 官网:https://m9ai.work