(Klicken Sie auf das obige Bild, um das Video zu dieser Lektion anzusehen)
Werkzeuge sind interessant, weil sie KI-Agenten eine breitere Palette von Fähigkeiten ermöglichen. Anstatt dass der Agent nur eine begrenzte Anzahl von Aktionen ausführen kann, kann er durch Hinzufügen eines Werkzeugs nun eine Vielzahl von Aktionen durchführen. In diesem Kapitel betrachten wir das Designmuster für Werkzeugnutzung, das beschreibt, wie KI-Agenten bestimmte Werkzeuge nutzen können, um ihre Ziele zu erreichen.
In dieser Lektion möchten wir die folgenden Fragen beantworten:
Nach Abschluss dieser Lektion werden Sie in der Lage sein:
Das Designmuster für Werkzeugnutzung konzentriert sich darauf, LLMs die Fähigkeit zu geben, mit externen Werkzeugen zu interagieren, um spezifische Ziele zu erreichen. Werkzeuge sind Code, der von einem Agenten ausgeführt werden kann, um Aktionen durchzuführen. Ein Werkzeug kann eine einfache Funktion wie ein Taschenrechner sein oder ein API-Aufruf zu einem Drittanbieterdienst, wie zum Beispiel eine Abfrage des Aktienkurses oder einer Wettervorhersage. Im Kontext von KI-Agenten sind Werkzeuge so konzipiert, dass sie als Antwort auf modellgenerierte Funktionsaufrufe ausgeführt werden.
KI-Agenten können Werkzeuge nutzen, um komplexe Aufgaben zu erledigen, Informationen abzurufen oder Entscheidungen zu treffen. Das Designmuster für Werkzeugnutzung wird häufig in Szenarien verwendet, die eine dynamische Interaktion mit externen Systemen erfordern, wie Datenbanken, Webdienste oder Code-Interpreter. Diese Fähigkeit ist für verschiedene Anwendungsfälle nützlich, darunter:
Diese Bausteine ermöglichen dem KI-Agenten eine breite Palette von Aufgaben auszuführen. Betrachten wir die zentralen Elemente, die zur Implementierung des Designmusters für Werkzeugnutzung nötig sind:
Funktions-/Werkzeugschemata: Detaillierte Definitionen verfügbarer Werkzeuge, einschließlich Funktionsname, Zweck, erforderliche Parameter und erwartete Ausgaben. Diese Schemata ermöglichen es dem LLM zu verstehen, welche Werkzeuge verfügbar sind und wie gültige Anfragen konstruiert werden.
Logik zur Funktionausführung: Bestimmt, wie und wann Werkzeuge basierend auf der Nutzerabsicht und dem Gesprächskontext aufgerufen werden. Dies kann Planungsmodule, Routing-Mechanismen oder bedingte Abläufe umfassen, die die Werkzeugnutzung dynamisch steuern.
Nachrichtenverwaltungssystem: Komponenten, die den Gesprächsfluss zwischen Nutzereingaben, LLM-Antworten, Werkzeugaufrufen und Werkzeugausgaben steuern.
Werkzeugintegrationsframework: Infrastruktur, die den Agenten mit verschiedenen Werkzeugen verbindet, sei es einfache Funktionen oder komplexe externe Dienste.
Fehlerbehandlung & Validierung: Mechanismen zur Handhabung von Fehlern bei der Werkzeugausführung, Validierung von Parametern und Umgang mit unerwarteten Antworten.
Zustandsverwaltung: Verfolgt den Gesprächskontext, vorherige Werkzeuginteraktionen und persistente Daten, um Konsistenz über mehrstufige Interaktionen hinweg zu gewährleisten.
Im Folgenden betrachten wir den Funktions-/Werkzeugaufruf im Detail.
Funktionsaufrufe sind der Hauptweg, wie wir Large Language Models (LLMs) ermöglichen, mit Werkzeugen zu interagieren. Oft sieht man ‘Funktion’ und ‘Werkzeug’ synonym verwendet, weil ‘Funktionen’ (wiederverwendbare Codeblöcke) die ‘Werkzeuge’ sind, die Agenten zur Erledigung von Aufgaben verwenden. Damit der Code einer Funktion aufgerufen werden kann, muss das LLM die Nutzeranfrage mit der Funktionsbeschreibung abgleichen. Dazu wird ein Schema mit den Beschreibungen aller verfügbaren Funktionen an das LLM gesendet. Das LLM wählt daraufhin die am besten geeignete Funktion für die Aufgabe aus und liefert deren Namen und Argumente zurück. Die ausgewählte Funktion wird ausgeführt, deren Antwort an das LLM zurückgesendet, das die Informationen nutzt, um auf die Nutzeranfrage zu antworten.
Damit Entwickler Funktionsaufrufe für Agenten implementieren können, benötigen Sie:
Nutzen wir das Beispiel, um die aktuelle Uhrzeit in einer Stadt zu erhalten:
Initialisieren Sie ein LLM, das Funktionsaufrufe unterstützt:
Nicht alle Modelle unterstützen Funktionsaufrufe, daher ist es wichtig zu prüfen, ob Ihr LLM dies tut. Azure OpenAI unterstützt Funktionsaufrufe. Wir können damit beginnen, den OpenAI-Client gegen die Azure OpenAI Responses API zu starten (den stabilen /openai/v1/ Endpunkt — kein api_version benötigt).
# Initialize the OpenAI client for Azure OpenAI (Responses API, v1 endpoint)
client = OpenAI(
base_url=f"{os.environ['AZURE_OPENAI_ENDPOINT'].rstrip('/')}/openai/v1/",
api_key=os.environ["AZURE_OPENAI_API_KEY"],
)
deployment_name = os.environ["AZURE_OPENAI_DEPLOYMENT"]
Erstellen Sie ein Funktionsschema:
Als nächstes definieren wir ein JSON-Schema, das den Funktionsnamen, eine Beschreibung dessen, was die Funktion tut, sowie Namen und Beschreibungen der Funktionsparameter enthält. Wir werden dieses Schema zusammen mit der Nutzeranfrage zur Uhrzeit in San Francisco an den zuvor erstellten Client übergeben. Wichtig zu beachten ist, dass ein Werkzeugaufruf, nicht die endgültige Antwort auf die Frage, zurückgegeben wird. Wie zuvor erwähnt, liefert das LLM den Namen der für die Aufgabe ausgewählten Funktion und die an sie übergebenen Argumente.
# Function description for the model to read (Responses API flat tool format)
tools = [
{
"type": "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"],
},
}
]
# Initial user message
messages = [{"role": "user", "content": "What's the current time in San Francisco"}]
# First API call: Ask the model to use the function
response = client.responses.create(
model=deployment_name,
input=messages,
tools=tools,
tool_choice="auto",
store=False,
)
# The Responses API returns tool calls as function_call items in response.output.
# Append them to the conversation so the model has full context on the next turn.
messages += response.output
print("Model's response:")
print(response.output)
Model's response:
[ResponseFunctionToolCall(arguments='{"location":"San Francisco"}', call_id='call_pOsKdUlqvdyttYB67MOj434b', name='get_current_time', type='function_call')]
Der Code der Funktion, der die Aufgabe ausführt:
Nachdem das LLM entschieden hat, welche Funktion ausgeführt werden muss, ist der Code zu implementieren und auszuführen, der die Aufgabe erledigt. Wir können den Code in Python schreiben, um die aktuelle Zeit zu erhalten. Außerdem müssen wir den Code schreiben, der den Funktionsnamen und die Argumente aus der Antwortnachricht extrahiert, um das endgültige Ergebnis zu erhalten.
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"})
# Handle function calls
tool_calls = [item for item in response.output if item.type == "function_call"]
if tool_calls:
for tool_call in tool_calls:
if tool_call.name == "get_current_time":
function_args = json.loads(tool_call.arguments)
time_response = get_current_time(
location=function_args.get("location")
)
# Return the tool result as a function_call_output item
messages.append({
"type": "function_call_output",
"call_id": tool_call.call_id,
"output": time_response,
})
else:
print("No tool calls were made by the model.")
# Second API call: Get the final response from the model
final_response = client.responses.create(
model=deployment_name,
input=messages,
tools=tools,
store=False,
)
return final_response.output_text
get_current_time called with location: San Francisco
Timezone found for san francisco
The current time in San Francisco is 09:24 AM.
Funktionsaufrufe sind das Herzstück der meisten, wenn nicht aller, Designs für Werkzeugnutzung bei Agenten, ihre Implementierung kann jedoch manchmal herausfordernd sein. Wie wir in Lektion 2 gelernt haben, bieten agentische Frameworks vorgefertigte Bausteine zur Implementierung von Werkzeugnutzung.
Hier einige Beispiele, wie Sie das Designmuster für Werkzeugnutzung mit verschiedenen agentischen Frameworks umsetzen können:
Microsoft Agent Framework ist ein Open-Source-KI-Framework zum Aufbau von KI-Agenten. Es vereinfacht die Nutzung von Funktionsaufrufen, indem es Ihnen erlaubt, Werkzeuge als Python-Funktionen mit dem @tool Dekorator zu definieren. Das Framework übernimmt die Kommunikation zwischen dem Modell und Ihrem Code. Es stellt auch vorgefertigte Werkzeuge wie die Dateisuche und den Code Interpreter über FoundryChatClient bereit.
Das folgende Diagramm zeigt den Prozess der Funktionsaufrufe mit dem Microsoft Agent Framework:

Im Microsoft Agent Framework werden Werkzeuge als dekorierte Funktionen definiert. Wir können die zuvor gezeigte get_current_time Funktion in ein Werkzeug umwandeln, indem wir den @tool Dekorator verwenden. Das Framework serialisiert die Funktion und ihre Parameter automatisch und erstellt das Schema, das an das LLM gesendet wird.
import os
from agent_framework import tool
from agent_framework.foundry import FoundryChatClient
from azure.identity import AzureCliCredential
@tool(approval_mode="never_require")
def get_current_time(location: str) -> str:
"""Get the current time for a given location"""
...
# Create the client
provider = FoundryChatClient(
project_endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
credential=AzureCliCredential(),
)
# Create an agent and run with the tool
agent = provider.as_agent(name="TimeAgent", instructions="Use available tools to answer questions.", tools=get_current_time)
response = await agent.run("What time is it?")
Werkzeuge müssen keine Funktionen in Ihrem eigenen Code sein. Ein Server, der das Model Context Protocol (MCP, behandelt in Lektion 11) spricht, veröffentlicht seine Werkzeuge zusammen mit deren Schemata, und das Framework kann diese laden, als ob es eine dekorierte Funktion serialisiert. MCPStreamableHTTPTool verbindet sich über HTTP mit einem solchen Server, liest die Werkzeugschemata und bietet sie dem Modell neben lokalen Werkzeugen an.
Das folgende Beispiel nutzt den Websuche-Server von Keenable. Er ist kostenlos nutzbar ohne Konto oder API-Schlüssel (Anfragen werden pro IP limitiert), sodass Sie nur die Zugangsdaten für Ihr Modell benötigen. Wie bei jedem externen Werkzeug werden die vom Modell geschriebenen Anfragen an diesen Server gesendet.
from agent_framework import MCPStreamableHTTPTool
web_search = MCPStreamableHTTPTool(
name="Keenable web search",
url="https://api.keenable.ai/mcp",
)
# Connecting loads the server's tool schemas; the agent decides when to call them
async with web_search:
agent = provider.as_agent(
name="ResearchAgent",
instructions="Use available tools to answer questions.",
tools=[web_search],
)
response = await agent.run("What is new in the latest Python release?")
print(response.text)
Der Server veröffentlicht zwei Werkzeuge, search_web_pages und fetch_page_content. Wenn aktuelle Informationen benötigt werden, ruft das Modell search_web_pages auf, erhält Titel, URLs und Textausschnitte zurück und schreibt seine Antwort daraus, ähnlich der Schleife im get_current_time Beispiel oben.
Microsoft Foundry Agent Service ist ein neueres agentisches Framework, das Entwicklern ermöglicht, sicher und erweiterbar hochwertige KI-Agenten zu bauen, bereitzustellen und zu skalieren, ohne die zugrunde liegenden Rechen- und Speicherressourcen verwalten zu müssen. Es ist besonders für Unternehmensanwendungen nützlich, da es ein vollständig verwalteter Service mit Sicherheitsstandards auf Unternehmensebene ist.
Im Vergleich zur direkten Entwicklung mit der LLM-API bietet der Microsoft Foundry Agent Service einige Vorteile, einschließlich:
Die im Microsoft Foundry Agent Service verfügbaren Werkzeuge lassen sich in zwei Kategorien einteilen:
Der Agent Service ermöglicht uns, diese Werkzeuge zusammen als toolset zu verwenden. Er nutzt auch threads, welche den Nachrichtenverlauf eines bestimmten Gesprächs verfolgen.
Stellen Sie sich vor, Sie sind Vertriebsmitarbeiter bei einer Firma namens Contoso. Sie möchten einen Gesprächsagenten entwickeln, der Fragen zu Ihren Vertriebsdaten beantworten kann.
Das folgende Bild zeigt, wie Sie Microsoft Foundry Agent Service zur Analyse Ihrer Vertriebsdaten nutzen könnten:

Um eines dieser Werkzeuge mit dem Service zu nutzen, können wir einen Client erstellen und ein Werkzeug oder Werkzeugset definieren. Für die praktische Umsetzung können wir den folgenden Python-Code verwenden. Das LLM kann dann das Werkzeugset analysieren und je nach Nutzeranfrage entscheiden, ob die benutzerdefinierte Funktion fetch_sales_data_using_sqlite_query oder der vorgefertigte Code Interpreter verwendet wird.
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 function which can be found in a fetch_sales_data_functions.py file.
from azure.ai.projects.models import ToolSet, FunctionTool, CodeInterpreterTool
project_client = AIProjectClient.from_connection_string(
credential=DefaultAzureCredential(),
conn_str=os.environ["PROJECT_CONNECTION_STRING"],
)
# Initialize toolset
toolset = ToolSet()
# Initialize function calling agent with the fetch_sales_data_using_sqlite_query function and adding it to the toolset
fetch_data_function = FunctionTool(fetch_sales_data_using_sqlite_query)
toolset.add(fetch_data_function)
# Initialize Code Interpreter tool and adding it to the toolset.
code_interpreter = CodeInterpreterTool()toolset.add(code_interpreter)
agent = project_client.agents.create_agent(
model="gpt-5-mini", name="my-agent", instructions="You are helpful agent",
toolset=toolset
)
Ein häufiges Anliegen bei von LLMs dynamisch generiertem SQL ist die Sicherheit, insbesondere das Risiko von SQL-Injektionen oder böswilligen Aktionen wie das Löschen oder Manipulieren der Datenbank. Obwohl diese Bedenken berechtigt sind, können sie durch richtig konfigurierte Datenbankzugriffsrechte effektiv gemindert werden. Für die meisten Datenbanken bedeutet dies, die Datenbank als schreibgeschützt zu konfigurieren. Für Datenbankdienste wie PostgreSQL oder Azure SQL sollte die App eine schreibgeschützte (SELECT) Rolle zugewiesen bekommen.
Die Ausführung der App in einer sicheren Umgebung erhöht den Schutz zusätzlich. In Unternehmensszenarien werden Daten typischerweise aus operativen Systemen extrahiert und in eine schreibgeschützte Datenbank oder ein Data Warehouse mit einem benutzerfreundlichen Schema transformiert. Dieser Ansatz stellt sicher, dass die Daten sicher sind, für Leistung und Zugänglichkeit optimiert sind und dass die App eingeschränkten, schreibgeschützten Zugriff hat.
Treten Sie dem Microsoft Foundry Discord bei, um andere Lernende zu treffen, an Sprechstunden teilzunehmen und Ihre Fragen zu KI-Agenten beantwortet zu bekommen.
Nachdem Sie gelernt haben, Agenten in Lektion 16 bereitzustellen, können Sie den TravelToolAgent dieser Lektion mit tests/lesson-04-smoke-tests.json smoke-testen (ruft er seine Tools noch auf und antwortet er?). Siehe tests/README.md für die Ausführung.
Verstehen agentischer Designmuster
Haftungsausschluss: Dieses Dokument wurde mit dem KI-Übersetzungsdienst Co-op Translator übersetzt. Obwohl wir uns um Genauigkeit bemühen, beachten Sie bitte, dass automatisierte Übersetzungen Fehler oder Ungenauigkeiten enthalten können. Das Originaldokument in seiner Ursprungssprache gilt als maßgebliche Quelle. Bei kritischen Informationen wird eine professionelle menschliche Übersetzung empfohlen. Wir übernehmen keine Haftung für Missverständnisse oder Fehlinterpretationen, die aus der Verwendung dieser Übersetzung entstehen.