Luma public docs
English

Operasyon

Telemetry & Trace

Luma her LLM isteğini, her tool çağrısını, her agent method'unu, her query'yi, her HTTP çağrısını ve her doğrulama kuralını ayrı bir event olarak kaydeder. Bu, bir çıkarımın neden başarısız olduğunu tahmin etmek yerine okuyabilmeni sağlar.

Event modeli

Her event aynı temel şekle sahiptir:

json
{
  "type":       "tool",
  "name":       "hesapla",
  "start":      1785242769011,
  "durationMs": 1,
  "ok":         true,
  "error":      null,
  "metadata":   { "cached": false }
}
typename ne olurNe zaman üretilir
llmModel kimliği (text-model-l)Her provider isteği için — cache isabetleri dahil.
toolTool adıHer tool çalıştırması için — direct ve native fark etmez.
agentAgent.methodHer agent method çağrısı tamamlandığında.
validationDoğrulanan alan yoluHer doğrulama kuralı için ayrı ayrı — başarılı olanlar dahil.
httphttp.<fn> (http.get, http.postJson …)Her std/http çağrısı için — başarısız olanlar dahil.
queryQuery adıBir query döndüğünde. type, bildirim türünün kendisidir.
commandCommand adıBir command döndüğünde — aynı kural, kendi type değeri.
parallel_overSonuç değişkeninin adıYalnızca on_error continue en az bir elemanı atladığında.
errorÖlen operasyonv0.9.0. Düşen bir koşuda, o ana kadar toplanan olayların ardına yazılan tek sentetik nihai olay. Diğer her olay gibi ok: false taşır.

Dört değil, sekiz type değeri var. http, query, command ve parallel_over v0.4.0'ın veri yüzeyiyle geldi; dolayısıyla llm|tool|agent|validation üzerine yazılmış her filtre — v0.4.0 öncesinde yayımlanmış her tarif dahil — bu yüzeyin tamamını rapordan sessizce düşürür. Bildirimlerin kendisi Veri & Entegrasyon sayfasında; bu sayfa onların telemetry görünümünün sahibidir.

validation event'leri çok sayıdadır

Her alan, her kural ve her array elemanı için bir event üretilir. Karmaşık bir schema'da tek bir ask yüzlerce validation event'i üretebilir. Bu bilinçlidir: hangi kuralın çalıştığını ve hangisinin patladığını tam olarak görürsün. Filtrelemek için aşağıdaki jq tariflerini kullan.

Event metadata'sı

llm

json
{
  "agent": "Analist", "method": "incele", "instance": "analist",
  "model": "text-model-l", "provider": "openai-compatible",
  "logical_run_id":      "run-8f3c…",
  "attempt_id":          "run-8f3c…:attempt-1",
  "local_request_id":    "request-1a2b…",
  "provider_request_id": "req_abc123",
  "cached": false,
  "usage": {
    "prompt_tokens": 812, "completion_tokens": 143,
    "total_tokens": 955,  "reasoning_tokens": 0
  },
  "cost": 0.00955,
  "cost_per_1k_tokens": 0.01
}

tool

AlanAnlamı
logical_run_id · attempt_idTool'u tetikleyen LLM akışının kimlikleri.
local_request_id · provider_request_idTool call'ı üreten HTTP isteği.
provider_tool_call_idProvider'ın verdiği tool call kimliği.
logical_tool_call_idattempt_id + provider_tool_call_id — retry'lar arasında tekil kalır.
timeoutUygulanan etkin timeout (ms).
cachedSonuç cache'ten geldi mi?
single_flightEşzamanlı özdeş çağrıyla paylaşıldı mı?
idempotent · deduplicatedIdempotency store'dan döndü mü?

agent

{ "instance": "h", "deterministic": true }

deterministic: true, method'un return ile bittiğini (LLM çağrısı yapmadığını) gösterir.

validation

rule alanı hangi kuralın çalıştığını söyler:

rule değeriAnlamı
typeTip doğrulaması (ek alan: value_type — v0.9.0'a kadar type idi; olayın kendi type alanıyla çakışıyor ve OTel çıktısında tekrarlı luma.type attribute'u üretiyordu).
schemaNesne düzeyi schema doğrulaması (ek alan: schema).
tagged_unionTagged union üye doğrulaması (ek alanlar: schema, member). Yayımlanmış filtrelerin çoğunda yoktur — bunu atlayan bir kural listesi tüm discriminated union kontrollerini düşürür.
fieldAlan düzeyi başarısızlık (eksik alan, alias çakışması).
optionalOpsiyonel alan mevcut değildi — atlandı.
unknown_fieldSchema'da tanımlı olmayan alan.
format:email · match:^…$Format ve desen kuralları.
minLength:2 · maxLength:40Uzunluk kuralları.
min:0 · max:100Sayısal aralık kuralları.
minItems:1 · maxItems:5 · unique · contains · uniqueBy:idKoleksiyon kuralları.
valid:x => …@valid ifadesi (ifadenin kendisi kodda görünür).
whereInvariant (ek alan: expression).
conditional_required · conditional_forbiddenwhen kuralları (ek alan: condition).
severity, soft ihlali sert olandan ayırır

v0.8.0'dan beri doğrulama olayı metadata.severity da taşır. Düşen bir kuralın koşuyu durdurup durdurmadığını, yalnızca trace'e bakarak anlamanın tek yolu budur: "warn" değer bir şerhle kabul edildi demektir, diğer her şey o denemenin ölümcül düştüğü anlamına gelir.

jq -r '.events[] | select(.type=="validation" and .ok==false and .metadata.severity=="warn") | .metadata.rule' trace.json

O olmadan bir rapor, şerhli bir koşuyla düşen bir koşuyu aynı şey sayar.

http

{ "method": "GET", "status": 200, "headers": { "x-api-key": "[REDACTED]", "cookie": "session=…" } }

Event adı http.<fn>'dir. Başarısız çağrı da event üretir: ok: false, sebep error alanında ve status yok — host'a hiç ulaşmamış bir isteğin raporlayacak status'ü yoktur. URL ve istek gövdesi trace'e hiç yazılmaz; header'lar redaksiyondan geçtikten sonra yazılır. Ayrıntılar: std/http.

query · command

{ "datasource": "TestDb", "rows": 3 }

Event type'ı bildirim türünün kendisidir, name ise bildirim adıdır; yani bir query Orders şunu üretir: { "type": "query", "name": "Orders" }. rows, dönen listenin uzunluğudur — ama yalnızca bir liste döndüğünde. Tek satırlık query (Schema[] değil, -> Schema) ve her command rows: 1 raporlar; çünkü runtime array'leri sayar, array olmayan her şeyi tek satır kabul eder. Bir command'ın etkilediği satır sayısı telemetry'sinde değil, dönüş değerindedir. Başarısız çağrılar aynı event'i ok: false ve yalnızca datasource ile üretir.

parallel_over — span değil, düşme sayacı

{ "type": "parallel_over", "name": "kept", "ok": true, "metadata": { "total": 3, "skipped": 1 } }

Bu event yalnızca skipped > 0 olduğunda ve yalnızca on_error continue altında üretilir. Bir parallel over'ın çalıştığını işaretlemez: hiçbir şey atlamayan bir fan-out hiç event bırakmaz, fail_fast bir fan-out ise hiçbir zaman üretmez. ok her zaman true'dur — fan-out'un kendisi başarılıdır; event, girdinin ne kadarını yolda düşürdüğünü raporlar.

Bu da onu, on_error continue'un bir sonuç listesini kısalttığını gösteren tek makine-okunur sinyal yapar. Başarısız eleman listede boşluk bırakmaz — liste yalnızca daha kısa döner ve bunu trace'te ya da stdout'ta söyleyen başka hiçbir şey yoktur. Aşağıdaki tarif bunu okur; semantiği parallel over'da.

Metrikler

json
{
  "llmCalls":         3,
  "toolCalls":        5,
  "promptTokens":     2436,
  "completionTokens": 419,
  "reasoningTokens":  0,
  "totalTokens":      2855,
  "estimatedCost":    0.02855
}
MetrikNasıl hesaplanır
llmCallsProvider'a giden gerçek istek sayısı. Cache isabetleri ve paylaşılan single-flight istekleri sayılmaz.
toolCallsTüm tool çağrıları (cache isabetleri dahil).
promptTokens · completionTokens · totalTokensProvider'ın usage alanından toplanır.
reasoningTokensreasoning_tokens ya da completion_tokens_details.reasoning_tokens.
estimatedCosttotalTokens / 1000 × cost_per_1k_tokens. Agent'ta bu ayar yoksa 0 kalır.
usage döndürmeyen gateway'ler

Bazı gateway'ler usage alanını hiç göndermez. Bu durumda token metrikleri 0 kalır, maliyet hesaplanamaz ve token_budget/cost_budget hiç tetiklenmez. Bütçe kontrolüne güveniyorsan gateway'inin usage döndürdüğünü doğrula.

Export biçimleri

BayrakÇıktı
--traceTam rapor stderr'e — stdout'taki program sonucunu kirletmez.
--trace-file trace.json{ metrics, traces, events } tek JSON.
--trace-jsonl trace.jsonlHer event bir satır; son satır {"type":"metrics", …}.
--otel-file otel.jsonOTLP uyumlu resourceSpans yapısı.
luma program.luma \
  --trace-file  /tmp/trace.json \
  --trace-jsonl /tmp/trace.jsonl \
  --otel-file   /tmp/otel.json
Koşu düştüğünde de dördü birden yazılır

Trace'in en değerli olduğu an düşen koşudur, bu yüzden trace yazımı finally konumundadır: hataya kadar biriken ne varsa diske iner, son hata da bir event olarak kaydedilir. Terminal mesajı yalnızca output schema failed validation demek yerine düşen kuralları ve kaç deneme harcandığını adıyla söyler.

Bu her zaman böyle değildi — v0.5.0'a kadar hatayla biten bir koşu hiç trace dosyası üretmiyordu, yani tanıya en çok ihtiyaç duyulan tek durum okunacak hiçbir şeyin olmadığı durumdu. Sahadan #100 olarak bildirildi.

Aggregate trace'ler

traces dizisi, event'leri logical_run_id'ye göre gruplar:

json
{
  "traceId":       "e19fbd6da18af2dc3b57561c073adf7a",
  "logicalRunId":  "run-8f3c…",
  "start":         1785242769010,
  "durationMs":    1843,
  "ok":            true,
  "attempts": [
    { "attemptId": "run-8f3c…:attempt-1", "start": …, "end": …, "ok": false, "events": 12 },
    { "attemptId": "run-8f3c…:attempt-2", "start": …, "end": …, "ok": true,  "events": 14 }
  ]
}

logical_run_id taşımayan event'ler (deterministik agent method'ları, direct tool çağrıları) kendi tekil trace'lerine yerleştirilir.

OpenTelemetry

json
{
  "resourceSpans": [{
    "resource":   { "attributes": [{ "key": "service.name", "value": { "stringValue": "luma" } }] },
    "scopeSpans": [{
      "scope": { "name": "luma-runtime" },
      "spans": [{
        "traceId": "e19fbd6d…", "spanId": "a1b2c3d4…",
        "name": "hesapla",
        "startTimeUnixNano": "1785242769011000000",
        "endTimeUnixNano":   "1785242769012000000",
        "attributes": [
          { "key": "luma.cached", "value": { "boolValue": false } },
          { "key": "luma.type",   "value": { "stringValue": "tool" } }
        ],
        "status": { "code": 1 }
      }]
    }]
  }]
}

Tüm event metadata'sı luma.<anahtar> önekiyle span attribute'una çevrilir. status.code: 1 başarılı, 2 hatalı. Dosya doğrudan bir OTLP collector'a POST edilebilir.

Correlation zinciri

logical_run_id            bir mantıksal ask akışı — retry'lar boyunca AYNI kalır
   │
   ├── attempt_id            her retry denemesi / her run policy adayı
   │      │                  run-8f3c…:attempt-2
   │      │                  run-8f3c…:fallback-2-Backup
   │      │
   │      ├── local_request_id       tekil HTTP isteği (Luma üretir)
   │      ├── provider_request_id    gateway'in döndürdüğü kimlik
   │      │
   │      └── provider_tool_call_id  provider'ın tool call kimliği
   │             └── logical_tool_call_id  attempt + tool call
   │
   └── ikinci deneme, üçüncü deneme …

Bu kimlikler her isteğe HTTP başlığı olarak da gönderilir:

x-luma-run-id:      run-8f3c…
x-luma-attempt-id:  run-8f3c…:attempt-2
x-luma-request-id:  request-1a2b…

Böylece gateway loglarındaki bir kaydı Luma trace'indeki event'le birebir eşleştirebilirsin.

attempt_id deseniNe zaman
<run>:attempt-NNormal retry denemeleri.
<run>:fallback-N-<Model>fallback policy adayları.
<run>:parallel-N-<Model> · race-… · vote-…İlgili policy adayları.
<run>:fusion-<Model>Fusion synthesizer çağrısı.
<run>:combo-N-<Model>Combo pipeline aşaması.

Secret redaksiyonu

Trace dosyaları paylaşılabilir olmalıdır; runtime bunu iki katmanda sağlar:

KatmanNe yapar
Değer redaksiyonuBilinen tüm API key değerleri (api_key, OPENAI_API_KEY, ANTHROPIC_API_KEY ve tüm model profil key'leri) hata mesajlarında [REDACTED] ile değiştirilir. Authorization: Bearer … başlıkları da maskelenir.
Anahtar adı redaksiyonuMetadata içinde adı api_key, password, secret, credential veya authorization desenine uyan her alanın — iç içe olsa bile — değerinin tamamı [REDACTED] ile değiştirilir.

HTTP header'larını yöneten katman anahtar adı katmanıdır: header adı metadata'ya anahtar olarak girer, dolayısıyla authorization ve x-api-key değerinin tamamını kaybeder — değer katmanının bir hata mesajı içinde yaptığı gibi yalnızca Bearer sonrasındaki token'ı değil. Desene uymayan her header adı trace'e olduğu gibi gider: cookie, x-auth-token, x-session ve imza header'ları redakte edilmez. Yalnızca header değerleri ayrıca önce değer katmanından geçer; böylece bilinen bir model API key'ini taşıyan header, adı ne olursa olsun değerinden yakalanır. Ya credential'ı desenin yakaladığı bir header adında tut, ya da trace dosyasını credential kadar hassas kabul et.

Prompt içeriği redakte edilmez

Redaksiyon hata mesajlarını ve metadata'yı kapsar. Prompt metinleri trace event'lerine yazılmaz, ancak bir doğrulama hatası mesajında model çıktısının bir parçası görünebilir. Ayrıca LUMA_DEBUG_MODEL_RESPONSE=1 ayarı ham model yanıtının ilk 4000 karakterini hata detayına ekler — bunu üretimde açık bırakma.

jq tarifleri

Başarısız doğrulamalar

jq -r '.events[] | select(.type=="validation" and .ok==false)
        | "\(.name) [\(.metadata.rule // "-")] \(.error // "-")"' trace.json

LLM istekleri: model, süre, token, maliyet

jq -r '.events[] | select(.type=="llm")
        | "\(.metadata.model)  \(.durationMs)ms  \(.metadata.usage.total_tokens // 0)tok  $\(.metadata.cost // 0)"' trace.json

En yavaş 10 adım

jq -r '.events | sort_by(-.durationMs) | .[:10][]
        | "\(.durationMs)ms  \(.type)  \(.name)"' trace.json

Tool çağrı özeti (cache isabetleriyle)

jq -r '.events[] | select(.type=="tool")
        | "\(.name)  ok=\(.ok)  cached=\(.metadata.cached // false)  \(.durationMs)ms"' trace.json

Hangi retry denemesi başarılı oldu?

jq -r '.traces[] | select(.attempts | length > 1)
        | "\(.logicalRunId): " + ([.attempts[] | "\(.attemptId)=\(.ok)"] | join("  "))' trace.json

En sık başarısız olan doğrulama kuralları

jq -r '.events[] | select(.type=="validation" and .ok==false) | .metadata.rule' trace.json \
  | sort | uniq -c | sort -rn

Sessizce düşen elemanlar (parallel over)

jq -r '.events[] | select(.type=="parallel_over")
        | "\(.name): \(.metadata.total) elemandan \(.metadata.skipped) tanesi düştü"' trace.json

Çıktı olmaması hiçbir şeyin atlanmadığı anlamına gelir: skipped 0 iken event hiç oluşmaz. Kısalmış bir on_error continue sonuç listesinin göründüğü tek yer burasıdır — içinde parallel over geçen her trace için bunu CI'da çalıştır.

Veri yüzeyi: query, command, HTTP

jq -r '.events[] | select(.type=="query" or .type=="command" or .type=="http")
        | "\(.type)  \(.name)  ok=\(.ok)  \(.durationMs)ms  \(.metadata.rows // .metadata.status // "-")"' trace.json

Tüm hatalar (her tür)

jq -r '.events[] | select(.ok==false) | "\(.type)  \(.name)  \(.error)"' trace.json

JSONL akışını canlı izleme

tail -f trace.jsonl | jq -r 'select(.type=="llm" or .ok==false)
                             | "\(.type) \(.name) ok=\(.ok)"'

Maliyet ve bütçe takibi

luma
agent Kontrollu {
  model: Primary
  cost_per_1k_tokens: 0.01
  token_budget: 20000
  cost_budget: 0.50
}

Bütçe kontrolü LLM yanıtının usage bilgisi okunduktan sonra yapılır: limiti aşan istek tamamlanır, ancak bir sonraki istek MODEL_BUDGET_EXCEEDED ile engellenir. Hata retryable: false olduğu için retry döngüsü de durur.

# Tek çalıştırmanın toplam maliyeti
jq '.metrics | { totalTokens, estimatedCost, llmCalls }' trace.json

# Agent bazında token dağılımı
jq -r '.events[] | select(.type=="llm")
      | "\(.metadata.agent // "top-level")\t\(.metadata.usage.total_tokens // 0)"' trace.json \
  | awk -F'\t' '{s[$1]+=$2} END {for (a in s) printf "%-24s %d\n", a, s[a]}' | sort -k2 -rn
Maliyeti düşüren ayarEtkisi
cache: true (model profili)Aynı istek tekrar edilirse provider'a gidilmez.
memory_limitGeçmiş mesajların prompt token'ını büyütmesini sınırlar.
max_tokensÇıktı token'ını sınırlar.
combo run policyUcuz modelle taslak, pahalı modelle rötuş.
Ara dosyalar (pre.md)Pahalı görsel adımını tekrarlamadan çıkarımı yeniden çalıştırmanı sağlar.
Dar schema'larJSON Schema system mesajına yazıldığı için her istekte token maliyeti vardır.
Schema boyutu her istekte ödenir

Üretilen JSON Schema her istekte system mesajına yazılır. $defs yalnızca kök schema'dan erişilebilen tanımları taşır — kullanılmayan schema'lar maliyete girmez. Yine de derin bir schema grafiği her istekte ödenir; nadiren kullanılan dalları ayırmak bu sabit maliyeti düşürür.