Web Search Tool
Exercise 2 β Add Hosted Web Search Tool
| Β | Β |
|---|---|
| Phase | 1 β Foundations |
| Difficulty | β |
| Estimated time | 20β30 min |
| Starter file | starter.py (3 TODOs) |
Learning Objectives
By completing this exercise you will be able to:
- Explain what hosted tools are and how they differ from local tools
- Instantiate
client.get_web_search_toolwith the correct configuration - Configure a Bing grounding connection for your Foundry project
- Pass tools to an agent via
as_agent(tools=[...])
Prerequisites
| Requirement | Details |
|---|---|
| Exercise 1 completed | You can create and run a basic agent |
BING_CONNECTION_ID env var |
Set in .env (see Background below) |
| Microsoft Foundry project | Same project used in Exercise 1 |
Background
Hosted Tools
The Agent Framework supports hosted tools β tools that execute on the Microsoft Foundry service side, not in your local process. When you attach a hosted tool to an agent:
- Your code sends the tool definition to Foundry when creating the agent.
- The model decides when to invoke the tool (you donβt call it yourself).
- Foundry runs the tool server-side and feeds the result back to the model.
client.get_web_search_tool is a hosted tool backed by Bing grounding. It lets the agent search the web for current information without you writing any HTTP/search logic.
Bing Grounding Connection
To use Bing grounding you need a Foundry project connection, not a raw Bing API key.
How to create one:
- Open your Microsoft Foundry project in the portal.
- Go to Management β Connected resources (or Settings β Connections).
- Click + New connection β Grounding with Bing Search.
- Select or create a Bing Search resource, then save.
- Copy the project connection ID β it looks like:
/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.MachineLearningServices/workspaces/<project>/connections/<name> - Set it as
BING_CONNECTION_IDin your.envfile.
How the Agent Decides to Search
The model uses its instructions and the conversation context to decide whether to invoke the web search tool. You can influence this by:
- Wording your instructions to mention web search capabilities
- Asking questions about current/real-time information
Your Task
Open starter.py. The helper code (.env loading, DNS check, Bing config) is already provided. You need to fill in 3 TODOs inside async def main():
Step 1 β Create the client.get_web_search_tool (TODO 1)
Create a client.get_web_search_tool instance with additional_properties that includes:
- A
user_locationdict (e.g.,{"city": "Seattle", "country": "US"}) - The Bing connection properties from
bing_props
Step 2 β Create the Agent with the Tool (TODO 2)
Use FoundryChatClient(credential=cred).as_agent(...) to create an agent with:
- A
name(e.g.,"web_search") instructionsthat tell the agent it can search the webtools=[...]containing yourclient.get_web_search_toolinstance
Remember to use async with so the agent is properly cleaned up.
Step 3 β Run the Agent and Print the Result (TODO 3)
Call agent.run() with a search query and print result.text. Wrap the call in a try/except ChatClientInvalidResponseException to handle model resolution errors gracefully.
Hints
Work through the hints one at a time β try each step on your own first!
π‘ Hint 1 β client.get_web_search_tool takes additional_properties
```python client.get_web_search_tool( additional_properties={ "user_location": {"city": "...", "country": "..."}, # ... bing connection config goes here too } ) ``` The `additional_properties` dict is where you pass both the user location and the Bing connection settings.π‘ Hint 2 β Use _get_bing_tool_properties() and merge dicts
The starter code already calls `bing_props = _get_bing_tool_properties()`. This returns a dict like `{"connection_id": "..."}`. Merge it with user_location using `**` unpacking: ```python additional_properties={ "user_location": {"city": "Seattle", "country": "US"}, **bing_props, } ```π‘ Hint 3 β Near-complete solution
```python # TODO(1) web_search_tool = client.get_web_search_tool( additional_properties={ "user_location": {"city": "Seattle", "country": "US"}, **bing_props, } ) # TODO(2) async with FoundryChatClient(credential=cred).as_agent( name="web_search", instructions=( "You are a web search expert who can find current information on the web " "to help plan events and answer questions." ), tools=[web_search_tool], ) as agent: # TODO(3) try: result = await agent.run( "What venue could hold 50 people on December 6th, 2026 in Seattle" ) except ChatClientInvalidResponseException as ex: msg = str(ex) if "Failed to resolve model info" in msg: raise RuntimeError( "Could not resolve model deployment. " "Check FOUNDRY_MODEL in the Foundry portal." ) from ex raise print(result.text) ```Validate Your Work
1. Run the structure check
bash workshop/exercises/ex2_web_search/check.sh
All checks should show β .
2. Run against Azure
python workshop/exercises/ex2_web_search/starter.py
You should see a response with web search results about venues in Seattle (or your chosen location). The response will include real, current information from the web.
Bonus Challenges
- Change the user location: Try
{"city": "Tokyo", "country": "JP"}and ask a location-specific question. Does the result change? - Control when search triggers: Modify the agent instructions to say βOnly use web search when the user explicitly asks for current information.β Then compare responses with and without a search-triggering prompt.
Troubleshooting
| Symptom | Likely Cause | Fix |
|---|---|---|
RuntimeError: Hosted web search requires a Bing connection |
BING_CONNECTION_ID not set or empty |
Set it in .env β get the value from the Foundry portal |
BING_CONNECTION_ID value looks wrong |
Wrong format β needs full ARM resource path | Use the full connection ID starting with /subscriptions/... |
Failed to resolve model info |
Model deployment name mismatch | Open Foundry portal β Models + endpoints β use the exact deployment name |
Cannot resolve ... host via DNS |
Private networking / DNS issue | Run from a network that can resolve the Foundry endpoint, or use a public project |
Solution Reference
The complete working solution is at src/demo2_web_search.py.
Reference: The
client.get_web_search_toolfactory method is part ofagent-framework-foundry(pinned at1.2.2in this repository). If Microsoft Learn docs show different behavior, the pinned version andsrc/demo2_web_search.pytake precedence.