{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Quick Start\n", "\n", ":::{note}\n", "See [here](installation) for installation instructions.\n", ":::\n", "\n", "Before diving into the core APIs, let's start with a simple example of two agents that count down from 10 to 1.\n", "\n", "We first define the agent classes and their respective procedures for \n", "handling messages.\n", "We create two agent classes: `Modifier` and `Checker`. The `Modifier` agent modifies a number that is given and the `Check` agent checks the value against a condition.\n", "We also create a `Message` data class, which defines the messages that are passed between the agents." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "from dataclasses import dataclass\n", "from typing import Callable\n", "\n", "from autogen_core import DefaultTopicId, MessageContext, RoutedAgent, default_subscription, message_handler\n", "\n", "\n", "@dataclass\n", "class Message:\n", " content: int\n", "\n", "\n", "@default_subscription\n", "class Modifier(RoutedAgent):\n", " def __init__(self, modify_val: Callable[[int], int]) -> None:\n", " super().__init__(\"A modifier agent.\")\n", " self._modify_val = modify_val\n", "\n", " @message_handler\n", " async def handle_message(self, message: Message, ctx: MessageContext) -> None:\n", " val = self._modify_val(message.content)\n", " print(f\"{'-'*80}\\nModifier:\\nModified {message.content} to {val}\")\n", " await self.publish_message(Message(content=val), DefaultTopicId()) # type: ignore\n", "\n", "\n", "@default_subscription\n", "class Checker(RoutedAgent):\n", " def __init__(self, run_until: Callable[[int], bool]) -> None:\n", " super().__init__(\"A checker agent.\")\n", " self._run_until = run_until\n", "\n", " @message_handler\n", " async def handle_message(self, message: Message, ctx: MessageContext) -> None:\n", " if not self._run_until(message.content):\n", " print(f\"{'-'*80}\\nChecker:\\n{message.content} passed the check, continue.\")\n", " await self.publish_message(Message(content=message.content), DefaultTopicId())\n", " else:\n", " print(f\"{'-'*80}\\nChecker:\\n{message.content} failed the check, stopping.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You might have already noticed, the agents' logic, whether it is using model or code executor,\n", "is completely decoupled from\n", "how messages are delivered. This is the core idea: the framework provides\n", "a communication infrastructure, and the agents are responsible for their own\n", "logic. We call the communication infrastructure an **Agent Runtime**.\n", "\n", "Agent runtime is a key concept of this framework. Besides delivering messages,\n", "it also manages agents' lifecycle. \n", "So the creation of agents are handled by the runtime.\n", "\n", "The following code shows how to register and run the agents using \n", "{py:class}`~autogen_core.SingleThreadedAgentRuntime`,\n", "a local embedded agent runtime implementation.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "--------------------------------------------------------------------------------\n", "Checker:\n", "10 passed the check, continue.\n", "--------------------------------------------------------------------------------\n", "Modifier:\n", "Modified 10 to 9\n", "--------------------------------------------------------------------------------\n", "Checker:\n", "9 passed the check, continue.\n", "--------------------------------------------------------------------------------\n", "Modifier:\n", "Modified 9 to 8\n", "--------------------------------------------------------------------------------\n", "Checker:\n", "8 passed the check, continue.\n", "--------------------------------------------------------------------------------\n", "Modifier:\n", "Modified 8 to 7\n", "--------------------------------------------------------------------------------\n", "Checker:\n", "7 passed the check, continue.\n", "--------------------------------------------------------------------------------\n", "Modifier:\n", "Modified 7 to 6\n", "--------------------------------------------------------------------------------\n", "Checker:\n", "6 passed the check, continue.\n", "--------------------------------------------------------------------------------\n", "Modifier:\n", "Modified 6 to 5\n", "--------------------------------------------------------------------------------\n", "Checker:\n", "5 passed the check, continue.\n", "--------------------------------------------------------------------------------\n", "Modifier:\n", "Modified 5 to 4\n", "--------------------------------------------------------------------------------\n", "Checker:\n", "4 passed the check, continue.\n", "--------------------------------------------------------------------------------\n", "Modifier:\n", "Modified 4 to 3\n", "--------------------------------------------------------------------------------\n", "Checker:\n", "3 passed the check, continue.\n", "--------------------------------------------------------------------------------\n", "Modifier:\n", "Modified 3 to 2\n", "--------------------------------------------------------------------------------\n", "Checker:\n", "2 passed the check, continue.\n", "--------------------------------------------------------------------------------\n", "Modifier:\n", "Modified 2 to 1\n", "--------------------------------------------------------------------------------\n", "Checker:\n", "1 failed the check, stopping.\n" ] } ], "source": [ "from autogen_core import AgentId, SingleThreadedAgentRuntime\n", "\n", "# Create an local embedded runtime.\n", "runtime = SingleThreadedAgentRuntime()\n", "\n", "# Register the modifier and checker agents by providing\n", "# their agent types, the factory functions for creating instance and subscriptions.\n", "await Modifier.register(\n", " runtime,\n", " \"modifier\",\n", " # Modify the value by subtracting 1\n", " lambda: Modifier(modify_val=lambda x: x - 1),\n", ")\n", "\n", "await Checker.register(\n", " runtime,\n", " \"checker\",\n", " # Run until the value is less than or equal to 1\n", " lambda: Checker(run_until=lambda x: x <= 1),\n", ")\n", "\n", "# Start the runtime and send a direct message to the checker.\n", "runtime.start()\n", "await runtime.send_message(Message(10), AgentId(\"checker\", \"default\"))\n", "await runtime.stop_when_idle()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "From the agent's output, we can see the value was successfully decremented from 10 to 1 as the modifier and checker conditions dictate." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "AutoGen also supports a distributed agent runtime, which can host agents running on\n", "different processes or machines, with different identities, languages and dependencies.\n", "\n", "To learn how to use agent runtime, communication, message handling, and subscription, please continue\n", "reading the sections following this quick start." ] } ], "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.12.7" } }, "nbformat": 4, "nbformat_minor": 2 }