Loading... 本文记录了笔者在自己的群晖 DS923+ NAS 上以 Docker 方式部署腾讯云开源 AI 助手 Octop 的完整过程,包括镜像源选择的踩坑、一个知识库功能的 Bug 从发现、根因定位到提交修复 PR 的全过程。希望对同样想在私有环境部署 Octop,或想参与 Octop 开源共建的朋友有所参考。 ## 一、为什么选择 Octop 作为一个长期自托管各种服务的 NAS 用户,我对 AI 助手的核心诉求一直很明确:**数据不出门、多端可用、能沉淀记忆**。市面上的 SaaS AI 助手要么数据在云端,要么没有多用户能力,要么记忆聊完即忘。 腾讯云 2026 年 7 月开源的 Octop(GitHub: [https://github.com/TencentCloud/Octop](https://github.com/TencentCloud/Octop) )正好打中这些点: * **自托管**:一条 `octop run` 或一个 Docker 容器跑在自己的机器上,数据全在本地(SQLite 单文件); * **多用户隔离**:一个管理员账号,家人/团队成员各有独立工作区和记忆; * **多智能体**:内置专家体系,不同场景切换不同角色; * **IM 集成**:企业微信、飞书、钉钉、QQ、微信、Telegram 等通道都能接,AI 助手直接住进聊天工具。 更难得的是它采用 MIT 协议,基于腾讯自研的 harness-agent 运行时,单进程设计不依赖外部消息队列——对家庭和小团队的轻量部署场景非常友好。 ## 二、NAS 部署实录与踩坑 ### 2.1 基本部署:三步搞定 部署本身出乎意料地简单。在群晖上(Docker 24.0.2 + Compose v2.20.1),核心就是一个单服务 compose 文件: ``` services: octop: image: ghcr.io/tencentcloud/octop:latest container_name: octop restart: unless-stopped ports: - "8088:8088" volumes: - "./data:/data/.octop" environment: HOME: /data # 关键:官方镜像按 HOME 定位数据目录 OCTOP_BIND_HOST: 0.0.0.0 # 关键:否则容器内不监听外部可达地址 OCTOP_PORT: "8088" ``` `docker-compose up -d` 之后约 30 秒服务就绪,浏览器打开 `http://NAS的IP:8088`,凭据文件在挂载目录的 `credential.txt` 里,登录改密即可使用。 这里有两个容易踩的坑:一是 `HOME` 环境变量必须指向挂载目录,否则数据会写进容器层,重建即丢失;二是群晖的 docker 不在默认 PATH 里,SSH 操作时记得 `export PATH=/usr/local/bin:$PATH`。 ### 2.2 镜像源踩坑:ghcr.io 的拉取困境 国内环境拉 `ghcr.io` 的体验大家都懂——不到 50KB/s,几百 MB 的镜像要拉到天荒地老。我先后试了三个方案,结论如下: | 方案 | 结果 | | --------------------------------- | ---------------------------------------------------------- | | ghcr.io 直连 | 极慢,不可用 | | docker.1ms.run(Docker Hub 代理) | ❌ 不支持,它是 Hub 代理,不认 ghcr 仓库路径,manifest 404 | | **ghcr.1ms.run(ghcr 专用代理)** | ✅ 可用,速度尚可 | | ghcr.nju.edu.cn(南大镜像) | ✅ 可用,备选 | 另一个反直觉的发现:**SSH 断开不等于 docker pull 失败**。paramiko 通道超时中断后我以为拉取失败了,实际 docker 的分层下载早已在服务端完成落库。排查时先 `docker images` 看一眼,别急着重拉。 ### 2.3 部署后的两件小事 第一件事是改密码——早期版本默认 admin 账号密码是公开的,公网部署后必须第一时间修改(Web 端改密后 `credential.txt` 即失效)。 第二件事是配模型:Octop 需要 OpenAI 兼容的 API(Base URL + Key),设置里填好就能用。之后内置专家、知识库、定时任务这些能力才真正活起来。 ## 三、发现 Bug:知识库的「0 上限」陷阱 部署完开始体验各项功能,很快在知识库模块撞上一个有趣的 Bug。 ### 3.1 现象 创建知识库时,「文档数量上限」的提示写着:**"0 表示不限制,默认为 100"**。出于对"不限制"的偏好,我填了 0。 结果知识库创建成功后直接躺平:文档统计显示 `0 / 0 个文档`,页面挂着一条"此知识库已达到 **0 个文档**的上限"的提示,「上传文档」「新建文件」按钮全部禁用,拖拽上传也被拒绝。一个"不限制"的知识库,变成了一个**连一个文档都放不进去**的知识库。 ### 3.2 根因定位:一行代码引发的锁死 有意思的地方在于:**后端是对的,错的是前端**。 翻容器里的源码(Octop 是 Python FastAPI 后端 + React 前端),后端两层都正确处理了 `0 = 不限制` 的语义: ``` # api 层字段定义 max_documents: int | None = Field(ge=0, le=10000, description="0 = unlimited") # 数据库层上传校验 # Treat both None and 0 (per-base "unlimited" sentinel) as unbounded enforce_limit = max_documents is not None and max_documents > 0 ``` 但前端知识库页面(`dashboard/src/pages/KnowledgeBases/index.tsx`)的判断是: ``` const isAtDocumentLimit = fileCount >= (selected?.max_documents ?? limits.max_docs_per_kb); ``` 当 `max_documents === 0` 时,`fileCount >= 0` 恒为真——于是按钮禁用、拖拽拒绝、Alert 常驻,UI 把一个后端完全放行的操作**静默锁死**了。这也是为什么用「知识库设置」把上限改成大数就能立即恢复:后端从来没拦过,拦它的只是前端那一行判断。 ### 3.3 修复与提交 修复本身很小:引入 `kbDocLimit`,仅在上限大于 0 时才执行判断,剩余配额在 0 时按无限处理: ``` const kbDocLimit = selected?.max_documents ?? limits.max_docs_per_kb; const isAtDocumentLimit = kbDocLimit > 0 && fileCount >= kbDocLimit; ``` 我先在 NAS 容器的构建产物上打了等价补丁验证:Alert 消失、按钮恢复、上传成功且计数正常,非零上限行为不变——确认方案可行后,在源码上做了同样修改,`tsc -b` 类型检查通过,提交 PR([https://github.com/TencentCloud/Octop/pull/1112](https://github.com/TencentCloud/Octop/pull/1112) ),并在 issue([https://github.com/TencentCloud/Octop/issues/1111](https://github.com/TencentCloud/Octop/issues/1111) )中附上了完整的根因分析。 ### 3.4 一点体会 这次排查最大的收获是**验证了"前端拦截层"这类 Bug 的典型形态**:后端语义正确、API 放行,但 UI 层的一个布尔判断没有对齐文档化语义,结果功能在用户侧完全不可用。这种 Bug 用户报障时往往只能描述"传不了文件",而真正的修复点藏在 `isAtDocumentLimit` 这一行里。报告时把「后端已正确 + 前端漏判」的调用链写清楚,维护者 review 起来会快很多。 ## 四、总结 Octop 的部署体验整体是流畅的:单容器、单端口、数据单文件,对 NAS/家庭服务器用户非常友好;文档里的"0 表示不限制"翻车属于快速迭代中的小瑕疵,官方仓库 Issue/PR 响应机制健全,共建门槛不高。如果你也在找一个"数据在自己手里、能接 IM、能沉淀知识库"的自托管 AI 助手,Octop 值得一试。 * 项目地址:[https://github.com/TencentCloud/Octop](https://github.com/TencentCloud/Octop) * 官网:[https://octop.cloud](https://octop.cloud/) * 本文涉及的 Issue:[https://github.com/TencentCloud/Octop/issues/1111](https://github.com/TencentCloud/Octop/issues/1111) * 本文涉及的 PR:[https://github.com/TencentCloud/Octop/pull/1112](https://github.com/TencentCloud/Octop/pull/1112) *(完,全文约 2300 字)* 最后修改:2026 年 09 月 24 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏