Skip to content

Commit

Permalink
Added ability to use a tag to insert the current datetime in prompts (#…
Browse files Browse the repository at this point in the history
…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>
  • Loading branch information
hagen-danswer and yuhongsun96 authored Jan 22, 2025
1 parent b9c29f2 commit 3e58cf2
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 42 deletions.
20 changes: 12 additions & 8 deletions backend/onyx/chat/prompt_builder/answer_prompt_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
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
Expand All @@ -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(
Expand All @@ -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

Expand Down
9 changes: 5 additions & 4 deletions backend/onyx/chat/prompt_builder/citations_prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
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,
Expand Down Expand Up @@ -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(
Expand Down
9 changes: 5 additions & 4 deletions backend/onyx/chat/prompt_builder/quotes_prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
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(
Expand Down Expand Up @@ -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(
Expand Down
46 changes: 29 additions & 17 deletions backend/onyx/prompts/prompt_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@
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(
Expand All @@ -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(
Expand Down
10 changes: 5 additions & 5 deletions backend/onyx/seeding/prompts.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand All @@ -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
Expand All @@ -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.
Expand All @@ -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!
Expand Down
6 changes: 2 additions & 4 deletions backend/onyx/server/features/persona/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)
Expand Down Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions backend/onyx/server/features/persona/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions backend/tests/integration/common_utils/managers/persona.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def create(
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,
Expand All @@ -46,6 +47,7 @@ def create(
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,
Expand Down Expand Up @@ -104,6 +106,7 @@ def edit(
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,
Expand All @@ -121,6 +124,7 @@ def edit(
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,
Expand Down
12 changes: 12 additions & 0 deletions web/src/app/admin/assistants/AssistantEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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"
Expand Down
4 changes: 4 additions & 0 deletions web/src/app/admin/assistants/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -105,6 +107,7 @@ function buildPersonaUpsertRequest(
is_public,
groups,
existing_prompt_id,
datetime_aware,
users,
tool_ids,
icon_color,
Expand All @@ -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] : [],
Expand Down

0 comments on commit 3e58cf2

Please sign in to comment.