{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 顺序工作流\n\n顺序工作流是一种多智能体设计模式,其中智能体按照确定性的顺序响应。工作流中的每个智能体通过处理消息、生成响应,然后将其传递给下一个智能体来执行特定任务。该模式适用于创建确定性工作流,其中每个智能体负责完成预先指定的子任务。\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "在本示例中,我们演示了一个顺序工作流,多个智能体协作将基础产品描述转化为精美的营销文案。\n\n该流水线包含四个专业智能体:\n- **概念提取智能体**:分析初始产品描述以提取关键特征、目标受众和独特卖点(USPs)。输出为结构化分析结果,以单一文本块呈现。\n- **文案撰写智能体**:根据提取的概念创作引人入胜的营销文案。该智能体将分析洞察转化为吸引人的促销内容,以单一文本块提供连贯的叙述。\n- **格式校对智能体**:通过优化语法、提升清晰度和保持一致的语调来润色文案草稿。该智能体确保专业质量并输出格式规范的最终版本。\n- **用户交互智能体**:向用户展示最终润色后的营销文案,完成整个工作流。\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "下图展示了本示例中的顺序工作流:\n\n![顺序工作流](sequential-workflow.svg)\n\n我们将使用发布-订阅消息机制实现此工作流。\n请阅读[主题与订阅](../core-concepts/topic-and-subscription.md)了解核心概念,\n以及[广播消息](../framework/message-and-communication.ipynb#broadcast)了解API使用方法。\n\n在该流水线中,智能体通过将已完成的工作作为消息发布到序列中下一个智能体的主题来进行通信。例如,当`ConceptExtractor`完成产品描述分析后,\n它会将发现发布到`\"WriterAgent\"`主题,而`WriterAgent`已订阅该主题。这种模式贯穿流水线的每个步骤,\n每个智能体都将消息发布到序列中下一个智能体所订阅的主题。\n" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "from dataclasses import dataclass\n", "\n", "from autogen_core import (\n", " MessageContext,\n", " RoutedAgent,\n", " SingleThreadedAgentRuntime,\n", " TopicId,\n", " TypeSubscription,\n", " message_handler,\n", " type_subscription,\n", ")\n", "from autogen_core.models import ChatCompletionClient, SystemMessage, UserMessage\n", "from autogen_ext.models.openai import OpenAIChatCompletionClient" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 消息协议\n\n本示例工作流使用的消息协议是智能体用于传递工作的简单文本消息。\n" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "@dataclass\n", "class Message:\n", " content: str" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 主题\n\n工作流中的每个智能体都将订阅特定的主题类型。主题类型按序列中的智能体命名,\n这使得每个智能体都能将其工作发布给序列中的下一个智能体。\n" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "concept_extractor_topic_type = \"ConceptExtractorAgent\"\n", "writer_topic_type = \"WriterAgent\"\n", "format_proof_topic_type = \"FormatProofAgent\"\n", "user_topic_type = \"User\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 代理\n\n每个代理类都通过 {py:class}`~autogen_core.type_subscription` 装饰器定义,用于指定其订阅的主题类型。\n作为装饰器的替代方案,您也可以使用 {py:meth}`~autogen_core.AgentRuntime.add_subscription` 方法通过运行时直接订阅主题。\n\n概念提取代理负责生成产品描述的初始要点。\n" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "@type_subscription(topic_type=concept_extractor_topic_type)\n", "class ConceptExtractorAgent(RoutedAgent):\n", " def __init__(self, model_client: ChatCompletionClient) -> None:\n", " super().__init__(\"A concept extractor agent.\")\n", " self._system_message = SystemMessage(\n", " content=(\n", " \"You are a marketing analyst. Given a product description, identify:\\n\"\n", " \"- Key features\\n\"\n", " \"- Target audience\\n\"\n", " \"- Unique selling points\\n\\n\"\n", " )\n", " )\n", " self._model_client = model_client\n", "\n", " @message_handler\n", " async def handle_user_description(self, message: Message, ctx: MessageContext) -> None:\n", " prompt = f\"Product description: {message.content}\"\n", " llm_result = await self._model_client.create(\n", " messages=[self._system_message, UserMessage(content=prompt, source=self.id.key)],\n", " cancellation_token=ctx.cancellation_token,\n", " )\n", " response = llm_result.content\n", " assert isinstance(response, str)\n", " print(f\"{'-'*80}\\n{self.id.type}:\\n{response}\")\n", "\n", " await self.publish_message(Message(response), topic_id=TopicId(writer_topic_type, source=self.id.key))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "写作代理负责执行文案撰写。\n" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [], "source": [ "@type_subscription(topic_type=writer_topic_type)\n", "class WriterAgent(RoutedAgent):\n", " def __init__(self, model_client: ChatCompletionClient) -> None:\n", " super().__init__(\"A writer agent.\")\n", " self._system_message = SystemMessage(\n", " content=(\n", " \"You are a marketing copywriter. Given a block of text describing features, audience, and USPs, \"\n", " \"compose a compelling marketing copy (like a newsletter section) that highlights these points. \"\n", " \"Output should be short (around 150 words), output just the copy as a single text block.\"\n", " )\n", " )\n", " self._model_client = model_client\n", "\n", " @message_handler\n", " async def handle_intermediate_text(self, message: Message, ctx: MessageContext) -> None:\n", " prompt = f\"Below is the info about the product:\\n\\n{message.content}\"\n", "\n", " llm_result = await self._model_client.create(\n", " messages=[self._system_message, UserMessage(content=prompt, source=self.id.key)],\n", " cancellation_token=ctx.cancellation_token,\n", " )\n", " response = llm_result.content\n", " assert isinstance(response, str)\n", " print(f\"{'-'*80}\\n{self.id.type}:\\n{response}\")\n", "\n", " await self.publish_message(Message(response), topic_id=TopicId(format_proof_topic_type, source=self.id.key))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "格式校对代理负责执行格式调整。\n" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "@type_subscription(topic_type=format_proof_topic_type)\n", "class FormatProofAgent(RoutedAgent):\n", " def __init__(self, model_client: ChatCompletionClient) -> None:\n", " super().__init__(\"A format & proof agent.\")\n", " self._system_message = SystemMessage(\n", " content=(\n", " \"You are an editor. Given the draft copy, correct grammar, improve clarity, ensure consistent tone, \"\n", " \"give format and make it polished. Output the final improved copy as a single text block.\"\n", " )\n", " )\n", " self._model_client = model_client\n", "\n", " @message_handler\n", " async def handle_intermediate_text(self, message: Message, ctx: MessageContext) -> None:\n", " prompt = f\"Draft copy:\\n{message.content}.\"\n", " llm_result = await self._model_client.create(\n", " messages=[self._system_message, UserMessage(content=prompt, source=self.id.key)],\n", " cancellation_token=ctx.cancellation_token,\n", " )\n", " response = llm_result.content\n", " assert isinstance(response, str)\n", " print(f\"{'-'*80}\\n{self.id.type}:\\n{response}\")\n", "\n", " await self.publish_message(Message(response), topic_id=TopicId(user_topic_type, source=self.id.key))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "在本示例中,用户代理仅将最终营销文案打印到控制台。\n在实际应用中,这可以替换为将结果存储到数据库、发送电子邮件或任何其他所需操作。\n" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": [ "@type_subscription(topic_type=user_topic_type)\n", "class UserAgent(RoutedAgent):\n", " def __init__(self) -> None:\n", " super().__init__(\"A user agent that outputs the final copy to the user.\")\n", "\n", " @message_handler\n", " async def handle_final_copy(self, message: Message, ctx: MessageContext) -> None:\n", " print(f\"\\n{'-'*80}\\n{self.id.type} received final copy:\\n{message.content}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 工作流\n\n现在我们可以将代理注册到运行时。\n由于我们使用了 {py:class}`~autogen_core.type_subscription` 装饰器,运行时将自动为代理订阅正确的主题。\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "model_client = OpenAIChatCompletionClient(\n", " model=\"gpt-4o-mini\",\n", " # api_key=\"YOUR_API_KEY\"\n", ")\n", "\n", "runtime = SingleThreadedAgentRuntime()\n", "\n", "await ConceptExtractorAgent.register(\n", " runtime, type=concept_extractor_topic_type, factory=lambda: ConceptExtractorAgent(model_client=model_client)\n", ")\n", "\n", "await WriterAgent.register(runtime, type=writer_topic_type, factory=lambda: WriterAgent(model_client=model_client))\n", "\n", "await FormatProofAgent.register(\n", " runtime, type=format_proof_topic_type, factory=lambda: FormatProofAgent(model_client=model_client)\n", ")\n", "\n", "await UserAgent.register(runtime, type=user_topic_type, factory=lambda: UserAgent())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 运行工作流\n\n最后,我们可以通过向序列中的第一个代理发布消息来运行工作流。\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "--------------------------------------------------------------------------------\n", "ConceptExtractorAgent:\n", "**Key Features:**\n", "- Made from eco-friendly stainless steel\n", "- Can keep drinks cold for up to 24 hours\n", "- Durable and reusable design\n", "- Lightweight and portable\n", "- BPA-free and non-toxic materials\n", "- Sleek, modern aesthetic available in various colors\n", "\n", "**Target Audience:**\n", "- Environmentally conscious consumers\n", "- Health and fitness enthusiasts\n", "- Outdoor adventurers (hikers, campers, etc.)\n", "- Urban dwellers looking for sustainable alternatives\n", "- Individuals seeking stylish and functional drinkware\n", "\n", "**Unique Selling Points:**\n", "- Eco-friendly design minimizes plastic waste and supports sustainability\n", "- Superior insulation technology that maintains cold temperatures for a full day\n", "- Durable construction ensures long-lasting use, offering a great return on investment\n", "- Attractive design that caters to fashion-forward individuals \n", "- Versatile use for both everyday hydration and outdoor activities\n", "--------------------------------------------------------------------------------\n", "WriterAgent:\n", "🌍🌿 Stay Hydrated, Stay Sustainable! 🌿🌍 \n", "\n", "Introducing our eco-friendly stainless steel drinkware, the perfect companion for the environmentally conscious and style-savvy individuals. With superior insulation technology, our bottles keep your beverages cold for an impressive 24 hours—ideal for hiking, camping, or just tackling a busy day in the city. Made from lightweight, BPA-free materials, this durable and reusable design not only helps reduce plastic waste but also ensures you’re making a responsible choice for our planet.\n", "\n", "Available in a sleek, modern aesthetic with various colors to match your personality, this drinkware isn't just functional—it’s fashionable! Whether you’re hitting the trails or navigating urban life, equip yourself with a stylish hydration solution that supports your active and sustainable lifestyle. Join the movement today and make a positive impact without compromising on style! 🌟🥤\n", "--------------------------------------------------------------------------------\n", "FormatProofAgent:\n", "🌍🌿 Stay Hydrated, Stay Sustainable! 🌿🌍 \n", "\n", "Introducing our eco-friendly stainless steel drinkware—the perfect companion for environmentally conscious and style-savvy individuals. With superior insulation technology, our bottles keep your beverages cold for an impressive 24 hours, making them ideal for hiking, camping, or simply tackling a busy day in the city. Crafted from lightweight, BPA-free materials, this durable and reusable design not only helps reduce plastic waste but also ensures that you’re making a responsible choice for our planet.\n", "\n", "Our drinkware features a sleek, modern aesthetic available in a variety of colors to suit your personality. It’s not just functional; it’s also fashionable! Whether you’re exploring the trails or navigating urban life, equip yourself with a stylish hydration solution that supports your active and sustainable lifestyle. Join the movement today and make a positive impact without compromising on style! 🌟🥤\n", "\n", "--------------------------------------------------------------------------------\n", "User received final copy:\n", "🌍🌿 Stay Hydrated, Stay Sustainable! 🌿🌍 \n", "\n", "Introducing our eco-friendly stainless steel drinkware—the perfect companion for environmentally conscious and style-savvy individuals. With superior insulation technology, our bottles keep your beverages cold for an impressive 24 hours, making them ideal for hiking, camping, or simply tackling a busy day in the city. Crafted from lightweight, BPA-free materials, this durable and reusable design not only helps reduce plastic waste but also ensures that you’re making a responsible choice for our planet.\n", "\n", "Our drinkware features a sleek, modern aesthetic available in a variety of colors to suit your personality. It’s not just functional; it’s also fashionable! Whether you’re exploring the trails or navigating urban life, equip yourself with a stylish hydration solution that supports your active and sustainable lifestyle. Join the movement today and make a positive impact without compromising on style! 🌟🥤\n" ] } ], "source": [ "runtime.start()\n", "\n", "await runtime.publish_message(\n", " Message(content=\"An eco-friendly stainless steel water bottle that keeps drinks cold for 24 hours\"),\n", " topic_id=TopicId(concept_extractor_topic_type, source=\"default\"),\n", ")\n", "\n", "await runtime.stop_when_idle()\n", "await model_client.close()" ] } ], "metadata": { "kernelspec": { "display_name": ".venv", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.5" } }, "nbformat": 4, "nbformat_minor": 2 }