Nutzungserfassung
Das Modul wippy/usage erfasst den LLM-Token-Verbrauch und stellt aggregierte
Abfragen nach Zeitintervall, Modell oder Benutzer bereit. Es ist die
Standardimplementierung des Vertrags wippy.llm:usage_tracker; Aufrufe über das
LLM-Modul erzeugen daher automatisch Nutzungsdatensätze.
Diese Seite ist eine API-Einführung mit Referenz-Snippets und kein eigenständiges
Tutorial. Die Snippets setzen ein bestehendes Wippy-Projekt, eine konfigurierte
SQL-Datenbank und für die automatische Erfassung wippy/llm voraus. Nutzungszeilen
bleiben in der gewählten Datenbank gespeichert. Entfernen Sie Beispieldaten nach dem
Test über den üblichen Wartungsablauf Ihrer Datenbank.
Einrichtung
Fügen Sie das Modul zum Projekt hinzu:
wippy add wippy/usage
wippy install
Deklarieren Sie die Abhängigkeit und setzen Sie target_db auf die Datenbank, in der
die Nutzungsdatensätze gespeichert werden sollen:
version: "1.0"
namespace: app
entries:
- name: app_db
kind: db.sql.sqlite
file: ./data/app.db
- name: dep.usage
kind: ns.dependency
component: wippy/usage
version: "*"
parameters:
- name: target_db
value: app:app_db
Beim Start der Anwendung führt wippy/migration die Migration
01_create_token_usage_table des Moduls aus. Sie erstellt die Tabelle token_usage
und Indizes auf user_id, context_id, model_id und timestamp.
Wenn Sie den oben gezeigten relativen SQLite-Pfad verwenden, erstellen Sie vor dem
Start der Anwendung das Verzeichnis data.
Schema
token_usage
├── usage_id text primary key (uuid v7)
├── user_id text not null
├── context_id text
├── model_id text not null
├── prompt_tokens integer
├── completion_tokens integer
├── thinking_tokens integer default 0
├── cache_read_tokens integer default 0
├── cache_write_tokens integer default 0
├── timestamp timestamp
└── meta text (JSON)
Automatische Erfassung
wippy/llm löst vor jeder Generierung den Vertrag wippy.llm:usage_tracker auf.
wippy/usage bindet seine Implementierung als Standard:
contracts:
- contract: wippy.llm:usage_tracker
default: true
methods:
track_usage: wippy.usage:usage_tracker
Jeder erfolgreiche LLM-Aufruf ruft track_usage mit der Modell-ID, den Token-Anzahlen
und einer optionalen context_id auf. Die user_id stammt vom aktiven
Sicherheitsakteur; Aufrufe außerhalb eines Benutzerkontexts werden als "system"
erfasst.
Tracker-API
Importieren Sie den Tracker direkt, um Nutzung außerhalb des LLM-Ablaufs aufzuzeichnen:
imports:
usage_tracker: wippy.usage:usage_tracker
local tracker = require("usage_tracker")
-- Numeric counts supplied by the caller or model provider.
local prompt_tokens, completion_tokens = 120, 40
local thinking_tokens = 0
local cache_read_tokens, cache_write_tokens = 0, 0
local usage_id, err = tracker.track_usage(
"openai:gpt-4o",
prompt_tokens,
completion_tokens,
thinking_tokens,
cache_read_tokens,
cache_write_tokens,
{ context_id = "chat-42", metadata = { feature = "summary" } }
)
if err then
error("Failed to record usage: " .. tostring(err))
end
| Parameter | Typ | Beschreibung |
|---|---|---|
model_id |
string | Kanonische Modell-ID |
prompt_tokens |
number | Eingabe-Tokens |
completion_tokens |
number | Ausgabe-Tokens |
thinking_tokens |
number | Reasoning-Tokens (0, wenn nicht gemeldet) |
cache_read_tokens |
number | Prompt-Cache-Treffer |
cache_write_tokens |
number | Schreibvorgänge in den Prompt-Cache |
options.context_id |
string | Frei wählbares Tag; fällt auf ctx.get("context_id") zurück |
options.timestamp |
number | Unix-Zeitstempel; Standard ist jetzt (UTC) |
options.metadata |
table | Beliebige JSON-Metadaten, die neben dem Datensatz gespeichert werden |
Gibt usage_id oder nil, err zurück.
Repository-API
wippy.usage:token_usage_repo bietet aggregierte Abfragen:
modules:
- time
imports:
usage: wippy.usage:token_usage_repo
local usage = require("usage")
local time = require("time")
-- Inclusive query bounds expressed as UNIX timestamps.
local end_unix = time.now():unix()
local start_unix = end_unix - (24 * 60 * 60)
local function require_result(value, err)
if err then
error("Usage query failed: " .. tostring(err))
end
return value
end
local summary = require_result(usage.get_summary(start_unix, end_unix))
local by_time = require_result(usage.get_usage_by_time(start_unix, end_unix, usage.INTERVAL.DAY))
local by_model = require_result(usage.get_usage_by_model(start_unix, end_unix))
local by_user = require_result(usage.get_usage_by_user(start_unix, end_unix))
Funktionen
| Funktion | Rückgabe |
|---|---|
get_summary(start, end) |
Summen über den Bereich: Prompt-, Completion-, Thinking- und Cache-Tokens, Anzahl der Anfragen sowie total_tokens (Prompt + Completion + Thinking) |
get_usage_by_time(start, end, interval) |
Array von Buckets, einer pro Intervall; fehlende Buckets liefern Nullen |
get_usage_by_model(start, end) |
Summen pro Modell, sortiert nach total_tokens absteigend |
get_usage_by_user(start, end) |
Summen pro Benutzer, sortiert nach total_tokens absteigend |
create(user_id, model_id, prompt, completion, options) |
Low-Level-Insert, das vom Tracker verwendet wird |
Intervalle
usage.INTERVAL.HOUR -- "hour"
usage.INTERVAL.DAY -- "day"
usage.INTERVAL.WEEK -- "week"
usage.INTERVAL.MONTH -- "month"
get_usage_by_time richtet Buckets am konfigurierten Intervall aus. PostgreSQL
verwendet generate_series mit Intervallarithmetik, SQLite eine rekursive CTE über
UNIX-Zeitstempel. total_tokens schließt Cache-Tokens in jedem Bucket aus.
Zeitbereiche
Tracker und Repository akzeptieren an der öffentlichen API-Grenze UNIX-Zeitstempel.
Intern konvertiert das Repository sie für Speicherung und Abfragen in RFC3339-Strings.
Übergeben Sie Werte von os.time() oder time.now():unix() und keine formatierten Strings.
Metadaten und Kontext
Die Spalte meta speichert frei definierbares JSON, um Datensätze mit
Anwendungsereignissen zu korrelieren:
local usage_id, err = tracker.track_usage("openai:gpt-4o", 120, 40, 0, 0, 0, {
context_id = "chat-42",
metadata = {
session_id = "s-7",
route = "/api/summarise",
agent_id = "writer",
},
})
if err then
error("Failed to record usage metadata: " .. tostring(err))
end
context_id ist eine Spalte der obersten Ebene und kann indiziert werden; metadata
wird als Text gespeichert und ist für die Anzeige, nicht zum Filtern vorgesehen.
Siehe auch
- LLM — LLM-Generierung und der Vertrag
usage_tracker - Migrationen — Migrations-Runner, der das Schema erstellt
- Framework-Übersicht — Verwendung von Framework-Modulen