329 lines
14 KiB
Markdown
329 lines
14 KiB
Markdown
# HuiBrain - 中文直播教育知识库系统
|
||
|
||
基于 FastAPI 的中文直播教育知识库系统,支持直播文字稿导入、OCR 截图识别、AI 语义搜索、企业微信机器人、MCP 协议等功能。
|
||
|
||
## 功能特性
|
||
|
||
### 知识库管理
|
||
- **多格式导入**: Markdown(解析 frontmatter + 按 `##` 标题分页)/ 纯文本 / Word 文档(.docx,按 Heading 分页)
|
||
- **批量导入**: 支持多文件批量导入、整个目录导入,实时进度显示
|
||
- **智能分块**: 按段落边界切分文本,保留重叠区域(默认 chunk_size=300, overlap=50)
|
||
- **向量嵌入**: 支持 MiniMax / OpenAI / 智谱 / DashScope / 本地 BGE 五种嵌入模型
|
||
- **知识导出**: 支持 JSON 和 Markdown 两种格式导出
|
||
- **索引重建**: 支持单页面重新生成嵌入向量
|
||
|
||
### 图片 OCR
|
||
- **多 Provider**: DeepSeek Vision / PaddleOCR / 阿里云 / 腾讯云,支持 `auto` 自动 fallback(PaddleOCR → DeepSeek → 阿里云 → 腾讯云)
|
||
- **批量处理**: 支持拖拽上传、选择文件、选择文件夹、服务器路径批量导入
|
||
- **上传去重**: OCR 识别后自动检查内容是否已存在,避免重复录入
|
||
- **图片管理**: 网页端管理所有图片,支持一键去重、手动删除
|
||
- **并发控制**: 通过 asyncio.Semaphore 控制 OCR 并发数量(可配置 1-10)
|
||
|
||
### AI 搜索
|
||
- **知识库搜索**: LIKE 关键词搜索 + LLM 查询扩展(生成语义相近的替代表述)
|
||
- **图片搜索**: MiniMax M2.7 语义匹配,SSE 流式实时返回结果
|
||
- **并发池**: 最多 10 个 LLM 请求并发,每批数量可配置
|
||
- **实体检测**: 自动识别知识点、技巧、人物、概念等实体类型
|
||
- **可配置参数**: 搜索返回数量、LLM 批量判断数量、OCR 并发数量均可在网页端动态修改
|
||
|
||
### 企业微信机器人
|
||
- **WebSocket 长连接**: 基于 wecom-aibot-python-sdk,无需公网 IP
|
||
- **关键词搜索**: 用户发文字 → 清理口语化前缀 → 搜索图片 → 流式回复文本 + 逐张发送图片
|
||
- **图片自动入库**: 用户发图片 → 下载解密 → OCR 识别 → 自动去重入库 → 回复结果
|
||
- **分片上传**: 支持大图片的三步分片上传(init → chunk → finish)
|
||
- **欢迎语**: 进入会话时自动发送欢迎语
|
||
- **集成启动**: 后端启动时自动检测配置并拉起机器人(BotManager 后台线程)
|
||
- **网页端管理**: 在设置页面配置 Bot ID / Secret,支持在线重启
|
||
|
||
### MCP 协议
|
||
- **MCP Server**: 支持 stdio 和 sse 两种传输协议,可被外部 AI Agent 直接调用
|
||
- **5 个工具**:
|
||
- `search_knowledge`: 语义搜索知识库
|
||
- `get_page`: 获取知识页面详情
|
||
- `list_courses`: 列出所有课程
|
||
- `get_page_chunks`: 获取页面的分块内容
|
||
- `search_images`: 根据关键字搜索已 OCR 识别的聊天截图
|
||
- **命令行入口**: `huibrain-mcp`(通过 pyproject.toml 定义)
|
||
|
||
### 其他
|
||
- **运行时配置**: 所有参数均可通过网页端设置 API 动态修改,无需重启服务
|
||
- **服务测试**: 网页端支持在线测试嵌入模型、LLM、OCR 服务连通性
|
||
- **Docker 部署**: 单容器部署,轻量级
|
||
|
||
## 技术栈
|
||
|
||
| 层级 | 技术 | 说明 |
|
||
|------|------|------|
|
||
| 后端框架 | FastAPI + Uvicorn | 异步 Python Web 框架 |
|
||
| ORM | SQLAlchemy 2.0 (async) | 异步 ORM |
|
||
| 数据库 | SQLite (aiosqlite) | 轻量级,WAL 模式 |
|
||
| 配置管理 | pydantic-settings | 环境变量 / .env 文件加载 |
|
||
| 前端 | 纯 HTML + CSS + JS | 苹果风格 SPA 单页应用 |
|
||
| OCR | DeepSeek Vision / PaddleOCR / 阿里云 / 腾讯云 | 4 种 Provider + auto fallback |
|
||
| LLM | MiniMax M2.7 / DeepSeek / OpenAI | 搜索匹配、查询扩展、批量判断 |
|
||
| 嵌入模型 | MiniMax / OpenAI / 智谱 / DashScope / 本地 BGE | 5 种嵌入 Provider |
|
||
| 搜索 | LIKE 关键词 + LLM 查询扩展 | 知识库搜索;图片搜索走 LLM 语义匹配 |
|
||
| 企业微信 | wecom-aibot-python-sdk | WebSocket 长连接模式 |
|
||
| MCP | mcp[cli] >= 1.2.0 | Model Context Protocol |
|
||
| 部署 | Docker + docker-compose | 单容器部署 |
|
||
|
||
## 项目结构
|
||
|
||
```
|
||
huibrain/
|
||
├── app/
|
||
│ ├── __init__.py # 包初始化,定义版本号
|
||
│ ├── main.py # FastAPI 入口,路由注册,生命周期管理,BotManager
|
||
│ ├── config.py # pydantic-settings 配置管理(所有环境变量)
|
||
│ ├── database.py # SQLite 异步数据库连接管理
|
||
│ ├── wework_bot.py # 企业微信智能机器人服务(WebSocket 长连接)
|
||
│ ├── api/
|
||
│ │ └── v1/
|
||
│ │ ├── pages.py # 知识页面 CRUD(列表/详情/创建/更新/删除/重建索引)
|
||
│ │ ├── search.py # 语义搜索(向量+全文混合)
|
||
│ │ ├── images.py # 图片 OCR + AI 搜索(SSE 流式)+ 去重 + 删除
|
||
│ │ ├── import_export.py # 文件导入(.md/.txt/.docx)+ 目录导入 + 导出(JSON/Markdown)
|
||
│ │ └── settings.py # 系统设置 + 机器人管理 + 服务测试 + 统计信息
|
||
│ ├── models/
|
||
│ │ └── base.py # ORM 模型(KnowledgePage, KnowledgeChunk, OCRImage, WebsiteSettings)
|
||
│ ├── schemas/
|
||
│ │ ├── ocr.py # OCR 相关 Schema
|
||
│ │ ├── page.py # 页面相关 Schema
|
||
│ │ └── search.py # 搜索相关 Schema
|
||
│ ├── services/
|
||
│ │ ├── ocr_service.py # OCR 识别服务(4 种 Provider + auto fallback)
|
||
│ │ ├── llm_service.py # LLM 服务(聊天/查询扩展/批量判断)
|
||
│ │ ├── search_service.py # 知识库搜索服务(LIKE 关键词搜索)
|
||
│ │ ├── embedding_service.py # 嵌入模型服务(5 种 Provider)
|
||
│ │ ├── import_service.py # 文件导入服务(分块+向量化)
|
||
│ │ └── page_service.py # 页面 CRUD 服务
|
||
│ └── mcp/
|
||
│ └── server.py # MCP Server 实现(5 个工具供 AI Agent 调用)
|
||
├── static/
|
||
│ └── index.html # 前端单页应用(苹果风格 SPA)
|
||
├── data/
|
||
│ ├── images/ # 图片存储目录
|
||
│ └── transcripts/ # 转写文字稿(.docx/.md)
|
||
├── docs/
|
||
│ ├── IMAGE_API_GUIDE.md # 图片 API 集成指南
|
||
│ └── 软著材料/ # 软件著作权申请材料
|
||
├── .env.example # 环境变量模板
|
||
├── .gitignore # Git 忽略规则
|
||
├── pyproject.toml # Python 项目元数据 + 构建配置
|
||
├── requirements.txt # Python 依赖清单
|
||
├── Dockerfile # Docker 镜像构建
|
||
└── docker-compose.yml # Docker Compose 编排
|
||
```
|
||
|
||
## 数据模型
|
||
|
||
| 模型 | 表名 | 说明 |
|
||
|------|------|------|
|
||
| `KnowledgePage` | knowledge_pages | 知识页面(标题/内容/来源/课程/讲师/日期/向量嵌入) |
|
||
| `KnowledgeChunk` | knowledge_chunks | 文本分块(关联页面/分块索引/内容/嵌入向量) |
|
||
| `OCRImage` | ocr_images | OCR 图片记录(文件路径/OCR文本/置信度/Provider/状态/文本块) |
|
||
| `WebsiteSettings` | website_settings | 网站设置(键值对,单例模式) |
|
||
|
||
## 快速开始
|
||
|
||
### 1. 环境准备
|
||
|
||
```bash
|
||
# 克隆项目
|
||
git clone <repo-url>
|
||
cd huibrain
|
||
|
||
# 复制配置文件
|
||
cp .env.example .env
|
||
|
||
# 安装依赖(Python >= 3.11)
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
### 2. 配置 .env
|
||
|
||
编辑 `.env` 文件,至少配置以下项:
|
||
|
||
```env
|
||
# 数据库(默认 SQLite,无需额外配置)
|
||
DATABASE_URL=sqlite+aiosqlite:///data/hui_brain.db
|
||
|
||
# OCR(使用 DeepSeek Vision)
|
||
OCR_PROVIDER=deepseek
|
||
DEEPSEEK_API_KEY=your-deepseek-api-key
|
||
DEEPSEEK_BASE_URL=http://your-ollama-host:11434/v1
|
||
DEEPSEEK_OCR_MODEL=deepseek-ocr:latest
|
||
|
||
# LLM(用于搜索匹配)
|
||
MINIMAX_API_KEY=your-minimax-api-key
|
||
MINIMAX_BASE_URL=https://api.minimaxi.com/v1
|
||
MINIMAX_CHAT_MODEL=MiniMax-M2.7
|
||
|
||
# 企业微信机器人(可选,不配则不启动)
|
||
WEWORK_BOT_ENABLED=true
|
||
WEWORK_BOT_ID=your-bot-id
|
||
WEWORK_BOT_SECRET=your-bot-secret
|
||
```
|
||
|
||
### 3. 启动服务
|
||
|
||
```bash
|
||
uvicorn app.main:app --host 0.0.0.0 --port 8765
|
||
```
|
||
|
||
启动后会自动检测企业微信机器人配置,如果 `WEWORK_BOT_ENABLED=true` 且 `WEWORK_BOT_ID` / `WEWORK_BOT_SECRET` 已配置,机器人会自动在后台线程启动。
|
||
|
||
访问 http://localhost:8765 即可使用。
|
||
|
||
### 4. Docker 部署
|
||
|
||
```bash
|
||
docker-compose up -d
|
||
```
|
||
|
||
- 单容器部署,数据持久化通过 `./data:/app/data` 卷挂载
|
||
- 默认端口 8000,可通过 `APP_PORT` 环境变量调整
|
||
- 内置健康检查,每 30 秒检查 `/health` 端点
|
||
|
||
## 图片搜索工作流
|
||
|
||
```
|
||
用户上传图片
|
||
→ OCR 识别文字(DeepSeek Vision / PaddleOCR / 阿里云 / 腾讯云,支持 auto fallback)
|
||
→ 检查 OCR 内容是否已存在(去重)
|
||
→ 存入 SQLite
|
||
|
||
用户搜索 "孩子不想上学"
|
||
→ LLM 查询扩展(生成语义相近的替代表述)
|
||
→ 从 DB 倒序取图片(每批 N 张,可配置)
|
||
→ 并发池发给 MiniMax M2.7 判断
|
||
→ 匹配结果通过 SSE 实时推送到前端
|
||
→ 找够指定数量或遍历完 DB 后结束
|
||
```
|
||
|
||
## 企业微信机器人
|
||
|
||
### 功能
|
||
|
||
| 场景 | 说明 |
|
||
|------|------|
|
||
| 单聊发关键词 | 清理口语化前缀 → 搜索图片 → 流式回复文本 + 逐张发送图片 |
|
||
| 单聊发图片 | 下载解密 → OCR 识别 → 自动去重入库 → 回复结果 |
|
||
| 进入会话 | 自动发送欢迎语 |
|
||
|
||
### 配置
|
||
|
||
1. 在企业微信管理后台创建智能机器人,开启 API 模式(长连接)
|
||
2. 获取 Bot ID 和 Secret
|
||
3. 在 `.env` 中配置或通过网页端设置页面配置
|
||
|
||
### 注意事项
|
||
|
||
- 图片消息**仅支持单聊**,群聊中发图片不会触发机器人
|
||
- 机器人支持多人同时使用(asyncio 异步架构)
|
||
- 大图片支持分片上传(init → chunk → finish)
|
||
- 配置修改后可通过网页端「重启机器人」按钮生效
|
||
|
||
## API 概览
|
||
|
||
### 知识页面
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/api/v1/pages` | 知识页面列表(分页) |
|
||
| GET | `/api/v1/pages/{id}` | 获取知识页面详情 |
|
||
| POST | `/api/v1/pages` | 创建知识页面 |
|
||
| PUT | `/api/v1/pages/{id}` | 更新知识页面 |
|
||
| DELETE | `/api/v1/pages/{id}` | 删除知识页面 |
|
||
| POST | `/api/v1/pages/{id}/rebuild-index` | 重建页面嵌入索引 |
|
||
|
||
### 搜索
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| POST | `/api/v1/search` | 关键词搜索知识库 |
|
||
|
||
### 图片 OCR
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| POST | `/api/v1/images/recognize` | 上传并识别图片(两步:先上传再识别) |
|
||
| POST | `/api/v1/images/recognize-direct` | 一步上传并识别图片 |
|
||
| POST | `/api/v1/images/batch-recognize` | 批量上传并识别 |
|
||
| POST | `/api/v1/images/import-path` | 服务器路径批量导入 |
|
||
| GET | `/api/v1/images/search` | AI 搜索图片(SSE 流式) |
|
||
| GET | `/api/v1/images` | 获取图片列表(分页) |
|
||
| GET | `/api/v1/images/{id}` | 获取图片识别结果 |
|
||
| DELETE | `/api/v1/images/{id}` | 删除图片 |
|
||
| POST | `/api/v1/images/dedup` | 一键去重 |
|
||
|
||
### 导入导出
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| POST | `/api/v1/import/file` | 导入文件(.md/.txt/.docx) |
|
||
| POST | `/api/v1/import/directory` | 导入整个目录 |
|
||
| GET | `/api/v1/export` | 导出知识库(JSON/Markdown) |
|
||
|
||
### 系统设置
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/api/v1/settings` | 获取系统设置 |
|
||
| PUT | `/api/v1/settings` | 更新系统设置 |
|
||
| GET | `/api/v1/settings/stats` | 获取统计信息 |
|
||
| POST | `/api/v1/settings/test/embedding` | 测试嵌入模型连通性 |
|
||
| POST | `/api/v1/settings/test/llm` | 测试 LLM 服务连通性 |
|
||
| POST | `/api/v1/settings/test/ocr` | 测试 OCR 服务连通性 |
|
||
| GET | `/api/v1/settings/bot/status` | 获取机器人状态 |
|
||
| POST | `/api/v1/settings/bot/restart` | 重启机器人 |
|
||
|
||
### 系统
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/health` | 健康检查 |
|
||
|
||
## 配置说明
|
||
|
||
### OCR Provider
|
||
|
||
| Provider | 说明 | 额外配置 |
|
||
|----------|------|----------|
|
||
| `deepseek` | DeepSeek Vision(推荐,支持 Ollama 自部署) | `DEEPSEEK_API_KEY`, `DEEPSEEK_BASE_URL` |
|
||
| `paddleocr` | 本地 PaddleOCR(免费、离线) | 无 |
|
||
| `aliyun` | 阿里云 OCR | `ALIYUN_OCR_ACCESS_KEY`, `ALIYUN_OCR_SECRET` |
|
||
| `tencent` | 腾讯云 OCR | `TENCENT_OCR_SECRET_ID`, `TENCENT_OCR_SECRET_KEY` |
|
||
| `auto` | 自动 fallback(PaddleOCR → DeepSeek → 阿里云 → 腾讯云) | 配置多个 Provider |
|
||
|
||
### 嵌入模型
|
||
|
||
| Provider | 说明 | 额外配置 |
|
||
|----------|------|----------|
|
||
| `minimax` | MiniMax 嵌入 | `MINIMAX_API_KEY` |
|
||
| `openai` | OpenAI 嵌入(兼容硅基流动等第三方接口) | `OPENAI_API_KEY` |
|
||
| `zhipu` | 智谱 AI 嵌入 | `ZHIPU_API_KEY` |
|
||
| `dashscope` | 阿里云 DashScope | `DASHSCOPE_API_KEY` |
|
||
| `local_bge` | 本地 BGE 模型 | `LOCAL_BGE_MODEL_PATH` |
|
||
|
||
### 网页端可配置参数
|
||
|
||
| 参数 | 说明 | 默认值 | 范围 |
|
||
|------|------|--------|------|
|
||
| 搜索返回数量 | 每次搜索最多返回多少条匹配结果 | 3 | 1-10 |
|
||
| LLM 批量判断数量 | 每批发给 LLM 判断的图片数量 | 10 | 1-50 |
|
||
| OCR 并发数量 | 多用户同时上传时 OCR 并发识别数量 | 1 | 1-10 |
|
||
|
||
## 架构设计
|
||
|
||
- **策略模式**: OCR 和嵌入服务均使用抽象基类 + 工厂模式,支持多 Provider 热切换
|
||
- **单例模式**: EmbeddingService、OCRService、LLMService 均为类方法单例,支持 `reset()` 重置
|
||
- **异步架构**: 全异步(FastAPI + SQLAlchemy async + asyncio),企业微信机器人在后台线程独立事件循环运行
|
||
- **SSE 流式**: 图片搜索使用 Server-Sent Events 实时推送结果,前端可即时展示
|
||
- **并发控制**: OCR 并发通过 Semaphore 控制,LLM 搜索通过并发池(最多 10 个)控制
|
||
- **运行时配置**: 所有参数均可通过网页端设置 API 动态修改,无需重启服务
|
||
|
||
## 许可证
|
||
|
||
MIT
|