乐于分享
好东西不私藏

用一台公司服务器,我给每个部门搭了专属AI助手

用一台公司服务器,我给每个部门搭了专属AI助手
职场痛点:信息找不到,知识管理混乱

公司的产品需求、售前资料、市场部文档,全在飞书上。

目录结构倒是挺清晰,但新人进来还是找不到。问了一圈,有人说"在飞书文档里",有人说"我发过群里"。找了半天,打开发现是三个月前的旧版本。

这不是某一个人的问题,是知识管理的问题。

找了好几个方案,最后用了一个叫 WeKnora 的开源项目——腾讯做的,RAG 架构的知识库平台。用公司闲置的 Ubuntu 服务器部署了一套,效果比预期好。


先说结果:

  • • 各部门有自己的知识库,飞书文档更新自动同步
  • • 每个部门有自己的 AI Agent,在飞书上直接提问
  • • 研发团队用 Claude Code 写代码时,自动获取公司技术文档作为上下文
  • • 零软件订阅费,服务器是现成的,模型 API 走按量付费,用多少花多少
WeKnora 整体架构图

服务器是公司已有的:Ubuntu 24.04.3 LTS,8 核 32G,200G 磁盘。

我用本地 Mac 的终端 SSH 上去操作:

ssh deploy@公司服务器IP

WeKnora 全部容器化部署,只需要 Docker 和 Docker Compose。部署前确认一下环境:

docker --versiondocker compose version

二、部署

拉代码

git clone https://github.com/Tencent/WeKnora.gitcd WeKnora

配环境变量

cp .env.example .env

有几个地方必须改:

# 数据库密码,别用默认值DB_USER=weknoraDB_PASSWORD=自己设# JWT密钥,生产环境必须改JWT_SECRET=自己设# 单机部署用local就行STORAGE_TYPE=local# 生产环境关闭注册DISABLE_REGISTRATION=true# 时区TZ=Asia/Shanghai

启动

docker compose up -d

核心服务只启动这几个就够了:

docker compose up -d app frontend postgres redis minio qdrant docreader

启动后等 30 秒左右数据库 migration 完成,然后访问 http://服务器IP:8080

看到登录页面就说明部署成功了。

三、模型配置——踩了一整天的坑

这是最需要认真对待的一步。

WeKnora 需要两类模型:LLM 负责对话和总结,Embedding 负责文档向量化。在管理后台的"系统设置 > 模型设置"里配,用 OpenAI 兼容格式。

LLM 选在线 API

我们用的 SiliconFlow,模型选 deepseek-chat(DeepSeek V3),中文场景够用了,性价比高。

Embedding——最大的坑

这是整个部署过程中代价最深的教训。

一开始想着本地跑省事,装了 Ollama 配了 nomic-embed-text。文档上传后 parse_status 显示 completed,一切看起来正常。

但搜索永远返回空结果。

排查了半天搜索接口、知识库配置、向量数据库,最后才发现是 Embedding 的问题。换了 SiliconFlow 的 BAAI/bge-m3 在线 API,立竿见影。

为什么不行?三个原因:

第一,Ollama 的 /v1/embeddings 接口和 OpenAI 标准不完全兼容,响应格式有差异。第二,本地模型在中文场景的精度远不如 BAAI/bge-m3。第三,批量处理几十个文档时 CPU 慢到无法接受。

结论:在 WeKnora 项目中,Embedding 用在线 API 更省心。

模型名称必须精确

又一个容易翻车的细节。在 SiliconFlow 上配 Embedding 模型,模型名必须一字不差:

  • • ❌ bge-m3 —— 报 "Model does not exist"
  • • ❌ BAAI/bge-M3 —— 同样报错
  • • ✅ BAAI/bge-m3 —— 正确

切换 Embedding 模型后,Qdrant 的 collection 需要重建,因为向量维度变了。

四、对接飞书

这是最有价值的部分。

在 WeKnora 后台 → IM 设置 → 新增飞书 Channel,选 WebSocket 模式,填入飞书应用的 App ID 和 App Secret。

WebSocket 模式的好处是不需要公网 IP 和回调地址,内网就能跑。但踩了两个坑:

第一,删除旧 Channel 后必须重启 app 容器。不然旧的 WebSocket 连接会残留,导致消息路由错乱。

第二,飞书 SDK 有自动重连机制,容器重启后会建立新连接。日志里会看到同一个 app_id 出现多次连接记录,这时候再重启一次容器清理就行。

配好之后,每个部门一个 Agent,绑定各自的知识库。部门的人在飞书上直接给 Agent 发消息提问,Agent 从知识库检索回答。

我们给产品部绑了产品文档,研发部绑了技术文档,客服部绑了 FAQ。飞书知识库更新后自动同步到 WeKnora,不需要手动维护。

飞书产品知识库BOT对话界面

五、Claude Code 集成

研发团队用 Claude Code 写代码和文档时,经常需要参考公司的技术规范、API 文档、架构决策。以前是人工把这些文档内容复制粘贴到对话里,现在通过 WeKnora 的 MCP(Model Context Protocol)服务器,Claude Code 可以直接搜索知识库。

在项目的 .mcp.json 里加上:

{  "mcpServers": {    "weknora-knowledge-base": {      "command": "python3",      "args": ["scripts/weknora_mcp_server.py"]    }  }}

Claude Code 启动时自动加载,写代码时自动调用 search_knowledge 获取背景知识。

WeKnora 自身也提供了 Web 对话界面,员工可以直接在浏览器里向知识库提问。

六、批量上传文档的注意事项

文档多了之后会遇到几个实际问题。

限流。SiliconFlow 等在线 API 有 TPM(每分钟 token 数)限制。一次上传 30 多个文档时,并发 Embedding 请求可能触发 429。表现是部分文档成功,部分卡在 processing 状态。解决方式是降低并发数,或者手动分批上传,每次 5 到 10 个。

搜索词。中英文混合搜索效果比纯英文好。比如搜 paycode 工资项 比只搜 paycode 准确得多。

文档状态排查。搜索返回空结果时,按顺序检查:文档是否启用、知识库 ID 是否正确、文档解析是否完成、Embedding 是否成功、查询词是否匹配。

七、日常运维

几个常用命令:

# 查看容器状态docker compose ps# 看后端日志docker compose logs -f app# 看飞书连接日志docker compose logs app | grep "\[IM\]"# 查 Embedding 错误docker compose logs app | grep -E "EmbedBatch|embedding|Error"

定期检查文档解析状态,发现失败的及时重新解析。MinIO 存储长期运行后 /data/files 会膨胀,记得留意磁盘空间。

总结

部署 WeKnora 本身不复杂,一行 docker compose up -d 搞定。真正花时间的是踩坑和调优。

经验浓缩成一句话:Embedding 用在线 API,模型名写全称,改配置后重启容器,文档分批上传。

好的知识库不是 AI 多聪明,而是公司里每个人踩过的坑,都不会让第二个人再踩一遍。