Voraussetzungen
Bei der Gestaltung moderner KI-Infrastruktur ist die erste große Weggabelung immer die Hardware. Es geht hier nicht nur darum, einen Cloud-Anbieter auszuwählen; es ist eine strategische Investition in Rechenleistung, die die gesamte Kostenstruktur und das Leistungsprofil eines KI-Dienstes bestimmt. Die Wahl zwischen General Processing Units (GPUs) und spezialisierten Chips wie Neural Processing Units (NPUs) kann den Unterschied zwischen einer profitablen Anwendung und einer unhaltbaren ausmachen.
Die Navigation in diesem „Hardware-Krieg“ bedeutet, rohe Rechenleistung mit Kosteneffizienz in Einklang zu bringen. Wir werden untersuchen, warum NVIDIAs GPU-Architekturen weiterhin das Training großer Modelle dominieren und warum kundenspezifische Chips den Inferenz-Kampf um Effizienz entschieden gewinnen. Mein Ziel ist es, eine klare Entscheidungsmatrix zu liefern, wann man bei GPUs für das Fine-Tuning bleiben sollte und wann man NPUs für die echtzeitnahen, agentischen Workflows einsetzen sollte, die die nächste Welle der KI definieren.
Um die Konzepte zu verfolgen und das Beispiel eines agentischen Workflows zu implementieren, benötigen Sie einige eingerichtete Dinge. Alle Infrastrukturbeispiele gehen von europäischen Regionen aus.
- Python 3.12+: Unser Anwendungscode verwendet moderne Python-Funktionen.
- Cloud CLIs: Sie benötigen Anmeldeinformationen, die für Ihre gewählte Cloud konfiguriert sind. Ich stelle Beispiele für Google Cloud und Azure bereit.
- Google Cloud SDK:
gcloud init
gcloud config set project your-gcp-project-id
gcloud config set compute/region europe-west1
* **Azure CLI**:
az login
az configure --defaults group=your-azure-resource-group location=westeurope
- Python Bibliotheken: Wir werden den OpenAI-Client für seine Tool-Calling-Funktionen verwenden, der eine großartige Abstraktion für die Erstellung von Agenten bietet, unabhängig von der endgültigen Bereitstellungsplattform.
pip install openai pydantic
Architektur und Konzepte
Die KI-Hardwarelandschaft lässt sich am besten verstehen, indem man die Arbeit in ihre zwei unterschiedlichen Phasen aufteilt: Training und Inferenz. Ihre architektonischen Entscheidungen für jede Phase werden dramatisch unterschiedlich sein.
Die Trainings-Mauer: NVIDIAs anhaltende Herrschaft
In den letzten zehn Jahren, wenn Sie ein groß angelegtes KI-Modell trainiert haben, haben Sie GPUs verwendet. Für Modelle mit Milliarden oder sogar Billionen von Parametern hat sich diese Realität nicht geändert. NVIDIAs Blackwell-Architektur und ihre Vorgänger bleiben die unbestrittenen Könige des Trainings-Clusters.
Der Grund ist einfach: Training, mit Algorithmen wie Backpropagation, erfordert massive, allgemeine parallele Berechnungen. Es ist eine Übung in brachialen Gleitkommaoperationen über riesige Datensätze hinweg, und die Tausenden von Kernen einer GPU sind genau dafür gebaut. Wenn ich Infrastruktur für das Fine-Tuning proprietärer Modelle bereitstelle, spezifiziere ich immer Cluster von NVIDIA-GPUs, sei es auf Googles Vertex AI oder Azure Machine Learning. Für Modelle mit mehr als Hunderten von Milliarden Parametern sind die Reife und Leistung des GPU-Stacks immer noch unübertroffen.
Die versteckten Kosten der Parallelität
Während GPUs bei parallelen Aufgaben hervorragend sind, können Orchestrierungs-Overhead und Speicherbandbreite zu Engpässen werden. Die 'Dekodierungsphase' der Token-Generierung in agentenbasierter KI erfordert beispielsweise eine signifikante Datenübertragung. Hier beginnt spezialisierte Hardware, die Allzweck-Natur der GPU herauszufordern, insbesondere für die Inferenz.
Der Aufstieg der NPU: Den Inferenz-Kampf gewinnen
Sobald ein Modell trainiert ist, ändert sich das Spiel komplett. Das Ziel verschiebt sich von roher Leistung zu Effizienz, Latenz und Kosten pro Abfrage. Hier machen Neural Processing Units (NPUs) und andere kundenspezifische Chips wie Groqs Language Processing Units (LPUs) einen massiven Unterschied.
NPUs sind speziell für die Kernoperationen der neuronalen Netzinferenz konzipiert – Matrizenmultiplikationen, Faltung und Aktivierungen. Diese Spezialisierung ermöglicht ihnen erstaunliche Effizienzgewinne. Einige Benchmarks und reale Ergebnisse zeigen wettbewerbsfähige Leistung und Stromkosten im Vergleich zu GPUs für denselben Inferenz-Workload. Googles TPUs waren hierfür jahrelang das Paradebeispiel, und der Rest des Marktes holt jetzt schnell auf.
Dies ist am wichtigsten für die echtzeitnahen, agentischen Workflows, die immer häufiger werden. Ein KI-Agent, der autonom externe Tools aufrufen, eine Datenbank abfragen oder einen mehrstufigen Prozess orchestrieren kann, benötigt geringe Latenz und hohen Durchsatz. Das Diagramm unten zeigt, wie diese beiden Welten abgebildet werden können.
Diese Arbeitsteilung ist der Schlüssel zum Aufbau einer kostengünstigen KI-Plattform. Und wenn Sie sich für die finanzielle Seite dieser Verschiebung interessieren, habe ich eine technische Analyse im Marktbereich des Blogs verfasst: Jenseits der GPU: Warum 2026 das Jahr des NPU-Trades ist.
Modell-Governance in der Produktion
Unabhängig von der Hardware erfordert der Einsatz agentischer Modelle in der Produktion eine strenge Governance. Eine Bereitstellungscheckliste umfasst immer:
- Versionskontrolle: Jedes Modell wird in einem Register wie Vertex AI Model Registry oder dem Äquivalent von Azure Machine Learning versioniert und überprüfbar.
- Containerisierung: Modelle werden in Container-Images verpackt, die mit Sigstore/Cosign signiert und auf Schwachstellen gescannt werden, um eine sichere Lieferkette zu gewährleisten.
- Audit-Logging: Alle Inferenzanfragen, Tool-Aufrufe und Agentenentscheidungen werden für Compliance, Sicherheitsüberwachung und Fehlerbehebung protokolliert.
- Zugriffskontrolle: Strikte IAM-Richtlinien regeln, wer und was Modell-Endpoints aufrufen und auf die zugrunde liegenden Daten zugreifen darf.
Mit diesem architektonischen Kontext kommen wir zur Entscheidung selbst.
Architektonisches Urteil: Eine Entscheidungsmatrix für Praktiker
So teile ich die Wahl basierend auf den Workload-Eigenschaften auf:
-
Wenn Sie echtzeitnahe „Agentic“-Workflows ausführen, wählen Sie NPUs. Wenn Latenz im Sub-Sekundenbereich und hohe Effizienz für die Benutzererfahrung oder die operative Automatisierung entscheidend sind, ist die NPU Ihr Weg zu besseren Margen. Die Bereitstellung von Inferenz-Workloads auf NPU-optimierten Plattformen (wie Googles TPUs oder aufkommende serverless LPU/NPU-Angebote) wird Ihre Betriebskosten drastisch senken und die Leistung verbessern.
-
Wenn Sie proprietäre Modelle feinabstimmen, bleiben Sie beim GPU-Stack. Auf absehbare Zeit, insbesondere für massive Modelle oder kontinuierliche Umschulungspipelines, bieten NVIDIAs Architekturen die kostengünstigste Lösung für die rohe parallele Berechnung, die für das Training erforderlich ist. Nutzen Sie verwaltete Dienste, die dedizierte GPU-Cluster bereitstellen, um Trainingsjobs zu optimieren.
Dies ist kein Entweder-Oder-Dilemma; es ist ein Mandat für strategische Ressourcenallokation. Das Training findet auf einem Stack statt, und das Serving auf einem anderen, hochspezialisierten Stack.
Implementierungsleitfaden: Aufbau eines agentischen Workflows
Der Kern eines agentischen Workflows besteht darin, einem LLM die intelligente Nutzung externer Tools zu ermöglichen. Ich werde Ihnen zeigen, wie ich diese Tools mit Python und Pydantic definiere und sie dann in einen Inferenzfluss mit dem openai-Client integriere. Dieses Muster ist portabel und kann auf jeder NPU-optimierten Plattform bereitgestellt werden.
Zuerst benötigen wir eine Möglichkeit, unsere Tools dem Modell zu beschreiben. Pydantic ist perfekt dafür, da es ein klares, typisiertes Schema erstellt, das das Modell verstehen kann.
1. Definieren des Agenten-Tools mit Pydantic
Hier erstelle ich ein Query-Tool, das ein Agent verwenden kann, um mit einer Datenbank zu interagieren. Die Field-Beschreibungen sind entscheidend – sie sind die Dokumentation, die das LLM verwendet, um zu verstehen, wie Ihre Funktion aufgerufen wird.
# query_tool.py
from enum import Enum
from typing import List, Union, Optional
from pydantic import BaseModel, Field
class Table(str, Enum):
orders = "orders"
customers = "customers"
products = "products"
class Column(str, Enum):
id = "id"
status = "status"
expected_delivery_date = "expected_delivery_date"
delivered_at = "delivered_at"
shipped_at = "shipped_at"
ordered_at = "ordered_at"
canceled_at = "canceled_at"
customer_name = "customer_name"
class Operator(str, Enum):
eq = "="
gt = ">"
lt = "<"
le = "<="
ge = ">="
ne = "!="
class DynamicValue(BaseModel):
"""A dynamic value that refers to another column."""
column_name: str
class Condition(BaseModel):
column: Column
operator: Operator
value: Union[str, int, DynamicValue]
class OrderBy(str, Enum):
asc = "asc"
desc = "desc"
class Query(BaseModel):
"""Query a database table."""
table_name: Table = Field(description="The name of the database table to query.")
columns: List[Column] = Field(description="A list of columns to select from the table.")
conditions: List[Condition] = Field(default_factory=list, description="Optional list of conditions to filter the results.")
order_by: Optional[OrderBy] = Field(default=OrderBy.desc, description="The order by which to sort results.")
limit: int = Field(default=10, description="The maximum number of rows to return.")
# In a real application, this function would connect to a database and execute the query.
def execute_query(query: Query) -> List[dict]:
"""Simulates executing a database query based on the Pydantic model."""
print(f"--- Executing Query ---")
print(query.model_dump_json(indent=2))
print(f"-----------------------")
# This is a mock response for a specific, simple query.
if query.table_name == Table.customers and Column.customer_name in query.columns and query.limit == 5:
return [
{"customer_name": "Alpha Corp"},
{"customer_name": "Beta Labs"},
{"customer_name": "Gamma Ltd"},
{"customer_name": "Delta Inc"},
{"customer_name": "Epsilon Co"}
]
# Return an empty list for any other query to simulate no results found.
return []
2. Integrieren des Tools mit dem OpenAI-Client
Als Nächstes schreibe ich die Agenten-Schleife. Sie macht einen ersten Aufruf an das LLM, um zu entscheiden, welches Tool verwendet werden soll, führt das Tool aus und macht dann einen zweiten Aufruf mit den Ergebnissen des Tools, um eine endgültige, menschenlesbare Antwort zu erhalten. Dieser zweistufige Prozess ist grundlegend für agentisches Verhalten.
Da die Standard-openai-Bibliothek ein JSON-Schema für Tools benötigt, erstelle ich einen kleinen Helfer, um unser Pydantic-Modell zu konvertieren.
# agent_app.py
import openai
import json
from openai.types.chat.completion_create_params import Tool
from pydantic import BaseModel
from query_tool import Query, execute_query, Column, Table, Operator, Condition, DynamicValue
# Helper to convert a Pydantic model to the OpenAI tool format
def pydantic_to_tool(model: type[BaseModel]) -> Tool:
schema = model.model_json_schema()
return {
"type": "function",
"function": {
"name": schema["title"],
"description": schema.get("description", ""),
"parameters": schema
}
}
# Initialize the client. Ensure the OPENAI_API_KEY environment variable is set.
client = openai.OpenAI()
def run_agentic_workflow(user_prompt: str) -> str:
messages = [
{"role": "system", "content": "You are a helpful assistant. The current date is March 31, 2026. You help users query data by calling the Query tool."},
{"role": "user", "content": user_prompt},
]
tools = [pydantic_to_tool(Query)]
try:
# First call: Let the LLM decide which tool to use.
first_response = client.chat.completions.parse(
model="gpt-4o",
messages=messages,
tools=tools,
)
response_message = first_response.choices[0].message
tool_calls = response_message.tool_calls
if not tool_calls:
return response_message.content or "I was unable to process your request."
# Append the assistant's decision to call a tool to the message history.
messages.append(response_message)
# Execute the tool calls.
for tool_call in tool_calls:
if tool_call.function.name == "Query":
try:
arguments = json.loads(tool_call.function.arguments)
query_instance = Query(**arguments)
tool_output = execute_query(query_instance)
messages.append(
{
"tool_call_id": tool_call.id,
"role": "tool",
"name": "Query",
"content": json.dumps(tool_output),
}
)
except (json.JSONDecodeError, TypeError) as e:
return f"Error parsing tool arguments: {e}"
# Second call: Provide the tool output to the LLM to generate a final response.
final_response = client.chat.completions.parse(
model="gpt-4o",
messages=messages,
)
return final_response.choices[0].message.content
except Exception as e:
return f"An error occurred: {e}"
if __name__ == "__main__":
prompt_simple = "Get me the first 5 customer names"
print(f"User: {prompt_simple}")
response_simple = run_agentic_workflow(prompt_simple)
print(f"Agent: {response_simple}")
prompt_complex = "Find all orders placed in May of last year that were fulfilled but not delivered on time, ordered by latest. Limit to 3."
print(f"\nUser: {prompt_complex}")
response_complex = run_agentic_workflow(prompt_complex)
print(f"Agent: {response_complex}")
Erwartete Ausgabe:
User: Get me the first 5 customer names
--- Executing Query ---
{
"table_name": "customers",
"columns": [
"customer_name"
],
"conditions": [],
"order_by": "desc",
"limit": 5
}
-----------------------
Agent: Here are the first 5 customer names I found: Alpha Corp, Beta Labs, Gamma Ltd, Delta Inc, and Epsilon Co.
User: Find all orders placed in May of last year that were fulfilled but not delivered on time, ordered by latest. Limit to 3.
--- Executing Query ---
{
"table_name": "orders",
"columns": [
"id",
"ordered_at",
"delivered_at",
"expected_delivery_date"
],
"conditions": [
{
"column": "ordered_at",
"operator": ">=",
"value": "2025-05-01"
},
{
"column": "ordered_at",
"operator": "<",
"value": "2025-06-01"
},
{
"column": "status",
"operator": "=",
"value": "fulfilled"
},
{
"column": "delivered_at",
"operator": ">",
"value": {
"column_name": "expected_delivery_date"
}
}
],
"order_by": "desc",
"limit": 3
}
-----------------------
Agent: I searched for orders matching your criteria but did not find any results.
Fehlerbehebung und Verifizierung
Wenn Sie LLM-Aufrufe und externe Tools miteinander verketten, gibt es einige häufige Fehlerquellen. So debugge ich sie.
Verifizierungsbefehle:
Stellen Sie zunächst sicher, dass Ihre Umgebung intakt ist.
python3.12 -c "import openai; print(f'OpenAI version: {openai.__version__}')"
python3.12 -c "import pydantic; print(f'Pydantic version: {pydantic.__version__}')"
# Expected output:
# OpenAI version: 1.x.x
# Pydantic version: 2.x.x
Führen Sie dann die Agentenanwendung aus, um den vollständigen Loop zu überprüfen:
python3.12 agent_app.py
Häufige Fehler und Lösungen:
-
Fehler: Das LLM halluziniert Argumente oder kann das Tool nicht aufrufen.
- Lösung: Dies liegt fast immer an der Qualität der Tool-Beschreibung. Stellen Sie in
query_tool.pysicher, dass der Haupt-Docstring vonQueryund jedeField(description=...)kristallklar sind. Das Modell verwendet diese Beschreibungen, um zu entscheiden, was zu tun ist. Wenn es verwirrt ist, schreiben Sie sie klarer um.
- Lösung: Dies liegt fast immer an der Qualität der Tool-Beschreibung. Stellen Sie in
-
Fehler: `PydanticValidationError: 1 validation error for Query ...
* **Lösung:** Dies bedeutet, dass die vom LLM generierten Argumente nicht mit Ihrem Pydantic-Schema übereinstimmen. Das ist gut so – Ihr Code fängt einen Modellfehler ab. Die Ursache ist normalerweise dieselbe wie der erste Punkt: unklare Beschreibungen. Sie müssen möglicherweise auch den System-Prompt in
agent_app.py` verfeinern, um das Verhalten des Modells besser zu steuern.
- Fehler: `BadRequestError: 400 ... does not support tool calling.
* **Lösung:** Sie verwenden ein Modell, das die Tool-Calling-API nicht unterstützt. Überprüfen Sie Ihren
model=-Parameter. Modelle wiegpt-4o-2024-08-06oder Googlesgemini-2.5-flash` sind dafür ausgelegt. Überprüfen Sie immer die offizielle Herstellerdokumentation auf Modellfunktionen.
Wichtige Erkenntnisse
Beim Hardware-Krieg geht es nicht darum, dass ein Chip gewinnt; es geht darum, das richtige Werkzeug für die richtige Aufgabe zu verwenden. Meine Erfahrung hat gezeigt, dass eine zweigeteilte Architektur der effektivste Ansatz für den Aufbau nachhaltiger, hochleistungsfähiger KI-Systeme ist.
-
Training = GPUs: Für die Schwerarbeit des Modelltrainings und groß angelegten Fine-Tunings bleiben NVIDIA GPUs die leistungsstärkste und kostengünstigste Wahl.
-
Inferenz = NPUs: Für echtzeitnahe, latenzarme Anwendungen, insbesondere agentische Workflows, ist spezialisierter Silizium (NPUs, LPUs, TPUs) unverzichtbar. Die Effizienzgewinne führen direkt zu besseren Margen und einer reaktionsschnelleren Benutzererfahrung.
-
Architektur für beides: Planen Sie Ihren KI-Stack so, dass er beides nutzt. Ihre Trainingspipelines sollten auf GPU-Clustern laufen, während Ihre Inferenz-Endpoints auf NPU-beschleunigten Plattformen bereitgestellt werden sollten.
-
Verwalten Sie Ihre Ausgaben: GPUs sind teuer. Implementieren Sie eine strenge FinOps-Governance, um ungenutzte Trainingscluster herunterzufahren und die Auslastung zu überwachen. Für die Inferenz ist der Wechsel zu NPUs selbst eine wichtige Kostenoptimierungsstrategie.
Als nächsten Schritt empfehle ich dringend, einen einfachen Agenten mit Ihrem eigenen benutzerdefinierten Tool zu prototypisieren, wobei Sie den Code in diesem Artikel als Ausgangspunkt verwenden. Die Bereitstellung und das direkte Erleben der Leistung werden die architektonischen Kompromisse sofort deutlich machen. Die Zukunft der KI-Anwendungen ist effizient, echtzeitnah und zunehmend agentisch – und diese Zukunft läuft auf spezialisiertem Silizium.