Sunday, July 13, 2025

 In continuation with the previous posts, this describes how to create a file search ai agent for use with aerial drone images to query drone world:

#!/usr/bin/python

from dotenv import load_dotenv

load_dotenv(override=True)

from azure.identity import DefaultAzureCredential, get_bearer_token_provider

from azure.ai.agents import AgentsClient

from azure.core.credentials import AzureKeyCredential

from azure.ai.projects import AIProjectClient

import os

project_endpoint = os.environ["AZURE_PROJECT_ENDPOINT"]

project_api_key = os.environ["AZURE_PROJECT_API_KEY"]

agent_model = os.getenv("AZURE_AGENT_MODEL", "gpt-4o-mini")

search_endpoint = os.environ["AZURE_SEARCH_SERVICE_ENDPOINT"]

api_version = os.getenv("AZURE_SEARCH_API_VERSION")

search_api_key = os.getenv("AZURE_SEARCH_ADMIN_KEY")

credential = AzureKeyCredential(search_api_key)

token_provider = get_bearer_token_provider(DefaultAzureCredential(), "https://search.azure.com/.default")

index_name = os.getenv("AZURE_SEARCH_INDEX_NAME", "index00")

azure_openai_endpoint = os.environ["AZURE_OPENAI_ENDPOINT"]

azure_openai_api_key = os.getenv("AZURE_OPENAI_API_KEY")

azure_openai_gpt_deployment = os.getenv("AZURE_OPENAI_GPT_DEPLOYMENT", "gpt-4o-mini")

azure_openai_gpt_model = os.getenv("AZURE_OPENAI_GPT_MODEL", "gpt-4o-mini")

azure_openai_embedding_deployment = os.getenv("AZURE_OPENAI_EMBEDDING_DEPLOYMENT", "text-embedding-ada-002")

azure_openai_embedding_model = os.getenv("AZURE_OPENAI_EMBEDDING_MODEL", "text-embedding-ada-002")

api_version = "2025-05-01-Preview"

agent_max_output_tokens=10000

from azure.ai.agents.models import FileSearchTool

from azure.ai.projects import AIProjectClient

from azure.ai.projects.models import Index

from azure.ai.agents.models import (

    AgentThreadCreationOptions,

    ThreadMessageOptions,

    MessageTextContent,

    ListSortOrder

)

project_client = AIProjectClient(endpoint=project_endpoint, credential=DefaultAzureCredential())

for index_agent in index_client.list_agents():

    print(index_agent.name)

file_agent_name = "file-agent-in-a-team"

file_agent_instructions = "Search files and documents to find relevant information."

def create_connected_agent(name, instructions, tools):

    return project_client.agents.create_agent(

        model=azure_openai_gpt_model,

        # deployment=azure_openai_gpt_deployment,

        name=name,

        instructions=instructions,

        tools=tools.definitions,

        tool_resources=tools.resources,

        top_p=1

    )

def get_file_agent(name, instructions):

    file_search_agent = None

    for agent in project_client.agents.list_agents():

        print(f"{agent.name} matches {agent.name == 'file-agent-in-a-team'}")

        if agent.name == name:

            file_search_agent = agent

            break

    # file_search_agent = [ agent for agent in project_client.agents.list_agents() if agent.name == name][0] # get_agent(agent_id=name)

    if not file_search_agent:

        print("Creating A File Search Agent...")

        file_search_tool = FileSearchTool(

            vector_store_id=index_name, # This is your Azure AI Search index name

            vector_field="vector", # The field storing embeddings

            endpoint=search_endpoint,

            api_key=search_api_key)

        file_search_agent = create_connected_agent(

            name="file_search_agent",

            instructions="Search files and documents to find relevant information.",

            tools=[file_search_tool]

        )

    return file_search_agent

agent = get_file_agent(file_agent_name, file_agent_instructions)

def get_response(agent, instructions, query):

    messages = [

        {

            "role":"assistant",

            "content": instructions

        }

    ]

    run = project_client.agents.create_thread_and_process_run(agent_id = agent.id,

        thread = AgentThreadCreationOptions(messages = [

        ThreadMessageOptions(role="assistant", content=instructions),

        ThreadMessageOptions(role="user", content=query)]),)

    print(run)

    if run.status == "failed":

        print(f"Run error: {run.last_error}")

    # List all messages in the thread, in ascending order of creation

    messages = project_client.agents.messages.list(

        thread_id=run.thread_id,

        order=ListSortOrder.ASCENDING,

    )

    for msg in messages:

        last_part = msg.content[-1]

        if isinstance(last_part, MessageTextContent):

            print(f"{msg.role}: {last_part.text.value}")

    return last_part.text.value

if agent:

    query_text = "Are there dedicated bicycle crossings in green color at street intersections?"

    response = get_response(agent, file_agent_instructions, query_text)

    print(response)

else:

    print("No agent found.")

Output:

Sample Response:

{'id': 'run_qSjEC1Isk2NCC2DfLtUBKACn', 'object': 'thread.run', 'created_at': 1752370195, 'assistant_id': 'asst_ilwEdVRNApUDmqa2EB3sSBKp', 'thread_id': 'thread_gX5kKqSaPvtR5ISQSkTCZVdk', 'status': 'completed', 'started_at': 1752370195, 'expires_at': None, 'cancelled_at': None, 'failed_at': None, 'completed_at': 1752370200, 'required_action': None, 'last_error': None, 'model': 'gpt-4o-mini', 'instructions': 'You are an AI assistant that answers questions by searching files and documents to find relevant information. If you do not find a match for the query, respond with "I don't know", otherwise cite references as a string formated with the document id with ".json" suffix replaced with ".jpg" ', 'tools': [{'type': 'file_search'}], 'tool_resources': {}, 'metadata': {}, 'temperature': 1.0, 'top_p': 1.0, 'max_completion_tokens': None, 'max_prompt_tokens': None, 'truncation_strategy': {'type': 'auto', 'last_messages': None}, 'incomplete_details': None, 'usage': {'prompt_tokens': 46448, 'completion_tokens': 66, 'total_tokens': 46514, 'prompt_token_details': {'cached_tokens': 0}}, 'response_format': 'auto', 'tool_choice': 'auto', 'parallel_tool_calls': True}

Agent List:

{'id': 'asst_ilwEdVRNApUDmqa2EB3sSBKp', 'object': 'assistant', 'created_at': 1752346264, 'name': 'file-agent-in-a-team', 'description': 'finds images given id and returns sas url', 'model': 'gpt-4o-mini', 'instructions': 'You are an AI assistant that answers questions by searching files and documents to find relevant information. If you do not find a match for the query, respond with "I don't know", otherwise cite references as a string formated with the document id with ".json" suffix replaced with ".jpg" ', 'tools': [{'type': 'file_search'}], 'top_p': 1.0, 'temperature': 1.0, 'tool_resources': {'file_search': {'vector_store_ids': ['vs_MNuwIdYIbJ6wVDdo2DFk01bT']}}, 'metadata': {}, 'response_format': 'auto'} {'id': 'asst_f3IUTrON3hMpdyTJU51aCo7v', 'object': 'assistant', 'created_at': 1750537933, 'name': 'search-agent-in-a-team', 'description': None, 'model': 'gpt-4o-mini', 'instructions': ' \nYou are an AI assistant that answers questions about the stored and indexed drone images and objects in search index index02. \nThe data source is an Azure AI Search resource where the schema has JSON description field, a vector field and an id field and this id field must be cited in your answer. \nIf you do not find a match for the query, respond with "I don't know", otherwise cite references with the value of the id field. \n', 'tools': [{'type': 'azure_ai_search'}], 'top_p': 1.0, 'temperature': 1.0, 'tool_resources': {'azure_ai_search': {'indexes': [{'index_connection_id': '/subscriptions/656e67c6-f810-4ea6-8b89-636dd0b6774c/resourceGroups/rg-ctl-2/providers/Microsoft.CognitiveServices/accounts/found-vision-1/projects/droneimage/connections/srchvision01', 'index_name': 'index00', 'query_type': 'vector_semantic_hybrid', 'top_k': 5, 'filter': '', 'index_asset_id': ''}]}}, 'metadata': {}, 'response_format': 'auto'} {'id': 'asst_lsH8uwS4hrg4v1lRpXm6sdtR', 'object': 'assistant', 'created_at': 1750523048, 'name': 'chat-agent-in-a-team', 'description': None, 'model': 'gpt-4o-mini', 'instructions': ' \nYou are an AI assistant that answers questions about the stored and indexed drone images and objects in search index index02. \nThe data source is an Azure AI Search resource where the schema has JSON description field, a vector field and an id field and this id field must be cited in your answer. \nIf you do not find a match for the query, respond with "I don't know", otherwise cite references with the value of the id field. \n', 'tools': [], 'top_p': 1.0, 'temperature': 1.0, 'tool_resources': {}, 'metadata': {}, 'response_format': 'auto'} {'id': 'asst_JI9VWjdav3To7jjGUROejGkV', 'object': 'assistant', 'created_at': 1750291400, 'name': 'object-search-agent', 'description': None, 'model': 'gpt-4o-mini', 'instructions': '\nYou are an AI assistant that answers questions about the stored and indexed drone images and objects in search index index02.\nThe data source is an Azure AI Search resource where the schema has JSON description field, a vector field and an id field and this id field must be cited in your answer.\nIf you do not find a match for the query, respond with "I don't know", otherwise cite references with the value of the id field.\n', 'tools': [{'type': 'azure_ai_search'}], 'top_p': 1.0, 'temperature': 1.0, 'tool_resources': {'azure_ai_search': {'indexes': [{'index_connection_id': None, 'index_name': None, 'query_type': 'vector_semantic_hybrid', 'top_k': 5, 'filter': None, 'index_asset_id': 'index02/versions/1'}]}}, 'metadata': {}, 'response_format': 'auto'}

#codingexercise: https://1drv.ms/w/c/d609fb70e39b65c8/EYMCYvb9NRtOtcJwdXRDUi0BVzUEyGL-Rz2NKFaKj6KLgA?e=cbtmrO 

No comments:

Post a Comment