Skip to content

Commit

Permalink
Prompt engineering refinements and related processing
Browse files Browse the repository at this point in the history
  • Loading branch information
erik-megarad committed Aug 1, 2023
1 parent 24f6fcc commit 7668daa
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 83 deletions.
19 changes: 10 additions & 9 deletions beebot/body/body.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

from beebot.body.body_state_machine import BodyStateMachine
from beebot.body.llm import call_llm, create_llm
from beebot.body.pack_utils import system_packs, get_or_install_pack
from beebot.body.pack_utils import get_or_install_pack
from beebot.body.revising_prompt import revise_task_prompt
from beebot.config import Config
from beebot.decider import Decider
Expand Down Expand Up @@ -99,7 +99,6 @@ def setup(self):
self.model_object.save()

self.revise_task()
self.packs = system_packs(self)
self.update_packs()

self.state.start()
Expand Down Expand Up @@ -218,16 +217,18 @@ def update_packs(
if not new_packs:
new_packs = recommend_packs_for_plan(self)

for pack in new_packs:
if pack.name in self.packs:
pack_names = [pack.name for pack in new_packs]
pack_names += self.config.auto_include_packs
for pack_name in pack_names:
if pack_name in self.packs:
continue

try:
installed_pack = get_or_install_pack(self, pack.name)
installed_pack = get_or_install_pack(self, pack_name)
if not installed_pack:
logger.warning(f"Pack {pack.name} could not be installed")
logger.warning(f"Pack {pack_name} could not be installed")

self.packs[pack.name] = installed_pack
self.packs[pack_name] = installed_pack

if installed_pack.depends_on:
for dep_name in installed_pack.depends_on:
Expand All @@ -237,12 +238,12 @@ def update_packs(
installed_dep = get_or_install_pack(self, dep_name)
if not installed_dep:
logger.warning(
f"Pack {dep_name}, a dependency of {pack.name} could not be installed"
f"Pack {dep_name}, a dependency of {pack_name} could not be installed"
)
continue

self.packs[dep_name] = installed_dep

except AutoPackError as e:
# This is usually because we got a response with a made-up function.
logger.warning(f"Pack {pack.name} could not be initialized: {e}")
logger.warning(f"Pack {pack_name} could not be initialized: {e}")
2 changes: 1 addition & 1 deletion beebot/body/llm.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def call_llm(
llm = body.llm
output_kwargs = {}

if include_functions:
if include_functions and body.packs:
output_kwargs["functions"] = format_packs_to_openai_functions(
body.packs.values()
)
Expand Down
19 changes: 4 additions & 15 deletions beebot/body/pack_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@

logger = logging.getLogger(__name__)

# TODO: This should be a Packfile
SUPPRESSED_PACKS = ["read_file"]
# TODO: This should be a config value?
SUPPRESSED_PACKS = ["read_file", "list_files", "delete_file"]


def all_packs(body: "Body") -> dict[str, Union[Pack, PackResponse]]:
Expand All @@ -25,13 +25,12 @@ def all_packs(body: "Body") -> dict[str, Union[Pack, PackResponse]]:
local_packs = all_local_packs(body)
remote_packs = get_all_pack_info()
for pack in remote_packs:
if pack.name not in SUPPRESSED_PACKS:
all_pack_data[pack.name] = pack
all_pack_data[pack.name] = pack

for pack in local_packs.values():
all_pack_data[pack.name] = pack

return all_pack_data
return {k: v for k, v in all_pack_data.items() if k not in SUPPRESSED_PACKS}


def all_local_packs(body: "Body") -> dict[str, Pack]:
Expand All @@ -56,16 +55,6 @@ def all_local_packs(body: "Body") -> dict[str, Pack]:
return return_packs


def system_packs(body: "Body") -> dict[str, Pack]:
from beebot.packs import Exit, GetMoreTools, RewindActions

return {
"exit": Exit(body=body),
"get_more_tools": GetMoreTools(body=body),
"rewind_actions": RewindActions(body=body),
}


def llm_wrapper(body: "Body") -> str:
def llm(prompt) -> str:
return call_llm(body, prompt).text
Expand Down
7 changes: 6 additions & 1 deletion beebot/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ class Config(BaseSettings):
auto_install_packs: bool = True
auto_install_dependencies: bool = True
file_manager: str = "workspace"
auto_include_packs: list[str] = ["read_file", "write_file"]
auto_include_packs: list[str] = [
"write_file",
"exit",
"rewind_actions",
"get_more_tools",
]

_global_config: ClassVar["Config"] = None

Expand Down
51 changes: 25 additions & 26 deletions beebot/function_selection/function_selection_prompt.py
Original file line number Diff line number Diff line change
@@ -1,50 +1,49 @@
from langchain.prompts import SystemMessagePromptTemplate
FORMAT_SECTION = """
Please respond in the following format:
TEMPLATE = """As the AI Tool Selector your responsibility is to identify functions (tools) that could be useful for an autonomous AI agent to accomplish a given task.
Firstly, provide a comma-separated list of function names. Exclude parentheses and arguments from this list. Secondly, after the special delimiter '###', provide explanations for why each function was chosen and how it contributes to accomplishing the task.
Analyze the task and available functions, and determine which functions could be useful. Consider functions that can achieve the goal directly or indirectly, in combination with other tools.
For example, your response may look like this:
Only recommend programming functions if the task explicitly requires programming.
function1, function2, function3 ### function1 can accomplish step A of the task because..., function2 and function3 can be used together to..."""

INITIAL_SELECTION_TEMPLATE = """As the AI Tool Selector, your responsibility is to analyze a given task and the available functions. Your goal is to identify and recommend functions (tools) that could be used, either directly or indirectly, to accomplish the task by an autonomous AI agent.
By providing more flexibility in the selection and emphasizing the consideration of alternative functions, we can ensure a wider range of function recommendations that align with the given task.
Task:
Take into account that programming functions should only be recommended if the task explicitly requires programming.
# Task
Your original task, given by the human, is:
{task}
Available functions:
# Functions
You may only recommend functions from the following list:
{functions}.
Please respond with a comma-separated list of function names, excluding parentheses and arguments. Do not include any other explanatory text.
By providing more flexibility in the selection and emphasizing the consideration of alternative functions, we can ensure a wider range of function recommendations that align with the given task.
"""
When making your recommendations, consider how the functions can work together to achieve the task's goal, how certain functions may be more effective than others, and prioritize those functions that are most likely to contribute to a successful task completion."""

GET_MORE_TOOLS_TEMPLATE = """As the AI Tool Selector your responsibility is to identify functions (tools) that could be useful for an autonomous AI agent to accomplish a given task.
Analyze the functions request and determine which functions could be useful. Consider functions that can achieve the goal directly or indirectly, in combination with other tools.
GET_MORE_TOOLS_TEMPLATE = """As the AI Tool Selector, your responsibility is to identify functions (tools) that could be useful for an autonomous AI agent to accomplish a given task. By providing more flexibility in the selection and emphasizing the consideration of alternative functions, we can ensure a wider range of function recommendations that align with the given task.
Only recommend programming functions if the task explicitly requires programming.
Functions request:
In this scenario, the Autonomous AI has made a request for additional tools to complete a task. Your role is to analyze the functions request and determine which functions could be useful, either directly or indirectly, in combination with other tools.
Request for more tools:
The Autonomous AI has made this request for more tools: {functions_request}
Task:
Your original task, given by the human, is:
Original Task:
The task originally assigned by the human is:
{task}
Available functions:
You may only recommend functions from the following list:
{functions}.
Please respond with a comma-separated list of function names, excluding parentheses and arguments. Do not include any other explanatory text.
By providing more flexibility in the selection and emphasizing the consideration of alternative functions, we can ensure a wider range of function recommendations that align with the given task.
"""
{functions}."""


def initial_selection_template() -> SystemMessagePromptTemplate:
return SystemMessagePromptTemplate.from_template(TEMPLATE)
def initial_selection_template() -> str:
return INITIAL_SELECTION_TEMPLATE + FORMAT_SECTION


def get_more_tools_template() -> SystemMessagePromptTemplate:
return SystemMessagePromptTemplate.from_template(GET_MORE_TOOLS_TEMPLATE)
def get_more_tools_template() -> str:
return GET_MORE_TOOLS_TEMPLATE + FORMAT_SECTION
30 changes: 20 additions & 10 deletions beebot/function_selection/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@


def recommend_packs_for_plan(body: "Body") -> list[Union[Pack, PackResponse]]:
prompt = (
initial_selection_template()
.format(
task=body.task,
functions=functions_bulleted_list(all_packs(body).values()),
)
.content
packs_for_recommendation = [
pack
for pack in all_packs(body).values()
if pack.name not in body.config.auto_include_packs
]
functions_list = functions_bulleted_list(packs_for_recommendation)

prompt = initial_selection_template().format(
task=body.task, functions=functions_list
)
logger.info("=== Function request sent to LLM ===")
logger.info(prompt)
Expand All @@ -34,9 +36,17 @@ def recommend_packs_for_plan(body: "Body") -> list[Union[Pack, PackResponse]]:
logger.info("=== Functions received from LLM ===")
logger.info(response)

# 1. Split by commas (if preceded by a word character), and newlines.
# 2. Remove any arguments given if provided. The prompt says they shouldn't be there, but sometimes they are.
functions = [r.split("(")[0].strip() for r in re.split(r"(?<=\w),|\n", response)]
# Split the response into function names and explanation.
response_parts = response.split("###")
# TODO: Do something with the explanation
function_part, _explanation_part = response_parts

# Split by commas (if preceded by a word character), and newlines.
# Remove any arguments given if provided. The prompt says they shouldn't be there, but sometimes they are.
functions = [
r.split("(")[0].strip() for r in re.split(r"(?<=\w),|\n", function_part)
]

functions += body.config.auto_include_packs
packs = all_packs(body)
return [packs[function] for function in functions if function in packs]
19 changes: 5 additions & 14 deletions beebot/packs/get_more_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from beebot.body.llm import call_llm
from beebot.body.pack_utils import (
all_local_packs, all_packs,
all_packs,
)
from beebot.function_selection.function_selection_prompt import get_more_tools_template
from beebot.packs.system_base_pack import SystemBasePack
Expand Down Expand Up @@ -39,19 +39,10 @@ class Meta:
categories = ["System"]

def _run(self, desired_functionality: str) -> list[str]:
packs_to_summarize = [
pack
for pack in all_local_packs(self.body).values()
if pack.name not in self.body.packs
]
prompt = (
get_more_tools_template()
.format(
task=self.body.task,
functions=functions_bulleted_list(all_packs(self.body).values()),
functions_request=desired_functionality,
)
.content
prompt = get_more_tools_template().format(
task=self.body.task,
functions=functions_bulleted_list(all_packs(self.body).values()),
functions_request=desired_functionality,
)

response = call_llm(self.body, prompt, include_functions=False).text
Expand Down
2 changes: 1 addition & 1 deletion beebot/packs/get_website_text_content.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from beebot.packs.system_base_pack import SystemBasePack
from beebot.tool_filters.filter_long_documents import filter_long_documents

PACK_NAME = "get_website_text_content"
PACK_NAME = "get_website_content"
PACK_DESCRIPTION = (
"Retrieves the text content of a specified webpage. It is useful when you want to obtain the textual information "
"from a webpage without the need for in-depth analysis."
Expand Down
21 changes: 15 additions & 6 deletions beebot/planner/planning_prompt.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
from langchain.prompts import SystemMessagePromptTemplate

INITIAL_TEMPLATE = """As the AI Task Strategist, your role is to strategize and plan the execution of tasks efficiently and effectively. Avoid redundancy, such as unnecessary immediate verification of actions, and leverage your knowledge base to make informed decisions. You only speak English and don't know how to write code.
INITIAL_TEMPLATE = """As the AI Task Strategist, your role is to strategize and plan the execution of tasks efficiently and effectively. Avoid redundancy, such as unnecessary immediate verification of actions, and leverage your knowledge base to make informed decisions. You only speak English and do not have the capability to write code.
You have these functions at your disposal: {functions}. If your current functions are inadequate, new functions can be acquired via the `get_more_tools()` function.
# Functions
You have these functions at your disposal:
{functions}.
## Specific instructions for Functions
If the AI Assistant appears to be making little progress and may be unable to proceed, instruct it to call the `rewind_actions` function to try another approach. If other approaches seem to have been unsuccessful, instruct the AI Assistant to call the `exit` function with all arguments.
Once the original task has been completed, instruct the AI Assistant to call the `exit` function with all arguments to indicate the completion of the task.
# Task
Your original task, given by the human, is:
{task}
# Files
You have access to these files, but no others:
You have access only to these listed files:
{file_list}
# Instructions
Now, devise a comprehensive and adaptable plan to guide the AI Assistant. Follow these guidelines:
1. Determine the next logical step towards the task goal, considering your current information, requirements, and available functions. Remember to be efficient, avoiding unnecessary steps like immediate verification of outcomes and repetitive function calls.
2. Direct the execution of the next action using exactly one of the available functions.
1. Independently estimate the number of steps the original task should take. Use this estimate as the basis of your plan.
2. Identify the initial function that should be executed to kick-start the task. Keep in mind the requirements of the task and the available functions when making this decision.
3. Develop a step-by-step plan of action that logically leads towards the task goal, considering your current information, requirements, and available functions. Remember to be efficient, avoiding unnecessary actions like immediate verification of outcomes.
4. Direct the execution of the first action using exactly one of the available functions. If the first action requires a function that you do not have, instead instruct the AI Assistant to acquire it via `get_more_tools`.
Please provide a concise summary of your plan, and end with one sentence describing the first action to be taken."""
Please provide, in paragraph format, an initial assessment of the task requirements, followed by a step-by-step summary of your plan going forward, and end with one sentence describing the first action to be taken."""

TEMPLATE = """As the AI Task Strategist, your role is to strategize and plan the execution of tasks efficiently and effectively. Avoid redundancy, such as unnecessary immediate verification of actions, and leverage your knowledge base to make informed decisions. You only speak English and do not have the capability to write code.
Expand Down

0 comments on commit 7668daa

Please sign in to comment.