Autogen Components Guide
Autogen Components Guide
AutoGen provides a suite of built-in model clients for using ChatCompletion API. All model
clients implement the ChatCompletionClient protocol class.
OpenAIChatCompletionClient
AzureOpenAIChatCompletionClient
AzureAIChatCompletionClient
OpenAI
To use the OpenAIChatCompletionClient, you need to install the openai extra.
az_model_client = AzureOpenAIChatCompletionClient(
azure_deployment="{your-azure-deployment}",
model="{model-name, such as gpt-4o}",
api_version="2024-06-01",
azure_endpoint="https://{your-custom-endpoint}.openai.azure.com/",
azure_ad_token_provider=token_provider, # Optional if you choose key-based
authentication.
# api_key="sk-...", # For key-based authentication.
)
Note
See here for how to use the Azure client directly or for more info.
Azure AI Foundry
Azure AI Foundry (previously known as Azure AI Studio) offers models hosted on Azure. To
use those models, you use the AzureAIChatCompletionClient.
import os
client = AzureAIChatCompletionClient(
model="Phi-4",
endpoint="https://models.inference.ai.azure.com",
# To authenticate with the model you will need to generate a personal access token (PAT)
in your GitHub settings.
# Create your PAT token by following instructions here:
https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-
your-personal-access-tokens
credential=AzureKeyCredential(os.environ["GITHUB_TOKEN"]),
model_info={
"json_output": False,
"function_calling": False,
"vision": False,
"family": "unknown",
},
)
model_client = OpenAIChatCompletionClient(
model="llama3.2:latest",
base_url="http://localhost:11434/v1",
api_key="placeholder",
model_info={
"vision": False,
"function_calling": True,
"json_output": False,
"family": "unknown",
},
)
model_client = OpenAIChatCompletionClient(
model="gemini-1.5-flash-8b",
# api_key="GEMINI_API_KEY",
)
You need to install the relevant provider extras to use this adapter.
import os
sk_client = AnthropicChatCompletion(
ai_model_id="claude-3-5-sonnet-20241022",
api_key=os.environ["ANTHROPIC_API_KEY"],
service_id="my-service-id", # Optional; for targeting specific services within Semantic
Kernel
)
settings = AnthropicChatPromptExecutionSettings(
temperature=0.2,
)
anthropic_model_client = SKChatCompletionAdapter(
sk_client, kernel=Kernel(memory=NullMemory()), prompt_settings=settings
)
Streaming Response
You can use the create_stream() method to create a chat completion request with streaming
response.
messages = [
UserMessage(content="Write a very short story about a dragon.", source="user"),
]
# Create a stream.
stream = model_client.create_stream(messages=messages)
One cold winter's eve, a young girl named Lira, brimming with curiosity and armed with the
innocence of youth, wandered into Elara’s domain. Instead of fire and fury, she found
warmth and a gentle gaze. The dragon shared stories of a world long forgotten and in return,
Lira gifted her simple stories of human life, rich in laughter and scent of earth.
From that night on, the villagers noticed subtle changes—the crops grew taller, and the air
seemed sweeter. Elara had infused the valley with ancient magic, a guardian of balance,
watching quietly as her new friend thrived under the stars. And so, Lira and Elara’s bond
marked the beginning of a timeless friendship that spun tales of hope whispered through the
leaves of the ever-verdant forest.
------------
One cold winter's eve, a young girl named Lira, brimming with curiosity and armed with the
innocence of youth, wandered into Elara’s domain. Instead of fire and fury, she found
warmth and a gentle gaze. The dragon shared stories of a world long forgotten and in return,
Lira gifted her simple stories of human life, rich in laughter and scent of earth.
From that night on, the villagers noticed subtle changes—the crops grew taller, and the air
seemed sweeter. Elara had infused the valley with ancient magic, a guardian of balance,
watching quietly as her new friend thrived under the stars. And so, Lira and Elara’s bond
marked the beginning of a timeless friendship that spun tales of hope whispered through the
leaves of the ever-verdant forest.
------------
The last response in the streaming response is always the final response of the type
CreateResult.
Note
The default usage response is to return zero values
Note
Note whilst other API’s like LiteLLM also support this, it is not always guarenteed that it is
fully supported or correct.
See the example below for how to use the stream_options parameter to return usage.
messages = [
UserMessage(content="Write a very short story about a dragon.", source="user"),
]
# Create a stream.
stream = model_client.create_stream(messages=messages,
extra_create_args={"stream_options": {"include_usage": True}})
Instead of fury, he was met with kindness as Ember extended a wing, guiding him back to
safety. In gratitude, the shepherd visited yearly, bringing tales of his world beyond the
mountains. Over time, a friendship blossomed, binding man and dragon in shared stories
and laughter.
As the years passed, the legend of Ember the gentle-hearted spread far and wide, forever
changing the way dragons were seen in the hearts of many.
------------
Instead of fury, he was met with kindness as Ember extended a wing, guiding him back to
safety. In gratitude, the shepherd visited yearly, bringing tales of his world beyond the
mountains. Over time, a friendship blossomed, binding man and dragon in shared stories
and laughter.
As the years passed, the legend of Ember the gentle-hearted spread far and wide, forever
changing the way dragons were seen in the hearts of many.
------------
Note
Structured output is only available for models that support it. It also requires the model client
to support structured output as well. Currently, the OpenAIChatCompletionClient and
AzureOpenAIChatCompletionClient support structured output.
# Create an agent that uses the OpenAI GPT-4o model with the custom response format.
model_client = OpenAIChatCompletionClient(
model="gpt-4o",
response_format=AgentResponse, # type: ignore
)
asyncio.run(main())
True
Inspecting cached_client.total_usage() (or model_client.total_usage()) before and after a
cached response should yield idential counts.
Note that the caching is sensitive to the exact arguments provided to cached_client.create or
cached_client.create_stream, so changing tools or json_output arguments might lead to a
cache miss.
@dataclass
class Message:
content: str
class SimpleAgent(RoutedAgent):
def __init__(self, model_client: ChatCompletionClient) -> None:
super().__init__("A simple agent")
self._system_messages = [SystemMessage(content="You are a helpful AI assistant.")]
self._model_client = model_client
@message_handler
async def handle_user_message(self, message: Message, ctx: MessageContext) ->
Message:
# Prepare input to the chat completion model.
user_message = UserMessage(content=message.content, source="user")
response = await self._model_client.create(
self._system_messages + [user_message],
cancellation_token=ctx.cancellation_token
)
# Return with the model's response.
assert isinstance(response.content, str)
return Message(content=response.content)
The SimpleAgent class is a subclass of the autogen_core.RoutedAgent class for the
convenience of automatically routing messages to the appropriate handlers. It has a single
handler, handle_user_message, which handles message from the user. It uses the
ChatCompletionClient to generate a response to the message. It then returns the response
to the user, following the direct communication model.
Note
runtime = SingleThreadedAgentRuntime()
await SimpleAgent.register(
runtime,
"simple_agent",
lambda: SimpleAgent(
OpenAIChatCompletionClient(
model="gpt-4o-mini",
# api_key="sk-...", # Optional if you have an OPENAI_API_KEY set in the
environment.
)
),
)
# Start the runtime processing messages.
runtime.start()
# Send a message to the agent and get the response.
message = Message("Hello, what are some fun things to do in Seattle?")
response = await runtime.send_message(message, AgentId("simple_agent", "default"))
print(response.content)
# Stop the runtime processing messages.
await runtime.stop()
Seattle is a vibrant city with a wide range of activities and attractions. Here are some fun
things to do in Seattle:
1. **Space Needle**: Visit this iconic observation tower for stunning views of the city and
surrounding mountains.
2. **Pike Place Market**: Explore this historic market where you can see the famous fish
toss, buy local produce, and find unique crafts and eateries.
3. **Museum of Pop Culture (MoPOP)**: Dive into the world of contemporary culture, music,
and science fiction at this interactive museum.
4. **Chihuly Garden and Glass**: Marvel at the beautiful glass art installations by artist Dale
Chihuly, located right next to the Space Needle.
5. **Seattle Aquarium**: Discover the diverse marine life of the Pacific Northwest at this
engaging aquarium.
6. **Seattle Art Museum**: Explore a vast collection of art from around the world, including
contemporary and indigenous art.
7. **Kerry Park**: For one of the best views of the Seattle skyline, head to this small park on
Queen Anne Hill.
8. **Ballard Locks**: Watch boats pass through the locks and observe the salmon ladder to
see salmon migrating.
9. **Ferry to Bainbridge Island**: Take a scenic ferry ride across Puget Sound to enjoy
charming shops, restaurants, and beautiful natural scenery.
10. **Olympic Sculpture Park**: Stroll through this outdoor park with large-scale sculptures
and stunning views of the waterfront and mountains.
11. **Underground Tour**: Discover Seattle's history on this quirky tour of the city's
underground passageways in Pioneer Square.
12. **Seattle Waterfront**: Enjoy the shops, restaurants, and attractions along the waterfront,
including the Seattle Great Wheel and the aquarium.
13. **Discovery Park**: Explore the largest green space in Seattle, featuring trails, beaches,
and views of Puget Sound.
14. **Food Tours**: Try out Seattle’s diverse culinary scene, including fresh seafood,
international cuisines, and coffee culture (don’t miss the original Starbucks!).
15. **Attend a Sports Game**: Catch a Seahawks (NFL), Mariners (MLB), or Sounders
(MLS) game for a lively local experience.
Whether you're interested in culture, nature, food, or history, Seattle has something for
everyone to enjoy!
The above SimpleAgent always responds with a fresh context that contains only the system
message and the latest user’s message. We can use model context classes from
autogen_core.model_context to make the agent “remember” previous conversations. See
the Model Context page for more details.
For Azure OpenAI, you can set the AZURE_OPENAI_API_KEY environment variable.
In addition, for Gemini (Beta), you can set the GEMINI_API_KEY environment variable.
This is a good practice to explore, as it avoids including sensitive api keys in your code.
Model Context
A model context supports storage and retrieval of Chat Completion messages. It is always
used together with a model client to generate LLM-based responses.
@message_handler
async def handle_user_message(self, message: Message, ctx: MessageContext) ->
Message:
# Prepare input to the chat completion model.
user_message = UserMessage(content=message.content, source="user")
# Add message to model context.
await self._model_context.add_message(user_message)
# Generate a response.
response = await self._model_client.create(
self._system_messages + (await self._model_context.get_messages()),
cancellation_token=ctx.cancellation_token,
)
# Return with the model's response.
assert isinstance(response.content, str)
# Add message to model context.
await self._model_context.add_message(AssistantMessage(content=response.content,
source=self.metadata["type"]))
return Message(content=response.content)
Now let’s try to ask follow up questions after the first one.
runtime = SingleThreadedAgentRuntime()
await SimpleAgentWithContext.register(
runtime,
"simple_agent_context",
lambda: SimpleAgentWithContext(
OpenAIChatCompletionClient(
model="gpt-4o-mini",
# api_key="sk-...", # Optional if you have an OPENAI_API_KEY set in the
environment.
)
),
)
# Start the runtime processing messages.
runtime.start()
agent_id = AgentId("simple_agent_context", "default")
# First question.
message = Message("Hello, what are some fun things to do in Seattle?")
print(f"Question: {message.content}")
response = await runtime.send_message(message, agent_id)
print(f"Response: {response.content}")
print("-----")
# Second question.
message = Message("What was the first thing you mentioned?")
print(f"Question: {message.content}")
response = await runtime.send_message(message, agent_id)
print(f"Response: {response.content}")
1. **Pike Place Market**: Visit this iconic market to explore local vendors, fresh produce,
artisanal products, and watch the famous fish throwing.
2. **Space Needle**: Take a trip to the observation deck for stunning panoramic views of the
city, Puget Sound, and the surrounding mountains.
3. **Chihuly Garden and Glass**: Marvel at the stunning glass art installations created by
artist Dale Chihuly, located right next to the Space Needle.
4. **Seattle Waterfront**: Enjoy a stroll along the waterfront, visit the Seattle Aquarium, and
take a ferry ride to nearby islands like Bainbridge Island.
5. **Museum of Pop Culture (MoPOP)**: Explore exhibits on music, science fiction, and pop
culture in this architecturally striking building.
6. **Seattle Art Museum (SAM)**: Discover an extensive collection of art from around the
world, including contemporary and Native American art.
7. **Gas Works Park**: Relax in this unique park that features remnants of an old
gasification plant, offering great views of the Seattle skyline and Lake Union.
8. **Discovery Park**: Enjoy nature trails, beaches, and beautiful views of the Puget Sound
and the Olympic Mountains in this large urban park.
9. **Ballard Locks**: Watch boats navigate the locks and see fish swimming upstream during
the salmon migration season.
10. **Fremont Troll**: Check out this quirky public art installation under a bridge in the
Fremont neighborhood.
11. **Underground Tour**: Take an entertaining guided tour through the underground
passages of Pioneer Square to learn about Seattle's history.
12. **Brewery Tours**: Seattle is known for its craft beer scene. Visit local breweries for
tastings and tours.
13. **Seattle Center**: Explore the cultural complex that includes the Space Needle,
MoPOP, and various festivals and events throughout the year.
These are just a few options, and Seattle has something for everyone, whether you're into
outdoor activities, culture, history, or food!
-----
Question: What was the first thing you mentioned?
Response: The first thing I mentioned was **Pike Place Market**. It's an iconic market in
Seattle known for its local vendors, fresh produce, artisanal products, and the famous fish
throwing by the fishmongers. It's a vibrant place full of sights, sounds, and delicious food.
From the second response, you can see the agent now can recall its own previous
responses.
Tools
Tools are code that can be executed by an agent to perform actions. A tool can be a simple
function such as a calculator, or an API call to a third-party service such as stock price
lookup or weather forecast. In the context of AI agents, tools are designed to be executed by
agents in response to model-generated function calls.
AutoGen provides the autogen_core.tools module with a suite of built-in tools and utilities for
creating and running custom tools.
Built-in Tools
One of the built-in tools is the PythonCodeExecutionTool, which allows agents to execute
Python code snippets.
The FunctionTool class uses descriptions and type annotations to inform the LLM when and
how to use a given function. The description provides context about the function’s purpose
and intended use cases, while type annotations inform the LLM about the expected
parameters and return type.
For example, a simple tool to obtain the stock price of a company might look like this:
import random
async def get_stock_price(ticker: str, date: Annotated[str, "Date in YYYY/MM/DD"]) -> float:
# Returns a random stock price for demonstration purposes.
return random.uniform(10, 200)
import json
The result of the tool call is wrapped in a FunctionExecutionResult object, which contains the
result of the tool execution and the ID of the tool that was called. The model client can use
this information to generate a reflection on the result of the tool execution.
# Make another chat completion with the history and function execution result message.
messages = [
user_message,
AssistantMessage(content=create_result.content, source="assistant"), # assistant
message with tool call
FunctionExecutionResultMessage(content=[exec_result]), # function execution result
message
]
create_result = await client.create(messages=messages,
cancellation_token=cancellation_token) # type: ignore
print(create_result.content)
The stock price of AAPL (Apple Inc.) on January 1, 2021, was approximately $32.38.
Tool-Equipped Agent
Putting the model client and the tools together, you can create a tool-equipped agent that
can use tools to perform actions, and reflect on the results of those actions.
import asyncio
import json
from dataclasses import dataclass
from typing import List
@dataclass
class Message:
content: str
class ToolUseAgent(RoutedAgent):
def __init__(self, model_client: ChatCompletionClient, tool_schema: List[Tool]) -> None:
super().__init__("An agent with tools")
self._system_messages: List[LLMMessage] = [SystemMessage(content="You are a
helpful AI assistant.")]
self._model_client = model_client
self._tools = tools
@message_handler
async def handle_user_message(self, message: Message, ctx: MessageContext) ->
Message:
# Create a session of messages.
session: List[LLMMessage] = self._system_messages +
[UserMessage(content=message.content, source="user")]
# Run the chat completion again to reflect on the history and function execution results.
create_result = await self._model_client.create(
messages=session,
cancellation_token=ctx.cancellation_token,
)
assert isinstance(create_result.content, str)
To run the agent, let’s create a runtime and register the agent with the runtime.
# Create a runtime.
runtime = SingleThreadedAgentRuntime()
# Create the tools.
tools: List[Tool] = [FunctionTool(get_stock_price, description="Get the stock price.")]
# Register the agents.
await ToolUseAgent.register(
runtime,
"tool_use_agent",
lambda: ToolUseAgent(
OpenAIChatCompletionClient(model="gpt-4o-mini"),
tools,
),
)
AgentType(type='tool_use_agent')
This example uses the OpenAIChatCompletionClient, for Azure OpenAI and other clients,
see Model Clients. Let’s test the agent with a question about stock price.
Docker
Note
You can use the executor as a context manager to ensure the container is cleaned up after
use. Otherwise, the atexit module will be used to stop the container when the program exits.
Example
from pathlib import Path
work_dir = Path("coding")
work_dir.mkdir(exist_ok=True)
The recommended approach to this is called “Docker out of Docker”, where the Docker
socket is mounted to the main AutoGen container, so that it can spawn and control “sibling”
containers on the host. This is better than what is called “Docker in Docker”, where the main
container runs a Docker daemon and spawns containers within itself. You can read more
about this here.
To do this you would need to mount the Docker socket into the container running your
application. This can be done by adding the following to the docker run command:
-v /var/run/docker.sock:/var/run/docker.sock
This will allow your application’s container to spawn and control sibling containers on the
host.
If you need to bind a working directory to the application’s container but the directory
belongs to your host machine, use the bind_dir parameter. This will allow the application’s
container to bind the host directory to the new spawned containers and allow it to access the
files within the said directory. If the bind_dir is not specified, it will fallback to work_dir.
Local
Attention
The local version will run code on your local system. Use it with caution.
To execute code on the host machine, as in the machine running your application,
LocalCommandLineCodeExecutor can be used.
Example
from pathlib import Path
work_dir = Path("coding")
work_dir.mkdir(exist_ok=True)
local_executor = LocalCommandLineCodeExecutor(work_dir=work_dir)
print(
await local_executor.execute_code_blocks(
code_blocks=[
CodeBlock(language="python", code="print('Hello, World!')"),
],
cancellation_token=CancellationToken(),
)
)
CommandLineCodeResult(exit_code=0, output='Hello, World!\n',
code_file='/home/ekzhu/agnext/python/packages/autogen-core/docs/src/guides/coding/
tmp_code_07da107bb575cc4e02b0e1d6d99cc204.py')
Local within a Virtual Environment
If you want the code to run within a virtual environment created as part of the application’s
setup, you can specify a directory for the newly created environment and pass its context to
LocalCommandLineCodeExecutor. This setup allows the executor to use the specified
virtual environment consistently throughout the application’s lifetime, ensuring isolated
dependencies and a controlled runtime environment.
import venv
from pathlib import Path
work_dir = Path("coding")
work_dir.mkdir(exist_ok=True)
local_executor = LocalCommandLineCodeExecutor(work_dir=work_dir,
virtual_env_context=venv_context)
await local_executor.execute_code_blocks(
code_blocks=[
CodeBlock(language="bash", code="pip install matplotlib"),
],
cancellation_token=CancellationToken(),
)
CommandLineCodeResult(exit_code=0, output='',
code_file='/Users/gziz/Dev/autogen/python/packages/autogen-core/docs/src/user-guide/
core-user-guide/framework/coding/
tmp_code_d2a7db48799db3cc785156a11a38822a45c19f3956f02ec69b92e4169ecbf2ca.ba
sh')
As we can see, the code has executed successfully, and the installation has been isolated to
the newly created virtual environment, without affecting our global environment.