Quick Start#
Note
See here for installation instructions.
Before diving into the core APIs, let’s start with a simple example of two agents creating a plot of Tesla’s and Nvidia’s stock returns.
We first define the agent classes and their respective procedures for
handling messages.
We create two agent classes: Assistant
and Executor
. The Assistant
agent writes code and the Executor
agent executes the code.
We also create a Message
data class, which defines the messages that are passed between
the agents.
Attention
Code generated in this example is run within a Docker container. Please ensure Docker is installed and running prior to running the example. Local code execution is available (LocalCommandLineCodeExecutor
) but is not recommended due to the risk of running LLM generated code in your local environment.
import re
from dataclasses import dataclass
from typing import List
from autogen_core import DefaultTopicId, MessageContext, RoutedAgent, default_subscription, message_handler
from autogen_core.components.code_executor import CodeBlock, CodeExecutor
from autogen_core.components.models import (
AssistantMessage,
ChatCompletionClient,
LLMMessage,
SystemMessage,
UserMessage,
)
@dataclass
class Message:
content: str
@default_subscription
class Assistant(RoutedAgent):
def __init__(self, model_client: ChatCompletionClient) -> None:
super().__init__("An assistant agent.")
self._model_client = model_client
self._chat_history: List[LLMMessage] = [
SystemMessage(
content="""Write Python script in markdown block, and it will be executed.
Always save figures to file in the current directory. Do not use plt.show()""",
)
]
@message_handler
async def handle_message(self, message: Message, ctx: MessageContext) -> None:
self._chat_history.append(UserMessage(content=message.content, source="user"))
result = await self._model_client.create(self._chat_history)
print(f"\n{'-'*80}\nAssistant:\n{result.content}")
self._chat_history.append(AssistantMessage(content=result.content, source="assistant")) # type: ignore
await self.publish_message(Message(content=result.content), DefaultTopicId()) # type: ignore
def extract_markdown_code_blocks(markdown_text: str) -> List[CodeBlock]:
pattern = re.compile(r"```(?:\s*([\w\+\-]+))?\n([\s\S]*?)```")
matches = pattern.findall(markdown_text)
code_blocks: List[CodeBlock] = []
for match in matches:
language = match[0].strip() if match[0] else ""
code_content = match[1]
code_blocks.append(CodeBlock(code=code_content, language=language))
return code_blocks
@default_subscription
class Executor(RoutedAgent):
def __init__(self, code_executor: CodeExecutor) -> None:
super().__init__("An executor agent.")
self._code_executor = code_executor
@message_handler
async def handle_message(self, message: Message, ctx: MessageContext) -> None:
code_blocks = extract_markdown_code_blocks(message.content)
if code_blocks:
result = await self._code_executor.execute_code_blocks(
code_blocks, cancellation_token=ctx.cancellation_token
)
print(f"\n{'-'*80}\nExecutor:\n{result.output}")
await self.publish_message(Message(content=result.output), DefaultTopicId())
You might have already noticed, the agents’ logic, whether it is using model or code executor, is completely decoupled from how messages are delivered. This is the core idea: the framework provides a communication infrastructure, and the agents are responsible for their own logic. We call the communication infrastructure an Agent Runtime.
Agent runtime is a key concept of this framework. Besides delivering messages, it also manages agents’ lifecycle. So the creation of agents are handled by the runtime.
The following code shows how to register and run the agents using
SingleThreadedAgentRuntime
,
a local embedded agent runtime implementation.
import tempfile
from autogen_core import SingleThreadedAgentRuntime
from autogen_ext.code_executors import DockerCommandLineCodeExecutor
from autogen_ext.models import OpenAIChatCompletionClient
work_dir = tempfile.mkdtemp()
# Create an local embedded runtime.
runtime = SingleThreadedAgentRuntime()
async with DockerCommandLineCodeExecutor(work_dir=work_dir) as executor: # type: ignore[syntax]
# Register the assistant and executor agents by providing
# their agent types, the factory functions for creating instance and subscriptions.
await Assistant.register(
runtime,
"assistant",
lambda: Assistant(
OpenAIChatCompletionClient(
model="gpt-4o",
# api_key="YOUR_API_KEY"
)
),
)
await Executor.register(runtime, "executor", lambda: Executor(executor))
# Start the runtime and publish a message to the assistant.
runtime.start()
await runtime.publish_message(
Message("Create a plot of NVIDA vs TSLA stock returns YTD from 2024-01-01."), DefaultTopicId()
)
await runtime.stop_when_idle()
--------------------------------------------------------------------------------
Assistant:
```python
import pandas as pd
import matplotlib.pyplot as plt
import yfinance as yf
# Define the stock tickers
ticker_symbols = ['NVDA', 'TSLA']
# Download the stock data from Yahoo Finance starting from 2024-01-01
start_date = '2024-01-01'
stock_data = yf.download(ticker_symbols, start=start_date)['Adj Close']
# Calculate daily returns
returns = stock_data.pct_change().dropna()
# Plot the stock returns
plt.figure(figsize=(10, 6))
for ticker in ticker_symbols:
returns[ticker].cumsum().plot(label=ticker)
plt.title('NVIDIA vs TSLA Stock Returns YTD from 2024-01-01')
plt.xlabel('Date')
plt.ylabel('Cumulative Returns')
plt.legend()
plt.grid(True)
# Save the plot to a file
plt.savefig('nvidia_vs_tsla_stock_returns_ytd_2024.png')
```
--------------------------------------------------------------------------------
Executor:
Traceback (most recent call last):
File "/workspace/tmp_code_f562e5e3c313207b9ec10ca87094085f.python", line 1, in <module>
import pandas as pd
ModuleNotFoundError: No module named 'pandas'
--------------------------------------------------------------------------------
Assistant:
It looks like some required modules are not installed. Let me proceed by installing the necessary libraries before running the script.
```python
!pip install pandas matplotlib yfinance
```
--------------------------------------------------------------------------------
Executor:
File "/workspace/tmp_code_78ffa711e7b0ff8738fdeec82404018c.python", line 1
!pip install -qqq pandas matplotlib yfinance
^
SyntaxError: invalid syntax
--------------------------------------------------------------------------------
Assistant:
It appears that I'm unable to run installation commands within the code execution environment. However, you can install the necessary libraries using the following commands in your local environment:
```sh
pip install pandas matplotlib yfinance
```
After installing the libraries, you can then run the previous plotting script. Here is the combined process:
1. First, install the required libraries (run this in your terminal or command prompt):
```sh
pip install pandas matplotlib yfinance
```
2. Now, you can run the script to generate the plot:
```python
import pandas as pd
import matplotlib.pyplot as plt
import yfinance as yf
# Define the stock tickers
ticker_symbols = ['NVDA', 'TSLA']
# Download the stock data from Yahoo Finance starting from 2024-01-01
start_date = '2024-01-01'
stock_data = yf.download(ticker_symbols, start=start_date)['Adj Close']
# Calculate daily returns
returns = stock_data.pct_change().dropna()
# Plot the stock returns
plt.figure(figsize=(10, 6))
for ticker in ticker_symbols:
returns[ticker].cumsum().plot(label=ticker)
plt.title('NVIDIA vs TSLA Stock Returns YTD from 2024-01-01')
plt.xlabel('Date')
plt.ylabel('Cumulative Returns')
plt.legend()
plt.grid(True)
# Save the plot to a file
plt.savefig('nvidia_vs_tsla_stock_returns_ytd_2024.png')
```
This should generate and save the desired plot in your current directory as `nvidia_vs_tsla_stock_returns_ytd_2024.png`.
--------------------------------------------------------------------------------
Executor:
Requirement already satisfied: pandas in /usr/local/lib/python3.12/site-packages (2.2.2)
Requirement already satisfied: matplotlib in /usr/local/lib/python3.12/site-packages (3.9.2)
Requirement already satisfied: yfinance in /usr/local/lib/python3.12/site-packages (0.2.43)
Requirement already satisfied: numpy>=1.26.0 in /usr/local/lib/python3.12/site-packages (from pandas) (2.1.1)
Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.12/site-packages (from pandas) (2.9.0.post0)
Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.12/site-packages (from pandas) (2024.2)
Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.12/site-packages (from pandas) (2024.1)
Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.12/site-packages (from matplotlib) (1.3.0)
Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.12/site-packages (from matplotlib) (0.12.1)
Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.12/site-packages (from matplotlib) (4.53.1)
Requirement already satisfied: kiwisolver>=1.3.1 in /usr/local/lib/python3.12/site-packages (from matplotlib) (1.4.7)
Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.12/site-packages (from matplotlib) (24.1)
Requirement already satisfied: pillow>=8 in /usr/local/lib/python3.12/site-packages (from matplotlib) (10.4.0)
Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.12/site-packages (from matplotlib) (3.1.4)
Requirement already satisfied: requests>=2.31 in /usr/local/lib/python3.12/site-packages (from yfinance) (2.32.3)
Requirement already satisfied: multitasking>=0.0.7 in /usr/local/lib/python3.12/site-packages (from yfinance) (0.0.11)
Requirement already satisfied: lxml>=4.9.1 in /usr/local/lib/python3.12/site-packages (from yfinance) (5.3.0)
Requirement already satisfied: platformdirs>=2.0.0 in /usr/local/lib/python3.12/site-packages (from yfinance) (4.3.6)
Requirement already satisfied: frozendict>=2.3.4 in /usr/local/lib/python3.12/site-packages (from yfinance) (2.4.4)
Requirement already satisfied: peewee>=3.16.2 in /usr/local/lib/python3.12/site-packages (from yfinance) (3.17.6)
Requirement already satisfied: beautifulsoup4>=4.11.1 in /usr/local/lib/python3.12/site-packages (from yfinance) (4.12.3)
Requirement already satisfied: html5lib>=1.1 in /usr/local/lib/python3.12/site-packages (from yfinance) (1.1)
Requirement already satisfied: soupsieve>1.2 in /usr/local/lib/python3.12/site-packages (from beautifulsoup4>=4.11.1->yfinance) (2.6)
Requirement already satisfied: six>=1.9 in /usr/local/lib/python3.12/site-packages (from html5lib>=1.1->yfinance) (1.16.0)
Requirement already satisfied: webencodings in /usr/local/lib/python3.12/site-packages (from html5lib>=1.1->yfinance) (0.5.1)
Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.12/site-packages (from requests>=2.31->yfinance) (3.3.2)
Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.12/site-packages (from requests>=2.31->yfinance) (3.10)
Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.12/site-packages (from requests>=2.31->yfinance) (2.2.3)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.12/site-packages (from requests>=2.31->yfinance) (2024.8.30)
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager, possibly rendering your system unusable.It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv. Use the --root-user-action option if you know what you are doing and want to suppress this warning.
File "/workspace/tmp_code_d094fa6242b4268e4812bf9902aa1374.python", line 1
import pandas as pd
IndentationError: unexpected indent
--------------------------------------------------------------------------------
Assistant:
Thank you for the confirmation. As the required packages are installed, let's proceed with the script to plot the NVIDIA vs TSLA stock returns YTD starting from 2024-01-01.
Here's the updated script:
```python
import pandas as pd
import matplotlib.pyplot as plt
import yfinance as yf
# Define the stock tickers
ticker_symbols = ['NVDA', 'TSLA']
# Download the stock data from Yahoo Finance starting from 2024-01-01
start_date = '2024-01-01'
stock_data = yf.download(ticker_symbols, start=start_date)['Adj Close']
# Calculate daily returns
returns = stock_data.pct_change().dropna()
# Plot the stock returns
plt.figure(figsize=(10, 6))
for ticker in ticker_symbols:
returns[ticker].cumsum().plot(label=ticker)
plt.title('NVIDIA vs TSLA Stock Returns YTD from 2024-01-01')
plt.xlabel('Date')
plt.ylabel('Cumulative Returns')
plt.legend()
plt.grid(True)
# Save the plot to a file
plt.savefig('nvidia_vs_tsla_stock_returns_ytd_2024.png')
```
--------------------------------------------------------------------------------
Executor:
[*********************100%***********************] 2 of 2 completed
--------------------------------------------------------------------------------
Assistant:
It looks like the stock data was successfully downloaded, and the plot has been generated and saved as `nvidia_vs_tsla_stock_returns_ytd_2024.png` in the current directory.
If you have any further questions or need additional assistance, feel free to ask!
From the agent’s output, we can see the plot of Tesla’s and Nvidia’s stock returns has been created.
from IPython.display import Image
Image(filename=f"{work_dir}/NVIDIA_vs_TSLA_Stock_Returns_YTD_2024.png") # type: ignore
/var/folders/cs/b9_18p1s2rd56_s2jl65rxwc0000gn/T/tmp_9c2ylon
AutoGen also supports a distributed agent runtime, which can host agents running on different processes or machines, with different identities, languages and dependencies.
To learn how to use agent runtime, communication, message handling, and subscription, please continue reading the sections following this quick start.