拓冰建站拓冰建站
首页 / 资讯中心 / 正文

企业私有知识库部署:Dify + 通义千问 Qwen3.6-27B + BGE-M3 全栈实战

把大模型接进公司业务最让人踏实的方式不是去调各家公有云 API而是在自己机器上把整套链路跑通文档进知识库、模型本地推理、Agent 能检索能调用工具而且数据不出内网。本文是一份端到端实战记录目标就一件事从零把「Dify 编排平台 → vLLM 起通义千问 Qwen3.6-27B → Xinference 跑 BGE-M3 向量模型 → 知识库 Agent 真正可用」整条链路正确配置跑通。所有命令、配置、关键补丁都贴在这里照做即可落地。说明文中出现的服务器地址、账号、密码、API Key、Token 均用占位符如Dify服务器IP、你的API Key表示请替换成你自己的环境值。涉及具体业务进程名也做了泛化处理。一、整体架构四块各司其职先看清这套组合在干什么后面每一步才知道在对哪块动手Dify低代码 AI 应用编排平台提供控制台、知识库、Agent、API。所有交互都从它进。vLLM高性能推理引擎在本机以 OpenAI 兼容接口对外提供Qwen3.6-27B的文本生成与工具调用能力。Xinference模型调度器负责把BGE-M3这种 Embedding 模型真正跑起来供 Dify 做知识库向量化。向量库 / 数据库Dify 默认用 Weaviate 存向量PostgreSQL 存业务数据。一句话链路文档 → BGE-M3 向量化 → 存入向量库 → 用户提问 → Qwen 经 vLLM 推理 → 结合检索到的知识 → 通过 Agent 返回答案。二、环境准备项本文取值请替换为你的环境说明Dify 服务器Dify服务器IProot 权限装 Docker docker compose v2编排目录DIFY_DIR/dockerGPU 主机GPU服务器IP本文用 H20 ~96GB与既有业务进程共享显存大模型Qwen3.6-27B本地权重路径模型路径config.json的model_type qwen3_5推理服务vLLM OpenAI 兼容http://GPU服务器IP:8000/v1served-model-name设为qwen3.6-27bEmbeddingBGE-M3Xinference 托管http://Dify服务器IP:9997model_uid bge-m3Dify 登录管理员邮箱/Dify密码控制台账号Xinference Key你的Xinference API KeyDify 对接 bge-m3 用形如xf-...前置要求Docker ≥ 24、docker compose v2能拉取docker.m.daocloud.iovLLM 镜像源国内机配置HF_ENDPOINThttps://hf-mirror.com加速 HuggingFace 下载。三、部署 Dify步骤 1 · 拉取源码并进入编排目录mkdir/difycd/difygitclone https://github.com/langgenius/difycd/dify/dify/docker# 后续所有 docker compose 命令都在该目录执行标准 clone 会把仓库落到/dify/dify编排文件在/dify/dify/docker。若你重命名为dify-main下文所有/dify/dify换成/dify/dify-main即可。步骤 2 · 生成并调整环境变量cp.env.example .env向量库默认weaviate。若本机出现IPv4→[::]套接字投递异常知识库偶发索引/检索失败在.env增加并改端点再用 socat 做一层8088 → 127.0.0.1:8080中继WEAVIATE_ENDPOINThttp://Dify服务器IP:8088步骤 3 · 启动 Dify 栈dockercompose up-ddockercomposeps# 全部 healthy/running 即就绪步骤 4 · 初始化管理员浏览器访问http://你的IP/install创建管理员账号。步骤 5 · 安装模型插件控制台 → 插件市场langgenius/openai:1.0.3LLM 接入OpenAI 兼容langgenius/xinference:0.0.15Embedding 接入插件代码位于plugin_daemon卷内后文两处补丁llm.py/chat.py就改在这里。四、部署 Xinference 启动 BGE-M3Embedding步骤 6 · 起 Xinference 容器并装依赖dockerrun-d--namexinference--restartalways-p9997:9997\-eHF_ENDPOINThttps://hf-mirror.com\xprobe/xinference:latest# 进入容器补装 bge-m3 运行依赖缺它 bge-m3 启动会失败dockerexec-itxinference pipinstallsentence-transformersdockerlogs-fxinference# 看到 Uvicorn running on http://0.0.0.0:9997 即就绪步骤 7 · 创建 Xinference 管理员账号启用鉴权建账号Web UI 注册或内置接口均可在用户中心生成 Dify 对接用的 API Key形如xf-...。步骤 8 · 显式启动 bge-m3 模型关键容器在跑 ≠ 模型在跑Xinference 只是调度器容器起来后必须再显式 launch 一次bge-m3它才会变成running实例# 启动model_type 必须是 embeddingmodel_uid 固定 bge-m3curl-XPOSThttp://Dify服务器IP:9997/v1/models\-HContent-Type: application/json\-d{model_uid:bge-m3,model_name:bge-m3,model_type:embedding}# 验证已在跑curlhttp://Dify服务器IP:9997/v1/models# 期望含 bge-m3# 实跑一次 embedding确认真能出向量1024 维curl-XPOSThttp://Dify服务器IP:9997/v1/embeddings\-HContent-Type: application/json\-d{model:bge-m3,input:这是一个测试文本}# 期望返回 data:[{embedding:[0.01,-0.03,...],index:0}]步骤 9 · Dify 接入 bge-m3 作为默认 Embedding控制台 → 模型供应商 → 添加Xinference服务器 URLhttp://Dify服务器IP:9997不要带/v1插件自动拼接模型 UIDbge-m3API Key你的Xinference API Key选中bge-m3并设为默认 Embedding生产建议本文示例 bge-m3 跑在 CPU 模式当时 GPU 显存被大模型和业务占满。CPU 能跑通但 embedding 是矩阵运算密集型索引慢、检索有可感知延迟不适合大文档量 / 高频检索。生产环境应把 Xinference 改到 GPU 主机以--gpus all运行bge-m3 在该实例上 launch自动用 GPUDify 侧只需把服务器 URL的 host 改掉model_uid/ API Key / 向量维度(1024) 全部不变已有知识库向量仍兼容、无需重建索引。切前先nvidia-smi确认 GPU 还有 4GB 余量避免挤压业务进程。五、启动 vLLM 大模型qwen3.6-27b步骤 10 · 在 GPU 主机执行启动脚本dockerrm-fvllm-qwen3.6-27b2/dev/null||truedockerrun-d\--namevllm-qwen3.6-27b\--restartalways\--gpusall\--shm-size8g\-p8000:8000\-v模型路径:/model\-eHF_HUB_OFFLINE1\--log-opt max-size100m\--log-opt max-file3\docker.m.daocloud.io/vllm/vllm-openai:latest\/model\--trust-remote-code\--dtypebfloat16\--tensor-parallel-size1\--enable-auto-tool-choice\--tool-call-parser qwen3_xml\--reasoning-parser qwen3\--max-model-len65536\--gpu-memory-utilization0.75\--max-num-seqs8\--served-model-name qwen3.6-27b\--enable-prefix-caching\--host0.0.0.0\--port8000关键参数对照参数值作用 / 踩坑点镜像latest0.25.1必须0.10.2不认qwen3_5架构会崩溃模型位置参数/model替代已弃用的--model--tool-call-parserqwen3_xmlqwen3不存在会KeyErrorqwen3_coder/hermes不适用--reasoning-parserqwen3分离思考块与工具调用--max-model-len65536上下文上限需与 Difycontext_size匹配--gpu-memory-utilization0.75共享 GPU 保护给业务留余量--max-num-seqs8共享 GPU 下降低 KV 压力--served-model-nameqwen3.6-27bDify 模型名必须与之完全一致--host 0.0.0.0开否则 Dify 服务器连不上步骤 11 · 确认 vLLM 真在对外服务三次 curldockerlogs-fvllm-qwen3.6-27b# 看到 Application startup complete 即就绪# 1) 列模型curlhttp://127.0.0.1:8000/v1/models# 返回 id qwen3.6-27b# 2) 单轮对话curl-XPOST http://127.0.0.1:8000/v1/chat/completions\-HContent-Type: application/json-HAuthorization: Bearer 你的API Key\-d{model:qwen3.6-27b,messages:[{role:system,content:你是助手},{role:user,content:你好}],max_tokens:64}# 3) 工具调用验证 qwen3_xml parsercurl-XPOST http://127.0.0.1:8000/v1/chat/completions\-HContent-Type: application/json-HAuthorization: Bearer 你的API Key\-d{model:qwen3.6-27b,messages:[{role:user,content:北京今天天气如何用工具查}], tools:[{type:function,function:{name:get_weather,description:查询天气,parameters:{type:object,properties:{city:{type:string}}}}}]}# 期望返回里 tool_calls 被正确解析启动三坑① 工具解析器必须用qwen3_xmlqwen3不存在会KeyError② 镜像必须用latest旧版不认qwen3_5架构③--model已弃用改用位置参数/model。六、Dify 接入 qwen3.6-27bOpenAI 兼容步骤 12 · 模型供应商入口添加自定义 Qwen控制台 → 模型供应商 → 找到OpenAI→ 设置/添加模型API Key你的API KeyAPI Basehttp://GPU服务器IP:8000/v1在自定义模型Customizable Model区域类型LLM模型名称qwen3.6-27b必须和 vLLM--served-model-name完全一致保存光配openai_api_base不够——必须作为自定义模型单独添加否则根本不出现在模型列表。步骤 13 · 设为默认 LLM两处都要改① 控制台点qwen3.6-27b右侧「设为默认」System Model → LLM。② 数据库确保持久生效默认模型记录在tenant_default_models把llm行改成qwen3.6-27bdockerexec-itdocker-db_postgres-1 psql-Upostgres-ddify\-cUPDATE tenant_default_models SET modelqwen3.6-27b WHERE model_typellm;cd/dify/dify/dockerdockercompose restart api plugin_daemon步骤 14 · 补丁llm.py让 Qwen 有可派生的 model schema消除不兼容OpenAI 插件的get_customizable_model_schema()按 base model 名查预定义 schemaqwen3.6-27b没有对应基座会抛Base model qwen3.6-27b not found前端标不兼容、Agent 选不到。需让它在找不到基座时 clone 一个通用 chat schema。文件容器内路径host 对应plugin_daemon卷hash随机用ls查/dify/dify/docker/volumes/plugin_daemon/cwd/langgenius/openai-1.0.3hash/models/llm/llm.py先备份cp llm.py llm.py.bak_qwenfix改动位置替换get_customizable_model_schema整个函数体defget_customizable_model_schema(self,model:str,credentials:dict)-AIModelEntity:schema{item.model:itemforiteminself.predefined_models()}.get(_base_model(model))ifschemaisNone:# Fallback for custom / non-OpenAI base models served via an# OpenAI-compatible endpoint (e.g. Qwen, DeepSeek, local vLLM):# clone a chat-capable predefined schema so the model is listable# and can be set as the default model.templatenext((mforminself.predefined_models()ifm.model_properties.get(mode)chat),None,)iftemplateisNone:templateself.predefined_models()[0]propsdict(template.model_properties)mp(credentialsor{}).get(model_properties)or{}VLLM_MAX_CTX64000try:props[context_size]int(mp[context_size])ifcontext_sizeinmpelseVLLM_MAX_CTXexcept(ValueError,TypeError):props[context_size]VLLM_MAX_CTX# NOTE: do NOT put max_tokens into model_properties. Dify API-side# ModelPropertyKey only allows {mode, context_size, ...} and does NOT# include MAX_TOKENS; adding it breaks Pydantic validation.schematemplate.model_copy(deepTrue,update{model_properties:props})returnschema.model_copy(deepTrue,update{model:model,label:I18nObject(zh_hansmodel,en_usmodel),fetch_from:FetchFrom.CUSTOMIZABLE_MODEL,},)改后docker compose restart plugin_daemon加载。七、对齐 context_sizeDify 凭据 vs vLLM max-model-len克隆 schema 默认context_size1.05M与 vLLM--max-model-len 65536不匹配。把凭据context_size改为64000。注意凭据级model_properties里的max_tokens不会被 Dify 持久化且把它写进model_properties会让 API 端 schema 校验失败ModelPropertyKey不含max_tokens所以只改context_size不要加max_tokens。max_tokens已作为parameter_rule由克隆模板暴露。运行对齐脚本时vLLM 端点必须已通否则保存凭据报Connection error。八、创建知识库 Agent 应用步骤 15 · 建知识库用 bge-m3 做 high_quality 索引控制台 →知识库 → 创建知识库。上传文档如公司考勤制度 PDF。索引方式选高质量high_qualityEmbedding 模型选bge-m3。提交后等索引完成状态available。进知识库 →命中测试输入考勤应返回相关 chunkscore≈0.6即 RAG 链路通。步骤 16 · 创建 Agent 应用并绑定知识库控制台 → 创建应用 →Agent默认模型选qwen3.6-27b开启工具调用。编辑页左侧「上下文 / 知识库」→ 添加知识库绑定步骤 15 的知识库。若 Agent 带 Shell/代码执行能力却不可用在应用「工具」里启用 Shell 执行 providerDifyShellLayer并绑定到当前工作区。在「指令 / 提示词」框填入下面这段约束它只基于知识库作答、不编造你是企业内部知识助手。请根据提供的知识库内容回答问题。 要求 1. 如果知识库中有明确答案请基于知识库回答。 2. 如果知识库中没有答案请明确说知识库中未找到相关内容。 3. 不要编造公司制度、流程或数据。 4. 回答要简洁适合企业内部员工阅读。把它与刚绑定的知识库配合即可得到「只答知识库里有的、答不出就直说、不乱编」的企内问答 Agent。九、补丁chat.py合并多条 system适配 Qwen3 chat templateQwen3/qwen3_5 的 chat template 只接受一条system 消息且在最前。Dify尤其 Agent会把多条 system/developer 提示堆在前面需让插件出站前把多条 system合并为一条。文件.../openai-1.0.3hash/models/llm/chat.py先备份cp chat.py chat.py.bak_systemfix改动 1 · 在模块顶部from __future__ import annotations之后新增 helperdef_ensure_system_first(messages:list[PromptMessage])-list[PromptMessage]:Qwen3/vLLM chat templates accept ONLY one system message, at the start. Dify (esp. Agent apps) stacks several system/developer prompts: KB assistant prompt agent tool prompt an empty system config manifest... Merging them into a single system message (joined by blank lines, empties dropped) keeps it at the front; every other message keeps its original relative order. system_parts:list[str][]rest:list[PromptMessage][]forminmessages:ifisinstance(m,(SystemPromptMessage,DeveloperPromptMessage)):text_text_content(m)iftext.strip():system_parts.append(text)else:rest.append(m)ifsystem_parts:rest.insert(0,SystemPromptMessage(content\n\n.join(system_parts)))returnrest⚠️_ensure_system_first必须写在from __future__ import annotations之后否则整文件SyntaxError、插件加载失败。改动 2 · 在client.chat.completions.create(...)的messages处调用它只改一行responseclient.chat.completions.create(modelmodel,messagescast(Any,[message(item)foritemin_ensure_system_first(prompt_messages)]),streamstream,**params)改后docker compose restart plugin_daemon。十、端到端验证Agent 必须 streamingcurl-s-N-XPOSThttp://Dify服务器IP/v1/chat-messages\-HAuthorization: Bearer 你的Agent API Token\-HContent-Type: application/json\-d{inputs:{},query:描述考勤与请休假管理制度的目的,response_mode:streaming,user:debug}返回流式事件里无event: error、且能正确检索知识库给出答案即全链路打通。Agent 应用必须用 streaming模式blocking 会被拒。十一、部署完成后应有的状态自检清单Dify 栈所有容器healthy/running管理员账号已创建。openai(1.0.3)、xinference(0.0.15) 两个插件已安装。Xinference 容器内sentence-transformers已装bge-m3状态runningPOST /v1/embeddings返回 1024 维向量。Dify 已接入 XinferenceBGE-M3 设为默认 EmbeddingURL 不含/v1。vLLM 容器Application startup complete三次 curl 均正常含工具调用。Dify 已接入 OpenAI 兼容模型qwen3.6-27b作为自定义模型添加、名称与 served-model-name 一致。tenant_default_models的llm行已指向qwen3.6-27b控制台 数据库一致。llm.py已 patchclone 通用 chat schema插件重启生效 → 列表不再不兼容。知识库已用 bge-m3 建 high_quality 索引命中测试正常。Agent 应用已绑定知识库默认模型 qwen3.6-27b开启工具调用Shell provider 按需启用。凭据context_size64000max_tokens只作为 parameter_rule 存在不进model_properties。chat.py已 patch合并多条 system函数位于from __future__之后插件重启生效。Agent API streaming 调用返回正常答案、无 error 事件。风险提示两处插件补丁位于plugin_daemon卷内升级/重装 openai 插件会被覆盖需重打备份llm.py.bak_qwenfix、chat.py.bak_systemfix已留在卷内。十二、踩坑速记把最容易翻车的地方集中在这里Embedding “容器在跑≠模型在跑”Xinference 起容器后必须再 launch 一次 bge-m3否则知识库建索引会静默失败。vLLM 三个启动坑工具解析器用qwen3_xml非qwen3镜像用latest旧版不认qwen3_5--model已弃用改位置参数/model。自定义模型必须单独添加只配openai_api_base不够Qwen 不会出现在模型列表要在自定义模型区域显式加qwen3.6-27b。不兼容是 schema 问题llm.py找不到基座时 clone 通用 chat schema 即可消除。context_size要对齐 vLLM 的--max-model-len本文 64000否则长 prompt 被截断且max_tokens千万别写进model_properties会触发 API 端 schema 校验失败、LLM 列表变空。Qwen3 只接受一条 systemchat.py合并多条 system 是必打补丁且函数必须写在from __future__之后否则整文件SyntaxError。共享 GPU 要留余量--gpu-memory-utilization 0.75、降--max-num-seqs避免把业务进程挤到 OOMEmbedding 优先上 GPU。Agent 调用务必 streamingblocking 模式会被拒。本文为基于公开技术资料与一次真实部署实践的整理仅供学习与交流文中涉及的具体版本号、参数均来自实操环境部署时请以你自身的硬件、镜像版本与官方文档为准。生产环境请务必使用自有凭证并妥善保管避免泄露。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门