从冷笑话到悲伤的笑话:使用GPTAssistantAgent进行函数调用
Autogen 允许 GPTAssistantAgent
通过“工具”——预定义的函数或能力——进行增强,以扩展其处理特定任务的能力,类似于在 OpenAI Assistant’s API 中原生使用工具的方式。
在本笔记本中,我们使用Autogen的GPTAssistantAgent
创建一个基本的多代理系统,将特定主题的爸爸笑话转换为悲伤笑话。该系统由一个“爸爸”代理和一个“悲伤笑话者”代理组成。“爸爸”代理具有搜索Dad Joke API的能力,“悲伤笑话者”代理则将爸爸笑话转换为悲伤笑话。然后,悲伤笑话者将悲伤笑话写入一个txt文件中。
在这个过程中,我们演示了如何调用工具并为GPTAssistantAgent
执行函数调用。
要求
AutoGen 需要 Python 3.8 或更新版本。对于这个笔记本,请安装 autogen-agentchat
:
pip install autogen-agentchat~=0.2
导入依赖项
from typing import Annotated, Literal
import requests
import autogen
from autogen import UserProxyAgent
from autogen.agentchat.contrib.gpt_assistant_agent import GPTAssistantAgent
from autogen.function_utils import get_function_schema
config_list = autogen.config_list_from_json(
env_or_file="OAI_CONFIG_LIST",
)
创建函数
我们需要为我们的代理创建可以调用的函数。
此函数使用代理生成的搜索词调用Dad Joke API,并返回一个爸爸笑话列表。
def get_dad_jokes(search_term: str, page: int = 1, limit: int = 10) -> str:
"""
Fetches a list of dad jokes based on a search term.
Parameters:
- search_term: The search term to find jokes about.
- page: The page number of results to fetch (default is 1).
- limit: The number of results to return per page (default is 20, max is 30).
Returns:
A list of dad jokes.
"""
url = "https://icanhazdadjoke.com/search"
headers = {"Accept": "application/json"}
params = {"term": search_term, "page": page, "limit": limit}
response = requests.get(url, headers=headers, params=params)
if response.status_code == 200:
data = response.json()
jokes = [joke["joke"] for joke in data["results"]]
return jokes
else:
return f"Failed to fetch jokes, status code: {response.status_code}"
# Example Dad Jokes Function Usage:
jokes = get_dad_jokes("cats")
print(jokes)
['Where do cats write notes?\r\nScratch Paper!', 'It was raining cats and dogs the other day. I almost stepped in a poodle.', 'What do you call a group of disorganized cats? A cat-tastrophe.', 'I accidentally took my cats meds last night. Don’t ask meow.', 'What do you call a pile of cats? A Meowtain.', 'Animal Fact #25: Most bobcats are not named bob.']
此功能允许代理写入txt文件。
def write_to_txt(content: str, filename: str = "dad_jokes.txt"):
"""
Writes a formatted string to a text file.
Parameters:
- content: The formatted string to write.
- filename: The name of the file to write to. Defaults to "output.txt".
"""
with open(filename, "w") as file:
file.write(content)
# Example Write to TXT Function Usage:
content = "\n".join(jokes) # Format the jokes from the above example
write_to_txt(content)
创建函数模式
为了使用我们GPTAssistantAgents中的功能,我们需要生成功能模式。这可以通过使用get_function_schema
来完成。
# Assistant API Tool Schema for get_dad_jokes
get_dad_jokes_schema = get_function_schema(
get_dad_jokes,
name="get_dad_jokes",
description="Fetches a list of dad jokes based on a search term. Allows pagination with page and limit parameters.",
)
# Assistant API Tool Schema for write_to_txt
write_to_txt_schema = get_function_schema(
write_to_txt,
name="write_to_txt",
description="Writes a formatted string to a text file. If the file does not exist, it will be created. If the file does exist, it will be overwritten.",
)
The return type of the function 'write_to_txt' is not annotated. Although annotating it is optional, the function should return either a string, a subclass of 'pydantic.BaseModel'.
创建Agents
在本节中,我们将创建并配置我们的Dad和Sad Joker代理
设置用户代理
user_proxy = UserProxyAgent(
name="user_proxy",
is_termination_msg=lambda msg: "TERMINATE" in msg["content"],
human_input_mode="NEVER",
max_consecutive_auto_reply=1,
)
爸爸代理
我们使用GPTAssistantAgent
创建了Dad代理,以便让我们能够使Dad使用get_dad_jokes
函数,我们需要在llm_config
中提供该函数的规格。
我们将tools
格式化为与OpenAI Assistant tools docs中提供的格式相同的llm_config
。
the_dad = GPTAssistantAgent(
name="the_dad",
instructions="""
As 'The Dad', your primary role is to entertain by fetching dad jokes which the sad joker will transform into 'sad jokes' based on a given theme. When provided with a theme, such as 'plants' or 'animals', your task is as follows:
1. Use the 'get_dad_jokes' function to search for dad jokes related to the provided theme by providing a search term related to the theme. Fetch a list of jokes that are relevant to the theme.
2. Present these jokes to the sad joker in a format that is clear and easy to read, preparing them for transformation.
Remember, the team's goal is to creatively adapt the essence of each dad joke to fit the 'sad joke' format, all while staying true to the theme provided by the user.
""",
overwrite_instructions=True, # overwrite any existing instructions with the ones provided
overwrite_tools=True, # overwrite any existing tools with the ones provided
llm_config={
"config_list": config_list,
"tools": [get_dad_jokes_schema],
},
)
OpenAI client config of GPTAssistantAgent(the_dad) - model: gpt-4-1106-preview
Matching assistant found, using the first matching assistant: {'id': 'asst_BLBUwYPugb1UR2jQMGAA7RtU', 'created_at': 1714660644, 'description': None, 'file_ids': [], 'instructions': "\n As 'The Dad', your primary role is to entertain by fetching dad jokes which the sad joker will transform into 'sad jokes' based on a given theme. When provided with a theme, such as 'plants' or 'animals', your task is as follows:\n\n 1. Use the 'get_dad_jokes' function to search for dad jokes related to the provided theme by providing a search term related to the theme. Fetch a list of jokes that are relevant to the theme.\n 2. Present these jokes to the sad joker in a format that is clear and easy to read, preparing them for transformation.\n\n Remember, the team's goal is to creatively adapt the essence of each dad joke to fit the 'sad joke' format, all while staying true to the theme provided by the user.\n ", 'metadata': {}, 'model': 'gpt-4-1106-preview', 'name': 'the_dad', 'object': 'assistant', 'tools': [ToolFunction(function=FunctionDefinition(name='get_dad_jokes', description='Fetches a list of dad jokes based on a search term. Allows pagination with page and limit parameters.', parameters={'type': 'object', 'properties': {'search_term': {'type': 'string', 'description': 'search_term'}, 'page': {'type': 'integer', 'default': 1, 'description': 'page'}, 'limit': {'type': 'integer', 'default': 10, 'description': 'limit'}}, 'required': ['search_term']}), type='function')]}
接下来,我们将get_dad_jokes
函数注册到Dad的GPTAssistantAgent
中。
# Register get_dad_jokes with the_dad GPTAssistantAgent
the_dad.register_function(
function_map={
"get_dad_jokes": get_dad_jokes,
},
)
悲伤的小丑代理
我们以与上述Dad代理类似的方式创建并配置Sad Joker代理。
the_sad_joker = GPTAssistantAgent(
name="the_sad_joker",
instructions="""
As 'The Sad Joker', your unique role is to take dad jokes and creatively transform them into 'sad jokes'. When you receive a list of dad jokes, themed around topics like 'plants' or 'animals', you should:
1. Read through each dad joke carefully, understanding its theme and punchline.
2. Creatively alter the joke to change its mood from humorous to somber or melancholic. This may involve tweaking the punchline, modifying the setup, or even completely reimagining the joke while keeping it relevant to the original theme.
3. Ensure your transformations maintain a clear connection to the original theme and are understandable as adaptations of the dad jokes provided.
4. Write your transformed sad jokes to a text file using the 'write_to_txt' function. Use meaningful file names that reflect the theme or the nature of the jokes within, unless a specific filename is requested.
Your goal is not just to alter the mood of the jokes but to do so in a way that is creative, thoughtful, and respects the essence of the original humor. Remember, while the themes might be light-hearted, your transformations should offer a melancholic twist that makes them uniquely 'sad jokes'.
""",
overwrite_instructions=True, # overwrite any existing instructions with the ones provided
overwrite_tools=True, # overwrite any existing tools with the ones provided
llm_config={
"config_list": config_list,
"tools": [write_to_txt_schema],
},
)
OpenAI client config of GPTAssistantAgent(the_sad_joker) - model: gpt-4-1106-preview
Matching assistant found, using the first matching assistant: {'id': 'asst_HzB75gkobafXZhkuIAmiBiai', 'created_at': 1714660668, 'description': None, 'file_ids': [], 'instructions': "\n As 'The Sad Joker', your unique role is to take dad jokes and creatively transform them into 'sad jokes'. When you receive a list of dad jokes, themed around topics like 'plants' or 'animals', you should:\n\n 1. Read through each dad joke carefully, understanding its theme and punchline.\n 2. Creatively alter the joke to change its mood from humorous to somber or melancholic. This may involve tweaking the punchline, modifying the setup, or even completely reimagining the joke while keeping it relevant to the original theme.\n 3. Ensure your transformations maintain a clear connection to the original theme and are understandable as adaptations of the dad jokes provided.\n 4. Write your transformed sad jokes to a text file using the 'write_to_txt' function. Use meaningful file names that reflect the theme or the nature of the jokes within, unless a specific filename is requested.\n\n Your goal is not just to alter the mood of the jokes but to do so in a way that is creative, thoughtful, and respects the essence of the original humor. Remember, while the themes might be light-hearted, your transformations should offer a melancholic twist that makes them uniquely 'sad jokes'.\n ", 'metadata': {}, 'model': 'gpt-4-1106-preview', 'name': 'the_sad_joker', 'object': 'assistant', 'tools': [ToolFunction(function=FunctionDefinition(name='write_to_txt', description='Writes a formatted string to a text file. If the file does not exist, it will be created. If the file does exist, it will be overwritten.', parameters={'type': 'object', 'properties': {'content': {'type': 'string', 'description': 'content'}, 'filename': {'type': 'string', 'default': 'dad_jokes.txt', 'description': 'filename'}}, 'required': ['content']}), type='function')]}
向Sad Joker GPTAssistantAgent
注册write_to_txt
函数
# Register get_dad_jokes with the_dad GPTAssistantAgent
the_sad_joker.register_function(
function_map={
"write_to_txt": write_to_txt,
},
)
创建群聊并开始对话
创建群聊
groupchat = autogen.GroupChat(agents=[user_proxy, the_dad, the_sad_joker], messages=[], max_round=15)
group_chat_manager = autogen.GroupChatManager(groupchat=groupchat, llm_config={"config_list": config_list})
开始对话
user_proxy.initiate_chat(group_chat_manager, message="Jokes about cats")
Jokes about cats
--------------------------------------------------------------------------------
>>>>>>>> EXECUTING FUNCTION get_dad_jokes...
Here are some cat-themed dad jokes for the sad joker to transform:
1. Where do cats write notes? Scratch Paper!
2. It was raining cats and dogs the other day. I almost stepped in a poodle.
3. What do you call a group of disorganized cats? A cat-tastrophe.
4. I accidentally took my cat's meds last night. Don’t ask meow.
5. What do you call a pile of cats? A Meowtain.
6. Animal Fact #25: Most bobcats are not named Bob.
--------------------------------------------------------------------------------
>>>>>>>> EXECUTING FUNCTION write_to_txt...
The cat-themed sad jokes have been transformed and saved to a text file named "sad_cat_jokes.txt".
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
ChatResult(chat_id=None, chat_history=[{'content': 'Jokes about cats', 'role': 'assistant'}, {'content': "Here are some cat-themed dad jokes for the sad joker to transform:\n\n1. Where do cats write notes? Scratch Paper!\n2. It was raining cats and dogs the other day. I almost stepped in a poodle.\n3. What do you call a group of disorganized cats? A cat-tastrophe.\n4. I accidentally took my cat's meds last night. Don’t ask meow.\n5. What do you call a pile of cats? A Meowtain.\n6. Animal Fact #25: Most bobcats are not named Bob.\n", 'name': 'the_dad', 'role': 'user'}, {'content': 'The cat-themed sad jokes have been transformed and saved to a text file named "sad_cat_jokes.txt".\n', 'name': 'the_sad_joker', 'role': 'user'}, {'content': '', 'role': 'assistant'}], summary='', cost=({'total_cost': 0.0278, 'gpt-4-1106-preview': {'cost': 0.0278, 'prompt_tokens': 2744, 'completion_tokens': 12, 'total_tokens': 2756}}, {'total_cost': 0.02194, 'gpt-4-1106-preview': {'cost': 0.02194, 'prompt_tokens': 2167, 'completion_tokens': 9, 'total_tokens': 2176}}), human_input=[])