From bc7b864a6c6c22c939c21655f947a1df5875f31e Mon Sep 17 00:00:00 2001
From: LIRUI YU <128563231+LiruiYu33@users.noreply.github.com>
Date: Thu, 22 Jan 2026 15:33:42 +0800
Subject: [PATCH] top_k parameter ignored, always returned page_size results
(#12753)
### What problem does this PR solve?
**Backend**
\rag\nlp\search.py
*Before the fix*
The top_k parameter was not applied to limit the total number of chunks,
and the rerank model also uses the exact whole valid_idx rather than
assigning valid_idx = valid_idx[:top] firstly.
*After the fix*
The top_k limit is applied to the total results before pagination, using
a default value of top = 1024 if top_k is not modified.
session.py
*Before the fix:*
When the frontend calls the retrieval API with `search_id`, the backend
only reads `meta_data_filter` from the saved `search_config`. The
`rerank_id`, `top_k`, `similarity_threshold`, and
`vector_similarity_weight` parameters are only taken from the direct
request body. Since the frontend doesn't pass these parameters
explicitly (it only passes `search_id`), they always fall back to
default values:
- `similarity_threshold` = 0.0
- `vector_similarity_weight` = 0.3
- `top_k` = 1024
- `rerank_id` = "" (no rerank)
This means user settings saved in the Search Settings page have no
effect on actual search results.
*After the fix:*
When a `search_id` is provided, the backend now reads all relevant
configuration from the saved `search_config`, including `rerank_id`,
`top_k`, `similarity_threshold`, and `vector_similarity_weight`. Request
parameters can still override these values if explicitly provided,
allowing flexibility. The rerank model is now properly instantiated
using the configured `rerank_id`, making the rerank feature actually
work.
**Frontend**
\web\src\pages\next-search\search-setting.tsx
*Before the fix*
search-setting.tsx file, the top_k input box is only displayed when
rerank is enabled (wrapped in the rerankModelDisabled condition). If the
rerank switch is turned off, the top_k input field will be hidden, but
the form value will remain unchanged. In other words: - When rerank is
enabled, users can modify top_k (default 1024). - When rerank is
disabled, top_k retains the previous value, but it's not visible on the
interface. Therefore, the backend will always receive the top_k
parameter; it's just that the frontend UI binds this configuration item
to the rerank switch. When rerank is turned off, top_k will not
automatically reset to 1024, but will retain its original value.
*After the fix*
On the contrary, if we switch off the button rerank model, the value
top-k will be reset to 1024. By the way, If we use top-k in an
individual method, rather than put it into the method retrieval, we can
control it separately
Now all methods valid
Using rerank
Not using rerank
Before fixing they are the same
### Type of change
- Bug Fix (non-breaking change which fixes an issue)
---
api/apps/sdk/session.py | 15 +++++++++++++--
web/src/pages/next-search/search-setting.tsx | 12 +++++++++++-
2 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/api/apps/sdk/session.py b/api/apps/sdk/session.py
index db388a0d9..36b407cea 100644
--- a/api/apps/sdk/session.py
+++ b/api/apps/sdk/session.py
@@ -1049,11 +1049,13 @@ async def retrieval_test_embedded():
use_kg = req.get("use_kg", False)
top = int(req.get("top_k", 1024))
langs = req.get("cross_languages", [])
+ rerank_id = req.get("rerank_id", "")
tenant_id = objs[0].tenant_id
if not tenant_id:
return get_error_data_result(message="permission denined.")
async def _retrieval():
+ nonlocal similarity_threshold, vector_similarity_weight, top, rerank_id
local_doc_ids = list(doc_ids) if doc_ids else []
tenant_ids = []
_question = question
@@ -1065,6 +1067,15 @@ async def retrieval_test_embedded():
meta_data_filter = search_config.get("meta_data_filter", {})
if meta_data_filter.get("method") in ["auto", "semi_auto"]:
chat_mdl = LLMBundle(tenant_id, LLMType.CHAT, llm_name=search_config.get("chat_id", ""))
+ # Apply search_config settings if not explicitly provided in request
+ if not req.get("similarity_threshold"):
+ similarity_threshold = float(search_config.get("similarity_threshold", similarity_threshold))
+ if not req.get("vector_similarity_weight"):
+ vector_similarity_weight = float(search_config.get("vector_similarity_weight", vector_similarity_weight))
+ if not req.get("top_k"):
+ top = int(search_config.get("top_k", top))
+ if not req.get("rerank_id"):
+ rerank_id = search_config.get("rerank_id", "")
else:
meta_data_filter = req.get("meta_data_filter") or {}
if meta_data_filter.get("method") in ["auto", "semi_auto"]:
@@ -1094,8 +1105,8 @@ async def retrieval_test_embedded():
embd_mdl = LLMBundle(kb.tenant_id, LLMType.EMBEDDING.value, llm_name=kb.embd_id)
rerank_mdl = None
- if req.get("rerank_id"):
- rerank_mdl = LLMBundle(kb.tenant_id, LLMType.RERANK.value, llm_name=req["rerank_id"])
+ if rerank_id:
+ rerank_mdl = LLMBundle(kb.tenant_id, LLMType.RERANK.value, llm_name=rerank_id)
if req.get("keyword", False):
chat_mdl = LLMBundle(kb.tenant_id, LLMType.CHAT)
diff --git a/web/src/pages/next-search/search-setting.tsx b/web/src/pages/next-search/search-setting.tsx
index 6b08bf184..c0bf71b9c 100644
--- a/web/src/pages/next-search/search-setting.tsx
+++ b/web/src/pages/next-search/search-setting.tsx
@@ -39,7 +39,7 @@ import { IKnowledge } from '@/interfaces/database/knowledge';
import { cn } from '@/lib/utils';
import { zodResolver } from '@hookform/resolvers/zod';
import { X } from 'lucide-react';
-import { useCallback, useEffect, useMemo, useState } from 'react';
+import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useForm, useWatch } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { z } from 'zod';
@@ -226,11 +226,21 @@ const SearchSetting: React.FC = ({
control: formMethods.control,
name: 'search_config.use_rerank',
});
+
const aiSummaryDisabled = useWatch({
control: formMethods.control,
name: 'search_config.summary',
});
+ // Reset top_k to 1024 only when user actively disables rerank (from true to false)
+ const prevRerankEnabled = useRef(undefined);
+ useEffect(() => {
+ if (prevRerankEnabled.current === true && rerankModelDisabled === false) {
+ formMethods.setValue('search_config.top_k', 1024);
+ }
+ prevRerankEnabled.current = rerankModelDisabled;
+ }, [rerankModelDisabled, formMethods]);
+
const { updateSearch } = useUpdateSearch();
const [formSubmitLoading, setFormSubmitLoading] = useState(false);
const { data: systemSetting } = useFetchTenantInfo();