AutoGen 技术博客系列 九:从 v0.2 到 v0.4 的迁移指南

本系列博文在掘金同步发布, 更多优质文章,请关注本人掘金账号:
人肉推土机的掘金账号

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_urlmodel_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 包装器。

您可以使用 DiskCacheStoreRedisStore 来存储缓存。

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_messagesassistant.on_messages_stream 来处理传入消息。此外,on_messageson_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_messageson_resetproduced_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 中,没有内置方法来保存和加载智能体的状态,您需要自己实现,通过导出 ConversableAgentchat_messages 属性,并通过 chat_messages 参数重新导入。

v0.4 中,您可以在智能体上调用 save_stateload_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_stateload_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 中,您可以从 runrun_stream 方法获取一个 TaskResult 对象。TaskResult 对象包含 messages,它是聊天的消息历史,包括智能体的私有(工具调用等)和公共消息。

TaskResultChatResult 之间有一些显著差异:

  • 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 中,您可以简单地再次使用相同的群聊对象调用 runrun_stream 来恢复聊天。要导出和加载状态,您可以使用 save_stateload_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 中,GPTAssistantAgentAssistantAgent 的一个变体,专门用于与 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 类及其子类(如 LocalCodeExecutorRemoteCodeExecutor)实现。例如,使用 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,当收到需要执行代码的消息时,智能体可以调用代码执行器来执行代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/896124.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习每周学习总结Y1(Yolov5 调用官方权重进行检测 )

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客Y1中的内容 &#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 ** 注意该训练营出现故意不退押金&#xff0c;恶意揣测偷懒用假的结果冒充真实打卡记录&#xff0c;在提出能够拿到视频录像…

为AI聊天工具添加一个知识系统 之117 详细设计之58 思维导图及观察者效应 之2 概念全景图

&#xff08;说明&#xff1a;本文和上一篇问题基本相同&#xff0c;但换了一个模型 deepseek-r1&#xff09; Q1227、在提出项目“为使用AI聊天工具的聊天者加挂一个专属的知识系统”后&#xff0c;我们已经进行了了大量的讨论-持续了近三个月了。这些讨论整体淋漓尽致体现了…

2012年IMO几何预选题第6题

设有非等腰的 △ A B C \triangle ABC △ABC, O O O 和 I I I 分别为外心和内心. 在边 A C AC AC, A B AB AB 上分别存在两点 E E E 和 F F F, 使得 C D C E A B CDCEAB CDCEAB, B F B D A C BFBDAC BFBDAC. 设 ( B D F ) (BDF) (BDF) 和 ( C D E ) (CDE) (CDE)…

为Eclipse IDE安装插件IBM编程助手watsonx Code Assistant

从Eclipse IDE 安装 从Eclipse IDE 安装插件&#xff1a; _1、在Eclipse IDE 中&#xff0c;单击帮助菜单&#xff0c;然后选择EclipseMarketplace。 _2、根据您计划进行的工作类型选择安装方式&#xff1a; 有关代码建议、代码解释、代码文档和单元测试的集成生成式人工智能&a…

Linux基本指令(三)+ 权限

文章目录 基本指令grep打包和压缩zip/unzipLinux和windows压缩包互传tar&#xff08;重要&#xff09;Linux和Linux压缩包互传 bcuname -r常用的热键关机外壳程序 知识点打包和压缩 Linux中的权限用户权限 基本指令 grep 1. grep可以过滤文本行 2. 把包含9的文本行过滤出来了 …

【部署优化篇十四】【十万字全景拆解:GitHub Actions自动化流水线设计圣经(DeepSeek工业级实践大公开)】

一、从手工作坊到智能工厂:CI/CD的革命之路 想象一下,你所在的公司每天要手工组装1000台手机,每个环节都靠老师傅肉眼检查——这就是没有CI/CD的软件开发现状。GitHub Actions的出现,就像给软件交付装上了特斯拉的超级工厂流水线。 DeepSeek的CI/CD演进史就是一部血泪史:…

“死”循环(查漏补缺)

以下代码会死循环&#xff1a; #include<iostream> using namespace std; int n,res; int main(){cin>>n;for(int i1;i<n;i){int xi;while(i){int ti%10;i/10;if(t2||t0||t1||t9){resx;break;}}}cout<<res<<endl;return 0; } 你的代码中存在一个逻…

力扣LeetCode: 2506 统计相似字符串对的数目

题目&#xff1a; 给你一个下标从 0 开始的字符串数组 words 。 如果两个字符串由相同的字符组成&#xff0c;则认为这两个字符串 相似 。 例如&#xff0c;"abca" 和 "cba" 相似&#xff0c;因为它们都由字符 a、b、c 组成。然而&#xff0c;"aba…

关于Java 反射的简单易懂的介绍

目录 #0.总览 #1. 类的反射 ①介绍 ②获取 ③作用 获取构造函数&#xff1a; 创建实例&#xff1a; 字段操作&#xff1a; 方法操作&#xff1a; 获取修饰符&#xff1a; #2.总结 #0.总览 反射&#xff0c;官方是这样介绍它的&#xff1a; Reflection is a …

【精调】LLaMA-Factory 快速开始1: Meta-Llama-3.1-8B-Instruct

llamafactory-cli train examples/train_lora/llama3_lora_sft.yaml llamafactory-cli chat examples/inference/llama3_lora_sft.yaml llamafactory-cli export examples/merge_lora/llama3_lora_sft.yaml模型下载 git clone https://www.modelscope.cn/LLM-Research/Meta-Lla…

【07】区块链性能

7-1 基础性能优化 7-1-1 区块链性能瓶颈 总述 区块链性能指标 区块链的性能指标主要包括&#xff1a; 吞吐量&#xff1a;在固定时间内处理的交易数量 延时&#xff1a;对交易的响应和处理时间 主流区块链与中心化平台TPS对比 区块链与传统计算的对比 区块链可信且中立…

安全面试2

文章目录 简单描述一下什么是水平越权&#xff0c;什么是垂直越权&#xff0c;我要发现这两类漏洞&#xff0c;那我代码审计要注意什么地方水平越权&#xff1a;垂直越权&#xff1a;水平越权漏洞的审计重点垂直越权漏洞的审计重点 解释一下ssrf漏洞原理攻击场景修复方法 横向移…

【Linux 专栏】echo命令实验

风123456789&#xff5e;-CSDN博客 最近文章阅读排行榜 【爬虫基础】第一部分 网络通讯 P1/3-CSDN博客 【爬虫基础】第一部分 网络通讯-Socket套接字 P2/3-CSDN博客 【Linux专栏】find命令同步 实验-CSDN博客 【Linux运维】非root用户的单向免密登录_linux 单向免密-CSDN博客…

RTSP协议全解析

RTSP&#xff08;Real Time Streaming Protocol&#xff09;协议全解析 一、协议概述 定位&#xff1a;应用层协议&#xff0c;用于控制流媒体服务器&#xff08;播放、暂停、录制&#xff09;&#xff0c;媒体传输由 RTP/RTCP 实现。 特点&#xff1a; 基于文本&#xff08;…

第15届 蓝桥杯 C++编程青少组中/高级选拔赛 202401 真题答案及解析

第 1 题 【 单选题 】 表达式117 % 16 的结果是( )。 A:0 B:5 C:7 D:10 解析: % 是取模运算符,用于计算两个数相除后的余数。 计算 117 / 16,结果是 7,余数是 5。因此,117 % 16 = 5。答案: B 第 2 题 【 单选题 】 下列选项中,字符数组定义正确的是( …

qt5实现表盘的旋转效果,通过提升QLabel类

因为工作需要&#xff0c;需要实现温度的表盘展示效果 实现思路&#xff1a; 通过提示声QLabel控价类&#xff0c;实现报盘的旋转和展示效果 1. 编写一个QLabel的类MyQLabel,实现两个方法 1. void paintEvent(QPaintEvent *event); //重绘函数 2. void valueChanged(int va…

通信系统中物理层与网络层联系与区别

在通信系统中&#xff0c;物理层和网络层是OSI&#xff08;开放系统互连&#xff09;模型中的两个重要层次&#xff0c;分别位于协议栈的最底层和第三层。它们在功能、职责和实现方式上有显著的区别&#xff0c;但同时也在某些方面存在联系。以下是物理层与网络层的联系与区别的…

【深度学习】Pytorch的深入理解和研究

一、Pytorch核心理解 PyTorch 是一个灵活且强大的深度学习框架&#xff0c;广泛应用于研究和工业领域。要深入理解和研究 PyTorch&#xff0c;需要从其核心概念、底层机制以及高级功能入手。以下是对 PyTorch 的深入理解与研究的详细说明。 1. 概念 动态计算图&#xff08;D…

23种设计模式 - 解释器模式

模式定义 解释器模式&#xff08;Interpreter Pattern&#xff09;是一种行为型设计模式&#xff0c;用于为特定语言&#xff08;如数控系统的G代码&#xff09;定义文法规则&#xff0c;并构建解释器来解析和执行该语言的语句。它通过将语法规则分解为多个类&#xff0c;实现…

使用 Openpyxl 操作 Excel 文件详解

文章目录 安装安装Python3安装 openpyxl 基础操作1. 引入2. 创建工作簿和工作表3. 写入数据4. 保存工作簿5. 加载已存在的Excel6. 读取单元格的值7. 选择工作表 样式和格式化1. 引入2. 设置字体3. 设置边框4. 填充5. 设置数字格式6. 数据验证7. 公式操作 性能优化1. read_only/…