Skip to content

Python: Multi-agent orchestration: Magentic #12104

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 16, 2025
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion python/.cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"logit",
"logprobs",
"lowlevel",
"Magentic",
"mistralai",
"mongocluster",
"nd",
Expand Down Expand Up @@ -77,4 +78,4 @@
"vertexai",
"Weaviate"
]
}
}
29 changes: 15 additions & 14 deletions python/samples/getting_started_with_agents/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,6 @@ Example|Description

_Note: For details on configuring an Azure AI Agent, please see [here](../getting_started_with_agents/azure_ai_agent/README.md)._

## Multi Agent Orchestration

Example|Description
---|---
[step1_concurrent](../getting_started_with_agents/multi_agent_orchestration/step1_concurrent.py)|How to run multiple agents concurrently and manage their output.
[step1a_concurrent_structure_output](../getting_started_with_agents/multi_agent_orchestration/step1a_concurrent_structure_output.py)|How to run concurrent agents that return structured outputs.
[step2_sequential](../getting_started_with_agents/multi_agent_orchestration/step2_sequential.py)|How to run agents sequentially where each one depends on the previous.
[step2a_sequential_cancellation_token](../getting_started_with_agents/multi_agent_orchestration/step2a_sequential_cancellation_token.py)|How to use cancellation tokens in a sequential agent flow.
[step3_group_chat](../getting_started_with_agents/multi_agent_orchestration/step3_group_chat.py)|How to create a group chat with multiple agents interacting together.
[step3a_group_chat_human_in_the_loop](../getting_started_with_agents/multi_agent_orchestration/step3a_group_chat_human_in_the_loop.py)|How to include a human participant in a group chat with agents.
[step3b_group_chat_with_chat_completion_manager](../getting_started_with_agents/multi_agent_orchestration/step3b_group_chat_with_chat_completion_manager.py)|How to manage a group chat with agents using a chat completion manager.
[step4_handoff](../getting_started_with_agents/multi_agent_orchestration/step4_handoff.py)|How to hand off conversation or tasks from one agent to another.
[step4a_handoff_structured_inputs](../getting_started_with_agents/multi_agent_orchestration/step4a_handoff_structured_inputs.py)|How to perform structured inputs handoffs between agents.


## OpenAI Assistant Agent

Expand All @@ -86,6 +72,21 @@ Example|Description
[step6_responses_agent_vision](../getting_started_with_agents/openai_responses/step6_responses_agent_vision.py)|How to provide an image as input to an OpenAI Responses agent.
[step7_responses_agent_structured_outputs](../getting_started_with_agents/openai_responses/step7_responses_agent_structured_outputs.py)|How to use have an OpenAI Responses agent use structured outputs.

## Multi-Agent Orchestration

Example|Description
---|---
[step1_concurrent](../getting_started_with_agents/multi_agent_orchestration/step1_concurrent.py)|How to run agents in parallel on the same task.
[step1a_concurrent_structure_output](../getting_started_with_agents/multi_agent_orchestration/step1a_concurrent_structure_output.py)|How to run agents in parallel on the same task and return structured output.
[step2_sequential](../getting_started_with_agents/multi_agent_orchestration/step2_sequential.py)|How to run agents in sequence to complete a task.
[step2a_sequential_cancellation_token](../getting_started_with_agents/multi_agent_orchestration/step2a_sequential_cancellation_token.py)|How to cancel an invocation while it is in progress.
[step3_group_chat](../getting_started_with_agents/multi_agent_orchestration/step3_group_chat.py)|How to run agents in a group chat to complete a task.
[step3a_group_chat_human_in_the_loop](../getting_started_with_agents/multi_agent_orchestration/step3a_group_chat_human_in_the_loop.py)|How to run agents in a group chat with human in the loop.
[step3b_group_chat_with_chat_completion_manager](../getting_started_with_agents/multi_agent_orchestration/step3b_group_chat_with_chat_completion_manager.py)|How to run agents in a group chat with a more dynamic manager.
[step4_handoff](../getting_started_with_agents/multi_agent_orchestration/step4_handoff.py)|How to run agents in a handoff orchestration to complete a task.
[step4a_handoff_structure_input](../getting_started_with_agents/multi_agent_orchestration/step4a_handoff_structure_input.py)|How to run agents in a handoff orchestration to complete a task with structured input.
[step5_magentic](../getting_started_with_agents/multi_agent_orchestration/step5_magentic.py)|How to run agents in a Magentic orchestration to complete a task.

## Configuring the Kernel

Similar to the Semantic Kernel Python concept samples, it is necessary to configure the secrets
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Multi-agent orchestration

The Semantic Kernel Agent Framework now supports orchestrating multiple agents to work together to complete a task.

## Background

The following samples are beneficial if you are just getting started with Semantic Kernel.

- [Chat Completion](../../concepts/chat_completion/)
- [Auto Function Calling](../../concepts/auto_function_calling/)
- [Structured Output](../../concepts/structured_output/)
- [Getting Started with Agents](../../getting_started_with_agents/)
- [More advanced agent samples](../../concepts/agents/)

## Prerequisites

The following environment variables are required to run the samples:

- OPENAI_API_KEY
- OPENAI_CHAT_MODEL_ID

However, if you are using other model services, feel free to switch to those in the samples.
Refer to [here](../../concepts/setup/README.md) on how to set up the environment variables for your model service.

## Orchestrations

| **Orchestrations** | **Description** |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Concurrent** | Useful for tasks that will benefit from independent analysis from multiple agents. |
| **Sequential** | Useful for tasks that require a well-defined step-by-step approach. |
| **Handoff** | Useful for tasks that are dynamic in nature and don't have a well-defined step-by-step approach. |
| **GroupChat** | Useful for tasks that will benefit from inputs from multiple agents and a highly configurable conversation flow. |
| **Magentic** | GroupChat like with a planner based manager. Inspired by [Magentic One](https://www.microsoft.com/en-us/research/articles/magentic-one-a-generalist-multi-agent-system-for-solving-complex-tasks/). |

## Samples

| Sample | Description |
|-----------------------------------------------------------------------------|--------------|
| [step1_concurrent](step1_concurrent.py) | Run agents in parallel on the same task. |
| [step1a_concurrent_structure_output](step1a_concurrent_structure_output.py) | Run agents in parallel on the same task and return structured output. |
| [step2_sequential](step2_sequential.py) | Run agents in sequence to complete a task. |
| [step2a_sequential_cancellation_token](step2a_sequential_cancellation_token.py) | Cancel an invocation while it is in progress. |
| [step3_group_chat](step3_group_chat.py) | Run agents in a group chat to complete a task. |
| [step3a_group_chat_human_in_the_loop](step3a_group_chat_human_in_the_loop.py) | Run agents in a group chat with human in the loop. |
| [step3b_group_chat_with_chat_completion_manager](step3b_group_chat_with_chat_completion_manager.py) | Run agents in a group chat with a more dynamic manager. |
| [step4_handoff](step4_handoff.py) | Run agents in a handoff orchestration to complete a task. |
| [step4a_handoff_structure_input](step4a_handoff_structure_input.py) | Run agents in a handoff orchestration to complete a task with structured input. |
| [step5_magentic](step5_magentic.py) | Run agents in a Magentic orchestration to complete a task. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# Copyright (c) Microsoft. All rights reserved.

import asyncio

from semantic_kernel.agents import Agent, ChatCompletionAgent, MagenticOrchestration, OpenAIAssistantAgent
from semantic_kernel.agents.orchestration.magentic import StandardMagenticManager
from semantic_kernel.agents.runtime import InProcessRuntime
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion, OpenAIPromptExecutionSettings
from semantic_kernel.contents import ChatMessageContent

"""
The following sample demonstrates how to create a Magentic orchestration with two agents:
- A Research agent that can perform web searches
- A Coder agent that can run code using the code interpreter

Read more about Magentic here:
https://www.microsoft.com/en-us/research/articles/magentic-one-a-generalist-multi-agent-system-for-solving-complex-tasks/

This sample demonstrates the basic steps of creating and starting a runtime, creating
a Magentic orchestration with two agents and a Magentic manager, invoking the
orchestration, and finally waiting for the results.

The Magentic manager requires a chat completion model that supports structured output.
"""


async def agents() -> list[Agent]:
"""Return a list of agents that will participate in the Magentic orchestration.

Feel free to add or remove agents.
"""
research_agent = ChatCompletionAgent(
name="ResearchAgent",
description="A helpful assistant with access to web search. Ask it to perform web searches.",
instructions=(
"You are a Researcher. You find information without additional computation or quantitative analysis."
),
# This agent requires the gpt-4o-search-preview model to perform web searches.
service=OpenAIChatCompletion(ai_model_id="gpt-4o-search-preview"),
)

# Create an OpenAI Assistant agent with code interpreter capability
client, model = OpenAIAssistantAgent.setup_resources()
code_interpreter_tool, code_interpreter_tool_resources = OpenAIAssistantAgent.configure_code_interpreter_tool()
definition = await client.beta.assistants.create(
model=model,
name="CoderAgent",
description="A helpful assistant with code interpreter capability.",
instructions="You solve questions using code. Please provide detailed analysis and computation process.",
tools=code_interpreter_tool,
tool_resources=code_interpreter_tool_resources,
)
coder_agent = OpenAIAssistantAgent(
client=client,
definition=definition,
)

return [research_agent, coder_agent]


def agent_response_callback(message: ChatMessageContent) -> None:
"""Observer function to print the messages from the agents."""
print(f"**{message.name}**\n{message.content}")


async def main():
"""Main function to run the agents."""
# 1. Create a Magentic orchestration with two agents and a Magentic manager
# Note, the Magentic manager accepts custom prompts for advanced users and scenarios.
magentic_orchestration = MagenticOrchestration(
members=await agents(),
manager=StandardMagenticManager(
chat_completion_service=OpenAIChatCompletion(),
prompt_execution_settings=OpenAIPromptExecutionSettings(),
),
agent_response_callback=agent_response_callback,
)

# 2. Create a runtime and start it
runtime = InProcessRuntime()
runtime.start()

# 3. Invoke the orchestration with a task and the runtime
orchestration_result = await magentic_orchestration.invoke(
task=(
"The 2025 trade war between the US and other countries has had a significant impact "
"on the global economy. I am a business owner in the US that import household goods "
"such as bed sheets and holiday decorations from south-east Asia. I want "
"to know the impact of the tariffs on my business given that my current profit "
"margin is 20%. And If I were to increase the price of my products by 10%, "
"how would that affect my customer behavior and profit margin? Base on the analysis, "
"find similar cases in the past to cross-reference the results. Provide a detailed "
"report and recommendations on how to adapt to the changing market conditions at the end."
),
runtime=runtime,
)

# 4. Wait for the results
value = await orchestration_result.get()

print(f"\nFinal result:\n{value}")

# 5. Stop the runtime when idle
await runtime.stop_when_idle()

"""
Sample output:
**ResearchAgent**
The 2025 trade war has led to significant tariffs imposed by the United States on imports from Southeast Asian
countries, directly affecting industries such as household goods. For instance, Cambodia faces a 49% tariff,
Vietnam 46%, and Thailand 36% on their exports to the U.S.
([thailandinfo.se](https://www.thailandinfo.se/en/usa-tariffs-southeast-asia-2025/?utm_source=openai))

...
**CoderAgent**
Here's the analysis based on your scenario:

1. **Initial Scenario:**
- Initial Selling Price: $125.00 (to achieve a 20% profit margin)

2. **After Applying Tariffs:**
- New Cost Price: $145.00 (after a 45% tariff on the initial $100 cost)

3. **With a 10% Price Increase:**
- New Selling Price: $137.50

4. **Profit Margin and Volume Impact:**
...
**ResearchAgent**
In response to increased tariffs during trade wars, various companies have implemented strategic measures to
mitigate financial impacts and maintain competitiveness. Notable examples include:

**1. Supply Chain Diversification:**

- **Steven Madden Ltd.:** Faced with a 10% tariff on handbags imported from China, the company relocated
production to Cambodia to circumvent the tariffs.([money.usnews.com](https://money.usnews.com/money/blogs/...
**CoderAgent**
Here's a detailed simulated report on the potential business impact due to tariffs and price adjustments,
along with strategic recommendations:

### Financial Impact Summary:

1. **New Cost Price after Tariffs:** $145.00
2. **New Selling Price after 10% Increase:** $137.50
3. **New Profit Margin:** -5.45%
4. **Estimated Sales Volume Change:** Decrease to 95.0% of original
5. **New Estimated Profit per Unit:** Negative $7.12

### Strategies from Historical Cases:
...
"""


if __name__ == "__main__":
asyncio.run(main())
9 changes: 9 additions & 0 deletions python/semantic_kernel/agents/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@
"HandoffOrchestration": ".orchestration.handoffs",
"OrchestrationHandoffs": ".orchestration.handoffs",
"GroupChatOrchestration": ".orchestration.group_chat",
"RoundRobinGroupChatManager": ".orchestration.group_chat",
"BooleanResult": ".orchestration.group_chat",
"StringResult": ".orchestration.group_chat",
"MessageResult": ".orchestration.group_chat",
"GroupChatManager": ".orchestration.group_chat",
"MagenticOrchestration": ".orchestration.magentic",
"ProgressLedger": ".orchestration.magentic",
"MagenticManager": ".orchestration.magentic",
"StandardMagenticManager": ".orchestration.magentic",
}


Expand Down
17 changes: 16 additions & 1 deletion python/semantic_kernel/agents/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,16 @@ from .open_ai.open_ai_assistant_agent import AssistantAgentThread, OpenAIAssista
from .open_ai.openai_responses_agent import OpenAIResponsesAgent, ResponsesAgentThread
from .open_ai.run_polling_options import RunPollingOptions
from .orchestration.concurrent import ConcurrentOrchestration
from .orchestration.group_chat import GroupChatManager, GroupChatOrchestration, RoundRobinGroupChatManager
from .orchestration.group_chat import (
BooleanResult,
GroupChatManager,
GroupChatOrchestration,
MessageResult,
RoundRobinGroupChatManager,
StringResult,
)
from .orchestration.handoffs import HandoffOrchestration, OrchestrationHandoffs
from .orchestration.magentic import MagenticManager, MagenticOrchestration, ProgressLedger, StandardMagenticManager
from .orchestration.sequential import SequentialOrchestration

__all__ = [
Expand All @@ -49,6 +57,7 @@ __all__ = [
"AzureResponsesAgent",
"BedrockAgent",
"BedrockAgentThread",
"BooleanResult",
"ChatCompletionAgent",
"ChatHistoryAgentThread",
"ConcurrentOrchestration",
Expand All @@ -60,15 +69,21 @@ __all__ = [
"GroupChatManager",
"GroupChatOrchestration",
"HandoffOrchestration",
"MagenticManager",
"MagenticOrchestration",
"MessageResult",
"ModelConnection",
"ModelSpec",
"OpenAIAssistantAgent",
"OpenAIResponsesAgent",
"OrchestrationHandoffs",
"ProgressLedger",
"ResponsesAgentThread",
"RoundRobinGroupChatManager",
"RunPollingOptions",
"SequentialOrchestration",
"StandardMagenticManager",
"StringResult",
"ToolSpec",
"register_agent_type",
]
Loading
Loading