WeKnora deployment source with the reviewed wiki identity, summary and recovery fixes
Anydoc / anydoc parser engine (push) Canceled after 0s
App / Format, vet, test, and build (push) Canceled after 0s
CLI / test (macos-latest / go 1.26) (push) Canceled after 0s
CLI / test (ubuntu-latest / go 1.26) (push) Canceled after 0s
CLI / test (windows-latest / go 1.26) (push) Canceled after 0s
Build and Push Docker Image / build-ui (push) Canceled after 0s
Build and Push Docker Image / build-docreader (push) Canceled after 0s
Build and Push Docker Image / build-sandbox (push) Canceled after 0s
Build and Push Docker Image / build-app (amd64, linux/amd64, ubuntu-latest) (push) Canceled after 0s
Build and Push Docker Image / build-app (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
DocReader / Python tests and Go client tests (push) Canceled after 0s
Build & Publish (dsh-weknora) / Typecheck, test, pack (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (pinned) (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (latest, advisory) (push) Canceled after 0s
Frontend / Test, type-check, and build (push) Canceled after 0s
Go Lint Cache / warm lint cache (.) (push) Canceled after 0s
Go Lint Cache / warm lint cache (cli) (push) Canceled after 0s
Go Lint Cache / warm lint cache (client) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.10) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.11) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.12) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.13) (push) Canceled after 0s
Build and Push Docker Image / merge (push) Canceled after 0s
Build & Publish (dsh-weknora) / Publish to npm (push) Canceled after 0s
Build & Publish (mcp-server) / Build sdist + wheel (push) Canceled after 0s
Build & Publish (mcp-server) / Publish to PyPI (push) Canceled after 0s
Anydoc / anydoc parser engine (push) Canceled after 0s
App / Format, vet, test, and build (push) Canceled after 0s
CLI / test (macos-latest / go 1.26) (push) Canceled after 0s
CLI / test (ubuntu-latest / go 1.26) (push) Canceled after 0s
CLI / test (windows-latest / go 1.26) (push) Canceled after 0s
Build and Push Docker Image / build-ui (push) Canceled after 0s
Build and Push Docker Image / build-docreader (push) Canceled after 0s
Build and Push Docker Image / build-sandbox (push) Canceled after 0s
Build and Push Docker Image / build-app (amd64, linux/amd64, ubuntu-latest) (push) Canceled after 0s
Build and Push Docker Image / build-app (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
DocReader / Python tests and Go client tests (push) Canceled after 0s
Build & Publish (dsh-weknora) / Typecheck, test, pack (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (pinned) (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (latest, advisory) (push) Canceled after 0s
Frontend / Test, type-check, and build (push) Canceled after 0s
Go Lint Cache / warm lint cache (.) (push) Canceled after 0s
Go Lint Cache / warm lint cache (cli) (push) Canceled after 0s
Go Lint Cache / warm lint cache (client) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.10) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.11) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.12) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.13) (push) Canceled after 0s
Build and Push Docker Image / merge (push) Canceled after 0s
Build & Publish (dsh-weknora) / Publish to npm (push) Canceled after 0s
Build & Publish (mcp-server) / Build sdist + wheel (push) Canceled after 0s
Build & Publish (mcp-server) / Publish to PyPI (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
# WeKnora 产品介绍
|
||||
|
||||
WeKnora(维娜拉)是腾讯开源的知识库问答系统,做的事情是:把 PDF、Word、网页,以及飞书、Notion、语雀里的资料收进知识库,然后你可以直接对着这批资料提问,答案带出处。技术上属于 RAG(Retrieval-Augmented Generation,检索增强生成)——先检索相关片段,再让大模型据此作答,而不是让模型凭记忆回答。
|
||||
|
||||
整套流程分四步:**文档理解 → 建索引 → 混合检索 → 生成回答**,本文后面逐个展开。
|
||||
|
||||
代码上是三个进程:Go(Gin)写的后端、Vue 3 的前端、Python(gRPC)的文档解析服务 docreader。部署方式有 Docker Compose、Helm、单二进制 Lite 模式和 macOS 桌面应用,按环境挑一种。
|
||||
|
||||
<Screenshot
|
||||
src="/screenshots/introduction-overview.png"
|
||||
caption="WeKnora 主界面:左侧知识库与会话,右侧问答区"
|
||||
hint="展示登录后的主界面全貌:侧边栏(知识库、智能体、设置入口)与一轮带引用的问答。" />
|
||||
|
||||
## WeKnora 解决什么问题
|
||||
|
||||
| 痛点 | WeKnora 的做法 |
|
||||
| --- | --- |
|
||||
| 文档格式繁杂,PDF/扫描件/表格难以结构化 | 独立的 docreader 解析服务:PDF 版式分析、扫描件 OCR、LibreOffice 转换、Playwright 网页抓取、多模态图片描述(VLM),可选 OpenDataLoader/Docling 混合解析 |
|
||||
| 单一向量检索召回不稳 | 向量 + 关键词(BM25)混合检索,RRF 融合,Rerank 重排,可选知识图谱(GraphRAG)与 Wiki 导航 |
|
||||
| 模型绑定单一厂商 | 模型抽象层:Ollama 本地模型与 OpenAI 兼容远程接口均可,LLM / Embedding / Rerank / VLM / ASR 分类管理(见 `internal/types/model.go`) |
|
||||
| 数据安全与私有化 | 全栈可私有部署;敏感凭证(API Key 等)以 AES-256 落盘加密(`SYSTEM_AES_KEY`);多租户隔离 + RBAC 角色鉴权 |
|
||||
| 只有问答不够用 | 内置 Agent(ReAct 多步推理)、MCP 工具接入、Agent Skills 沙箱执行、Web 搜索(SearXNG 等)、数据分析(对 CSV/Excel 执行 SQL) |
|
||||
| 团队协作 | 租户(工作空间)+ 成员角色 + 组织(Organization)跨租户知识库共享 + 邀请机制 |
|
||||
|
||||
## 核心概念
|
||||
|
||||
下面这些概念构成 WeKnora 的数据模型,理解它们就能看懂界面上的大部分选项。想对照源码的话,它们都定义在 `internal/types/` 目录下。
|
||||
|
||||
### 租户与身份
|
||||
|
||||
| 概念 | 说明 |
|
||||
| --- | --- |
|
||||
| 租户 Tenant | 即「工作空间」。持有存储配额(`StorageQuota`,默认 10GB)、全局检索参数(`RetrievalConfig`)、上下文配置(`ContextConfig`)、解析引擎配置(`ParserEngineConfig`)、存储引擎配置(`StorageEngineConfig`)与检索引擎列表(`RetrieverEngines`)。所有知识库、模型、Agent、会话都归属某个租户 |
|
||||
| 用户 User | 全局唯一的 `Username`/`Email`,`TenantID` 指向其「主租户」;`IsSystemAdmin` 标记平台级管理员,`CanAccessAllTenants` 标记跨租户超管 |
|
||||
| 成员 TenantMember | 用户与租户的多对多关系,携带角色 `Role` 与状态(`active` / `invited` / `suspended`) |
|
||||
| 角色 TenantRole | 四级:`owner`(40,完全控制)> `admin`(30,管理成员/模型/集成)> `contributor`(20,创建知识库与 Agent)> `viewer`(10,只读) |
|
||||
| API Key(TenantAPIKey) | 机器访问凭证,请求头 `X-API-Key` 携带。分 `tenant` / `platform` 两种作用域;支持 `FullAccess` 或细粒度能力(`retrieve`、`chat`、`ingest`、`manage_kbs`、`manage_models` 等),并可用 `KnowledgeBaseIDs` 限定可访问的知识库 |
|
||||
| 组织 Organization | 跨租户协作单元:邀请码加入、`admin`/`editor`/`viewer` 三级组织角色,实现知识库跨租户共享 |
|
||||
|
||||
### 知识域
|
||||
|
||||
| 概念 | 说明 |
|
||||
| --- | --- |
|
||||
| 知识库 KnowledgeBase | 知识容器,`Type` 支持 `document`(默认)/ `faq` / `wiki`。核心配置:`ChunkingConfig`(分块大小/重叠/父子分块/自适应策略 `auto`/`heading`/`heuristic` 等)、`EmbeddingModelID`、`IndexingStrategy`(向量 / 关键词 / Wiki / 图谱四路索引开关)、`VectorStoreID`(可绑定独立向量库) |
|
||||
| 知识 Knowledge | 一份文档 / 网页 / 手写条目。记录文件元数据(`FileName`/`FileType`/`FileHash`)、导入渠道 `Channel`(web / api / wechat / feishu 等)与解析状态机 `ParseStatus`:`pending → processing → finalizing → completed`(可 `failed` / `cancelled`) |
|
||||
| 分块 Chunk | 检索的最小单元。`ChunkType` 十余种:`text`、`parent_text`(父子分块)、`image_ocr`、`image_caption`、`faq`、`entity` / `relationship`(图谱)、`table_summary` / `table_column`(表格)、`wiki_page`、`web_search` 等;状态 `Stored`(已存)→ `Indexed`(已入索引) |
|
||||
| FAQ | FAQ 型知识库中的问答对,存于 Chunk 的 Metadata:标准问 `StandardQuestion`、相似问、反例问、多答案与答案策略 |
|
||||
| Wiki 页面 WikiPage | Wiki 型索引产物:由 LLM 从文档生成的结构化百科页面,最多三级分类路径,可被 Agent 以 `wiki_search` / `wiki_read_page` 工具导航 |
|
||||
| 知识图谱 Entity / Relationship | 从分块中抽取的实体与关系(强度 1-10),存储在 Neo4j(`NEO4J_ENABLE=true` 时),用于 GraphRAG 增强检索 |
|
||||
| 数据源 DataSource | 外部内容连接器。**当前可用 7 个**:`feishu`、`lark`(与飞书同一适配器,域名不同)、`gitlab`、`ima`(腾讯 IMA 笔记)、`notion`、`yuque`、`rss`,支持 Cron 定时同步(增量/全量)与冲突策略。`internal/types/datasource.go` 里还声明了 `confluence`、`github`、`imap` 等类型常量,但对应实现尚未接入(`initConnectorRegistry()` 中相关注册被注释),选不到 |
|
||||
| 检索配置 RetrievalConfig | 租户级检索参数:`EmbeddingTopK`(默认 50)、`VectorThreshold`(0.15)、`KeywordThreshold`(0.3)、`RerankTopK`(10)、`RerankThreshold`(0.2)、RRF 融合参数(`RRFK`=60,向量权重 0.7 / 关键词权重 0.3) |
|
||||
|
||||
### 对话与智能体
|
||||
|
||||
| 概念 | 说明 |
|
||||
| --- | --- |
|
||||
| 会话 Session | 一次多轮对话。记录 `LastRequestState`(上次提问时选中的 Agent、模型、知识库范围、Web 搜索、MCP 服务),重开会话时恢复;上下文压缩策略(`sliding_window` / `smart` LLM 摘要)来自 `ContextConfig` |
|
||||
| 消息 Message | `user` / `assistant` 角色消息,支持图片、附件、@提及(知识库/文档/标签/MCP/Skill),并统计 `TokenUsage`(含 prompt cache 命中情况) |
|
||||
| 模型 Model | 模型注册项。`Type`:`KnowledgeQA`(对话 LLM)/ `Embedding` / `Rerank` / `VLLM`(视觉)/ `ASR`(语音);`Source`:`local`(Ollama)、`remote` 及 `openai`、`azure_openai`、`gemini`、`deepseek`、`aliyun`、`zhipu`、`volcengine`、`hunyuan`、`siliconflow`、`openrouter`、`litellm`、`jina` 等厂商;`ManagedBy: "yaml"` 表示由 `config/builtin_models.yaml` 声明式管理 |
|
||||
| Agent(自定义智能体) CustomAgent | 两种模式:`quick-answer`(经典 RAG 管线)与 `smart-reasoning`(ReAct 多步推理 + 工具调用)。smart-reasoning 下有类型预设 `AgentType`:`rag-qa` / `wiki-qa` / `hybrid-rag-wiki` / `data-analysis` / `custom`(定义见 `config/agent_type_presets.yaml`) |
|
||||
| 内置 Agent | 开箱可用:`builtin-quick-answer`(快速问答)、`builtin-smart-reasoning`(智能推理)、`builtin-data-analyst`(数据分析)、`builtin-wiki-researcher`(Wiki 研究员)、`builtin-wiki-fixer`(Wiki 修复员)等 |
|
||||
| MCP 服务 MCPService | Model Context Protocol 工具接入:`sse` / `http-streamable` / `stdio` 三种传输;认证支持 API Key / Bearer / OAuth2;Agent 可按 `all` / `selected` / `none` 选用其工具 |
|
||||
|
||||
### 概念关系图
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph identity["身份与租户"]
|
||||
U["User (用户)"]
|
||||
T["Tenant (租户 / 工作空间)"]
|
||||
TM["TenantMember (角色: owner/admin/contributor/viewer)"]
|
||||
AK["TenantAPIKey (X-API-Key)"]
|
||||
ORG["Organization (跨租户组织)"]
|
||||
end
|
||||
subgraph knowledge["知识域"]
|
||||
KB["KnowledgeBase (document/faq/wiki)"]
|
||||
K["Knowledge (文档/网页/手写条目)"]
|
||||
C["Chunk (text/faq/image/table/entity...)"]
|
||||
W["WikiPage"]
|
||||
G["Entity / Relationship (知识图谱)"]
|
||||
DS["DataSource (飞书/Notion/RSS...)"]
|
||||
end
|
||||
subgraph chat["对话与智能体"]
|
||||
S["Session (会话)"]
|
||||
MSG["Message (消息)"]
|
||||
AG["CustomAgent (quick-answer / smart-reasoning)"]
|
||||
M["Model (LLM/Embedding/Rerank/VLM/ASR)"]
|
||||
MCP["MCPService (外部工具)"]
|
||||
end
|
||||
U -- "成员关系" --> TM --> T
|
||||
T --> AK
|
||||
T --> ORG
|
||||
T --> KB
|
||||
T --> M
|
||||
T --> AG
|
||||
KB --> K --> C
|
||||
KB --> W
|
||||
C --> G
|
||||
DS -- "定时同步" --> KB
|
||||
T --> S --> MSG
|
||||
AG -- "检索" --> KB
|
||||
AG -- "调用" --> M
|
||||
AG -- "工具" --> MCP
|
||||
```
|
||||
|
||||
## 功能清单
|
||||
|
||||
- **文档接入**:文件上传(PDF/Word/PPT/Excel/Markdown/HTML/图片/音频等)、URL 抓取、手写 Markdown、整目录上传、飞书 / Lark / Notion / 语雀 / RSS 定时同步。
|
||||
- **文档理解**:版式分析、扫描件 OCR、表格抽取、图片多模态描述(VLM)、音频转写(ASR)、按文件类型选择解析引擎(`ParserEngineRules`,可接 MinerU / OpenDataLoader)。
|
||||
- **索引管道**:可配置分块(含父子分块与自适应策略)、向量索引、关键词全文索引、FAQ 索引、Wiki 生成、知识图谱抽取、预生成问题(question generation)。
|
||||
- **检索**:向量 + BM25 混合检索、RRF 融合、Rerank 重排、查询改写与扩展、意图识别(greeting/chitchat/web_search 等,见 `config/prompt_templates/intent_prompts.yaml`)。
|
||||
- **问答与 Agent**:流式 SSE 问答、多轮上下文压缩、引用溯源;ReAct Agent(工具:`knowledge_search`、`grep_chunks`、`wiki_search`、`data_analysis` 等)、MCP 外部工具、Agent Skills(Docker 沙箱执行脚本)、Web 搜索。
|
||||
- **多租户与安全**:RBAC 角色鉴权(默认开启,`WEKNORA_TENANT_ENABLE_RBAC`)、审计日志(默认保留 90 天)、邀请制注册(`auth.registration_mode=invite_only`,也可用旧变量 `DISABLE_REGISTRATION=true`)、OIDC 单点登录、SSRF 防护、敏感字段 AES-256 加密。
|
||||
- **可观测性**:Langfuse 全链路追踪(LLM/Embedding/Rerank/VLM/ASR 调用与 token 统计)、健康检查、Swagger API 文档(`GIN_MODE=debug` 时)。
|
||||
- **生态**:REST API(`/api/v1`)+ API Key、独立 MCP Server(把 WeKnora 作为工具暴露给其他 Agent)、CLI(`cli/`)、微信小程序(`miniprogram/`)、浏览器插件渠道。
|
||||
|
||||
## 系统组件一览
|
||||
|
||||
| 组件 | 技术栈 | 源码位置 | 默认端口 | 职责 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| app(后端) | Go / Gin | `cmd/server`、`internal/` | 8080 | REST API、检索问答、Agent 引擎、异步任务(Asynq) |
|
||||
| frontend(前端) | Vue 3 + Nginx | `frontend/` | 80 | Web 控制台,Nginx 反代 `/api` 到 app |
|
||||
| docreader | Python / gRPC | `docreader/` | 50051(仅容器网络内) | 文档解析、OCR、网页抓取、图片提取 |
|
||||
| postgres | ParadeDB(PostgreSQL 17 + BM25/向量扩展) | 镜像 `paradedb/paradedb` | 5432 | 主数据库 + 默认混合检索引擎(`RETRIEVE_DRIVER=postgres`) |
|
||||
| redis | Redis 7 | — | 6379 | 流管理(SSE 恢复)、Asynq 任务队列 |
|
||||
| sandbox | Python 3.11 + Node 20 | `docker/Dockerfile.sandbox` | — | Agent Skills 的会话沙箱容器镜像 |
|
||||
| 可选:qdrant / milvus / weaviate / doris | — | `docker-compose.yml` profiles | 6334 / 19530 / 9035 / 9030 | 替代或叠加的向量检索引擎(`RETRIEVE_DRIVER`) |
|
||||
| 可选:opensearch | — | 仅 `docker-compose.dev.yml` | 9200 | 开发环境用;生产需自备集群 |
|
||||
| 可选:elasticsearch / tencent_vectordb | — | 不随 compose 提供 | — | 代码支持,但需自行部署后用 `RETRIEVE_DRIVER` 接入 |
|
||||
| 可选:neo4j | Neo4j | profile `neo4j` | 7474 / 7687 | 知识图谱存储(GraphRAG) |
|
||||
| 可选:minio | MinIO | profile `minio` | 9000 / 9001 | S3 兼容对象存储(`STORAGE_TYPE=minio`) |
|
||||
| 可选:searxng | SearXNG | profile `searxng` | 8888 | 自建 Web 搜索引擎 |
|
||||
| 可选:langfuse 栈 | Langfuse 3 + ClickHouse + MinIO | profile `langfuse` | 3000 | LLM 可观测性 |
|
||||
| 可选:mcp | Python | `mcp-server/`,profile `full` | 8082 | 将 WeKnora API 封装为 MCP Server |
|
||||
| 可选:odl-hybrid | Docling | profile `odl-hybrid` | 5002 | OpenDataLoader PDF 混合解析后端 |
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Browser["浏览器 / SDK / CLI"] --> FE["frontend (Nginx :80)"]
|
||||
FE -- "/api 反向代理" --> APP["app 后端 (Go :8080)"]
|
||||
Browser -. "直连 API + X-API-Key" .-> APP
|
||||
APP -- "gRPC :50051" --> DR["docreader (Python 文档解析)"]
|
||||
APP --> PG[("ParadeDB / PostgreSQL :5432 元数据 + 混合检索")]
|
||||
APP --> RD[("Redis :6379 流管理 + Asynq 队列")]
|
||||
APP -. "docker run 按需" .-> SB["sandbox (Skills 沙箱)"]
|
||||
APP -. "可选" .-> VDB[("Qdrant / Milvus / ES / OpenSearch / Doris ...")]
|
||||
APP -. "可选" .-> NEO[("Neo4j 知识图谱")]
|
||||
APP -. "可选" .-> OSS[("MinIO / COS / S3 / OSS / OBS / TOS 对象存储")]
|
||||
APP -. "可选" .-> SX["SearXNG Web 搜索 :8888"]
|
||||
APP -. "可选" .-> LF["Langfuse 可观测 :3000"]
|
||||
APP --> LLM["Ollama 本地模型 / OpenAI 兼容远程模型"]
|
||||
MCPS["mcp-server :8082"] -- "REST" --> APP
|
||||
```
|
||||
|
||||
## 下一步
|
||||
|
||||
- 部署安装:见 [02-installation.md](./02-installation.md)
|
||||
- 快速上手:见 [03-quickstart.md](./03-quickstart.md)
|
||||
- 配置详解:见 [04-configuration.md](./04-configuration.md)
|
||||
@@ -0,0 +1,303 @@
|
||||
# 安装部署
|
||||
|
||||
WeKnora 支持从「一台笔记本」到「Kubernetes 集群」的多种部署形态。本文逐一介绍 Docker Compose(生产/开发两套编排)、镜像构建、Makefile 与脚本、Helm,以及桌面端(Lite 单二进制、桌面应用与 Homebrew)。
|
||||
|
||||
## 部署形态总览
|
||||
|
||||
| 形态 | 入口 | 数据库 | 队列/流 | 适用场景 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Docker Compose(标准) | `docker-compose.yml` | ParadeDB(PostgreSQL) | Redis + Asynq | 生产 / 团队自托管,推荐 |
|
||||
| Docker Compose(开发) | `docker-compose.dev.yml` | 同上(仅基础设施进容器) | 同上 | 本地开发:app / frontend 在宿主机运行 |
|
||||
| Helm | `helm/` | ParadeDB(chart 内置) | Redis(chart 内置) | Kubernetes >= 1.25 |
|
||||
| Lite 单二进制 | `make build-lite` / `scripts/package-lite.sh` | SQLite(FTS5 + sqlite-vec) | 内存(无 Redis) | 个人 / 离线 / 低资源环境 |
|
||||
| 桌面应用(**未正式发布**) | `cmd/desktop`(Wails v2)+ `scripts/package-mac-app.sh` | SQLite | 内存 | 桌面单机使用,带图形界面与本地数据目录 |
|
||||
| Homebrew | `Formula/weknora-lite.rb` | SQLite | 内存 | macOS / Linux 命令行安装 Lite |
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph prod["标准部署 (docker compose up)"]
|
||||
FE1["frontend :80"] --> APP1["app :8080"]
|
||||
APP1 --> PG1[("postgres :5432")]
|
||||
APP1 --> RD1[("redis :6379")]
|
||||
APP1 --> DR1["docreader :50051"]
|
||||
APP1 -. "profile 可选" .-> OPT1["qdrant / milvus / neo4j / minio / searxng / langfuse / mcp ..."]
|
||||
end
|
||||
subgraph dev["开发模式 (make dev-start)"]
|
||||
LOCALAPP["宿主机 go run app :8080"] --> PG2[("postgres 容器")]
|
||||
LOCALAPP --> RD2[("redis 容器")]
|
||||
LOCALAPP --> DR2["docreader 容器 :50051"]
|
||||
LOCALFE["宿主机 npm run dev 前端"] --> LOCALAPP
|
||||
end
|
||||
subgraph lite["Lite / 桌面 (单进程)"]
|
||||
BIN["WeKnora-lite 二进制 (内嵌 web/ 前端)"]
|
||||
BIN --> SQLITE[("SQLite: FTS5 + sqlite-vec")]
|
||||
BIN --> MEMQ[("内存流管理")]
|
||||
BIN -. "可选" .-> DR3["docreader 127.0.0.1:50051"]
|
||||
BIN --> OLLAMA["Ollama :11434"]
|
||||
end
|
||||
```
|
||||
|
||||
## 硬件与依赖要求
|
||||
|
||||
- **标准 Docker 部署**:Docker 20.10+ 与 Docker Compose v2(v1 `docker-compose` 也兼容,`scripts/start_all.sh` 会自动探测);建议 4 核 CPU / 8GB 内存起步(docreader 含 LibreOffice、Playwright,较吃内存),磁盘按知识库规模预留(Postgres 卷 + `/data/files` 文件卷)。启用 Milvus / OpenSearch / Langfuse 等可选组件需相应增加内存。
|
||||
- **模型服务**:本地推理需 [Ollama](https://ollama.com)(默认地址 `http://host.docker.internal:11434`,`OLLAMA_OPTIONAL=true` 时不可用仅告警不阻断);或任意 OpenAI 兼容 API(DeepSeek、通义、智谱、硅基流动等)。
|
||||
- **源码编译**:Go 1.26(见 `docker/Dockerfile.app` builder 阶段 `golang:1.26-bookworm`)、CGO(依赖 `libsqlite3-dev`)、Node.js + npm(前端)、Python 3.10 + uv(docreader)。
|
||||
- **Kubernetes**:>= 1.25.0(`helm/Chart.yaml`)。
|
||||
|
||||
## 一、Docker Compose 标准部署(docker-compose.yml)
|
||||
|
||||
最快路径:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/Tencent/WeKnora.git && cd WeKnora
|
||||
cp .env.example .env # 编辑必填项:DB_USER/DB_PASSWORD/DB_NAME、REDIS_PASSWORD、JWT_SECRET、SYSTEM_AES_KEY
|
||||
make start-all # 等价 ./scripts/start_all.sh(默认拉取最新镜像)
|
||||
# 或直接:
|
||||
docker compose pull # 拉取与 WEKNORA_VERSION 匹配的镜像
|
||||
docker compose up -d
|
||||
docker compose ps # 等所有服务变成 healthy/running
|
||||
```
|
||||
|
||||
停止用 `docker compose down`(加 `-v` 会连数据卷一起删,慎用)。仓库里的 `make start-all` 是同一条命令的封装(`scripts/start_all.sh`,额外做 Ollama 检查、`.env` 兜底、沙箱镜像预拉取),两者选一即可。
|
||||
|
||||
启动后在浏览器打开 `http://localhost` 就是前端(端口由 `FRONTEND_PORT` 决定,默认 80),首次访问会落到注册页。前端 Nginx 把 `/api/` 反代到后端,所以接口调用同样走 `http://localhost/api/v1`;后端 `8080` 端口也直接映射到宿主机,`curl http://localhost:8080/health` 可用于确认后端就绪。
|
||||
|
||||
> 注意:`docker-compose.yml` 的 app 服务使用 `env_file: [.env]`,`.env` 不存在会导致 compose 解析失败。`make docker-run` / `start_all.sh` 会自动 `cp .env.example .env` 或 `touch .env` 兜底。
|
||||
|
||||
### 版本升级
|
||||
|
||||
若已有部署并下载了更新的 release:
|
||||
|
||||
```bash
|
||||
# 在 .env 中将 WEKNORA_VERSION 设为目标版本(如 0.7.0),或保持 latest
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
> 仅执行 `docker compose up -d` 会复用本地缓存镜像,可能导致 Web UI 显示版本与下载的 release 不一致。
|
||||
|
||||
### 核心服务(默认启动)
|
||||
|
||||
| 服务 | 镜像 | 端口(宿主:容器) | 依赖 | 说明 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `frontend` | `wechatopenai/weknora-ui:${WEKNORA_VERSION:-latest}` | `${FRONTEND_PORT:-80}:80` | app(healthy) | Nginx 托管 SPA 并反代到 app;`APP_HOST`/`APP_BACKEND_PORT`/`APP_SCHEME` 可指向远程后端 |
|
||||
| `app` | `wechatopenai/weknora-app` | `${APP_PORT:-8080}:8080` | postgres(healthy)、redis、docreader(healthy) | Go 后端;挂载 `./config/config.yaml`、`data-files` 卷、`./skills/preloaded`;健康检查 `GET /health` |
|
||||
| `docreader` | `wechatopenai/weknora-docreader` | 仅 `expose: 50051`(不发布到宿主机) | — | 文档解析 gRPC 服务;健康检查 `grpc_health_probe`;与 app 共享 `docreader-tmp` 卷传递图片 |
|
||||
| `postgres` | `paradedb/paradedb:v0.22.2-pg17` | 不映射宿主端口 | — | ParadeDB = PostgreSQL 17 + BM25/向量扩展,默认检索引擎 |
|
||||
| `redis` | `redis:7.0-alpine` | 不映射宿主端口 | — | `--appendonly yes --requirepass ${REDIS_PASSWORD}` |
|
||||
|
||||
### 可选服务与 profiles
|
||||
|
||||
按需以 `docker compose --profile <name> up -d` 启用:
|
||||
|
||||
| profile | 服务 | 端口 | 用途 |
|
||||
| --- | --- | --- | --- |
|
||||
| `searxng`(含 `full`) | `searxng-init` + `searxng` | `127.0.0.1:8888`(`SEARXNG_BIND`/`SEARXNG_PORT`) | 自建 Web 搜索;默认仅绑定回环,公开前必须轮换 `SEARXNG_SECRET` |
|
||||
| `minio`(含 `full`) | `minio` | 9000(S3)/ 9001(控制台) | S3 兼容对象存储(`STORAGE_TYPE=minio`),默认账号 `minioadmin/minioadmin` |
|
||||
| `neo4j`(含 `full`) | `neo4j` | 7474 / 7687 | 知识图谱(`NEO4J_ENABLE=true`),默认 `neo4j/password` |
|
||||
| `qdrant`(含 `full`) | `qdrant` | 6333(REST)/ 6334(gRPC) | 向量库(`RETRIEVE_DRIVER=qdrant`) |
|
||||
| `milvus` | `milvus` | 19530 / 9091 | 向量库(standalone,内嵌 etcd) |
|
||||
| `weaviate` | `weaviate` | 9035(HTTP)/ 50052(gRPC) | 向量库 |
|
||||
| `doris` | `doris-fe` + `doris-be` | 8030(FE HTTP)/ 9030(FE MySQL)/ 8040(BE) | Apache Doris 4.1 检索引擎(需 >= 3.0,HNSW ANN) |
|
||||
| `dex`(含 `full`) | `dex` | 5556 | OIDC 测试用 IdP(配置在 `misc/dex-config.yaml`) |
|
||||
| `langfuse`(含 `full`) | `langfuse-db-init`、`langfuse-clickhouse`、`langfuse-minio`、`langfuse-worker`、`langfuse-web` | 3000(UI)/ 9100/9101(专用 MinIO) | 自建 Langfuse 可观测栈,复用 WeKnora 的 postgres(新建 `langfuse` 库)与 redis(DB 1) |
|
||||
| `odl-hybrid` | `odl-hybrid` | expose 5002 | OpenDataLoader/Docling PDF 混合解析后端(仅本地构建,配 `DOCREADER_ODL_HYBRID` 使用) |
|
||||
| `full` | `sandbox`、`mcp` 及上述带 full 标记的服务 | mcp: `${MCP_PORT:-8082}:8000` | `sandbox` 仅用于 build/pull 镜像(`command: ["true"]`,非常驻)。Docker 沙箱默认关闭,需设 `WEKNORA_SANDBOX_DOCKER_ENABLED=true` 并挂载 `docker.sock`(等同宿主机 root);Cube/E2B 不依赖本机 daemon。`mcp` 为 MCP Server |
|
||||
|
||||
app 容器的 `environment` 段落是全量环境变量清单(数据库、向量库、对象存储、Docreader 调优、租户策略、OIDC 等),详见 [04-configuration.md](./04-configuration.md)。
|
||||
|
||||
## 二、开发模式(docker-compose.dev.yml + scripts/dev.sh)
|
||||
|
||||
开发编排只把**基础设施**放进容器(postgres、redis、docreader 端口全部映射到宿主机),app 与 frontend 在宿主机上以热更新方式运行:
|
||||
|
||||
```bash
|
||||
make dev-start # ./scripts/dev.sh start,可加 DEV_ARGS=--odl-hybrid / --minio / --qdrant / --neo4j / --dex / --full
|
||||
make dev-app # 宿主机启动 Go 后端(自动把 DB_HOST/REDIS_ADDR 指到 localhost)
|
||||
make dev-frontend # 宿主机启动 Vue 前端 dev server
|
||||
make dev-logs / dev-status / dev-stop / dev-restart
|
||||
```
|
||||
|
||||
与生产编排的差异:
|
||||
|
||||
- postgres(`5432`)、redis(`6379`)、docreader(`50051`)都发布到宿主机端口,便于本地进程直连;
|
||||
- 额外提供 `opensearch`(9200)与 `opensearch-dashboards`(5601,profile `opensearch-ui`)单节点开发环境(security 插件关闭);
|
||||
- `dev.sh` 会加载 `.env` 与 `.env.local`(后者覆盖前者),并支持 `DEV_REMOTE_HOST` 指向远程基础设施。
|
||||
|
||||
## 三、镜像构建(docker/ 目录)
|
||||
|
||||
| Dockerfile | 产物镜像 | 要点 |
|
||||
| --- | --- | --- |
|
||||
| `docker/Dockerfile.app` | `wechatopenai/weknora-app` | 两阶段:`golang:1.26-bookworm` 编译(`make build-prod`,默认 `WITH_ANYDOC=1` 链接进程内 office 解析引擎,注入版本信息,预下载 DuckDB 扩展 `cmd/download/duckdb`)→ `debian:12.12-slim` 运行层(含 `migrate` 迁移工具、python3/node/uvx(供 stdio MCP 与 Skills 使用)、ffmpeg(ASR)、gosu 降权)。入口 `scripts/docker-entrypoint.sh`:修复挂载目录属主、把 `_builtin` 内置 Skills 合并回 `skills/preloaded`;若挂载了 docker.sock,按 socket GID 把 appuser 加入对应组(compose `group_add` 在 gosu 后无效),再以 appuser 运行 `./WeKnora`。`EXPOSE 8080` |
|
||||
| `docker/Dockerfile.docreader` | `wechatopenai/weknora-docreader` | Python 3.10 + uv 依赖锁定;生成 protobuf;运行层安装 LibreOffice、OpenJDK 17、antiword、Playwright(webkit)与 `grpc_health_probe`。轻量版不含 PaddleOCR。`EXPOSE 50051`。支持 `APT_MIRROR` 构建参数 |
|
||||
| `docker/Dockerfile.odl-hybrid` | `weknora-odl-hybrid:local` | 安装 `opendataloader-pdf[hybrid]`(Docling),监听 5002,默认 `--no-ocr`;仅本地构建不发布 |
|
||||
| `docker/Dockerfile.sandbox` | `wechatopenai/weknora-sandbox` | Python 3.11-slim + Node 20 + jq,非 root 用户 `user`(UID 1000),Agent Skills 的会话沙箱镜像 |
|
||||
| `frontend/Dockerfile` | `wechatopenai/weknora-ui` | 需先在宿主机执行 `./scripts/build_frontend_dist.sh` 产出 `dist/`;基底为按 digest 固定的 `nginx:1.30.3-alpine`(兼容 CentOS 7 旧内核) |
|
||||
|
||||
从源码构建全部镜像:
|
||||
|
||||
```bash
|
||||
make build-images # ./scripts/build_images.sh,参数 --app/--docreader/--frontend/--sandbox/--clean
|
||||
# 或单独:
|
||||
make docker-build-app
|
||||
make docker-build-docreader
|
||||
make docker-build-frontend
|
||||
```
|
||||
|
||||
## 四、Makefile 部署相关目标速查
|
||||
|
||||
| 目标 | 作用 |
|
||||
| --- | --- |
|
||||
| `make start-all` / `stop-all` | 调 `scripts/start_all.sh` 启停整套服务(含 Ollama 检查、.env 兜底、沙箱镜像预拉取) |
|
||||
| `make start-ollama` / `start-docker` | 仅启动 Ollama / 仅启动 Docker 服务 |
|
||||
| `make docker-run` / `docker-stop` / `docker-restart` | 传统 `docker-compose up/down/restart`(自动兜底 `.env`) |
|
||||
| `make build-images*` / `clean-images` / `pull-images` | 源码构建 / 清理 / 拉取镜像 |
|
||||
| `make check-env` / `list-containers` / `show-platform` | 环境检查(`scripts/check-env.sh` 校验 .env 必填变量与工具链)/ 容器列表 / 构建平台(自动识别 amd64/arm64) |
|
||||
| `make migrate-up` / `migrate-down` / `migrate-version` / `migrate-create name=x` / `migrate-force version=n` / `migrate-goto version=n` | 数据库迁移(`scripts/migrate.sh`;容器内默认 `AUTO_MIGRATE=true` 启动时自动迁移) |
|
||||
| `make dev-*` | 开发模式(见上文) |
|
||||
| `make build` / `run` / `build-prod` | 本地编译运行 `cmd/server`(`build-prod` 需 CGO,注入版本号与 `Edition=standard`) |
|
||||
| `make build-lite` / `run-lite` / `package-lite` | Lite 模式构建 / 运行(读 `.env.lite`)/ 打发行包 |
|
||||
| `make package-mac-app` | 打包 macOS 桌面应用 |
|
||||
| `make docs` / `install-swagger` | 生成 Swagger 文档(`http://localhost:8080/swagger/index.html`,release 模式禁用) |
|
||||
| `make clean-db` | 删除 postgres/minio/redis 数据卷(危险操作) |
|
||||
|
||||
## 五、scripts/ 启动脚本
|
||||
|
||||
| 脚本 | 职责 |
|
||||
| --- | --- |
|
||||
| `scripts/start_all.sh` | 一键启动:参数 `-o`(仅 Ollama)、`-d`(仅 Docker)、`-a`(全部,默认)、`-s`(停止)、`-c`(检查环境)、`-l`(列容器)、`-p`(拉镜像);自动探测 compose v1/v2、按 `uname -m` 设定 `PLATFORM`、后台预拉取 sandbox 镜像 |
|
||||
| `scripts/dev.sh` | 开发环境编排(见上文),子命令 `start/stop/restart/logs/status/app/frontend` |
|
||||
| `scripts/check-env.sh` | 校验 `.env` 必填变量(DB_*、STORAGE_TYPE、REDIS_ADDR、OLLAMA_BASE_URL 等)与 Go/npm/Docker/Air 工具链 |
|
||||
| `scripts/build_images.sh` | 构建镜像并注入版本(git tag / commit / build time),支持跨架构 |
|
||||
| `scripts/build_frontend_dist.sh` | 构建前端静态产物 `frontend/dist`(frontend 镜像的前置步骤) |
|
||||
| `scripts/migrate.sh` | golang-migrate 封装 |
|
||||
| `scripts/docker-entrypoint.sh` | app 容器入口(属主修复 + 内置 Skills 合并 + docker.sock GID 补组 + gosu 降权) |
|
||||
| `scripts/package-lite.sh` / `package-mac-app.sh` | Lite tarball / macOS .app 打包 |
|
||||
|
||||
## 六、Helm 部署(helm/)
|
||||
|
||||
`helm/Chart.yaml`:apiVersion v2,chart 名 `weknora`,appVersion 跟随版本(如 v0.8.0),要求 Kubernetes >= 1.25.0。
|
||||
|
||||
Chart 内包含五个组件:`app`(`wechatopenai/weknora-app`)、`frontend`(`wechatopenai/weknora-ui`)、`docreader`、`postgresql`(ParadeDB 镜像)、`redis`(`redis:7-alpine`),并可选启用 `minio` 与 `neo4j`。
|
||||
|
||||
`helm/values.yaml` 关键配置:
|
||||
|
||||
```yaml
|
||||
app:
|
||||
replicaCount: 1
|
||||
env:
|
||||
GIN_MODE: release
|
||||
RETRIEVE_DRIVER: postgres # postgres / elasticsearch_v7 / elasticsearch_v8 / qdrant ...
|
||||
STORAGE_TYPE: local # local / minio / cos / tos / s3
|
||||
STREAM_MANAGER_TYPE: redis
|
||||
postgresql:
|
||||
enabled: true
|
||||
persistence: { enabled: true, size: 10Gi }
|
||||
redis:
|
||||
enabled: true
|
||||
persistence: { enabled: true, size: 1Gi }
|
||||
dataFiles:
|
||||
persistence: { enabled: true, size: 10Gi }
|
||||
secrets: # 必填项,或用 existingSecret 引用已有 Secret
|
||||
dbPassword: ""
|
||||
redisPassword: ""
|
||||
jwtSecret: ""
|
||||
systemAesKey: "" # 32 字节 AES-256 主密钥
|
||||
```
|
||||
|
||||
```bash
|
||||
helm install weknora ./helm -n weknora --create-namespace \
|
||||
--set secrets.dbPassword=xxx --set secrets.redisPassword=xxx \
|
||||
--set secrets.jwtSecret=xxx --set secrets.systemAesKey=$(openssl rand -hex 16)
|
||||
```
|
||||
|
||||
## 七、桌面端(Lite 模式 / 桌面应用 / Homebrew)
|
||||
|
||||
桌面端面向本机与低资源环境,底层都是同一套 Lite 运行时(单进程 + SQLite + 内存队列),只是分发与启动方式不同:**单二进制**(命令行启动,也可作为后台服务)、**桌面应用**(图形界面,双击启动)、**Homebrew**(macOS/Linux 命令行安装 Lite)。三者能力范围一致。
|
||||
|
||||
### 7.1 Lite 运行时(零外部依赖)
|
||||
|
||||
Lite 模式通过编译期 `EDITION=lite` 与运行期 `.env.lite` 环境实现「一进程跑全套」:
|
||||
|
||||
- **数据库**:`DB_DRIVER=sqlite` + `DB_PATH=./data/weknora.db`,编译加 `-tags "sqlite_fts5"`;
|
||||
- **检索**:`RETRIEVE_DRIVER=sqlite`,走 SQLite FTS5 全文检索 + sqlite-vec 向量检索,无需任何向量数据库;
|
||||
- **队列/流**:`STREAM_MANAGER_TYPE=memory`(`internal/stream/factory.go`),不需要 Redis,Asynq 分布式队列在 Lite 模式下为内存/no-op;
|
||||
- **前端**:`make build-lite` 会把 `frontend/dist` 复制为仓库根的 `web/`,二进制直接内嵌托管静态资源(`WEKNORA_WEB_DIR` 可指定目录,router 的 `serveFrontendStatic` 提供服务);
|
||||
- **文档解析**:仍可选连本地 docreader(`DOCREADER_ADDR=127.0.0.1:50051`);
|
||||
- **沙箱**:Lite 启动时不预置后端;可在设置页按空间统一配置 Docker、CubeSandbox 或 E2B。
|
||||
|
||||
```bash
|
||||
cp .env.lite.example .env.lite # 修改 SYSTEM_AES_KEY / JWT_SECRET
|
||||
make run-lite # 构建并以 .env.lite 环境启动 ./WeKnora-lite
|
||||
make package-lite # 打包发行 tarball(scripts/package-lite.sh)
|
||||
```
|
||||
|
||||
Lite 还提供 `POST /auth/auto-setup` 一键生成本地账号(仅 lite edition 开放,见 `internal/handler/auth.go`),桌面应用据此实现免注册启动。
|
||||
|
||||
### 7.2 桌面应用(cmd/desktop,Wails v2)
|
||||
|
||||
桌面应用提供图形界面的本机使用方式:双击启动,进程内自带后端与 SQLite,数据落在系统的应用数据目录;另有端口设置、局域网绑定与更新检查等桌面特有能力。运行时能力与 §7.1 相同。
|
||||
|
||||
::: warning 尚未正式发布
|
||||
桌面应用目前**没有随 Release 提供安装包**,需要自己按下面的步骤构建。`release-lite.yml` 里已有跨平台(macOS universal/amd64/arm64、Linux amd64、Windows amd64)的构建任务,但该工作流的 tag 触发被注释掉、只能手动触发,且当前最新 Release 未附带任何产物。
|
||||
:::
|
||||
|
||||
- 入口 `cmd/desktop/main.go` + `cmd/desktop/wails.json`;`cmd/desktop/app.go` 向前端暴露 `GetAPIBaseURL`(返回 `http://127.0.0.1:PORT/api/v1`)、HTTP 端口与「绑定到局域网」设置、`CheckForUpdates` 自动更新检查等绑定方法。
|
||||
- `scripts/package-mac-app.sh`:先构建前端到 `web/`,再 `wails build -tags "sqlite_fts5"`,最后组装 `.app` 包 —— `Contents/MacOS/WeKnora Lite` 为主程序,`Contents/Resources` 内嵌 `.env`、config、`migrations/sqlite`、web 前端;相对路径数据自动重定向到 `~/Library/Application Support/WeKnora Lite/data/`,日志写 `~/Library/Logs/WeKnora Lite/`。
|
||||
|
||||
```bash
|
||||
make package-mac-app
|
||||
```
|
||||
|
||||
### 7.3 Homebrew(Formula/weknora-lite.rb)
|
||||
|
||||
```bash
|
||||
brew install weknora-lite # 从 GitHub Releases 下载 WeKnora-lite_v{ver}_{os}_{arch}.tar.gz
|
||||
brew services start weknora-lite # 作为后台服务运行(keep_alive,日志 var/log/weknora-lite.log)
|
||||
```
|
||||
|
||||
Formula 描述为 "Knowledge base management system — single-binary Lite edition",支持 macOS/Linux 的 arm64 与 amd64。包装脚本首次运行会把 `.env.lite.example` 复制为 `~/.config/weknora/.env.lite`(可用 `WEKNORA_CONFIG_DIR` / `WEKNORA_DATA_DIR` 覆盖配置与数据目录,数据默认在 `~/.local/share/weknora`)。
|
||||
|
||||
## 八、源码编译运行
|
||||
|
||||
```bash
|
||||
# 后端(标准版,需本地 postgres/redis/docreader,见开发模式)
|
||||
go mod download
|
||||
make build && ./WeKnora # 或 make build-prod
|
||||
|
||||
# 前端
|
||||
cd frontend && npm ci && npm run dev # 开发;npm run build 产出 dist/
|
||||
|
||||
# docreader
|
||||
cd docreader && uv sync --locked && bash scripts/generate_proto.sh && python -m docreader.server # 具体入口见 docreader/
|
||||
```
|
||||
|
||||
配置文件查找顺序(`internal/config/config.go` 的 `LoadConfig`):当前目录 → `./config` → `$HOME/.appname` → `/etc/appname/`,文件名 `config.yaml`。
|
||||
|
||||
## 常见部署拓扑
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph host["单机 Docker Compose(最常见)"]
|
||||
direction LR
|
||||
U1["用户"] --> N1["frontend :80"] --> A1["app :8080"]
|
||||
A1 --> D1["docreader"]
|
||||
A1 --> P1[("postgres")]
|
||||
A1 --> R1[("redis")]
|
||||
A1 --> O1["宿主机 Ollama :11434 (host.docker.internal)"]
|
||||
end
|
||||
subgraph k8s["Kubernetes (Helm)"]
|
||||
direction LR
|
||||
ING["Ingress"] --> FE2["frontend Deployment"] --> A2["app Deployment"]
|
||||
A2 --> PVC1[("PVC: postgres 10Gi / redis 1Gi / data-files 10Gi")]
|
||||
A2 --> D2["docreader Deployment"]
|
||||
end
|
||||
subgraph laptop["个人:Lite / 桌面 / Homebrew"]
|
||||
direction LR
|
||||
U3["用户"] --> L1["WeKnora-lite 单进程 (内嵌前端 + SQLite + 内存队列)"]
|
||||
L1 --> O3["Ollama / 远程 OpenAI 兼容 API"]
|
||||
end
|
||||
```
|
||||
|
||||
## 下一步
|
||||
|
||||
部署完成后,请阅读 [03-quickstart.md](./03-quickstart.md) 完成初始化与首次问答。
|
||||
@@ -0,0 +1,219 @@
|
||||
# 快速上手
|
||||
|
||||
跟着本文走一遍,你会得到一个能回答自己文档内容的知识库:注册账号 → 建库并选模型 → 上传文档 → 提问并看到带出处的回答。全程在网页界面完成,顺利的话十几分钟,其中大部分时间花在等文档解析上。
|
||||
|
||||
想用接口做集成的,跳到本文第 7 节,那里有一段可直接复制运行的 curl 链路。
|
||||
|
||||
## 1. 开始之前
|
||||
|
||||
- 服务已经跑起来:按[安装部署](./02-installation.md)启动后,前端在 `http://localhost`,后端在 `http://localhost:8080`;
|
||||
- 手上有一套可用的模型:本地 Ollama(容器内默认地址 `http://host.docker.internal:11434`),或者任意 OpenAI 兼容服务的 `base_url` + `api_key`。至少需要一个对话模型和一个向量(embedding)模型;
|
||||
- 确认后端活着:`curl http://localhost:8080/health` 返回 `{"status":"ok"}`。
|
||||
|
||||
## 2. 注册并登录
|
||||
|
||||
首次访问会落到登录页,注册是同一页上的一个页签——只有当注册模式是 `self_serve` 时才显示(前端读 `/auth/config` 决定)。系统没有内置默认账号,注册完成后会自动得到一个属于自己的工作空间,你在这个空间里是 Owner。
|
||||
|
||||
<Screenshot
|
||||
src="/screenshots/quickstart-register.png"
|
||||
caption="首次访问的注册页面"
|
||||
hint="展示注册表单(用户名 / 邮箱 / 密码)与登录入口即可。" />
|
||||
|
||||
几点值得先知道:
|
||||
|
||||
- 用户名 2–50 个字符;密码在注册页要求 8–32 位且含字母和数字(直接调 `POST /auth/register` 接口时后端只校验 ≥6 位,建议仍按 8 位以上来);
|
||||
- 团队部署时,注册完第一个账号就可以关闭公开注册,之后通过邀请链接加人。关的方式有两种:设 `DISABLE_REGISTRATION=true`(启动时把注册模式强制为 `invite_only`),或者登录后在「设置 → 系统」里把 `auth.registration_mode` 改成 `invite_only`(立即生效,不用重启);
|
||||
- 如果部署把默认空间策略设成了 `tenantless`(`auth.default_tenant_mode`),注册后**不会**自动建空间,而是被引导到 `/onboarding/workspace`,需要先自建或接受邀请加入一个空间才能继续;
|
||||
- 桌面版 / Lite 版免注册,启动即自动创建本地账号。
|
||||
|
||||
::: tip 空间 Owner ≠ 系统管理员
|
||||
这两个是不同维度的身份,很容易混:
|
||||
|
||||
- **空间 Owner**:某一个工作空间内的最高权限,管这个空间的成员、模型、知识库。注册即拥有自己的空间,所以人人都是自己空间的 Owner。
|
||||
- **系统管理员(System Admin)**:平台级身份,管的是整个部署——全局系统设置、任务队列、平台 API Key、跨空间审计日志、重置用户密码。它不属于任何空间,也不会因为你在某个空间是 Owner 就自动获得。
|
||||
|
||||
新部署里**没有任何系统管理员**,需要显式指定第一个。做法:先正常注册账号,然后给 app 服务设 `WEKNORA_BOOTSTRAP_SYSTEM_ADMIN_EMAIL=<该账号邮箱>` 并重启——启动时若检测到「当前部署一个系统管理员都没有」,就把这个邮箱对应的用户提升为系统管理员。已经存在系统管理员时这个变量不再生效(避免界面上刚撤销的权限被下次重启悄悄恢复),用户没注册时也只是打一条 WARN、下次重启再试。之后新增管理员就在界面上操作即可。详见[租户、用户与认证授权](../03-features/01-tenant-auth.md)。
|
||||
:::
|
||||
|
||||
## 3. 创建知识库并配置模型
|
||||
|
||||
登录后新建一个知识库。WeKnora 的模型配置是**按知识库**走的:新建之后前端会引导你为这个库选模型,没有全局的一次性初始化。
|
||||
|
||||
1. 在「知识库」页点新建,填名称,选类型:`document`(普通文档库)或 `faq`(问答对库);
|
||||
2. 在弹出的初始化向导里选模型:
|
||||
- **对话模型(LLM)**:生成回答用;
|
||||
- **向量模型(Embedding)**:把文档转成向量用,**建库后不要再换**,换了需要重建索引;
|
||||
- 其余(重排 Rerank、图片理解 VLM、语音转写 ASR、知识图谱抽取、问题预生成)都可以先不开,之后随时能加;
|
||||
3. 用向导里的「测试」按钮确认模型连得通,再保存。
|
||||
|
||||
<Screenshot
|
||||
src="/screenshots/quickstart-init-wizard.png"
|
||||
caption="初始化向导:为知识库选择对话模型与向量模型"
|
||||
hint="展示模型来源(Ollama / 远程 API)、模型名、Base URL 输入框,以及连通性测试通过的提示。" />
|
||||
|
||||
::: tip 用本地 Ollama 时最容易踩的坑
|
||||
后端跑在容器里,填 `http://localhost:11434` 连不上宿主机的 Ollama,要填 `http://host.docker.internal:11434`。
|
||||
:::
|
||||
|
||||
## 4. 上传文档
|
||||
|
||||
进入知识库,把文件拖进上传区,或者粘贴一个网页 URL。上传确认对话框里可以顺手指定标签和这一批文件的解析选项。
|
||||
|
||||
支持的格式包括 PDF、Word、Excel、PPT、Markdown、HTML、EPUB、图片和音频等,完整清单见[文档解析服务](../03-features/03-document-parsing.md)。
|
||||
|
||||
<Screenshot
|
||||
src="/screenshots/quickstart-upload.png"
|
||||
caption="上传确认对话框:选择文件、打标签、调整解析选项"
|
||||
hint="展示待上传文件列表、标签选择与解析引擎选项。" />
|
||||
|
||||
上传后文档会异步解析,状态依次是 `pending → processing → finalizing → completed`。PDF 扫描件、大文件会慢一些,列表页会实时刷新进度。
|
||||
|
||||
<Screenshot
|
||||
src="/screenshots/quickstart-document-list.png"
|
||||
caption="文档列表:三篇文档解析完成"
|
||||
hint="展示文档名称、类型、解析状态为「已完成」、分块数等列。" />
|
||||
|
||||
## 5. 提问
|
||||
|
||||
进入对话页,选择刚才的知识库,直接提问。默认用的是内置的「快速问答」Agent:检索相关片段 → 交给大模型作答 → 回答里带出处,点引用可以跳回原文。
|
||||
|
||||
<Screenshot
|
||||
src="/screenshots/quickstart-chat.png"
|
||||
caption="知识问答:回答与可点击的引用来源"
|
||||
hint="展示一轮问答,回答正文中的引用角标以及展开后的引用来源面板。" />
|
||||
|
||||
到这一步,最小闭环就跑通了。
|
||||
|
||||
## 6. 再往前一步
|
||||
|
||||
- **换成会推理的 Agent**:在对话框顶部切换到内置的「智能推理」Agent,它会自己决定检索几轮、要不要联网、要不要调工具,适合需要多步推理的问题。也可以在「智能体」页建自定义 Agent,挂上 MCP 工具与联网搜索,见 [Agent 引擎](../03-features/07-agent.md);
|
||||
- **让答案更准**:开启 Rerank 重排、调整分块大小,见[分块机制](../03-features/04-chunking.md)与[检索引擎](../03-features/05-retrieval-engines.md);
|
||||
- **让知识自动进来**:接飞书 / Notion / 语雀 / RSS 自动同步,见[数据源导入](../03-features/10-datasource.md);
|
||||
- **让别人也能问**:接入企业微信 / 飞书等 IM,或把 Agent 以挂件形式嵌到自己的网站,见 [IM 集成](../03-features/12-im-integration.md)与[网页嵌入](../03-features/13-embed-channel.md)。
|
||||
|
||||
## 7. 用 API 走通同样的链路
|
||||
|
||||
上面每一步都有对应接口,统一前缀 `/api/v1`。下面这段可以直接跑:
|
||||
|
||||
```bash
|
||||
BASE=http://localhost:8080/api/v1
|
||||
|
||||
# 1) 注册(首次部署时;username>=2 字符,password>=6 字符)
|
||||
curl -s -X POST $BASE/auth/register -H "Content-Type: application/json" \
|
||||
-d '{"username":"admin","email":"admin@example.com","password":"pass123456"}'
|
||||
|
||||
# 2) 登录,取 JWT
|
||||
TOKEN=$(curl -s -X POST $BASE/auth/login -H "Content-Type: application/json" \
|
||||
-d '{"email":"admin@example.com","password":"pass123456"}' | jq -r '.token')
|
||||
AUTH="Authorization: Bearer $TOKEN"
|
||||
|
||||
# 3) 创建知识库
|
||||
KB_ID=$(curl -s -X POST $BASE/knowledge-bases -H "$AUTH" -H "Content-Type: application/json" \
|
||||
-d '{"name":"我的知识库","description":"demo","type":"document"}' | jq -r '.data.id')
|
||||
|
||||
# 4) 初始化知识库(以本地 Ollama 为例;远程模型改 source/baseUrl/apiKey)
|
||||
curl -s -X POST $BASE/initialization/initialize/$KB_ID -H "$AUTH" -H "Content-Type: application/json" -d '{
|
||||
"llm": {"source":"local","modelName":"qwen3:8b"},
|
||||
"embedding": {"source":"local","modelName":"bge-m3","dimension":1024},
|
||||
"rerank": {"enabled":false},
|
||||
"multimodal":{"enabled":false},
|
||||
"documentSplitting":{"chunkSize":512,"chunkOverlap":50,"separators":["\n\n","\n","。"]},
|
||||
"nodeExtract":{"enabled":false},
|
||||
"questionGeneration":{"enabled":false}}'
|
||||
|
||||
# 5) 上传文档(multipart,字段名 file)
|
||||
curl -s -X POST $BASE/knowledge-bases/$KB_ID/knowledge/file -H "$AUTH" \
|
||||
-F "file=@./demo.pdf"
|
||||
# 轮询解析状态:GET /knowledge-bases/$KB_ID/knowledge 直到 parse_status=completed
|
||||
|
||||
# 6) 创建会话
|
||||
SESSION_ID=$(curl -s -X POST $BASE/sessions -H "$AUTH" -H "Content-Type: application/json" \
|
||||
-d '{"title":"第一次对话"}' | jq -r '.data.id')
|
||||
|
||||
# 7) 知识问答(SSE 流式输出)
|
||||
curl -N -X POST $BASE/knowledge-chat/$SESSION_ID -H "$AUTH" -H "Content-Type: application/json" \
|
||||
-d '{"query":"这份文档讲了什么?","knowledge_base_ids":["'$KB_ID'"]}'
|
||||
|
||||
# 7b) Agent 对话(同为 SSE;agent_id 可取内置 builtin-smart-reasoning)
|
||||
curl -N -X POST $BASE/agent-chat/$SESSION_ID -H "$AUTH" -H "Content-Type: application/json" \
|
||||
-d '{"query":"总结文档要点并列出依据","agent_enabled":true,"agent_id":"builtin-smart-reasoning","knowledge_base_ids":["'$KB_ID'"]}'
|
||||
|
||||
# 8) 仅检索不生成(结构化 JSON 结果)
|
||||
curl -s -X POST $BASE/knowledge-search -H "$AUTH" -H "Content-Type: application/json" \
|
||||
-d '{"query":"关键字","knowledge_base_ids":["'$KB_ID'"]}'
|
||||
```
|
||||
|
||||
问答请求体还支持 `knowledge_ids`(限定单文档)、`web_search_enabled`、`summary_model_id`、`mcp_service_ids`、`skill_names`、`images` / `attachment_uploads`(多模态附件)等字段,完整说明见 [API 参考:会话与聊天](../04-api/02-api-chat.md)。
|
||||
|
||||
### 三种认证方式
|
||||
|
||||
| 方式 | 请求头 | 适用 |
|
||||
| --- | --- | --- |
|
||||
| JWT | `Authorization: Bearer <token>` | 浏览器 / 交互式调用,登录接口签发 |
|
||||
| API Key | `X-API-Key: <key>` | 服务端集成;在「空间设置」或 `POST /api/v1/tenants/:id/api-keys` 创建,支持细粒度能力(`retrieve`/`chat`/`ingest`/`manage_kbs` 等) |
|
||||
| 指定空间 | `X-Tenant-ID: <id>` | 多空间用户切换当前工作空间 |
|
||||
|
||||
服务端集成建议用 API Key 而不是 JWT:
|
||||
|
||||
```bash
|
||||
# 以 Owner 身份创建 API Key(TENANT_ID 来自登录响应)
|
||||
curl -s -X POST $BASE/tenants/$TENANT_ID/api-keys -H "$AUTH" -H "Content-Type: application/json" \
|
||||
-d '{"name":"ci-bot","full_access":true}'
|
||||
# 之后所有请求改用:
|
||||
curl -s $BASE/knowledge-bases -H "X-API-Key: <创建时返回的 key>"
|
||||
```
|
||||
|
||||
### 初始化向导对应的接口
|
||||
|
||||
界面上的每一步向导都有独立端点,自建管理后台时可以直接复用:
|
||||
|
||||
| 步骤 | 端点 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 读取当前配置 | `GET /api/v1/initialization/config/:kbId` | 返回 llm / embedding / rerank / multimodal / documentSplitting / nodeExtract / questionGeneration 各段及 `hasFiles`(已有文件时限制修改 embedding) |
|
||||
| 检测 Ollama | `GET /api/v1/initialization/ollama/status`、`GET /api/v1/initialization/ollama/models` | 检查 Ollama 可用性与已装模型 |
|
||||
| 下载 Ollama 模型 | `POST /api/v1/initialization/ollama/models/download` → `GET /api/v1/initialization/ollama/download/progress/:taskId` | 异步下载并轮询进度 |
|
||||
| 测试远程模型 | `POST /api/v1/initialization/remote/check`、`/initialization/embedding/test`、`/initialization/rerank/check`、`/initialization/asr/check`、`/initialization/multimodal/test` | 保存前连通性验证 |
|
||||
| 知识图谱试抽取 | `POST /api/v1/initialization/extract/text-relation`(配 `fabri-text` / `fabri-tag` 生成示例) | 预览实体/关系抽取效果 |
|
||||
| 保存配置 | `POST /api/v1/initialization/initialize/:kbId`(首次)/ `PUT /api/v1/initialization/config/:kbId`(更新) | 落库:创建/更新 Model 记录并写入 KnowledgeBase 配置 |
|
||||
|
||||
`source` 取 `local`(Ollama)或远程厂商标识(`openai`、`deepseek`、`aliyun`、`zhipu`、`siliconflow` 等)。`chunkSize` 合法范围 100–10000。
|
||||
|
||||
### 整条链路发生了什么
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant U as "用户 (浏览器)"
|
||||
participant FE as "frontend (Nginx)"
|
||||
participant APP as "app 后端 (:8080)"
|
||||
participant DR as "docreader (gRPC)"
|
||||
participant DB as "ParadeDB / 向量索引"
|
||||
participant LLM as "LLM (Ollama / 远程 API)"
|
||||
U->>FE: 注册 / 登录
|
||||
FE->>APP: POST /api/v1/auth/register → login
|
||||
APP-->>FE: JWT + 自动创建的租户
|
||||
U->>APP: POST /api/v1/knowledge-bases (创建知识库)
|
||||
U->>APP: POST /api/v1/initialization/initialize/:kbId (配置模型)
|
||||
APP->>LLM: 连通性测试 (remote/check, embedding/test)
|
||||
U->>APP: POST /api/v1/knowledge-bases/:id/knowledge/file (上传)
|
||||
APP->>DR: gRPC 解析文档 (OCR / 版式 / 图片)
|
||||
DR-->>APP: 结构化文本 + 图片
|
||||
APP->>DB: 分块 → Embedding → 向量/关键词索引 (Asynq 异步)
|
||||
U->>APP: POST /api/v1/sessions (创建会话)
|
||||
U->>APP: POST /api/v1/knowledge-chat/:session_id (提问)
|
||||
APP->>DB: 混合检索 (向量+BM25) → RRF → Rerank
|
||||
APP->>LLM: 拼装上下文生成回答
|
||||
APP-->>U: SSE 流式回答 + 引用来源
|
||||
```
|
||||
|
||||
## 8. 卡住了看这里
|
||||
|
||||
| 现象 | 检查点 |
|
||||
| --- | --- |
|
||||
| 上传后一直 `processing` | `docker logs WeKnora-docreader`;大文件受 `MAX_FILE_SIZE_MB`(默认 50)与 `WEKNORA_DOCUMENT_PROCESS_TIMEOUT`(默认 2h)约束 |
|
||||
| 初始化时 Ollama 检测失败 | 容器内默认地址 `http://host.docker.internal:11434`(`OLLAMA_BASE_URL`);Linux 需确认 `extra_hosts: host.docker.internal:host-gateway` 生效 |
|
||||
| 问答无引用 / 召回为空 | 确认知识解析 `completed`;调低 `vector_threshold`;检查 embedding 模型与建库时一致 |
|
||||
| 注册页签消失 | 查 `GET /auth/config` 的 `registration_mode`。值可能来自「设置 → 系统」里的数据库设置,不只是 `DISABLE_REGISTRATION`;邀请链接与 OIDC 首次登录是另外两条通路,不受它影响 |
|
||||
| API Key 请求 403 | Key 的 capabilities 不含所需能力,或 `knowledge_base_ids` 白名单未包含目标库 |
|
||||
|
||||
下一步:想调细节看[配置详解](./04-configuration.md),想了解系统怎么运转看[总体架构](../02-architecture/01-overview.md)。
|
||||
@@ -0,0 +1,373 @@
|
||||
# 配置详解
|
||||
|
||||
WeKnora 的配置由四层组成,**优先级从低到高**:
|
||||
|
||||
| 层 | 位置 | 什么时候用 |
|
||||
| --- | --- | --- |
|
||||
| 主配置文件 | `config/config.yaml` | 结构化的默认值,随镜像分发 |
|
||||
| 模板 / 预设 | `config/prompt_templates/*.yaml`、`builtin_agents.yaml`、`agent_type_presets.yaml`、`builtin_models.yaml` | 提示词、内置 Agent、内置模型 |
|
||||
| 环境变量 | `.env` / 容器 environment | 部署级覆盖,改完需重启 |
|
||||
| 运行时系统设置 | 数据库 `system_settings` 表,界面在「设置 → 系统」 | 一部分开关可以在线改,**盖过环境变量**,绝大多数立即生效 |
|
||||
|
||||
最后一层容易被忽略,却是排查「改了 env 没生效」的第一现场:注册模式、空间策略与配额、SSRF 白名单、各 worker pool 并发、模型并发上限这些键一旦在界面上改过,数据库里就留下一行记录,此后环境变量不再起作用;把该项重置(`DELETE /api/v1/system/admin/settings/:key`)才会回落到环境变量或内置默认值。完整键表与语义见[租户、用户与认证授权](../03-features/01-tenant-auth.md)的「运行时可改的系统设置」。
|
||||
|
||||
下文对照 `internal/config/config.go` 中的结构体逐段解读,并在末尾汇总环境变量。
|
||||
|
||||
## 配置加载机制
|
||||
|
||||
`internal/config/config.go` 的 `LoadConfig()` 流程:
|
||||
|
||||
1. viper 按顺序查找 `config.yaml`:当前目录 → `./config` → `$HOME/.appname` → `/etc/appname/`;
|
||||
2. **环境变量展开**:对文件内容做正则替换,`${ENV_VAR}` 会被同名环境变量的值替换;变量未设置时保留字面量 `${ENV_VAR}` 原样(便于暴露配置错误);
|
||||
3. viper 开启 `AutomaticEnv()` 且 key 分隔符 `.` 映射为 `_`(即 `server.port` 可被环境变量 `SERVER_PORT` 覆盖);
|
||||
4. 从 `config/prompt_templates/*.yaml` 加载提示词模板,并按 `xxx_prompt_id` 字段**回填**到 conversation 配置(`backfillConversationDefaults`);
|
||||
5. 加载 `builtin_agents.yaml`(内置 Agent)与 `agent_type_presets.yaml`(Agent 类型预设),并解析其中的 `system_prompt_id` 引用;
|
||||
6. 应用环境变量覆盖(OIDC、Agent、KnowledgeBase、Auth/Tenant、Audit 各组)并执行 `ValidateConfig` 校验。
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Y["config/config.yaml"] --> EXP["展开 dollar-brace 环境变量引用"]
|
||||
EXP --> V["viper Unmarshal 为 Config 结构体"]
|
||||
PT["config/prompt_templates/*.yaml"] --> BF["backfillConversationDefaults (按 *_prompt_id 解析为文本)"]
|
||||
V --> BF
|
||||
BA["config/builtin_agents.yaml"] --> LD["LoadBuiltinAgentsConfig"]
|
||||
AP["config/agent_type_presets.yaml"] --> LD2["LoadAgentTypePresetsConfig"]
|
||||
BF --> OV["applyOIDCEnvOverrides / applyAgentEnvOverrides / applyKnowledgeBaseEnvOverrides / applyAuthAndTenantDefaults / applyAuditDefaults"]
|
||||
LD --> OV
|
||||
LD2 --> OV
|
||||
OV --> VC["ValidateConfig"] --> CFG["最终 *config.Config"]
|
||||
```
|
||||
|
||||
## config/config.yaml 逐段解读
|
||||
|
||||
### server(`ServerConfig`)
|
||||
|
||||
| 名称 | 类型 | 默认值 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `server.port` | int | 8080 | HTTP 监听端口,校验范围 1–65535 |
|
||||
| `server.host` | string | "0.0.0.0" | 监听地址 |
|
||||
| `server.log_path` | string | 空 | 日志文件路径(也可用环境变量 `LOG_PATH`) |
|
||||
| `server.shutdown_timeout` | duration | 30s | 优雅停机超时 |
|
||||
|
||||
### conversation(`ConversationConfig`)——检索问答管线
|
||||
|
||||
| 名称 | 类型 | 默认值(config.yaml) | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `max_rounds` | int | 5 | 携带的多轮历史轮数 |
|
||||
| `keyword_threshold` | float | 0.3 | 关键词检索最低分 |
|
||||
| `embedding_top_k` | int | 30 | 向量检索召回条数(>=0) |
|
||||
| `vector_threshold` | float | 0.2 | 向量相似度阈值(0–1) |
|
||||
| `rerank_top_k` | int | 30 | 重排后保留条数 |
|
||||
| `rerank_threshold` | float | 0.3 | 重排最低分(-10–10) |
|
||||
| `fallback_strategy` | string | "model" | 召回为空时策略:`model`(让模型兜底)或固定回复 |
|
||||
| `fallback_response` | string | "Sorry, I am unable to answer this question." | 固定兜底文案 |
|
||||
| `enable_rewrite` | bool | true | 多轮指代消解 / 查询改写 |
|
||||
| `enable_query_expansion` | bool | true | 查询扩展 |
|
||||
| `enable_rerank` | bool | true | 启用 Rerank |
|
||||
| `fallback_prompt_id` | string | "default_fallback_prompt" | 兜底 prompt 模板 ID(`prompt_templates/fallback.yaml`,mode:"model") |
|
||||
| `rewrite_prompt_id` | string | "default_rewrite" | 改写模板 ID(含 content 系统侧 + user 用户侧) |
|
||||
| `generate_summary_prompt_id` | string | "default_summary" | 文档摘要模板 ID |
|
||||
| `generate_session_title_prompt_id` | string | "default_session_title" | 会话标题生成模板 ID |
|
||||
| `extract_entities_prompt_id` / `extract_relationships_prompt_id` | string | "default_extract_entities" / "default_extract_relationships" | 图谱抽取模板 ID(`graph_extraction.yaml`) |
|
||||
| `generate_questions_prompt_id` | string | "default_generate_questions" | 预生成问题模板 ID |
|
||||
|
||||
`conversation.summary`(`SummaryConfig`,答案生成参数):
|
||||
|
||||
| 名称 | 类型 | 默认值 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `max_input_chars` | int | 16384 | 送入 LLM 的最大字符数 |
|
||||
| `temperature` | float | 0.3 | 生成温度 |
|
||||
| `repeat_penalty` | float | 1.0 | 重复惩罚 |
|
||||
| `max_completion_tokens` | int | 2048 | 最大生成 token |
|
||||
| `no_match_prefix` | string | `<think>\n</think>\nNO_MATCH` | 模型输出以此为前缀时判定「未命中」触发 fallback |
|
||||
| `prompt_id` | string | "default_kb" | 系统 Prompt 模板 ID(`system_prompt.yaml`) |
|
||||
| `context_template_id` | string | "default_context" | 上下文拼装模板 ID(`context_template.yaml`) |
|
||||
| `max_tokens` / `top_k` / `top_p` / `frequency_penalty` / `presence_penalty` / `seed` / `thinking` | 多种 | 未设置 | 透传给模型的可选采样参数;`thinking` 为 `*bool` 控制思考模式 |
|
||||
|
||||
### knowledge_base(`KnowledgeBaseConfig`)——全局默认分块
|
||||
|
||||
| 名称 | 类型 | 默认值 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `chunk_size` | int | 512 | 默认分块大小(>0,且 > overlap) |
|
||||
| `chunk_overlap` | int | 50 | 分块重叠 |
|
||||
| `split_markers` | []string | `["\n\n", "\n", "。"]` | 分割标记 |
|
||||
| `keep_separator` | bool | false | 保留分隔符 |
|
||||
| `document_process_timeout` | duration | 2h | 单文档处理任务总超时(env `WEKNORA_DOCUMENT_PROCESS_TIMEOUT` 可覆盖) |
|
||||
| `docreader_call_timeout` | duration | 30m | 单次 DocReader RPC 超时(env `WEKNORA_DOCREADER_CALL_TIMEOUT`),须小于上一项 |
|
||||
| `image_processing.enable_multimodal` | bool | true | 上传时启用图片多模态处理(OCR/Caption) |
|
||||
|
||||
> 每个知识库的 `ChunkingConfig` 会覆盖这里的全局默认值。
|
||||
|
||||
### extract(`ExtractManagerConfig`)——知识图谱抽取模板
|
||||
|
||||
`extract.extract_graph` / `extract.extract_entity` / `extract.fabri_text` 定义图谱抽取的说明文(`description`)、允许的关系标签(`tags`,默认 `Author`、`Alias`)与 few-shot 示例(`examples`:`text` + `node` + `relation`)。初始化向导中的「试抽取 / 生成示例文本」即使用这些配置(`fabri_text.with_tag` / `with_no_tag` 中的 `%s` 会被标签列表替换)。
|
||||
|
||||
### tenant(`TenantConfig`)
|
||||
|
||||
| 名称 | 类型 | 默认值 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `enable_cross_tenant_access` | bool | false | 允许具备 `CanAccessAllTenants` 的用户跨空间访问(内网可开) |
|
||||
| `enable_rbac` | *bool | true | 空间角色强制鉴权;显式 `false` 进入仅记录不拦截的灰度模式(env `WEKNORA_TENANT_ENABLE_RBAC`) |
|
||||
| `max_owned_per_user` | int | 0(走 handler 默认) | 单个非超管可自建空间数上限;<0 关闭限制(env `WEKNORA_TENANT_MAX_OWNED_PER_USER`) |
|
||||
| `self_service_creation_enabled` | *bool | true | 普通用户能否自建空间(env `WEKNORA_TENANT_SELF_SERVICE_CREATION_ENABLED`) |
|
||||
| `default_session_name` / `default_session_title` / `default_session_description` | string | 空 | 新会话默认文案 |
|
||||
|
||||
### 结构体支持但默认文件未写出的段
|
||||
|
||||
以下段落在 `Config` 结构体中存在,可按需追加到 `config.yaml`(多数也有环境变量入口):
|
||||
|
||||
| 段 | 结构体 | 关键字段与默认值 |
|
||||
| --- | --- | --- |
|
||||
| `auth` | `AuthConfig` | `registration_mode`:`self_serve`(默认)/ `invite_only`(`DISABLE_REGISTRATION=true` 时强制);`default_tenant_mode`:`create_personal`(默认)/ `tenantless` |
|
||||
| `audit` | `AuditConfig` | `retention_days`:审计日志保留天数,段落省略时默认 90;0 禁用清理;<0 校验报错(env `WEKNORA_AUDIT_RETENTION_DAYS`) |
|
||||
| `oidc_auth` | `OIDCAuthConfig` | `enable`、`issuer_url`、`discovery_url`(缺省由 issuer 拼 `/.well-known/openid-configuration`)、`client_id`、`client_secret`、`authorization_endpoint`、`token_endpoint`、`user_info_endpoint`、`scopes`(默认 `openid profile email`)、`user_info_mapping.username`(默认 `name`)/`email`(默认 `email`);全部可用 `OIDC_AUTH_*` 环境变量覆盖 |
|
||||
| `agent` | `AgentConfig` | `llm_call_timeout`:单次 LLM 调用超时秒数(默认 120,env `WEKNORA_AGENT_LLM_TIMEOUT`);`tool_approval_timeout_seconds`:MCP 工具人工审批等待(默认 600,env `WEKNORA_AGENT_TOOL_APPROVAL_TIMEOUT`) |
|
||||
| `im` | `IMConfig` | IM 渠道 QA 并发:`workers`(5)、`global_max_workers`(0=不限,需 Redis)、`max_queue_size`(50)、`max_per_user`(3)、`rate_limit_window`(60s)、`rate_limit_max`(10) |
|
||||
| `docreader` | `DocReaderConfig` | `addr`(gRPC 地址如 `docreader:50051` 或 HTTP base URL)、`transport`:`grpc`(默认)/ `http`;通常用 env `DOCREADER_ADDR` / `DOCREADER_TRANSPORT` |
|
||||
| `vector_database` | `VectorDatabaseConfig` | `driver`(通常用 env `RETRIEVE_DRIVER`) |
|
||||
| `stream_manager` | `StreamManagerConfig` | `type`:`memory` / `redis`;`redis.address/username/password/db/prefix/ttl`;`cleanup_timeout`(通常用 env `STREAM_MANAGER_TYPE`、`REDIS_*`) |
|
||||
| `web_search` | `WebSearchConfig` | `timeout`:Web 搜索超时秒数 |
|
||||
| `models` | `[]ModelConfig` | 历史遗留的静态模型清单(`type`/`source`/`model_name`/`parameters`);现推荐用 `builtin_models.yaml` 或界面配置 |
|
||||
| `frontend_base_url` | string | 空 | SPA 对外 origin,用于生成邀请等绝对链接(env `FRONTEND_BASE_URL`) |
|
||||
|
||||
## 重要环境变量
|
||||
|
||||
以下变量来自 `docker-compose.yml` 的 app/docreader `environment` 段、`.env.example` 与代码中的 `os.Getenv`。生产部署至少要改:`DB_USER/DB_PASSWORD/DB_NAME`、`REDIS_PASSWORD`、`JWT_SECRET`、`SYSTEM_AES_KEY`。
|
||||
|
||||
### 运行时基础
|
||||
|
||||
| 名称 | 默认值 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `GIN_MODE` | release | `debug` 开发模式(启用 Swagger)/ `release` 生产 |
|
||||
| `LOG_LEVEL` / `LOG_PATH` / `LOG_FORMAT` | debug / 空 / 空 | 日志级别、文件路径(空则仅 stdout)、自定义格式 |
|
||||
| `LLM_DEBUG_LOG` | false | true 时在 LOG_PATH 同目录写 `llm_debug.log` |
|
||||
| `TZ` | Asia/Shanghai | 时区 |
|
||||
| `WEKNORA_LANGUAGE` | 空 | 文档处理语言(问题/摘要生成)。优先级:本变量 > 请求的 `Accept-Language` > 内置 `zh-CN`。**它压过请求头**是刻意的:界面语言与文档处理语言是两件事,允许「英文界面 + 处理韩文文档」 |
|
||||
| `AUTO_MIGRATE` | true | 启动时自动执行数据库迁移 |
|
||||
| `AUTO_RECOVER_DIRTY` | true | 自动修复 golang-migrate 的 dirty 状态(上次迁移中断留下的)。手工排查迁移问题时应临时设为 false,否则启动会自动改写迁移版本记录,见[数据库与迁移](../06-development/02-database-schema.md) |
|
||||
| `WEKNORA_TRUSTED_PROXIES` | 空 | gin 信任代理 CIDR(逗号分隔) |
|
||||
| `MAX_FILE_SIZE_MB` | 50 | 上传文件大小限制(app/frontend/docreader 三处共用) |
|
||||
| `CONCURRENCY_POOL_SIZE` | 5 | 通用并发池 |
|
||||
| `APP_EXTERNAL_URL` / `FRONTEND_BASE_URL` | 空 | IM 渠道图片/文件外链的外部可达 URL / 前端外部 origin |
|
||||
| `RESOURCE_URL_MODE` | handle | API 响应里文件引用的默认形式:`handle` 返回内部 `resource://`,`public` 返回可直接加载的限时外链。单次请求可用 `?resource_urls=` 覆盖,详见 [API 总览](../04-api/01-api-overview.md) |
|
||||
|
||||
`APP_EXTERNAL_URL` 影响 IM 渠道能否渲染知识库图片。IM 平台需要拿到公网 http(s) URL,二选一:
|
||||
|
||||
1. 存储后端本身公网可达(对象存储用公网 endpoint,或把 `MINIO_ENDPOINT` 设成公网 host),此时 `resource://` 回退到后端预签名 URL,不需要本变量;
|
||||
2. 设置 `APP_EXTERNAL_URL`,`resource://` 图片被改写成 `<APP_EXTERNAL_URL>/r/<token>` 走 WeKnora 自身(需要 nginx 代理 `/r/`,官方前端镜像已内置该 location)。
|
||||
|
||||
默认的 MinIO 内网部署与 `local` 后端都只能走第二种。IM 渠道已启用但本变量为空时,服务启动会打印一次 WARN;改写结果若不是 http(s) URL 会保留原引用并记录可操作的告警,而不是发出 IM 端无法访问的链接。
|
||||
|
||||
四种 URL 形式与各渠道的取法见[图片与文件的对外访问](../03-features/21-file-access.md)。
|
||||
|
||||
### 数据库与队列
|
||||
|
||||
| 名称 | 默认值 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `DB_DRIVER` | postgres | `postgres` / `sqlite`(Lite) |
|
||||
| `DB_HOST` / `DB_PORT` / `DB_USER` / `DB_PASSWORD` / `DB_NAME` | postgres / 5432 / 空 / 空 / 空 | PostgreSQL 连接(必填) |
|
||||
| `DB_PATH` | — | `DB_DRIVER=sqlite` 时的数据库文件路径 |
|
||||
| `STREAM_MANAGER_TYPE` | 空(compose 实际走 redis) | `redis` / `memory` |
|
||||
| `REDIS_ADDR` / `REDIS_USERNAME` / `REDIS_PASSWORD` / `REDIS_DB` / `REDIS_PREFIX` | redis:6379 / … | Redis 连接 |
|
||||
| `REDIS_USE_TLS` | false | **启用 TLS 的总开关**,托管 Redis(如 AWS ElastiCache)需要打开;`REDIS_TLS_SERVER_NAME` 指定校验与 SNI 用的服务器名(地址是 IP 时有用),`REDIS_TLS_INSECURE_SKIP_VERIFY` 跳过证书校验(不安全,仅自签证书的开发环境用) |
|
||||
| `WEKNORA_REDIS_NAMESPACE` | 空 | 多部署共用 Redis 时的频道命名空间后缀 |
|
||||
| `WEKNORA_ASYNQ_CORE_CONCURRENCY` 等 | 8 / 2 / 12 / 4 / 6 | Asynq 各队列并发(core/postprocess/enrichment/maintenance/shared),另有 `WEKNORA_WIKI_ASYNQ_CONCURRENCY=8`、`WEKNORA_MODEL_MAX_CONCURRENCY=32` |
|
||||
|
||||
### 检索引擎与向量库
|
||||
|
||||
| 名称 | 默认值 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `RETRIEVE_DRIVER` | postgres | 检索引擎:`postgres` / `elasticsearch_v7` / `elasticsearch_v8` / `qdrant` / `milvus` / `weaviate` / `opensearch` / `doris` / `tencent_vectordb` / `sqlite`(Lite);可逗号分隔多引擎并行 |
|
||||
| `ELASTICSEARCH_ADDR/USERNAME/PASSWORD/INDEX` | 空 | Elasticsearch |
|
||||
| `QDRANT_HOST/PORT/COLLECTION/API_KEY/USE_TLS` | qdrant / 6334 / weknora_embeddings / 空 / false | Qdrant |
|
||||
| `MILVUS_ADDRESS/COLLECTION/METRIC_TYPE/...` | milvus:19530 / weknora_embeddings / IP | Milvus |
|
||||
| `OPENSEARCH_ADDR/USERNAME/PASSWORD/INDEX/INSECURE_SKIP_VERIFY` | 空 | OpenSearch |
|
||||
| `WEAVIATE_HOST/GRPC_ADDRESS/SCHEME/AUTH_ENABLED/API_KEY` | 空 | Weaviate |
|
||||
| `DORIS_ADDR/HTTP_PORT/DATABASE/USERNAME/PASSWORD/TABLE_PREFIX/COMPAT_MODE` | 空 | Apache Doris 4.1+ |
|
||||
| `TENCENT_VECTORDB_ADDR/USERNAME/API_KEY/DATABASE/COLLECTION/REPLICA_NUMBER` | 空 | 腾讯云 VectorDB |
|
||||
| `MULTI_STORE_RETRIEVE_TIMEOUT_SEC` | 空 | 多引擎并行检索超时 |
|
||||
| `NEO4J_ENABLE` / `NEO4J_URI` / `NEO4J_USERNAME` / `NEO4J_PASSWORD` | 空 / bolt://neo4j:7687 / neo4j / password | 知识图谱唯一开关(`ENABLE_GRAPH_RAG` 自 v0.1.6 起废弃) |
|
||||
|
||||
### 文件存储
|
||||
|
||||
| 名称 | 默认值 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `STORAGE_TYPE` | local | `local` / `minio` / `cos` / `tos` / `s3` / `obs` / `oss` |
|
||||
| `STORAGE_ALLOW_LIST` | 空 | 允许用户选择的存储类型白名单(逗号分隔) |
|
||||
| `LOCAL_STORAGE_BASE_DIR` | /data/files | 本地存储根目录 |
|
||||
| `MINIO_ENDPOINT/ACCESS_KEY_ID/SECRET_ACCESS_KEY/BUCKET_NAME/USE_SSL` | minio:9000 / minioadmin / minioadmin / 空 / false | MinIO |
|
||||
| `COS_SECRET_ID/SECRET_KEY/REGION/BUCKET_NAME/APP_ID/PATH_PREFIX` | 空 | 腾讯云 COS(另有 TEMP_BUCKET/TEMP_REGION) |
|
||||
| `S3_*` / `OBS_*` / `OSS_*` / `TOS_*` | 见 `.env.example` B4 节 | AWS S3 / 华为 OBS / 阿里 OSS / 火山 TOS,均含 ENDPOINT/REGION/KEY/BUCKET/PATH_PREFIX 等 |
|
||||
|
||||
AWS S3 的 `S3_ACCESS_KEY` / `S3_SECRET_KEY` 可以**同时留空**,此时走 AWS SDK 默认凭证链,支持 EC2/ECS/EKS IAM Role、IRSA/Web Identity、环境变量与共享配置文件——在 AWS 上部署时不必再往环境变量里塞长期密钥。两者必须同填或同空。`S3_ENDPOINT` 留空则使用 Region 对应的标准端点。
|
||||
|
||||
### 模型与推理
|
||||
|
||||
| 名称 | 默认值 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `OLLAMA_BASE_URL` | http://host.docker.internal:11434 | Ollama 地址 |
|
||||
| `OLLAMA_OPTIONAL` | true | Ollama 不可用时仅告警不阻断启动 |
|
||||
| `BATCH_EMBED_SIZE` | 空 | 批量 embedding 大小 |
|
||||
| `VLM_HTTP_TIMEOUT_SECONDS` | 180 | VLM 单次请求超时 |
|
||||
| `BUILTIN_MODELS_CONFIG` | config/builtin_models.yaml | 内置模型声明文件路径(见下文) |
|
||||
| `WEKNORA_LLM_STREAM_RAW_DUMP` / `_DIR` | 空 | LLM 流原始转储(排障用) |
|
||||
|
||||
### 认证、租户与安全
|
||||
|
||||
| 名称 | 默认值 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `JWT_SECRET` | 空 | JWT 签名密钥(必填) |
|
||||
| `SYSTEM_AES_KEY` | 空 | 敏感字段落盘加密的 AES-256 主密钥,**必须 32 字节**;丢失则已加密数据(租户 API Key、模型 key、向量库凭证等)不可恢复。v0.4.0 起取代 `TENANT_AES_KEY`/`CRYPTO_MASTER_KEY`/`CRYPTO_SALT` |
|
||||
| `DISABLE_REGISTRATION` | false | true 时强制 `registration_mode=invite_only` |
|
||||
| `WEKNORA_AUTH_DEFAULT_TENANT_MODE` | create_personal | 注册后建空间策略(`create_personal` / `tenantless`) |
|
||||
| `WEKNORA_TENANT_ENABLE_RBAC` | (默认 true) | 空间角色强制鉴权开关 |
|
||||
| `WEKNORA_TENANT_ENABLE_CROSS_TENANT_ACCESS` | false | 跨空间访问 |
|
||||
| `WEKNORA_TENANT_SELF_SERVICE_CREATION_ENABLED` | true | 普通用户自建空间 |
|
||||
| `WEKNORA_TENANT_MAX_OWNED_PER_USER` | 空 | 自建空间上限 |
|
||||
| `WEKNORA_TENANT_AUTO_CREATE_API_KEY` | false | 建空间时自动下发 full_access API Key(兼容旧行为) |
|
||||
| `WEKNORA_TENANT_DEFAULT_STORAGE_QUOTA_GB` | 10 | 新空间默认存储配额 |
|
||||
| `WEKNORA_INVITATION_TTL` | 168h | 邀请链接有效期 |
|
||||
| `WEKNORA_AUDIT_RETENTION_DAYS` | 90 | 审计日志保留天数 |
|
||||
| `WEKNORA_BOOTSTRAP_SYSTEM_ADMIN_EMAIL` | 空 | 引导第一个系统管理员。**不会创建用户**:该邮箱需先自行注册,下次启动时若部署内还没有任何系统管理员,才把它提升;已有管理员后本变量不再生效。详见[租户、用户与认证授权](../03-features/01-tenant-auth.md) |
|
||||
| `OIDC_AUTH_ENABLE` 及 `OIDC_AUTH_*` / `OIDC_USER_INFO_MAPPING_*` | false / 空 | OIDC 单点登录全套配置 |
|
||||
| `SSRF_WHITELIST` / `SSRF_WHITELIST_EXTRA` | 空 / `searxng,qdrant,milvus,weaviate,doris-fe,doris-be` | 出站请求 SSRF 白名单(app 与 docreader 共用) |
|
||||
| `IMAGE_HOST_KEEP_URL` | 空 | 保留原始 URL 的图片域名白名单 |
|
||||
|
||||
### Docreader 解析(docreader 容器)
|
||||
|
||||
| 名称 | 默认值 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `DOCREADER_ADDR` / `DOCREADER_TRANSPORT` | docreader:50051 / grpc | app 侧连接地址与传输(`grpc`/`http`) |
|
||||
| `DOCREADER_GRPC_MAX_WORKERS` / `DOCREADER_GRPC_PORT` / `DOCREADER_GRPC_MAX_FILE_SIZE_MB` | 4 / 50051 / 跟随 MAX_FILE_SIZE_MB | gRPC 服务参数 |
|
||||
| `GRPC_TLS_ENABLED/CERT/KEY/CA/SERVER_NAME`、`GRPC_MTLS_REQUIRE_CLIENT_CERT`、`GRPC_AUTH_TOKEN` | false / 空 | app↔docreader 链路 TLS/mTLS 与 token 认证 |
|
||||
| `DOCREADER_PDF_RENDER_DPI` / `DOCREADER_PDF_JPEG_QUALITY` / `DOCREADER_PDF_RENDER_MAX_EDGE` | 200 / 85 / 2000 | PDF 渲染 |
|
||||
| `DOCREADER_PDF_FORCE_SCANNED` / `DOCREADER_PDF_SCAN_IMAGE_RATIO` / `DOCREADER_PDF_SCAN_MIN_CHARS` | false / 代码默认 | 扫描件判定 |
|
||||
| `DOCREADER_ODL_HYBRID` / `DOCREADER_ODL_HYBRID_URL` / `DOCREADER_ODL_HYBRID_MODE` / `DOCREADER_ODL_HYBRID_FALLBACK` | off / http://odl-hybrid:5002 / auto / false | OpenDataLoader 混合解析 |
|
||||
| 其余 `DOCREADER_PDF_*`(词距/边栏/隐藏文本/嵌入图/图表区等 20+ 项) | 见 `docker-compose.yml` docreader 段注释 | PDF 版式与抽取精调 |
|
||||
| `DOCREADER_EXTERNAL_HTTP_PROXY` / `_HTTPS_PROXY` | 空 | docreader 出站抓取代理 |
|
||||
|
||||
### Agent、Skills 与附件
|
||||
|
||||
| 名称 | 默认值 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| Sandbox 配置 | 设置页按空间维护 | 后端、凭据、模板、超时和私网访问策略按空间保存 |
|
||||
| `WEKNORA_SANDBOX_DOCKER_ENABLED` | false | Docker 沙箱后端回退开关。系统管理员也可在「设置 → 系统设置」打开(DB 优先,立即生效)。默认关闭,因为本机 `docker.sock` 等同宿主机 root |
|
||||
| `WEKNORA_SKILLS_DIR` | 空(镜像内 /app/skills/preloaded) | 自定义 Skills 目录 |
|
||||
| `WEKNORA_AGENT_LLM_TIMEOUT` | 120s | Agent 单次 LLM 调用超时(Go duration 或纯数字秒) |
|
||||
| `WEKNORA_AGENT_TOOL_APPROVAL_TIMEOUT` / `_FAIL_OPEN` | 600s / fail-close | MCP 工具人工审批等待与失败策略 |
|
||||
| `WEKNORA_CHAT_ATTACHMENT_TTL_HOURS` / `_WAIT_TIMEOUT_SEC` / `_OCR_CONCURRENCY` / `_OCR_MAX_PAGES` | 24 / 60 / 8 / 8 | 聊天附件解析保留时长、等待超时与 OCR 并发/页数上限 |
|
||||
| `WEKNORA_HOUSEKEEPING_ENABLED` | 启用 | 回收卡在 processing 的脏数据 |
|
||||
| `WEKNORA_DOCUMENT_PROCESS_TIMEOUT` / `WEKNORA_DOCREADER_CALL_TIMEOUT` | 2h / 30m | 文档处理任务与单次 RPC 超时 |
|
||||
|
||||
### 可观测性(Langfuse)
|
||||
|
||||
`LANGFUSE_PUBLIC_KEY` + `LANGFUSE_SECRET_KEY` 同时设置即自动启用;`LANGFUSE_HOST`(默认 `https://cloud.langfuse.com`,自建栈填 `http://langfuse-web:3000`)、`LANGFUSE_ENABLED`、`LANGFUSE_RELEASE`、`LANGFUSE_ENVIRONMENT`、`LANGFUSE_SAMPLE_RATE`、`LANGFUSE_FLUSH_AT/FLUSH_INTERVAL/QUEUE_SIZE/REQUEST_TIMEOUT/DEBUG` 为调优项;`--profile langfuse` 自建栈另有 `LANGFUSE_SALT`、`LANGFUSE_ENCRYPTION_KEY`、`LANGFUSE_NEXTAUTH_SECRET`、`LANGFUSE_INIT_*`(首启自动建组织/项目/管理员)等,见 `.env.example` I1/I2 节。
|
||||
|
||||
### 可选服务:SearXNG 与 MCP Server
|
||||
|
||||
这两组变量只在启用对应 compose profile 时才需要,独立于主服务。
|
||||
|
||||
**SearXNG**(自托管元搜索,`--profile searxng` / `full`):
|
||||
|
||||
| 名称 | 默认值 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `SEARXNG_PORT` | 8888 | 宿主机端口 |
|
||||
| `SEARXNG_BIND` | 127.0.0.1 | **默认只监听本机**。WeKnora 打包的配置关掉了 SearXNG 自身的限流(否则后端会被节流),所以不应直接暴露到 LAN;确实要开放请显式改成 `0.0.0.0` 并自行加固 |
|
||||
| `SEARXNG_SECRET` | 空 | 入口脚本用它替换 `settings.yml` 里的 `secret_key`,对外开放时必须设 |
|
||||
|
||||
自建 SearXNG 时记得把 `127.0.0.1` 加进 `SSRF_WHITELIST`,否则后端的 SSRF 防护会拦掉本机地址。用法见[网络搜索与网页抓取](../03-features/11-web-search.md)。
|
||||
|
||||
**MCP Server**(把 WeKnora 暴露给 Claude Desktop 等 MCP 客户端,`--profile full`):
|
||||
|
||||
| 名称 | 默认值 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `WEKNORA_API_KEY` | 空 | mcp-server 反过来调 WeKnora REST 用的 Key,在「设置 → API Keys」生成 |
|
||||
| `MCP_SERVER_AUTH_TOKEN` | 空 | **HTTP/SSE 传输必填**,缺失时进程直接拒绝启动;客户端以 `Authorization: Bearer` 携带 |
|
||||
| `WEKNORA_CHAT_TIMEOUT` | 300 | 调 WeKnora REST 的读超时(秒) |
|
||||
| `WEKNORA_VERIFY_SSL` | true | 是否校验后端 TLS 证书,自签证书可设 false |
|
||||
| `MCP_ALLOWED_UPLOAD_DIRS` | 空 | 允许上传的目录白名单(逗号分隔),留空即禁用文件上传工具 |
|
||||
|
||||
完整说明见 [MCP 集成](../03-features/08-mcp.md)。
|
||||
|
||||
## config/prompt_templates/:提示词模板
|
||||
|
||||
每类 Prompt 一个 YAML 文件,统一结构为 `templates:` 列表;单个模板字段(`PromptTemplate` 结构体,`internal/config/config.go`):
|
||||
|
||||
| 字段 | 说明 |
|
||||
| --- | --- |
|
||||
| `id` | 唯一 ID,被 config.yaml 的 `*_prompt_id`、内置 Agent 的 `system_prompt_id`、类型预设引用 |
|
||||
| `name` / `description` | 展示名与说明 |
|
||||
| `content` | 系统侧 Prompt 正文(所有模板必备) |
|
||||
| `user` | 用户侧 Prompt(仅 system+user 配对模板使用,如 rewrite、keywords_extraction) |
|
||||
| `default` | 是否为该类默认模板 |
|
||||
| `mode` | 子类区分(如 fallback 中 `model` 表示模型兜底 prompt) |
|
||||
| `has_knowledge_base` / `has_web_search` | 模板适用场景标记 |
|
||||
| `i18n` | 多语言 name/description(键为 locale,如 `zh-CN`) |
|
||||
|
||||
各文件用途与内含模板 ID:
|
||||
|
||||
| 文件 | 用途 | 模板 ID |
|
||||
| --- | --- | --- |
|
||||
| `system_prompt.yaml` | 问答系统 Prompt(quick-answer / RAG) | `default_kb`(默认)、`expert_assistant`、`customer_service`、`technical_support`、`pure_chat`、`web_search_assistant` |
|
||||
| `context_template.yaml` | 检索结果拼装为上下文的模板 | `default_context`、`detailed_context`、`simple_context`、`qa_context` |
|
||||
| `rewrite.yaml` | 多轮查询改写(content+user 成对) | `default_rewrite`、`standard_rewrite`、`strict_rewrite` |
|
||||
| `fallback.yaml` | 未命中兜底(固定回复 + `mode:"model"` 模型兜底) | `default_fallback`、`polite_fallback`、`brief_fallback`、`model_fallback`、`default_fallback_prompt` |
|
||||
| `generate_session_title.yaml` | 会话标题生成 | `default_session_title` |
|
||||
| `generate_summary.yaml` | 文档摘要生成 | `default_summary` |
|
||||
| `generate_questions.yaml` | 文档预生成问题 | `default_generate_questions` |
|
||||
| `keywords_extraction.yaml` | 关键词抽取 | `default_keywords_extraction` |
|
||||
| `graph_extraction.yaml` | 图谱实体/关系抽取 | `default_extract_entities`、`default_extract_relationships` |
|
||||
| `agent_system_prompt.yaml` | Agent(smart-reasoning)系统 Prompt | `pure_agent`、`progressive_rag_agent`、`data_analyst`、`wiki_researcher`、`wiki_fixer`、`hybrid_rag_wiki_agent` |
|
||||
| `intent_prompts.yaml` | 意图路由的分意图系统 Prompt(模板 ID = 意图值) | `greeting`、`chitchat`、`follow_up`、`image_only`、`summarize`、`web_search`、`doc_only` |
|
||||
|
||||
**可定制点**:直接编辑模板 `content`,或新增模板条目并把 config.yaml 中对应 `*_prompt_id` 改为新 ID;重启(compose 已挂载 `./config/config.yaml`,模板目录随镜像/挂载)即生效。ID 找不到时启动日志会输出 `Warning: xxx_prompt_id not found`。
|
||||
|
||||
## config/agent_type_presets.yaml:Agent 类型预设
|
||||
|
||||
为 smart-reasoning 模式的自定义 Agent 提供「一键预填」:每个预设(`AgentTypePresetEntry`,`internal/types/agent_type_preset.go`)包含 `id`、`i18n`(label/description 多语言)、`config`(预填值,零值不生效)与可选 `kb_filter`(限定可选知识库的能力谓词 `any_of` / `all_of` / `none_of`,能力名:`vector`、`keyword`、`wiki`、`graph`、`faq`)。前端经 `GET /agents/type-presets` 读取。
|
||||
|
||||
内置五种预设:
|
||||
|
||||
| id | 系统 Prompt | 工具白名单 | 备注 |
|
||||
| --- | --- | --- | --- |
|
||||
| `rag-qa` | `progressive_rag_agent` | knowledge_search、grep_chunks、list_knowledge_chunks、get_document_info | temperature 0.7、max_iterations 30、FAQ 优先 |
|
||||
| `wiki-qa` | `wiki_researcher` | wiki_search、wiki_read_page、wiki_read_source_doc、wiki_flag_issue | 需 Wiki 已启用的知识库 |
|
||||
| `hybrid-rag-wiki` | `hybrid_rag_wiki_agent` | Wiki + RAG 工具全集 | max_iterations 40,最灵活的预设 |
|
||||
| `data-analysis` | `data_analyst` | data_schema、data_analysis | temperature 0.3;`kb_filter: none_of: [faq]`;支持 csv/xlsx |
|
||||
| `custom` | 无 | 无预填 | 完全手动配置 |
|
||||
|
||||
## config/builtin_agents.yaml:内置 Agent
|
||||
|
||||
定义随系统分发、对所有租户可见的 Agent(`BuiltinAgentEntry`,`internal/types/builtin_agent_config.go`)。每条含 `id`、`avatar`、`is_builtin: true`、`i18n`(default/zh-CN/zh-TW/ja-JP/ko-KR 的名称与描述)与完整 `config`(`CustomAgentConfig`)。文件内置五个 Agent:
|
||||
|
||||
- `builtin-quick-answer`:`agent_mode: quick-answer`,引用 `system_prompt_id: default_kb` 与 `context_template_id: default_context`,带完整检索参数(`embedding_top_k: 10`、`vector_threshold: 0.5`、`rerank_threshold: 0.3`、FAQ 直答阈值 0.9 等);
|
||||
- `builtin-smart-reasoning`:`agent_mode: smart-reasoning`、`agent_type: rag-qa`、`max_iterations: 50`;
|
||||
- `builtin-data-analyst`、`builtin-wiki-researcher`、`builtin-wiki-fixer`:分别面向表格分析与 Wiki 场景。
|
||||
|
||||
`config` 中的 `system_prompt_id` 在启动时由 `resolveBuiltinAgentPromptIDs` 解析为 `agent_system_prompt.yaml` 中的实际内容。修改此文件并重启即可调整内置 Agent 行为。
|
||||
|
||||
## config/builtin_models.yaml.example:声明式内置模型
|
||||
|
||||
复制为 `config/builtin_models.yaml`(或用 `BUILTIN_MODELS_CONFIG` 指定路径)后,其中条目会在**每次启动时**写入 `models` 表并标记 `is_builtin=true`,对所有租户可见(compose 中取消 `- ./config/builtin_models.yaml:/app/config/builtin_models.yaml:ro` 挂载行的注释)。格式:
|
||||
|
||||
```yaml
|
||||
builtin_models:
|
||||
- id: builtin-llm-default # 稳定 ID,重复启动按 ID 幂等更新
|
||||
type: KnowledgeQA # KnowledgeQA | Embedding | Rerank | VLLM | ASR
|
||||
source: remote # remote(默认)| local
|
||||
is_default: true # 是否设为该类型默认模型
|
||||
name: ${LLM_MODEL_NAME} # 字符串字段均支持 ${ENV} 引用(.env 经 env_file 注入容器)
|
||||
parameters:
|
||||
base_url: ${LLM_BASE_URL}
|
||||
api_key: ${LLM_API_KEY}
|
||||
provider: ${LLM_PROVIDER} # openai | generic | aliyun | moonshot | ...
|
||||
embedding_parameters: # 仅 Embedding 类型
|
||||
dimension: 1536
|
||||
truncate_prompt_tokens: 0
|
||||
```
|
||||
|
||||
注意:未设置的 `${ENV}` 会保留字面量以便暴露配置错误;非字符串字段(`type`、`source`、`is_default`、`dimension` 等)必须写字面值;从文件删除条目**不会**自动删库,需手动清理。
|
||||
|
||||
## 配置优先级速记
|
||||
|
||||
对同一语义的配置,生效优先级为:**数据库 `system_settings`(仅注册在表内的键)> 环境变量 > config.yaml > 代码内置默认值**;租户/知识库级配置(`RetrievalConfig`、`ChunkingConfig` 等,存于数据库)在运行时覆盖全局默认。修改 `.env` 后需重启容器(`docker compose up -d app`);开发模式 air 热重载不会重读 `.env`,需重启 dev 脚本。
|
||||
Reference in New Issue
Block a user