AI Agent Frameworks
AI Agent Frameworks
What are AI Agent Frameworks and what do they enable developers to achieve?
How can teams use these to quickly prototype, iterate, and improve their agent’s capabilities?
What are the differences between the frameworks and tools created by Microsoft AutoGen, Semantic Kernel,
and Azure AI Agent Service?
Can I integrate my existing Azure ecosystem tools directly, or do I need standalone solutions?
What is Azure AI Agents service and how is this helping me?
Learning goals
The goals of this lesson are to help you understand:
Personalization: AI can analyze user behavior and preferences to provide personalized recommendations,
content, and experiences. Example: Streaming services like Netflix use AI to suggest movies and shows based
on viewing history, enhancing user engagement and satisfaction.
Automation and Efficiency: AI can automate repetitive tasks, streamline workflows, and improve operational
efficiency. Example: Customer service apps use AI-powered chatbots to handle common inquiries, reducing
response times and freeing up human agents for more complex issues.
Enhanced User Experience: AI can improve the overall user experience by providing intelligent features such
as voice recognition, natural language processing, and predictive text. Example: Virtual assistants like Siri and
Google Assistant use AI to understand and respond to voice commands, making it easier for users to interact
with their devices.
That all sounds great right, so why do we need the AI Agent Framework?
AI Agent frameworks represent something more than just AI frameworks. They are designed to enable the
creation of intelligent agents that can interact with users, other agents, and the environment to achieve specific
goals. These agents can exhibit autonomous behavior, make decisions, and adapt to changing conditions. Let's
look at some key capabilities enabled by AI Agent Frameworks:
Agent Collaboration and Coordination: Enable the creation of multiple AI agents that can work together,
communicate, and coordinate to solve complex tasks.
Task Automation and Management: Provide mechanisms for automating multi-step workflows, task
delegation, and dynamic task management among agents.
Contextual Understanding and Adaptation: Equip agents with the ability to understand context, adapt to
changing environments, and make decisions based on real-time information.
So in summary, agents allow you to do more, to take automation to the next level, to create more intelligent
systems that can adapt and learn from their environment.
How to quickly prototype, iterate, and improve the agent’s
capabilities?
This is a fast-moving landscape, but there are some things that are common across most AI Agent
Frameworks that can help you quickly prototype and iterate namely module components, collaborative tools,
and real-time learning. Let's dive into these:
Use Modular Components: AI SDKs offer pre-built components such as AI and Memory connectors, function
calling using natural language or code plugins, prompt templates, and more.
Leverage Collaborative Tools: Design agents with specific roles and tasks, enabling them to test and refine
collaborative workflows.
Learn in Real-Time: Implement feedback loops where agents learn from interactions and adjust their behavior
dynamically.
SDKs like Microsoft Semantic Kernel and LangChain offer pre-built components such as AI connectors,
prompt templates, and memory management.
How teams can use these: Teams can quickly assemble these components to create a functional prototype
without starting from scratch, allowing for rapid experimentation and iteration.
How it works in practice: You can use a pre-built parser to extract information from user input, a memory
module to store and retrieve data, and a prompt generator to interact with users, all without having to build
these components from scratch.
Example code. Let's look at examples of how you can use a pre-built AI Connector with Semantic Kernel
Python and .Net that uses auto-function calling to have the model respond to user input:
import asyncio
from typing import Annotated
# Define the request settings to configure the model with auto-function calling
request_settings =
AzureChatPromptExecutionSettings(function_choice_behavior=FunctionChoiceBehavior.Auto())
"""
Note: In the auto function calling process, the model determines it can invoke the
`BookTravelPlugin` using the `book_flight` function, supplying the necessary
arguments.
For example:
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "BookTravelPlugin-book_flight",
"arguments": "{'location': 'New York', 'date': '2025-01-01'}"
}
}
]
Since the location and date arguments are required (as defined by the kernel
function), if the
model lacks either, it will prompt the user to provide them. For instance:
print(f"`{response}`")
# Example AI Model Response: `Your flight to New York on January 1, 2025, has been
successfully booked. Safe travels! ✈ �`
if __name__ == "__main__":
asyncio.run(main())
// Semantic Kernel C# example
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using System.ComponentModel;
using Microsoft.SemanticKernel.Connectors.AzureOpenAI;
/*
Behind the scenes, the model recognizes the tool to call, what arguments it already has
(location) and (date)
{
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "BookTravelPlugin-book_flight",
"arguments": "{'location': 'New York', 'date': '2025-01-01'}"
}
}
]
*/
Console.WriteLine(response.Content);
chatHistory.AddMessage(response!.Role, response!.Content!);
// Example AI Model Response: Your flight to New York on January 1, 2025, has been
successfully booked. Safe travels! ✈ �
What you can see from this example is how you can leverage a pre-built parser to extract key information
from user input, such as the origin, destination, and date of a flight booking request. This modular approach
allows you to focus on the high-level logic.
Leverage Collaborative Tools
Frameworks like CrewAI, Microsoft AutoGen, and Semantic Kernel facilitate the creation of multiple agents
that can work together.
How teams can use these: Teams can design agents with specific roles and tasks, enabling them to test and
refine collaborative workflows and improve overall system efficiency.
How it works in practice: You can create a team of agents where each agent has a specialized function, such
as data retrieval, analysis, or decision-making. These agents can communicate and share information to
achieve a common goal, such as answering a user query or completing a task.
# creating agents, then create a round robin schedule where they can work together, in
this case in order
agent_retrieve = AssistantAgent(
name="dataretrieval",
model_client=model_client,
tools=[retrieve_tool],
system_message="Use tools to solve tasks."
)
agent_analyze = AssistantAgent(
name="dataanalysis",
model_client=model_client,
tools=[analyze_tool],
system_message="Use tools to solve tasks."
)
What you see in the previous code is how you can create a task that involves multiple agents working together
to analyze data. Each agent performs a specific function, and the task is executed by coordinating the agents to
achieve the desired outcome. By creating dedicated agents with specialized roles, you can improve task
efficiency and performance.
Learn in Real-Time
Advanced frameworks provide capabilities for real-time context understanding and adaptation.
How teams can use these: Teams can implement feedback loops where agents learn from interactions and
adjust their behavior dynamically, leading to continuous improvement and refinement of capabilities.
How it works in practice: Agents can analyze user feedback, environmental data, and task outcomes to
update their knowledge base, adjust decision-making algorithms, and improve performance over time. This
iterative learning process enables agents to adapt to changing conditions and user preferences, enhancing
overall system effectiveness.
AutoGen
AutoGen is an open-source framework developed by Microsoft Research's AI Frontiers Lab. It focuses on
event-driven, distributed agentic applications, enabling multiple LLMs and SLMs, tools, and advanced multi-
agent design patterns.
AutoGen is built around the core concept of agents, which are autonomous entities that can perceive their
environment, make decisions, and take actions to achieve specific goals. Agents communicate through
asynchronous messages, allowing them to work independently and in parallel, enhancing system scalability
and responsiveness.
Agents are based on the actor model. According to Wikipedia, an actor is the basic building block of
concurrent computation. In response to a message it receives, an actor can: make local decisions, create more
actors, send more messages, and determine how to respond to the next message received.
Use Cases: Automating code generation, data analysis tasks, and building custom agents for planning and
research functions.
Here you have a short code snippet in which you create your own agent with Chat capabilities:
class MyAssistant(RoutedAgent):
def __init__(self, name: str) -> None:
super().__init__(name)
model_client = OpenAIChatCompletionClient(model="gpt-4o")
self._delegate = AssistantAgent(name, model_client=model_client)
@message_handler
async def handle_my_message_type(self, message: MyMessageType, ctx:
MessageContext) -> None:
print(f"{self.id.type} received message: {message.content}")
response = await self._delegate.on_messages(
[TextMessage(content=message.content, source="user")],
ctx.cancellation_token
)
print(f"{self.id.type} responded: {response.chat_message.content}")
In the previous code, MyAssistant has been created and inherits from RoutedAgent. It has a message handler
that prints the content of the message and then sends a response using the AssistantAgent delegate.
Especially note how we assign to self._delegate an instance of AssistantAgent which is a pre-built agent
that can handle chat completions.
Let's let AutoGen know about this agent type and kick off the program next:
# main.py
runtime = SingleThreadedAgentRuntime()
await MyAgent.register(runtime, "my_agent", lambda: MyAgent())
In the previous code the agents are registered with the runtime and then a message is sent to the agent
resulting in the following output:
Multi agents. AutoGen supports the creation of multiple agents that can work together to achieve complex
tasks. Agents can communicate, share information, and coordinate their actions to solve problems more
efficiently. To create a multi-agent system, you can define different types of agents with specialized functions
and roles, such as data retrieval, analysis, decision-making, and user interaction. Let's see how such a creation
looks like so we get a sense of it:
# Group chat
group_chat_manager_type = await GroupChatManager.register(
runtime,
"group_chat_manager",
lambda: GroupChatManager(
participant_topic_types=[writer_topic_type, illustrator_topic_type,
editor_topic_type, user_topic_type],
model_client=OpenAIChatCompletionClient(
model="gpt-4o-2024-08-06",
# api_key="YOUR_API_KEY",
),
participant_descriptions=[
writer_description,
illustrator_description,
editor_description,
user_description
],
),
)
In the previous code we have a GroupChatManager that is registered with the runtime. This manager is
responsible for coordinating the interactions between different types of agents, such as writers,
illustrators, editors, and users.
Agent Runtime. The framework provides a runtime environment, enabling communication between
agents, manages their identities and lifecycles, and enforce security and privacy boundaries. This
means that you can run your agents in a secure and controlled environment, ensuring that they can
interact safely and efficiently. There are two runtimes of interest:
o Stand-alone runtime. This is a good choice for single-process applications where all agents
are implemented in the same programming language and run in the same process. Here's an
illustration of how it works:
Stand-alone runtime
Application stack
agents communicate via messages through the runtime, and the runtime manages the lifecycle
of agents
o Distributed agent runtime, is suitable for multi-process applications where agents may be
implemented in different programming languages and running on different machines. Here's an
illustration of how it works:
Distributed runtime
AI Connectors: This is an interface with external AI services and data sources for use in both Python
and C#.
# Semantic Kernel Python
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
from semantic_kernel.kernel import Kernel
kernel = Kernel()
kernel.add_service(
AzureChatCompletion(
deployment_name="your-deployment-name",
api_key="your-api-key",
endpoint="your-endpoint",
)
)
// Semantic Kernel C#
using Microsoft.SemanticKernel;
// Create kernel
var builder = Kernel.CreateBuilder();
Here you have a simple example of how you can create a kernel and add a chat completion service.
Semantic Kernel creates a connection to an external AI service, in this case, Azure OpenAI Chat Completion.
Plugins: These encapsulate functions that an application can use. There are both ready-made plugins and
custom ones you can create. A related concept is "prompt functions." Instead of providing natural language
cues for function invocation, you broadcast certain functions to the model. Based on the current chat context,
the model may choose to call one of these functions to complete a request or query. Here's an example:
kernel = Kernel()
kernel.add_service(AzureChatCompletion())
kernel_function = KernelFunctionFromPrompt(
function_name="SummarizeText",
prompt="""
Summarize the provided unstructured text in a sentence that is easy to
understand.
Text to summarize: {{$user_input}}
""",
)
"""
Sample Console Output:
if __name__ == "__main__":
import asyncio
asyncio.run(main())
var userInput = Console.ReadLine();
Here, you first have a template prompt skPrompt that leaves room for the user to input text, $userInput.
Then you create the kernel function SummarizeText and then import it into the kernel with the plugin name
SemanticFunctions. Note the name of the function that helps Semantic Kernel understand what the function
does and when it should be called.
Native function: There's also native functions that the framework can call directly to carry out the task.
Here's an example of such a function retrieving the content from a file:
Memory: Abstracts and simplifies context management for AI apps. The idea with memory is that this is
something the LLM should know about. You can store this information in a vector store which ends up being
an in-memory database or a vector database or similar. Here's an example of a very simplified scenario where
facts are added to the memory:
facts.Add(
"Azure SQL Service; https://learn.microsoft.com/azure/azure-sql/",
@"Azure SQL is a family of managed, secure, and intelligent products
that use the SQL Server database engine in the Azure cloud."
);
These facts are then stored in the memory collection SummarizedAzureDocs. This is a very simplified
example, but you can see how you can store information in the memory for the LLM to use.
So that's the basics of the Semantic Kernel framework, what about the Agent Framework?
Azure AI Agent Service provides stronger enterprise security mechanisms and data storage methods, making
it suitable for enterprise applications.
It works out-of-the-box with multi-agent orchestration frameworks like AutoGen and Semantic Kernel.
This service is currently in Public Preview and supports Python and C# for building agents.
Using Semantic Kernel Python, we can create an Azure AI Agent with a user-defined plugin:
import asyncio
from typing import Annotated
async with (
DefaultAzureCredential() as creds,
AzureAIAgent.create_client(
credential=creds,
conn_str=ai_agent_settings.project_connection_string.get_secret_value(),
) as client,
):
# Create agent definition
agent_definition = await client.agents.create_agent(
model=ai_agent_settings.model_deployment_name,
name="Host",
instructions="Answer questions about the menu.",
)
# Create the AzureAI Agent using the defined client and agent definition
agent = AzureAIAgent(
client=client,
definition=agent_definition,
plugins=[MenuPlugin()],
)
user_inputs = [
"Hello",
"What is the special soup?",
"How much does that cost?",
"Thank you",
]
try:
for user_input in user_inputs:
print(f"# User: '{user_input}'")
# Invoke the agent for the specified thread
response = await agent.get_response(
messages=user_input,
thread_id=thread,
)
print(f"# {response.name}: {response.content}")
thread = response.thread
finally:
await thread.delete() if thread else None
await client.agents.delete_agent(agent.id)
if __name__ == "__main__":
asyncio.run(main())
Core concepts
Agent. Azure AI Agent Service integrates with Azure AI Foundry. Within AI Foundry, an AI Agent
acts as a "smart" microservice that can be used to answer questions (RAG), perform actions, or
completely automate workflows. It achieves this by combining the power of generative AI models
with tools that allow it to access and interact with real-world data sources. Here's an example of an
agent:
agent = project_client.agents.create_agent(
model="gpt-4o-mini",
name="my-agent",
instructions="You are helpful agent",
tools=code_interpreter.definitions,
tool_resources=code_interpreter.resources,
)
In this example, an agent is created with the model gpt-4o-mini, a name my-agent, and instructions You
are helpful agent. The agent is equipped with tools and resources to perform code interpretation tasks.
Thread and messages. The thread is another important concept. It represents a conversation or interaction
between an agent and a user. Threads can be used to track the progress of a conversation, store context
information, and manage the state of the interaction. Here's an example of a thread:
thread = project_client.agents.create_thread()
message = project_client.agents.create_message(
thread_id=thread.id,
role="user",
content="Could you please create a bar chart for the operating profit using the
following data and provide the file to me? Company A: $1.2 million, Company B: $2.5
million, Company C: $3.0 million, Company D: $1.8 million",
)
In the previous code, a thread is created. Thereafter, a message is sent to the thread. By calling
create_and_process_run, the agent is asked to perform work on the thread. Finally, the messages
are fetched and logged to see the agent's response. The messages indicate the progress of the
conversation between the user and the agent. It's also important to understand that the messages can be
of different types such as text, image, or file, that is the agents work has resulted in for example an
image or a text response for example. As a developer, you can then use this information to further
process the response or present it to the user.
Integrates with other AI frameworks. Azure AI Agent service can interact with other frameworks
like AutoGen and Semantic Kernel, which means you can build part of your app in one of these
frameworks and for example using the Agent service as an orchestrator or you can build everything in
the Agent service.
Use Cases: Azure AI Agent Service is designed for enterprise applications that require secure, scalable, and
flexible AI agent deployment.
Use Cases
Let's see if we can help you by going through some common use cases:
Q: I'm experimenting, learning and building proof-of-concept agent applications, and I want to be able to
build and experiment quickly
A: AutoGen would be a good choice for this scenario, as it focuses on event-driven, distributed agentic
applications and supports advanced multi-agent design patterns.
Q: What makes AutoGen a better choice than Semantic Kernel and Azure AI Agent Service for this use case?
A: AutoGen is specifically designed for event-driven, distributed agentic applications, making it well-suited
for automating code generation and data analysis tasks. It provides the necessary tools and capabilities to build
complex multi-agent systems efficiently.
Q: Sounds like Azure AI Agent Service could work here too, it has tools for code generation and more?
A: Yes, Azure AI Agent Service is a platform service for agents and add built-in capabilities for multiple
models, Azure AI Search, Bing Search and Azure Functions. It makes it easy to build your agents in the
Foundry Portal and deploy them at scale.
A: A great choice is to build your application in Semantic Kernel first and then use Azure AI Agent Service to
deploy your agent. This approach allows you to easily persist your agents while leveraging the power to build
multi-agent systems in Semantic Kernel. Additionally, Semantic Kernel has a connector in AutoGen, making
it easy to use both frameworks together.
Event-driven, distributed agentic Agents, Personas, Functions, Code generation, data analysis
AutoGen
applications Data tasks
Natural language
Understanding and generating Agents, Modular
Semantic Kernel understanding, content
human-like text content Components, Collaboration
generation
Azure AI Agent Flexible models, enterprise security, Modularity, Collaboration, Secure, scalable, and flexible AI
Service Code generation, Tool calling Process Orchestration agent deployment
For AutoGen and Semantic Kernel, you can also integrate with Azure services, but it may require you to call
the Azure services from your code. Another way to integrate is to use the Azure SDKs to interact with Azure
services from your agents. Additionally, like was mentioned, you can use Azure AI Agent Service as an
orchestrator for your agents built in AutoGen or Semantic Kernel which would give easy access to the Azure
ecosystem.