[Bug] Hybrid Search in dataset settings cannot persist reranking_enable=true when the retrieval method card is already selected, so rerank silently never runs
@Neo1Noir 已经在做这个了。
开始于 2026年9月20日。
评估
这个 Issue 还没有评估数据。
描述
Self Checks
- I have read the Contributing Guide and Language Policy.
- This is only for bug report, if you would like to ask a question, please head to Discussions.
- I have searched for existing issues search for existing issues, including closed ones.
- I confirm that I am using English to submit this report, otherwise it will be closed.
- 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
- Please do not modify this template :) and fill in all the required fields.
Dify version
1.16.1 (also reproducible on latest main)
Cloud or Self Hosted
Self Hosted (Docker)
Steps to reproduce
- Create or open a knowledge base whose indexing technique is High Quality.
- In Settings → Retrieval Setting, make sure the Hybrid Search card is already the selected method (i.e.
search_method === "hybrid_search"). - Under Rerank Model, pick a rerank model. Note that in Hybrid Search mode Dify does not render the rerank on/off
Switch— the only visible control is the model selector. - Click Save.
- Reopen the knowledge base settings, or read the dataset row directly.
✔️ Expected Behavior
After selecting a rerank model and saving, retrieval_model.reranking_enable should be true, and the rerank model should actually be invoked during retrieval.
❌ Actual Behavior
retrieval_model.reranking_enable stays false (the API default), so the rerank model is silently never called.
Observed value persisted after Save — read back from GET /console/api/datasets/{id}:
{
"search_method": "hybrid_search",
"reranking_mode": "reranking_model",
"reranking_model": {
"reranking_provider_name": "<configured provider>",
"reranking_model_name": "<configured rerank model>"
},
"weights": { "weight_type": "customized" },
"top_k": 5,
"score_threshold_enabled": true,
"score_threshold": 0.7,
"reranking_enable": false // <-- expected true; the model is selected and displayed in the UI
}
The UI renders the selected rerank model normally, so there is no visual indication that reranking is off. The result is a knowledge base that looks configured for reranking but never reranks.
Root cause analysis
Writing reranking_enable is currently bound to a side effect of switching the retrieval method card, not to the rerank configuration itself. Four links in the chain:
1. Hybrid Search deliberately hides the rerank toggle
web/app/components/datasets/common/retrieval-param-config/index.tsx:44
const canToggleRerankModalEnable = type !== RETRIEVE_METHOD.hybrid
For type === hybrid, the <Switch checked={value.reranking_enable} …> at line 120 is never rendered. In Hybrid Search there is literally no UI control that can set reranking_enable.
2. OptionCard refuses to fire onClick when the card is already active
web/app/components/datasets/settings/option-card.tsx:60-63
onClick={() => {
if (isActive || disabled) return
onClick?.(id)
}}
Clicking an already-selected card is a no-op.
3. onSwitch is the only writer of reranking_enable — and it only runs on a real method change
web/app/components/datasets/common/retrieval-method-config/index.tsx:63-86
if (retrieveMethod === RETRIEVE_METHOD.hybrid) {
onChange({
...value,
search_method: retrieveMethod,
...(!value.reranking_model.reranking_model_name ||
!value.reranking_model.reranking_provider_name
? {
reranking_model: { /* defaults from isRerankDefaultModelValid */ },
reranking_enable: !!isRerankDefaultModelValid,
reranking_mode: isRerankDefaultModelValid
? RerankingModeEnum.RerankingModel
: RerankingModeEnum.WeightedScore,
}
: {
reranking_enable: true,
reranking_mode: RerankingModeEnum.RerankingModel,
}),
...
})
}
Combined with (2), the only way to reach reranking_enable: true for Hybrid Search is to click a different retrieval method card first, then click back to Hybrid Search.
4. The backend default is false, so the stale value survives the round trip
api/models/dataset.py:353-367
default_retrieval_model = {
"search_method": RetrievalMethod.SEMANTIC_SEARCH,
"reranking_enable": False,
...
}
The save path itself is innocent — retrieval_model is passed through verbatim (api/services/dataset_service.py, _update_internal_dataset), so whatever the frontend sends is what gets persisted. The frontend simply never sends true.
Why this is easy to miss
The bug is masked by the user's own history:
- A knowledge base created by switching method (e.g. Vector → Hybrid) fires
onSwitchand correctly persistsreranking_enable: true. - A knowledge base configured via "open → pick rerank model → Save" never fires
onSwitchand silently persistsfalse.
Two knowledge bases can therefore end up with identical-looking UI state and opposite reranking_enable values. In my case one knowledge base reranked correctly and another silently did not, which is how this was eventually tracked down.
Suggested fix
Decouple reranking_enable from the retrieval-method switch. In Hybrid Search, "a rerank model is configured and reranking_mode === reranking_model" already means the same thing as "reranking is enabled" — web/app/components/datasets/common/check-rerank-model.ts:38-45 validates the save against exactly that predicate. The persisted value should follow.
The smallest consistent change is to derive the field at save time in useFormState.handleSave:
if (
retrievalConfig.reranking_mode === RerankingModeEnum.RerankingModel &&
retrievalConfig.reranking_model?.reranking_model_name
) {
retrievalConfig.reranking_enable = true
}
This keeps the existing product semantics (which check-rerank-model.ts already encodes) and does not introduce a new UI branch. Happy to open a PR if the maintainers agree with this direction.
Related but distinct
- #13668 / #13721 — a different code path (
web/app/components/workflow/nodes/knowledge-retrieval/utils.ts) wherereranking_enablewas hardcoded totrue. Fixed in #13721 (merged 2025-02-14); not related to the dataset settings form. - #26127 —
reranking_enablepreventing rerank for multi-dataset search. Different surface.
- 主要语言
- TypeScript
- 星标
- 157k
- 派生
- 24.7k
- 平均合并
- 22 小时 32 分钟
- 30 天内合并 PR
- 611
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
langgenius/dify 的其他 Issue
-
Annotation Reply: a stored score threshold of 0.0 is silently replaced with 1, disabling the feature 未关闭
难度 2/5 1-3 小时 新手友好度 88/100
langgenius/dify#42639 · 1 条评论 · 1 个 reaction ·
-
难度 2/5 1-3 小时 新手友好度 70/100
langgenius/dify#42468 · 1 条评论 · 1 个 reaction ·
-
🐞 bug
难度 2/5 1-3 小时 新手友好度 86/100
langgenius/dify#42446 · 1 个 reaction ·
-
难度 2/5 1-3 小时 新手友好度 88/100
langgenius/dify#42355 · 1 条评论 · 1 个 reaction ·
-
难度 2/5 1-3 小时 新手友好度 88/100
langgenius/dify#42350 · 1 条评论 · 1 个 reaction ·
相似的 Issue
-
calcite-components needs triage refactor
难度 2/5 1-3 小时 新手友好度 75/100
Esri/calcite-design-system#15203 ·
-
难度 2/5 1-3 小时 新手友好度 91/100
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
难度 1/5 1 小时以内 新手友好度 95/100
-
难度 2/5 1-3 小时 新手友好度 78/100
Automattic/studio#4908 ·
-
难度 2/5 1-3 小时 新手友好度 90/100