Dify_Qwen安装配置手册_cursor.md
这是基于原文生成的 Cursor 版文档。
原文件未改动;本版只做三件事:统一阅读入口、修正已审出的明显问题、补充更适合快速排障的提示。
Cursor 版修订说明
- 把过时的“十个专题”表述统一收敛为“专题合集 / 全部专题”。
- 修正目录映射里“步骤 8(chat.py)/ 九”的表述,避免与正文真实步骤号混淆。
- 保留原主线内容,不改原文件,只在 Cursor 版中统一口径。
阅读提示
- 若正文中的容器名、目录名、IP 与你的环境不一致,请以实际
docker ps、docker compose ps、目录结构为准。 - 若正文属于“本次实战记录”,应理解为环境实录,不等同于所有环境的唯一正确默认值。
运行环境:业务脚本均在 207 固定目录
/opt/workbuddy执行,Python 为/usr/bin/python3。 Windows 开发机仅保留_probe_*调试脚本;同步命令:python scripts_cursor/完整代码约定/00_部署_workbuddy到207.py。
原文主体(已纳入 Cursor 版纠错)
Dify + vLLM(Qwen3.6-27B) + BGE-M3 安装配置手册(完整部署方案)
本文定位:从零把「Dify 1.16.1 部署 → BGE-M3(Embedding) 接入 → vLLM 起 Qwen3.6-27B → 知识库 + Agent 可用」整条链路正确配置跑通的主线手册。
本文只讲"该怎么做、配什么、贴什么代码",不展开排错;每一步可能遇到的坑与对应的代码级修复,全部收在专题合集里。
本文 + 全部专题 = 一套完整的安装解决方案:本手册负责端到端把环境跑通,相关专题负责每一步"遇到 X 怎么办"。
〇、路径约定与文档地图
0.1 仓库目录约定
本文按标准 git clone 约定,Dify 源码落在 /dify/dify(docker 编排目录即 /dify/dify/docker)。 若你的实际目录名为 dify-main(本文相关专题里的路径示例即如此),只需把下文所有 /dify/dify 替换为 /dify/dify-main,其余完全一致。
0.2 文档地图(本手册 + 全部专题 = 完整方案)
| 文档 | 角色 | 覆盖内容 |
|---|---|---|
| 本手册 | 主线 | 从 git clone 到 Agent 可用的端到端配置步骤(含全部代码/配置) |
| 专题一 | 接入 Qwen | 在 Dify 模型供应商入口正确添加自定义 qwen3.6-27b、消除"不兼容"、设默认 LLM |
| 专题二 | bge-m3 | Xinference 如何真正"运行起来" bge-m3(容器在跑 ≠ 模型在跑) |
| 专题三 | 知识库 | 创建 Agent 时知识检索选不到已有知识库的解决 |
| 专题四 | 问答报错 | Agent 问答期报错(400 System message / Connection / 工具解析)排查 |
| 专题五 | 假成功 | 模型"运行成功"但 Dify 仍不可用的 7 层排查 |
| 专题六 | weaviate 中继 | IPv4→[::] 套接字投递 bug 的 socat 中继解决 |
| 专题七 | shell provider | Agent 应用启用 Shell 执行 provider(DifyShellLayer)、sandbox/ssrf_proxy/plugin_daemon 三层确认 |
| 专题八 | from __future__ 子坑 | 插件 patch 的 from __future__ 顺序 SyntaxError 与正确补丁位置 |
| 专题九 | 其余配置 | 控制台登录、vLLM 启动三坑、共享 GPU、context_size 对齐 |
| 专题十 | 模型列表为空 / Agent 报错 | 插件 schema 校验失败(max_tokens 误写进 model_properties)导致 LLM 列表为空、创建 Agent 报错 |
阅读建议:先把本手册从头到尾做一遍;某一步卡住时,按「本章导读里的卡住查哪」或 第十章 索引跳到对应专题看根因与修复代码。
0.3 部署主线五阶段(建议先通读一遍)
| 阶段 | 章节 | 步骤号 | 做完应达到什么 |
|---|---|---|---|
| A. 平台 | 二 | 1~5 | Dify 栈 healthy、管理员可登录、openai/xinference 插件已装 |
| B. 向量 | 三 | 6~9(+9.1 可选 GPU) | Xinference 在跑、bge-m3 running、Dify 默认 Embedding 可用 |
| C. 大模型 | 四 | 10~11 | vLLM :8000 返回 qwen3.6-27b,工具调用 parser 正常 |
| D. 接入 Dify | 五~六 | 12~14 | 模型列表可选 qwen、默认 LLM 已设、context_size 对齐 |
| E. 应用 | 七~九 | 15~16 + patch + 验收 | 知识库 available、Agent 绑库、streaming 问答无 error |
执行原则:按步骤顺序做;某步失败不要跳步——先在本章「本章导读」查常见报错,再打开对应专题修完,回到本步继续。
0.4 全链路常见报错 → 专题索引(速查)
| 你看到的症状 | 最可能卡在哪一步 | 优先打开 |
|---|---|---|
docker compose 起不来 / 容器 unhealthy | 步骤 2~3 | 专题六(weaviate)、专题九 |
| 知识库索引失败、检索偶发超时 | 步骤 2 | 专题六 |
Xinference 有容器但 /v1/models 空 | 步骤 8 | 专题二 |
| Dify Embedding 列表没有 bge-m3 | 步骤 9 | 专题二、专题五·第 3 层 |
| vLLM 容器 Exit / 不认 qwen3_5 | 步骤 10 | 专题九·二、专题四·四 |
| 模型列表空 / 创建 Agent 报 schema | 步骤 12~14 | 专题十、专题一 |
| 模型「不兼容」、下拉里灰掉 | 步骤 12~13 | 专题一 |
400 System message / 多条 system | 章节八 chat.py | 专题四·二、专题一·六 |
| Connection error 但 vLLM curl 通 | 步骤 12~14、六 | 专题五(7 层)、专题九·四 |
| Agent 选不到知识库 | 步骤 16 | 专题三 |
| Shell/代码执行不可用 | 步骤 16 | 专题七 |
一、环境准备
| 项 | 值(本文环境) | 说明 |
|---|---|---|
| Dify 服务器 | 192.168.110.207(root / 123456) | Docker + docker compose v2,目录 /dify/dify/docker |
| GPU 主机 | 116.62.10.183(prod102) | H20 ~96GB,与业务 mxh_env/mxh_live 共享 |
| 大模型 | Qwen3.6-27B | 路径 /models/Qwen3.6-27B,config.json 的 model_type = qwen3_5 |
| 推理服务 | vLLM OpenAI 兼容 | http://116.62.10.183:8000/v1,served-model-name qwen3.6-27b |
| Embedding | bge-m3(Xinference) | http://192.168.110.207:9997,model_uid bge-m3 |
| Dify 登录 | 38205036@qq.com / Difyai123456 | 控制台 API 密码需 base64 |
| Xinference Key | xf-K8H3LiS27H4188XdOyWJj74MWMOlIR9tZbiybDbxbSas7eAI | Dify 对接 bge-m3 用 |
前置要求:Docker ≥ 24、docker compose v2、能访问 docker.m.daocloud.io(vLLM 镜像源)、国内机配 HF_ENDPOINT=https://hf-mirror.com。
二、获取并部署 Dify
本章导读
- 干什么:拉 Dify 源码、配
.env、起 compose、建管理员、装 openai/xinference 两个插件。- 完成标志:
docker compose ps全 healthy;浏览器能/install或登录;插件市场两个插件已安装。- 卡住怎么办:见下表;weaviate 相关见 专题六。
| 常见现象 | 可能原因 | 处理 |
|---|---|---|
| compose pull 超时 | 镜像源不可达 | 配 docker.m.daocloud.io 或国内 mirror |
| 某容器 Restarting | 端口冲突、内存不足 | docker logs <容器>;对照 .env |
| 插件装不上 | plugin_daemon 未就绪 | 等栈 healthy 后重试;见专题九 |
| 步骤 2 改 weaviate 后仍索引失败 | 未加 relay 或未改 compose | 按步骤 2 注释 + 专题六 完整 socat 方案 |
步骤 1 · 拉取 Dify 源码并进入编排目录
完整脚本:scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_01.sh
运行/引用:bash /opt/workbuddy/scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_01.sh
#!/usr/bin/env bash
set -euo pipefail
mkdir /dify
cd /dify
git clone https://github.com/langgenius/dify
cd /dify/dify/docker # 后续所有 docker compose 命令都在该目录执行说明:标准
git clone会把仓库落到/dify/dify,编排文件在/dify/dify/docker。若你重命名为dify-main,下文/dify/dify全部换成/dify/dify-main(见 0.1)。
步骤 2 · 生成并调整环境变量
cp .env.example .env- 向量库默认
weaviate。若本机出现 IPv4→[::]套接字投递 bug(知识库偶发索引/检索失败),在.env增加并改端点:
完整脚本:scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_02.sh
运行/引用:bash /opt/workbuddy/scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_02.sh
#!/usr/bin/env bash
set -euo pipefail
WEAVIATE_ENDPOINT=http://192.168.110.207:8088
并在 docker-compose.yaml 增加 weaviate_relay 中继服务(socat 8088 → 127.0.0.1:8080),详见 专题六。
步骤 3 · 启动 Dify 栈
完整脚本:scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_03.sh
运行/引用:bash /opt/workbuddy/scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_03.sh
#!/usr/bin/env bash
set -euo pipefail
docker compose up -d
docker compose ps # 全部 healthy/running 即就绪步骤 4 · 初始化管理员
浏览器访问 http://<你的IP>/install 创建管理员账号(本文 38205036@qq.com / Difyai123456)。
步骤 5 · 安装模型插件(控制台 → 插件市场)
langgenius/openai:1.0.3(LLM 接入,OpenAI 兼容)langgenius/xinference:0.0.15(Embedding 接入)
插件代码位于
plugin_daemon卷内,本文后续两处 patch(llm.py/chat.py)就在该卷。
三、部署 Xinference + 启动 bge-m3(Embedding)
本章导读
- 干什么:起 Xinference 容器 → 装依赖 → 显式 launch bge-m3 → Dify 接为默认 Embedding。
- 完成标志:
GET /v1/models含bge-m3;POST /v1/embeddings返回 1024 维;Dify 模型页 bge-m3 为默认 Embedding。- 关键认知:容器在跑 ≠ 模型在跑(步骤 8 必须做)。
- 卡住怎么办:专题二(运行机制);选不到知识库时还要查 专题三。
| 常见现象 | 可能原因 | 处理 |
|---|---|---|
| launch 后 models 仍空 | 未 POST launch / model_type 错 | 重跑步骤 8 curl;model_type 必须是 embedding |
sentence-transformers 相关报错 | 步骤 6 未 pip install | 进容器补装 |
| Dify 测 embedding 失败 | URL 带了 /v1 或 Key 错 | URL 只写到 :9997;核对 xf- Key |
| 索引极慢 | CPU 跑 embedding | 可选 步骤 9.1 迁 GPU;见专题二、专题九·三 |
步骤 6 · 起 Xinference 容器并装依赖
完整脚本:scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_04.sh
运行/引用:bash /opt/workbuddy/scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_04.sh
#!/usr/bin/env bash
set -euo pipefail
docker run -d --name xinference --restart always -p 9997:9997 \
-e HF_ENDPOINT=https://hf-mirror.com \
xprobe/xinference:latest
# 进入容器补装 bge-m3 运行依赖(缺它 bge-m3 启动会失败)
docker exec -it xinference pip install sentence-transformers
# 国内 pip 慢可先:docker exec -it xinference pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
docker logs -f xinference # 看到 Uvicorn running on http://0.0.0.0:9997 即就绪步骤 7 · 创建 Xinference 管理员账号
Xinference 启用鉴权,建账号 admin / admin1234(Web UI 注册或内置管理接口均可);在用户中心生成 Dify 对接用的 API Key(形如 xf-...)。
步骤 8 · 显式启动 bge-m3 模型(关键:容器 ≠ 模型在跑)
Xinference 只是调度器,容器起来后必须再显式 launch 一次 bge-m3,它才会变成 running 实例。推荐 REST 方式(可脚本化):
完整脚本:scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_05.sh
运行/引用:bash /opt/workbuddy/scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_05.sh
#!/usr/bin/env bash
set -euo pipefail
# 启动(model_type 必须是 embedding,model_uid 固定 bge-m3)
curl -X POST 'http://192.168.110.207:9997/v1/models' \
-H 'Content-Type: application/json' \
-d '{"model_uid":"bge-m3","model_name":"bge-m3","model_type":"embedding"}'
# 验证已在跑
curl 'http://192.168.110.207:9997/v1/models' # 期望含 "bge-m3"
# 实跑一次 embedding,确认真能出向量(1024 维)
curl -X POST 'http://192.168.110.207:9997/v1/embeddings' \
-H 'Content-Type: application/json' \
-d '{"model":"bge-m3","input":"这是一个测试文本"}'
# 期望返回 "data":[{"embedding":[0.01,-0.03,...],"index":0}]也可用 Web UI(Models → Launch Model → 搜 bge-m3 → Model UID 设
bge-m3→ Launch)或 Python 客户端(client.launch_model(...))。详见 专题二。
步骤 9 · Dify 接入 bge-m3 作为默认 Embedding
控制台 → 模型供应商 → 添加 Xinference:
- 服务器 URL:
http://192.168.110.207:9997(不要带/v1,插件自动拼接) - 模型 UID:
bge-m3 - API Key:
xf-K8H3LiS27H4188XdOyWJj74MWMOlIR9tZbiybDbxbSas7eAI - 选中
bge-m3并设为默认 Embedding
等价控制台 API(本次这类「往供应商里加自定义模型」都是这条;找不到 UI 时直接跑):
完整程序:/opt/workbuddy/scripts_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_01.py
运行/引用:/usr/bin/python3 /opt/workbuddy/scripts_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_01.py
from dify_api import Dify, pp
XF_KEY = "xf-K8H3LiS27H4188XdOyWJj74MWMOlIR9tZbiybDbxbSas7eAI"
d = Dify("38205036@qq.com", "Difyai123456")
d.login()
body = {
"model": "bge-m3",
"model_type": "embedding",
"credentials": {
"server_url": "http://192.168.110.207:9997",
"model_uid": "bge-m3",
"api_key": XF_KEY,
"invoke_timeout": "60",
"max_retries": "3",
},
"name": "bge-m3",
}
r = d.post(
"/workspaces/current/model-providers/langgenius/xinference/xinference/models/credentials",
body,
)
pp("add embedding", r)
r = d.post(
"/workspaces/current/default-model",
body={
"model_settings": [{
"model_type": "text-embedding",
"provider": "langgenius/xinference/xinference",
"model": "bge-m3",
}]
},
)
pp("default embedding", r)
d.close()对应专题:专题二(bge-m3 运行机制)、专题三(知识库选不到时优先怀疑 bge-m3 是否真在跑)。
⚠️ 特殊说明:本次 bge-m3 走的是 CPU 模式,生产环境应部署在 GPU 资源上
本次现状:本环境 Xinference 部署在
192.168.110.207(Dify 那台机),bge-m3 以 CPU 模式launch。之所以走 CPU,是因为当时资源有限——GPU 服务器
116.62.10.183的 H20 显存已被 Qwen3.6-27B(权重+KV,压到 0.75)和mxh_env/mxh_live业务进程占去,没有余量再塞 embedding。CPU 模式能跑通(文档已验证
POST /v1/embeddings返回 1024 维向量、知识库可建索引),但 embedding 是矩阵运算密集型,CPU 下索引慢、检索有可感知延迟,不适合大文档量 / 高频检索的生产场景。生产建议:bge-m3 这类 embedding 模型应当跑在 GPU 上。约 2~4GB 显存(FP16),对 H20(~96GB) 是轻量负载;上 GPU 后索引与检索均为秒级,是"正常"的生产形态。
是否真挪,取决于两点:①知识库文档量 / 检索并发是否到了 CPU 扛不动的程度;②GPU 服务器挪过去后 Qwen 与业务进程仍有余量、不被挤压到 OOM。
步骤 9.1 · 切换到 GPU 服务器运行 bge-m3(生产推荐,操作步骤)
思路:把 Xinference 改到 GPU 主机
116.62.10.183以--gpus all运行,bge-m3 在该实例上 launch(自动用 GPU),Dify 侧只把"服务器 URL"的 host 从192.168.110.207改成116.62.10.183,model_uid/ API Key / 向量维度(1024) 全部不变,已有的知识库向量仍兼容、无需重建索引。
① 先确认 GPU 余量(关键前置,避免挤压业务) 完整脚本:scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_06.sh
运行/引用:bash /opt/workbuddy/scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_06.sh
#!/usr/bin/env bash
set -euo pipefail
# 在 GPU 主机 116.62.10.183 上
nvidia-smi
# 确认:Qwen(约 0.75 利用率) + 业务(~11GB) 之外,还剩 > 4GB 给 bge-m3。
# 若已无余量,不要挪,继续用 CPU 模式。② 在 GPU 主机起 Xinference(加 --gpus all) 完整脚本:scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_07.sh
运行/引用:bash /opt/workbuddy/scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_07.sh
#!/usr/bin/env bash
set -euo pipefail
# 原 CPU 版(在 207 上,无 --gpus):docker run ... xprobe/xinference:latest
# GPU 版(在 116 上):
docker run -d --name xinference-gpu --restart always --gpus all -p 9997:9997 \
-e HF_ENDPOINT=https://hf-mirror.com \
xprobe/xinference:latest
docker exec -it xinference-gpu pip install sentence-transformers # 依赖仍要装
docker logs -f xinference-gpu # 看到 Uvicorn running on http://0.0.0.0:9997 即就绪③ launch bge-m3(强制 GPU) 完整脚本:scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_08.sh
运行/引用:bash /opt/workbuddy/scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_08.sh
#!/usr/bin/env bash
set -euo pipefail
# 在 GPU 主机上,launch 时显式指定 device 用 cuda(不指定 Xinference 也会自动探测到 GPU)
curl -X POST 'http://116.62.10.183:9997/v1/models' \
-H 'Content-Type: application/json' \
-d '{"model_uid":"bge-m3","model_name":"bge-m3","model_type":"embedding","device":"cuda:0"}'
curl 'http://116.62.10.183:9997/v1/models' # 期望含 "bge-m3" 且 state=running
curl -X POST 'http://116.62.10.183:9997/v1/embeddings' \
-H 'Content-Type: application/json' \
-d '{"model":"bge-m3","input":"这是一个测试文本"}' # 期望 1024 维向量④ 确认 Dify(207) 能访问新端点 完整脚本:scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_09.sh
运行/引用:bash /opt/workbuddy/scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_09.sh
#!/usr/bin/env bash
set -euo pipefail
# 在 Dify 服务器 192.168.110.207 上
curl -s http://116.62.10.183:9997/v1/models | head -c 200 # 能返回即网络通
# 若不通:检查 116 防火墙是否放行 9997、两机是否同网段/可路由。⑤ 改 Dify 的 Xinference 供应商配置(唯一必改项)
控制台 → 模型供应商 → Xinference → 编辑:
- 服务器 URL:http://116.62.10.183:9997 # 仅 host 由 207 改 116,仍不带 /v1
- 模型 UID:bge-m3 # 不变
- API Key:xf-K8H3LiS27H4188XdOyWJj74MWMOlIR9tZbiybDbxbSas7eAI # 不变
保存。bge-m3 仍为默认 Embedding,无需动知识库。⑥ 需要改的代码/配置汇总(切换前后对照)
| 位置 | 切换前(本次 CPU) | 切换后(GPU 生产) |
|---|---|---|
Xinference 容器 docker run | 在 207,无 --gpus | 在 116,加 --gpus all |
bge-m3 launch device | 省略(CPU 默认) | "device":"cuda:0" |
| Dify 供应商「服务器 URL」 | http://192.168.110.207:9997 | http://116.62.10.183:9997 |
model_uid / API Key / 维度 | bge-m3 / 原 Key / 1024 | 全部不变 |
| 知识库索引 | 已建(CPU 产出 1024 维) | 无需重建(GPU 同样 1024 维,向量兼容) |
| GPU 显存占用 | 0(CPU 机) | +约 2~4GB(需确认余量) |
注意:
vllm_qwen_run.sh等 LLM 相关配置不用动;只有 Xinference 这一路 + Dify 供应商 URL 需要改。若 GPU 主机另有防火墙策略,放行9997即可。对应专题:专题二(bge-m3 运行机制,含 GPU/CPU 启动差异)、专题九·三(共享 GPU 显存保护)。
四、启动 vLLM 大模型(qwen3.6-27b)
本章导读
- 干什么:在 GPU 机 116 上 docker 起 vLLM,加载
/models/Qwen3.6-27B,暴露 OpenAI 兼容:8000。- 完成标志:步骤 11 三条 curl 通过——列模型、单轮对话、tool_calls 被 qwen3_xml 正确解析。
- 卡住怎么办:启动参数见下表「关键参数」;系统性排查 专题五·第 1 层、专题九·二/三(共享 GPU)。
| 常见现象 | 可能原因 | 处理 |
|---|---|---|
| 容器秒退 / CrashLoop | 镜像太旧不认 qwen3_5 | 必须用 vllm-openai:latest(0.25.1+) |
| OOM / CUDA error | gpu-memory-util 太高 | 降到 0.75;确认业务进程占显存 |
/v1/models 空或 502 | 模型还在加载 | 等 1~3 分钟;docker logs -f |
| tool_calls 乱码/未解析 | parser 错 | 必须 --tool-call-parser qwen3_xml(不是 qwen3) |
步骤 10 · 在 GPU 主机执行启动脚本
在 116.62.10.183 上执行 vllm_qwen_run.sh(脚本先 docker rm -f 同名旧容器,可重复运行):
完整脚本:scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_10.sh
运行/引用:bash /opt/workbuddy/scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_10.sh
#!/usr/bin/env bash
# vLLM 启动 qwen3.6-27b —— H20(96GB) 共享 GPU、业务进程不可受影响 优化版
# 模型 model_type = qwen3_5;镜像必须用 latest(实测 vLLM 0.25.1) 才能识别该架构。
# 工具解析器:标准 Qwen3 instruct 必须用 --tool-call-parser qwen3_xml(qwen3 不存在)。
# 另加 --reasoning-parser qwen3:把思考块从工具调用中分离。
# GPU 约束:业务(mxh_env/mxh_live)已占 ~11.3GB,必须留余量。
docker rm -f vllm-qwen3.6-27b 2>/dev/null || true
docker run -d \
--name vllm-qwen3.6-27b \
--restart always \
--gpus all \
--shm-size=8g \
-p 8000:8000 \
-v /models/Qwen3.6-27B:/model \
-e HF_HUB_OFFLINE=1 \
--log-opt max-size=100m \
--log-opt max-file=3 \
docker.m.daocloud.io/vllm/vllm-openai:latest \
/model \
--trust-remote-code \
--dtype bfloat16 \
--tensor-parallel-size 1 \
--enable-auto-tool-choice \
--tool-call-parser qwen3_xml \
--reasoning-parser qwen3 \
--max-model-len 65536 \
--gpu-memory-utilization 0.75 \
--max-num-seqs 8 \
--served-model-name qwen3.6-27b \
--enable-prefix-caching \
--host 0.0.0.0 \
--port 8000关键参数对照
| 参数 | 值 | 作用 / 踩坑点 |
|---|---|---|
| 镜像 | latest(0.25.1) | 必须,0.10.2 不认 qwen3_5 架构会崩溃 |
| 模型位置参数 | /model | 替代已弃用的 --model |
--tool-call-parser | qwen3_xml | qwen3 不存在会 KeyError;qwen3_coder/hermes 不适用 |
--reasoning-parser | qwen3 | 分离思考块与工具调用 |
--max-model-len | 65536 | 上下文上限,需与 Dify context_size 匹配 |
--gpu-memory-utilization | 0.75 | 共享 GPU 保护,给业务留余量 |
--max-num-seqs | 8 | 共享 GPU 下降低 KV 压力 |
--served-model-name | qwen3.6-27b | Dify 模型名必须与之完全一致 |
--host 0.0.0.0 | 开 | 否则 Dify 服务器连不上 |
启动三坑(parser 名、镜像版本、
--model弃用告警)与共享 GPU 显存保护,详见 专题九·二、三。
步骤 11 · 确认 vLLM 真在对外服务(三次 curl)
完整脚本:scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_11.sh
运行/引用:bash /opt/workbuddy/scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_11.sh
#!/usr/bin/env bash
set -euo pipefail
docker logs -f vllm-qwen3.6-27b # 看到 "Application startup complete" 即就绪
# 1) 列模型
curl http://127.0.0.1:8000/v1/models # 返回 id = "qwen3.6-27b"
# 2) 单轮对话(单条 system)
curl -X POST http://127.0.0.1:8000/v1/chat/completions \
-H 'Content-Type: application/json' -H 'Authorization: Bearer 123456' \
-d '{"model":"qwen3.6-27b","messages":[{"role":"system","content":"你是助手"},{"role":"user","content":"你好"}],"max_tokens":64}'
# 3) 工具调用(验证 qwen3_xml parser)
curl -X POST http://127.0.0.1:8000/v1/chat/completions \
-H 'Content-Type: application/json' -H 'Authorization: Bearer 123456' \
-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 被正确解析对应专题:专题五·一(第 1 层)、专题四·四(C 类工具解析)。
五、Dify 接入 qwen3.6-27b(OpenAI 兼容)
本章导读
- 干什么:在 OpenAI 供应商下单独添加自定义模型
qwen3.6-27b→ patchllm.py→ 设为默认 LLM。- 完成标志:LLM 列表里 qwen 可点、无「不兼容」;默认模型已是 qwen3.6-27b。
- 卡住怎么办:专题一(接入/不兼容/schema);列表为空见 专题十。
| 常见现象 | 可能原因 | 处理 |
|---|---|---|
| 模型列表没有 qwen | 只配了 base 未「单独添加」 | 步骤 12 自定义模型区域必做 |
| 「不兼容」灰显 | 插件 schema 查不到基座 | 专题一 patch get_customizable_model_schema |
| 保存凭据 Connection error | vLLM 未起或 Base URL 错 | 先验 :8000/v1/models;Base 勿多斜杠 |
| LLM 列表突然变空 | max_tokens 写进 model_properties | 专题十 |
步骤 12 · 模型供应商入口添加自定义 Qwen
控制台 → 模型供应商 → 找到 OpenAI → 设置/添加模型:
- API Key:
123456 - API Base:
http://116.62.10.183:8000/v1 - 在 自定义模型(Customizable Model) 区域:类型
LLM,模型名称qwen3.6-27b(必须和 vLLM--served-model-name完全一致) - 保存
光配 openai_api_base 不够——必须作为自定义模型单独添加,否则根本不出现在模型列表。
等价控制台 API(本次添加自定义 LLM 走的就是这条,不是只点 UI):
完整程序:/opt/workbuddy/scripts_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_02.py
运行/引用:/usr/bin/python3 /opt/workbuddy/scripts_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_02.py
from dify_api import Dify, pp
d = Dify("38205036@qq.com", "Difyai123456")
d.login()
body = {
"model": "qwen3.6-27b",
"model_type": "llm",
"credentials": {
"openai_api_key": "123456",
"openai_api_base": "http://116.62.10.183:8000/v1",
"openai_organization": "",
"api_protocol": "chat",
},
"name": "qwen3.6-27b",
}
r = d.post(
"/workspaces/current/model-providers/langgenius/openai/openai/models/credentials",
body,
)
pp("add qwen", r)
r = d.get("/workspaces/current/models/model-types/llm")
pp("llm list", r)
d.close()已有凭据时改用 PUT 并带 credential_id,见专题九。
步骤 13 · 设为默认 LLM(两处都要改)
① 控制台:点 qwen3.6-27b 右侧「设为默认」(System Model → LLM)。找不到该按钮时用 API:
完整程序:/opt/workbuddy/scripts_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_03.py
运行/引用:/usr/bin/python3 /opt/workbuddy/scripts_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_03.py
from dify_api import Dify, pp
d = Dify("38205036@qq.com", "Difyai123456")
d.login()
r = d.post(
"/workspaces/current/default-model",
body={
"model_settings": [{
"model_type": "llm",
"provider": "langgenius/openai/openai",
"model": "qwen3.6-27b",
}]
},
)
pp("default llm", r)
d.close()② 数据库(确保持久生效):默认模型记录在 tenant_default_models,把 llm 行从插件自带的 gpt-5.6 改成 qwen3.6-27b:
完整脚本:scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_12.sh
运行/引用:bash /opt/workbuddy/scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_12.sh
#!/usr/bin/env bash
set -euo pipefail
docker exec -it docker-db_postgres-1 psql -U postgres -d dify \
-c "UPDATE tenant_default_models SET model='qwen3.6-27b' WHERE model_type='llm';"
cd /dify/dify/docker && docker compose restart api plugin_daemon步骤 14 · Patch 插件 llm.py:让 qwen 有可派生的 model schema(消除"不兼容")
OpenAI 插件的 get_customizable_model_schema() 按 base model 名查预定义 schema,qwen3.6-27b 没有对应基座会抛 Base model qwen3.6-27b not found,前端标"不兼容"、Agent 选不到。需让它在找不到基座时 clone 一个通用 chat schema。
插件升级后:卷内可能并存多个
openai-1.0.x@hash。必须给当前运行版本(及建议给全部版本)打补丁,否则会出现「昨天还好、今天模型不可用」。详见 专题十七。一键:
python scripts_cursor/Dify_专题一_集成Qwen3.6-27B/专题一_04_改llm_schema_修改后.py
文件(容器内路径,host 对应 plugin_daemon 卷;<hash> 随机,用 ls 查;不要只改其中一个旧版本):
/dify/dify/docker/volumes/plugin_daemon/cwd/langgenius/openai-<版本>@<hash>/models/llm/llm.py先备份:cp llm.py llm.py.bak_qwenfix
改动位置:替换 get_customizable_model_schema 整个函数体:
完整补丁:patches_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_01.py
运行/引用:见 patches_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_01.py
def get_customizable_model_schema(
self, model: str, credentials: dict
) -> AIModelEntity:
schema = {item.model: item for item in self.predefined_models()}.get(
_base_model(model)
)
if schema is None:
# 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.
template = next(
(m for m in self.predefined_models()
if m.model_properties.get("mode") == "chat"),
None,
)
if template is None:
template = self.predefined_models()[0]
props = dict(template.model_properties)
mp = (credentials or {}).get("model_properties") or {}
# Align context_size to the actual vLLM --max-model-len (65536) so Dify
# never lets prompts exceed what the served model can accept. The
# credential-update API does NOT persist model_properties for this
# provider, so we hardcode the safe ceiling here as the default and
# still honor an explicit override when one is supplied.
VLLM_MAX_CTX = 64000
try:
props["context_size"] = int(mp["context_size"]) if "context_size" in mp else VLLM_MAX_CTX
except (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 when the API
# parses the schema from plugin_daemon. max_tokens is already exposed
# as a parameter_rule by the cloned template.
schema = template.model_copy(deep=True, update={"model_properties": props})
return schema.model_copy(
deep=True,
update={
"model": model,
"label": I18nObject(zh_hans=model, en_us=model),
"fetch_from": FetchFrom.CUSTOMIZABLE_MODEL,
},
)改后 docker compose restart plugin_daemon 加载。
对应专题:专题一·四(含"不兼容"根因)、专题五·六(第 4 层)。
六、对齐 context_size(Dify 凭据 vs vLLM max-model-len)
本章导读
- 干什么:把 Dify 里 qwen 凭据的
context_size与 vLLM--max-model-len对齐(本文 64000)。- 完成标志:脚本打印
VERIFY context_size=64000(或与你 vLLM 一致)。- 注意:不要把 max_tokens 写进 model_properties(那是 parameter_rule,见 专题十)。
- 卡住怎么办:Connection error → 先确认 vLLM 已通;仍失败 专题九·四、专题五·第 2 层。
| 常见现象 | 可能原因 | 处理 |
|---|---|---|
| align 脚本 Connection error | 116:8000 不通 | 回到第四章验 vLLM |
| context_size 改完又变回去 | UI 保存覆盖了凭据 | 用 API/脚本改;勿乱点供应商保存 |
| 对话截断异常短 | max_tokens 与 context 混淆 | 专题十一/十二(Agent 快照 max_tokens) |
克隆 schema 默认 context_size=1.05M,与 vLLM --max-model-len 65536 不匹配。把凭据 context_size 改为 64000,运行 align_qwen_ctx.py(依赖 dify_api.py)。注意:凭据级 model_properties 里的 max_tokens 不会被 Dify 持久化,且把它写进 model_properties 会让 API 端 schema 校验失败(ModelPropertyKey 不含 max_tokens),所以脚本里只改 context_size:
完整程序:/opt/workbuddy/scripts_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_04.py
运行/引用:/usr/bin/python3 /opt/workbuddy/scripts_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_04.py
import json, time
from dify_api import Dify
EMAIL = "38205036@qq.com"
PW = "Difyai123456"
PROVIDER = "langgenius/openai/openai"
MODEL = "qwen3.6-27b"
NEW_CTX = 64000
# 不要在这里加 max_tokens;max_tokens 是 parameter_rule,不是 model_properties。
d = Dify(EMAIL, PW)
ok, resp, csrf = d.login()
print("LOGIN ok=%s" % ok)
if not ok:
d.close(); raise SystemExit("login failed")
# 1) GET current credential (decrypted) + credential_id
r = d.get("/workspaces/current/model-providers/%s/models/credentials?model_type=llm&model=%s"
% (PROVIDER, MODEL))
js = r["json"] or {}
cur_cred = js.get("credentials") or {}
cid = js.get("current_credential_id")
# 2) inject/overwrite model_properties (只保留 context_size)
cred = dict(cur_cred)
cred["model_properties"] = {"context_size": NEW_CTX}
name = js.get("current_credential_name") or "Qwen3.6-27b"
# 3) PUT update
r = d.req("PUT", "/workspaces/current/model-providers/%s/models/credentials" % PROVIDER,
body={"model": MODEL, "model_type": "llm",
"credential_id": cid, "credentials": cred, "name": name})
print("PUT cred HTTP", r["code"], r["text"][:200])
# 4) verify
time.sleep(2)
r = d.get("/workspaces/current/models/model-types/llm")
for p in (r["json"] or {}).get("data", []):
if p.get("provider") == PROVIDER:
for m in p.get("models", []):
if m.get("model") == MODEL:
mp = m.get("model_properties") or {}
print("VERIFY context_size=%s" % mp.get("context_size"))
d.close()python align_qwen_ctx.py前置条件:运行脚本时 vLLM 端点
116.62.10.183:8000必须已通(否则保存凭据报Connection error)。详见 专题九·四、专题五·二(第 2 层)。
七、创建知识库 + 创建 Agent 应用
本章导读
- 干什么:建 high_quality 知识库(bge-m3 索引)→ 创建 Agent → 绑库 + 写系统提示词。
- 完成标志:知识库
available、命中测试有 chunk;Agent 编辑页已绑库。- 卡住怎么办:索引失败回 第三章/专题二;选不到库 专题三;Shell 工具 专题七。
| 常见现象 | 可能原因 | 处理 |
|---|---|---|
| 知识库一直 indexing | embedding 不可用 / weaviate | 验 bge-m3;专题六 |
| 命中测试无结果 | 文档未分段完或 embedding 错 | 等 available;换高质量索引 |
| Agent 知识库列表空 | bge-m3 未默认 / 库未 available | 专题三 |
| 创建 Agent 报错 | LLM schema / 列表空 | 专题十 |
步骤 15 · 建知识库(用 bge-m3 做 high_quality 索引)
- 控制台 → 知识库 → 创建知识库。
- 上传文档(如
dbbjthr_001_kaoqin.pdf,考勤制度)。 - 索引方式选 高质量(high_quality),Embedding 模型选 bge-m3。
- 提交后等索引完成(状态
available)。 - 进知识库 → 命中测试,输入"考勤"应返回相关 chunk(score≈0.6+)即 RAG 链路通。
步骤 16 · 创建 Agent 应用并绑定知识库
- 控制台 → 创建应用 → Agent;默认模型选
qwen3.6-27b,开启工具调用。 - 编辑页左侧「上下文 / 知识库」→ 添加知识库,绑定步骤 15 的知识库。
- 若 Agent 带 Shell/代码执行能力却不可用:在应用「工具」里启用 Shell 执行 provider(
DifyShellLayer)并绑定到当前工作区。详见 专题七。 - 填写「指令 / 提示词」(系统提示):作为企业内部知识助手,建议在编辑页的「指令」框填入下面这段,约束它只基于知识库作答、不编造:
` 你是企业内部知识助手。请根据提供的知识库内容回答问题。 要求:
- 如果知识库中有明确答案,请基于知识库回答。
- 如果知识库中没有答案,请明确说“知识库中未找到相关内容”。
- 不要编造公司制度、流程或数据。
- 回答要简洁,适合企业内部员工阅读。
`
把它与刚绑定的知识库配合,即可得到一个「只答知识库里有的、答不出就直说、不乱编」的企内问答 Agent。
对应专题:专题三(选不到知识库时优先查 bge-m3 是否真在跑)、专题五(第 5 层之后)。
八、Patch 插件 chat.py:合并多条 system(适配 Qwen3 chat template)
本章导读
- 干什么:改 openai 插件
chat.py,把 Agent 多条 system 合并成一条再发给 vLLM。- 完成标志:patch 后
plugin_daemon已 restart;Agent 对话不再400 System message。- 卡住怎么办:
from __future__顺序错 专题八;仍 400 专题四·二、专题五·第 7 层。
| 常见现象 | 可能原因 | 处理 |
|---|---|---|
| patch 后 SyntaxError | future import 不在文件首行 | 专题八 |
| 仍报 system 相关 400 | 未 restart plugin_daemon | docker compose restart plugin_daemon |
| 改错文件 | 插件 hash 目录变了 | docker exec 找最新 openai-1.0.3@ 路径 |
Qwen3/qwen3_5 的 chat template 只接受一条 system 消息且在最前。Dify(尤其 Agent)会把多条 system/developer 提示堆在前面,需让插件出站前把多条 system 合并为一条。
文件:.../openai-1.0.3@<hash>/models/llm/chat.py 先备份:cp chat.py chat.py.bak_systemfix
改动 1 · 在模块顶部(from __future__ import annotations 之后)新增 helper:
完整程序:/opt/workbuddy/scripts_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_05.py
运行/引用:/usr/bin/python3 /opt/workbuddy/scripts_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_05.py
def _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] = []
for m in messages:
if isinstance(m, (SystemPromptMessage, DeveloperPromptMessage)):
text = _text_content(m)
if text.strip():
system_parts.append(text)
else:
rest.append(m)
if system_parts:
rest.insert(0, SystemPromptMessage(content="\n\n".join(system_parts)))
return rest⚠️
_ensure_system_first必须写在from __future__ import annotations之后,否则整文件SyntaxError、插件加载失败(详见 专题八)。
改动 2 · 在 client.chat.completions.create(...) 的 messages= 处调用它(只改一行):
完整程序:/opt/workbuddy/scripts_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_06.py
运行/引用:/usr/bin/python3 /opt/workbuddy/scripts_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_06.py
response = client.chat.completions.create(
model=model,
messages=cast(Any, [message(item) for item in _ensure_system_first(prompt_messages)]),
stream=stream,
**params
)改后 docker compose restart plugin_daemon。
对应专题:专题一·六、专题四·二(A 类 400)、专题五·九(第 7 层)。
九、端到端验证可用(Agent 必须 streaming)
本章导读
- 干什么:用 streaming 调 Agent API,问一道知识库里有答案的制度题。
- 完成标志:SSE 流里无
event: error,且回答引用知识库内容(非胡编)。- 卡住怎么办:blocking 模式会被拒;Connection/400 按 专题四、专题五 分层查。
| 常见现象 | 可能原因 | 处理 |
|---|---|---|
event: error + Connection | vLLM 断或 Dify→116 不通 | 验 vLLM;专题五 |
| 流式空、无正文 | max_tokens 过小 | 专题十一/十二 |
| 答非所问 | 未绑库 / 检索失败 | 回步骤 15~16;专题十三 Rerank 后续优化 |
完整脚本:scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_13.sh
运行/引用:bash /opt/workbuddy/scripts_bash_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_13.sh
#!/usr/bin/env bash
set -euo pipefail
curl -s -N -X POST 'http://192.168.110.207/v1/chat-messages' \
-H 'Authorization: Bearer app-v9yYVTQTrUoSFHNqAhufSGmh' \
-H 'Content-Type: application/json' \
-d '{"inputs":{},"query":"描述考勤与请休假管理制度的目的","response_mode":"streaming","user":"debug"}'返回流式事件里无 event: error、且能正确检索知识库给出答案,即全链路打通。
Agent 应用必须用 streaming 模式(blocking 会被拒)。对应专题:专题四·二(验证)、专题五(最终验证)。
十、本手册 ↔ 专题合集 对应关系(完整方案索引)
| 本手册步骤 | 做的是什么 | 卡住时看 |
|---|---|---|
| 步骤 2 | weaviate 端点 / 中继 | 专题六 |
| 步骤 6–9 | Xinference + bge-m3 | 专题二(运行机制)、专题三(知识库选不到) |
| 步骤 10–11 | vLLM 启动 + 验证 | 专题九·二、三(启动三坑/共享GPU)、专题四·四(C 类)、专题五·一 |
| 步骤 12–14 | 接入 Qwen + 设默认 + llm.py patch | 专题一(接入/不兼容)、专题五·四、六(第 4/5 层) |
| 章节八(chat.py)/ 章节九 | 合并 system + 验证 | 专题四(问答报错)、专题五·七(第 7 层) |
| 步骤 6(上下文对齐) | context_size 对齐 64000 | 专题九·四、专题五·二(第 2 层)、专题十(max_tokens 勿写进 model_properties) |
| 步骤 15–16 | 知识库 + Agent 绑定 / 模型列表为空 | 专题三(选不到)、专题七(shell provider)、专题十(创建 Agent 报错 / 列表为空) |
完整排查路径:当"模型运行成功但 Dify 仍不行"时,按 专题五 的 7 层从外到内逐层定位。
十一、配置清单(部署完成后应有的状态)
- [ ] Dify 栈所有容器
healthy/running,管理员账号已创建(/dify/dify/docker下docker compose ps)。 - [ ] openai(
1.0.3)、xinference(0.0.15) 两个插件已安装。 - [ ] Xinference 容器内
sentence-transformers已装,bge-m3状态running(uid=bge-m3),POST /v1/embeddings返回 1024 维向量。 - [ ] Dify 已接入 Xinference,BGE-M3 设为默认 Embedding,URL 不含
/v1。 - [ ] vLLM 容器
Application startup complete,三次 curl 均正常(含工具调用)。 - [ ] Dify 已接入 OpenAI 兼容模型,
qwen3.6-27b作为自定义模型添加、名称与 served-model-name 一致。 - [ ]
tenant_default_models的llm行已指向qwen3.6-27b(控制台 + 数据库一致)。 - [ ]
llm.py已 patch(clone 通用 chat schema),插件重启生效 → 列表不再"不兼容"。 - [ ] 知识库已用 bge-m3 建 high_quality 索引,命中测试正常。
- [ ] Agent 应用已绑定知识库,默认模型 qwen3.6-27b,开启工具调用(Shell provider 按需启用)。
- [ ]
align_qwen_ctx.py已跑,凭据context_size=64000;max_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已留在卷内)。
本专题 Python 程序一览
| 文件 | 用途 | |---|---|| Qwen手册_01_添加Embedding凭据.py | Qwen 手册 · 步骤 9:添加 bge-m3 Embedding 凭据。 | | Qwen手册_02_添加Qwen凭据.py | Qwen 手册 · 步骤 12:添加 Qwen3.6-27B 自定义 LLM 凭据。 | | Qwen手册_03_设默认LLM.py | Qwen 手册 · 步骤 13:设 qwen3.6-27b 为默认 LLM。 | | Qwen手册_04_对齐context_size.py | Qwen 手册 · 步骤 6:对齐 Qwen context_size=64000(勿写 max_tokens 进 model_properties)。 |
Qwen手册_01_添加Embedding凭据.py
运行:/usr/bin/python3 /opt/workbuddy/scripts_cursor/Dify_Qwen安装配置手册/Qwen手册_01_添加Embedding凭据.py
完整补丁:patches_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_02.py
运行/引用:见 patches_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_02.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Qwen 手册 · 步骤 9:添加 bge-m3 Embedding 凭据。"""
from __future__ import annotations
import subprocess
import sys
from pathlib import Path
def main() -> int:
script = Path(__file__).resolve().parent / "专题二_04_添加Dify_Embedding凭据.py"
return subprocess.call([sys.executable, str(script)])
if __name__ == "__main__":
sys.exit(main())Qwen手册_02_添加Qwen凭据.py
运行:/usr/bin/python3 /opt/workbuddy/scripts_cursor/Dify_Qwen安装配置手册/Qwen手册_02_添加Qwen凭据.py
完整补丁:patches_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_03.py
运行/引用:见 patches_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_03.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Qwen 手册 · 步骤 12:添加 Qwen3.6-27B 自定义 LLM 凭据。"""
from __future__ import annotations
import subprocess
import sys
from pathlib import Path
def main() -> int:
script = Path(__file__).resolve().parent / "专题一_01_添加Qwen凭据.py"
return subprocess.call([sys.executable, str(script)])
if __name__ == "__main__":
sys.exit(main())Qwen手册_03_设默认LLM.py
运行:/usr/bin/python3 /opt/workbuddy/scripts_cursor/Dify_Qwen安装配置手册/Qwen手册_03_设默认LLM.py
完整补丁:patches_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_04.py
运行/引用:见 patches_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_04.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Qwen 手册 · 步骤 13:设 qwen3.6-27b 为默认 LLM。"""
from __future__ import annotations
import subprocess
import sys
from pathlib import Path
def main() -> int:
script = Path(__file__).resolve().parent / "专题一_02_设默认LLM.py"
return subprocess.call([sys.executable, str(script)])
if __name__ == "__main__":
sys.exit(main())Qwen手册_04_对齐context_size.py
运行:/usr/bin/python3 /opt/workbuddy/scripts_cursor/Dify_Qwen安装配置手册/Qwen手册_04_对齐context_size.py
完整补丁:patches_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_05.py
运行/引用:见 patches_cursor/Dify_Qwen安装配置手册/Qwen手册_内联_05.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Qwen 手册 · 步骤 6:对齐 Qwen context_size=64000(勿写 max_tokens 进 model_properties)。"""
from __future__ import annotations
import sys
import time
import _bootstrap # noqa: F401
import _config as C
from dify_api import Dify
def main() -> int:
d = Dify(C.DIFY_EMAIL, C.DIFY_PASSWORD)
try:
ok, _, _ = d.login()
print("login ok:", ok)
if not ok:
return 1
r = d.get(
"/workspaces/current/model-providers/%s/models/credentials?model_type=llm&model=%s"
% (C.OPENAI_PROVIDER, C.QWEN_MODEL)
)
js = r.get("json") or {}
cur_cred = js.get("credentials") or {}
cid = js.get("current_credential_id")
print("current_credential_id:", cid)
cred = dict(cur_cred)
cred["model_properties"] = {"context_size": C.QWEN_CTX}
name = js.get("current_credential_name") or C.QWEN_MODEL
r = d.req(
"PUT",
"/workspaces/current/model-providers/%s/models/credentials" % C.OPENAI_PROVIDER,
body={
"model": C.QWEN_MODEL,
"model_type": "llm",
"credential_id": cid,
"credentials": cred,
"name": name,
},
)
print("PUT cred HTTP", r.get("code"), (r.get("text") or "")[:200])
time.sleep(2)
r = d.get("/workspaces/current/models/model-types/llm")
for p in (r.get("json") or {}).get("data") or []:
if p.get("provider") == C.OPENAI_PROVIDER:
for m in p.get("models") or []:
if m.get("model") == C.QWEN_MODEL:
mp = m.get("model_properties") or {}
print("VERIFY context_size=", mp.get("context_size"))
return 0 if r.get("code") == "200" else 1
finally:
d.close()
if __name__ == "__main__":
sys.exit(main())