[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分
- マージ済み PR(30日)
- 611
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- 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 件 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
langgenius/dify#42468 · コメント 1 件 · リアクション 1 件 ·
-
🐞 bug
難易度 2/5 1〜3時間 初心者へのやさしさ 86/100
langgenius/dify#42446 · リアクション 1 件 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
langgenius/dify#42355 · コメント 1 件 · リアクション 1 件 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
langgenius/dify#42350 · コメント 1 件 · リアクション 1 件 ·
langgenius/dify の issue をすべて見る
似ている 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