Skip to content

Commit 1c4fba3

Browse files
authored
Merge pull request #32 from Azure-Samples/agentframework
Add agent-framework examples (en/es)
2 parents 5db3026 + d65f9a4 commit 1c4fba3

11 files changed

+855
-22
lines changed

README.md

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,14 @@ A related option is VS Code Dev Containers, which will open the project in your
8686

8787
You can run the examples in this repository by executing the scripts in the `examples` directory. Each script demonstrates a different AI agent pattern or framework.
8888

89-
### Autogen
89+
### Microsoft Agent Framework
9090

9191
| Example | Description |
9292
| ------- | ----------- |
93-
| [autogen_basic.py](examples/autogen_basic.py) | Uses AutoGen to build a single agent. |
94-
| [autogen_tools.py](examples/autogen_tools.py) | Uses AutoGen to build a single agent with tools. |
95-
| [autogen_magenticone.py](examples/autogen_magenticone.py) | Uses AutoGen with the MagenticOne orchestrator agent for travel planning. |
96-
| [autogen_swarm.py](examples/autogen_swarm.py) | Uses AutoGen with the Swarm orchestrator agent for flight refunding requests. |
93+
| [agentframework_basic.py](examples/agentframework_basic.py) | Uses Agent Framework to build a basic informational agent. |
94+
| [agentframework_tool.py](examples/agentframework_tool.py) | Uses Agent Framework to build an agent with a single weather tool. |
95+
| [agentframework_tools.py](examples/agentframework_tools.py) | Uses Agent Framework to build a weekend planning agent with multiple tools. |
96+
| [agentframework_supervisor.py](examples/agentframework_supervisor.py) | Uses Agent Framework with a supervisor orchestrating activity and recipe sub-agents. |
9797

9898
### Langchain v1 and LangGraph
9999

@@ -131,14 +131,6 @@ You can run the examples in this repository by executing the scripts in the `exa
131131
| [pydanticai_mcp_http.py](examples/pydanticai_mcp_http.py) | Uses PydanticAI with an MCP HTTP server toolset for travel planning (hotel search). |
132132
| [pydanticai_mcp_github.py](examples/pydanticai_mcp_github.py) | Uses PydanticAI with an MCP GitHub server toolset to triage repository issues. |
133133

134-
### Semantic Kernel
135-
136-
| Example | Description |
137-
| ------- | ----------- |
138-
| [semantickernel_basic.py](examples/semantickernel_basic.py) | Uses Semantic Kernel to build a simple agent that teaches Spanish. |
139-
| [semantickernel_groupchat.py](examples/semantickernel_groupchat.py) | Uses Semantic Kernel to build a writer/editor two-agent workflow. |
140-
| [semantickernel_mcp_http.py](examples/semantickernel_mcp_http.py) | Uses Semantic Kernel agent with tools from a local MCP HTTP server for hotel search. |
141-
142134
### Other frameworks
143135

144136
| Example | Description |

examples/agentframework_basic.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import asyncio
2+
import os
3+
4+
from agent_framework.azure import AzureOpenAIChatClient
5+
from agent_framework.openai import OpenAIChatClient
6+
from azure.identity import DefaultAzureCredential
7+
from dotenv import load_dotenv
8+
from rich import print
9+
10+
load_dotenv(override=True)
11+
API_HOST = os.getenv("API_HOST", "github")
12+
13+
if API_HOST == "azure":
14+
client = AzureOpenAIChatClient(
15+
credential=DefaultAzureCredential(),
16+
deployment_name=os.environ.get("AZURE_OPENAI_CHAT_DEPLOYMENT"),
17+
endpoint=os.environ.get("AZURE_OPENAI_ENDPOINT"),
18+
api_version=os.environ.get("AZURE_OPENAI_VERSION"),
19+
)
20+
elif API_HOST == "github":
21+
client = OpenAIChatClient(
22+
base_url="https://models.github.ai/inference",
23+
api_key=os.environ["GITHUB_TOKEN"],
24+
model_id=os.getenv("GITHUB_MODEL", "openai/gpt-4o"),
25+
)
26+
elif API_HOST == "ollama":
27+
client = OpenAIChatClient(
28+
base_url=os.environ.get("OLLAMA_ENDPOINT", "http://localhost:11434/v1"),
29+
api_key="none",
30+
model_id=os.environ.get("OLLAMA_MODEL", "llama3.1:latest"),
31+
)
32+
else:
33+
client = OpenAIChatClient(
34+
api_key=os.environ.get("OPENAI_API_KEY"), model_id=os.environ.get("OPENAI_MODEL", "gpt-4o")
35+
)
36+
37+
agent = client.create_agent(instructions="You're an informational agent. Answer questions cheerfully.")
38+
39+
40+
async def main():
41+
response = await agent.run("Whats weather today in San Francisco?")
42+
print(response.text)
43+
44+
45+
if __name__ == "__main__":
46+
asyncio.run(main())
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
import asyncio
2+
import logging
3+
import os
4+
import random
5+
from datetime import datetime
6+
from typing import Annotated
7+
8+
from agent_framework.azure import AzureOpenAIChatClient
9+
from agent_framework.openai import OpenAIChatClient
10+
from azure.identity import DefaultAzureCredential
11+
from dotenv import load_dotenv
12+
from pydantic import Field
13+
from rich import print
14+
from rich.logging import RichHandler
15+
16+
# Logging setup
17+
logging.basicConfig(level=logging.WARNING, format="%(message)s", datefmt="[%X]", handlers=[RichHandler()])
18+
logger = logging.getLogger("supervisor_demo")
19+
20+
load_dotenv(override=True)
21+
API_HOST = os.getenv("API_HOST", "github")
22+
23+
if API_HOST == "azure":
24+
client = AzureOpenAIChatClient(
25+
credential=DefaultAzureCredential(),
26+
deployment_name=os.environ.get("AZURE_OPENAI_CHAT_DEPLOYMENT"),
27+
endpoint=os.environ.get("AZURE_OPENAI_ENDPOINT"),
28+
api_version=os.environ.get("AZURE_OPENAI_VERSION"),
29+
)
30+
elif API_HOST == "github":
31+
client = OpenAIChatClient(
32+
base_url="https://models.github.ai/inference",
33+
api_key=os.environ["GITHUB_TOKEN"],
34+
model_id=os.getenv("GITHUB_MODEL", "openai/gpt-4o"),
35+
)
36+
elif API_HOST == "ollama":
37+
client = OpenAIChatClient(
38+
base_url=os.environ.get("OLLAMA_ENDPOINT", "http://localhost:11434/v1"),
39+
api_key="none",
40+
model_id=os.environ.get("OLLAMA_MODEL", "llama3.1:latest"),
41+
)
42+
else:
43+
client = OpenAIChatClient(
44+
api_key=os.environ.get("OPENAI_API_KEY"), model_id=os.environ.get("OPENAI_MODEL", "gpt-4o")
45+
)
46+
47+
# ----------------------------------------------------------------------------------
48+
# Sub-agent 1 tools: weekend planning
49+
# ----------------------------------------------------------------------------------
50+
51+
52+
def get_weather(
53+
city: Annotated[str, Field(description="The city to get the weather for.")],
54+
date: Annotated[str, Field(description="The date to get weather for in format YYYY-MM-DD.")],
55+
) -> dict:
56+
"""Returns weather data for a given city and date."""
57+
logger.info(f"Getting weather for {city} on {date}")
58+
if random.random() < 0.05:
59+
return {"temperature": 72, "description": "Sunny"}
60+
else:
61+
return {"temperature": 60, "description": "Rainy"}
62+
63+
64+
def get_activities(
65+
city: Annotated[str, Field(description="The city to get activities for.")],
66+
date: Annotated[str, Field(description="The date to get activities for in format YYYY-MM-DD.")],
67+
) -> list[dict]:
68+
"""Returns a list of activities for a given city and date."""
69+
logger.info(f"Getting activities for {city} on {date}")
70+
return [
71+
{"name": "Hiking", "location": city},
72+
{"name": "Beach", "location": city},
73+
{"name": "Museum", "location": city},
74+
]
75+
76+
77+
def get_current_date() -> str:
78+
"""Gets the current date from the system (YYYY-MM-DD)."""
79+
logger.info("Getting current date")
80+
return datetime.now().strftime("%Y-%m-%d")
81+
82+
83+
weekend_agent = client.create_agent(
84+
instructions=(
85+
"You help users plan their weekends and choose the best activities for the given weather. "
86+
"If an activity would be unpleasant in the weather, don't suggest it. "
87+
"Include the date of the weekend in your response."
88+
),
89+
tools=[get_weather, get_activities, get_current_date],
90+
)
91+
92+
93+
async def plan_weekend(query: str) -> str:
94+
"""Plan a weekend based on user query and return the final response."""
95+
logger.info("Tool: plan_weekend invoked")
96+
response = await weekend_agent.run(query)
97+
return response.text
98+
99+
100+
# ----------------------------------------------------------------------------------
101+
# Sub-agent 2 tools: meal planning
102+
# ----------------------------------------------------------------------------------
103+
104+
105+
def find_recipes(
106+
query: Annotated[str, Field(description="User query or desired meal/ingredient")],
107+
) -> list[dict]:
108+
"""Returns recipes (JSON) based on a query."""
109+
logger.info(f"Finding recipes for '{query}'")
110+
if "pasta" in query.lower():
111+
recipes = [
112+
{
113+
"title": "Pasta Primavera",
114+
"ingredients": ["pasta", "vegetables", "olive oil"],
115+
"steps": ["Cook pasta.", "Sauté vegetables."],
116+
}
117+
]
118+
elif "tofu" in query.lower():
119+
recipes = [
120+
{
121+
"title": "Tofu Stir Fry",
122+
"ingredients": ["tofu", "soy sauce", "vegetables"],
123+
"steps": ["Cube tofu.", "Stir fry veggies."],
124+
}
125+
]
126+
else:
127+
recipes = [
128+
{
129+
"title": "Grilled Cheese Sandwich",
130+
"ingredients": ["bread", "cheese", "butter"],
131+
"steps": ["Butter bread.", "Place cheese between slices.", "Grill until golden brown."],
132+
}
133+
]
134+
return recipes
135+
136+
137+
def check_fridge() -> list[str]:
138+
"""Returns a JSON list of ingredients currently in the fridge."""
139+
logger.info("Checking fridge for current ingredients")
140+
if random.random() < 0.5:
141+
items = ["pasta", "tomato sauce", "bell peppers", "olive oil"]
142+
else:
143+
items = ["tofu", "soy sauce", "broccoli", "carrots"]
144+
return items
145+
146+
147+
meal_agent = client.create_agent(
148+
instructions=(
149+
"You help users plan meals and choose the best recipes. "
150+
"Include the ingredients and cooking instructions in your response. "
151+
"Indicate what the user needs to buy from the store when their fridge is missing ingredients."
152+
),
153+
tools=[find_recipes, check_fridge],
154+
)
155+
156+
157+
async def plan_meal(query: str) -> str:
158+
"""Plan a meal based on user query and return the final response."""
159+
logger.info("Tool: plan_meal invoked")
160+
response = await meal_agent.run(query)
161+
return response.text
162+
163+
164+
# ----------------------------------------------------------------------------------
165+
# Supervisor agent orchestrating sub-agents
166+
# ----------------------------------------------------------------------------------
167+
168+
supervisor_agent = client.create_agent(
169+
instructions=(
170+
"You are a supervisor managing two specialist agents: a weekend planning agent and a meal planning agent. "
171+
"Break down the user's request, decide which specialist (or both) to call via the available tools, "
172+
"and then synthesize a final helpful answer. When invoking a tool, provide clear, concise queries."
173+
),
174+
tools=[plan_weekend, plan_meal],
175+
)
176+
177+
178+
async def main():
179+
user_query = "my kids want pasta for dinner"
180+
response = await supervisor_agent.run(user_query)
181+
print(response.text)
182+
183+
184+
if __name__ == "__main__":
185+
logger.setLevel(logging.INFO)
186+
asyncio.run(main())

examples/agentframework_tool.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import asyncio
2+
import logging
3+
import os
4+
import random
5+
from typing import Annotated
6+
7+
from agent_framework.azure import AzureOpenAIChatClient
8+
from agent_framework.openai import OpenAIChatClient
9+
from azure.identity import DefaultAzureCredential
10+
from dotenv import load_dotenv
11+
from pydantic import Field
12+
from rich import print
13+
from rich.logging import RichHandler
14+
15+
# Setup logging with rich
16+
logging.basicConfig(level=logging.WARNING, format="%(message)s", datefmt="[%X]", handlers=[RichHandler()])
17+
logger = logging.getLogger("weekend_planner")
18+
19+
load_dotenv(override=True)
20+
API_HOST = os.getenv("API_HOST", "github")
21+
22+
if API_HOST == "azure":
23+
client = AzureOpenAIChatClient(
24+
credential=DefaultAzureCredential(),
25+
deployment_name=os.environ.get("AZURE_OPENAI_CHAT_DEPLOYMENT"),
26+
endpoint=os.environ.get("AZURE_OPENAI_ENDPOINT"),
27+
api_version=os.environ.get("AZURE_OPENAI_VERSION"),
28+
)
29+
elif API_HOST == "github":
30+
client = OpenAIChatClient(
31+
base_url="https://models.github.ai/inference",
32+
api_key=os.environ["GITHUB_TOKEN"],
33+
model_id=os.getenv("GITHUB_MODEL", "openai/gpt-4o"),
34+
)
35+
elif API_HOST == "ollama":
36+
client = OpenAIChatClient(
37+
base_url=os.environ.get("OLLAMA_ENDPOINT", "http://localhost:11434/v1"),
38+
api_key="none",
39+
model_id=os.environ.get("OLLAMA_MODEL", "llama3.1:latest"),
40+
)
41+
else:
42+
client = OpenAIChatClient(
43+
api_key=os.environ.get("OPENAI_API_KEY"), model_id=os.environ.get("OPENAI_MODEL", "gpt-4o")
44+
)
45+
46+
47+
def get_weather(
48+
city: Annotated[str, Field(description="City name, spelled out fully")],
49+
) -> dict:
50+
"""Returns weather data for a given city, a dictionary with temperature and description."""
51+
logger.info(f"Getting weather for {city}")
52+
if random.random() < 0.05:
53+
return {
54+
"temperature": 72,
55+
"description": "Sunny",
56+
}
57+
else:
58+
return {
59+
"temperature": 60,
60+
"description": "Rainy",
61+
}
62+
63+
64+
agent = client.create_agent(
65+
instructions="You're an informational agent. Answer questions cheerfully.", tools=[get_weather]
66+
)
67+
68+
69+
async def main():
70+
response = await agent.run("how's weather today in sf?")
71+
print(response.text)
72+
73+
74+
if __name__ == "__main__":
75+
asyncio.run(main())

0 commit comments

Comments
 (0)