Skip to content

Commit

Permalink
change max_turn_num to max_consecutive_auto_reply
Browse files Browse the repository at this point in the history
  • Loading branch information
qingyun-wu committed May 9, 2023
1 parent 87116ec commit 3b3dd60
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 19 deletions.
33 changes: 20 additions & 13 deletions flaml/autogen/agent/human_proxy_agent.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
from .agent import Agent
from flaml.autogen.code_utils import extract_code, execute_code
from collections import defaultdict


class HumanProxyAgent(Agent):
"""(Experimental) A proxy agent for human, that can execute code and provide feedback to the other agents."""

DEFAULT_SYSTEM_MESSAGE = """You are human agent. You can execute_code or give feedback to the sender.
"""
MAX_TURN_NUM = 100 # maximum number of turns in one conversation session (subject to future change)
MAX_CONSECUTIVE_AUTO_REPLY = 100 # maximum number of consecutive auto replies (subject to future change)

def __init__(
self,
name,
system_message="",
work_dir=None,
human_input_mode="ALWAYS",
max_turn_num=None,
max_consecutive_auto_reply=None,
is_termination_msg=None,
**config,
):
Expand All @@ -29,15 +30,15 @@ def __init__(
When "ALWAYS", the agent will ask for human input every time a message is received.
When "TERMINATE", the agent will ask for human input only when a termination message is received.
When "NEVER", the agent will never ask for human input.
max_turn_num (int): the maximum number of turns in one conversation session.
default: None (no limit provided, class attribute MAX_TURN_NUM will be used as the limit).
max_consecutive_auto_reply (int): the maximum number of consecutive auto replies.
default: None (no limit provided, class attribute MAX_CONSECUTIVE_AUTO_REPLY will be used as the limit in this case).
The limit only plays a role when human_input_mode is not "ALWAYS".
is_termination_msg (function): a function that takes a message and returns a boolean value.
This function is used to determine if a received message is a termination message.
config (dict): other configurations.
The conversation stops when a termination message is received or the number of turns larger than
the provided max_turn_num or the human input is "exit".
The conversation stops when the human input is "exit", or no human input is provided and a termination message is received,
or the number of consecutive auto reply is larger than the provided max_consecutive_auto_reply (when human_input_mode is not "ALWAYS").
"""
super().__init__(name, system_message)
self._work_dir = work_dir
Expand All @@ -46,14 +47,17 @@ def __init__(
is_termination_msg if is_termination_msg is not None else (lambda x: x == "TERMINATE")
)
self._config = config
self._max_turn_num = max_turn_num if max_turn_num is not None else self.MAX_TURN_NUM
self._conversation_turn_counter = {}
self._max_consecutive_auto_reply = (
max_consecutive_auto_reply if max_consecutive_auto_reply is not None else self.MAX_CONSECUTIVE_AUTO_REPLY
)
self._consecutive_auto_reply_counter = defaultdict(int)

def receive(self, message, sender):
"""Receive a message from the sender agent.
Every time a message is received, the human agent will give feedback.
The conversation stops when a termination message is received or the number of turns larger than
the provided max_turn_num or the human input is "exit".
The conversation stops when the human input is "exit", or no human input is provided and a termination message is received,
or the number of consecutive auto reply is larger than the provided max_consecutive_auto_reply (when human_input_mode is not "ALWAYS").
"""
super().receive(message, sender)
# to determine if the message is a termination message using a function
Expand All @@ -63,18 +67,21 @@ def receive(self, message, sender):
if self._human_input_mode == "ALWAYS" or terminate and self._human_input_mode == "TERMINATE"
else ""
)
# reset the consecutive_auto_reply_counter
if self._human_input_mode != "ALWAYS" and feedback:
self._consecutive_auto_reply_counter[sender.name] = 0
if feedback and feedback != "exit":
self._send(feedback, sender)
elif (
terminate
or feedback == "exit"
or (
self._human_input_mode != "ALWAYS"
and (len(self._conversations[sender.name]) + 1) / 2 >= self._max_turn_num
and self._consecutive_auto_reply_counter[sender.name] >= self._max_consecutive_auto_reply
)
):
# note that len(self._conversations[sender.name])+1)/2 is the number of turns in the conversation
return
self._consecutive_auto_reply_counter[sender.name] += 1
# try to execute the code
code, lang = extract_code(message)
if lang == "unknown":
Expand All @@ -93,7 +100,7 @@ def receive(self, message, sender):
exitcode, logs = execute_code(code, work_dir=self._work_dir, filename=filename)
else:
# TODO: could this happen?
exitcode = 1
exitcode, logs = 1, "unknown language"
raise NotImplementedError
exitcode2str = "execution succeeded" if exitcode == 0 else "execution failed"
self._send(f"exitcode: {exitcode} ({exitcode2str})\nCode output: {logs.decode('utf-8')}", sender)
13 changes: 8 additions & 5 deletions test/autogen/test_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ def test_extract_code():
print(extract_code("```bash\npython temp.py\n```"))


def test_coding_agent(human_input_mode="NEVER", max_turn_num=10):
def test_coding_agent(human_input_mode="NEVER", max_consecutive_auto_reply=10):

This comment has been minimized.

Copy link
@gagb

gagb May 9, 2023

Collaborator

Some observations:

  1. the agent many times starts to suggest shell commands which makes the code fail. Especially as the conversation gets longer
  2. Sometimes the user responds with empty strings and the code agent never returns terminal and the code gets stuck in a loop. Also happens when lang=unknown eg cuz the agent didn't wrap the python code in codeblockss
  3. The code fails if the context size > 8k

This comment has been minimized.

Copy link
@qingyun-wu

qingyun-wu May 10, 2023

Author Contributor

Thanks for sharing the observations. How about creating an issue for now and try to address the problems you mentioned in future PRs?

try:
import openai
except ImportError:
Expand All @@ -20,7 +20,7 @@ def test_coding_agent(human_input_mode="NEVER", max_turn_num=10):
user = HumanProxyAgent(
"user",
human_input_mode=human_input_mode,
max_turn_num=max_turn_num,
max_consecutive_auto_reply=max_consecutive_auto_reply,
is_termination_msg=lambda x: x.rstrip().endswith("TERMINATE"),
)
# agent.receive("""Find $a+b+c$, given that $x+y\\neq -1$ and \\begin{align*}
Expand Down Expand Up @@ -52,7 +52,7 @@ def test_coding_agent(human_input_mode="NEVER", max_turn_num=10):
oai.ChatCompletion.stop_logging()


def test_tsp(human_input_mode="NEVER", max_turn_num=10):
def test_tsp(human_input_mode="NEVER", max_consecutive_auto_reply=10):
try:
import openai
except ImportError:
Expand All @@ -69,7 +69,10 @@ def test_tsp(human_input_mode="NEVER", max_turn_num=10):
oai.ChatCompletion.start_logging()
agent = PythonAgent("coding_agent", temperature=0)
user = HumanProxyAgent(
"user", work_dir="test/autogen", human_input_mode=human_input_mode, max_turn_num=max_turn_num
"user",
work_dir="test/autogen",
human_input_mode=human_input_mode,
max_consecutive_auto_reply=max_consecutive_auto_reply,
)
with open("test/autogen/tsp_prompt.txt", "r") as f:
prompt = f.read()
Expand All @@ -91,4 +94,4 @@ def test_tsp(human_input_mode="NEVER", max_turn_num=10):
# openai.api_key = "<your_api_key>"
# test_extract_code()
test_coding_agent(human_input_mode="TERMINATE")
test_tsp(human_input_mode="NEVER", max_turn_num=2)
test_tsp(human_input_mode="NEVER", max_consecutive_auto_reply=2)
2 changes: 1 addition & 1 deletion test/autogen/test_human_proxy_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def test_human_agent():
conversations = {}
oai.ChatCompletion.start_logging(conversations)
agent = ChatAgent("chat_agent")
user = HumanProxyAgent("human_user", human_input_mode="NEVER", max_turn_num=2)
user = HumanProxyAgent("human_user", human_input_mode="NEVER", max_consecutive_auto_reply=2)
agent.receive(
"""Write python code to solve the equation x^3=125. You must write code in the following format. You must always print the result.
Wait for me to return the result.
Expand Down

0 comments on commit 3b3dd60

Please sign in to comment.