本系列博文在掘金同步發布, 更多優質文章,請關注本人掘金賬號:
人肉推土機的掘金賬號
AutoGen系列一:基礎介紹與入門教程
AutoGen系列二:深入自定義智能體
AutoGen系列三:內置智能體的應用與實戰
AutoGen系列四:自定義智能體的高級技巧
AutoGen系列五: 智能體團隊協作的深度剖析與實踐
AutoGen 技術博客系列 (六):SelectorGroupChat 的原理與實踐
AutoGen 技術博客系列 (七):狀態管理與組件序列化解析
AutoGen 技術博客系列 八:深入剖析 Swarm—— 智能體協作的新范式
AutoGen 技術博客系列 九:從 v0.2 到 v0.4 的遷移指南
這是一份為 autogen-agentchat
v0.2.*
版本用戶提供的遷移指南,旨在幫助用戶升級到 v0.4
版本,該版本引入了一組新的 API 和功能。v0.4
版本包含重大變更,請仔細閱讀本指南。我們仍在 0.2
分支中維護 v0.2
版本,但強烈建議您升級到 v0.4
版本。
注意: v0.4
不再擁有 pyautogen
PyPI 包的管理員權限,自 0.2.34 版本起,該包的發布不再來自微軟。如需繼續使用 v0.2
版本的 AutoGen,請使用 autogen-agentchat~=0.2
進行安裝。請閱讀我們關于分支的澄清聲明。
什么是 v0.4?
自 2023 年 AutoGen 發布以來,我們積極傾聽社區以及來自小型初創公司和大型企業用戶的反饋,并基于這些反饋構建了 AutoGen v0.4
。這是一個從頭開始重寫的版本,采用異步、事件驅動架構,旨在解決可觀測性、靈活性、交互控制和擴展性等問題。
v0.4
API 是分層的:核心 API 是基礎層,提供了一個可擴展的、事件驅動的參與者框架,用于創建智能體工作流;AgentChat API 構建在核心 API 之上,提供了一個任務驅動的高級框架,用于構建交互式智能體應用程序,它是 AutoGen v0.2
的替代品。
本指南主要關注 v0.4
的 AgentChat API,但您也可以僅使用核心 API 構建自己的高級框架。
新用戶:直接跳轉到 AgentChat 教程開始使用 v0.4
。
本指南內容
我們提供了一份詳細指南,說明如何將現有代碼庫從 v0.2
遷移到 v0.4
。有關如何遷移的詳細信息,請參閱以下每個功能。
- 模型客戶端
- 與 OpenAI 兼容的 API 的模型客戶端
- 模型客戶端緩存
- 助手智能體
- 多模態智能體
- 用戶代理
- 可對話智能體和注冊回復
- 保存和加載智能體狀態
- 雙智能體聊天
- 工具使用
- 聊天結果
- v0.2 和 v0.4 消息之間的轉換
- 群聊
- 恢復群聊
- 保存和加載群聊狀態
- 帶工具使用的群聊
- 帶自定義選擇器(Stateflow)的群聊
- 嵌套聊天
- 順序聊天
- GPTAssistantAgent
- 長上下文處理
- 可觀測性和控制
- 代碼執行器
以下 v0.2
中的功能將在未來的 v0.4.*
版本中提供:
- 模型客戶端成本 #4835
- 可教學智能體
- RAG 智能體
當缺失的功能可用時,我們將更新本指南。
模型客戶端
在 v0.2
中,您可以按如下方式配置模型客戶端并創建 OpenAIWrapper
對象:
from autogen.oai import OpenAIWrapperconfig_list = [{"model": "gpt-4o", "api_key": "sk-xxx"},{"model": "gpt-4o-mini", "api_key": "sk-xxx"},
]
model_client = OpenAIWrapper(config_list=config_list)
注意:在 AutoGen 0.2 中,OpenAI 客戶端會嘗試列表中的配置,直到找到一個可用的。而 0.4 版本需要選擇特定的模型配置。
在 v0.4
中,我們提供了兩種創建模型客戶端的方法。
使用組件配置
AutoGen 0.4 有一個通用的組件配置系統,模型客戶端是其一個很好的應用場景。以下是創建 OpenAI 聊天完成客戶端的示例:
from autogen_core.models import ChatCompletionClientconfig = {"provider": "OpenAIChatCompletionClient","config": {"model": "gpt-4o","api_key": "sk-xxx" # 也可以使用 os.environ["..."]}
}
model_client = ChatCompletionClient.load_component(config)
直接使用模型客戶端類
- Open AI:
from autogen_ext.models.openai import OpenAIChatCompletionClient
model_client = OpenAIChatCompletionClient(model="gpt-4o", api_key="sk-xxx")
- Azure OpenAI:
from autogen_ext.models.openai import AzureOpenAIChatCompletionClient
model_client = AzureOpenAIChatCompletionClient(azure_deployment="gpt-4o",azure_endpoint="https://<your-endpoint>.openai.azure.com/",model="gpt-4o",api_version="2024-09-01-preview",api_key="sk-xxx",
)
與 OpenAI 兼容的 API 的模型客戶端
您可以使用 OpenAIChatCompletionClient
連接到與 OpenAI 兼容的 API,但需要指定 base_url
和 model_info
:
from autogen_ext.models.openai import OpenAIChatCompletionClientcustom_model_client = OpenAIChatCompletionClient(model="custom-model-name",base_url="https://custom-model.com/reset/of/the/path",api_key="placeholder",model_info={"vision": True,"function_calling": True,"json_output": True,"family": "unknown",},
)
注意:我們并未測試所有與 OpenAI 兼容的 API,其中許多 API 與 OpenAI API 的工作方式不同,盡管它們可能聲稱支持 OpenAI API。在使用之前,請務必進行測試。
未來將添加對其他托管模型的支持。
模型客戶端緩存
在 v0.2
中,您可以通過 LLM 配置中的 cache_seed
參數設置緩存種子,緩存默認啟用。
llm_config = {"config_list": [{"model": "gpt-4o", "api_key": "sk-xxx"}],"seed": 42,"temperature": 0,"cache_seed": 42,
}
在 v0.4
中,緩存默認未啟用,要使用緩存,需要在模型客戶端周圍使用 ChatCompletionCache
包裝器。
您可以使用 DiskCacheStore
或 RedisStore
來存儲緩存。
pip install -U "autogen-ext[openai, diskcache, redis]"
以下是使用 diskcache
進行本地緩存的示例:
import asyncio
import tempfile
from autogen_core.models import UserMessage
from autogen_ext.models.openai import OpenAIChatCompletionClient
from autogen_ext.models.cache import ChatCompletionCache, CHAT_CACHE_VALUE_TYPE
from autogen_ext.cache_store.diskcache import DiskCacheStore
from diskcache import Cacheasync def main():with tempfile.TemporaryDirectory() as tmpdirname:# 初始化原始客戶端openai_model_client = OpenAIChatCompletionClient(model="gpt-4o")# 然后初始化 CacheStore,這里使用 diskcache.Cache# 您也可以使用 redis,如下所示:# from autogen_ext.cache_store.redis import RedisStore# import redis# redis_instance = redis.Redis()# cache_store = RedisCacheStore[CHAT_CACHE_VALUE_TYPE](redis_instance)cache_store = DiskCacheStore[CHAT_CACHE_VALUE_TYPE](Cache(tmpdirname))cache_client = ChatCompletionCache(openai_model_client, cache_store)response = await cache_client.create([UserMessage(content="Hello, how are you?", source="user")])print(response) # 應打印來自 OpenAI 的響應response = await cache_client.create([UserMessage(content="Hello, how are you?", source="user")])print(response) # 應打印緩存的響應asyncio.run(main())
助手智能體
在 v0.2
中,您可以按如下方式創建助手智能體:
from autogen.agentchat import AssistantAgentllm_config = {"config_list": [{"model": "gpt-4o", "api_key": "sk-xxx"}],"seed": 42,"temperature": 0,
}
assistant = AssistantAgent(name="assistant",system_message="You are a helpful assistant.",llm_config=llm_config,
)
在 v0.4
中,創建方式類似,但需要指定 model_client
而不是 llm_config
:
from autogen_agentchat.agents import AssistantAgent
from autogen_ext.models.openai import OpenAIChatCompletionClientmodel_client = OpenAIChatCompletionClient(model="gpt-4o", api_key="sk-xxx", seed=42, temperature=0)
assistant = AssistantAgent(name="assistant",system_message="You are a helpful assistant.",model_client=model_client,
)
然而,使用方式有所不同。在 v0.4
中,不再調用 assistant.send
,而是調用 assistant.on_messages
或 assistant.on_messages_stream
來處理傳入消息。此外,on_messages
和 on_messages_stream
方法是異步的,后者返回一個異步生成器,用于流式傳輸智能體的內部思考過程。
以下是在 v0.4
中直接調用助手智能體的示例,延續上述代碼:
import asyncio
from autogen_agentchat.messages import TextMessage
from autogen_agentchat.agents import AssistantAgent
from autogen_core import CancellationToken
from autogen_ext.models.openai import OpenAIChatCompletionClientasync def main() -> None:model_client = OpenAIChatCompletionClient(model="gpt-4o", seed=42, temperature=0)assistant = AssistantAgent(name="assistant",system_message="You are a helpful assistant.",model_client=model_client,)cancellation_token = CancellationToken()response = await assistant.on_messages([TextMessage(content="Hello!", source="user")], cancellation_token)print(response)asyncio.run(main())
CancellationToken
可用于在調用 cancellation_token.cancel()
時異步取消請求,這將導致 on_messages
調用的 await
引發 CancelledError
。
多模態智能體
v0.4
中的 AssistantAgent
如果模型客戶端支持,則支持多模態輸入。模型客戶端的 vision
能力用于確定智能體是否支持多模態輸入。
import asyncio
from pathlib import Path
from autogen_agentchat.messages import MultiModalMessage
from autogen_agentchat.agents import AssistantAgent
from autogen_core import CancellationToken, Image
from autogen_ext.models.openai import OpenAIChatCompletionClientasync def main() -> None:model_client = OpenAIChatCompletionClient(model="gpt-4o", seed=42, temperature=0)assistant = AssistantAgent(name="assistant",system_message="You are a helpful assistant.",model_client=model_client,)cancellation_token = CancellationToken()message = MultiModalMessage(content=["Here is an image:", Image.from_file(Path("test.png"))],source="user",)response = await assistant.on_messages([message], cancellation_token)print(response)asyncio.run(main())
用戶代理
在 v0.2
中,您可以按如下方式創建用戶代理:
from autogen.agentchat import UserProxyAgentuser_proxy = UserProxyAgent(name="user_proxy",human_input_mode="NEVER",max_consecutive_auto_reply=10,code_execution_config=False,llm_config=False,
)
此用戶代理將通過控制臺接收用戶輸入,如果傳入消息以 “TERMINATE” 結尾,則會終止。
在 v0.4
中,用戶代理只是一個僅接收用戶輸入的智能體,無需其他特殊配置。您可以按如下方式創建用戶代理:
from autogen_agentchat.agents import UserProxyAgentuser_proxy = UserProxyAgent("user_proxy")
有關更多詳細信息以及如何使用超時自定義輸入函數,請參閱 UserProxyAgent
。
可對話智能體和注冊回復
在 v0.2
中,您可以按如下方式創建可對話智能體并注冊回復函數:
from typing import Any, Dict, List, Optional, Tuple, Union
from autogen.agentchat import ConversableAgentllm_config = {"config_list": [{"model": "gpt-4o", "api_key": "sk-xxx"}],"seed": 42,"temperature": 0,
}
conversable_agent = ConversableAgent(name="conversable_agent",system_message="You are a helpful assistant.",llm_config=llm_config,code_execution_config={"work_dir": "coding"},human_input_mode="NEVER",max_consecutive_auto_reply=10,
)def reply_func(recipient: ConversableAgent,messages: Optional[List[Dict]] = None,sender: Optional[Agent] = None,config: Optional[Any] = None,
) -> Tuple[bool, Union[str, Dict, None]]:# 自定義回復邏輯return True, "Custom reply"# 注冊回復函數
conversable_agent.register_reply([ConversableAgent], reply_func, position=0)
# 注意:異步回復函數僅在使用異步發送時調用
在 v0.4
中,我們可以簡單地創建一個自定義智能體,并實現 on_messages
、on_reset
和 produced_message_types
方法,而無需猜測 reply_func
的功能、其參數以及 position
的值。
from typing import Sequence
from autogen_core import CancellationToken
from autogen_agentchat.agents import BaseChatAgent
from autogen_agentchat.messages import TextMessage, ChatMessage
from autogen_agentchat.base import Responseclass CustomAgent(BaseChatAgent):async def on_messages(self, messages: Sequence[ChatMessage], cancellation_token: CancellationToken) -> Response:return Response(chat_message=TextMessage(content="Custom reply", source=self.name))async def on_reset(self, cancellation_token: CancellationToken) -> None:pass@propertydef produced_message_types(self) -> Sequence[type[ChatMessage]]:return (TextMessage,)
然后,您可以像使用 AssistantAgent
一樣使用自定義智能體。有關更多詳細信息,請參閱自定義智能體教程。
保存和加載智能體狀態
在 v0.2
中,沒有內置方法來保存和加載智能體的狀態,您需要自己實現,通過導出 ConversableAgent
的 chat_messages
屬性,并通過 chat_messages
參數重新導入。
在 v0.4
中,您可以在智能體上調用 save_state
和 load_state
方法來保存和加載其狀態。
import asyncio
import json
from autogen_agentchat.messages import TextMessage
from autogen_agentchat.agents import AssistantAgent
from autogen_core import CancellationToken
from autogen_ext.models.openai import OpenAIChatCompletionClientasync def main() -> None:model_client = OpenAIChatCompletionClient(model="gpt-4o", seed=42, temperature=0)assistant = AssistantAgent(name="assistant",system_message="You are a helpful assistant.",model_client=model_client,)cancellation_token = CancellationToken()response = await assistant.on_messages([TextMessage(content="Hello!", source="user")], cancellation_token)print(response)# 保存狀態state = await assistant.save_state()# (可選)將狀態寫入磁盤with open("assistant_state.json", "w") as f:json.dump(state, f)# (可選)從磁盤加載狀態with open("assistant_state.json", "r") as f:state = json.load(f)print(state) # 檢查狀態,其中包含聊天歷史# 繼續聊天response = await assistant.on_messages([TextMessage(content="Tell me a joke.", source="user")], cancellation_token)print(response)# 加載狀態,使智能體恢復到最后一條消息之前的狀態await assistant.load_state(state)# 再次進行相同的聊天response = await assistant.on_messages([TextMessage(content="Tell me a joke.", source="user")], cancellation_token)asyncio.run(main())
您也可以在任何團隊(如 RoundRobinGroupChat
)上調用 save_state
和 load_state
來保存和加載整個團隊的狀態。
雙智能體聊天
在 v0.2
中,您可以按如下方式創建用于代碼執行的雙智能體聊天:
from autogen.coding import LocalCommandLineCodeExecutor
from autogen.agentchat import AssistantAgent, UserProxyAgentllm_config = {"config_list": [{"model": "gpt-4o", "api_key": "sk-xxx"}],"seed": 42,"temperature": 0,
}assistant = AssistantAgent(name="assistant",system_message="You are a helpful assistant. Write all code in python. Reply only 'TERMINATE' if the task is done.",llm_config=llm_config,is_termination_msg=lambda x: x.get("content", "").rstrip().endswith("TERMINATE"),
)user_proxy = UserProxyAgent(name="user_proxy",human_input_mode="NEVER",max_consecutive_auto_reply=10,code_execution_config={"code_executor": LocalCommandLineCodeExecutor(work_dir="coding")},llm_config=False,is_termination_msg=lambda x: x.get("content", "").rstrip().endswith("TERMINATE"),
)chat_result = user_proxy.initiate_chat(assistant, message="Write a python script to print 'Hello, world!'")
# Intermediate messages are printed to the console directly.
print(chat_result)
在 v0.4
中,您可以按如下方式創建用于代碼執行的雙智能體聊天:
import asyncio
from autogen_agentchat.agents import AssistantAgent, CodeExecutorAgent
from autogen_agentchat.teams import RoundRobinGroupChat
from autogen_agentchat.conditions import TextMentionTermination, MaxMessageTermination
from autogen_agentchat.ui import Console
from autogen_ext.code_executors.local import LocalCommandLineCodeExecutor
from autogen_ext.models.openai import OpenAIChatCompletionClientasync def main() -> None:model_client = OpenAIChatCompletionClient(model="gpt-4o", seed=42, temperature=0)assistant = AssistantAgent(name="assistant",system_message="You are a helpful assistant. Write all code in python. Reply only 'TERMINATE' if the task is done.",model_client=model_client,)code_executor = CodeExecutorAgent(name="code_executor",code_executor=LocalCommandLineCodeExecutor(work_dir="coding"),)# The termination condition is a combination of text termination and max message termination, either of which will cause the chat to terminate.termination = TextMentionTermination("TERMINATE") | MaxMessageTermination(10)# The group chat will alternate between the assistant and the code executor.group_chat = RoundRobinGroupChat([assistant, code_executor], termination_condition=termination)# `run_stream` returns an async generator to stream the intermediate messages.stream = group_chat.run_stream(task="Write a python script to print 'Hello, world!'")# `Console` is a simple UI to display the stream.await Console(stream)asyncio.run(main())
工具使用
在 v0.2
中,要創建一個使用工具的聊天機器人,必須有兩個智能體,一個用于調用工具,一個用于執行工具。對于每個用戶請求,都需要發起一個雙智能體聊天。
from autogen.agentchat import AssistantAgent, UserProxyAgent, register_functionllm_config = {"config_list": [{"model": "gpt-4o", "api_key": "sk-xxx"}],"seed": 42,"temperature": 0,
}tool_caller = AssistantAgent(name="tool_caller",system_message="You are a helpful assistant. You can call tools to help user.",llm_config=llm_config,max_consecutive_auto_reply=1, # 設置為 1,以便在每個助手回復后返回應用程序,因為我們正在構建一個聊天機器人
)tool_executor = UserProxyAgent(name="tool_executor",human_input_mode="NEVER",code_execution_config=False,llm_config=False,
)def get_weather(city: str) -> str:return f"The weather in {city} is 72 degree and sunny."# 將工具函數注冊到工具調用者和執行者
register_function(get_weather, caller=tool_caller, executor=tool_executor)while True:user_input = input("User: ")if user_input == "exit":breakchat_result = tool_executor.initiate_chat(tool_caller,message=user_input,summary_method="reflection_with_llm", # 讓模型反思工具使用,設置為 "last_msg" 可直接返回工具調用結果)print("Assistant:", chat_result.summary)
在 v0.4
中,實際上只需要一個智能體 ——AssistantAgent
—— 來處理工具調用和工具執行。
import asynciofrom autogen_core import CancellationTokenfrom autogen_ext.models.openai import OpenAIChatCompletionClientfrom autogen_agentchat.agents import AssistantAgentfrom autogen_agentchat.messages import TextMessagedef get_weather(city: str) -> str: # 也可以是異步工具return f"The weather in {city} is 72 degree and sunny."async def main() -> None:model_client = OpenAIChatCompletionClient(model="gpt-4o", seed=42, temperature=0)assistant = AssistantAgent(name="assistant",system_message="You are a helpful assistant. You can call tools to help user.",model_client=model_client,tools=[get_weather],reflect_on_tool_use=True, # 設置為 True 讓模型反思工具使用,設置為 False 可直接返回工具調用結果)while True:user_input = input("User: ")if user_input == "exit":breakresponse = await assistant.on_messages([TextMessage(content=user_input, source="user")], CancellationToken())print("Assistant:", response.chat_message.content)asyncio.run(main())
在諸如 RoundRobinGroupChat
這樣的群聊中使用配備工具的智能體時,只需像上面那樣將工具添加到智能體中,并創建一個包含這些智能體的群聊即可。
聊天結果
在 v0.2
中,您可以從 initiate_chat
方法獲取一個 ChatResult
對象。例如:
chat_result = tool_executor.initiate_chat(tool_caller,message=user_input,summary_method="reflection_with_llm",
)print(chat_result.summary) # 獲取聊天的 LLM 反思總結
print(chat_result.chat_history) # 獲取聊天歷史
print(chat_result.cost) # 獲取聊天成本
print(chat_result.human_input) # 獲取聊天請求的人工輸入
有關更多詳細信息,請參閱 ChatResult
文檔。
在 v0.4
中,您可以從 run
或 run_stream
方法獲取一個 TaskResult
對象。TaskResult
對象包含 messages
,它是聊天的消息歷史,包括智能體的私有(工具調用等)和公共消息。
TaskResult
和 ChatResult
之間有一些顯著差異:
TaskResult
中的messages
列表使用與ChatResult.chat_history
列表不同的消息格式。- 沒有
summary
字段。應用程序需要決定如何使用messages
列表總結聊天。 TaskResult
對象中不提供human_input
,因為可以通過使用source
字段過濾從messages
列表中提取用戶輸入。TaskResult
對象中不提供cost
,但是您可以根據令牌使用情況計算成本。添加成本計算將是一個很好的社區擴展。有關社區擴展,請參閱。
v0.2 和 v0.4 消息之間的轉換
您可以使用以下轉換函數在 autogen_agentchat.base.TaskResult.messages
中的 v0.4
消息和 ChatResult.chat_history
中的 v0.2
消息之間進行轉換。
from typing import Any, Dict, List, Literalfrom autogen_agentchat.messages import (AgentEvent,ChatMessage,HandoffMessage,MultiModalMessage,StopMessage,TextMessage,ToolCallExecutionEvent,ToolCallRequestEvent,ToolCallSummaryMessage,
)from autogen_core import FunctionCall, Imagefrom autogen_core.models import FunctionExecutionResultdef convert_to_v02_message(message: AgentEvent | ChatMessage,role: Literal["assistant", "user", "tool"],image_detail: Literal["auto", "high", "low"] = "auto",
) -> Dict[str, Any]:"""將 v0.4 AgentChat 消息轉換為 v0.2 消息。Args:message (AgentEvent | ChatMessage): 要轉換的消息。role (Literal["assistant", "user", "tool"]): 消息的角色。image_detail (Literal["auto", "high", "low"], 可選): 多模態消息中圖像內容的詳細級別。默認為 "auto"。Returns:Dict[str, Any]: 轉換后的 AutoGen v0.2 消息。"""v02_message: Dict[str, Any] = {}if isinstance(message, TextMessage | StopMessage | HandoffMessage | ToolCallSummaryMessage):v02_message = {"content": message.content, "role": role, "name": message.source}elif isinstance(message, MultiModalMessage):v02_message = {"content": [], "role": role, "name": message.source}for modal in message.content:if isinstance(modal, str):v02_message["content"].append({"type": "text", "text": modal})elif isinstance(modal, Image):v02_message["content"].append(modal.to_openai_format(detail=image_detail))else:raise ValueError(f"無效的多模態消息內容: {modal}")elif isinstance(message, ToolCallRequestEvent):v02_message = {"tool_calls": [], "role": "assistant", "content": None, "name": message.source}for tool_call in message.content:v02_message["tool_calls"].append({"id": tool_call.id,"type": "function","function": {"name": tool_call.name, "args": tool_call.arguments},})elif isinstance(message, ToolCallExecutionEvent):tool_responses: List[Dict[str, str]] = []for tool_result in message.content:tool_responses.append({"tool_call_id": tool_result.call_id,"role": "tool","content": tool_result.content,})content = "\n\n".join([response["content"] for response in tool_responses])v02_message = {"tool_responses": tool_responses, "role": "tool", "content": content}else:raise ValueError(f"無效的消息類型: {type(message)}")return v02_messagedef convert_to_v04_message(message: Dict[str, Any]) -> AgentEvent | ChatMessage:"""將 v0.2 消息轉換為 v0.4 AgentChat 消息。"""if "tool_calls" in message:tool_calls: List[FunctionCall] = []for tool_call in message["tool_calls"]:tool_calls.append(FunctionCall(id=tool_call["id"],name=tool_call["function"]["name"],arguments=tool_call["function"]["args"],))return ToolCallRequestEvent(source=message["name"], content=tool_calls)elif "tool_responses" in message:tool_results: List[FunctionExecutionResult] = []for tool_response in message["tool_responses"]:tool_results.append(FunctionExecutionResult(call_id=tool_response["tool_call_id"],content=tool_response["content"],))return ToolCallExecutionEvent(source="tools", content=tool_results)elif isinstance(message["content"], list):content: List[str | Image] = []for modal in message["content"]: # type: ignoreif modal["type"] == "text": # type: ignorecontent.append(modal["text"]) # type: ignoreelse:content.append(Image.from_uri(modal["image_url"]["url"])) # type: ignorereturn MultiModalMessage(content=content, source=message["name"])elif isinstance(message["content"], str):return TextMessage(content=message["content"], source=message["name"])else:raise ValueError(f"無法轉換消息: {message}")
群聊
在 v0.2
中,您需要創建一個 GroupChat
類并將其傳遞給 GroupChatManager
,并且需要有一個用戶代理作為參與者來發起聊天。對于一個簡單的作家和評論家場景,您可以如下操作:
from autogen.agentchat import AssistantAgent, GroupChat, GroupChatManagerllm_config = {"config_list": [{"model": "gpt-4o", "api_key": "sk-xxx"}],"seed": 42,"temperature": 0,
}writer = AssistantAgent(name="writer",description="A writer.",system_message="You are a writer.",llm_config=llm_config,is_termination_msg=lambda x: x.get("content", "").rstrip().endswith("APPROVE"),
)critic = AssistantAgent(name="critic",description="A critic.",system_message="You are a critic, provide feedback on the writing. Reply only 'APPROVE' if the task is done.",llm_config=llm_config,
)# 創建一個包含作家和評論家的群聊
groupchat = GroupChat(agents=[writer, critic], messages=[], max_round=12)# 創建一個群聊管理器來管理群聊,使用輪詢選擇方法
manager = GroupChatManager(groupchat=groupchat, llm_config=llm_config, speaker_selection_method="round_robin")# 與編輯者發起聊天,中間消息將直接打印到控制臺
result = editor.initiate_chat(manager,message="Write a short story about a robot that discovers it has feelings.",
)print(result.summary)
在 v0.4
中,您可以使用 RoundRobinGroupChat
來實現相同的行為。
import asynciofrom autogen_agentchat.agents import AssistantAgentfrom autogen_agentchat.teams import RoundRobinGroupChatfrom autogen_agentchat.conditions import TextMentionTerminationfrom autogen_agentchat.ui import Consolefrom autogen_ext.models.openai import OpenAIChatCompletionClientasync def main() -> None:model_client = OpenAIChatCompletionClient(model="gpt-4o", seed=42, temperature=0)writer = AssistantAgent(name="writer",description="A writer.",system_message="You are a writer.",model_client=model_client,)critic = AssistantAgent(name="critic",description="A critic.",system_message="You are a critic, provide feedback on the writing. Reply only 'APPROVE' if the task is done.",model_client=model_client,)# 終止條件是文本終止,當收到 "APPROVE" 文本時聊天將終止termination = TextMentionTermination("APPROVE")# 群聊將在作家和評論家之間交替group_chat = RoundRobinGroupChat([writer, critic], termination_condition=termination, max_turns=12)# `run_stream` 返回一個異步生成器來流式傳輸中間消息stream = group_chat.run_stream(task="Write a short story about a robot that discovers it has feelings.")# `Console` 是一個簡單的 UI 來顯示流await Console(stream)asyncio.run(main())
對于基于 LLM 的發言者選擇,您可以使用 SelectorGroupChat
代替。有關更多詳細信息,請參閱 Selector Group Chat
教程和 SelectorGroupChat
。
注意:在 v0.4
中,在群聊中使用工具時不需要在用戶代理上注冊函數。您可以像在工具使用部分所示的那樣將工具函數傳遞給 AssistantAgent
。智能體將在需要時自動調用工具。如果您的工具輸出格式不正確,您可以使用 reflect_on_tool_use
參數讓模型反思工具使用。
恢復群聊
在 v0.2
中,恢復群聊有點復雜。您需要顯式地保存群聊消息,并在想要恢復聊天時重新加載它們。有關更多詳細信息,請參閱 v0.2
中的恢復群聊。
在 v0.4
中,您可以簡單地再次使用相同的群聊對象調用 run
或 run_stream
來恢復聊天。要導出和加載狀態,您可以使用 save_state
和 load_state
方法。
import asyncio
import jsonfrom autogen_agentchat.agents import AssistantAgentfrom autogen_agentchat.teams import RoundRobinGroupChatfrom autogen_agentchat.conditions import TextMentionTerminationfrom autogen_agentchat.ui import Consolefrom autogen_ext.models.openai import OpenAIChatCompletionClientdef create_team() -> RoundRobinGroupChat:model_client = OpenAIChatCompletionClient(model="gpt-4o", seed=42, temperature=0)writer = AssistantAgent(name="writer",description="A writer.",system_message="You are a writer.",model_client=model_client,)critic = AssistantAgent(name="critic",description="A critic.",system_message="You are a critic, provide feedback on the writing. Reply only 'APPROVE' if the task is done.",model_client=model_client,)# 終止條件是文本終止,當收到 "APPROVE" 文本時聊天將終止termination = TextMentionTermination("APPROVE")# 群聊將在作家和評論家之間交替group_chat = RoundRobinGroupChat([writer, critic], termination_condition=termination)return group_chatasync def main() -> None:# 創建團隊group_chat = create_team()# `run_stream` 返回一個異步生成器來流式傳輸中間消息stream = group_chat.run_stream(task="Write a short story about a robot that discovers it has feelings.")# `Console` 是一個簡單的 UI 來顯示流await Console(stream)# 保存群聊和所有參與者的狀態state = await group_chat.save_state()with open("group_chat_state.json", "w") as f:json.dump(state, f)# 創建一個具有相同參與者配置的新團隊group_chat = create_team()# 加載群聊和所有參與者的狀態with open("group_chat_state.json", "r") as f:state = json.load(f)await group_chat.load_state(state)# 恢復聊天stream = group_chat.run_stream(task="Translate the story into Chinese.")await Console(stream)asyncio.run(main())
帶工具使用的群聊
在 v0.2
的群聊中,若要使用工具,需在用戶代理上注冊工具函數,并將用戶代理納入群聊。如此,其他智能體發出的工具調用會被路由至用戶代理執行。但我們發現這種方式存在諸多問題,比如工具調用路由可能無法按預期工作,且不支持函數調用的模型無法接收工具調用請求與結果。
在 v0.4
中,無需在用戶代理上注冊工具函數。因為在 v0.4
里,智能體能夠直接調用工具,只要在創建 AssistantAgent
時將工具函數作為參數傳入即可。例如,在群聊場景下,若有多個智能體,每個智能體都可按如下方式配置工具:
import asyncio
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.teams import RoundRobinGroupChat
from autogen_agentchat.conditions import TextMentionTermination
from autogen_agentchat.ui import Console
from autogen_ext.models.openai import OpenAIChatCompletionClientdef get_weather(city: str) -> str:return f"The weather in {city} is 72 degree and sunny."async def main() -> None:model_client = OpenAIChatCompletionClient(model="gpt-4o", seed=42, temperature=0)agent1 = AssistantAgent(name="agent1",system_message="You can use the get_weather tool to answer user questions.",model_client=model_client,tools=[get_weather])agent2 = AssistantAgent(name="agent2",system_message="You are another agent in the group chat.",model_client=model_client)termination = TextMentionTermination("END")group_chat = RoundRobinGroupChat([agent1, agent2], termination_condition=termination)stream = group_chat.run_stream(task="Ask about the weather in New York")await Console(stream)asyncio.run(main())
在上述示例中,agent1
被配置為可使用 get_weather
工具。當群聊運行時,若 agent1
認為需要,便會調用該工具。
帶自定義選擇器(Stateflow)的群聊
在 v0.2
中,沒有直接支持帶自定義選擇器(如 Stateflow)的群聊功能。
在 v0.4
中,SelectorGroupChat
類提供了基于自定義邏輯選擇發言者的功能。通過自定義選擇器函數,可以實現類似 Stateflow 的復雜狀態流轉邏輯。例如,根據消息內容、智能體狀態等因素決定下一個發言的智能體。以下是一個簡單示例:
import asyncio
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.teams import SelectorGroupChat
from autogen_agentchat.conditions import TextMentionTermination
from autogen_agentchat.ui import Console
from autogen_ext.models.openai import OpenAIChatCompletionClientdef custom_selector(team, messages):# 簡單示例:總是選擇第一個智能體發言return team.agents[0]async def main() -> None:model_client = OpenAIChatCompletionClient(model="gpt-4o", seed=42, temperature=0)agent1 = AssistantAgent(name="agent1",system_message="Agent 1 in the group.",model_client=model_client)agent2 = AssistantAgent(name="agent2",system_message="Agent 2 in the group.",model_client=model_client)termination = TextMentionTermination("END")group_chat = SelectorGroupChat([agent1, agent2], termination_condition=termination, selector=custom_selector)stream = group_chat.run_stream(task="Start the group chat")await Console(stream)asyncio.run(main())
在這個示例中,custom_selector
函數簡單地選擇第一個智能體發言。實際應用中,可以根據更復雜的邏輯來選擇發言者,實現類似 Stateflow 的功能。
嵌套聊天
在 v0.2
中,實現嵌套聊天較為復雜,需要手動管理不同智能體之間的交互以及消息傳遞,并且難以跟蹤和管理嵌套層次。
在 v0.4
中,由于其事件驅動和分層的架構,嵌套聊天變得更加直觀和易于管理。例如,可以在一個群聊中,讓某個智能體發起一個子聊天,而無需復雜的手動管理。以下是一個簡單的概念示例:
import asyncio
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.teams import RoundRobinGroupChat
from autogen_agentchat.conditions import TextMentionTermination
from autogen_agentchat.ui import Console
from autogen_ext.models.openai import OpenAIChatCompletionClientasync def main() -> None:model_client = OpenAIChatCompletionClient(model="gpt-4o", seed=42, temperature=0)parent_agent1 = AssistantAgent(name="parent_agent1",system_message="Parent agent 1.",model_client=model_client)parent_agent2 = AssistantAgent(name="parent_agent2",system_message="Parent agent 2.",model_client=model_client)child_agent1 = AssistantAgent(name="child_agent1",system_message="Child agent 1 for nested chat.",model_client=model_client)child_agent2 = AssistantAgent(name="child_agent2",system_message="Child agent 2 for nested chat.",model_client=model_client)child_termination = TextMentionTermination("CHILD_END")child_group_chat = RoundRobinGroupChat([child_agent1, child_agent2], termination_condition=child_termination)def nested_chat_handler(parent_messages):async def run_nested_chat():task = "Some task for nested chat based on parent messages"stream = child_group_chat.run_stream(task)async for message in stream:# 可以在這里處理子聊天的消息,例如發送回父聊天passasyncio.create_task(run_nested_chat())parent_agent1.register_event_handler("on_message", nested_chat_handler)parent_termination = TextMentionTermination("PARENT_END")parent_group_chat = RoundRobinGroupChat([parent_agent1, parent_agent2], termination_condition=parent_termination)stream = parent_group_chat.run_stream(task="Start the parent chat")await Console(stream)asyncio.run(main())
在上述示例中,parent_agent1
注冊了一個事件處理程序,當收到消息時,會發起一個子群聊 child_group_chat
。
順序聊天
在 v0.2
中,實現順序聊天需要手動控制智能體之間的消息傳遞順序,并且難以動態調整順序。
在 v0.4
中,可以通過自定義團隊類或者利用現有的團隊類(如 RoundRobinGroupChat
并結合自定義邏輯)來實現順序聊天。例如,創建一個新的團隊類,按照預定義的順序依次讓智能體發言:
import asyncio
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.teams import BaseGroupChat
from autogen_agentchat.conditions import TextMentionTermination
from autogen_agentchat.ui import Console
from autogen_ext.models.openai import OpenAIChatCompletionClientclass SequentialChatGroup(BaseGroupChat):def __init__(self, agents, termination_condition):super().__init__(agents, termination_condition)self.current_agent_index = 0async def _select_next_speaker(self, messages):speaker = self.agents[self.current_agent_index]self.current_agent_index = (self.current_agent_index + 1) % len(self.agents)return speakerasync def main() -> None:model_client = OpenAIChatCompletionClient(model="gpt-4o", seed=42, temperature=0)agent1 = AssistantAgent(name="agent1",system_message="First agent in sequential chat.",model_client=model_client)agent2 = AssistantAgent(name="agent2",system_message="Second agent in sequential chat.",model_client=model_client)termination = TextMentionTermination("END")sequential_group_chat = SequentialChatGroup([agent1, agent2], termination_condition=termination)stream = sequential_group_chat.run_stream(task="Start sequential chat")await Console(stream)asyncio.run(main())
在上述示例中,SequentialChatGroup
類繼承自 BaseGroupChat
,并自定義了 _select_next_speaker
方法,按照順序選擇智能體發言。
GPTAssistantAgent
在 v0.2
中,沒有專門的 GPTAssistantAgent
類。
在 v0.4
中,GPTAssistantAgent
是 AssistantAgent
的一個變體,專門用于與 OpenAI 的 GPT Assistant API 進行交互。使用 GPTAssistantAgent
時,需要提供 assistant_id
,它代表在 OpenAI 平臺上創建的特定助手。例如:
import asyncio
from autogen_agentchat.agents import GPTAssistantAgent
from autogen_agentchat.messages import TextMessage
from autogen_core import CancellationToken
from autogen_ext.models.openai import OpenAIChatCompletionClientasync def main() -> None:model_client = OpenAIChatCompletionClient(model="gpt-4o", api_key="sk-xxx")assistant = GPTAssistantAgent(name="gpt_assistant",assistant_id="your_assistant_id",model_client=model_client)cancellation_token = CancellationToken()response = await assistant.on_messages([TextMessage(content="Hello!", source="user")], cancellation_token)print(response)asyncio.run(main())
GPTAssistantAgent
允許用戶利用在 OpenAI 平臺上預先配置好的助手功能,例如自定義工具、知識庫等。
長上下文處理
在 v0.2
中,長上下文處理較為困難,因為沒有內置的機制來有效管理和總結長對話歷史。用戶需要手動處理上下文,例如截斷消息歷史或者使用外部工具進行總結。
在 v0.4
中,通過引入智能體狀態管理和更靈活的消息處理機制,長上下文處理得到了顯著改善。例如,AssistantAgent
類提供了 summary
方法,可以在需要時對對話歷史進行總結。此外,v0.4
的架構允許更方便地集成外部總結工具或者自定義總結邏輯。以下是一個簡單示例,展示如何在對話過程中進行總結:
import asyncio
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.messages import TextMessage
from autogen_core import CancellationToken
from autogen_ext.models.openai import OpenAIChatCompletionClientasync def main() -> None:model_client = OpenAIChatCompletionClient(model="gpt-4o", seed=42, temperature=0)assistant = AssistantAgent(name="assistant",system_message="You are a helpful assistant.",model_client=model_client)cancellation_token = CancellationToken()messages = [TextMessage(content="First message", source="user"),TextMessage(content="Second message", source="user")]for message in messages:response = await assistant.on_messages([message], cancellation_token)summary = await assistant.summary()print("Summary:", summary)asyncio.run(main())
在這個示例中,隨著對話消息的積累,調用 assistant.summary()
方法可以獲取對話的總結,有助于管理長上下文。
可觀測性和控制
在 v0.2
中,可觀測性和控制能力有限。例如,很難實時監控智能體之間的交互,并且對智能體行為的控制大多依賴于手動配置參數。
在 v0.4
中,由于其事件驅動的架構,提供了更好的可觀測性和控制能力。可以通過注冊事件處理程序來監控智能體的各種事件,如消息接收、發送、工具調用等。例如,以下代碼展示如何監控智能體發送消息的事件:
import asyncio
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.messages import TextMessage
from autogen_core import CancellationToken
from autogen_ext.models.openai import OpenAIChatCompletionClientdef message_sent_handler(event):print(f"Message sent: {event.chat_message.content}")async def main() -> None:model_client = OpenAIChatCompletionClient(model="gpt-4o", seed=42, temperature=0)assistant = AssistantAgent(name="assistant",system_message="You are a helpful assistant.",model_client=model_client)assistant.register_event_handler("on_message_sent", message_sent_handler)cancellation_token = CancellationToken()response = await assistant.on_messages([TextMessage(content="Hello!", source="user")], cancellation_token)asyncio.run(main())
此外,通過 CancellationToken
可以在運行時取消智能體的操作,實現對智能體行為的動態控制。
代碼執行器
在 v0.2
中,代碼執行器主要通過 CodeExecutor
類及其子類(如 LocalCodeExecutor
和 RemoteCodeExecutor
)實現。例如,使用 LocalCommandLineCodeExecutor
來在本地執行代碼:
from autogen.coding import LocalCommandLineCodeExecutorcode_executor = LocalCommandLineCodeExecutor()
result = code_executor.run("print('Hello, World!')")
print(result)
在 v0.4
中,代碼執行器的功能得到了進一步整合和改進。CodeExecutor
類得到了增強,并且可以更方便地與智能體集成。例如,在 AssistantAgent
中,可以直接配置代碼執行器,使得智能體在需要時能夠執行代碼。以下是一個示例:
import asyncio
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.messages import TextMessage
from autogen_core import CancellationToken
from autogen_ext.models.openai import OpenAIChatCompletionClient
from autogen_agentchat.code_execution import LocalCodeExecutorasync def main() -> None:model_client = OpenAIChatCompletionClient(model="gpt-4o", seed=42, temperature=0)code_executor = LocalCodeExecutor()assistant = AssistantAgent(name="assistant",system_message="You can execute code when needed.",model_client=model_client,code_executor=code_executor)cancellation_token = CancellationToken()response = await assistant.on_messages([TextMessage(content="Execute print('Hello, World!')", source="user")], cancellation_token)print(response)asyncio.run(main())
在這個示例中,AssistantAgent
配置了 LocalCodeExecutor
,當收到需要執行代碼的消息時,智能體可以調用代碼執行器來執行代碼。