Added ability to use a tag to insert the current datetime in prompts (#3697)

* Added ability to use a tag to insert the current datetime in prompts

* made tagging logic more robust

* rename

* k

---------

Co-authored-by: Yuhong Sun <yuhongsun96@gmail.com>
This commit is contained in:
hagen-danswer 2025-01-22 08:17:20 -08:00 committed by GitHub
parent b9c29f2a36
commit 3e58cf2667
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 79 additions and 42 deletions

View File

@ -18,8 +18,8 @@ from onyx.llm.utils import message_to_prompt_and_imgs
from onyx.natural_language_processing.utils import get_tokenizer
from onyx.prompts.chat_prompts import CHAT_USER_CONTEXT_FREE_PROMPT
from onyx.prompts.direct_qa_prompts import HISTORY_BLOCK
from onyx.prompts.prompt_utils import add_date_time_to_prompt
from onyx.prompts.prompt_utils import drop_messages_history_overflow
from onyx.prompts.prompt_utils import handle_onyx_date_awareness
from onyx.tools.force import ForceUseTool
from onyx.tools.models import ToolCallFinalResult
from onyx.tools.models import ToolCallKickoff
@ -31,15 +31,16 @@ def default_build_system_message(
prompt_config: PromptConfig,
) -> SystemMessage | None:
system_prompt = prompt_config.system_prompt.strip()
if prompt_config.datetime_aware:
system_prompt = add_date_time_to_prompt(prompt_str=system_prompt)
tag_handled_prompt = handle_onyx_date_awareness(
system_prompt,
prompt_config,
add_additional_info_if_no_tag=prompt_config.datetime_aware,
)
if not system_prompt:
if not tag_handled_prompt:
return None
system_msg = SystemMessage(content=system_prompt)
return system_msg
return SystemMessage(content=tag_handled_prompt)
def default_build_user_message(
@ -64,8 +65,11 @@ def default_build_user_message(
else user_query
)
user_prompt = user_prompt.strip()
tag_handled_prompt = handle_onyx_date_awareness(user_prompt, prompt_config)
user_msg = HumanMessage(
content=build_content_with_imgs(user_prompt, files) if files else user_prompt
content=build_content_with_imgs(tag_handled_prompt, files)
if files
else tag_handled_prompt
)
return user_msg

View File

@ -21,9 +21,9 @@ from onyx.prompts.constants import DEFAULT_IGNORE_STATEMENT
from onyx.prompts.direct_qa_prompts import CITATIONS_PROMPT
from onyx.prompts.direct_qa_prompts import CITATIONS_PROMPT_FOR_TOOL_CALLING
from onyx.prompts.direct_qa_prompts import HISTORY_BLOCK
from onyx.prompts.prompt_utils import add_date_time_to_prompt
from onyx.prompts.prompt_utils import build_complete_context_str
from onyx.prompts.prompt_utils import build_task_prompt_reminders
from onyx.prompts.prompt_utils import handle_onyx_date_awareness
from onyx.prompts.token_counts import ADDITIONAL_INFO_TOKEN_CNT
from onyx.prompts.token_counts import (
CHAT_USER_PROMPT_WITH_CONTEXT_OVERHEAD_TOKEN_CNT,
@ -127,10 +127,11 @@ def build_citations_system_message(
system_prompt = prompt_config.system_prompt.strip()
if prompt_config.include_citations:
system_prompt += REQUIRE_CITATION_STATEMENT
if prompt_config.datetime_aware:
system_prompt = add_date_time_to_prompt(prompt_str=system_prompt)
tag_handled_prompt = handle_onyx_date_awareness(
system_prompt, prompt_config, add_additional_info_if_no_tag=True
)
return SystemMessage(content=system_prompt)
return SystemMessage(content=tag_handled_prompt)
def build_citations_user_message(

View File

@ -9,8 +9,8 @@ from onyx.llm.utils import message_to_prompt_and_imgs
from onyx.prompts.direct_qa_prompts import CONTEXT_BLOCK
from onyx.prompts.direct_qa_prompts import HISTORY_BLOCK
from onyx.prompts.direct_qa_prompts import JSON_PROMPT
from onyx.prompts.prompt_utils import add_date_time_to_prompt
from onyx.prompts.prompt_utils import build_complete_context_str
from onyx.prompts.prompt_utils import handle_onyx_date_awareness
def _build_strong_llm_quotes_prompt(
@ -39,10 +39,11 @@ def _build_strong_llm_quotes_prompt(
language_hint_or_none=LANGUAGE_HINT.strip() if use_language_hint else "",
).strip()
if prompt.datetime_aware:
full_prompt = add_date_time_to_prompt(prompt_str=full_prompt)
tag_handled_prompt = handle_onyx_date_awareness(
full_prompt, prompt, add_additional_info_if_no_tag=True
)
return HumanMessage(content=full_prompt)
return HumanMessage(content=tag_handled_prompt)
def build_quotes_user_message(

View File

@ -19,9 +19,8 @@ from onyx.utils.logger import setup_logger
logger = setup_logger()
MOST_BASIC_PROMPT = "You are a helpful AI assistant."
DANSWER_DATETIME_REPLACEMENT = "DANSWER_DATETIME_REPLACEMENT"
BASIC_TIME_STR = "The current date is {datetime_info}."
_DANSWER_DATETIME_REPLACEMENT_PAT = "[[CURRENT_DATETIME]]"
_BASIC_TIME_STR = "The current date is {datetime_info}."
def get_current_llm_day_time(
@ -38,23 +37,36 @@ def get_current_llm_day_time(
return f"{formatted_datetime}"
def add_date_time_to_prompt(prompt_str: str) -> str:
if DANSWER_DATETIME_REPLACEMENT in prompt_str:
def build_date_time_string() -> str:
return ADDITIONAL_INFO.format(
datetime_info=_BASIC_TIME_STR.format(datetime_info=get_current_llm_day_time())
)
def handle_onyx_date_awareness(
prompt_str: str,
prompt_config: PromptConfig,
add_additional_info_if_no_tag: bool = False,
) -> str:
"""
If there is a [[CURRENT_DATETIME]] tag, replace it with the current date and time no matter what.
If the prompt is datetime aware, and there are no [[CURRENT_DATETIME]] tags, add it to the prompt.
do nothing otherwise.
This can later be expanded to support other tags.
"""
if _DANSWER_DATETIME_REPLACEMENT_PAT in prompt_str:
return prompt_str.replace(
DANSWER_DATETIME_REPLACEMENT,
_DANSWER_DATETIME_REPLACEMENT_PAT,
get_current_llm_day_time(full_sentence=False, include_day_of_week=True),
)
if prompt_str:
return prompt_str + ADDITIONAL_INFO.format(
datetime_info=get_current_llm_day_time()
)
else:
return (
MOST_BASIC_PROMPT
+ " "
+ BASIC_TIME_STR.format(datetime_info=get_current_llm_day_time())
)
any_tag_present = any(
_DANSWER_DATETIME_REPLACEMENT_PAT in text
for text in [prompt_str, prompt_config.system_prompt, prompt_config.task_prompt]
)
if add_additional_info_if_no_tag and not any_tag_present:
return prompt_str + build_date_time_string()
return prompt_str
def build_task_prompt_reminders(

View File

@ -8,7 +8,7 @@ prompts:
# System Prompt (as shown in UI)
system: >
You are a question answering system that is constantly learning and improving.
The current date is DANSWER_DATETIME_REPLACEMENT.
The current date is [[CURRENT_DATETIME]].
You can process and comprehend vast amounts of text and utilize this knowledge to provide
grounded, accurate, and concise answers to diverse queries.
@ -24,7 +24,7 @@ prompts:
If there are no relevant documents, refer to the chat history and your internal knowledge.
# Inject a statement at the end of system prompt to inform the LLM of the current date/time
# If the DANSWER_DATETIME_REPLACEMENT is set, the date/time is inserted there instead
# If the [[CURRENT_DATETIME]] is set, the date/time is inserted there instead
# Format looks like: "October 16, 2023 14:30"
datetime_aware: true
# Prompts the LLM to include citations in the for [1], [2] etc.
@ -51,7 +51,7 @@ prompts:
- name: "OnlyLLM"
description: "Chat directly with the LLM!"
system: >
You are a helpful AI assistant. The current date is DANSWER_DATETIME_REPLACEMENT
You are a helpful AI assistant. The current date is [[CURRENT_DATETIME]]
You give concise responses to very simple questions, but provide more thorough responses to
@ -69,7 +69,7 @@ prompts:
system: >
You are a text summarizing assistant that highlights the most important knowledge from the
context provided, prioritizing the information that relates to the user query.
The current date is DANSWER_DATETIME_REPLACEMENT.
The current date is [[CURRENT_DATETIME]].
You ARE NOT creative and always stick to the provided documents.
If there are no documents, refer to the conversation history.
@ -87,7 +87,7 @@ prompts:
description: "Recites information from retrieved context! Least creative but most safe!"
system: >
Quote and cite relevant information from provided context based on the user query.
The current date is DANSWER_DATETIME_REPLACEMENT.
The current date is [[CURRENT_DATETIME]].
You only provide quotes that are EXACT substrings from provided documents!

View File

@ -192,8 +192,7 @@ def create_persona(
name=build_prompt_name_from_persona_name(persona_upsert_request.name),
system_prompt=persona_upsert_request.system_prompt,
task_prompt=persona_upsert_request.task_prompt,
# TODO: The PersonaUpsertRequest should provide the value for datetime_aware
datetime_aware=False,
datetime_aware=persona_upsert_request.datetime_aware,
include_citations=persona_upsert_request.include_citations,
prompt_id=prompt_id,
)
@ -237,8 +236,7 @@ def update_persona(
db_session=db_session,
user=user,
name=build_prompt_name_from_persona_name(persona_upsert_request.name),
# TODO: The PersonaUpsertRequest should provide the value for datetime_aware
datetime_aware=False,
datetime_aware=persona_upsert_request.datetime_aware,
system_prompt=persona_upsert_request.system_prompt,
task_prompt=persona_upsert_request.task_prompt,
include_citations=persona_upsert_request.include_citations,

View File

@ -60,6 +60,7 @@ class PersonaUpsertRequest(BaseModel):
description: str
system_prompt: str
task_prompt: str
datetime_aware: bool
document_set_ids: list[int]
num_chunks: float
include_citations: bool

View File

@ -26,6 +26,7 @@ class PersonaManager:
is_public: bool = True,
llm_filter_extraction: bool = True,
recency_bias: RecencyBiasSetting = RecencyBiasSetting.AUTO,
datetime_aware: bool = False,
prompt_ids: list[int] | None = None,
document_set_ids: list[int] | None = None,
tool_ids: list[int] | None = None,
@ -46,6 +47,7 @@ class PersonaManager:
description=description,
system_prompt=system_prompt,
task_prompt=task_prompt,
datetime_aware=datetime_aware,
include_citations=include_citations,
num_chunks=num_chunks,
llm_relevance_filter=llm_relevance_filter,
@ -104,6 +106,7 @@ class PersonaManager:
is_public: bool | None = None,
llm_filter_extraction: bool | None = None,
recency_bias: RecencyBiasSetting | None = None,
datetime_aware: bool = False,
prompt_ids: list[int] | None = None,
document_set_ids: list[int] | None = None,
tool_ids: list[int] | None = None,
@ -121,6 +124,7 @@ class PersonaManager:
description=description or persona.description,
system_prompt=system_prompt,
task_prompt=task_prompt,
datetime_aware=datetime_aware,
include_citations=include_citations,
num_chunks=num_chunks or persona.num_chunks,
llm_relevance_filter=llm_relevance_filter or persona.llm_relevance_filter,

View File

@ -221,6 +221,7 @@ export function AssistantEditor({
const initialValues = {
name: existingPersona?.name ?? "",
description: existingPersona?.description ?? "",
datetime_aware: existingPrompt?.datetime_aware ?? false,
system_prompt: existingPrompt?.system_prompt ?? "",
task_prompt: existingPrompt?.task_prompt ?? "",
is_public: existingPersona?.is_public ?? defaultPublic,
@ -1372,6 +1373,17 @@ export function AssistantEditor({
</div>
<Separator />
<BooleanFormField
small
removeIndent
alignTop
name="datetime_aware"
label="Date and Time Aware"
subtext='Toggle this option to let the assistant know the current date and time (formatted like: "Thursday Jan 1, 1970 00:01"). To inject it in a specific place in the prompt, use the pattern [[CURRENT_DATETIME]]'
/>
<Separator />
<TextFormField
maxWidth="max-w-4xl"
name="task_prompt"

View File

@ -6,6 +6,7 @@ interface PersonaUpsertRequest {
description: string;
system_prompt: string;
task_prompt: string;
datetime_aware: boolean;
document_set_ids: number[];
num_chunks: number | null;
include_citations: boolean;
@ -36,6 +37,7 @@ export interface PersonaUpsertParameters {
system_prompt: string;
existing_prompt_id: number | null;
task_prompt: string;
datetime_aware: boolean;
document_set_ids: number[];
num_chunks: number | null;
include_citations: boolean;
@ -105,6 +107,7 @@ function buildPersonaUpsertRequest(
is_public,
groups,
existing_prompt_id,
datetime_aware,
users,
tool_ids,
icon_color,
@ -129,6 +132,7 @@ function buildPersonaUpsertRequest(
icon_shape,
remove_image,
search_start_date,
datetime_aware,
is_default_persona: creationRequest.is_default_persona ?? false,
recency_bias: "base_decay",
prompt_ids: existing_prompt_id ? [existing_prompt_id] : [],