diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py
index ec541f5a336..3cb594bdf31 100644
--- a/backend/open_webui/config.py
+++ b/backend/open_webui/config.py
@@ -2296,6 +2296,32 @@ class BannerModel(BaseModel):
"""
+# Retrieval (knowledge base) queries need a different prompt than web search queries:
+# semantic vector search rewards natural-language phrasings over keyword queries.
+RETRIEVAL_QUERY_GENERATION_PROMPT_TEMPLATE = os.getenv('RETRIEVAL_QUERY_GENERATION_PROMPT_TEMPLATE', '')
+
+DEFAULT_RETRIEVAL_QUERY_GENERATION_PROMPT_TEMPLATE = """### Task:
+Analyze the chat history and generate 1-3 search queries optimized for retrieving relevant documents from a knowledge base using semantic vector search.
+
+### Guidelines:
+- Respond **EXCLUSIVELY** with a JSON object.
+- Base queries on the **user's questions and information needs only**. Use assistant responses solely for context and disambiguation (e.g. resolving "that", "it", "the one you mentioned").
+- Generate queries as natural-language phrases that capture the semantic meaning of the user's information need.
+- Reformulate conversational references into standalone, self-contained queries.
+- Each query should target a different aspect or angle to maximize retrieval coverage.
+- If the user's message clearly needs no document retrieval (e.g. greetings), return: { "queries": [] }
+- Respond in the same language as the user's messages.
+- Today's date is: {{CURRENT_DATE}}
+
+### Output:
+{ "queries": ["query1", "query2"] }
+
+### Chat History:
+
+{{MESSAGES:END:4}}
+
+"""
+
ENABLE_AUTOCOMPLETE_GENERATION = os.getenv('ENABLE_AUTOCOMPLETE_GENERATION', 'False').lower() == 'true'
AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH = int(os.getenv('AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH', '-1'))
@@ -3101,6 +3127,7 @@ def feishu_oauth_register(oauth: OAuth):
'task.query.search.enable': ENABLE_SEARCH_QUERY_GENERATION,
'task.query.retrieval.enable': ENABLE_RETRIEVAL_QUERY_GENERATION,
'task.query.prompt_template': QUERY_GENERATION_PROMPT_TEMPLATE,
+ 'task.query.retrieval_prompt_template': RETRIEVAL_QUERY_GENERATION_PROMPT_TEMPLATE,
'task.autocomplete.enable': ENABLE_AUTOCOMPLETE_GENERATION,
'task.autocomplete.input_max_length': AUTOCOMPLETE_GENERATION_INPUT_MAX_LENGTH,
'task.autocomplete.prompt_template': AUTOCOMPLETE_GENERATION_PROMPT_TEMPLATE,
diff --git a/backend/open_webui/routers/tasks.py b/backend/open_webui/routers/tasks.py
index 4e377e2b789..3bf6afdb96d 100644
--- a/backend/open_webui/routers/tasks.py
+++ b/backend/open_webui/routers/tasks.py
@@ -11,6 +11,7 @@
DEFAULT_IMAGE_PROMPT_GENERATION_PROMPT_TEMPLATE,
DEFAULT_MOA_GENERATION_PROMPT_TEMPLATE,
DEFAULT_QUERY_GENERATION_PROMPT_TEMPLATE,
+ DEFAULT_RETRIEVAL_QUERY_GENERATION_PROMPT_TEMPLATE,
DEFAULT_TAGS_GENERATION_PROMPT_TEMPLATE,
DEFAULT_TITLE_GENERATION_PROMPT_TEMPLATE,
DEFAULT_VOICE_MODE_PROMPT_TEMPLATE,
@@ -53,6 +54,7 @@
'ENABLE_SEARCH_QUERY_GENERATION': 'task.query.search.enable',
'ENABLE_RETRIEVAL_QUERY_GENERATION': 'task.query.retrieval.enable',
'QUERY_GENERATION_PROMPT_TEMPLATE': 'task.query.prompt_template',
+ 'RETRIEVAL_QUERY_GENERATION_PROMPT_TEMPLATE': 'task.query.retrieval_prompt_template',
'TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE': 'task.tools.prompt_template',
'ENABLE_VOICE_MODE_PROMPT': 'task.voice.prompt.enable',
'VOICE_MODE_PROMPT_TEMPLATE': 'task.voice.prompt_template',
@@ -96,6 +98,7 @@ class TaskConfigForm(BaseModel):
ENABLE_SEARCH_QUERY_GENERATION: bool
ENABLE_RETRIEVAL_QUERY_GENERATION: bool
QUERY_GENERATION_PROMPT_TEMPLATE: str
+ RETRIEVAL_QUERY_GENERATION_PROMPT_TEMPLATE: str
TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE: str
ENABLE_VOICE_MODE_PROMPT: bool
VOICE_MODE_PROMPT_TEMPLATE: Optional[str]
@@ -441,11 +444,18 @@ async def generate_queries(request: Request, form_data: dict, user=Depends(get_v
log.debug(f'generating {type} queries using model {task_model_id} for user {user.email}')
- query_template = await Config.get('task.query.prompt_template')
- if query_template.strip() != '':
- template = query_template
+ if type == 'retrieval':
+ retrieval_query_template = await Config.get('task.query.retrieval_prompt_template')
+ if retrieval_query_template.strip() != '':
+ template = retrieval_query_template
+ else:
+ template = DEFAULT_RETRIEVAL_QUERY_GENERATION_PROMPT_TEMPLATE
else:
- template = DEFAULT_QUERY_GENERATION_PROMPT_TEMPLATE
+ query_template = await Config.get('task.query.prompt_template')
+ if query_template.strip() != '':
+ template = query_template
+ else:
+ template = DEFAULT_QUERY_GENERATION_PROMPT_TEMPLATE
content = await query_generation_template(template, form_data['messages'], user)
diff --git a/src/lib/components/admin/Settings/Documents.svelte b/src/lib/components/admin/Settings/Documents.svelte
index 3f2911ff36c..2dfd88c2db1 100644
--- a/src/lib/components/admin/Settings/Documents.svelte
+++ b/src/lib/components/admin/Settings/Documents.svelte
@@ -17,6 +17,8 @@
updateRAGConfig
} from '$lib/apis/retrieval';
+ import { getTaskConfig, updateTaskConfig } from '$lib/apis';
+
import { reindexKnowledgeFiles } from '$lib/apis/knowledge';
import { deleteAllFiles } from '$lib/apis/files';
@@ -70,6 +72,8 @@
};
let RAGConfig: any = null;
+ let retrievalQueryPrompt: any = '';
+
const inputClass =
'w-full h-7 rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 text-xs text-gray-700 outline-hidden transition-colors placeholder:text-gray-300 focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:placeholder:text-gray-700 dark:focus:border-blue-500';
const actionButtonClass =
@@ -252,6 +256,15 @@
}
}
+ // Save the retrieval query prompt via the task config API
+ const currentTaskConfig = await getTaskConfig(localStorage.token);
+ if (currentTaskConfig) {
+ await updateTaskConfig(localStorage.token, {
+ ...currentTaskConfig,
+ RETRIEVAL_QUERY_GENERATION_PROMPT_TEMPLATE: retrievalQueryPrompt
+ });
+ }
+
const res = await updateRAGConfig(localStorage.token, {
...RAGConfig,
// Convert null (from cleared number inputs) to empty string so the backend
@@ -340,6 +353,11 @@
config.RAG_TOKENIZER_MODEL = config?.RAG_TOKENIZER_MODEL ?? '';
RAGConfig = config;
+
+ const taskConfig = await getTaskConfig(localStorage.token);
+ if (taskConfig) {
+ retrievalQueryPrompt = taskConfig.RETRIEVAL_QUERY_GENERATION_PROMPT_TEMPLATE ?? '';
+ }
});
@@ -1369,6 +1387,25 @@
{/if}
{/if}
+
+
+
+
+
+