|
| 1 | +# Copyright (c) Microsoft. All rights reserved. |
| 2 | + |
| 3 | +import asyncio |
| 4 | +from functools import reduce |
| 5 | + |
| 6 | +from azure.ai.projects.models import BingGroundingTool |
| 7 | +from azure.identity.aio import DefaultAzureCredential |
| 8 | + |
| 9 | +from semantic_kernel.agents import AzureAIAgent, AzureAIAgentSettings, AzureAIAgentThread |
| 10 | +from semantic_kernel.contents import ( |
| 11 | + ChatMessageContent, |
| 12 | + FunctionCallContent, |
| 13 | + StreamingAnnotationContent, |
| 14 | + StreamingChatMessageContent, |
| 15 | +) |
| 16 | + |
| 17 | +""" |
| 18 | +The following sample demonstrates how to create an Azure AI agent that |
| 19 | +uses the Bing grounding tool to answer a user's question. |
| 20 | +
|
| 21 | +Additionally, the `on_intermediate_message` callback is used to handle intermediate messages |
| 22 | +from the agent. |
| 23 | +
|
| 24 | +Note: Please visit the following link to learn more about the Bing grounding tool: |
| 25 | +
|
| 26 | +https://learn.microsoft.com/en-us/azure/ai-services/agents/how-to/tools/bing-grounding?tabs=python&pivots=overview |
| 27 | +""" |
| 28 | + |
| 29 | +TASK = "Which team won the 2025 NCAA basketball championship?" |
| 30 | + |
| 31 | +intermediate_steps: list[ChatMessageContent] = [] |
| 32 | + |
| 33 | + |
| 34 | +async def handle_streaming_intermediate_steps(message: ChatMessageContent) -> None: |
| 35 | + intermediate_steps.append(message) |
| 36 | + |
| 37 | + |
| 38 | +async def main() -> None: |
| 39 | + async with ( |
| 40 | + DefaultAzureCredential() as creds, |
| 41 | + AzureAIAgent.create_client(credential=creds) as client, |
| 42 | + ): |
| 43 | + # 1. Enter your Bing Grounding Connection Name |
| 44 | + # <your-bing-grounding-connection-name> |
| 45 | + bing_connection = await client.connections.get(connection_name="skbinggrounding") |
| 46 | + conn_id = bing_connection.id |
| 47 | + |
| 48 | + # 2. Initialize agent bing tool and add the connection id |
| 49 | + bing_grounding = BingGroundingTool(connection_id=conn_id) |
| 50 | + |
| 51 | + # 3. Create an agent with Bing grounding on the Azure AI agent service |
| 52 | + agent_definition = await client.agents.create_agent( |
| 53 | + name="BingGroundingAgent", |
| 54 | + instructions="Use the Bing grounding tool to answer the user's question.", |
| 55 | + model=AzureAIAgentSettings().model_deployment_name, |
| 56 | + tools=bing_grounding.definitions, |
| 57 | + ) |
| 58 | + |
| 59 | + # 4. Create a Semantic Kernel agent for the Azure AI agent |
| 60 | + agent = AzureAIAgent( |
| 61 | + client=client, |
| 62 | + definition=agent_definition, |
| 63 | + ) |
| 64 | + |
| 65 | + # 5. Create a thread for the agent |
| 66 | + # If no thread is provided, a new thread will be |
| 67 | + # created and returned with the initial response |
| 68 | + thread: AzureAIAgentThread | None = None |
| 69 | + |
| 70 | + try: |
| 71 | + print(f"# User: '{TASK}'") |
| 72 | + # 6. Invoke the agent for the specified thread for response |
| 73 | + first_chunk = True |
| 74 | + async for response in agent.invoke_stream( |
| 75 | + messages=TASK, thread=thread, on_intermediate_message=handle_streaming_intermediate_steps |
| 76 | + ): |
| 77 | + if first_chunk: |
| 78 | + print(f"# {response.name}: ", end="", flush=True) |
| 79 | + first_chunk = False |
| 80 | + print(f"{response}", end="", flush=True) |
| 81 | + thread = response.thread |
| 82 | + |
| 83 | + # 7. Show annotations |
| 84 | + if any(isinstance(item, StreamingAnnotationContent) for item in response.items): |
| 85 | + print() |
| 86 | + for annotation in response.items: |
| 87 | + if isinstance(annotation, StreamingAnnotationContent): |
| 88 | + print( |
| 89 | + f"Annotation :> {annotation.url}, source={annotation.quote}, with " |
| 90 | + f"start_index={annotation.start_index} and end_index={annotation.end_index}" |
| 91 | + ) |
| 92 | + finally: |
| 93 | + # 8. Cleanup: Delete the thread and agent |
| 94 | + await thread.delete() if thread else None |
| 95 | + await client.agents.delete_agent(agent.id) |
| 96 | + |
| 97 | + print("====================================================") |
| 98 | + print("\nResponse complete:\n") |
| 99 | + # Combine the intermediate `StreamingChatMessageContent` chunks into a single message |
| 100 | + filtered_steps = [step for step in intermediate_steps if isinstance(step, StreamingChatMessageContent)] |
| 101 | + streaming_full_completion: StreamingChatMessageContent = reduce(lambda x, y: x + y, filtered_steps) |
| 102 | + # Grab the other messages that are not `StreamingChatMessageContent` |
| 103 | + other_steps = [s for s in intermediate_steps if not isinstance(s, StreamingChatMessageContent)] |
| 104 | + final_msgs = [streaming_full_completion] + other_steps |
| 105 | + for msg in final_msgs: |
| 106 | + if any(isinstance(item, FunctionCallContent) for item in msg.items): |
| 107 | + for item in msg.items: |
| 108 | + if isinstance(item, FunctionCallContent): |
| 109 | + # Note: the AI Projects SDK is not returning a `requesturl` for streaming events |
| 110 | + # The issue was raised with the AI Projects team |
| 111 | + print(f"Function call: {item.function_name} with arguments: {item.arguments}") |
| 112 | + |
| 113 | + print(f"{msg.content}") |
| 114 | + |
| 115 | + """ |
| 116 | + Sample Output: |
| 117 | + |
| 118 | + # User: 'Which team won the 2025 NCAA basketball championship?' |
| 119 | + # BingGroundingAgent: The Florida Gators won the 2025 NCAA men's basketball championship, defeating the Houston Cougars 65-63. It marked Florida's third national title and their first since back-to-back wins in 2006-2007【5:0†source】 |
| 120 | + Annotation :> https://www.usatoday.com/story/sports/ncaab/2025/04/07/houston-florida-live-updates-national-championship-score/82982004007/, source=Florida vs Houston final score: Gators win 2025 NCAA championship, with start_index=198 and end_index=210 |
| 121 | + 【5:5†source】 |
| 122 | + Annotation :> https://www.nbcsports.com/mens-college-basketball/live/florida-vs-houston-live-score-updates-game-news-stats-highlights-for-2025-ncaa-march-madness-mens-national-championship, source=Houston vs. Florida RECAP: Highlights, stats, box score, results as ..., with start_index=210 and end_index=222 |
| 123 | + . |
| 124 | + ==================================================== |
| 125 | +
|
| 126 | + Response complete: |
| 127 | +
|
| 128 | + Function call: bing_grounding with arguments: None |
| 129 | + Function call: bing_grounding with arguments: None |
| 130 | +
|
| 131 | + The Florida Gators won the 2025 NCAA men's basketball championship, defeating the Houston Cougars 65-63. It marked Florida's third national title and their first since back-to-back wins in 2006-2007【5:0†source】【5:5†source】. |
| 132 | + """ # noqa: E501 |
| 133 | + |
| 134 | + |
| 135 | +if __name__ == "__main__": |
| 136 | + asyncio.run(main()) |
0 commit comments