摘要

公开的 WeKnora 文章大致分三类:NAS/Compose 启动清单、产品功能宣传向介绍、以及偏源码的局部拆解。本文按工程落地需要,把三条线拧在一起:

  1. 它是什么、进程怎么拆(架构与数据流)
  2. 检索链路为何这样设计(分块 → 混合检索 → 事件管线 → 生成)
  3. 怎么部署、怎么选形态(Compose / Lite / Helm)、和谁比、何时用

版本锚点:v0.8.0(官网页脚与 README 徽章一致)。仓库 Tencent/WeKnora,MIT。


1. 定位:不是「又一个聊天套壳」

WeKnora(维娜拉) 是腾讯开源的企业级知识管理 / RAG 框架,背景硬在两点:

  • 官网与文档挂在 weknora.weixin.qq.com,是微信对话开放平台技术栈的开源形态(WXG 系,而非实验室 demo)。
  • 同时提供 REST API、MCP Server、CLI、IM 渠道、嵌入 Widget,面向「可私有化、可集成」,而不是只做一个网页聊天窗。

README 给的三合一能力:

形态解决什么
RAG 快速问答带引用的日常查文档
ReAct Agent 智能推理跨文档对比、多轮工具、联网、数据分析
Wiki 模式Agent 把原始资料蒸馏成互链 Markdown + 图谱,可回滚

再叠加:多源同步(飞书 / Notion / 语雀 / GitLab / IMA / RSS…)、多租户 RBAC、技能沙箱、跨会话记忆、Langfuse 追踪。
结论先说:它是「知识中台」体量,不是单文件桌面玩具;默认 Docker 形态对内存不友好,但默认不需要单独向量库。


2. 架构:三进程 + 两基础设施 + 可选插件

2.1 核心服务

浏览器
  │
  ▼
frontend  (Nginx + Vue3)     :${FRONTEND_PORT:-80}
  │  反代 /api
  ▼
app       (Go / Gin)         :8080
  │ gRPC :50051(仅 compose 网内)     │ SQL + BM25 + 向量
  ▼                                 ▼
docreader (Python 解析)       postgres (ParadeDB pg17)
  │                                 ▲
  │  共享卷传图片                    │
  └──────────────────────────── redis (Asynq + SSE 流)
服务镜像/技术职责
appGo 1.26 + GinREST、RAG 管线、Agent 引擎、异步 worker、IM/Embed
frontendVue3 + Nginx控制台;Nginx 反代 /api
docreaderPython gRPC版式/OCR/Office/网页等解析(LibreOffice、Playwright 等,吃内存)
postgresParadeDB业务数据 + BM25 + pgvector(RETRIEVE_DRIVER=postgres 默认)
redisRedis 7Asynq 队列、SSE 断线续传、设置 Pub/Sub、并发闸门

工程含义:

  • 默认部署不引入独立向量库——ParadeDB 同时承担稀疏与稠密检索,减少组件。
  • docreader 默认不映射宿主机端口,只暴露在 compose 网络。
  • 可选能力全部走 Compose profile(neo4j / minio / qdrant / milvus / searxng / langfuse / mcp / full…),避免一上来 --profile full 把机器拖垮。

2.2 部署形态选型

形态存储 / 队列适用
Docker Compose 标准ParadeDB + Redis团队/服务器,默认推荐
开发编排 docker-compose.dev.yml基础设施进容器,app/前端在宿主机热更新改 Go/前端代码
Lite 单二进制SQLite + sqlite-vec + 内存队列,无 Redis个人、低配、离线
HelmChart 内置 PG/RedisK8s ≥ 1.25
桌面(Wails)同 Lite 运行时Release 尚未附安装包
Homebrew weknora-lite同 LitemacOS/Linux 命令行

硬件(官方建议):标准 Compose 4 核 / 8GB 起步;启用 Milvus、Langfuse 等再加内存。磁盘按 Postgres 卷 + data-files 文件卷预留。

2.3 源码分层(读文档时有用)

  • cmd/server 入口;internal/ 分层(handler → application/service → repository)。
  • 检索:RetrieveEngineRepository → 组合引擎 → 注册表(RETRIEVE_DRIVER + DB 内 VectorStore 实例)。
  • 问答:事件驱动插件管线 chat_pipeline(见 §3.4),不是单函数黑盒。
  • Agent:AgentEngine 跨轮无状态,历史每轮从 DB 重建;事件经 EventBus → StreamManager → SSE。

3. 特性深挖(比「功能列表」多一层)

3.1 文档入库:异步管线

上传/URL/Markdown 一律走异步:

parse(docreader) → chunk(Go chunker) → embedding/BM25 索引
                 → 可选:问题生成 / 图谱抽取 / Wiki 富化
状态:pending → processing → finalizing → completed

要点:

  • 解析在 Python docreader(生态:LibreOffice、OCR、Playwright…);
  • 分块与索引在 Go,与业务同事务边界更清晰;
  • 大文件受 MAX_FILE_SIZE_MB(默认 50)、处理超时(默认 2h)约束;
  • 批量 reparse、按上传 process_config 覆盖解析/分块/多模态开关。

3.2 分块:自适应三级 + 父子

默认起点:chunk_size=512、overlap=80(约 15%)、strategy=auto。

auto 不是玄学,是「画像 → 尝试链 → 校验回退」:

Tier策略适用
1标题感知(Markdown/书签层级 + 面包屑 ContextHeader)技术文档、导出规范的结构稿
2启发式边界(换页、编号章节、全大写行、分隔线…)OCR PDF、纯文本手册
3递归 legacy(\n\n → \n → 。 + 受保护区间)一切兜底

受保护、绝不从中间切开:代码围栏、公式 $$、表格结构、图片/链接引用等;大表还有表头前置,避免后半表丢列名。

父子分块(推荐长文档):

parent ≈ 4096 字符(只入库,通常不进向量)
child  ≈ 384 字符(真正被 embedding / 检索)
检索命中 child → 回答时展开 parent 上下文

调参直觉(官网表):

现象动作
答案碎、缺上下文调大 chunk_size 或开父子
命中的块跑题调小 chunk_size,主题更集中
FAQ / 参数表overlap=0,防相邻条目串味
长叙事overlap 150–200,可叠父子

预览:POST /api/v1/chunker/preview(不写库、不 embedding)。改配置后必须 reparse 才作用于存量文档。

3.3 检索:多引擎 + 统一 RRF

引擎矩阵(RETRIEVE_DRIVER 可逗号多驱动):

引擎向量关键词典型场景
postgres(默认)pgvector halfvec + HNSWParadeDB BM25默认;业务同库
sqlitesqlite-vecFTS5 bigramLite / 桌面
ES v8 / OpenSearch有BM25已有搜索栈
ES v7仅关键词BM25存量,需再配向量引擎
Qdrant / Milvus / Weaviate原生各异独立扩容向量
Doris / 腾讯云 VectorDB有有数仓或云托管

无论底层是否「原生混合」,上层混合始终是加权 RRF:

score = w_v / (k + rank_v) + w_k / (k + rank_k)

向量与关键词各自检索 → 按 rank 融合,对分数量纲免疫;跨引擎时向量分归一化到 [0,1],BM25 分不硬压。

一次典型检索还会叠加:

  1. 查询改写 + 意图(kb_search / 闲聊 / 网页…)
  2. 查询扩展(召回不足时本地变体,中文走 jieba)
  3. 可选图谱实体并行(Neo4j GraphRAG)
  4. Rerank + 复合分 0.6·模型 + 0.3·检索 + 0.1·来源
  5. MMR 去冗(λ≈0.7)
  6. 父子展开、FAQ 填充、邻居短块扩展、历史引用注入
  7. FILTER_TOP_K 稳定排序截断
  8. 组装上下文 → 流式生成 + 引用别名(cN/dN 不进模型明文)

这条链解释了:为什么首次「没引用」要先查 parse 是否 completed、embedding 是否换过、阈值是否过高——问题常在入库或检索配置,不在「模型不会说话」。

3.4 RAG 管线:事件插件,而不是一坨 if

问答是 事件驱动插件责任链,例如 RAG 流可动态拼成:

LOAD_HISTORY? → QUERY_UNDERSTAND → CHUNK_SEARCH_PARALLEL
→ CHUNK_RERANK → WEB_FETCH? → CHUNK_MERGE → FILTER_TOP_K
→ DATA_ANALYSIS? → INTO_CHAT_MESSAGE → CHAT_COMPLETION_STREAM
  • 结果不直接写 HTTP,而是 EventBus → StreamManager(memory/redis)→ SSE 100ms 拉取。
  • 因此:刷新页面可 continue-stream 重放;多副本可共享 Redis 流;stop 与生成解耦。
  • 引用在流关闭前以 references 事件先推,前端角标与「召回面板」不依赖最后一帧。

对集成方:自建面板时优先消费标准 SSE response_type(answer / thinking / references / complete…),不要假设一次性 JSON。

3.5 Agent:两种模式 + 工具面

模式行为
quick-answer经典 RAG:检索→拼上下文→一次生成(不进 ReAct)
smart-reasoningReAct:Think/Act/Observe,多轮工具

内置 Agent 示例:快速问答、智能推理(高 max_iterations)、数据分析(DuckDB SQL)、Wiki 问答/修订。

工具面(节选):knowledge_search、grep_chunks、图谱查询、web_search/web_fetch、data_analysis、沙箱 shell_exec/文件工具、search_memory、Wiki 读写、动态 MCP。

安全相关(与部署直接相关):

  • MCP 危险工具可 HITL 审批(默认可等 10 分钟量级)+ 会话内 OAuth;
  • 技能在 Docker / E2B / Cube 沙箱执行;local 宿主机后端已移除;
  • Docker 沙箱默认关:开启 ≈ 挂 docker.sock ≈ 宿主机 root 级,务必威胁建模后再开;
  • 工具注册 first-wins,防 MCP 同名劫持内置工具。

3.6 Wiki、记忆、评估(常被一笔带过的三块)

Wiki 模式:入库侧 Agent 蒸馏互链 Markdown + Neo4j 图谱;页面有版本、行级 diff、回滚;检索侧 Wiki chunk 可加权(×1.3 量级)。这是相对 Dify/RAGFlow 更「产品完整」的差异点。

跨会话记忆:profile / preference / fact / task / interest;默认关,按空间与调用者隔离;Agent 可关 memory_enabled。

评估(Evaluation)——和「只靠手感调 RAG」对立:

  • 数据集:Parquet(queries / corpus / answers / qrels / qas);
  • 指标:检索 Precision / Recall / NDCG@3 / NDCG@10 / MRR / MAP;生成 BLEU-1/2/4、ROUGE-1/2/L;
  • API:POST /api/v1/evaluation 创建(Admin),GET ...?task_id= 轮询;结果在内存,重启丢;
  • 做法:固定数据集,一次只改一个变量(分块、阈值、模型、rerank)。

3.7 平台能力速览

能力要点
多租户空间 RBAC:Owner/Admin/Contributor/Viewer;按 KB 归属;审计默认可保留 90 天
认证JWT / X-API-Key(能力级 + KB 白名单)/ OIDC;注册可 invite_only
模型LLM/Embedding/Rerank/VLM/ASR 分类;Ollama 或任意 OpenAI 兼容;LiteLLM(0.8)
可观测Langfuse 为唯一追踪后端;解析时间线;任务队列面板
客户端Web、CLI(agent-first JSON)、Go SDK、Chrome 插件、小程序、DSH 插件

4. Docker 部署(标准路径)

4.1 启动

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(32 字节)
docker compose pull
docker compose up -d
# 等价封装(.env 兜底、Ollama 检查、沙箱镜像预拉取):
# make start-all
docker compose ps
curl http://localhost:8080/health   # {"status":"ok"}

SYSTEM_AES_KEY 必须 32 字节:租户 API Key、模型密钥、数据源凭据等落盘 AES 加密;丢了密钥 = 密文不可恢复。禁止把 .env 提交进 Git。

4.2 端口与冲突

用途变量/端口默认
Web UIFRONTEND_PORT80(占用则改此变量)
后端 APIAPP_PORT8080
Langfuse(profile)—3000
docreader不映射宿主—

若机器 80 已被其它反代占用:只改 FRONTEND_PORT=8081 等,再 docker compose up -d;不要为了腾 80 去动本机 Docker 里无关的其它 nginx(例如若你另有业务栈在 80/443,明确避开)。

4.3 可选 profile

docker compose --profile neo4j up -d     # GraphRAG
docker compose --profile minio up -d     # STORAGe_TYPE=minio
docker compose --profile langfuse up -d  # 链路追踪
docker compose --profile full pull && docker compose --profile full up -d

searxng 默认只绑 127.0.0.1;对外开放必须设 SEARXNG_SECRET 并加固。自建时把 127.0.0.1 加入 SSRF_WHITELIST,否则后端出站白名单会拦。

4.4 升级 / 停止

# .env 中 WEKNORA_VERSION=目标版 或 latest
docker compose pull && docker compose up -d   # 必须先 pull,否则吃旧镜像

docker compose down        # 保留卷
# docker compose down -v   # 删数据,慎用

4.5 Lite 单二进制

cp .env.lite.example .env.lite   # SYSTEM_AES_KEY / JWT_SECRET
make run-lite
# 或 make package-lite

Lite:DB_DRIVER=sqlite + FTS5/sqlite-vec,队列 memory,前端内嵌;仍可连本地 docreader。适合先验证产品形态再决定是否上完整 Compose。

4.6 首次问答最短闭环

  1. 打开 http://localhost → 注册(无默认账号;密码 8–32 且含字母数字)。
  2. 建知识库 → 向导配 LLM + Embedding(至少各一;可选 Rerank/VLM/ASR)。
  3. 容器内连宿主机 Ollama:http://host.docker.internal:11434(Linux 依赖 host-gateway)。
  4. 上传文档,等 completed。
  5. 对话页选库提问,点引用展开原文。
  6. 向导务必点「测试」;换 Embedding 模型必须重建索引。

API 路径与向导一一对应:注册/登录 → POST /knowledge-bases → POST /initialization/initialize/:kbId → 上传 → POST /knowledge-chat/:session_id(SSE)或 knowledge-search(只要检索)。服务端集成优先 API Key(X-API-Key),不要把 JWT 当长期凭据。


5. 和 Dify / RAGFlow / FastGPT 怎么比

没有统一官方 benchmark,下表是能力定位(非跑分):

维度WeKnoraDifyRAGFlowFastGPT
主后端GoPythonPythonNode/TS
文档解析深度docreader + OCR + 父子 + 自适应中深(DeepDoc)中
工作流编排ReAct + 插件管线(偏 Agent)强(可视化 workflow)中中
Wiki 自维护有(版本/图谱)无无无
IM 渠道企微/飞书/钉钉等 10+部分部分部分
默认向量依赖ParadeDB 同库,可零外置多种多种多种
多租户 RBAC四级 + 审计有部分有
评估内置检索/生成指标 API有(产品化)有有

选型一句话:

  • 要 可视化工作流编排、应用市场式搭建 → 优先 Dify。
  • 要 解析/表格/扫描件极限质量 → RAGFlow 一类更「摄入痴迷」。
  • 要 私有化 + IM + Wiki 沉淀 + 接近企业知识中台 → WeKnora 差异化最明显。
  • 要 极轻个人库 → Lite,或继续用「笔记 + 薄 RAG 工具」(见本站 rag-as-agent-tool 思路)。
  • 已深度绑定 Dify 工作流 → 迁移成本在编排模型,不在再装一个容器。

6. 接进 DeepSeek Harness(只读知识面)

官方插件 @wxg-prc-cpg/dsh-weknora(文档写明验证 dsh 0.1.0-rc.8 + WeKnora 0.8.0):

dsh plugin --profile web add @wxg-prc-cpg/dsh-weknora

export WEKNORA_BASE_URL=https://weknora.example.com
export WEKNORA_API_KEY='<api-key>'     # retrieve;ask 另需 chat
export WEKNORA_KNOWLEDGE_BASE_IDS=kb-123,kb-456
export WEKNORA_RESOURCE_URLS=public
dsh web

四个只读工具:

工具用途
weknora_search混合检索片段(带 knowledge_id)
weknora_read_document按文档拼回正文、翻页
weknora_ask服务端 RAG/Agent 成稿 + 引用
weknora_list_knowledge_bases列库,便于 Agent 自缩范围

与本站 DeepSeek Harness 插件化笔记一致:Harness 不负责检索,知识落在外部,用插件只读挂载——编码 Agent 与知识库权限面分离。


7. 安全与运维清单(生产必读)

  1. 网络:官方明确建议内网/反代后部署,避免裸公网;定期升级。
  2. 密钥:JWT_SECRET、SYSTEM_AES_KEY、DB/Redis 口令只进环境注入;轮换 AES 主密钥前评估密文兼容。
  3. 沙箱:Docker 沙箱默认关;开 WEKNORA_SANDBOX_DOCKER_ENABLED=true + docker.sock 等于交出宿主机控制权;Cube/E2B 用网络策略(默认可改「默认拒绝出站 + allow_out」)。
  4. 注册与权限:DISABLE_REGISTRATION=true 或系统设置 invite_only;首个系统管理员用 WEKNORA_BOOTSTRAP_SYSTEM_ADMIN_EMAIL(邮箱需先注册)。
  5. 文件上传:MAX_FILE_SIZE_MB、技能包 MAX_SKILL_BUNDLE_SIZE_MB(默认至 256 MiB)与 Nginx client_max_body_size 对齐。
  6. 审计与日志:空间审计默认可保留 90 天;Langfuse 侧注意勿把密钥打进 trace 属性。
  7. 评估结果内存态:不要把内存中的 evaluation 当历史存档;重要结论应外部落盘。

8. 排错表

现象检查顺序
compose 解析失败缺 .envcp .env.example .env(app 使用 env_file)
上传卡 processingdocker logs WeKnora-docreader;文件大小/超时;磁盘
Ollama 探测失败OLLAMA_BASE_URL=host.docker.internal:11434;Linux host-gateway
无引用 / 召回空completed?→ embedding 与建库一致?→ 降 vector_threshold → 查 rerank
注册页消失GET /auth/config 的 registration_mode(可能已是 invite_only)
API Key 403capabilities 是否含 retrieve/chat/评估;KB 白名单
UI 版本与 release 不符只 up -d 没 pull
80 被占用改 FRONTEND_PORT,勿抢机器上其它业务的 80/443
分块改了没效果未 reparse;或预览与入库父子策略不一致(新版本已对齐)
评估指标恒 0结果 ID 是否对上 dataset pid;corpus 是否同步索引完成

9. 实验路径建议(按投入排序)

阶段做什么退出条件
T0 半天Lite 或最小 Compose + 远程 API 模型,传 3~5 份文档引用可点开
T1 一天调 chunk/父子、开 rerank,固定 20 个真实问题手感对比稳定命中意图
T2起 Parquet 评估,锁数据集改单变量有 Precision/NDCG 数字
T3需要时:neo4j / langfuse profile;DSH 只读接入编码 Agent编码流可检索且不写库
T4IM 或 Embed Widget;关公开注册;备份卷与 AES 密钥管理可对外小流量

不必一步 full:默认核心跑通 → 按缺口开 profile,比一次拉齐所有服务更省运维。


10. 结论

WeKnora v0.8.0 的专业价值不在「又接了几个 LLM 厂商」,而在把企业知识库的脏活做成了可替换组件:

  • 摄入:独立 docreader + 自适应/父子分块 + 异步队列;
  • 检索:多引擎 + 统一 RRF + rerank/MMR/引用别名;
  • 交互:事件化 RAG 管线 + 可断点 SSE;
  • 演进:Wiki / 记忆 / 评估 / 沙箱 / 多租户,而不是停在 demo 问答。

部署主线始终是三步:Compose 起服务 → 配 LLM+Embedding → 文档到 completed 再提问。
是否值得长期占用一台 8GB 机器,取决于你要的是「能问答」,还是「能沉淀、能评估、能接进现有 IM 与编码工作流」——后者才是它相对轻量脚手架的分水岭。


参考

官方

  • 仓库:github.com/Tencent/WeKnora · CHANGELOG / LICENSE (MIT)
  • 站点与文档:weknora.weixin.qq.com
  • 文档专题:安装部署、快速上手、总体架构、分块机制、检索引擎、RAG Pipeline、评估能力、技能与沙箱、DeepSeek Harness 插件

社区写法(本文对照过的类型)

  • 部署向:腾讯云开发者社区《轻松部署全攻略》等 NAS/Compose 清单文
  • 功能向:CSDN/知乎「保姆级」介绍(偏场景与截图)
  • 拆解向:掘金《开源知识库项目 WeKnora 技术拆解》(异步向量化、Asynq、多租户)
  • 对比向:博客园等对 Dify/RAGFlow/FastGPT 的能力矩阵讨论

版本说明:行文以 v0.8.0 文档与 README 为准;升级前以仓库 CHANGELOG.md 为准。本文不构成安全审计;公网暴露前请按 §7 自行加固。