From b2af8b887441af0ea8f1376e1d287ffdcb6f33a1 Mon Sep 17 00:00:00 2001 From: Liqun Li Date: Mon, 15 Jul 2024 16:05:05 +0800 Subject: [PATCH 1/4] refine prompt and add context --- project/planner_examples/example-planner.yaml | 22 +++++++++---------- .../code_interpreter/code_generator.py | 4 ++++ .../code_generator_prompt.yaml | 5 ++++- taskweaver/planner/planner.py | 4 ++++ taskweaver/planner/planner_prompt.yaml | 18 ++++++++++----- 5 files changed, 36 insertions(+), 17 deletions(-) diff --git a/project/planner_examples/example-planner.yaml b/project/planner_examples/example-planner.yaml index 29b741b9..1efc4ec0 100644 --- a/project/planner_examples/example-planner.yaml +++ b/project/planner_examples/example-planner.yaml @@ -13,15 +13,15 @@ rounds: attachment_list: - type: init_plan content: |- - 1. load the data file - 2. count the rows of the loaded data - 3. report the result to the user + 1. Load the data file + 2. Count the rows of the loaded data + 3. Check the execution result and report the result to the user - type: plan content: |- - 1. instruct CodeInterpreter to load the data file and count the rows of the loaded data - 2. report the result to the user + 1. Instruct CodeInterpreter to load the data file and count the rows of the loaded data + 2. Check the execution result and report the result to the user if it is correct - type: current_plan_step - content: 1. instruct CodeInterpreter to load the data file and count the rows of the loaded data + content: 1. Instruct CodeInterpreter to load the data file and count the rows of the loaded data - message: Load the data file /home/data.csv successfully and there are 100 rows in the data file send_from: CodeInterpreter send_to: Planner @@ -32,12 +32,12 @@ rounds: attachment_list: - type: init_plan content: |- - 1. load the data file - 2. count the rows of the loaded data - 3. report the result to the user + 1. Load the data file + 2. Count the rows of the loaded data + 3. Check the execution result and report the result to the user - type: plan content: |- - 1. instruct CodeInterpreter to load the data file and count the rows of the loaded data - 2. report the result to the user + 1. Instruct CodeInterpreter to load the data file and count the rows of the loaded data + 2. Check the execution result and report the result to the user if it is correct - type: current_plan_step content: 2. report the result to the user \ No newline at end of file diff --git a/taskweaver/code_interpreter/code_interpreter/code_generator.py b/taskweaver/code_interpreter/code_interpreter/code_generator.py index de7a9007..9ff61ccb 100644 --- a/taskweaver/code_interpreter/code_interpreter/code_generator.py +++ b/taskweaver/code_interpreter/code_interpreter/code_generator.py @@ -1,5 +1,6 @@ import json import os +from datetime import date from typing import List, Optional from injector import inject @@ -93,7 +94,10 @@ def __init__( self.code_verification_on: bool = False self.allowed_modules: List[str] = [] + current_date = date.today() + day_of_week = current_date.strftime("%A") self.instruction = self.instruction_template.format( + ENVIRONMENT_CONTEXT=f"- Today is {current_date}.\n- It is {day_of_week}.\n", ROLE_NAME=self.role_name, RESPONSE_JSON_SCHEMA=json.dumps(self.response_json_schema), ) diff --git a/taskweaver/code_interpreter/code_interpreter/code_generator_prompt.yaml b/taskweaver/code_interpreter/code_interpreter/code_generator_prompt.yaml index db97230d..4d394d76 100644 --- a/taskweaver/code_interpreter/code_interpreter/code_generator_prompt.yaml +++ b/taskweaver/code_interpreter/code_interpreter/code_generator_prompt.yaml @@ -1,5 +1,8 @@ -version: 0.1 +version: 0.2 content: |- + ## On current environment context: + {ENVIRONMENT_CONTEXT} + ## On conversations: - Each conversation starts with "==============================\n## Conversation Start" - Each conversation has multiple rounds, each round starts with "-----------------------------" diff --git a/taskweaver/planner/planner.py b/taskweaver/planner/planner.py index 77c9e268..d6a10b71 100644 --- a/taskweaver/planner/planner.py +++ b/taskweaver/planner/planner.py @@ -1,6 +1,7 @@ import json import os import types +from datetime import date from json import JSONDecodeError from typing import Dict, Iterable, List, Optional @@ -121,7 +122,10 @@ def compose_sys_prompt(self): f'- The message from {alias} will start with "From: {alias}"\n' ) + current_date = date.today() + day_of_week = current_date.strftime("%A") instruction = self.instruction_template.format( + environment_context=f"- Today is {current_date}\n- It is {day_of_week}.\n", response_json_schema=json.dumps(self.response_json_schema), worker_intro=worker_description, ) diff --git a/taskweaver/planner/planner_prompt.yaml b/taskweaver/planner/planner_prompt.yaml index cc8a6bf0..cc616894 100644 --- a/taskweaver/planner/planner_prompt.yaml +++ b/taskweaver/planner/planner_prompt.yaml @@ -1,7 +1,10 @@ -version: 0.2 +version: 0.3 instruction_template: |- You are the Planner who can coordinate Workers to finish the user task. + ## About the current environment context + {environment_context} + ## About conversation history - There could be multiple Conversations in the chat history - Each Conversation starts with the User query "Let's start a new conversation!". @@ -27,6 +30,7 @@ instruction_template: |- - Planner should ignore the permission or file access issues since Workers are powerful and can handle them. - Planner needs to inform Workers on the User's request and the current step. - Planner must reject the User's request if it contains potential security risks or illegal activities. + - Planner must check the Worker's response and provide feedback to the Worker if the response is incorrect or incomplete. ## Planner's planning process You need to make a step-by-step plan to complete the User's task. The planning process includes 2 phases: "init_plan" and "plan". @@ -54,17 +58,21 @@ instruction_template: |- init_plan: 1. Read ./data.csv file 2. Count the rows of the loaded data + 3. Check the execution result and report the result to the user plan: 1. Read ./data.csv file and count the rows of the loaded data + 2. Check the execution result and report the result to the user [Example 2] User: Read a manual file and follow the instructions in it. init_plan: 1. Read the file content and show its content to the user 2. Follow the instructions based on the file content. + 3. Confirm the completion of the instructions and report the result to the user plan: 1. Read the file content and show its content to the user 2. follow the instructions based on the file content. + 3. Confirm the completion of the instructions and report the result to the user [Example 3] User: detect anomaly on ./data.csv @@ -72,11 +80,11 @@ instruction_template: |- 1. Read the ./data.csv and show me the top 5 rows to understand the data schema 2. Confirm the columns to be detected anomalies 3. Detect anomalies on the loaded data - 4. Report the detected anomalies to the user + 4. Check the execution result and report the detected anomalies to the user plan: 1. Read the ./data.csv and show me the top 5 rows to understand the data schema and confirm the columns to be detected anomalies 2. Detect anomalies on the loaded data - 3. Report the detected anomalies to the user + 3. Check the execution result and report the detected anomalies to the user [Example 4] User: read a.csv and b.csv and join them together @@ -85,11 +93,11 @@ instruction_template: |- 2. Load b.csv as dataframe and show me the top 5 rows to understand the data schema 3. Ask which column to join 4. Join the two dataframes - 5. report the result to the user + 5. Check the execution result and report the joined data to the user plan: 1. Load a.csv and b.csv as dataframes, show me the top 5 rows to understand the data schema, and ask which column to join 2. Join the two dataframes - 3. report the result to the user + 3. Check the execution result and report the joined data to the user ## Useful Tips - When the request involves loading a file, Planner should always set the first subtask to reading the file content to understand the structure or schema of the data. From 85317899d08e9ff32a92fef7bca39eece720a2d6 Mon Sep 17 00:00:00 2001 From: Liqun Li Date: Tue, 16 Jul 2024 10:49:27 +0800 Subject: [PATCH 2/4] fix bug --- auto_eval/evaluator.py | 10 ++++++++++ .../code_generator_cli_only.py | 3 ++- .../code_interpreter_cli_only.py | 6 +++--- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/auto_eval/evaluator.py b/auto_eval/evaluator.py index 37d4c733..1c73f002 100644 --- a/auto_eval/evaluator.py +++ b/auto_eval/evaluator.py @@ -9,6 +9,7 @@ from langchain.load import dumps from langchain.schema.messages import AIMessage, HumanMessage, SystemMessage from langchain_community.chat_models import ChatOpenAI +from langchain_google_genai import ChatGoogleGenerativeAI from langchain_openai import AzureChatOpenAI EVALUATOR_PROMPT_FILE_PATH = os.path.join(os.path.dirname(__file__), "evaluator_prompt.yaml") @@ -56,6 +57,15 @@ def config_llm(config: Dict[str, str]) -> Union[ChatOpenAI, AzureChatOpenAI]: temperature=0, verbose=True, ) + elif api_type == "google": + os.environ["GOOGLE_API_KEY"] = get_config(config, "llm.api_key") + model = ChatGoogleGenerativeAI( + temperature=0, + model=get_config(config, "llm.model"), + verbose=True, + convert_system_message_to_human=True, + ) + else: raise ValueError("Invalid API type. Please check your config file.") return model diff --git a/taskweaver/code_interpreter/code_interpreter_cli_only/code_generator_cli_only.py b/taskweaver/code_interpreter/code_interpreter_cli_only/code_generator_cli_only.py index 88e49271..7046a464 100644 --- a/taskweaver/code_interpreter/code_interpreter_cli_only/code_generator_cli_only.py +++ b/taskweaver/code_interpreter/code_interpreter_cli_only/code_generator_cli_only.py @@ -136,7 +136,8 @@ def reply( llm_response["code"] = f"powershell -Command {llm_response['code']}" post_proxy.update_attachment(llm_response["description"], AttachmentType.thought) - post_proxy.update_attachment(llm_response["code"], AttachmentType.python) + post_proxy.update_attachment("python", AttachmentType.reply_type) + post_proxy.update_attachment(llm_response["code"], AttachmentType.reply_content) self.tracing.set_span_attribute("code", llm_response["code"]) diff --git a/taskweaver/code_interpreter/code_interpreter_cli_only/code_interpreter_cli_only.py b/taskweaver/code_interpreter/code_interpreter_cli_only/code_interpreter_cli_only.py index 9a599431..a4979a52 100644 --- a/taskweaver/code_interpreter/code_interpreter_cli_only/code_interpreter_cli_only.py +++ b/taskweaver/code_interpreter/code_interpreter_cli_only/code_interpreter_cli_only.py @@ -41,10 +41,10 @@ def __init__( self.return_index = 0 self.logger.info(f"{self.alias} initialized successfully.") - + def update_session_variables(self, session_variables: dict) -> None: assert False, "Not implemented" - + @tracing_decorator def reply( self, @@ -58,7 +58,7 @@ def reply( prompt_log_path=prompt_log_path, ) - code = post_proxy.post.get_attachment(type=AttachmentType.python)[0] + code = post_proxy.post.get_attachment(type=AttachmentType.reply_content)[0] if len(code) == 0: post_proxy.update_message(post_proxy.post.get_attachment(type=AttachmentType.thought)[0], is_end=True) return post_proxy.end() From a78b0eb9d94fc0796b845b23be768e6df22b7f48 Mon Sep 17 00:00:00 2001 From: Liqun Li Date: Tue, 16 Jul 2024 12:00:39 +0800 Subject: [PATCH 3/4] add review attachment --- .../example-planner-echo.yaml | 6 +++- project/planner_examples/example-planner.yaml | 7 ++++- .../code_interpreter/code_generator.py | 31 +++++++++++++------ taskweaver/memory/attachment.py | 1 + taskweaver/planner/planner.py | 25 ++++++++++----- taskweaver/planner/planner_prompt.yaml | 4 +++ 6 files changed, 54 insertions(+), 20 deletions(-) diff --git a/project/planner_examples/example-planner-echo.yaml b/project/planner_examples/example-planner-echo.yaml index b712ce20..0971d373 100644 --- a/project/planner_examples/example-planner-echo.yaml +++ b/project/planner_examples/example-planner-echo.yaml @@ -34,4 +34,8 @@ rounds: content: |- 1. Ask Echo to echo the user's input, 'Hello World' - type: current_plan_step - content: 1. Ask Echo to echo the user's input, 'Hello World' \ No newline at end of file + content: 1. Ask Echo to echo the user's input, 'Hello World' + - type: review + content: |- + The user query is successfully answered + diff --git a/project/planner_examples/example-planner.yaml b/project/planner_examples/example-planner.yaml index 1efc4ec0..bf2ef921 100644 --- a/project/planner_examples/example-planner.yaml +++ b/project/planner_examples/example-planner.yaml @@ -40,4 +40,9 @@ rounds: 1. Instruct CodeInterpreter to load the data file and count the rows of the loaded data 2. Check the execution result and report the result to the user if it is correct - type: current_plan_step - content: 2. report the result to the user \ No newline at end of file + content: 2. report the result to the user + - type: review + content: |- + The data file /home/data.csv is loaded and there are 100 rows in the data file + The execution result is correct + The user query is successfully answered \ No newline at end of file diff --git a/taskweaver/code_interpreter/code_interpreter/code_generator.py b/taskweaver/code_interpreter/code_interpreter/code_generator.py index 9ff61ccb..9ceb011f 100644 --- a/taskweaver/code_interpreter/code_interpreter/code_generator.py +++ b/taskweaver/code_interpreter/code_interpreter/code_generator.py @@ -1,6 +1,6 @@ +import datetime import json import os -from datetime import date from typing import List, Optional from injector import inject @@ -94,14 +94,6 @@ def __init__( self.code_verification_on: bool = False self.allowed_modules: List[str] = [] - current_date = date.today() - day_of_week = current_date.strftime("%A") - self.instruction = self.instruction_template.format( - ENVIRONMENT_CONTEXT=f"- Today is {current_date}.\n- It is {day_of_week}.\n", - ROLE_NAME=self.role_name, - RESPONSE_JSON_SCHEMA=json.dumps(self.response_json_schema), - ) - self.round_compressor: RoundCompressor = round_compressor self.compression_template = read_yaml(self.config.compression_prompt_path)["content"] @@ -155,6 +147,20 @@ def compose_verification_requirements( ) return "\n".join(requirements) + def compose_sys_prompt(self, context: str): + return self.instruction_template.format( + ENVIRONMENT_CONTEXT=context, + ROLE_NAME=self.role_name, + RESPONSE_JSON_SCHEMA=json.dumps(self.response_json_schema), + ) + + def get_env_context(self): + # get date and time + now = datetime.datetime.now() + current_time = now.strftime("%Y-%m-%d %H:%M:%S") + + return f"- Current time: {current_time}" + def compose_prompt( self, rounds: List[Round], @@ -170,7 +176,12 @@ def compose_prompt( else "" ) - chat_history = [format_chat_message(role="system", message=f"{self.instruction}\n{experiences}")] + chat_history = [ + format_chat_message( + role="system", + message=f"{self.compose_sys_prompt(context=self.get_env_context())}" f"\n{experiences}", + ), + ] if self.examples is None: self.examples = self.load_examples() diff --git a/taskweaver/memory/attachment.py b/taskweaver/memory/attachment.py index e7655e88..183a5b70 100644 --- a/taskweaver/memory/attachment.py +++ b/taskweaver/memory/attachment.py @@ -12,6 +12,7 @@ class AttachmentType(Enum): init_plan = "init_plan" plan = "plan" current_plan_step = "current_plan_step" + review = "review" # CodeInterpreter - generate code thought = "thought" diff --git a/taskweaver/planner/planner.py b/taskweaver/planner/planner.py index d6a10b71..ffa6e0c1 100644 --- a/taskweaver/planner/planner.py +++ b/taskweaver/planner/planner.py @@ -1,7 +1,7 @@ +import datetime import json import os import types -from datetime import date from json import JSONDecodeError from typing import Dict, Iterable, List, Optional @@ -93,8 +93,6 @@ def __init__( self.recipient_alias_set, ) + ["User"] - self.instruction = self.compose_sys_prompt() - self.ask_self_cnt = 0 self.max_self_ask_num = 3 @@ -112,7 +110,7 @@ def __init__( self.logger.info("Planner initialized successfully") - def compose_sys_prompt(self): + def compose_sys_prompt(self, context: str): worker_description = "" for alias, role in self.workers.items(): worker_description += ( @@ -122,10 +120,8 @@ def compose_sys_prompt(self): f'- The message from {alias} will start with "From: {alias}"\n' ) - current_date = date.today() - day_of_week = current_date.strftime("%A") instruction = self.instruction_template.format( - environment_context=f"- Today is {current_date}\n- It is {day_of_week}.\n", + environment_context=context, response_json_schema=json.dumps(self.response_json_schema), worker_intro=worker_description, ) @@ -211,6 +207,13 @@ def compose_conversation_for_prompt( return conversation + def get_env_context(self) -> str: + # get the current time + now = datetime.datetime.now() + current_time = now.strftime("%Y-%m-%d %H:%M:%S") + + return f"- Current time: {current_time}" + def compose_prompt( self, rounds: List[Round], @@ -224,7 +227,13 @@ def compose_prompt( if self.config.use_experience else "" ) - chat_history = [format_chat_message(role="system", message=f"{self.instruction}\n{experiences}")] + + chat_history = [ + format_chat_message( + role="system", + message=f"{self.compose_sys_prompt(context=self.get_env_context())}" f"\n{experiences}", + ), + ] if self.config.use_example and len(self.examples) != 0: for conv_example in self.examples: diff --git a/taskweaver/planner/planner_prompt.yaml b/taskweaver/planner/planner_prompt.yaml index cc616894..5de980bc 100644 --- a/taskweaver/planner/planner_prompt.yaml +++ b/taskweaver/planner/planner_prompt.yaml @@ -131,6 +131,10 @@ response_json_schema: |- "type": "string", "description": "The current step Planner is executing." }, + "review": { + "type": "string", + "description": "The review of the current step. If the Worker's response is incorrect or incomplete, Planner should provide feedback to the Worker." + }, "send_to": { "type": "string", "description": "The name of character (User or name of the Worker) that Planner wants to speak to." From 73f803262afc7a5c63d264cf533d1bc0382ac3b0 Mon Sep 17 00:00:00 2001 From: Liqun Li Date: Tue, 16 Jul 2024 13:56:40 +0800 Subject: [PATCH 4/4] add support for azure ml endpoint --- .../rag/knowledge_base/chunk_id_to_index.pkl | Bin 0 -> 270 bytes auto_eval/cases/rag/knowledge_base/index.faiss | Bin 0 -> 50733 bytes auto_eval/cases/rag/knowledge_base/index.pkl | Bin 0 -> 12215 bytes .../complicated_task_stock_forecasting.yaml | 4 +++- auto_eval/evaluator.py | 10 ++++++++-- auto_eval/taskweaver_eval.py | 15 +++++++++++++++ 6 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 auto_eval/cases/rag/knowledge_base/chunk_id_to_index.pkl create mode 100644 auto_eval/cases/rag/knowledge_base/index.faiss create mode 100644 auto_eval/cases/rag/knowledge_base/index.pkl diff --git a/auto_eval/cases/rag/knowledge_base/chunk_id_to_index.pkl b/auto_eval/cases/rag/knowledge_base/chunk_id_to_index.pkl new file mode 100644 index 0000000000000000000000000000000000000000..e8e7008a4192583aa9788ea322166511bd9c1b2f GIT binary patch literal 270 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 literal 0 HcmV?d00001 diff --git a/auto_eval/cases/rag/knowledge_base/index.pkl b/auto_eval/cases/rag/knowledge_base/index.pkl new file mode 100644 index 0000000000000000000000000000000000000000..b814bebb4e44ddacb39a739da4d879eef233ad89 GIT binary patch literal 12215 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 QCHli2yn#R6kB+DR2ZjkZ8vp Union[ChatOpenAI, AzureChatOpenAI]: temperature=0, verbose=True, ) - elif api_type == "google": + elif api_type == "google_ai": os.environ["GOOGLE_API_KEY"] = get_config(config, "llm.api_key") model = ChatGoogleGenerativeAI( temperature=0, @@ -65,7 +66,12 @@ def config_llm(config: Dict[str, str]) -> Union[ChatOpenAI, AzureChatOpenAI]: verbose=True, convert_system_message_to_human=True, ) - + elif api_type == "azure_ml": + model = AzureMLChatOnlineEndpoint( + endpoint_url=get_config(config, "llm.api_base"), + endpoint_api_key=get_config(config, "llm.api_key"), + content_formatter=CustomOpenAIChatContentFormatter(), + ) else: raise ValueError("Invalid API type. Please check your config file.") return model diff --git a/auto_eval/taskweaver_eval.py b/auto_eval/taskweaver_eval.py index f8b107d9..a3f0139c 100644 --- a/auto_eval/taskweaver_eval.py +++ b/auto_eval/taskweaver_eval.py @@ -113,6 +113,7 @@ def batch_auto_evaluate_for_taskweaver( result_file_path: str, eval_case_root: str, flush_result_file: bool = False, + sleep_time: int = 0, ): if not os.path.exists(result_file_path): df = pd.DataFrame(columns=["case_file", "score", "normalized_score"]) @@ -147,6 +148,12 @@ def batch_auto_evaluate_for_taskweaver( results.to_csv(result_file_path, index=False) + if sleep_time > 0: + print(f"Sleeping for {sleep_time} seconds...") + import time + + time.sleep(sleep_time) + if __name__ == "__main__": import argparse @@ -186,6 +193,13 @@ def batch_auto_evaluate_for_taskweaver( action="store_true", help="Flush the result file", ) + parser.add_argument( + "-s", + "--sleep", + type=int, + default=0, + help="Sleep time between evaluations", + ) args = parser.parse_args() @@ -197,4 +211,5 @@ def batch_auto_evaluate_for_taskweaver( args.result, args.path, flush_result_file=args.fresh, + sleep_time=args.sleep, )