Luma public docs
English

Çalışma Zamanı

Model & Provider

Model profili, bir LLM sağlayıcısına nasıl bağlanılacağını tanımlar. Luma provider-neutral bir adapter katmanı kullanır: aynı .luma programı OpenAI-compatible bir gateway'de, Anthropic'te, Gemini'de veya Azure'da değişmeden çalışır — tool çağrısı biçimleri ve structured output kuralları adapter tarafından çevrilir.

Model profili

luma
model Primary {
  provider: "openai-compatible"
  base_url: "https://gateway.example/v1"
  model: "text-model-l"
  api_key: getEnv("api_key")
  timeout: 30000
  max_tokens: 4000
  capabilities: ["json_schema", "tool_calling"]
  cache: true
  cache_ttl: 60000
  cache_max_entries: 256
  stream: false
  reasoning: false
  multimodal: false
  cost_per_1k_tokens: 0.002
}

agent Analist {
  model: Primary
}
AnahtarZorunluVarsayılanAçıklama
providerevet—Adapter seçimi. Geçerli değerler aşağıda.
base_urlevet—Gateway kökü. Endpoint yolu adapter tarafından eklenir.
modelevet—Provider'daki model kimliği.
api_keyevet—Yalnızca getEnv("ENV_ADI") biçimi kabul edilir.
timeouthayırsınırsızİstek timeout'u (ms).
max_tokenshayır—Çıktı token limiti. Anthropic'te değer yoksa 4096 kullanılır.
capabilitieshayır[]Capability probe'un doğrulayacağı yetenekler.
cachehayırfalseModel yanıt cache'i.
cache_ttlhayır300000Cache girişi ömrü (ms).
cache_max_entrieshayır256LRU kapasitesi.
stream / streaminghayırfalseSSE akışı — yanıt yine de tam olarak toplanır.
reasoninghayırfalseİsteğe reasoning_effort: "medium" ekler.
multimodalhayırfalsePrompt içindeki görsel/dosya marker'larının işlenmesini açar.
cost_per_1k_tokenshayıragent'ın oranıBu modelin 1000 token başına birim fiyatı. Bu modelin yürüttüğü her istekte agent'ın cost_per_1k_tokens değerini ezer; agent'ın token_budget / cost_budget ayarları aynı defteri okumaya devam eder. Negatif değer parse hatası verir: Model 'Primary' cost_per_1k_tokens cannot be negative.

Model başına fiyat, tek bir agent birden çok model çalıştırdığında önem kazanır: fiyat verilmezse ucuz model de pahalı model de aynı orandan faturalanır ve escalate policy'sinin max_cost_per_call tavanı maliyeti değil token'ı ölçmüş olur. Agent geneli oran ve bütçeler için → Bütçeler ve limitler.

Yanlış yazılmış bir model anahtarı tek kelime etmeden düşürülür

Yukarıdaki tablodaki her anahtar kendi regex'iyle okunur ve geriye kalanı denetleyen hiçbir şey yoktur. Parser'ın tanımadığı bir satır bildirilmez ve uygulanmaz — ayar yalnızca varsayılanında kalır. Aşağıdaki blok parse olur, çalışır, hiçbir uyarı basmaz ve şu üç satırın üçünü de atar:

model Primary {
  provider: "openai-compatible"
  base_url: "https://gateway.example/v1"
  model: "text-model-l"
  api_key: getEnv("api_key")
  max_token: 100        // düşürüldü — gerçek anahtardan bir harf eksik
  cache_ttll: 5000      // düşürüldü
  multimodel: true      // düşürüldü — bayrak false kalır
}

Bunu söylemeye değer, çünkü dilin geri kalanının öğrettiği alışkanlık bu değil. agent, datasource, query ve command blokları her key: satırını bilinen kümesine karşı denetler ve tanımadığını program başlamadan adıyla reddeder: Agent 'A' has no key 'retryy'; known keys: role, model, temperature, … model bloğunda böyle bir denetim yok; run_policy'de de yok — orada da bilinmeyen anahtar düşürülür, buna karşılık bilinen bir anahtarın yanlış strategy ile kullanımı yine reddedilir (RunPolicy 'R' tie can only be used with the vote strategy.).

En çok canını yakan yer boolean bayraklardır; çünkü düşürülmüş bir bayrak, hiç yazılmamış bir bayraktan ayırt edilemez. multimodel: true, multimodal'ı false'ta bırakır; prompt içindeki görsel ve dosya marker'ları da o zaman yazıldığı gibi — base64 yüküyle birlikte — düz metin olarak gider: token harcanır, görsel görülmez, hiçbir yerde tanı çıkmaz. Yukarıdaki tabloyu allowlist say ve bir ayarı hiç yazmamışsın gibi davranan bir modeli önce bir yazım sorusu olarak oku.

Profil vermezsen legacy gateway kullanılır

Agent'ta model ayarı yoksa ya da tırnak içinde ham bir model kimliği (model: "org/text-model-s") verilmişse, bağlantı .env'deki base_url / api_key / model üzerinden kurulur ve provider openai-compatible kabul edilir. Yeni projelerde adlandırılmış profil kullanmak tercih edilir — capability probe, cache ve run policy yalnızca profillerle çalışır.

Provider adapter'ları

provider değeriAdapterEndpointAuth başlığı
openai-compatible · openai · gateway · deepseekOpenAI Chat Completions{base_url}/chat/completionsAuthorization: Bearer …
anthropicAnthropic Messages{base_url}/messagesx-api-key + anthropic-version: 2023-06-01
gemini · googleGemini generateContent{base_url}/v1beta/models/{model}:generateContentx-goog-api-key
azure · azure-openaiAzure OpenAI{base_url}/chat/completionsapi-key

base_url zaten endpoint yolunu içeriyorsa (örn. …/chat/completions) tekrar eklenmez; query string korunur. Bilinmeyen bir provider adı, hiçbir istek yapılmadan parse zamanında reddedilir: Error: Model 'M' has unknown provider '…'. Valid values: …

Tool çağrısı eşlemesi

AdapterTool bildirimiModel → çağrıRuntime → sonuç
OpenAI / Azuretools[].functiontool_calls[]role: "tool" mesajı
Anthropictools[].input_schematool_use bloğutool_result içeren user mesajı
GeminifunctionDeclarationsfunctionCallfunctionResponse

Structured output desteği

AdapterSchema provider'a nasıl iletilir
OpenAI / Azureresponse_format: { type: "json_schema", json_schema: { strict: true, schema } }
GeminigenerationConfig.responseMimeType: "application/json" + responseSchema
AnthropicSchema tek bir tool olarak bildirilir (tools[0].input_schema) ve tool_choice: { type: "tool", name } ile zorunlu kılınır; dönen tool_use.input yapılandırılmış çıktıdır. Yalnızca agent kendi tool'larını bildirmediğinde geçerlidir — bildirdiğinde native tool döngüsü devreye girer ve schema system mesajıyla taşınır.
Tagged union wire'da: anyOf ve daima type:object olan bir kök

Strict json_schema modu oneOf'u doğrudan reddediyor ve kökün type: "object" olmasını istiyor. Bu yüzden tagged union anyOf olarak emit ediliyor — üyeler zaten const tag'leriyle ayrık olduğu için hiçbir şey kaybolmuyor — ve yalnızca OpenAPI'ye ait discriminator anahtar kelimesi hiç gönderilmiyor, çünkü onu okuyan provider yok ve strict mod reddediyor.

ask union'ın kendisini hedeflediğinde istek, union'ın adını taşıyan tek alanlı bir zarfa sarılıyor ve yanıt doğrulamadan önce açılıyor. Programın zarfı hiç görmüyor; zarf, provider'ın "kök nesne olmalı" kuralının senin şemalarının dışında kalması için var.

Bu, provider'a göre dallanmak yerine her adapter için aynı şekilde emit ediliyor; böylece interpreter ile transpiled artifact byte-byte aynı kalıyor. Sahadan #96 olarak bildirildi — v0.5.0'a kadar eski oneOf emit'i, her tagged-union ask'inin strict provider tarafından 400 ile reddedilmesi demekti.

Anthropic'te agent tool bildiriyorsa retry ver

Agent kendi tools'unu bildirdiğinde schema'yı tool olarak gönderme yöntemi kullanılamaz; biçim, system mesajı ve Luma'nın yerel doğrulamasına geri düşer. retry: 2 gibi bir değer, doğrulama hatasını modele geri besleyerek bu farkı büyük ölçüde kapatır.

İsteğin şekillenmesi

Her ask için gönderilen gövde şu kurallarla oluşturulur:

AlanKaynak / kural
modelProfil model değeri.
messagessystem (schema + context talimatı + role) → memory geçmişi → user (prompt).
temperatureAgent temperature; verilmezse 0.
max_tokensAgent max_tokens, yoksa profil değeri; ikisi de yoksa gönderilmez.
streamProfil stream değeri.
reasoning_effortProfilde reasoning: true ise "medium".
tools + tool_choiceAgent'ın tools listesi doluysa gönderilir. ask üzerinde using tool yoksa tool_choice "auto"'dur; varsa o tek tool'a sabitlenir.
response_formatTool yoksa her istekte; tool varsa yalnızca en az bir tool çağrısı gerçekleştikten sonra.
Korelasyon başlıkları her istekte gönderilir:

  x-luma-run-id      → logical_run_id   (mantıksal çalıştırma)
  x-luma-attempt-id  → attempt_id       (retry / policy adayı)
  x-luma-request-id  → local_request_id (tekil HTTP isteği)

Yanıttan okunan provider kimliği:
  x-request-id · request-id · anthropic-request-id → provider_request_id

Bu değerler telemetry event'lerine de yazılır; gateway loglarıyla trace'i eşleştirmeni sağlar. → Correlation

Yanıt işleme

ham yanıt (JSON veya SSE)
   ↓ adapter normalizasyonu → { content, refusal, toolCalls, usage }
   ↓ refusal varsa → MODEL_REFUSAL (retryable: false)
   ↓ toolCalls varsa → tool'ları çalıştır, sonucu ekle, döngüye dön
   ↓ content boş → MODEL_EMPTY_CONTENT (retryable)
   ↓ ```json çitleri temizlenir
   ↓ JSON.parse başarısız → MODEL_INVALID_RESPONSE (retryable)
   ↓ yerel schema doğrulaması başarısız → MODEL_INVALID_RESPONSE (retryable)
   ↓ sonuç

Model yanıtı ```json … ``` bloğu içine sararsa çitler otomatik temizlenir. Ham yanıtı görmek için LUMA_DEBUG_MODEL_RESPONSE=1 kullan.

Capability probe

Program başlamadan önce Luma, kullanılacak her model için gateway'in /models endpoint'ine bir istek atar ve modelin gerekli yetenekleri desteklediğini doğrular.

YetenekNe zaman aranır
json_schemaLLM method'u olan her agent ve her üst düzey ask için.
tool_callingAgent'ın tools listesi doluysa.
streaming · reasoning · multimodalProfilde ilgili bayrak açıksa.
Profildeki capabilitiesListelenen her değer ayrıca doğrulanır.
Durumwarn varsayılanstrict
Gateway'e ulaşılamıyorUyarı yazar, devam ederProgram durur
Model /models yanıtında yokUyarı yazar, devam ederProgram durur
Yetenek bilgisi eksikUyarı yazar, devam ederProgram durur
Yetenek açıkça falsedururdurur
jsonluma.config.json
{
  "model_runtime": {
    "capability_policy": "strict",
    "capability_probe_timeout_ms": 5000
  }
}
export LUMA_CAPABILITY_POLICY=strict
export LUMA_CAPABILITY_PROBE_TIMEOUT_MS=3000

Environment değişkenleri config'i ezer. Probe timeout'u varsayılan 5000 ms'dir ve Ctrl-C ile iptal edilebilir.

Yetenek bilgisi eksikse uyarı görürsün
Warning: 'text-model-l' has no json_schema capability information.

Çoğu gateway /models yanıtında capabilities nesnesi döndürmez; bu uyarı normaldir ve programı engellemez. Sıkı kontrol istiyorsan strict moda geç — ama gateway'in bu bilgiyi gerçekten verdiğinden emin ol.

Streaming, reasoning, multimodal

luma
model VisionReasoner {
  provider: "openai-compatible"
  base_url: "https://gateway.example/v1"
  model: "vision-model"
  api_key: getEnv("api_key")
  stream: true
  reasoning: true
  multimodal: true
}
BayrakEtkisi
stream: trueİstek SSE olarak yapılır; parçalar (içerik, tool call argümanları, usage) toplanır ve yanıt tam olarak döner. Luma parça parça çıktı yayınlamaz — akış yalnızca taşıma katmanındadır.
reasoning: trueİsteğe reasoning_effort: "medium" eklenir. Reasoning token'ları telemetry'de reasoningTokens olarak raporlanır.
multimodal: truePrompt içindeki {{image_url:…}} ve {{file_url:…}} marker'ları content part'larına çevrilir. Bayrak kapalıysa marker'lar düz metin olarak gider.

Multimodal ayrıntıları ve dosya akışı için → IO & Multimodal.

Model response cache

luma
model Cached {
  provider: "openai-compatible"
  base_url: "https://gateway.example/v1"
  model: "text-model-l"
  api_key: getEnv("api_key")
  cache: true
  cache_ttl: 60000
  cache_max_entries: 256
}
ÖzellikDavranış
KapsamYalnızca cache: true olan profillerde ve istekte tool bildirimi yoksa.
Anahtarprovider + base_url + model + isteğin kanonik JSON'u. API key anahtara girmez.
SaklananYalnızca schema-valid nihai sonuç.
TahliyeTTL dolduğunda ve cache_max_entries aşıldığında (LRU).
Single-flightAynı anahtar için eşzamanlı istekler tek çağrıyı paylaşır.

Run policy: çok modelli stratejiler

run_policy, bir ask çağrısının birden fazla model üzerinde nasıl yürütüleceğini belirler. Agent'a bağlanır ve o agent'ın tüm LLM çağrılarını kapsar.

luma
run_policy Resilient {
  strategy: "fallback"
  models: [Primary, Backup]
  on: ["timeout", "rate_limit", "provider_error", "empty_content"]
  max_attempts: 2
}

agent Analist {
  model: Primary
  run_policy: Resilient
}

Stratejiler

StrategyDavranışModel sayısı
singleTek model. Policy vermemekle aynı; retry normal çalışır.0–1
fallbackSırayla dener; yalnızca on listesindeki hata türlerinde sonrakine geçer.≥ 1
escalateUcuz modelden güçlüye uzanan bir merdiven: yalnızca on listesindeki hata türlerinde bir üst basamağa çıkar, bir model yanıt verdiği anda durur. max_cost_per_call tek bir çağrının harcayabileceğini sınırlar.≥ 2
parallelHepsini eşzamanlı çalıştırır. select: "first" ilk başarılıyı, "all" tüm başarılıları döndürür.≥ 1
raceHepsini başlatır, ilk başarılı sonucu alır ve diğerlerini iptal eder.≥ 1
voteSonuçları kanonik JSON üzerinden oylar; quorum arar.≥ 2
fusionBaşarılı adayları bir synthesizer modele verip tek nihai sonuç ürettirir.≥ 1 + synthesizer
comboModelleri sıralı pipeline olarak çalıştırır; her aşama öncekinin çıktısını iyileştirir.≥ 2

Yapılandırma anahtarları

AnahtarHangi strategy'lerdeVarsayılan
modelssingle hariç hepsinde zorunlu—
onhepsi (pratikte fallback ve escalate)["retryable"]
max_attemptsyalnızca fallbackmodel sayısı
max_modelsparallel · race · vote · fusionmodel sayısı
max_stagesyalnızca combomodel sayısı
max_cost_per_callyalnızca escalatesınırsız
quorumyalnızca votefloor(n/2) + 1
tieyalnızca votefail
selectyalnızca parallelfirst
synthesizeryalnızca fusion (zorunlu)—
synthesizer_policyyalnızca fusiondeny_tools
max_fusion_inputs · fusion_input_tokensyalnızca fusionsınırsız

Bir anahtarı yanlış strategy ile kullanmak parse hatası verir — örneğin tie yalnızca vote için geçerlidir.

on: hangi hatalarda devreye girer

Geçerli trigger değerleri:

retryable        timeout          rate_limit       provider_error
empty_content    invalid_response refusal          invalid_tool_call
cancelled        unsupported      budget_exceeded

ayrıca ham error code'ları da yazılabilir:
MODEL_TIMEOUT · MODEL_RATE_LIMIT · MODEL_PROVIDER_ERROR · …

"retryable" özel bir değerdir: hatanın retryable bayrağına bakar, koduna değil. Tanınmayan bir trigger parse hatası verir.

Strateji detayları

fallback

luma
run_policy Resilient {
  strategy: "fallback"
  models: [Primary, Backup, Reserve]
  on: ["timeout", "rate_limit", "provider_error"]
  max_attempts: 2
}

Modeller sırayla denenir. Hata on listesine uymuyorsa hemen fırlatılır — yani bir doğrulama hatası yüzünden gereksiz yere ikinci modele geçilmez. max_attempts kaç modelin deneneceğini sınırlar.

escalate

luma
run_policy Adaptive {
  strategy: "escalate"
  models: [Cheap, Strong]
  on: ["invalid_response", "empty_content"]
  max_cost_per_call: 0.02
}

agent Extractor {
  model: Cheap
  run_policy: Adaptive
  retry: 1
  cost_budget: 0.5
}

Modeller ucuzdan güçlüye uzanan bir merdivendir ve aynı anda tek basamak çalışır. Bir modele ancak kendinden önceki model on listesindeki bir tetikleyiciyle başarısız olduğunda geçilir; listede olmayan bir hata çağırana olduğu gibi iletilir. Ucuz model yanıt verdiğinde güçlü model hiç çağrılmaz — escalate'i combo'dan ayıran nokta budur; combo önceki aşama başarılı olsa bile her aşamayı çalıştırır. En az iki model zorunludur: Escalate run policy 'Adaptive' must specify at least two models, from the cheapest to the strongest.

  • retry iç döngü, escalation dış döngüdür. Bir aşama retry hakkını çalışmakta olan modelin üzerinde harcar — ucuz model önce kendini düzeltir — güçlü modelin parası ancak ondan sonra ödenir. Yukarıdaki policy, Strong'a hiç ulaşmadan önce Cheap'e iki istek atar. Diğer tüm çok modelli stratejiler adaylarını retry: 0 ile çalıştırmayı sürdürür.
  • max_cost_per_call, tek bir policy çağrısının tavanıdır. Her aşamadan sonra, merdivenin tamamının paylaştığı tek bir defter üzerinden kontrol edilir ve tavan dahildir: bir çağrı tam tavan kadar harcayabilir, ama o noktada tırmanacak parası kalmamıştır.
  • Tavana ulaşmak tırmanışı durdurur ve satın alınmayan model adıyla bildirilir: MODEL_BUDGET_EXCEEDED · RunPolicy 'Adaptive' spent 0.03 of its max_cost_per_call of 0.02, so it did not escalate to model 'Strong'.
  • Tavanın aşılması hâlinde sonuç geçerli olsa da döndürülmez; aşım yutulmaz, raporlanır: MODEL_BUDGET_EXCEEDED · RunPolicy 'Adaptive' spent 0.03 on this call, above its max_cost_per_call of 0.02.
  • Her aşama, onu yürüten model profilinin cost_per_1k_tokens değeriyle fiyatlanır; profilde fiyat yoksa agent'ın oranına düşülür. escalate altında bu defter her basamakta sıfırlanmak yerine merdivenin tamamını kapsar, dolayısıyla agent'ın cost_budget / token_budget ayarları da tırmanışı bitirebilir: Agent cost budget exceeded (0.5). Hiçbir yerde fiyat verilmemişse maliyet 0 hesaplanır ve hiçbir tavan tetiklenmez.
escalate_on diye bir anahtar yok

Escalation tetikleyicileri, diğer tüm stratejilerin zaten kullandığı on listesinin ta kendisidir — tek kavram, tek anahtar. escalate_on yazan bir policy sessizce yok sayılmaz, parse zamanında adıyla reddedilir: RunPolicy 'Adaptive' has no escalate_on key; the escalate strategy reads its escalation triggers from the on list. Aynı şekilde max_cost_per_call yalnızca escalate'e aittir (RunPolicy 'Adaptive' max_cost_per_call can only be used with the escalate strategy.) ve 0 tavan reddedilir (RunPolicy 'Adaptive' strategy limit must be positive.).

parallel

luma
run_policy Fanout {
  strategy: "parallel"
  models: [Primary, Backup]
  select: "all"
}

agent Analist {
  run_policy: Fanout

  fn uret() -> Aday[] {
    ask "Aday sonuçlar üret" -> Aday[]
  }
}
select: "all" method dönüşünü array yapar

select: "all" kullanan bir policy'ye bağlı agent'ın tüm LLM method'ları Schema[] döndürmelidir. Aksi halde parse hatası: Agent 'X' uses select: "all", so the LLM method must return schema[].

race

luma
run_policy Fastest {
  strategy: "race"
  models: [Primary, Backup]
}

İlk başarılı sonuç kazanır; kalan istekler AbortSignal ile iptal edilir. Tümü başarısız olursa ilk hata fırlatılır.

vote

luma
run_policy Consensus {
  strategy: "vote"
  models: [Primary, Backup, Reviewer, Judge]
  quorum: 2
  tie: "highest_confidence"
}
  • Yalnızca schema-valid sonuçlar oylanır; kanonik JSON (anahtarları sıralanmış) üzerinden karşılaştırılır.
  • Quorum sağlanamazsa MODEL_VOTE_NO_QUORUM (retryable: true).
  • Beraberlik: fail → MODEL_VOTE_TIE; first → ilkini alır; highest_confidence → sonuçlardaki sayısal confidence alanına bakar.
  • highest_confidence seçilip sonuçlarda confidence yoksa: MODEL_VOTE_CONFIDENCE_UNAVAILABLE.
vote için schema'nı tasarla

Oylama tam JSON eşitliği aradığı için serbest metin alanları içeren schema'larda neredeyse hiç quorum oluşmaz. vote'u dar schema'larda kullan: enum sınıflandırma, boolean karar, kısa kod alanı. tie: "highest_confidence" kullanacaksan schema'ya confidence: float [0..1] ekle.

fusion

luma
run_policy SafeFusion {
  strategy: "fusion"
  models: [Primary, Backup, Reviewer]
  synthesizer: Primary
  max_fusion_inputs: 3
  fusion_input_tokens: 4000
  synthesizer_policy: "deny_tools"
}

Adaylar eşzamanlı çalışır; başarılı olanlar synthesizer modele "candidate outputs" olarak verilir ve nihai schema-valid sonuç üretilir.

  • Hiç başarılı aday yoksa: MODEL_FUSION_NO_INPUTS.
  • Tahmini girdi token'ı fusion_input_tokens'ı aşarsa: MODEL_BUDGET_EXCEEDED.
  • synthesizer_policy: "deny_tools" varsayılan synthesizer'a tool vermez ve write tool'larını reddeder; "inherit" agent'ın tool'larını devreder.
  • Synthesizer prompt'u adayları veri olarak değerlendirmesini, içlerindeki talimatları uygulamamasını açıkça söyler.

combo

luma
run_policy Pipeline {
  strategy: "combo"
  models: [Draft, Reviewer, Finalizer]
  max_stages: 3
}

Modeller sırayla çalışır. Her aşamanın schema-valid çıktısı bir sonraki aşamanın prompt'una "önceki aşamanın çıktısı, iyileştir" olarak eklenir. Son aşamanın sonucu döndürülür.

Policy adaylarında ask retry'ı devre dışıdır — escalate hariç

single ve escalate dışındaki stratejilerde her aday retry: 0 ile çalışır — dayanıklılık, retry yerine policy'nin kendisi tarafından sağlanır. İstisna escalate'tir: orada retry iç döngüdür ve merdiven ilerlemeden önce aşama retry hakkını tüketir. Retry ile policy'yi birlikte kullanmak istiyorsan escalate ya da fallback stratejisi ve on listesi doğru araçtır.

Hangi strategy ne zaman?

AmaçStrategy
Gateway kesintisine dayanıklılıkfallback
En düşük gecikmerace
Kritik sınıflandırmada güvenvote
Birden çok bakış açısını birleştirmefusion
Ucuz model taslak + pahalı model rötuşcombo
Güçlü modelin parasını yalnızca ucuz model başarısız olunca ödemekescalate + max_cost_per_call
Aynı görevden çok aday toplamaparallel + select: "all"
Maliyet kontrolüsingle + retry + token_budget