概述
知识库第一阶段是一个使用 FastAPI、SQLite 和本地文件系统存储构建的最低可用文件知识库。它支持经过身份验证的文档管理、嵌套文件夹、浏览器本地预览、元数据和标签、管理员工具、审计信息,以及通过模型上下文协议(Model Context Protocol,简称 MCP)为 AI 代理提供只读访问。
本阶段有意保持轻量。它不需要 Docker、PostgreSQL、MinIO、LibreOffice、ONLYOFFICE 或其他正在运行的数据库服务。PostgreSQL 和对象存储将在后续迁移中使用。
项目提供的功能
- 由管理员创建用户、登录和 JWT 身份验证。
- 支持嵌套文件夹和面包屑导航的公共知识库。
- 按文件夹查看文档列表、单文件上传和批量上传。
- 支持 PDF、文本、Markdown、HTML、图像、PowerPoint、Word 和 Excel 文件。
- 文档元数据、标签、所有者和上传者信息。
- 原始文件预览和下载。
- 在应用内阅读文本、Markdown、PDF、DOCX、XLSX、PPTX 和图像。
- 尽力提取旧版 DOC、XLS 和 PPT 文件中的文本。
- 仅所有者可编辑文档、软删除和恢复文档、重命名文件夹,以及删除空文件夹。
- 用于存放已删除文档的回收站。
- 跨范围复制文档和文件夹,包括递归复制文件夹和复制实际存储内容。
- 仅管理员可使用的用户管理、审计日志和 MCP 调用日志。
- 只读 REST API、生成的 OpenAPI 文档和 MCP 集成。
存储工作方式
应用会在 backend/data/ 下创建运行时文件。SQLite 数据库存储为 backend/data/knowledge_base.db,上传的文件和生成的 Markdown 文件则放置在 backend/data/storage/ 下。
本地存储包含路径遍历防护。现有的 Docker Compose 配置用于后续迁移到 PostgreSQL 和对象存储,本阶段无需使用。
安装后端
1. 创建环境文件
打开 PowerShell,进入仓库的 backend 目录,并将根目录环境模板复制为 backend/.env。
cd backend
Copy-Item ..\.env.example .env运行配置通过 .env.example、backend/app/core/config.py 以及 scripts/ 下的 PowerShell 控制文件定义。
2. 创建 Python 虚拟环境
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt请在 backend 目录中运行这些命令。激活虚拟环境可以将项目依赖与全局 Python 安装分隔开。
3. 初始化 SQLite
python -m app.db.init_db此命令会初始化或重新创建所需的 SQLite 表。由于重新创建表可能影响现有数据,因此在开始存储文档后请谨慎使用。
4. 启动 FastAPI
uvicorn app.main:app --reload开发服务器随后可通过 http://127.0.0.1:8000 访问。--reload 选项会在源文件发生更改时自动重新加载应用。
5. 打开 API 文档
访问 http://127.0.0.1:8000/docs,查看并试用生成的 OpenAPI 接口。
验证安装
测试要求将后端目录添加到 PYTHONPATH。在 Windows 命令提示符中运行:
set PYTHONPATH=.
python -m pytest在 PowerShell 中使用:
$env:PYTHONPATH = "."
python -m pytest仓库还在 scripts/ 下提供了独立的 PowerShell 控制文件,用于启动、重启、停止服务和查看服务状态。
通过 REST API 进行身份验证
用户由管理员创建。拥有账户后,将用户名和密码提交到登录接口。响应中会包含经过身份验证的请求所需的令牌。
$body = @{
username = "demo"
password = "password-123"
} | ConvertTo-Json
$response = Invoke-RestMethod `
-Method Post `
-Uri http://127.0.0.1:8000/api/v1/auth/login `
-ContentType "application/json" `
-Body $body
$response复制返回的访问令牌,并将其用作 Bearer 凭据。令牌权限取决于经过身份验证的用户身份和角色。
上传文档
上传接口接受 multipart 表单数据。请提供知识库 ID、可选标签、文件和 Bearer 令牌:
$token = "<access_token>"
$knowledgeBaseId = 1
curl.exe `
-X POST `
"http://127.0.0.1:8000/api/v1/documents/upload" `
-H "Authorization: Bearer $token" `
-F "knowledge_base_id=$knowledgeBaseId" `
-F "tags=制度,测试" `
-F "file=@D:\path\to\guide.txt"项目同时支持单个上传和批量上传。上传的原始文件会保留在本地存储中,支持的内容则可以在应用内阅读器中打开。
创建和使用文件夹
向文件夹接口提交知识库 ID 和名称即可创建文件夹:
$body = @{
knowledge_base_id = 1
name = "实验方案"
} | ConvertTo-Json
Invoke-RestMethod `
-Method Post `
-Uri http://127.0.0.1:8000/api/v1/folders `
-Headers @{ Authorization = "Bearer $token" } `
-ContentType "application/json" `
-Body $body要将文件上传到特定文件夹,请在 multipart 上传表单中添加 folder_id。选择文件夹后,Web 界面会自动添加该字段。
知识库选择器默认设置为 全部,表示“全部”。此视图会显示所有公开知识库中的根文档和文件夹。创建文件夹时,请在对话框中选择其目标知识库。在“所有知识库”视图中上传文件时,如果未选择文件夹,文件会上传到第一个可用的知识库。
了解浏览器本地预览
前端通过经过身份验证的 API 获取文件,将文件保存在浏览器内存中,并在本地进行渲染。DOCX、PPTX、XLS 和 XLSX 使用 vue3-office-preview,PDF 使用 @vue3-office/vue-pdf,Markdown 使用 @deot/docs-markdown。PPTX 渲染使用内置的 pptx-renderer。
此流程不需要 LibreOffice、ONLYOFFICE、Docker 或 Python 文档预览 SDK。原始文件会保留在本地存储中。Markdown 提取,以及旧版 .doc、.xls 和 .ppt 文件的回退处理,仍由后端负责。
通过 MCP 连接 AI 智能体
代码库包含一个独立的只读 MCP 服务。它与 FastAPI 应用共享 SQLite 数据库、本地存储、JWT 密钥和文档读取器。第一阶段提供的工具包括:
list_knowledge_baseslist_documentssearch_knowledgeget_documentget_document_metadata
MCP 进程无法上传、移动或删除文件,也无法管理文件夹。其文档访问权限受限于关联用户获准读取的内容。
安装 MCP 依赖
从 backend 目录创建专用的 MCP 虚拟环境:
cd backend
python -m venv .mcp-venv
.\.mcp-venv\Scripts\python.exe -m pip install -r requirements-mcp.txt通过标准输入输出运行 MCP
使用与 API 相同的数据库和存储设置配置 MCP 进程。将登录访问令牌放入 KB_MCP_TOKEN,然后启动服务器:
$env:PYTHONPATH = "."
$env:KB_MCP_TOKEN = "<access_token>"
.\.mcp-venv\Scripts\python.exe -m app.mcp_server对于本地 stdio 客户端,可以省略 KB_MCP_TOKEN。此时,智能体必须使用用户的用户名和密码调用一次 authenticate 工具。生成的短期会话仅存在于 MCP 进程内存中。
不要向 stdio MCP 服务添加普通的
print()调用。标准输出承载协议消息,因此诊断信息必须写入标准错误。
运行 MCP 冒烟测试
$env:PYTHONPATH = "."
.\.mcp-venv\Scripts\python.exe scripts\mcp_stdio_smoke.py通过 Streamable HTTP 暴露 MCP
在启动同一个 MCP 模块前,设置传输方式、监听地址、端口、路径和无状态模式:
$env:PYTHONPATH = "."
$env:MCP_TRANSPORT = "streamable-http"
$env:MCP_HOST = "0.0.0.0"
$env:MCP_PORT = "8020"
$env:MCP_PATH = "/mcp"
$env:MCP_STATELESS_HTTP = "true"
.\.mcp-venv\Scripts\python.exe -m app.mcp_server配置 HTTPS 反向代理后,公共端点可以是 https://your-domain/mcp。远程客户端必须发送 Authorization: Bearer <access_token>,并应使用与 API 连接相同的受保护 Bearer 凭据。
浏览器页面 /mcp-token.html 可以为已登录账户请求 MCP Token,而无需读取或存储其密码。管理员可以使用 /admin.html 管理用户状态、角色、密码和每个用户的 MCP Token 过期策略,包括持久的长期 Token。
高级运维提示
- 保持 API 和 MCP 设置一致。 两项服务必须指向相同的 SQLite 数据库和存储路径,并使用相同的 JWT 密钥。
- 使用最小权限身份。 MCP 智能体继承其令牌所属用户可读取的文档范围。
- 保护 Bearer 令牌。 不要将 API 或 MCP 凭据放入源代码管理系统、日志或普通控制台输出中。
- 维护 stdio 协议。 将 MCP 诊断信息发送到标准错误,而不是标准输出。
- 远程使用 HTTPS。 在将 Streamable HTTP 端点暴露到本地计算机之外之前,应将其置于 HTTPS 反向代理之后。
- 牢记第一阶段边界。 Docker Compose、PostgreSQL 和对象存储属于迁移目标,而不是当前的运行时要求。
- 检查所有权限制。 文档编辑、软删除、恢复、文件夹重命名和空文件夹删除均为仅所有者可执行的操作。
- 使用生成的 API 文档。 除了本文所示示例外,
/docs页面是检查可用请求字段和响应的最直接方式。
结论
知识库第一阶段为经过身份验证的文件组织、预览、检索和智能体访问提供了实用的本地基础。仅使用 Python、SQLite 和本地存储,即可初始化服务、上传结构化文档集合、管理文件夹和元数据,并通过本地 stdio 或远程 Streamable HTTP MCP 传输安全地暴露只读知识工具。
