mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Sample to show passing in JSON schema for structured outputs (#2362)
This commit is contained in:
committed by
GitHub
Unverified
parent
cf13e35c73
commit
5bdf8a774a
@@ -853,6 +853,7 @@ class ChatAgent(BaseAgent):
|
||||
await self._async_exit_stack.enter_async_context(mcp_server)
|
||||
final_tools.extend(mcp_server.functions)
|
||||
|
||||
merged_additional_options = additional_chat_options or {}
|
||||
co = run_chat_options & ChatOptions(
|
||||
model_id=model_id,
|
||||
conversation_id=thread.service_thread_id,
|
||||
@@ -871,7 +872,7 @@ class ChatAgent(BaseAgent):
|
||||
tools=final_tools,
|
||||
top_p=top_p,
|
||||
user=user,
|
||||
**(additional_chat_options or {}),
|
||||
additional_properties=merged_additional_options, # type: ignore[arg-type]
|
||||
)
|
||||
# Filter chat_options from kwargs to prevent duplicate keyword argument
|
||||
filtered_kwargs = {k: v for k, v in kwargs.items() if k != "chat_options"}
|
||||
@@ -986,6 +987,7 @@ class ChatAgent(BaseAgent):
|
||||
await self._async_exit_stack.enter_async_context(mcp_server)
|
||||
final_tools.extend(mcp_server.functions)
|
||||
|
||||
merged_additional_options = additional_chat_options or {}
|
||||
co = run_chat_options & ChatOptions(
|
||||
conversation_id=thread.service_thread_id,
|
||||
allow_multiple_tool_calls=allow_multiple_tool_calls,
|
||||
@@ -1004,7 +1006,7 @@ class ChatAgent(BaseAgent):
|
||||
tools=final_tools,
|
||||
top_p=top_p,
|
||||
user=user,
|
||||
**(additional_chat_options or {}),
|
||||
additional_properties=merged_additional_options, # type: ignore[arg-type]
|
||||
)
|
||||
|
||||
# Filter chat_options from kwargs to prevent duplicate keyword argument
|
||||
|
||||
@@ -118,6 +118,7 @@ This directory contains samples demonstrating the capabilities of Microsoft Agen
|
||||
| [`getting_started/agents/openai/openai_chat_client_with_local_mcp.py`](./getting_started/agents/openai/openai_chat_client_with_local_mcp.py) | OpenAI Chat Client with Local MCP Example |
|
||||
| [`getting_started/agents/openai/openai_chat_client_with_thread.py`](./getting_started/agents/openai/openai_chat_client_with_thread.py) | OpenAI Chat Client with Thread Management Example |
|
||||
| [`getting_started/agents/openai/openai_chat_client_with_web_search.py`](./getting_started/agents/openai/openai_chat_client_with_web_search.py) | OpenAI Chat Client with Web Search Example |
|
||||
| [`getting_started/agents/openai/openai_chat_client_with_runtime_json_schema.py`](./getting_started/agents/openai/openai_chat_client_with_runtime_json_schema.py) | OpenAI Chat Client with runtime JSON Schema for structured output without a Pydantic model |
|
||||
| [`getting_started/agents/openai/openai_responses_client_basic.py`](./getting_started/agents/openai/openai_responses_client_basic.py) | OpenAI Responses Client Basic Example |
|
||||
| [`getting_started/agents/openai/openai_responses_client_image_analysis.py`](./getting_started/agents/openai/openai_responses_client_image_analysis.py) | OpenAI Responses Client Image Analysis Example |
|
||||
| [`getting_started/agents/openai/openai_responses_client_image_generation.py`](./getting_started/agents/openai/openai_responses_client_image_generation.py) | OpenAI Responses Client Image Generation Example |
|
||||
|
||||
@@ -19,6 +19,7 @@ This folder contains examples demonstrating different ways to create and use age
|
||||
| [`openai_chat_client_with_local_mcp.py`](openai_chat_client_with_local_mcp.py) | Shows how to integrate OpenAI agents with local Model Context Protocol (MCP) servers for enhanced functionality and tool integration. |
|
||||
| [`openai_chat_client_with_thread.py`](openai_chat_client_with_thread.py) | Demonstrates thread management with OpenAI agents, including automatic thread creation for stateless conversations and explicit thread management for maintaining conversation context across multiple interactions. |
|
||||
| [`openai_chat_client_with_web_search.py`](openai_chat_client_with_web_search.py) | Shows how to use web search capabilities with OpenAI agents to retrieve and use information from the internet in responses. |
|
||||
| [`openai_chat_client_with_runtime_json_schema.py`](openai_chat_client_with_runtime_json_schema.py) | Shows how to supply a runtime JSON Schema via `additional_chat_options` for structured output without defining a Pydantic model. |
|
||||
| [`openai_responses_client_basic.py`](openai_responses_client_basic.py) | The simplest way to create an agent using `ChatAgent` with `OpenAIResponsesClient`. Shows both streaming and non-streaming responses for structured response generation with OpenAI models. |
|
||||
| [`openai_responses_client_image_analysis.py`](openai_responses_client_image_analysis.py) | Demonstrates how to use vision capabilities with agents to analyze images. |
|
||||
| [`openai_responses_client_image_generation.py`](openai_responses_client_image_generation.py) | Demonstrates how to use image generation capabilities with OpenAI agents to create images based on text descriptions. Requires PIL (Pillow) for image display. |
|
||||
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
|
||||
from agent_framework.openai import OpenAIChatClient
|
||||
|
||||
"""
|
||||
OpenAI Chat Client Runtime JSON Schema Example
|
||||
|
||||
Demonstrates structured outputs when the schema is only known at runtime.
|
||||
Uses additional_chat_options to pass a JSON Schema payload directly to OpenAI
|
||||
without defining a Pydantic model up front.
|
||||
"""
|
||||
|
||||
|
||||
runtime_schema = {
|
||||
"title": "WeatherDigest",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"location": {"type": "string"},
|
||||
"conditions": {"type": "string"},
|
||||
"temperature_c": {"type": "number"},
|
||||
"advisory": {"type": "string"},
|
||||
},
|
||||
# OpenAI strict mode requires every property to appear in required.
|
||||
"required": ["location", "conditions", "temperature_c", "advisory"],
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
|
||||
async def non_streaming_example() -> None:
|
||||
print("=== Non-streaming runtime JSON schema example ===")
|
||||
|
||||
agent = OpenAIChatClient().create_agent(
|
||||
name="RuntimeSchemaAgent",
|
||||
instructions="Return only JSON that matches the provided schema. Do not add commentary.",
|
||||
)
|
||||
|
||||
query = "Give a brief weather digest for Seattle."
|
||||
print(f"User: {query}")
|
||||
|
||||
response = await agent.run(
|
||||
query,
|
||||
additional_chat_options={
|
||||
"response_format": {
|
||||
"type": "json_schema",
|
||||
"json_schema": {
|
||||
"name": runtime_schema["title"],
|
||||
"strict": True,
|
||||
"schema": runtime_schema,
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
print("Model output:")
|
||||
print(response.text)
|
||||
|
||||
parsed = json.loads(response.text)
|
||||
print("Parsed dict:")
|
||||
print(parsed)
|
||||
|
||||
|
||||
async def streaming_example() -> None:
|
||||
print("=== Streaming runtime JSON schema example ===")
|
||||
|
||||
agent = OpenAIChatClient().create_agent(
|
||||
name="RuntimeSchemaAgent",
|
||||
instructions="Return only JSON that matches the provided schema. Do not add commentary.",
|
||||
)
|
||||
|
||||
query = "Give a brief weather digest for Portland."
|
||||
print(f"User: {query}")
|
||||
|
||||
chunks = []
|
||||
async for chunk in agent.run_stream(
|
||||
query,
|
||||
additional_chat_options={
|
||||
"response_format": {
|
||||
"type": "json_schema",
|
||||
"json_schema": {
|
||||
"name": runtime_schema["title"],
|
||||
"strict": True,
|
||||
"schema": runtime_schema,
|
||||
},
|
||||
},
|
||||
},
|
||||
):
|
||||
if chunk.text:
|
||||
chunks.append(chunk.text)
|
||||
|
||||
raw_text = "".join(chunks)
|
||||
print("Model output:")
|
||||
print(raw_text)
|
||||
|
||||
parsed = json.loads(raw_text)
|
||||
print("Parsed dict:")
|
||||
print(parsed)
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
print("=== OpenAI Chat Client with runtime JSON Schema ===")
|
||||
|
||||
await non_streaming_example()
|
||||
await streaming_example()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user