Dify_专题三_Agent知识库选择_cursor.md
这是基于原文生成的 Cursor 版文档。
原文件未改动;本版只做三件事:统一阅读入口、修正已审出的明显问题、补充更适合快速排障的提示。
Cursor 版修订说明
- 修正明显笔误,把“关联网的”改为“关联的”。
- 保留核心结论:知识库可选性取决于 embedding provider 是否可用,以及 provider 名与 model uid 是否稳定。
阅读提示
- 若正文中的容器名、目录名、IP 与你的环境不一致,请以实际
docker ps、docker compose ps、目录结构为准。 - 若正文属于“本次实战记录”,应理解为环境实录,不等同于所有环境的唯一正确默认值。
运行环境:业务脚本均在 207 固定目录
/opt/workbuddy执行,Python 为/usr/bin/python3。 Windows 开发机仅保留_probe_*调试脚本;同步命令:python scripts_cursor/完整代码约定/00_部署_workbuddy到207.py。
原文主体(已纳入 Cursor 版纠错)
专题三:创建 Agent 时知识检索无法选择已有知识库的解决
阅读导航(何时打开 · 报错往哪查)
本文是单点修复/排障专题,配合《安装配置手册》使用;下文实战步骤与代码全部保留,此处只做索引。
| 现象 | 优先看本文 | 还可能是 |
|---|---|---|
| Agent 知识库列表空/灰 | §2 bge-m3 | 专题二 |
| 库 available 仍选不到 | §4 UI 位置 | 快照未绑库→专题十五 |
| 绑了库对话像没检索 | §6 API 核查 | 专题十三 Rerank |
专题目标:解决一个高频卡点——创建/编辑 Agent 应用时,"知识检索 / 上下文"里选不到已经建好的知识库。把根因、配置动作和可用于核查的代码直接写进文章。
环境:Dify 1.16.1,知识库用 bge-m3(Xinference)建 high_quality 索引。
0. 现象描述
在 Dify 里创建 Agent 应用(或编辑已有 Agent),进入"知识检索 / 上下文"要绑定一个已经建好的知识库,但:
- 下拉列表为空;或
- 列表里能看到知识库名称,但置灰 / 选不中;或
- 提示"暂无可用知识库"。
本质:Dify 在 Agent 上下文里只列出"当前可被检索服务调用"的知识库。凡是 embedding 模型不可达、索引未完成、或绑定关系丢失的 KB,都会被隐藏。
1. 先确认知识库自身是否"可用"
知识库必须处于索引完成(available)状态才会被允许选择。
控制台 → 知识库:
- 状态列应为
available(或"可用")。 - 若是
indexing(索引中):等进度跑完。 - 若是
failed/disabled:点「重建索引」重新跑;跑完变available才可选。
只有
available的 KB 会出现在 Agent 的知识检索列表里——这是第一道也是最常见的筛选。
2. 最常见根因:知识库的 Embedding 模型不可达(bge-m3 没在跑)
本环境知识库是用 bge-m3(Xinference) 建的。只要 Xinference 里 bge-m3 不在 running,Dify 就认为该 KB 的 embedding provider 不可用,直接在 Agent 选择列表里把它隐藏。
排查 & 解决:
- 回到 Xinference(专题二),确认 bge-m3 状态
running、model_uid=bge-m3一致:
完整脚本:scripts_bash_cursor/Dify_专题三_Agent知识库选择/专题三_内联_01.sh
运行/引用:bash /opt/workbuddy/scripts_bash_cursor/Dify_专题三_Agent知识库选择/专题三_内联_01.sh
#!/usr/bin/env bash
set -euo pipefail
curl 'http://192.168.110.207:9997/v1/models' # 应含 bge-m3
curl -X POST 'http://192.168.110.207:9997/v1/embeddings' \
-H 'Content-Type: application/json' \
-d '{"model":"bge-m3","input":"test"}' # 应返回 1024 维向量
- 控制台 → 模型供应商 → Xinference 连接正常,
bge-m3为默认 Embedding。 - 进该知识库详情页,点「命中测试」,能返回相关 chunk 即 embedding 链路恢复。
- 回到 Agent,知识库即可正常选中。
若 bge-m3 容器/实例被重建过,重新 launch 一次(保持
model_uid=bge-m3)即可,无需重建知识库——Dify 是按 provider 名 + model uid 关联 KB 的。
3. Embedding 模型"一致性":别让 KB 关联的模型失效
知识库在建立时,会把当时用的 Embedding 模型(provider + model) 写进元数据。以下情况会导致它在 Agent 里消失:
- Xinference 插件被卸载/重装,且重装后模型 UID 变成别的(不再是
bge-m3)。 - Dify 里把 bge-m3 删掉、换成了别的 embedding(旧 KB 仍指向 bge-m3)。
- served-model-name / model_uid 改过,KB 的关联对不上。
解决原则:保持 Xinference 这个 provider 一直在、且 bge-m3 的 uid 不变。KB 是按"provider 名 + model uid"关联的,只要这两者稳定,KB 就一直可选。
4. Agent 里"正确添加知识库"的位置(别找错地方)
不同应用类型,加知识库的位置不同,找错地方会以为"选不到":
- Agent 应用(Agent Playground):编辑页左侧「上下文 / 知识库」区 → 点「添加知识库」直接选。不是在节点画布里拖。
- Chatflow / 工作流应用:在工作流画布里拖一个「知识检索」节点 → 节点配置里选数据集(dataset)。
- 两者都要求 KB 满足第 1、2 条(available + embedding 可达)。
5. 用代码核查知识库状态(定位"为什么选不到")
如果 UI 上看不出原因,用下面完整程序列出知识库状态(不要从正文抄片段自己拼):
完整程序:/opt/workbuddy/scripts_cursor/Dify_专题三_Agent知识库选择/专题三_01_列出知识库.py
在 207 上运行:/usr/bin/python3 /opt/workbuddy/scripts_cursor/Dify_专题三_Agent知识库选择/专题三_01_列出知识库.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""专题三 · 步骤 1:列出 workspace 所有知识库及索引/embedding 状态。"""
from __future__ import annotations
import sys
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)
r = d.get("/datasets")
kb_list = (r.get("json") or {}).get("data", [])
if not kb_list:
print("当前 workspace 没有任何知识库")
return 0
for kb in kb_list:
print("---")
print("name :", kb.get("name"))
print("id :", kb.get("id"))
print("indexing_status:", kb.get("indexing_status"))
print("embedding_model:", kb.get("embedding_model"))
print("provider :", kb.get("embedding_model_provider"))
return 0
finally:
d.close()
if __name__ == "__main__":
sys.exit(main())判读:
indexing_status != available→ 回到第 1 条,重建/等索引。embedding_model_provider是xinference但 Xinference 里 bge-m3 没跑 → 回到第 2 条。- 列表为空 → 说明 KB 根本没建,或建在了别的 workspace。
若某个 KB 索引失败,可在知识库页面点「重建索引」(UI 操作);重建后状态会变 available,Agent 里即可选中。
6. 进阶:通过 API 把知识库绑到 Agent(当 UI 仍不便时)
Agent 应用的知识库绑定是写在应用 model_config 里的。若 UI 始终选不到、但确认 KB 已 available 且 embedding 可达,运行:
完整程序:/opt/workbuddy/scripts_cursor/Dify_专题三_Agent知识库选择/专题三_02_绑定知识库到Agent.py
在 207 上运行:/usr/bin/python3 /opt/workbuddy/scripts_cursor/Dify_专题三_Agent知识库选择/专题三_02_绑定知识库到Agent.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""专题三 · 步骤 2:通过 API 把指定 dataset 绑到 Agent 上下文检索。"""
from __future__ import annotations
import sys
import _bootstrap # noqa: F401
import _config as C
from dify_api import Dify, pp
def main() -> int:
d = Dify(C.DIFY_EMAIL, C.DIFY_PASSWORD)
try:
d.login()
r = d.get("/apps/%s/model-config" % C.APP_ID)
cfg = r.get("json") or {}
if not cfg:
print("无法读取 model-config:", r.get("code"))
return 1
cfg["dataset_configs"] = {
"retrieval_model": {
"search_method": "semantic_search",
"reranking_enable": False,
"top_k": 4,
"score_threshold_enabled": False,
},
"datasets": [{"id": C.DS_ID}],
}
out = d.req("POST", "/apps/%s/model-config" % C.APP_ID, body=cfg)
pp("bind result", out)
return 0 if out.get("code") == "200" else 1
finally:
d.close()
if __name__ == "__main__":
sys.exit(main())提示:上述
model-config字段结构随 Dify 版本略有差异;若字段名不符,先在d.get(f'/apps/{APP_ID}/model-config')的返回里确认dataset_configs的真实结构再回填。核心就是保证datasets里包含目标 KB 的 id。
7. 解决清单(按顺序排查)
- [ ] 知识库状态为
available(非 indexing/failed/disabled)。 - [ ] Xinference 里 bge-m3
running,uid 固定bge-m3,embedding 实跑返回向量。 - [ ] Dify 模型供应商里 Xinference 连接正常,bge-m3 为默认 Embedding。
- [ ] 知识库详情页「命中测试」能返回相关 chunk。
- [ ] 添加位置正确:Agent 在「上下文/知识库」区添加;工作流拖「知识检索」节点。
- [ ] provider 名 + model uid 未变(Xinference 插件未被卸载重装成别的 uid)。
- [ ] 仍异常时,运行
/opt/workbuddy/scripts_cursor/Dify_专题三_Agent知识库选择/专题三_01_列出知识库.py列状态;必要时运行专题三_02_绑定知识库到Agent.py直接 API 绑定。
八、实战记录(本次部署真实遇到的情况)
问题现象 在本次 Dify + bge-m3 部署中,Agent 应用「播城内部知识库」一开始能正常绑定并检索。但当 Xinference 容器因重启/升级后,再去 Agent 的"上下文/知识库"添加时,原本建好的知识库从下拉列表里消失了、选不到——而知识库页面里它仍显示 available。
根因定位 关键就在专题二强调的那句话:Xinference 容器起来 ≠ 模型在跑。bge-m3 必须显式 launch 才会变成 running 实例;容器重启后 bge-m3 实例不会自动恢复。于是:
- Dify 侧 Xinference 的 bge-m3 虽然"已添加",但实际 embedding 端点不可达;
- 知识库元数据指向
xinference / bge-m3,Dify 判定其 embedding provider 不可用 → 直接在 Agent 选择列表里隐藏该 KB(这正是第 0 节说的"只列可被检索服务调用的 KB")。
解决过程(按实际执行顺序)
- 进 Xinference 确认:
完整脚本:scripts_bash_cursor/Dify_专题三_Agent知识库选择/专题三_内联_02.sh
运行/引用:bash /opt/workbuddy/scripts_bash_cursor/Dify_专题三_Agent知识库选择/专题三_内联_02.sh
#!/usr/bin/env bash
set -euo pipefail
curl 'http://192.168.110.207:9997/v1/models' # 列表里没有 bge-m3 —— 果然没起
- 重新 launch(保持 uid 不变
bge-m3,否则旧 KB 的关联会丢失,更麻烦):
完整脚本:scripts_bash_cursor/Dify_专题三_Agent知识库选择/专题三_内联_03.sh
运行/引用:bash /opt/workbuddy/scripts_bash_cursor/Dify_专题三_Agent知识库选择/专题三_内联_03.sh
#!/usr/bin/env bash
set -euo pipefail
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"}'
- 验证实跑出向量:
完整脚本:scripts_bash_cursor/Dify_专题三_Agent知识库选择/专题三_内联_04.sh
运行/引用:bash /opt/workbuddy/scripts_bash_cursor/Dify_专题三_Agent知识库选择/专题三_内联_04.sh
#!/usr/bin/env bash
set -euo pipefail
curl -X POST 'http://192.168.110.207:9997/v1/embeddings' \
-H 'Content-Type: application/json' \
-d '{"model":"bge-m3","input":"test"}' # 返回 1024 维向量
- 回 Dify:知识库详情页「命中测试」恢复返回相关 chunk。
- 再进 Agent 的"上下文/知识库",原本的知识库重新出现并可选中,检索正常。
怎么重启服务:本步只在 Xinference 侧 launch 模型,无需重启任何 Dify 容器;Dify 按 provider 名 + model uid 关联 KB,模型恢复可达后刷新即可。
怎么看日志: 完整脚本:scripts_bash_cursor/Dify_专题三_Agent知识库选择/专题三_内联_05.sh
运行/引用:bash /opt/workbuddy/scripts_bash_cursor/Dify_专题三_Agent知识库选择/专题三_内联_05.sh
#!/usr/bin/env bash
set -euo pipefail
docker logs xinference 2>&1 | tail -20 # 看 bge-m3 launch 成功日志
docker logs docker-plugin_daemon-1 2>&1 | grep -i bge-m3 # 看 Dify 侧 embedding provider 探测怎么判断正常(逐条核对):
- Xinference 侧
GET /v1/models含bge-m3且状态running; - Dify 知识库详情页「命中测试」恢复返回相关 chunk;
- 再进 Agent 的"上下文/知识库",原本知识库重新出现并可选中,检索正常。
经验沉淀
- 不要误把"Xinference 容器在跑"当成"bge-m3 可用";每次容器重启后都要确认 bge-m3 实例
running。 - 若该容器会频繁重启,建议把 launch bge-m3 做成容器启动后的自动动作(在
docker run里用启动脚本/entrypoint 拉起模型,或在外部守护脚本里检测并自动 launch),避免手动遗漏导致 KB 集体"消失"。 - Agent 里"知识库选不到"优先怀疑 embedding provider 可达性(bge-m3 是否真的在跑、uid 是否一致),而不是 KB 本身被删或索引坏了。
一句话对照:专题三前面七节是"方法论",本节是"本次真实踩到的那个坑"——根因就是 bge-m3 没随容器自起;并补充了"怎么重启 / 怎么看日志 / 怎么判断正常"三个维度,照着即可自查。