chore: import upstream snapshot with attribution
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:21:23 +08:00
commit b957a53def
5423 changed files with 863745 additions and 0 deletions
@@ -0,0 +1,44 @@
# Chat Completion Agents
The following samples demonstrate how to get started with Chat Completion Agents using Semantic Kernel.
## Configuring a Chat Completion Agent
The `ChatCompletionAgent` relies on an underlying AI service connector. Depending on the AI service you choose, you may need to install additional packages. Refer to the [official SK documentation](https://learn.microsoft.com/en-us/semantic-kernel/concepts/ai-services/chat-completion/?tabs=csharp-AzureOpenAI%2Cpython-AzureOpenAI%2Cjava-AzureOpenAI&pivots=programming-language-python#installing-the-necessary-packages-1) for guidance on which extras are required.
Next, follow this [configuration guide](../../concepts/README.md#configuring-the-kernel) to set up your environment for running the sample code.
If you're developing outside the Semantic Kernel repository, it's recommended to place your `.env` file at the root of your project. When using VSCode, this allows the IDE to automatically load the `.env` file and make the environment variables available to your application.
This setup enables the following code to work without explicitly passing keyword arguments to the AI service constructor:
```python
from semantic_kernel.agents import ChatCompletionAgent
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
agent = ChatCompletionAgent(
service=AzureChatCompletion(), # No explicit kwargs needed due to environment variable configuration
name="Assistant",
instructions="Answer questions about the world in one sentence.",
)
```
If you prefer to configure the service manually, you can do the following:
```python
from semantic_kernel.agents import ChatCompletionAgent
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
agent = ChatCompletionAgent(
service=AzureChatCompletion(
api_key="your-api-key",
endpoint="your-aoai-endpoint",
deployment_name="your-deployment-name",
api_version="2025-03-01-preview" # Replace with your desired API version
),
name="Assistant",
instructions="Answer questions about the world in one sentence.",
)
```
For more information about the `ChatCompletionAgent` see Semantic Kernel's official documentation [here](https://learn.microsoft.com/en-us/semantic-kernel/frameworks/agent/chat-completion-agent?pivots=programming-language-python).
@@ -0,0 +1,56 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from azure.identity import AzureCliCredential
from semantic_kernel.agents import ChatCompletionAgent
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
"""
The following sample demonstrates how to create a chat completion agent that
answers user questions using the Azure Chat Completion service. The Chat Completion
Service is passed directly via the ChatCompletionAgent constructor. This sample
demonstrates the basic steps to create an agent and simulate a conversation
with the agent.
The interaction with the agent is via the `get_response` method, which sends a
user input to the agent and receives a response from the agent.
"""
# Simulate a conversation with the agent
USER_INPUTS = [
"Why is the sky blue?",
"What is the capital of France?",
]
async def main():
# 1. Create the agent by specifying the service
agent = ChatCompletionAgent(
service=AzureChatCompletion(credential=AzureCliCredential()),
name="Assistant",
instructions="Answer questions about the world in one sentence.",
)
for user_input in USER_INPUTS:
print(f"# User: {user_input}")
# 2. Invoke the agent for a response
response = await agent.get_response(
messages=user_input,
)
# 3. Print the response
print(f"# {response.name}: {response}")
"""
Sample output:
# User: Why is the sky blue?
# Assistant: The sky appears blue because molecules in the Earth's atmosphere scatter shorter wavelengths of
sunlight, like blue, more than the longer wavelengths, causing the sky to look blue to our eyes.
# User: What is the capital of France?
# Assistant: The capital of France is Paris.
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,73 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from azure.identity import AzureCliCredential
from semantic_kernel.agents import (
ChatCompletionAgent,
ChatHistoryAgentThread,
)
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
"""
The following sample demonstrates how to create a chat completion agent that
answers user questions using the Azure Chat Completion service. The Chat Completion
Service is passed directly via the ChatCompletionAgent constructor. This sample
demonstrates the basic steps to create an agent and simulate a conversation
with the agent.
The interaction with the agent is via the `get_response` method, which sends a
user input to the agent and receives a response from the agent. The conversation
history needs to be maintained by the caller in the chat history object.
"""
# Simulate a conversation with the agent
USER_INPUTS = [
"Hello, I am John Doe.",
"What is your name?",
"What is my name?",
]
async def main():
# 1. Create the agent by specifying the service
agent = ChatCompletionAgent(
service=AzureChatCompletion(credential=AzureCliCredential()),
name="Assistant",
instructions="Answer the user's questions.",
)
# 2. Create a thread to hold the conversation
# If no thread is provided, a new thread will be
# created and returned with the initial response
thread: ChatHistoryAgentThread = None
for user_input in USER_INPUTS:
print(f"# User: {user_input}")
# 3. Invoke the agent for a response
response = await agent.get_response(
messages=user_input,
thread=thread,
)
print(f"# {response.name}: {response}")
# 4. Store the thread, which allows the agent to
# maintain conversation history across multiple messages.
thread = response.thread
# 5. Cleanup: Clear the thread
await thread.delete() if thread else None
"""
Sample output:
# User: Hello, I am John Doe.
# Assistant: Hello, John Doe! How can I assist you today?
# User: What is your name?
# Assistant: I don't have a personal name like a human does, but you can call me Assistant.?
# User: What is my name?
# Assistant: You mentioned that your name is John Doe. How can I assist you further, John?
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,75 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from azure.identity import AzureCliCredential
from semantic_kernel import Kernel
from semantic_kernel.agents import ChatCompletionAgent, ChatHistoryAgentThread
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
"""
The following sample demonstrates how to create a chat completion agent that
answers user questions using the Azure Chat Completion service. The Chat Completion
Service is first added to the kernel, and the kernel is passed in to the
ChatCompletionAgent constructor. This sample demonstrates the basic steps to
create an agent and simulate a conversation with the agent.
Note: if both a service and a kernel are provided, the service will be used.
The interaction with the agent is via the `get_response` method, which sends a
user input to the agent and receives a response from the agent. The conversation
history needs to be maintained by the caller in the chat history object.
"""
# Simulate a conversation with the agent
USER_INPUTS = [
"Hello, I am John Doe.",
"What is your name?",
"What is my name?",
]
async def main():
# 1. Create the instance of the Kernel to register an AI service
kernel = Kernel()
kernel.add_service(AzureChatCompletion(credential=AzureCliCredential()))
# 2. Create the agent
agent = ChatCompletionAgent(
kernel=kernel,
name="Assistant",
instructions="Answer the user's questions.",
)
# 3. Create a thread to hold the conversation
# If no thread is provided, a new thread will be
# created and returned with the initial response
thread: ChatHistoryAgentThread = None
for user_input in USER_INPUTS:
print(f"# User: {user_input}")
# 4. Invoke the agent for a response
response = await agent.get_response(
messages=user_input,
thread=thread,
)
print(f"# {response.name}: {response}")
thread = response.thread
# 4. Cleanup: Clear the thread
await thread.delete() if thread else None
"""
Sample output:
# User: Hello, I am John Doe.
# Assistant: Hello, John Doe! How can I assist you today?
# User: What is your name?
# Assistant: I don't have a personal name like a human does, but you can call me Assistant.?
# User: What is my name?
# Assistant: You mentioned that your name is John Doe. How can I assist you further, John?
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,86 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from typing import Annotated
from azure.identity import AzureCliCredential
from semantic_kernel.agents import ChatCompletionAgent, ChatHistoryAgentThread
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
from semantic_kernel.functions import kernel_function
"""
The following sample demonstrates how to create a chat completion agent that
answers questions about a sample menu using a Semantic Kernel Plugin. The Chat
Completion Service is passed directly via the ChatCompletionAgent constructor.
Additionally, the plugin is supplied via the constructor.
"""
# Define a sample plugin for the sample
class MenuPlugin:
"""A sample Menu Plugin used for the concept sample."""
@kernel_function(description="Provides a list of specials from the menu.")
def get_specials(self) -> Annotated[str, "Returns the specials from the menu."]:
return """
Special Soup: Clam Chowder
Special Salad: Cobb Salad
Special Drink: Chai Tea
"""
@kernel_function(description="Provides the price of the requested menu item.")
def get_item_price(
self, menu_item: Annotated[str, "The name of the menu item."]
) -> Annotated[str, "Returns the price of the menu item."]:
return "$9.99"
# Simulate a conversation with the agent
USER_INPUTS = [
"Hello",
"What is the special soup?",
"What does that cost?",
"Thank you",
]
async def main():
# 1. Create the agent
agent = ChatCompletionAgent(
service=AzureChatCompletion(credential=AzureCliCredential()),
name="Host",
instructions="Answer questions about the menu.",
plugins=[MenuPlugin()],
)
# 2. Create a thread to hold the conversation
# If no thread is provided, a new thread will be
# created and returned with the initial response
thread: ChatHistoryAgentThread = None
for user_input in USER_INPUTS:
print(f"# User: {user_input}")
# 4. Invoke the agent for a response
response = await agent.get_response(messages=user_input, thread=thread)
print(f"# {response.name}: {response} ")
thread = response.thread
# 4. Cleanup: Clear the thread
await thread.delete() if thread else None
"""
Sample output:
# User: Hello
# Host: Hello! How can I assist you today?
# User: What is the special soup?
# Host: The special soup is Clam Chowder.
# User: What does that cost?
# Host: The special soup, Clam Chowder, costs $9.99.
# User: Thank you
# Host: You're welcome! If you have any more questions, feel free to ask. Enjoy your day!
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,102 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from typing import Annotated
from azure.identity import AzureCliCredential
from semantic_kernel import Kernel
from semantic_kernel.agents import ChatCompletionAgent, ChatHistoryAgentThread
from semantic_kernel.connectors.ai import FunctionChoiceBehavior
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
from semantic_kernel.functions import KernelArguments, kernel_function
"""
The following sample demonstrates how to create a chat completion agent that
answers questions about a sample menu using a Semantic Kernel Plugin. The Chat
Completion Service is first added to the kernel, and the kernel is passed in to the
ChatCompletionAgent constructor. Additionally, the plugin is supplied via the kernel.
To enable auto-function calling, the prompt execution settings are retrieved from the kernel
using the specified `service_id`. The function choice behavior is set to `Auto` to allow the
agent to automatically execute the plugin's functions when needed.
"""
# Define a sample plugin for the sample
class MenuPlugin:
"""A sample Menu Plugin used for the concept sample."""
@kernel_function(description="Provides a list of specials from the menu.")
def get_specials(self) -> Annotated[str, "Returns the specials from the menu."]:
return """
Special Soup: Clam Chowder
Special Salad: Cobb Salad
Special Drink: Chai Tea
"""
@kernel_function(description="Provides the price of the requested menu item.")
def get_item_price(
self, menu_item: Annotated[str, "The name of the menu item."]
) -> Annotated[str, "Returns the price of the menu item."]:
return "$9.99"
# Simulate a conversation with the agent
USER_INPUTS = [
"Hello",
"What is the special soup?",
"What does that cost?",
"Thank you",
]
async def main():
# 1. Create the instance of the Kernel to register the plugin and service
service_id = "agent"
kernel = Kernel()
kernel.add_plugin(MenuPlugin(), plugin_name="menu")
kernel.add_service(AzureChatCompletion(service_id=service_id, credential=AzureCliCredential()))
# 2. Configure the function choice behavior to auto invoke kernel functions
# so that the agent can automatically execute the menu plugin functions when needed
settings = kernel.get_prompt_execution_settings_from_service_id(service_id=service_id)
settings.function_choice_behavior = FunctionChoiceBehavior.Auto()
# 3. Create the agent
agent = ChatCompletionAgent(
kernel=kernel,
name="Host",
instructions="Answer questions about the menu.",
arguments=KernelArguments(settings=settings),
)
# 4. Create a thread to hold the conversation
# If no thread is provided, a new thread will be
# created and returned with the initial response
thread: ChatHistoryAgentThread = None
for user_input in USER_INPUTS:
print(f"# User: {user_input}")
# 5. Invoke the agent for a response
async for response in agent.invoke(messages=user_input, thread=thread):
print(f"# {response.name}: {response}")
thread = response.thread
# 6. Cleanup: Clear the thread
await thread.delete() if thread else None
"""
Sample output:
# User: Hello
# Host: Hello! How can I assist you today?
# User: What is the special soup?
# Host: The special soup is Clam Chowder.
# User: What does that cost?
# Host: The special soup, Clam Chowder, costs $9.99.
# User: Thank you
# Host: You're welcome! If you have any more questions, feel free to ask. Enjoy your day!
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,110 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from azure.identity import AzureCliCredential
from semantic_kernel import Kernel
from semantic_kernel.agents import AgentGroupChat, ChatCompletionAgent
from semantic_kernel.agents.strategies import TerminationStrategy
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
"""
The following sample demonstrates how to create a simple, agent group chat that
utilizes An Art Director Chat Completion Agent along with a Copy Writer Chat
Completion Agent to complete a task.
Note: This sample use the `AgentGroupChat` feature of Semantic Kernel, which is
no longer maintained. For a replacement, consider using the `GroupChatOrchestration`.
Read more about the `GroupChatOrchestration` here:
https://learn.microsoft.com/semantic-kernel/frameworks/agent/agent-orchestration/group-chat?pivots=programming-language-python
Here is a migration guide from `AgentGroupChat` to `GroupChatOrchestration`:
https://learn.microsoft.com/semantic-kernel/support/migration/group-chat-orchestration-migration-guide?pivots=programming-language-python
"""
def _create_kernel_with_chat_completion(service_id: str) -> Kernel:
kernel = Kernel()
kernel.add_service(AzureChatCompletion(service_id=service_id, credential=AzureCliCredential()))
return kernel
class ApprovalTerminationStrategy(TerminationStrategy):
"""A strategy for determining when an agent should terminate."""
async def should_agent_terminate(self, agent, history):
"""Check if the agent should terminate."""
last_message = history[-1].content.lower()
return "approved" in last_message and "not approved" not in last_message
REVIEWER_NAME = "ArtDirector"
REVIEWER_INSTRUCTIONS = """
You are an art director who has opinions about copywriting born of a love for David Ogilvy.
The goal is to determine if the given copy is acceptable to print.
If so, state that it is approved.
If not, provide insight on how to refine suggested copy without example.
"""
COPYWRITER_NAME = "CopyWriter"
COPYWRITER_INSTRUCTIONS = """
You are a copywriter with ten years of experience and are known for brevity and a dry humor.
The goal is to refine and decide on the single best copy as an expert in the field.
Only provide a single proposal per response.
You're laser focused on the goal at hand.
Don't waste time with chit chat.
Consider suggestions when refining an idea.
"""
TASK = "a slogan for a new line of electric cars."
async def main():
# 1. Create the reviewer agent based on the chat completion service
agent_reviewer = ChatCompletionAgent(
kernel=_create_kernel_with_chat_completion("artdirector"),
name=REVIEWER_NAME,
instructions=REVIEWER_INSTRUCTIONS,
)
# 2. Create the copywriter agent based on the chat completion service
agent_writer = ChatCompletionAgent(
kernel=_create_kernel_with_chat_completion("copywriter"),
name=COPYWRITER_NAME,
instructions=COPYWRITER_INSTRUCTIONS,
)
# 3. Place the agents in a group chat with a custom termination strategy
group_chat = AgentGroupChat(
agents=[
agent_writer,
agent_reviewer,
],
termination_strategy=ApprovalTerminationStrategy(
agents=[agent_reviewer],
maximum_iterations=10,
),
)
# 4. Add the task as a message to the group chat
await group_chat.add_chat_message(message=TASK)
print(f"# User: {TASK}")
# 5. Invoke the chat
async for content in group_chat.invoke():
print(f"# {content.name}: {content.content}")
"""
Sample output:
# User: a slogan for a new line of electric cars.
# CopyWriter: "Drive the Future: Shockingly Efficient."
# ArtDirector: This slogan has potential but could benefit from refinement to create a stronger ...
# CopyWriter: "Electrify Your Drive."
# ArtDirector: Approved. This slogan is concise, memorable, and effectively communicates the ...
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,145 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from azure.identity import AzureCliCredential
from semantic_kernel import Kernel
from semantic_kernel.agents import AgentGroupChat, ChatCompletionAgent
from semantic_kernel.agents.strategies import KernelFunctionSelectionStrategy, KernelFunctionTerminationStrategy
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
from semantic_kernel.functions import KernelFunctionFromPrompt
"""
The following sample demonstrates how to create a simple, agent group chat that utilizes
An Art Director Chat Completion Agent along with a Copy Writer Chat Completion Agent to
complete a task. The sample also shows how to specify a Kernel Function termination and
selection strategy to determine when to end the chat or how to select the next agent to
take a turn in the conversation.
Note: This sample use the `AgentGroupChat` feature of Semantic Kernel, which is
no longer maintained. For a replacement, consider using the `GroupChatOrchestration`.
Read more about the `GroupChatOrchestration` here:
https://learn.microsoft.com/semantic-kernel/frameworks/agent/agent-orchestration/group-chat?pivots=programming-language-python
Here is a migration guide from `AgentGroupChat` to `GroupChatOrchestration`:
https://learn.microsoft.com/semantic-kernel/support/migration/group-chat-orchestration-migration-guide?pivots=programming-language-python
"""
def _create_kernel_with_chat_completion(service_id: str) -> Kernel:
kernel = Kernel()
kernel.add_service(AzureChatCompletion(service_id=service_id, credential=AzureCliCredential()))
return kernel
REVIEWER_NAME = "ArtDirector"
REVIEWER_INSTRUCTIONS = """
You are an art director who has opinions about copywriting born of a love for David Ogilvy.
The goal is to determine if the given copy is acceptable to print.
If so, state that it is approved.
If not, provide insight on how to refine suggested copy without example.
"""
COPYWRITER_NAME = "CopyWriter"
COPYWRITER_INSTRUCTIONS = """
You are a copywriter with ten years of experience and are known for brevity and a dry humor.
The goal is to refine and decide on the single best copy as an expert in the field.
Only provide a single proposal per response.
You're laser focused on the goal at hand.
Don't waste time with chit chat.
Consider suggestions when refining an idea.
"""
TASK = "a slogan for a new line of electric cars."
async def main():
# 1. Create the reviewer agent based on the chat completion service
agent_reviewer = ChatCompletionAgent(
kernel=_create_kernel_with_chat_completion("artdirector"),
name=REVIEWER_NAME,
instructions=REVIEWER_INSTRUCTIONS,
)
# 2. Create the copywriter agent based on the chat completion service
agent_writer = ChatCompletionAgent(
kernel=_create_kernel_with_chat_completion("copywriter"),
name=COPYWRITER_NAME,
instructions=COPYWRITER_INSTRUCTIONS,
)
# 3. Create a Kernel Function to determine if the copy has been approved
termination_function = KernelFunctionFromPrompt(
function_name="termination",
prompt="""
Determine if the copy has been approved. If so, respond with a single word: yes
History:
{{$history}}
""",
)
# 4. Create a Kernel Function to determine which agent should take the next turn
selection_function = KernelFunctionFromPrompt(
function_name="selection",
prompt=f"""
Determine which participant takes the next turn in a conversation based on the the most recent participant.
State only the name of the participant to take the next turn.
No participant should take more than one turn in a row.
Choose only from these participants:
- {REVIEWER_NAME}
- {COPYWRITER_NAME}
Always follow these rules when selecting the next participant:
- After user input, it is {COPYWRITER_NAME}'s turn.
- After {COPYWRITER_NAME} replies, it is {REVIEWER_NAME}'s turn.
- After {REVIEWER_NAME} provides feedback, it is {COPYWRITER_NAME}'s turn.
History:
{{{{$history}}}}
""",
)
# 5. Place the agents in a group chat with the custom termination and selection strategies
chat = AgentGroupChat(
agents=[agent_writer, agent_reviewer],
termination_strategy=KernelFunctionTerminationStrategy(
agents=[agent_reviewer],
function=termination_function,
kernel=_create_kernel_with_chat_completion("termination"),
result_parser=lambda result: str(result.value[0]).lower() == "yes",
history_variable_name="history",
maximum_iterations=10,
),
selection_strategy=KernelFunctionSelectionStrategy(
function=selection_function,
kernel=_create_kernel_with_chat_completion("selection"),
result_parser=lambda result: str(result.value[0]) if result.value is not None else COPYWRITER_NAME,
agent_variable_name="agents",
history_variable_name="history",
),
)
# 6. Add the task as a message to the group chat
await chat.add_chat_message(message=TASK)
print(f"# User: {TASK}")
# 7. Invoke the chat
async for content in chat.invoke():
print(f"# {content.name}: {content.content}")
"""
Sample Output:
# User: a slogan for a new line of electric cars.
# CopyWriter: "Electrify your drive. Spare the gas, not the thrill."
# ArtDirector: This slogan captures the essence of electric cars but could use refinement to ...
# CopyWriter: "Go electric. Enjoy the thrill. Skip the gas."
# ArtDirector: Approved. This slogan is clear, concise, and effectively communicates the ...
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,111 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from pydantic import BaseModel, ValidationError
from semantic_kernel import Kernel
from semantic_kernel.agents import AgentGroupChat, ChatCompletionAgent
from semantic_kernel.agents.strategies import TerminationStrategy
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion, OpenAIChatPromptExecutionSettings
from semantic_kernel.functions import KernelArguments
"""
The following sample demonstrates how to configure an Agent Group Chat, and invoke an
agent with only a single turn.A custom termination strategy is provided where the model
is to rate the user input on creativity and expressiveness and end the chat when a score
of 70 or higher is provided.
Note: This sample use the `AgentGroupChat` feature of Semantic Kernel, which is
no longer maintained. For a replacement, consider using the `GroupChatOrchestration`.
Read more about the `GroupChatOrchestration` here:
https://learn.microsoft.com/semantic-kernel/frameworks/agent/agent-orchestration/group-chat?pivots=programming-language-python
Here is a migration guide from `AgentGroupChat` to `GroupChatOrchestration`:
https://learn.microsoft.com/semantic-kernel/support/migration/group-chat-orchestration-migration-guide?pivots=programming-language-python
"""
def _create_kernel_with_chat_completion(service_id: str) -> Kernel:
kernel = Kernel()
kernel.add_service(OpenAIChatCompletion(service_id=service_id))
return kernel
class InputScore(BaseModel):
"""A model for the input score."""
score: int
notes: str
class ThresholdTerminationStrategy(TerminationStrategy):
"""A strategy for determining when an agent should terminate."""
threshold: int = 70
async def should_agent_terminate(self, agent, history):
"""Check if the agent should terminate."""
try:
result = InputScore.model_validate_json(history[-1].content or "")
return result.score >= self.threshold
except ValidationError:
return False
INSTRUCTION = """
Think step-by-step and rate the user input on creativity and expressiveness from 1-100 with some notes on improvements.
"""
# Simulate a conversation with the agent
USER_INPUTS = {
"The sunset is very colorful.",
"The sunset is setting over the mountains.",
"The sunset is setting over the mountains and fills the sky with a deep red flame, setting the clouds ablaze.",
}
async def main():
# 1. Create the instance of the Kernel to register a service
service_id = "agent"
kernel = _create_kernel_with_chat_completion(service_id)
# 2. Configure the prompt execution settings to return the score in the desired format
settings = kernel.get_prompt_execution_settings_from_service_id(service_id)
assert isinstance(settings, OpenAIChatPromptExecutionSettings) # nosec
settings.response_format = InputScore
# 3. Create the agent
agent = ChatCompletionAgent(
kernel=kernel,
name="Tutor",
instructions=INSTRUCTION,
arguments=KernelArguments(settings),
)
# 4. Create the group chat with the custom termination strategy
group_chat = AgentGroupChat(termination_strategy=ThresholdTerminationStrategy(maximum_iterations=10))
for user_input in USER_INPUTS:
# 5. Add the user input to the chat history
await group_chat.add_chat_message(message=user_input)
print(f"# User: {user_input}")
# 6. Invoke the chat with the agent for a response
async for content in group_chat.invoke_single_turn(agent):
print(f"# {content.name}: {content.content}")
"""
Sample output:
# User: The sunset is very colorful.
# Tutor: {"score":45,"notes":"The sentence 'The sunset is very colorful' is simple and direct. While it ..."}
# User: The sunset is setting over the mountains.
# Tutor: {"score":50,"notes":"This sentence provides a basic scene of a sunset over mountains, which ..."}
# User: The sunset is setting over the mountains and fills the sky with a deep red flame, setting the clouds ablaze.
# Tutor: {"score":75,"notes":"This sentence demonstrates improved creativity and expressiveness by ..."}
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,123 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import logging
from azure.identity import AzureCliCredential
from semantic_kernel import Kernel
from semantic_kernel.agents import AgentGroupChat, ChatCompletionAgent
from semantic_kernel.agents.strategies import TerminationStrategy
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
"""
The following sample demonstrates how to create a simple, agent group chat that
utilizes An Art Director Chat Completion Agent along with a Copy Writer Chat
Completion Agent to complete a task. The main point of this sample is to note
how to enable logging to view all interactions between the agents and the model.
Note: This sample use the `AgentGroupChat` feature of Semantic Kernel, which is
no longer maintained. For a replacement, consider using the `GroupChatOrchestration`.
Read more about the `GroupChatOrchestration` here:
https://learn.microsoft.com/semantic-kernel/frameworks/agent/agent-orchestration/group-chat?pivots=programming-language-python
Here is a migration guide from `AgentGroupChat` to `GroupChatOrchestration`:
https://learn.microsoft.com/semantic-kernel/support/migration/group-chat-orchestration-migration-guide?pivots=programming-language-python
"""
# 0. Enable logging
# NOTE: This is all that is required to enable logging.
# Set the desired level to INFO, DEBUG, etc.
logging.basicConfig(level=logging.INFO)
class ApprovalTerminationStrategy(TerminationStrategy):
"""A strategy for determining when an agent should terminate."""
async def should_agent_terminate(self, agent, history):
"""Check if the agent should terminate."""
return "approved" in history[-1].content.lower()
def _create_kernel_with_chat_completion(service_id: str) -> Kernel:
kernel = Kernel()
kernel.add_service(AzureChatCompletion(service_id=service_id, credential=AzureCliCredential()))
return kernel
REVIEWER_NAME = "ArtDirector"
REVIEWER_INSTRUCTIONS = """
You are an art director who has opinions about copywriting born of a love for David Ogilvy.
The goal is to determine if the given copy is acceptable to print.
If so, state that it is approved.
If not, provide insight on how to refine suggested copy without example.
"""
COPYWRITER_NAME = "CopyWriter"
COPYWRITER_INSTRUCTIONS = """
You are a copywriter with ten years of experience and are known for brevity and a dry humor.
The goal is to refine and decide on the single best copy as an expert in the field.
Only provide a single proposal per response.
You're laser focused on the goal at hand.
Don't waste time with chit chat.
Consider suggestions when refining an idea.
"""
TASK = "a slogan for a new line of electric cars."
async def main():
# 1. Create the reviewer agent based on the chat completion service
agent_reviewer = ChatCompletionAgent(
kernel=_create_kernel_with_chat_completion("artdirector"),
name=REVIEWER_NAME,
instructions=REVIEWER_INSTRUCTIONS,
)
# 2. Create the copywriter agent based on the chat completion service
agent_writer = ChatCompletionAgent(
kernel=_create_kernel_with_chat_completion("copywriter"),
name=COPYWRITER_NAME,
instructions=COPYWRITER_INSTRUCTIONS,
)
# 3. Place the agents in a group chat with a custom termination strategy
group_chat = AgentGroupChat(
agents=[agent_writer, agent_reviewer],
termination_strategy=ApprovalTerminationStrategy(agents=[agent_reviewer], maximum_iterations=10),
)
# 4. Add the task as a message to the group chat
await group_chat.add_chat_message(message=TASK)
print(f"# User: {TASK}")
# 5. Invoke the chat
async for content in group_chat.invoke():
print(f"# {content.name}: {content.content}")
"""
Sample output:
INFO:semantic_kernel.agents.group_chat.agent_chat:Adding `1` agent chat messages
# User: a slogan for a new line of electric cars.
INFO:semantic_kernel.agents.strategies.selection.sequential_selection_strategy:Selected agent at index 0 (ID: ...
INFO:semantic_kernel.agents.group_chat.agent_chat:Invoking agent CopyWriter
INFO:semantic_kernel.utils.telemetry.model_diagnostics.decorators:{"role": "system", "content": "\nYou are a ...
INFO:semantic_kernel.utils.telemetry.model_diagnostics.decorators:{"role": "user", "content": "a slogan for ...
INFO:semantic_kernel.connectors.ai.open_ai.services.open_ai_handler:OpenAI usage: CompletionUsage(completion_...
INFO:semantic_kernel.utils.telemetry.model_diagnostics.decorators:{"message": {"role": "assistant", "content": ...
INFO:semantic_kernel.agents.chat_completion.chat_completion_agent:[ChatCompletionAgent] Invoked AzureChatCompl...
INFO:semantic_kernel.agents.strategies.termination.termination_strategy:Evaluating termination criteria for ...
INFO:semantic_kernel.agents.strategies.termination.termination_strategy:Agent 598d827e-ce5e-44fa-879b-42793bb...
# CopyWriter: "Drive Change. Literally."
INFO:semantic_kernel.agents.strategies.selection.sequential_selection_strategy:Selected agent at index 1 (ID: ...
INFO:semantic_kernel.agents.group_chat.agent_chat:Invoking agent ArtDirector
INFO:semantic_kernel.utils.telemetry.model_diagnostics.decorators:{"role": "system", "content": "\nYou are an ...
INFO:semantic_kernel.utils.telemetry.model_diagnostics.decorators:{"role": "user", "content": "a slogan for a ...
INFO:semantic_kernel.utils.telemetry.model_diagnostics.decorators:{"role": "assistant", "content": "\"Drive ...
...
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,110 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import json
from azure.identity import AzureCliCredential
from pydantic import BaseModel
from semantic_kernel.agents import ChatCompletionAgent, ChatHistoryAgentThread
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion, AzureChatPromptExecutionSettings
from semantic_kernel.functions.kernel_arguments import KernelArguments
"""
The following sample demonstrates how to create a chat completion agent that
answers user questions using structured outputs. The `Reasoning` model is defined
on the prompt execution settings. The settings are then passed into the agent
via the `KernelArguments` object.
The interaction with the agent is via the `get_response` method, which sends a
user input to the agent and receives a response from the agent. The conversation
history needs to be maintained by the caller in the chat history object.
"""
# Define the BaseModel we will use for structured outputs
class Step(BaseModel):
explanation: str
output: str
class Reasoning(BaseModel):
steps: list[Step]
final_answer: str
# Simulate a conversation with the agent
USER_INPUT = "how can I solve 8x + 7y = -23, and 4x=12?"
async def main():
# 1. Create the prompt settings
settings = AzureChatPromptExecutionSettings()
settings.response_format = Reasoning
# 2. Create the agent by specifying the service
agent = ChatCompletionAgent(
service=AzureChatCompletion(credential=AzureCliCredential()),
name="Assistant",
instructions="Answer the user's questions.",
arguments=KernelArguments(settings=settings),
)
# 3. Create a thread to hold the conversation
# If no thread is provided, a new thread will be
# created and returned with the initial response
thread: ChatHistoryAgentThread = None
print(f"# User: {USER_INPUT}")
# 4. Invoke the agent for a response
response = await agent.get_response(messages=USER_INPUT, thread=thread)
# 5. Validate the response and print the structured output
reasoned_result = Reasoning.model_validate(json.loads(response.message.content))
print(f"# {response.name}:\n\n{reasoned_result.model_dump_json(indent=4)}")
# 6. Cleanup: Clear the thread
await thread.delete() if thread else None
"""
Sample output:
# User: how can I solve 8x + 7y = -23, and 4x=12?
# Assistant:
{
"steps": [
{
"explanation": "The second equation 4x = 12 can be solved for x by dividing both sides by 4.",
"output": "x = 3."
},
{
"explanation": "Substitute x = 3 from the second equation into the first equation 8x + 7y = -23.",
"output": "8(3) + 7y = -23."
},
{
"explanation": "Calculate 8 times 3 to simplify the equation.",
"output": "24 + 7y = -23."
},
{
"explanation": "Subtract 24 from both sides to isolate the term with y.",
"output": "7y = -23 - 24."
},
{
"explanation": "Perform the subtraction.",
"output": "7y = -47."
},
{
"explanation": "Divide both sides by 7 to solve for y.",
"output": "y = -47 / 7."
},
{
"explanation": "Simplify the division to get the value of y.",
"output": "y = -6.714285714285714 (approximately -6.71)."
}
],
"final_answer": "The solution to the system of equations is x = 3 and y = -6.71."
}
"""
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,126 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from typing import Annotated
from azure.identity import AzureCliCredential
from pydantic import BaseModel
from semantic_kernel import Kernel
from semantic_kernel.agents import AgentRegistry, ChatHistoryAgentThread
from semantic_kernel.agents.chat_completion.chat_completion_agent import ChatCompletionAgent
from semantic_kernel.connectors.ai.open_ai import (
AzureChatCompletion,
AzureChatPromptExecutionSettings,
)
from semantic_kernel.functions import KernelArguments, kernel_function
"""
The following sample demonstrates how to create a chat completion agent using a
declarative approach. The Chat Completion Agent is created from a YAML spec,
with a specific service and plugins. The agent is then used to answer user questions.
This sample also demonstrates how to properly pass execution settings (like response format)
when using AgentRegistry.create_from_yaml().
"""
# Example structure for structured output
class StructuredResult(BaseModel):
"""Example structure for demonstrating response format."""
response: str
category: str
# 1. Define a Sample Plugin
class MenuPlugin:
"""A sample Menu Plugin used for the concept sample."""
@kernel_function(description="Provides a list of specials from the menu.")
def get_specials(self) -> Annotated[str, "Returns the specials from the menu."]:
return """
Special Soup: Clam Chowder
Special Salad: Cobb Salad
Special Drink: Chai Tea
"""
@kernel_function(description="Provides the price of the requested menu item.")
def get_item_price(
self, menu_item: Annotated[str, "The name of the menu item."]
) -> Annotated[str, "Returns the price of the menu item."]:
return "$9.99"
# 2. Define the YAML string
AGENT_YAML = """
type: chat_completion_agent
name: Assistant
description: A helpful assistant.
instructions: Answer the user's questions using the menu functions.
tools:
- id: MenuPlugin.get_specials
type: function
- id: MenuPlugin.get_item_price
type: function
model:
options:
temperature: 0.7
"""
# 3. Define your simulated conversation
USER_INPUTS = [
"Hello",
"What is the special soup?",
"What does that cost?",
"Thank you",
]
async def main():
# 4. Create a Kernel and add the plugin
# For declarative agents, the kernel is required to resolve the plugin
kernel = Kernel()
kernel.add_plugin(MenuPlugin(), plugin_name="MenuPlugin")
# 5. Create execution settings with structured output
execution_settings = AzureChatPromptExecutionSettings()
execution_settings.response_format = StructuredResult
# 6. Create KernelArguments with the execution settings
arguments = KernelArguments(settings=execution_settings)
# 7. Create the agent from YAML + inject the AI service
agent: ChatCompletionAgent = await AgentRegistry.create_from_yaml(
AGENT_YAML, kernel=kernel, service=AzureChatCompletion(credential=AzureCliCredential()), arguments=arguments
)
# 8. Create a thread to hold the conversation
thread: ChatHistoryAgentThread | None = None
for user_input in USER_INPUTS:
print(f"# User: {user_input}")
# 9. Invoke the agent for a response
response = await agent.get_response(messages=user_input, thread=thread)
print(f"# {response.name}: {response}")
thread = response.thread
# 10. Cleanup the thread
await thread.delete() if thread else None
"""
# Sample output:
# User: Hello
# Assistant: {"response":"Hello! How can I help you today? If you have any questions about the menu, feel free to ask!","category":"Greeting"}
# User: What is the special soup?
# Assistant: {"response":"Today's special soup is Clam Chowder. Would you like to know more about it or see other specials?","category":"Menu Specials"}
# User: What does that cost?
# Assistant: {"response":"The Clam Chowder special soup costs $9.99.","category":"Menu Pricing"}
# User: Thank you
# Assistant: {"response":"You're welcome! If you have any more questions or need assistance with the menu, just let me know. Enjoy your meal!","category":"Polite Closing"}
""" # noqa: E501
if __name__ == "__main__":
asyncio.run(main())
@@ -0,0 +1,95 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
import os
from azure.identity import AzureCliCredential
from semantic_kernel.agents import ChatCompletionAgent
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
from semantic_kernel.contents import ChatMessageContent, FunctionCallContent, FunctionResultContent
from semantic_kernel.core_plugins import SessionsPythonTool
"""
The following sample demonstrates how to create a chat completion agent with
code interpreter capabilities using the Azure Container Apps session pool service.
"""
async def handle_intermediate_steps(message: ChatMessageContent) -> None:
for item in message.items or []:
if isinstance(item, FunctionResultContent):
print(f"# Function Result:> {item.result}")
elif isinstance(item, FunctionCallContent):
print(f"# Function Call:> {item.name} with arguments: {item.arguments}")
else:
print(f"# {message.name}: {message} ")
async def main():
credential = AzureCliCredential()
# Define the resources directory for file uploads
resources_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "resources")
# 1. Create the python code interpreter tool using the SessionsPythonTool
# allowed_upload_directories restricts which local directories can be accessed for uploads
python_code_interpreter = SessionsPythonTool(
credential=credential,
allowed_upload_directories=[resources_dir],
)
# 2. Create the agent
agent = ChatCompletionAgent(
service=AzureChatCompletion(credential=credential),
name="Host",
instructions="Answer questions about the menu.",
plugins=[python_code_interpreter],
)
# 3. Upload a CSV file to the session
csv_file_path = os.path.join(resources_dir, "sales.csv")
file_metadata = await python_code_interpreter.upload_file(local_file_path=csv_file_path)
# 4. Invoke the agent for a response to a task
TASK = (
"What's the total sum of all sales for all segments using Python? "
f"Use the uploaded file {file_metadata.full_path} for reference."
)
print(f"# User: '{TASK}'")
async for response in agent.invoke(
messages=TASK,
on_intermediate_message=handle_intermediate_steps,
):
print(f"# {response.name}: {response} ")
"""
Sample output:
# User: 'What's the total sum of all sales for all segments using Python?
Use the uploaded file /mnt/data/sales.csv for reference.'
# Function Call:> SessionsPythonTool-execute_code with arguments: {
"code": "
import pandas as pd
# Load the sales data
file_path = '/mnt/data/sales.csv'
sales_data = pd.read_csv(file_path)
# Calculate the total sum of sales
# Assuming there's a column named 'Sales' which contains the sales amounts
total_sales = sales_data['Sales'].sum()
total_sales"
}
# Function Result:> Status:
Success
Result:
118726350.28999999
Stdout:
Stderr:
# Host: The total sum of all sales for all segments is approximately $118,726,350.29.
"""
if __name__ == "__main__":
asyncio.run(main())