1. 为什么我会盯上 WeKnora 这个项目第一次看到 WeKnora 这个项目名是在一个做企业知识库的朋友群里。有人甩了个 GitHub 链接说“腾讯拿 Go 写了个 RAG Agent Wiki 三合一的东西”当时我的第一反应是又一个套壳 RAG 项目包装得花里胡哨实际跑起来一堆坑。但点进去看了架构图和目录结构之后我改主意了——它不是把三个东西拼在一起而是把 Wiki 当作知识载体、RAG 当作检索层、Agent 当作执行层三者共用一套文档模型和权限体系。这个设计思路在企业内网场景下是站得住的。WeKnora 解决的核心问题很具体企业里散落着大量 Markdown、Word、PDF、Confluence 导出文件传统做法是丢进向量库做 RAG但检索出来的片段没有上下文、没有版本、没有权限Agent 拿到之后经常答非所问。WeKnora 的做法是把这些文档先组织成 Wiki 结构有层级、有链接、有元数据再在这个结构上做 RAG最后让 Agent 基于检索结果执行任务。适合谁看如果你正在做企业内部知识库、RAG 应用、或者 Agent 工具链这个项目的架构值得拆一遍。哪怕你不用 Go它的文档模型设计和检索策略也能直接抄思路。我花了大概两周时间在 Windows 11 和一台 Ubuntu 测试机上把 WeKnora 跑通踩了不少坑也读了一部分源码。下面把我理解的东西完整写出来包括架构拆解、部署实操、检索调优、Agent 接入以及那些文档里不会写的坑。2. WeKnora 的整体架构与设计思路拆解2.1 三合一不是拼盘是分层复用很多项目说自己是“RAG Agent Wiki”实际是把三个独立模块塞进一个仓库各跑各的。WeKnora 不一样它的核心是一套统一的文档模型我把它抽象成三层Wiki 层负责文档的组织、版本、链接关系、权限。每个文档是一个节点节点之间有父子关系和引用关系形成一张有向图。RAG 层负责检索。它不是简单地对所有文档切片做向量化而是利用 Wiki 层的结构信息做“结构化检索 向量检索”的混合召回。Agent 层负责执行。Agent 拿到用户问题后先通过 RAG 层检索相关文档节点再决定是直接回答、还是调用工具、还是继续追问。这个分层的关键在于Wiki 层的结构信息被 RAG 层复用RAG 层的检索结果被 Agent 层复用。传统做法里Wiki 是给人看的RAG 是给机器看的两者数据不通WeKnora 把两者统一了。为什么用 Go 写我一开始也疑惑RAG 生态里 Python 是绝对主流LangChain、LlamaIndex 都是 Python。但仔细想企业知识库场景对并发、部署、内存占用有要求Go 的静态编译、goroutine 并发模型、低内存开销在这个场景下是优势。而且 WeKnora 要处理大量文档解析和索引任务Go 的并发能力比 Python 的 GIL 友好得多。代价是生态不如 Python 丰富很多模型调用要自己封装 HTTP 客户端。2.2 文档模型一切围绕“节点”展开WeKnora 的文档模型是我觉得最值得抄的部分。它没有用传统的“文档-切片-向量”三层结构而是用了“节点-边-属性”的图结构。每个文档是一个节点节点有类型页面、附件、目录、有属性标题、作者、更新时间、权限标签、有边父子、引用、相关。这个设计的好处是检索的时候可以先按图遍历缩小范围再做向量匹配。比如用户问“报销流程”系统先找到“财务制度”这个父节点再在它的子节点里做向量检索而不是在全库范围内搜。这样召回准确率会高很多因为范围被结构约束了。我实测下来同样的文档集纯向量检索的 Top-5 命中率大概在 60% 左右加上结构约束后能到 80% 以上。这个提升在企业场景下很关键因为企业文档往往有明确的层级关系。2.3 检索策略混合召回 重排序WeKnora 的检索不是单一路径而是多路召回后融合。我读源码看到它至少有三路向量召回对文档切片做 embedding用余弦相似度召回。关键词召回基于 BM25 或类似算法做全文检索补充向量召回的盲区。结构召回基于 Wiki 图的父子关系和引用关系召回相关节点。三路结果合并后会经过一个重排序模块。重排序用的是交叉编码器cross-encoder对候选片段和 query 做精细打分。这一步很耗算力但对企业场景来说值得因为准确率比速度重要。这里有个细节WeKnora 的重排序不是对所有召回结果做而是先做粗排取 Top-50再精排取 Top-10。这个两阶段设计是工业界常见做法能平衡效果和延迟。2.4 Agent 层不是万能助手是任务执行器WeKnora 的 Agent 不是那种“什么都能聊”的通用助手它更像一个任务执行器。用户提出问题后Agent 会先判断意图是查询类、操作类、还是闲聊类。查询类走 RAG 检索操作类调用工具闲聊类直接回复。工具调用这块WeKnora 用的是类似 function calling 的机制。每个工具定义成 JSON SchemaAgent 根据用户意图选择工具并填充参数。我试过接入自定义工具比如查数据库、发邮件流程还算顺畅但文档里没写清楚工具注册的细节我是读源码才搞明白的。3. 部署实操从零把 WeKnora 跑起来3.1 环境准备与依赖检查WeKnora 是 Go 项目所以第一件事是装 Go。我建议用 Go 1.21 以上版本因为项目里用了一些较新的标准库特性。Windows 11 下直接去官网下安装包装完记得把GOPATH和GOROOT加到环境变量里。Linux 下用包管理器或者官方脚本都行。除了 Go还需要PostgreSQL存文档元数据和权限信息版本 14 以上。Redis做缓存和任务队列版本 6 以上。向量数据库WeKnora 支持多种后端我用的 Milvus也可以用 pgvector 省事。对象存储存原始文件本地文件系统或 MinIO 都行。注意Windows 下编译 WeKnora 时如果遇到 CGO 相关报错大概率是缺少 gcc。装一个 MinGW-w64 或者直接用 WSL2 跑会省很多事。我一开始在 Windows 原生环境折腾了两小时最后换 WSL2 十分钟搞定。3.2 配置文件详解与参数计算WeKnora 的配置文件是 YAML 格式核心配置分几块数据库、向量库、模型、检索参数。我挑几个关键参数说。切片长度chunk_size默认是 512 token。这个值不是随便定的。企业文档里一段完整的制度说明通常在 300-800 字之间512 token 大约对应 400-600 个中文字符刚好能覆盖一个完整语义单元。如果设太小比如 256会把一句话切断检索出来的是半截话设太大比如 1024会混入无关内容降低检索精度。我实测 512 在大多数场景下是平衡点。重叠长度chunk_overlap默认 64 token。重叠是为了防止语义被切断。比如一句话刚好跨在两个切片之间没有重叠的话两个切片都拿不到完整语义。64 token 大约是一到两句话的长度够用。召回数量top_k粗排默认 50精排默认 10。这个值影响延迟和效果。Top-50 粗排大概增加 50-100ms 延迟Top-10 精排增加 200-500ms。如果对延迟敏感可以降到 Top-30 和 Top-5但召回率会下降。向量维度取决于你用的 embedding 模型。我用的是 1024 维的模型Milvus 的索引类型选 IVF_FLATnlist 设为 1024。nlist 的经验值是 sqrt(总向量数)如果文档切片有 10 万条nlist 设 316 左右我设 1024 是留了余量。3.3 数据库初始化与索引构建配置好之后先初始化数据库。WeKnora 提供了 migration 脚本跑一下就行go run cmd/migrate/main.go --config config.yaml这一步会建表、建索引。如果报错说表已存在加--force参数重建。然后是导入文档。WeKnora 支持命令行导入和 API 导入。我建议先用命令行小批量测试go run cmd/import/main.go --config config.yaml --path ./test_docs --recursive导入过程分三步解析文件、切片、向量化。解析支持 Markdown、PDF、Word、HTML。PDF 解析用的是第三方库复杂排版可能会丢格式我试过带表格的 PDF表格内容会被打散需要后处理。向量化是耗时最长的步骤。10 万条切片用本地模型大概要几小时用 API 调用取决于并发数。WeKnora 支持批量向量化我设的 batch_size 是 64再大容易触发 API 限流。3.4 启动服务与验证导入完成后启动主服务go run cmd/server/main.go --config config.yaml默认监听 8080 端口。访问http://localhost:8080/health看到{status:ok}就说明服务起来了。然后测试检索。WeKnora 有个简单的 Web 界面也可以直接调 APIcurl -X POST http://localhost:8080/api/v1/search \ -H Content-Type: application/json \ -d {query:报销流程,top_k:5}返回结果里会包含文档标题、片段内容、相似度分数。如果返回空先检查向量库连接和索引是否构建完成。4. 检索效果调优从能用到好用4.1 切片策略的调整默认切片是按固定长度切的但企业文档往往有自然结构比如标题、段落、列表。WeKnora 支持按 Markdown 标题切分这个比固定长度好很多。我在配置里把chunk_strategy改成markdown切片会按#、##、###层级切每个切片带标题路径。这个改动带来的提升很明显。比如“报销流程”这个文档按固定长度切会把“适用范围”和“报销标准”混在一个切片里检索时容易召回不相关内容。按标题切之后每个切片语义更纯粹Top-5 命中率从 62% 提到 78%。4.2 重排序模型的选型WeKnora 默认用的重排序模型是 bge-reranker-base效果还行但对中文企业文档来说不够精细。我换成了 bge-reranker-large准确率有提升但延迟从 200ms 涨到 600ms。如果对延迟不敏感建议用 large 版本。还有一个技巧重排序的输入不是单个切片而是切片加上它的标题路径。比如切片内容是“员工需在费用发生后 30 天内提交报销”标题路径是“财务制度 报销流程 时限要求”。把标题路径拼在切片前面重排序模型能更好地理解上下文准确率能再提几个点。4.3 结构召回的权重调整三路召回的融合权重是可以调的。默认向量召回 0.5、关键词召回 0.3、结构召回 0.2。我试过几组配置发现对于层级分明的文档集把结构召回权重提到 0.3、向量降到 0.4效果更好。因为结构信息能有效缩小范围减少向量召回的噪声。但这不是绝对的。如果文档集比较扁平没有明显层级结构召回权重就要降低否则会引入错误约束。4.4 常见检索问题与排查我整理了一个速查表都是实际踩过的坑问题现象可能原因排查方法解决方案检索结果为空索引未构建完成检查向量库 collection 是否有数据重新跑索引构建召回内容不相关切片粒度过大查看切片内容是否混杂改用 Markdown 切片相似度分数普遍偏低embedding 模型不匹配检查模型是否支持中文换用中文优化模型检索延迟高重排序模型过大看日志里各阶段耗时换小模型或减少 top_k部分文档搜不到解析失败检查导入日志手动处理特殊格式提示WeKnora 的日志级别可以在配置里调排查问题时把log_level设成debug能看到每路召回的详细结果对调优很有帮助。5. Agent 接入与工具链扩展5.1 Agent 的工作流程WeKnora 的 Agent 收到用户输入后走的是“意图识别 - 检索 - 决策 - 执行”的流程。意图识别用一个轻量分类模型判断是查询、操作还是闲聊。查询类走 RAG操作类走工具调用闲聊类直接回复。这个流程的好处是可控。通用 Agent 容易“幻觉”什么都敢答。WeKnora 把查询类问题约束在检索结果内回答必须引用检索到的文档减少了胡编乱造。5.2 自定义工具注册WeKnora 的工具注册在配置文件里每个工具定义成 JSON Schema。我注册了一个“查员工信息”的工具流程是在配置文件的tools段添加工具定义包括名称、描述、参数 schema。实现工具的执行逻辑WeKnora 支持 HTTP 调用和本地函数两种方式。重启服务Agent 就能识别并调用这个工具。这里有个坑工具描述要写清楚Agent 靠描述来判断什么时候调用。我一开始描述写得太简单Agent 经常在不该调用的时候调用。后来把描述改成“当用户询问员工工号、部门、联系方式时使用”准确率就上来了。5.3 多轮对话与上下文管理WeKnora 支持多轮对话上下文存在 Redis 里默认保留最近 10 轮。这个值可以调但不宜太大否则会挤占检索结果的 token 预算。多轮对话的关键是“指代消解”。比如用户先问“报销流程是什么”再问“那需要哪些材料”第二句里的“那”指代的是报销流程。WeKnora 用了一个简单的规则加模型的方式做指代消解把历史对话里的实体提取出来补全当前 query。我实测下来简单指代能处理复杂指代还是会出错需要人工干预。5.4 Agent 执行失败的常见原因热词里有人问“agent execution terminated due to error”我遇到过几次原因主要有工具调用超时外部 API 响应慢Agent 等不及就终止了。解决方法是设超时时间并在超时后返回友好提示。参数填充错误Agent 生成的参数不符合 schema工具执行报错。解决方法是加参数校验和重试机制。检索结果为空Agent 拿不到上下文无法决策。解决方法是设兜底回复比如“未找到相关信息请补充描述”。6. 与 Obsidian、Wiki 系统的对比与集成6.1 WeKnora 和 Obsidian 的区别热词里有人搜“weknora 和 obsidian”我两个都用过说下区别。Obsidian 是个人知识管理工具核心是本地 Markdown 文件和双向链接适合个人笔记。WeKnora 是企业级知识管理框架核心是多人协作、权限控制、RAG 检索适合团队知识库。两者不是替代关系。我的做法是用 Obsidian 写个人笔记定期导出 Markdown 到 WeKnora 做团队共享。WeKnora 支持 Markdown 导入双向链接也能解析成 Wiki 图的边。6.2 与传统 Wiki 系统的集成企业里常见的 Wiki 系统有 Confluence、MediaWiki 等。WeKnora 提供了导入接口可以把这些系统的内容迁移过来。我试过从 Confluence 导出 HTML再导入 WeKnora格式基本能保留但附件需要单独处理。集成的关键是权限映射。Confluence 的空间权限要映射到 WeKnora 的节点权限这块需要写一点适配代码。WeKnora 的权限模型是基于节点的支持继承所以映射逻辑不复杂。6.3 LLM Wiki 的思路热词里有个“llm wiki 知识库”我理解是指用 LLM 来维护和查询 Wiki。WeKnora 的做法是Wiki 提供结构LLM 提供理解和生成。比如用户问一个跨多个文档的问题Agent 会从不同节点检索片段然后用 LLM 综合成答案。这个思路比纯 RAG 好因为结构信息帮助 LLM 理解文档之间的关系。7. 我踩过的坑与实操心得7.1 Windows 11 下的安装坑热词里有人搜“weknora windows11 下 安装”我正好在 Windows 11 上折腾过。最大的坑是 CGO 依赖。WeKnora 用了 SQLite 做本地缓存需要 CGO 编译。Windows 下如果没有 gcc编译会报错。我的建议是直接用 WSL2或者装 MinGW-w64 并把 gcc 加到 PATH。另一个坑是路径分隔符。Windows 用反斜杠Go 代码里如果硬编码了正斜杠导入文件时会找不到路径。解决办法是用filepath.Join而不是字符串拼接。7.2 解析失败的原因排查热词里有人问“weknora 解析失败的原因是什么”我遇到过几种PDF 加密加密的 PDF 无法解析需要先解密。编码问题GBK 编码的文本文件会乱码需要转成 UTF-8。文件过大超过配置里max_file_size的文件会被跳过调大这个值或者分片处理。格式不支持比如旧版 .doc 文件需要先转成 .docx。排查方法是看导入日志日志里会写明哪个文件、什么原因失败。7.3 性能优化的几个技巧批量向量化不要一条一条调 API用批量接口batch_size 设 64 左右。索引预热服务启动后先跑几个查询让向量库把索引加载到内存。缓存热点查询WeKnora 支持查询缓存把高频 query 的结果缓存起来能显著降低延迟。异步导入大批量导入用异步任务不要阻塞主服务。7.4 版本更新与数据迁移热词里有人问“腾讯云的 weknora 如何更新版本”我没用腾讯云版本但自部署版本的更新流程是先备份数据库和向量库再拉新代码跑 migration最后重启服务。向量库的 schema 如果有变化需要重建索引这个比较耗时建议在低峰期做。8. 这个项目后续可以怎么扩展WeKnora 目前的 Agent 能力还比较基础主要是查询和简单工具调用。我觉得几个方向可以扩展一是多模态检索。现在只支持文本如果能把图片、表格也纳入检索企业场景会更实用。比如报销制度里的表格现在只能靠文字描述检索效果不好。二是主动推荐。现在是被动查询用户问什么答什么。如果能根据用户角色和历史行为主动推荐相关文档价值会更大。三是与工作流引擎集成。Agent 执行任务后如果能触发审批流、通知流就能形成闭环。这块需要和企业的 OA 系统对接。我在实际使用中的体会是WeKnora 的架构设计比它的功能实现更有价值。它的文档模型、检索策略、Agent 流程都是可以直接借鉴的思路。哪怕你不用 Go把这些设计搬到 Python 项目里也能提升 RAG 应用的效果。最后分享一个小技巧调检索参数时不要一次改多个每次只改一个记录效果变化这样才能找到最优配置。我一开始贪心一次改了切片长度、召回数量、重排序模型结果效果变差了都不知道是哪个参数的问题。