Skip to content

Commit 4f060e5

Browse files
krishnashedsonichirysweet
authored
Autobuild Function calling (#3238)
* [Fix] Precommit issues * [Fix] checks * [Fix] iterating through list_of_functions * [Fix] pre-commit checks * Update test/agentchat/contrib/test_agent_builder.py Co-authored-by: Chi Wang <[email protected]> --------- Co-authored-by: Chi Wang <[email protected]> Co-authored-by: Ryan Sweet <[email protected]> Co-authored-by: Chi Wang <[email protected]>
1 parent 11ef58b commit 4f060e5

File tree

3 files changed

+671
-19
lines changed

3 files changed

+671
-19
lines changed

autogen/agentchat/contrib/agent_builder.py

+77-2
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,26 @@ class AgentBuilder:
172172
```
173173
"""
174174

175+
AGENT_FUNCTION_MAP_PROMPT = """Consider the following function.
176+
Function Name: {function_name}
177+
Function Description: {function_description}
178+
179+
The agent details are given in the format: {format_agent_details}
180+
181+
Which one of the following agents should be able to execute this function, preferably an agent with programming background?
182+
{agent_details}
183+
184+
Hint:
185+
# Only respond with the name of the agent that is most suited to execute the function and nothing else.
186+
"""
187+
188+
UPDATED_AGENT_SYSTEM_MESSAGE = """
189+
{agent_system_message}
190+
191+
You have access to execute the function: {function_name}.
192+
With following description: {function_description}
193+
"""
194+
175195
def __init__(
176196
self,
177197
config_file_or_env: Optional[str] = "OAI_CONFIG_LIST",
@@ -358,6 +378,7 @@ def build(
358378
self,
359379
building_task: str,
360380
default_llm_config: Dict,
381+
list_of_functions: Optional[List[Dict]] = None,
361382
coding: Optional[bool] = None,
362383
code_execution_config: Optional[Dict] = None,
363384
use_oai_assistant: Optional[bool] = False,
@@ -373,6 +394,7 @@ def build(
373394
coding: use to identify if the user proxy (a code interpreter) should be added.
374395
code_execution_config: specific configs for user proxy (e.g., last_n_messages, work_dir, ...).
375396
default_llm_config: specific configs for LLM (e.g., config_list, seed, temperature, ...).
397+
list_of_functions: list of functions to be associated with Agents
376398
use_oai_assistant: use OpenAI assistant api instead of self-constructed agent.
377399
user_proxy: user proxy's class that can be used to replace the default user proxy.
378400
@@ -480,8 +502,9 @@ def build(
480502
"code_execution_config": code_execution_config,
481503
}
482504
)
505+
483506
_config_check(self.cached_configs)
484-
return self._build_agents(use_oai_assistant, user_proxy=user_proxy, **kwargs)
507+
return self._build_agents(use_oai_assistant, list_of_functions, user_proxy=user_proxy, **kwargs)
485508

486509
def build_from_library(
487510
self,
@@ -653,13 +676,18 @@ def build_from_library(
653676
return self._build_agents(use_oai_assistant, user_proxy=user_proxy, **kwargs)
654677

655678
def _build_agents(
656-
self, use_oai_assistant: Optional[bool] = False, user_proxy: Optional[autogen.ConversableAgent] = None, **kwargs
679+
self,
680+
use_oai_assistant: Optional[bool] = False,
681+
list_of_functions: Optional[List[Dict]] = None,
682+
user_proxy: Optional[autogen.ConversableAgent] = None,
683+
**kwargs,
657684
) -> Tuple[List[autogen.ConversableAgent], Dict]:
658685
"""
659686
Build agents with generated configs.
660687
661688
Args:
662689
use_oai_assistant: use OpenAI assistant api instead of self-constructed agent.
690+
list_of_functions: list of functions to be associated to Agents
663691
user_proxy: user proxy's class that can be used to replace the default user proxy.
664692
665693
Returns:
@@ -695,6 +723,53 @@ def _build_agents(
695723
)
696724
agent_list = agent_list + [user_proxy]
697725

726+
agent_details = []
727+
728+
for agent in agent_list[:-1]:
729+
agent_details.append({"name": agent.name, "description": agent.description})
730+
731+
if list_of_functions:
732+
for func in list_of_functions:
733+
resp = (
734+
self.builder_model.create(
735+
messages=[
736+
{
737+
"role": "user",
738+
"content": self.AGENT_FUNCTION_MAP_PROMPT.format(
739+
function_name=func["name"],
740+
function_description=func["description"],
741+
format_agent_details='[{"name": "agent_name", "description": "agent description"}, ...]',
742+
agent_details=str(json.dumps(agent_details)),
743+
),
744+
}
745+
]
746+
)
747+
.choices[0]
748+
.message.content
749+
)
750+
751+
autogen.agentchat.register_function(
752+
func["function"],
753+
caller=self.agent_procs_assign[resp][0],
754+
executor=agent_list[0],
755+
name=func["name"],
756+
description=func["description"],
757+
)
758+
759+
agents_current_system_message = [
760+
agent["system_message"] for agent in agent_configs if agent["name"] == resp
761+
][0]
762+
763+
self.agent_procs_assign[resp][0].update_system_message(
764+
self.UPDATED_AGENT_SYSTEM_MESSAGE.format(
765+
agent_system_message=agents_current_system_message,
766+
function_name=func["name"],
767+
function_description=func["description"],
768+
)
769+
)
770+
771+
print(f"Function {func['name']} is registered to agent {resp}.")
772+
698773
return agent_list, self.cached_configs.copy()
699774

700775
def save(self, filepath: Optional[str] = None) -> str:

0 commit comments

Comments
 (0)