📋 方案概述
本方案旨在构建一个基于 OpenClaw 框架的本地知识问答助手,通过向量化技术实现对本地文档的快速检索和智能问答。系统支持多种文档格式,无需依赖外部 API,完全本地化部署,确保数据安全。
🚀 快速检索
基于向量嵌入的语义检索,毫秒级响应速度,支持模糊匹配和相关性排序。
🔒 本地部署
所有数据存储在本地,无需上传到云端,保障敏感信息安全。
📚 多格式支持
重点支持 PDF、Word、Excel、PPT 等办公文档,以及 Markdown、TXT 等文本格式。
💬 自然语言
支持中文自然语言提问,无需学习复杂查询语法。
🏗️ 系统架构
四层架构设计
📥 知识采集层
文档解析 | 格式转换 | 内容提取
文档解析 | 格式转换 | 内容提取
⬇
🔍 索引引擎层
文本分块 | 向量嵌入 | 索引构建
文本分块 | 向量嵌入 | 索引构建
⬇
🧠 问答服务层
查询理解 | 混合检索 | 答案生成
查询理解 | 混合检索 | 答案生成
⬇
💻 交互界面层
Web 界面 | 飞书集成 | API 服务
Web 界面 | 飞书集成 | API 服务
核心组件选型
| 组件 | 技术选型 | 说明 |
|---|---|---|
| 向量数据库 | ChromaDB | 轻量级,无需单独部署,支持持久化存储 |
| 嵌入模型 | m3e-base / sentence-transformers | 支持中文,768 维向量,本地运行 |
| 检索框架 | LangChain + OpenClaw | 混合检索 (向量 + 关键词),可解释性强 |
| PDF 解析 | PyMuPDF + pdfplumber | 保留表格/图片位置,支持扫描件 OCR |
| Word 解析 | python-docx | 提取正文、标题、表格、批注 |
| Excel 解析 | openpyxl + pandas | 按 Sheet 分块,保留表头上下文 |
| PPT 解析 | python-pptx | 按幻灯片分块,提取演讲者备注 |
| 前端界面 | HTML + FastAPI | 简洁轻量,支持 API 调用 |
📦 部署步骤
第 1 天:环境准备
安装 Python 3.10+、pip 依赖、创建项目目录结构
# 1. 创建项目目录
mkdir -p ~/knowledge-assistant/{docs,vectors,scripts,web}
cd ~/knowledge-assistant
# 2. 创建虚拟环境
python3 -m venv venv
source venv/bin/activate
# 3. 安装核心依赖
pip install chromadb sentence-transformers langchain
pip install unstructured pymupdf python-docx openpyxl
pip install fastapi uvicorn python-multipart jinja2
第 2 天:文档索引脚本
编写文档解析和向量化索引脚本
# 核心功能
- 扫描 docs/ 目录下所有文档
- 自动解析不同格式 (md/pdf/docx/xlsx)
- 文本分块 (chunk_size=500, overlap=50)
- 生成向量嵌入并存储到 ChromaDB
- 建立倒排索引加速关键词检索
第 3 天:问答服务开发
实现查询处理和答案生成逻辑
# 查询处理流程
1. 接收用户自然语言问题
2. 生成问题向量
3. 向量相似度检索 (top_k=5)
4. 关键词 BM25 检索 (top_k=5)
5. 混合重排序 (RRF 算法)
6. 提取最相关片段作为答案
第 4 天:Web 界面开发
构建简洁的问答交互界面
# 界面功能
- 搜索框 + 提交按钮
- 答案展示区域 (支持 Markdown)
- 相关文档引用链接
- 历史查询记录
- 文档上传入口
第 5 天:OpenClaw 集成
通过 OpenClaw 工具链实现飞书消息对接
# 集成方式
1. 创建独立问答子 agent (sessions_spawn)
2. 监听飞书消息中的@提及
3. 调用本地问答 API 获取答案
4. 通过 message 工具回传飞书
第 6 天:测试优化
功能测试、性能调优、错误处理
第 7 天:上线部署
部署到 daiwang.cloud 服务器,配置 Nginx 反向代理
📄 PDF/Office 文档处理策略
✅ 针对皇上指定的知识来源,采用以下专门处理策略:
PDF 文档处理
| 文档类型 | 处理策略 | 注意事项 |
|---|---|---|
| 文字版 PDF | 直接提取文本 + 保留章节结构 | 按标题层级分块 |
| 扫描版 PDF | OCR 识别 (paddleocr/tesseract) | 需额外安装 OCR 引擎 |
| 含表格 PDF | pdfplumber 提取表格结构 | 转换为 Markdown 表格存储 |
| 含图片 PDF | 提取图片 + 图注说明 | 图片单独存储,建立索引关联 |
Office 文档处理
| 格式 | 处理策略 | 分块方式 |
|---|---|---|
| Word (.docx) | 提取正文 + 标题 + 表格 | 按章节/标题分块 |
| Excel (.xlsx) | 按 Sheet 提取 + 表头上下文 | 每 10 行作为一个知识块 |
| PPT (.pptx) | 按幻灯片提取 + 备注 | 每张幻灯片独立分块 |
依赖安装命令
# PDF 处理
pip install pymupdf pdfplumber paddleocr
# Word 处理
pip install python-docx
# Excel 处理
pip install openpyxl pandas
# PPT 处理
pip install python-pptx
# OCR 引擎 (扫描版 PDF)
pip install paddlepaddle paddleocr
📁 项目目录结构
knowledge-assistant/
├── docs/ # 知识库文档目录
│ ├── technical/ # 技术文档
│ ├── business/ # 业务资料
│ └── faq/ # 常见问题
├── vectors/ # 向量数据库存储
├── scripts/
│ ├── index_knowledge.py # 文档索引脚本
│ ├── qa_engine.py # 问答引擎核心
│ └── update_index.sh # 增量更新脚本
├── web/
│ ├── app.py # FastAPI 服务
│ ├── index.html # Web 界面
│ └── static/ # 静态资源
├── openclaw/
│ ├── qa_agent.py # OpenClaw 子 agent
│ └── config.yaml # 配置文件
├── requirements.txt # Python 依赖
└── README.md # 使用说明
💻 核心代码示例
文档索引脚本 (index_knowledge.py)
import chromadb
from sentence_transformers import SentenceTransformer
from unstructured.partition.auto import partition
# 初始化
model = SentenceTransformer('m3e-base')
client = chromadb.PersistentClient(path='./vectors')
collection = client.get_or_create_collection('knowledge')
# 文档解析
def parse_document(filepath):
elements = partition(filepath)
text = "\n\n".join([str(el) for el in elements])
return text
# 文本分块
def chunk_text(text, size=500, overlap=50):
chunks = []
start = 0
while start < len(text):
end = start + size
chunk = text[start:end]
chunks.append(chunk)
start += size - overlap
return chunks
# 建立索引
for filepath in scan_docs():
text = parse_document(filepath)
chunks = chunk_text(text)
for i, chunk in enumerate(chunks):
embedding = model.encode(chunk)
collection.add(
documents=[chunk],
embeddings=[embedding],
ids=[f"{filepath}_{i}"],
metadatas=[{"source": filepath}]
)
问答引擎 (qa_engine.py)
def query_knowledge(question, top_k=5):
# 生成问题向量
query_embedding = model.encode(question)
# 向量检索
vector_results = collection.query(
query_embeddings=[query_embedding],
n_results=top_k * 2
)
# 关键词检索 (BM25)
keyword_results = bm25_search(question, top_k=top_k)
# 混合重排序 (RRF)
reranked = reciprocal_rank_fusion(
vector_results,
keyword_results
)
# 提取答案
answer = extract_answer(reranked[:top_k], question)
return answer
🔗 OpenClaw 集成方案
✅ 集成优势
- 直接复用 OpenClaw 的 sessions_spawn 创建问答子 agent
- 通过 message 工具自动路由到飞书/企业微信
- 支持多会话并发处理,互不干扰
- 可调用 OpenClaw 的 read/exec 工具访问本地文件
集成流程
# 1. 创建问答子 agent
sessions_spawn(
runtime="subagent",
task="回答用户关于知识库的问题",
mode="session"
)
# 2. 监听飞书消息 (通过 OpenClaw 插件)
# 当收到@提及或关键词时触发
# 3. 调用本地问答 API
import requests
response = requests.post(
"http://localhost:8000/query",
json={"question": user_question}
)
answer = response.json()["answer"]
# 4. 回传飞书
message(
action="send",
channel="feishu",
to=user_id,
message=answer
)
⚠️ 注意事项
⚠️ 性能优化建议
- 首次索引大量文档时,建议使用 GPU 加速嵌入生成
- 文档超过 1000 篇时,考虑使用 HNSW 索引加速检索
- 定期清理无用文档,保持向量库精简
- 生产环境建议使用 PostgreSQL + pgvector 替代 ChromaDB
⚠️ 安全建议
- 敏感文档建议加密存储
- API 服务配置访问令牌验证
- 限制单用户查询频率 (如 10 次/分钟)
- 记录查询日志用于审计
💰 资源预算
| 项目 | 配置要求 | 成本估算 |
|---|---|---|
| 服务器 | 4 核 8G 50G SSD | ~200 元/月 |
| GPU 加速 (可选) | T4 / A10 | ~500 元/月 |
| 存储空间 | 100GB (1 万篇文档) | 包含在服务器内 |
| 开发人力 | 7 人天 | 一次性投入 |