[Bug] Hybrid Search in dataset settings cannot persist reranking_enable=true when the retrieval method card is already selected, so rerank silently never runs

未关闭
#42,553 3 条评论 1 个 reaction 已指派 1 人 在 GitHub 查看

@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
  1. Create or open a knowledge base whose indexing technique is High Quality.
  2. In Settings → Retrieval Setting, make sure the Hybrid Search card is already the selected method (i.e. search_method === "hybrid_search").
  3. 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.
  4. Click Save.
  5. 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 onSwitch and correctly persists reranking_enable: true.
  • A knowledge base configured via "open → pick rerank model → Save" never fires onSwitch and silently persists false.

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) where reranking_enable was hardcoded to true. Fixed in #13721 (merged 2025-02-14); not related to the dataset settings form.
  • #26127 — reranking_enable preventing rerank for multi-dataset search. Different surface.
主要语言
TypeScript
星标
157k
派生
24.7k
平均合并
22 小时 32 分钟
30 天内合并 PR
611

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

langgenius/dify 的其他 Issue

查看 langgenius/dify 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。