Task 1 — Build an agent with a tool
Part of the Build multi-agent solutions with the Agent Framework lab. New here? Start with Getting started.
Set up (start here): This task needs a Foundry project and the starter code. If you haven’t already, complete Getting started to create your project, clone the code, and set
PROJECT_ENDPOINTandMODEL_DEPLOYMENT_NAMEinPython/.env. Then, from theLabfiles/C-build-multi-agent-solutions-with-agent-frameworkfolder, verify you’re ready:
python setup/check_env.py --task 1
Continuing from a previous task? If you just finished an earlier task in the same
Pythonfolder, your project, virtual environment, and.envare already set — go straight to Build the agent with a custom tool below.
Every useful agent can do something beyond chatting. With the Microsoft Agent Framework
(MAF), you give an agent a capability by writing an ordinary Python function, marking it with
@tool, and handing it to the agent — the framework generates the tool’s schema and runs the
whole tool-calling loop for you. In this task you’ll build the Tailwind Traders trip-expense
agent: it reads a guide’s trip-expense data, itemizes it, and calls a tool to “email” a
reimbursement claim to the finance desk.
What is a tool?
A tool is a function you give an agent so it can take action or fetch information beyond the
model’s own knowledge. In the Agent Framework you write a normal Python function and add the
@tool decorator; the framework reads the function signature (including the parameter
descriptions) to build the schema the model needs. When the model decides a tool is needed,
agent.run() calls your function, feeds the result back to the model, and continues — all
automatically.
Open the Python folder and activate the virtual environment from Getting started (.\labenv\Scripts\Activate.ps1), then continue below.
Build the agent with a custom tool
Open expense_agent.py and add code at each commented placeholder.
- Review the code already in the file. It contains:
- Some import statements.
- A
mainfunction that loadsdata.txt(the trip-expense data), asks you what to do with it, and then calls… - A
process_expenses_datafunction where you’ll create and run your agent.
Tip: As you add code, keep the indentation aligned with the comments.
-
At the top of the file, find the comment Add references and add the namespaces you’ll need:
# Add references from agent_framework import tool, Agent from agent_framework.foundry import FoundryChatClient from azure.identity import AzureCliCredential from pydantic import Field -
Near the bottom of the file, find the comment Create a tool function for the email functionality and add the tool the agent will use to send the claim:
# Create a tool function for the email functionality @tool(approval_mode="never_require") def submit_claim( to: Annotated[str, Field(description="Who to send the email to")], subject: Annotated[str, Field(description="The subject of the email.")], body: Annotated[str, Field(description="The text body of the email.")], ): """Submit a Tailwind Traders trip-expense claim by sending an email.""" print("\nTo:", to) print("Subject:", subject) print(body, "\n")Note: The function simulates sending an email by printing it to the console. In a real application, you’d use an SMTP service or similar to actually send the email.
approval_mode="never_require"lets the agent call the tool without pausing to ask you for approval each time. -
Back up in the
process_expenses_datafunction, find the comment Create a foundry chat client and add the following (keep the indentation level):# Create a foundry chat client client = FoundryChatClient( project_endpoint=os.getenv("PROJECT_ENDPOINT"), model=os.getenv("MODEL_DEPLOYMENT_NAME"), credential=AzureCliCredential(), )The AzureCliCredential object lets your code authenticate to Azure using your
az loginsession. The FoundryChatClient connects to your Foundry project using the endpoint and model deployment name from.env. -
Find the comment Initialize an agent with the tool and instructions and add the following:
# Initialize an agent with the tool and instructions agent = Agent( client=client, name="TripExpenseAgent", instructions="""You are an AI assistant for Tailwind Traders trip-expense claims. At the user's request, create an expense claim and use the submit_claim tool to send an email to expenses@tailwindtraders.com with the subject 'Trip Expense Claim' and a body that contains the itemized expenses with a total. Then confirm to the user that you've done so. Don't ask for any more information from the user, just use the data provided to create the email.""", tools=[submit_claim], )The Agent object is initialized with the client, instructions that tell it how to behave, and the
submit_claimtool it’s allowed to call. -
Review the code that follows the agent (already provided). It creates a session to hold the conversation and calls
await agent.run(...), which runs the entire tool-calling loop and returns the final response asresponse.text:# Create a session and use the agent to process the expenses data try: # A session keeps the conversation history across the agent run session = agent.create_session() # Invoke the agent with the prompt and the trip expenses data response = await agent.run(f"{prompt}: {expenses_data}", session=session) # Display the response print(f"\n# Agent:\n{response.text}") except Exception as e: # Something went wrong print(e) - Save the file (Ctrl+S).
Run and test
-
In the terminal, sign in and run the app:
az loginpython expense_agent.pyaz loginlets theAzureCliCredentialauthenticate to your Azure account. -
When asked what to do with the expenses data, enter:
Submit an expense claim -
Review the output. The agent should compose an itemized expense-claim email — printed by the
submit_claimtool — and then confirm it’s done. You’ll see output similar to:To: expenses@tailwindtraders.com Subject: Trip Expense Claim ...itemized expenses with a total... # Agent: I've submitted your trip-expense claim to expenses@tailwindtraders.com.Tip: If the app fails because the rate limit is exceeded, wait a few seconds and try again. If there is insufficient quota available in your subscription, the model may not be able to respond.
✅ Checkpoint: You’ve built a single agent with a custom tool using the Microsoft Agent Framework — the model decided when to call your tool, and
agent.run()handled the loop. That’s the Core of this lab. The optional tasks below grow this into a multi-agent solution.
When you’re finished, enter deactivate to exit the virtual environment.
Next (optional): Task 2 — Orchestrate multiple agents in sequence · Task 3 — Connect remote agents with A2A