Skip to content

Commit 141183d

Browse files
moonbox3glorious-beard
authored andcommitted
Python: Add AzureAIAgent Structured Outputs sample (microsoft#11281)
### Motivation and Context Add AzureAIAgent Structured Outputs sample <!-- Thank you for your contribution to the semantic-kernel repo! Please help reviewers and future users, providing the following information: 1. Why is this change required? 2. What problem does it solve? 3. What scenario does it contribute to? 4. If it fixes an open issue, please link to the issue here. --> ### Description Add AzureAIAgent Structured Outputs sample <!-- Describe your changes, the overall approach, the underlying design. These notes will help understanding how your code works. Thanks! --> ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [X] The code builds clean without any errors or warnings - [X] The PR follows the [SK Contribution Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [X] All unit tests pass, and I have added new tests where possible - [X] I didn't break anyone 😄
1 parent ef83836 commit 141183d

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

python/samples/concepts/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
- [Azure AI Agent Prompt Templating](./agents/azure_ai_agent/azure_ai_agent_prompt_templating.py)
1313
- [Azure AI Agent Chat History Callback](./agents/azure_ai_agent/azure_ai_agent_streaming_chat_history_callback.py)
1414
- [Azure AI Agent Streaming](./agents/azure_ai_agent/azure_ai_agent_streaming.py)
15+
- [Azure AI Agent Structured Outputs](./agents/azure_ai_agent/azure_ai_agent_structured_outputs.py)
1516

1617
#### [Bedrock Agent](../../semantic_kernel/agents/bedrock/bedrock_agent.py)
1718

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# Copyright (c) Microsoft. All rights reserved.
2+
3+
import asyncio
4+
from enum import Enum
5+
6+
from azure.ai.projects.models import (
7+
ResponseFormatJsonSchema,
8+
ResponseFormatJsonSchemaType,
9+
)
10+
from azure.identity.aio import DefaultAzureCredential
11+
from pydantic import BaseModel
12+
13+
from semantic_kernel.agents import (
14+
AzureAIAgent,
15+
AzureAIAgentSettings,
16+
)
17+
18+
"""
19+
The following sample demonstrates how to create an Azure AI Agent
20+
and leverage the agent's ability to return structured outputs,
21+
based on a user-defined Pydantic model.
22+
"""
23+
24+
25+
# Define a Pydantic model that represents the structured output from the agent
26+
class Planets(str, Enum):
27+
Earth = "Earth"
28+
Mars = "Mars"
29+
Jupyter = "Jupyter"
30+
31+
32+
class Planet(BaseModel):
33+
planet: Planets
34+
mass: float
35+
36+
37+
async def main():
38+
ai_agent_settings = AzureAIAgentSettings.create()
39+
async with (
40+
DefaultAzureCredential() as creds,
41+
AzureAIAgent.create_client(
42+
credential=creds,
43+
conn_str=ai_agent_settings.project_connection_string.get_secret_value(),
44+
) as client,
45+
):
46+
# Create the agent definition
47+
agent_definition = await client.agents.create_agent(
48+
model=ai_agent_settings.model_deployment_name,
49+
name="Assistant",
50+
instructions="Extract the information about planets.",
51+
response_format=ResponseFormatJsonSchemaType(
52+
json_schema=ResponseFormatJsonSchema(
53+
name="planet_mass",
54+
description="Extract planet mass.",
55+
schema=Planet.model_json_schema(),
56+
)
57+
),
58+
)
59+
60+
# Create the AzureAI Agent
61+
agent = AzureAIAgent(
62+
client=client,
63+
definition=agent_definition,
64+
)
65+
66+
# Create a new thread for use with the assistant
67+
# If no thread is provided, a new thread will be
68+
# created and returned with the initial response
69+
thread = None
70+
71+
user_inputs = ["The mass of the Mars is 6.4171E23 kg; the mass of the Earth is 5.972168E24 kg;"]
72+
73+
try:
74+
for user_input in user_inputs:
75+
print(f"# User: '{user_input}'")
76+
async for response in agent.invoke(messages=user_input, thread=thread):
77+
# The response returned is a Pydantic Model, so we can validate it using the
78+
# model_validate_json method
79+
response_model = Planet.model_validate_json(str(response.content))
80+
print(f"# {response.role}: {response_model}")
81+
thread = response.thread
82+
finally:
83+
await thread.delete() if thread else None
84+
await client.agents.delete_agent(agent_definition.id)
85+
86+
"""
87+
Sample Output:
88+
89+
# User: 'The mass of the Mars is 6.4171E23 kg; the mass of the Earth is 5.972168E24 kg;'
90+
# AuthorRole.ASSISTANT: planet=<Planets.Earth: 'Earth'> mass=5.972168e+24
91+
# AuthorRole.ASSISTANT: planet=<Planets.Mars: 'Mars'> mass=6.4171e+23
92+
"""
93+
94+
95+
if __name__ == "__main__":
96+
asyncio.run(main())

0 commit comments

Comments
 (0)