Skip to content

Commit 3dc804e

Browse files
authored
Updates & fixes to Agents samples that set response_format (#42872)
1 parent 195c3ab commit 3dc804e

5 files changed

+124
-83
lines changed

sdk/ai/azure-ai-agents/samples/agents_async/sample_agents_json_schema_async.py renamed to sdk/ai/azure-ai-agents/samples/agents_async/sample_agents_json_schema_response_format_using_pydantic_async.py

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,23 @@
55

66
"""
77
DESCRIPTION:
8-
This sample demonstrates how to use agents with JSON schema output format.
8+
This sample demonstrates how to use agents with JSON schema output format, using
9+
an asynchronous client. It uses the Pydantic package to define the output JSON
10+
schema from Python classes.
911
1012
USAGE:
11-
python sample_agents_json_schema_async.py
13+
python sample_agents_json_schema_response_format_using_pydantic_async.py
1214
1315
Before running the sample:
1416
15-
pip install azure-ai-projects azure-ai-agents azure-identity pydantic
17+
pip install azure-ai-projects azure-ai-agents azure-identity aiohttp pydantic
1618
1719
Set these environment variables with your own values:
1820
1) PROJECT_ENDPOINT - The Azure AI Project endpoint, as found in the Overview
1921
page of your Azure AI Foundry portal.
2022
2) MODEL_DEPLOYMENT_NAME - The deployment name of the AI model, as found under the "Name" column in
2123
the "Models + endpoints" tab in your Azure AI Foundry project.
2224
"""
23-
2425
import asyncio
2526
import os
2627

@@ -30,7 +31,6 @@
3031
from azure.identity.aio import DefaultAzureCredential
3132
from azure.ai.agents.models import (
3233
ListSortOrder,
33-
MessageTextContent,
3434
MessageRole,
3535
ResponseFormatJsonSchema,
3636
ResponseFormatJsonSchemaType,
@@ -39,17 +39,26 @@
3939

4040

4141
# Create the pydantic model to represent the planet names and there masses.
42-
class Planets(str, Enum):
42+
class PlanetName(str, Enum):
43+
Mercury = "Mercury"
44+
Venus = "Venus"
4345
Earth = "Earth"
4446
Mars = "Mars"
45-
Jupyter = "Jupyter"
47+
Jupiter = "Jupiter"
48+
Saturn = "Saturn"
49+
Uranus = "Uranus"
50+
Neptune = "Neptune"
4651

4752

4853
class Planet(BaseModel):
49-
planet: Planets
54+
name: PlanetName
5055
mass: float
5156

5257

58+
class Planets(BaseModel):
59+
planets: list[Planet]
60+
61+
5362
async def main():
5463
project_client = AIProjectClient(
5564
endpoint=os.environ["PROJECT_ENDPOINT"],
@@ -62,12 +71,12 @@ async def main():
6271
agent = await agents_client.create_agent(
6372
model=os.environ["MODEL_DEPLOYMENT_NAME"],
6473
name="my-agent",
65-
instructions="Extract the information about planets.",
74+
instructions="You are helpful agent. Your response is JSON formatted.",
6675
response_format=ResponseFormatJsonSchemaType(
6776
json_schema=ResponseFormatJsonSchema(
6877
name="planet_mass",
69-
description="Extract planet mass.",
70-
schema=Planet.model_json_schema(),
78+
description="Masses of Solar System planets.",
79+
schema=Planets.model_json_schema(),
7180
)
7281
),
7382
)
@@ -79,7 +88,7 @@ async def main():
7988
message = await agents_client.messages.create(
8089
thread_id=thread.id,
8190
role="user",
82-
content=("The mass of the Mars is 6.4171E23 kg; the mass of the Earth is 5.972168E24 kg;"),
91+
content="Hello, give me a list of planets in our solar system, and their mass in kilograms.",
8392
)
8493
print(f"Created message, message ID: {message.id}")
8594

@@ -91,17 +100,16 @@ async def main():
91100
await agents_client.delete_agent(agent.id)
92101
print("Deleted agent")
93102

94-
messages = agents_client.messages.list(
95-
thread_id=thread.id,
96-
order=ListSortOrder.ASCENDING,
97-
)
98-
103+
messages = agents_client.messages.list(thread_id=thread.id, order=ListSortOrder.ASCENDING)
99104
async for msg in messages:
100-
if msg.role == MessageRole.AGENT:
101-
last_part = msg.content[-1]
102-
if isinstance(last_part, MessageTextContent):
103-
planet = TypeAdapter(Planet).validate_json(last_part.text.value)
104-
print(f"The mass of {planet.planet} is {planet.mass} kg.")
105+
if msg.text_messages:
106+
last_text = msg.text_messages[-1]
107+
print(f"{msg.role}: {last_text.text.value}")
108+
# Deserialize the Agent's JSON response to the `Planets` class defined above
109+
if msg.role == MessageRole.AGENT:
110+
planets = TypeAdapter(Planets).validate_json(last_text.text.value)
111+
for planet in planets.planets:
112+
print(f"The mass of {planet.name.value} is {planet.mass} kg.")
105113

106114

107115
if __name__ == "__main__":

sdk/ai/azure-ai-agents/samples/agents_response_formats/sample_agents_json_object_response_format.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
the "Models + endpoints" tab in your Azure AI Foundry project.
2222
"""
2323

24-
import os, time
24+
import os
2525
from azure.ai.projects import AIProjectClient
2626
from azure.identity import DefaultAzureCredential
2727
from azure.ai.agents.models import ListSortOrder, AgentsResponseFormat, RunStatus
@@ -45,11 +45,12 @@
4545
thread = agents_client.threads.create()
4646
print(f"Created thread, thread ID: {thread.id}")
4747

48-
# List all threads for the agent
4948
threads = agents_client.threads.list()
5049

5150
message = agents_client.messages.create(
52-
thread_id=thread.id, role="user", content="Hello, give me a list of planets in our solar system."
51+
thread_id=thread.id,
52+
role="user",
53+
content="Hello, give me a list of planets in our solar system, and their mass in kilograms.",
5354
)
5455
print(f"Created message, message ID: {message.id}")
5556

sdk/ai/azure-ai-agents/samples/agents_response_formats/sample_agents_json_schema_response_format.py

Lines changed: 53 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
1313
Before running the sample:
1414
15-
pip install azure-ai-projects azure-ai-agents azure-identity pydantic
15+
pip install azure-ai-projects azure-ai-agents azure-identity
1616
1717
Set these environment variables with your own values:
1818
1) PROJECT_ENDPOINT - The Azure AI Project endpoint, as found in the Overview
@@ -22,31 +22,55 @@
2222
"""
2323

2424
import os
25-
26-
from enum import Enum
27-
from pydantic import BaseModel, TypeAdapter
25+
import json
26+
from typing import Dict, Any
2827
from azure.ai.projects import AIProjectClient
2928
from azure.identity import DefaultAzureCredential
3029
from azure.ai.agents.models import (
3130
ListSortOrder,
32-
MessageTextContent,
3331
MessageRole,
3432
ResponseFormatJsonSchema,
3533
ResponseFormatJsonSchemaType,
3634
RunStatus,
3735
)
3836

39-
40-
# Create the pydantic model to represent the planet names and there masses.
41-
class Planets(str, Enum):
42-
Earth = "Earth"
43-
Mars = "Mars"
44-
Mercury = "Mercury"
45-
46-
47-
class Planet(BaseModel):
48-
planet: Planets
49-
mass: float
37+
# Defines a JSON schema for listing Solar System planets and their masses. We would like the AI model to respond in this format.
38+
# See `sample_agents_json_schema_response_format_using_pydantic.py` for an alternative way to define the schema using Pydantic.
39+
json_schema: Dict[str, Any] = {
40+
"$defs": {
41+
"PlanetName": {
42+
"type": "string",
43+
"description": "The name of the planet",
44+
"enum": ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"],
45+
}
46+
},
47+
"type": "object",
48+
"description": "Information about the planets in the Solar System",
49+
"properties": {
50+
"planets": {
51+
"type": "array",
52+
"items": {
53+
"type": "object",
54+
"description": "Information about a planet in the Solar System",
55+
"properties": {
56+
"name": {"$ref": "#/$defs/PlanetName"},
57+
"mass": {
58+
"type": "number",
59+
"description": "Mass of the planet in kilograms",
60+
},
61+
"relative_mass": {
62+
"type": "number",
63+
"description": "Relative mass of the planet compared to Earth (for example, a value of 2.0 means the planet is twice as massive as Earth)",
64+
},
65+
},
66+
"required": ["name", "mass"],
67+
"additionalProperties": False,
68+
},
69+
},
70+
},
71+
"required": ["planets"],
72+
"additionalProperties": False,
73+
}
5074

5175

5276
project_client = AIProjectClient(
@@ -60,12 +84,12 @@ class Planet(BaseModel):
6084
agent = agents_client.create_agent(
6185
model=os.environ["MODEL_DEPLOYMENT_NAME"],
6286
name="my-agent",
63-
instructions="Extract the information about planets.",
87+
instructions="You are helpful agent. Your response is JSON formatted.",
6488
response_format=ResponseFormatJsonSchemaType(
6589
json_schema=ResponseFormatJsonSchema(
6690
name="planet_mass",
67-
description="Extract planet mass.",
68-
schema=Planet.model_json_schema(),
91+
description="Masses of Solar System planets",
92+
schema=json_schema,
6993
)
7094
),
7195
)
@@ -77,7 +101,7 @@ class Planet(BaseModel):
77101
message = agents_client.messages.create(
78102
thread_id=thread.id,
79103
role="user",
80-
content=("The mass of the Mars is 6.4171E23 kg; the mass of the Earth is 5.972168E24 kg;"),
104+
content="Hello, give me a list of planets in our solar system, and their mass in kilograms.",
81105
)
82106
print(f"Created message, message ID: {message.id}")
83107

@@ -89,14 +113,13 @@ class Planet(BaseModel):
89113
agents_client.delete_agent(agent.id)
90114
print("Deleted agent")
91115

92-
messages = agents_client.messages.list(
93-
thread_id=thread.id,
94-
order=ListSortOrder.ASCENDING,
95-
)
96-
116+
messages = agents_client.messages.list(thread_id=thread.id, order=ListSortOrder.ASCENDING)
97117
for msg in messages:
98-
if msg.role == MessageRole.AGENT:
99-
last_part = msg.content[-1]
100-
if isinstance(last_part, MessageTextContent):
101-
planet = TypeAdapter(Planet).validate_json(last_part.text.value)
102-
print(f"The mass of {planet.planet} is {planet.mass} kg.")
118+
if msg.text_messages:
119+
last_text = msg.text_messages[-1]
120+
print(f"{msg.role}: {last_text.text.value}")
121+
# Convert the Agent's JSON response message to a Dict object, extract and print planet masses
122+
if msg.role == MessageRole.AGENT:
123+
response_dict = json.loads(last_text.text.value)
124+
for planet in response_dict["planets"]:
125+
print(f"The mass of {planet['name']} is {planet['mass']} kg.")

sdk/ai/azure-ai-agents/samples/agents_files_images_inputs/sample_agents_json_schema.py renamed to sdk/ai/azure-ai-agents/samples/agents_response_formats/sample_agents_json_schema_response_format_using_pydantic.py

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
"""
77
DESCRIPTION:
88
This sample demonstrates how to use agents with JSON schema output format.
9+
It uses the Pydantic package to define the output JSON schema from Python classes.
910
1011
USAGE:
11-
python sample_agents_json_schema.py
12+
python sample_agents_json_schema_response_format_using_pydantic.py
1213
1314
Before running the sample:
1415
@@ -28,45 +29,52 @@
2829
from azure.ai.projects import AIProjectClient
2930
from azure.identity import DefaultAzureCredential
3031
from azure.ai.agents.models import (
31-
MessageTextContent,
32+
ListSortOrder,
3233
MessageRole,
3334
ResponseFormatJsonSchema,
3435
ResponseFormatJsonSchemaType,
3536
RunStatus,
3637
)
3738

38-
# [START create_agents_client]
39-
project_client = AIProjectClient(
40-
endpoint=os.environ["PROJECT_ENDPOINT"],
41-
credential=DefaultAzureCredential(),
42-
)
43-
# [END create_agents_client]
44-
4539

4640
# Create the pydantic model to represent the planet names and there masses.
47-
class Planets(str, Enum):
41+
class PlanetName(str, Enum):
42+
Mercury = "Mercury"
43+
Venus = "Venus"
4844
Earth = "Earth"
4945
Mars = "Mars"
50-
Jupyter = "Jupyter"
46+
Jupiter = "Jupiter"
47+
Saturn = "Saturn"
48+
Uranus = "Uranus"
49+
Neptune = "Neptune"
5150

5251

5352
class Planet(BaseModel):
54-
planet: Planets
53+
name: PlanetName
5554
mass: float
5655

5756

57+
class Planets(BaseModel):
58+
planets: list[Planet]
59+
60+
61+
project_client = AIProjectClient(
62+
endpoint=os.environ["PROJECT_ENDPOINT"],
63+
credential=DefaultAzureCredential(),
64+
)
65+
5866
with project_client:
5967
agents_client = project_client.agents
6068

6169
agent = agents_client.create_agent(
6270
model=os.environ["MODEL_DEPLOYMENT_NAME"],
6371
name="my-agent",
64-
instructions="Extract the information about planets.",
72+
instructions="You are helpful agent. Your response is JSON formatted.",
6573
response_format=ResponseFormatJsonSchemaType(
6674
json_schema=ResponseFormatJsonSchema(
6775
name="planet_mass",
68-
description="Extract planet mass.",
69-
schema=Planet.model_json_schema(),
76+
description="Masses of Solar System planets.",
77+
schema=Planets.model_json_schema(),
7078
)
7179
),
7280
)
@@ -78,7 +86,7 @@ class Planet(BaseModel):
7886
message = agents_client.messages.create(
7987
thread_id=thread.id,
8088
role="user",
81-
content=("The mass of the Mars is 6.4171E23 kg; the mass of the Earth is 5.972168E24 kg;"),
89+
content="Hello, give me a list of planets in our solar system, and their mass in kilograms.",
8290
)
8391
print(f"Created message, message ID: {message.id}")
8492

@@ -90,13 +98,13 @@ class Planet(BaseModel):
9098
agents_client.delete_agent(agent.id)
9199
print("Deleted agent")
92100

93-
messages = agents_client.messages.list(thread_id=thread.id)
94-
95-
# The messages are following in the reverse order,
96-
# we will iterate them and output only text contents.
101+
messages = agents_client.messages.list(thread_id=thread.id, order=ListSortOrder.ASCENDING)
97102
for msg in messages:
98-
if msg.role == MessageRole.AGENT:
99-
last_part = msg.content[-1]
100-
if isinstance(last_part, MessageTextContent):
101-
planet = TypeAdapter(Planet).validate_json(last_part.text.value)
102-
print(f"The mass of {planet.planet} is {planet.mass} kg.")
103+
if msg.text_messages:
104+
last_text = msg.text_messages[-1]
105+
print(f"{msg.role}: {last_text.text.value}")
106+
# Deserialize the Agent's JSON response to the `Planets` class defined above
107+
if msg.role == MessageRole.AGENT:
108+
planets = TypeAdapter(Planets).validate_json(last_text.text.value)
109+
for planet in planets.planets:
110+
print(f"The mass of {planet.name.value} is {planet.mass} kg.")

0 commit comments

Comments
 (0)