diff --git a/src/khoj/processor/conversation/prompts.py b/src/khoj/processor/conversation/prompts.py index ae4f8230..0738af4e 100644 --- a/src/khoj/processor/conversation/prompts.py +++ b/src/khoj/processor/conversation/prompts.py @@ -487,16 +487,24 @@ Khoj: plan_function_execution = PromptTemplate.from_template( """ -You are an extremely methodical planner. Your goal is to make a plan to execute a function based on the user's query. +You are a smart, methodical researcher. You use the provided data sources to retrieve information to answer the users query. +You carefully create multi-step plans and intelligently iterate on the plan based on the retrieved information to find the requested information. {personality_context} -- You have access to a variety of data sources to help you answer the user's question -- You can use the data sources listed below to collect more relevant information, one at a time. The outputs will be chained. -- You are given multiple iterations to with these data sources to answer the user's question -- You are provided with additional context. If you have enough context to answer the question, then exit execution -- Each query is self-contained and you can use the data source to answer the user's question. There will be no additional data injected between queries, so make sure the query you're asking is answered in the current iteration. -- Limit each query to a *single* intention. For example, do not say "Look up the top city by population and output the GDP." Instead, say "Look up the top city by population." and then "Tell me the GDP of ." - -If you already know the answer to the question, return an empty response, e.g., {{}}. +- Use the data sources provided below, one at a time, if you need to find more information. Their output will be shown to you in the next iteration. +- You are allowed upto {max_iterations} iterations to use these data sources to answer the user's question +- If you have enough information to answer the question, then exit execution by returning an empty response. E.g., {{}} +- Ensure the query contains enough context to retrieve relevant information from the data sources. +- Break down the problem into smaller steps. Some examples are provided below assuming you have access to the notes and online data sources: + - If the user asks for the population of their hometown + 1. Try look up their hometown in their notes + 2. Only then try find the population of the city online. + - If the user asks for their computer's specs + 1. Try find the computer model in their notes + 2. Now look up their computer models spec online + - If the user asks what clothes to carry for their upcoming trip + 1. Find the itinerary of their upcoming trip in their notes + 2. Next find the weather forecast at the destination online + 3. Then find if they mention what clothes they own in their notes Background Context: - Current Date: {day_of_week}, {current_date} @@ -525,10 +533,12 @@ Response: previous_iteration = PromptTemplate.from_template( """ -data_source: {data_source} -query: {query} -summary: {summary} ----""" +# Iteration {index}: +# --- +- data_source: {data_source} +- query: {query} +- summary: {summary} +""" ) pick_relevant_information_collection_tools = PromptTemplate.from_template( diff --git a/src/khoj/routers/research.py b/src/khoj/routers/research.py index fd52142b..2974b511 100644 --- a/src/khoj/routers/research.py +++ b/src/khoj/routers/research.py @@ -54,6 +54,7 @@ async def apick_next_tool( user_name: str = None, agent: Agent = None, previous_iterations: List[InformationCollectionIteration] = None, + max_iterations: int = 5, ): """ Given a query, determine which of the available tools the agent should use in order to answer appropriately. One at a time, and it's able to use subsequent iterations to refine the answer. @@ -72,11 +73,12 @@ async def apick_next_tool( chat_history = construct_chat_history(conversation_history) previous_iterations_history = "" - for iteration in previous_iterations: + for idx, iteration in enumerate(previous_iterations): iteration_data = prompts.previous_iteration.format( query=iteration.query, data_source=iteration.data_source, summary=iteration.summarizedResult, + index=idx + 1, ) previous_iterations_history += iteration_data @@ -104,6 +106,7 @@ async def apick_next_tool( username=username, location=location_data, previous_iterations=previous_iterations_history, + max_iterations=max_iterations, ) chat_model_option = await ConversationAdapters.aget_advanced_conversation_config() @@ -152,10 +155,10 @@ async def execute_information_collection( location: LocationData = None, file_filters: List[str] = [], ): - iteration = 0 + current_iteration = 0 MAX_ITERATIONS = 2 previous_iterations: List[InformationCollectionIteration] = [] - while iteration < MAX_ITERATIONS: + while current_iteration < MAX_ITERATIONS: online_results: Dict = dict() compiled_references: List[Any] = [] @@ -164,7 +167,15 @@ async def execute_information_collection( result: str = "" this_iteration = await apick_next_tool( - query, conversation_history, subscribed, uploaded_image_url, location, user_name, agent, previous_iterations + query, + conversation_history, + subscribed, + uploaded_image_url, + location, + user_name, + agent, + previous_iterations, + MAX_ITERATIONS, ) if this_iteration.data_source == ConversationCommand.Notes: ## Extract Document References @@ -291,9 +302,9 @@ async def execute_information_collection( # ) # ) else: - iteration = MAX_ITERATIONS + current_iteration = MAX_ITERATIONS - iteration += 1 + current_iteration += 1 if compiled_references or online_results: results_data = f"**Results**:\n" @@ -302,8 +313,8 @@ async def execute_information_collection( if online_results: results_data += f"**Online Results**: {online_results}\n" - intermediate_result = await extract_relevant_info(this_iteration.query, results_data, agent) - this_iteration.summarizedResult = intermediate_result + # intermediate_result = await extract_relevant_info(this_iteration.query, results_data, agent) + this_iteration.summarizedResult = results_data previous_iterations.append(this_iteration) yield this_iteration diff --git a/src/khoj/utils/helpers.py b/src/khoj/utils/helpers.py index 25243a27..9ed8ffa2 100644 --- a/src/khoj/utils/helpers.py +++ b/src/khoj/utils/helpers.py @@ -346,9 +346,9 @@ tool_descriptions_for_llm = { } function_calling_description_for_llm = { - ConversationCommand.Notes: "Use this if you think the user's personal knowledge base contains relevant context.", - ConversationCommand.Online: "Use this if you think the there's important information on the internet related to the query.", - ConversationCommand.Webpage: "Use this if the user has provided a webpage URL or you are share of a webpage URL that will help you directly answer this query", + ConversationCommand.Notes: "To search the user's personal knowledge base. Especially helpful if the question expects context from the user's notes or documents.", + ConversationCommand.Online: "To search for the latest, up-to-date information from the internet.", + ConversationCommand.Webpage: "To use if the user has directly provided the webpage urls or you are certain of the webpage urls to read.", } mode_descriptions_for_llm = {