1. QAnything 本地部署为什么值得折腾,以及它到底解决什么问题
QAnything 是网易有道开源的一套本地知识库问答系统,全称 Question and Answer based on Anything,核心能力是把你手头的 PDF、Word、PPT、Excel、Markdown、TXT、图片、CSV、网页链接等文件直接丢进去,就能基于这些内容做问答。它适合谁?适合手里有一堆内部文档、产品手册、技术资料,又不想把数据传到第三方云服务的团队和个人。它最大的特点是支持全程断网安装使用,数据不出本地,同时内置了两阶段检索(embedding 召回 + rerank 重排),数据量越大检索效果越稳,这一点比单纯用向量检索要靠谱得多。
但真正动手部署过的人会碰到一个很现实的问题:QAnything 默认要拉一堆模型服务,LLM、embedding、rerank 各占一块,如果你还想接外部大模型 API,Key 就会散落在好几个配置文件里。今天改 LLM 的 Key,明天换 embedding 的地址,配置一多就容易乱。这篇就聚焦 Docker 本地部署场景,用 TaoToken 把多模型 API Key 收敛成一条统一通道,给出可复制的 docker-compose 与 config 骨架,最后验证容器启动和问答连通性。
2. 部署前先把 TaoToken 这条统一通道准备好
QAnything 从 v1.2.0 开始支持自定义大模型,包括 OpenAI 兼容接口。这意味着只要你的 API 网关是 OpenAI 格式,就能直接接进去。TaoToken 提供的正是这样一条 OpenAI 兼容通道,把不同模型的调用统一到一个 Base URL 和一把 Key 上,QAnything 里那些分散的 LLM 配置就能合并。
你需要先拿到两样东西:API Key 和 Base URL。Key 在控制台的 API Keys 页面创建,地址是 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite ,创建后复制保存,后面填进配置文件。Base URL 统一用 https://taotoken.net/api ,注意这个地址后面不加任何路径后缀,QAnything 会自己在后面拼 /v1/chat/completions 这类端点。
如果你只是想先验证模型通不通,可以到模型对话页面 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite 直接发一条消息试试,确认 Key 有效再往下走。长期跑编码或 Agent 类任务的话,可以了解下 Coding Plan https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite ,按套餐走比单次调用更划算。接入细节和参数说明都在接入文档 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 里,遇到字段对不上时优先查这里。
注意:TaoToken 是合规的 API 聚合通道,配置时只填 Base URL 和 Key,不要在任何配置文件里写额外的网络代理参数,QAnything 本身也不需要这些。
3. 可复制的 docker-compose 与 config 骨架
先把项目拉下来。QAnything 的仓库在 GitHub,用 git-lfs 确保大文件能正常拉取:
git clone https://github.com/netease-youdao/QAnything.git cd QAnything git lfs install git lfs pull进入项目根目录后,你会看到docker-compose-linux.yaml(Linux)和docker-compose-windows.yaml(Windows WSL)两个编排文件。我们以 Linux 为例,核心是改两处:编排文件里的环境变量,以及 QAnything 自己的模型配置文件。
先看 docker-compose 里跟 LLM 相关的片段,通常长这样,你需要把 OpenAI 兼容的地址和 Key 注入进去:
services: qanything_local: image: freeren/qanything:v1.2.1 container_name: qanything_local environment: - LLM_API_BASE=https://taotoken.net/api - LLM_API_KEY=sk-你的TaoToken密钥 - LLM_MODEL_NAME=gpt-4o-mini - EMBEDDING_API_BASE=https://taotoken.net/api - EMBEDDING_API_KEY=sk-你的TaoToken密钥 - RERANK_API_BASE=https://taotoken.net/api - RERANK_API_KEY=sk-你的TaoToken密钥 volumes: - ./QAnything:/workspace/QAnything - ./models:/workspace/models ports: - "8777:8777" deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu]这里的关键点是把 LLM、embedding、rerank 三处的 Base URL 全部指向https://taotoken.net/api,Key 也统一成同一把。这样你以后换模型、换 Key,只改这一处,不用满项目找配置。
接着是 QAnything 内部的模型配置文件,一般在QAnything/configs/model_config.yaml或类似路径。找到 LLM 那段,改成 OpenAI 兼容模式:
llm: mode: openai_api openai_api: base_url: "https://taotoken.net/api" api_key: "sk-你的TaoToken密钥" model: "gpt-4o-mini" temperature: 0.3 max_tokens: 2048 embedding: mode: openai_api openai_api: base_url: "https://taotoken.net/api" api_key: "sk-你的TaoToken密钥" model: "text-embedding-3-small" rerank: mode: openai_api openai_api: base_url: "https://taotoken.net/api" api_key: "sk-你的TaoToken密钥" model: "rerank-english-v3.0"参数对照可以看这张表,方便你按需替换:
| 配置项 | 作用 | 建议值 |
|---|---|---|
| base_url | API 入口 | https://taotoken.net/api |
| api_key | 鉴权密钥 | 控制台创建的 Key |
| model | 调用的模型名 | 按套餐支持的模型填 |
| temperature | 生成随机性 | 问答场景 0.2–0.4 |
| max_tokens | 单次输出上限 | 2048 起步 |
提示:embedding 和 rerank 的模型名要跟你实际开通的模型对齐,填错会报 404 或 model not found,排查时先看日志里的请求体。
4. 启动容器并验证问答连通性
配置改完,启动脚本一行搞定。QAnything 提供了run.sh,默认在 0 号 GPU 上启动:
bash run.sh如果你想指定单卡,或者你的卡是 24GB 以上、Compute Capability 8.6 以上,可以用对应的启动参数,具体看bash ./run.sh -h的输出。启动过程会拉镜像、起 Milvus、MySQL、MinIO 这些依赖服务,第一次会比较慢,耐心等日志刷完。
启动成功后,前端地址是http://你的主机IP:8777/qanything/,API 地址是http://你的主机IP:8777/api/。先别急着传文件,做一次最小连通性验证,确认 TaoToken 通道是通的:
curl -X POST http://localhost:8777/api/local_doc_qa/new_knowledge_base \ -H "Content-Type: application/json" \ -d '{"user_id": "test_user", "kb_name": "demo_kb"}'返回里如果带上了kb_id,说明后端服务正常。接着往知识库里传一个测试文件,再发一条问答请求:
curl -X POST http://localhost:8777/api/local_doc_qa/upload_files \ -F "files=@./test.pdf" \ -F "user_id=test_user" \ -F "kb_id=你的kb_id" curl -X POST http://localhost:8777/api/local_doc_qa/local_doc_chat \ -H "Content-Type: application/json" \ -d '{"user_id": "test_user", "kb_id": "你的kb_id", "question": "这份文档讲了什么?"}'如果返回的 answer 字段有内容,且不是报错信息,说明 LLM 通道打通了。实测下来,第一次问答会稍慢,因为要等 embedding 和 rerank 走完,后面就快了。
5. 本篇常见错误排查
部署过程中最容易卡在几个地方,我按出现频率排一下。
第一个是模型下载失败。QAnything 默认会从 HuggingFace 拉模型,网络不稳就会断。解决办法是手动下载模型放到models/目录,或者改用 OpenAI API 模式,让 embedding 和 rerank 也走 TaoToken 通道,本地就不需要下大模型了。
第二个是端口冲突。8777 被占用时容器起不来,用docker ps和lsof -i:8777查一下,改 compose 里的端口映射即可。
第三个是 GPU 显存不足。最低要求是 4GB 显存(走 OpenAI API 模式),推荐 3090 级别。如果显存不够,把 LLM 切到 API 模式,本地只跑 embedding 和 rerank,能省不少显存。
第四个是 Key 或 Base URL 填错导致的 401/404。检查三点:Base URL 是不是https://taotoken.net/api且没多加/v1;Key 有没有多余空格;模型名是不是当前套餐支持的。日志在QAnything/logs/debug_logs/下,llm_server_entrypoint.log和sanic_api.log最有用。
第五个是容器间网络不通。QAnything 内部服务通过容器名互相访问,如果你改了 compose 的服务名,记得同步改配置里的地址。
关闭服务用bash close.sh,别直接docker rm,否则数据卷可能残留。
6. 后续怎么把这套配置用顺
整套跑通之后,你会发现最大的收益是配置收敛。以前 LLM、embedding、rerank 三套 Key 三套地址,现在全指向 TaoToken 一条通道,换模型只改 model 字段,换 Key 只改一处。如果你要长期跑知识库问答或者接 Agent,建议把 Key 管理放到控制台统一做,地址是 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite ,需要新 Key 时在 API Keys 页面创建 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite 。接入过程中如果碰到字段对不上、报错看不懂,优先翻接入文档 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,里面把 OpenAI 兼容格式的请求体和返回都列清楚了。想先确认某个模型能不能用,直接去模型对话页面发一条最快 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite 。