(Klicka på bilden ovan för att se videon av denna lektion)
Verktyg är intressanta eftersom de tillåter AI-agenter att ha ett bredare spektrum av möjligheter. Istället för att agenten bara har ett begränsat antal handlingar den kan utföra, kan agenten nu utföra en mängd olika handlingar genom att lägga till ett verktyg. I detta kapitel ska vi titta på designmönstret för verktygsanvändning, som beskriver hur AI-agenter kan använda specifika verktyg för att uppnå sina mål.
I denna lektion söker vi svar på följande frågor:
Efter att ha avslutat denna lektion kommer du att kunna:
Designmönstret för verktygsanvändning fokuserar på att ge LLM:er förmågan att interagera med externa verktyg för att uppnå specifika mål. Verktyg är kod som kan köras av en agent för att utföra handlingar. Ett verktyg kan vara en enkel funktion som en räknare eller ett API-anrop till en tredje parts tjänst som aktiekursuppslag eller väderprognos. I sammanhanget AI-agenter är verktyg designade att köras av agenter som svar på modellgenererade funktionsanrop.
AI-agenter kan använda verktyg för att slutföra komplexa uppgifter, hämta information eller fatta beslut. Designmönstret för verktygsanvändning används ofta i scenarier som kräver dynamisk interaktion med externa system, såsom databaser, webbtjänster eller kodtolkare. Denna förmåga är användbar för en rad olika användningsfall, inklusive:
Dessa byggstenar möjliggör för AI-agenten att utföra ett brett spektrum av uppgifter. Låt oss titta på de viktigaste elementen som behövs för att implementera designmönstret för verktygsanvändning:
Funktions-/verktygsscheman: Detaljerade definitioner av tillgängliga verktyg, inklusive funktionsnamn, syfte, nödvändiga parametrar och förväntade utdata. Dessa scheman gör det möjligt för LLM att förstå vilka verktyg som finns tillgängliga och hur giltiga förfrågningar konstrueras.
Logik för funktionskörning: Styr hur och när verktyg anropas baserat på användarens intention och konversationens kontext. Detta kan inkludera planeringsmoduler, routningsmekanismer eller villkorliga flöden som bestämmer användningen av verktyg dynamiskt.
System för meddelandehantering: Komponenter som hanterar konversationsflödet mellan användarinmatningar, LLM-svar, verktygsanrop och verktygsutdata.
Verktygsintegrationsramverk: Infrastruktur som kopplar agenten till olika verktyg, oavsett om det är enkla funktioner eller komplexa externa tjänster.
Felhantering och validering: Mekanismer för att hantera fel vid verktygskörning, validera parametrar och hantera oväntade svar.
Tillståndshantering: Spårar konversationskontext, tidigare verktygsinteraktioner och persistent data för att säkerställa konsistens över flera interaktioner.
Nästa steg är att titta närmare på Funktions-/Verktygsanrop.
Funktionsanrop är det huvudsakliga sättet vi möjliggör för stora språkmodeller (LLM) att interagera med verktyg. Du kommer ofta att se “funktion” och “verktyg” användas synonymt eftersom “funktioner” (block av återanvändbar kod) är de “verktyg” som agenter använder för att utföra uppgifter. För att en funktionskod ska anropas måste LLM jämföra användarens begäran med funktionens beskrivning. För detta skickas ett schema som innehåller beskrivningar av alla tillgängliga funktioner till LLM. LLM väljer sedan den mest lämpliga funktionen för uppgiften och returnerar dess namn och argument. Den valda funktionen anropas, dess svar skickas tillbaka till LLM, som använder informationen för att svara på användarens förfrågan.
För utvecklare som vill implementera funktionsanrop för agenter krävs:
Låt oss använda exemplet att hämta aktuell tid i en stad för att illustrera:
Initiera en LLM som stödjer funktionsanrop:
Alla modeller stödjer inte funktionsanrop, så det är viktigt att kontrollera att den LLM du använder gör det. Azure OpenAI stödjer funktionsanrop. Vi kan börja med att initiera Azure OpenAI-klienten.
# Initiera Azure OpenAI-klienten
client = AzureOpenAI(
azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT"),
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
api_version="2024-05-01-preview"
)
Skapa ett funktionsschema:
Nästa steg är att definiera ett JSON-schema som innehåller funktionsnamn, en beskrivning av vad funktionen gör och namnen och beskrivningarna av funktionsparametrarna. Vi skickar sedan detta schema till den tidigare skapade klienten, tillsammans med användarens förfrågan att hitta tiden i San Francisco. Viktigt att notera är att ett verktygsanrop är vad som returneras, inte det slutgiltiga svaret på frågan. Som nämnts tidigare returnerar LLM namnet på den funktion som valts för uppgiften och argumenten som kommer att skickas till den.
# Funktionsbeskrivning för modellen att läsa
tools = [
{
"type": "function",
"function": {
"name": "get_current_time",
"description": "Get the current time in a given location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city name, e.g. San Francisco",
},
},
"required": ["location"],
},
}
}
]
# Inledande användarmeddelande
messages = [{"role": "user", "content": "What's the current time in San Francisco"}]
# Första API-anropet: Be modellen använda funktionen
response = client.chat.completions.create(
model=deployment_name,
messages=messages,
tools=tools,
tool_choice="auto",
)
# Bearbeta modellens svar
response_message = response.choices[0].message
messages.append(response_message)
print("Model's response:")
print(response_message)
Model's response:
ChatCompletionMessage(content=None, role='assistant', function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_pOsKdUlqvdyttYB67MOj434b', function=Function(arguments='{"location":"San Francisco"}', name='get_current_time'), type='function')])
Funktionskoden som krävs för att utföra uppgiften:
Nu när LLM har valt vilken funktion som ska köras måste koden som utför uppgiften implementeras och köras. Vi kan implementera koden för att hämta aktuell tid i Python. Vi behöver också skriva kod för att extrahera namn och argument från response_message för att få slutresultatet.
def get_current_time(location):
"""Get the current time for a given location"""
print(f"get_current_time called with location: {location}")
location_lower = location.lower()
for key, timezone in TIMEZONE_DATA.items():
if key in location_lower:
print(f"Timezone found for {key}")
current_time = datetime.now(ZoneInfo(timezone)).strftime("%I:%M %p")
return json.dumps({
"location": location,
"current_time": current_time
})
print(f"No timezone data found for {location_lower}")
return json.dumps({"location": location, "current_time": "unknown"})
# Hantera funktionsanrop
if response_message.tool_calls:
for tool_call in response_message.tool_calls:
if tool_call.function.name == "get_current_time":
function_args = json.loads(tool_call.function.arguments)
time_response = get_current_time(
location=function_args.get("location")
)
messages.append({
"tool_call_id": tool_call.id,
"role": "tool",
"name": "get_current_time",
"content": time_response,
})
else:
print("No tool calls were made by the model.")
# Andra API-anropet: Hämta det slutgiltiga svaret från modellen
final_response = client.chat.completions.create(
model=deployment_name,
messages=messages,
)
return final_response.choices[0].message.content
get_current_time called with location: San Francisco
Timezone found for san francisco
The current time in San Francisco is 09:24 AM.
Funktionsanrop står i centrum för det mesta, om inte all, agentverktygsanvändning, men att implementera det från grunden kan ibland vara utmanande. Som vi lärde oss i Lektion 2 erbjuder agentramverk färdigbyggda byggstenar för att implementera verktygsanvändning.
Här är några exempel på hur du kan implementera designmönstret för verktygsanvändning med olika agentramverk:
Semantic Kernel är ett open-source AI-ramverk för .NET-, Python- och Java-utvecklare som arbetar med stora språkmodeller (LLM). Det förenklar processen att använda funktionsanrop genom att automatiskt beskriva dina funktioner och deras parametrar till modellen genom en process kallad serialisering. Det hanterar också kommunikationen fram och tillbaka mellan modellen och din kod. En annan fördel med att använda ett agentramverk som Semantic Kernel är att det tillåter dig att få tillgång till förbyggda verktyg som Fil sökning och Kodtolkare.
Följande diagram illustrerar processen för funktionsanrop med Semantic Kernel:

I Semantic Kernel kallas funktioner/verktyg Plugins. Vi kan konvertera get_current_time funktionen vi såg tidigare till ett plugin genom att göra den till en klass med funktionen i sig. Vi kan också importera kernel_function-dekorationen, som tar in beskrivningen av funktionen. När du sedan skapar en kernel med GetCurrentTimePlugin, serialiserar kärnan automatiskt funktionen och dess parametrar och skapar schemat att skicka till LLM i processen.
from semantic_kernel.functions import kernel_function
class GetCurrentTimePlugin:
async def __init__(self, location):
self.location = location
@kernel_function(
description="Get the current time for a given location"
)
def get_current_time(location: str = ""):
...
from semantic_kernel import Kernel
# Skapa kärnan
kernel = Kernel()
# Skapa pluginet
get_current_time_plugin = GetCurrentTimePlugin(location)
# Lägg till pluginet i kärnan
kernel.add_plugin(get_current_time_plugin)
Azure AI Agent Service är ett nyare agentramverk som är utformat för att möjliggöra för utvecklare att säkert bygga, distribuera och skala högkvalitativa och utbyggbara AI-agenter utan att behöva hantera underliggande beräkning och lagringsresurser. Det är särskilt användbart för företagsapplikationer eftersom det är en helt hanterad tjänst med företagsklassad säkerhet.
Jämfört med att utveckla direkt med LLM-API:n erbjuder Azure AI Agent Service flera fördelar, inklusive:
Verktygen som är tillgängliga i Azure AI Agent Service kan delas in i två kategorier:
Agenttjänsten låter oss använda dessa verktyg tillsammans som ett toolset. Den använder också threads som håller reda på historiken av meddelanden från en viss konversation.
Föreställ dig att du är en försäljningsagent på ett företag som heter Contoso. Du vill utveckla en konversationsagent som kan svara på frågor om dina försäljningsdata.
Följande bild illustrerar hur du kan använda Azure AI Agent Service för att analysera dina försäljningsdata:

För att använda något av dessa verktyg med tjänsten kan vi skapa en klient och definiera ett verktyg eller toolset. För att implementera detta praktiskt kan vi använda följande Python-kod. LLM kommer att kunna titta på toolsetet och avgöra om den ska använda den användarskapade funktionen fetch_sales_data_using_sqlite_query eller den förbyggda Kodtolkaren beroende på användarens förfrågan.
import os
from azure.ai.projects import AIProjectClient
from azure.identity import DefaultAzureCredential
from fetch_sales_data_functions import fetch_sales_data_using_sqlite_query # fetch_sales_data_using_sqlite_query-funktion som finns i en fil som heter fetch_sales_data_functions.py.
from azure.ai.projects.models import ToolSet, FunctionTool, CodeInterpreterTool
project_client = AIProjectClient.from_connection_string(
credential=DefaultAzureCredential(),
conn_str=os.environ["PROJECT_CONNECTION_STRING"],
)
# Initiera verktygsuppsättning
toolset = ToolSet()
# Initiera funktionsanropsagent med funktionen fetch_sales_data_using_sqlite_query och lägg till den i verktygsuppsättningen
fetch_data_function = FunctionTool(fetch_sales_data_using_sqlite_query)
toolset.add(fetch_data_function)
# Initiera Code Interpreter-verktyget och lägg till det i verktygsuppsättningen.
code_interpreter = code_interpreter = CodeInterpreterTool()
toolset.add(code_interpreter)
agent = project_client.agents.create_agent(
model="gpt-4o-mini", name="my-agent", instructions="You are helpful agent",
toolset=toolset
)
En vanlig oro med SQL som genereras dynamiskt av LLM är säkerhet, särskilt risken för SQL-injektion eller skadliga åtgärder, såsom att ta bort eller manipulera databasen. Även om dessa farhågor är giltiga kan de effektivt mildras genom att korrekt konfigurera databasåtkomsträttigheter. För de flesta databaser innebär detta att konfigurera databasen som skrivskyddad. För databastjänster som PostgreSQL eller Azure SQL bör applikationen tilldelas en skrivskyddad (SELECT) roll. Att köra appen i en säker miljö förbättrar skyddet ytterligare. I företagsmiljöer extraheras och transformeras data vanligtvis från operativa system till en skrivskyddad databas eller datalager med ett användarvänligt schema. Denna metod säkerställer att data är säker, optimerad för prestanda och åtkomlighet, samt att appen har begränsad, skrivskyddad åtkomst.
Join the Azure AI Foundry Discord to meet with other learners, attend office hours and get your AI Agents questions answered.
Understanding Agentic Design Patterns
Ansvarsfriskrivning: Detta dokument har översatts med hjälp av AI-översättningstjänsten Co-op Translator. Även om vi strävar efter noggrannhet, bör du vara medveten om att automatiska översättningar kan innehålla fel eller brister. Det ursprungliga dokumentet på dess modersmål bör betraktas som den auktoritativa källan. För kritisk information rekommenderas professionell mänsklig översättning. Vi ansvarar inte för eventuella missförstånd eller feltolkningar som uppstår vid användning av denna översättning.