Python: semantic-kernel to agent-framework migration code samples (#1045)

* wip migrations

* Wip: workflow migrations

* Add migration samples for sk to af

* Fix typo

* Fixes
This commit is contained in:
Evan Mattson
2025-10-01 16:02:03 +09:00
committed by GitHub
Unverified
parent 498fc06fd6
commit fb51d917fd
23 changed files with 1817 additions and 5 deletions
@@ -0,0 +1,123 @@
# Copyright (c) Microsoft. All rights reserved.
"""Side-by-side concurrent orchestrations for Agent Framework and Semantic Kernel."""
import asyncio
from collections.abc import Sequence
from typing import cast
from agent_framework import ChatMessage, ConcurrentBuilder, WorkflowOutputEvent
from agent_framework.azure import AzureOpenAIChatClient
from azure.identity import AzureCliCredential
from semantic_kernel.agents import Agent, ChatCompletionAgent, ConcurrentOrchestration
from semantic_kernel.agents.runtime import InProcessRuntime
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
from semantic_kernel.contents import ChatMessageContent
PROMPT = "Explain the concept of temperature from multiple scientific perspectives."
######################################################################
# Semantic Kernel orchestration path
######################################################################
def build_semantic_kernel_agents() -> list[Agent]:
credential = AzureCliCredential()
physics_agent = ChatCompletionAgent(
name="PhysicsExpert",
instructions=("You are an expert in physics. Answer questions from a physics perspective."),
service=AzureChatCompletion(credential=credential),
)
chemistry_agent = ChatCompletionAgent(
name="ChemistryExpert",
instructions=("You are an expert in chemistry. Answer questions from a chemistry perspective."),
service=AzureChatCompletion(credential=credential),
)
return [physics_agent, chemistry_agent]
async def run_semantic_kernel_example(prompt: str) -> Sequence[ChatMessageContent]:
concurrent_orchestration = ConcurrentOrchestration(members=build_semantic_kernel_agents())
runtime = InProcessRuntime()
runtime.start()
try:
orchestration_result = await concurrent_orchestration.invoke(task=prompt, runtime=runtime)
final_value = await orchestration_result.get(timeout=60)
if isinstance(final_value, ChatMessageContent):
return [final_value]
if isinstance(final_value, Sequence):
return list(final_value)
return []
finally:
await runtime.stop_when_idle()
def _print_semantic_kernel_outputs(outputs: Sequence[ChatMessageContent]) -> None:
if not outputs:
print("No Semantic Kernel output.")
return
print("===== Semantic Kernel Concurrent =====")
for item in outputs:
content = item.content or ""
print(f"# {item.name}\n{content}\n")
######################################################################
# Agent Framework orchestration path
######################################################################
async def run_agent_framework_example(prompt: str) -> Sequence[list[ChatMessage]]:
chat_client = AzureOpenAIChatClient(credential=AzureCliCredential())
physics = chat_client.create_agent(
instructions=("You are an expert in physics. Answer questions from a physics perspective."),
name="physics",
)
chemistry = chat_client.create_agent(
instructions=("You are an expert in chemistry. Answer questions from a chemistry perspective."),
name="chemistry",
)
workflow = ConcurrentBuilder().participants([physics, chemistry]).build()
outputs: list[list[ChatMessage]] = []
async for event in workflow.run_stream(prompt):
if isinstance(event, WorkflowOutputEvent):
outputs.append(cast(list[ChatMessage], event.data))
return outputs
def _print_agent_framework_outputs(conversations: Sequence[Sequence[ChatMessage]]) -> None:
if not conversations:
print("No Agent Framework output.")
return
print("===== Agent Framework Concurrent =====")
for index, conversation in enumerate(conversations, start=1):
print(f"--- Conversation {index} ---")
for message in conversation:
name = message.author_name or "assistant"
print(f"[{name}] {message.text}")
print()
async def main() -> None:
agent_framework_outputs = await run_agent_framework_example(PROMPT)
_print_agent_framework_outputs(agent_framework_outputs)
semantic_kernel_outputs = await run_semantic_kernel_example(PROMPT)
_print_semantic_kernel_outputs(semantic_kernel_outputs)
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,172 @@
# Copyright (c) Microsoft. All rights reserved.
"""Side-by-side Magentic orchestrations for Agent Framework and Semantic Kernel."""
import asyncio
from collections.abc import Sequence
from typing import cast
from agent_framework import ChatAgent, HostedCodeInterpreterTool, MagenticBuilder, WorkflowOutputEvent
from agent_framework.openai import OpenAIChatClient, OpenAIResponsesClient
from semantic_kernel.agents import (
Agent,
ChatCompletionAgent,
MagenticOrchestration,
OpenAIAssistantAgent,
StandardMagenticManager,
)
from semantic_kernel.agents.runtime import InProcessRuntime
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion, OpenAISettings
from semantic_kernel.contents import ChatMessageContent
PROMPT = (
"I am preparing a report on the energy efficiency of different machine learning model architectures. "
"Compare the estimated training and inference energy consumption of ResNet-50, BERT-base, and GPT-2 "
"on standard datasets (e.g., ImageNet for ResNet, GLUE for BERT, WebText for GPT-2). "
"Then, estimate the CO2 emissions associated with each, assuming training on an Azure Standard_NC6s_v3 VM "
"for 24 hours. Provide tables for clarity, and recommend the most energy-efficient model per task type "
"(image classification, text classification, and text generation)."
)
######################################################################
# Semantic Kernel orchestration path
######################################################################
async def build_semantic_kernel_agents() -> list[Agent]:
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."
),
service=OpenAIChatCompletion(ai_model_id="gpt-4o-search-preview"),
)
client = OpenAIAssistantAgent.create_client()
code_interpreter_tool, code_interpreter_tool_resources = OpenAIAssistantAgent.configure_code_interpreter_tool()
openai_settings = OpenAISettings()
model_id = openai_settings.chat_model_id if openai_settings.chat_model_id else "gpt-5"
definition = await client.beta.assistants.create(
model=model_id,
name="CoderAgent",
description="A helpful assistant that writes and executes code to process and analyze data.",
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 sk_agent_response_callback(
message: ChatMessageContent | Sequence[ChatMessageContent],
) -> None:
if isinstance(message, ChatMessageContent):
messages: Sequence[ChatMessageContent] = [message]
elif isinstance(message, Sequence) and not isinstance(message, (str, bytes)):
messages = [item for item in message if isinstance(item, ChatMessageContent)]
else:
messages = []
for item in messages:
content = item.content or ""
print(f"**{item.name}**\n{content}\n")
async def run_semantic_kernel_example(prompt: str) -> Sequence[ChatMessageContent]:
agents = await build_semantic_kernel_agents()
magentic_orchestration = MagenticOrchestration(
members=agents,
manager=StandardMagenticManager(chat_completion_service=OpenAIChatCompletion()),
agent_response_callback=sk_agent_response_callback,
)
runtime = InProcessRuntime()
runtime.start()
try:
orchestration_result = await magentic_orchestration.invoke(task=prompt, runtime=runtime)
value = await orchestration_result.get()
if isinstance(value, ChatMessageContent):
return [value]
if isinstance(value, Sequence) and not isinstance(value, (str, bytes)):
return [item for item in value if isinstance(item, ChatMessageContent)]
return []
finally:
await runtime.stop_when_idle()
def _print_semantic_kernel_outputs(outputs: Sequence[ChatMessageContent]) -> None:
if not outputs:
print("No Semantic Kernel output.")
return
print("===== Semantic Kernel Magentic =====")
for item in outputs:
content = item.content or ""
print(f"**{item.name}**\n{content}\n")
######################################################################
# Agent Framework orchestration path
######################################################################
async def run_agent_framework_example(prompt: str) -> str | None:
researcher = ChatAgent(
name="ResearcherAgent",
description="Specialist in research and information gathering",
instructions=(
"You are a Researcher. You find information without additional computation or quantitative analysis."
),
chat_client=OpenAIChatClient(ai_model_id="gpt-4o-search-preview"),
)
coder = ChatAgent(
name="CoderAgent",
description="A helpful assistant that writes and executes code to process and analyze data.",
instructions="You solve questions using code. Please provide detailed analysis and computation process.",
chat_client=OpenAIResponsesClient(),
tools=HostedCodeInterpreterTool(),
)
workflow = (
MagenticBuilder()
.participants(researcher=researcher, coder=coder)
.with_standard_manager(chat_client=OpenAIChatClient())
.build()
)
final_text: str | None = None
async for event in workflow.run_stream(prompt):
if isinstance(event, WorkflowOutputEvent):
final_text = cast(str, event.data)
return final_text
def _print_agent_framework_output(result: str | None) -> None:
if result is None:
print("No Agent Framework output.")
return
print("===== Agent Framework Magentic =====")
print(result)
async def main() -> None:
agent_framework_result = await run_agent_framework_example(PROMPT)
_print_agent_framework_output(agent_framework_result)
semantic_kernel_outputs = await run_semantic_kernel_example(PROMPT)
_print_semantic_kernel_outputs(semantic_kernel_outputs)
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,127 @@
# Copyright (c) Microsoft. All rights reserved.
"""Side-by-side sequential orchestrations for Agent Framework and Semantic Kernel."""
import asyncio
from collections.abc import Sequence
from typing import cast
from agent_framework import ChatMessage, Role, SequentialBuilder, WorkflowOutputEvent
from agent_framework.azure import AzureOpenAIChatClient
from azure.identity import AzureCliCredential
from semantic_kernel.agents import Agent, ChatCompletionAgent, SequentialOrchestration
from semantic_kernel.agents.runtime import InProcessRuntime
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
from semantic_kernel.contents import ChatMessageContent
PROMPT = "Write a tagline for a budget-friendly eBike."
######################################################################
# Semantic Kernel orchestration path
######################################################################
def build_semantic_kernel_agents() -> list[Agent]:
credential = AzureCliCredential()
writer_agent = ChatCompletionAgent(
name="WriterAgent",
instructions=("You are a concise copywriter. Provide a single, punchy marketing sentence based on the prompt."),
service=AzureChatCompletion(credential=credential),
)
reviewer_agent = ChatCompletionAgent(
name="ReviewerAgent",
instructions=("You are a thoughtful reviewer. Give brief feedback on the previous assistant message."),
service=AzureChatCompletion(credential=credential),
)
return [writer_agent, reviewer_agent]
async def sk_agent_response_callback(
message: ChatMessageContent | Sequence[ChatMessageContent],
) -> None:
if isinstance(message, ChatMessageContent):
messages: Sequence[ChatMessageContent] = [message]
elif isinstance(message, Sequence) and not isinstance(message, (str, bytes)):
messages = list(message)
else:
messages = [cast(ChatMessageContent, message)]
for item in messages:
content = item.content or ""
print(f"# {item.name}\n{content}\n")
######################################################################
# Agent Framework orchestration path
######################################################################
async def run_agent_framework_example(prompt: str) -> list[ChatMessage]:
chat_client = AzureOpenAIChatClient(credential=AzureCliCredential())
writer = chat_client.create_agent(
instructions=("You are a concise copywriter. Provide a single, punchy marketing sentence based on the prompt."),
name="writer",
)
reviewer = chat_client.create_agent(
instructions=("You are a thoughtful reviewer. Give brief feedback on the previous assistant message."),
name="reviewer",
)
workflow = SequentialBuilder().participants([writer, reviewer]).build()
conversation_outputs: list[list[ChatMessage]] = []
async for event in workflow.run_stream(prompt):
if isinstance(event, WorkflowOutputEvent):
conversation_outputs.append(cast(list[ChatMessage], event.data))
return conversation_outputs[-1] if conversation_outputs else []
async def run_semantic_kernel_example(prompt: str) -> str:
sequential_orchestration = SequentialOrchestration(
members=build_semantic_kernel_agents(),
agent_response_callback=sk_agent_response_callback,
)
runtime = InProcessRuntime()
runtime.start()
try:
orchestration_result = await sequential_orchestration.invoke(task=prompt, runtime=runtime)
final_message = await orchestration_result.get(timeout=20)
if isinstance(final_message, ChatMessageContent):
return final_message.content or ""
return str(final_message)
finally:
await runtime.stop_when_idle()
def _format_conversation(conversation: list[ChatMessage]) -> None:
if not conversation:
print("No Agent Framework output.")
return
print("===== Agent Framework Sequential =====")
for index, message in enumerate(conversation, start=1):
name = message.author_name or ("assistant" if message.role == Role.ASSISTANT else "user")
print(f"{'-' * 60}\n{index:02d} [{name}]\n{message.text}")
print()
async def main() -> None:
conversation = await run_agent_framework_example(PROMPT)
_format_conversation(conversation)
print("===== Semantic Kernel Sequential =====")
final_text = await run_semantic_kernel_example(PROMPT)
print(final_text)
if __name__ == "__main__":
asyncio.run(main())