AI-API-Kosten in PHP berechnen: Warum ich `ai-costs` gebaut habe
Wer mit OpenAI, Anthropic oder Gemini arbeitet, kennt das Problem: Die eigentliche Modellintegration ist oft schnell gebaut, aber bei den Kosten wird es unübersichtlich. Token-Verbrauch ist je nach Anbieter anders strukturiert, Caching taucht in unterschiedlichen Feldern auf, Zusatzkosten für Tools kommen dazu, und am Ende möchte man trotzdem eine verlässliche Zahl für Monitoring, Reporting oder interne Abrechnung haben.
Genau dafür gibt es `ai-costs`.
`ai-costs` ist eine kleine, SDK-agnostische PHP-Library, die Usage-Payloads von LLM-APIs in eine nachvollziehbare Kostenaufschlüsselung übersetzt. Statt Preise und Tokenlogik an mehreren Stellen in der Anwendung zu verteilen, bekommt man einen zentralen Baustein für Kostenschätzung in `usd_micros`.
Das eigentliche Problem
In vielen Projekten startet die Kostenberechnung mit einer simplen Formel:
input_tokens * input_price + output_tokens * output_price
In der Praxis reicht das aber schnell nicht mehr aus.
- OpenAI, Anthropic und Gemini liefern unterschiedliche Usage-Formate zurück.
- Cached Tokens müssen oft separat bepreist werden.
- Manche Modelle haben Long-Context-Preise ab einer bestimmten Eingabelänge.
- Zusatzkosten wie Web Search oder Container-Sessions passen nicht in ein reines Tokenmodell.
- Float-basierte Geldbeträge sind für technische Auswertung unnötig fehleranfällig.
Wenn man das ad hoc in einem Controller oder Service verdrahtet, entsteht sehr schnell Logik, die schwer testbar und noch schwerer wartbar ist.
Was `ai-costs`macht
Die Library trennt drei Dinge sauber voneinander:
- Usage extrahieren
- Preise bereitstellen
- Kosten berechnen
Das klingt unspektakulär, ist im Alltag aber enorm hilfreich.
Die Extraktoren lesen provider-spezifische API-Responses und normalisieren sie in ein gemeinsames `UsageBreakdown`-Objekt. Darin landen unter anderem:
- Input Tokens
- Cached Input Tokens
- Output Tokens
- Reasoning Tokens
- Cache-Write-Tokens
- Metadaten wie Modellname, Quelle und Service-Tier
Auf dieser normalisierten Basis übernimmt der `CostCalculator` die eigentliche Berechnung.
Warum `usd_micros`eine gute Entscheidung sind
Ein Detail, das mir an dem Paket besonders gefällt: Es rechnet konsequent mit Integer-Werten in `usd_micros`.
Das bedeutet:
- `1 USD = 1_000_000 usd_micros`
- keine Rundungsprobleme durch Floats
- saubere Weiterverarbeitung in Logs, Datenbanken und Reports
Gerade bei vielen kleinen Requests ist das robuster als ein verteiltes Sammelsurium aus `float`, `round()` und impliziten Formatierungen.
Unterstützte Quellen
Aktuell deckt das Paket diese APIs ab:
- OpenAI Chat Completions API
- Anthropic Messages API
- Google Gemini `generateContent`
Dazu kommt ein statischer, versionierter Preiskatalog für ausgewählte aktuelle Modelle, darunter GPT-5.4, GPT-5.5, Claude-Modelle und Gemini 2.5.
Der wichtige Punkt ist: Die Library möchte nicht das Billing-System der Provider ersetzen. Sie liefert bewusst eine nachvollziehbare Schätzung auf Basis öffentlicher Preisdokumentation und realer Usage-Payloads.
Beispiel: Kosten aus einer OpenAI-Response berechnen
So sieht der Einstieg aus:
<?php
declare(strict_types=1);
use AiCosts\CostCalculator;
use AiCosts\Enum\BillingMode;
use AiCosts\OpenAI\OpenAIResponsesUsageExtractor;
use AiCosts\OpenAI\OpenAIToolPricing;
use AiCosts\Pricing\StaticPriceProvider;
use AiCosts\Value\BillingContext;
$payload = [
'model' => 'gpt-5.4',
'usage' => [
'input_tokens' => 1200,
'input_tokens_details' => ['cached_tokens' => 200],
'output_tokens' => 300,
'output_tokens_details' => ['reasoning_tokens' => 50],
],
];
$extractor = new OpenAIResponsesUsageExtractor();
$usage = $extractor->extract($payload);
$calculator = new CostCalculator(StaticPriceProvider::default());
$breakdown = $calculator->calculate(
$usage,
new BillingContext(
billingMode: BillingMode::STANDARD,
additionalCharges: [
OpenAIToolPricing::webSearchCalls(3),
],
),
);
echo $breakdown->totalCostInUsdMicros;
// 37050
Der interessante Teil daran ist nicht nur die Zahl am Ende, sondern die Struktur dazwischen:
- Die OpenAI-Response wird normalisiert.
- Zusatzkosten lassen sich explizit am Billing-Kontext anhängen.
- Das Ergebnis ist kein einzelner Preis, sondern ein `CostBreakdown`.
Damit kann man zum Beispiel sehr einfach interne Dashboards, Job-Kosten pro Task oder Cost-Alerts aufbauen.
Links
- Repository: 1manfactory/ai-costs
- Paketname: 1manfactory/ai-costs
- Lizenz: MIT
0 Kommentare