34  Ajanlar için Gözlemlenebilirlik

Bölüm durumu: çevrildi. Kaynak metin: İngilizce 34. bölüm. Tek bir küçük deney: ölçüm düzeneği kurulmuş (instrumentation: koda iz ve metrik kaydı ekleme) beş ajan koşusu. Span’ler OpenTelemetry GenAI uzlaşımlarına (semantic conventions: span, metrik ve öznitelik adları için ortak adlandırma kuralları) göre biçimlendirildi. Amaç, bir iz (trace) kaydının span ve bayt cinsinden gerçekte neye mal olduğunu öğrenmekti. Uzlaşım ayrıntıları hatırlanarak değil, şartnameden okundu: şartname 2026’da depo değiştirdi ve büyük kısmı hâlâ kararsız; bu da başlı başına hesaba katılması gereken bir durum. Yazılım: ollama 0.24.0, llama3.2:3b servis ediyor; Python 3.14.5, Apple Silicon; uzlaşımlar open-telemetry/semantic-conventions-genai deposundan 2026-08-27 tarihinde okundu.

Öğrenme hedefleri. Bu bölümün sonunda:

34.1 Bir ajan izi, üç farkla, bir dağıtık izdir

Önce iyi haber, çünkü sizi tekerleği yeniden icat etmekten kurtarıyor. Bir ajan koşusu, iç içe geçmiş işlemlerden oluşan bir ağaçtır: işlemlerin ebeveynleri, çocukları, zamanlamaları ve hataları vardır. Dağıtık izleme de tam bunun için geliştirildi. Span’ler, iz bağlamının yayılması, örnekleme, dışa aktarıcılar ve zaten işlettiğiniz her arka uç değişmeden geçerli.

span — bir izdeki zamanlanmış tek bir iş birimi: bir adı, başlangıç ve bitiş zamanı, bir ebeveyni, anahtar–değer öznitelikleri ve bir durumu vardır. ↩︎

Bu sözcükler size yeniyse, bütün sözlük tek paragrafta şöyle. İz (trace), tek bir isteğin sistemin içinden geçişinin kaydıdır. İz bir span ağacıdır: her span, zamanlanmış tek bir işlemdir (bir model çağrısı, bir araç çağrısı) ve bir adı, başlangıç ve bitiş zamanı, bir ebeveyni, bir durumu ve bir dizi anahtar–değer özniteliği vardır. Ölçüm düzeneği (instrumentation) bu span’leri üreten koddur; bir programa ölçüm düzeneği kurmak, ona bu kodu eklemek demektir. OpenTelemetry (OTel), bu iş için açık, satıcıdan bağımsız standart ve kütüphaneler bütünüdür. Bağlamın yayılması (context propagation), iz kimliğini çağırandan onun çağırdığı her şeye — süreçler arasında bile — taşır; böylece alt span’ler ebeveynlerini bulur. Dışa aktarıcı (exporter), biten span’leri bir arka uca gönderir; arka uç, onları aradığınız ve okuduğunuz depolama ve arayüzdür. Örnekleme (sampling), izlerin yalnızca bir kısmını saklamaktır. İzler, OpenTelemetry’nin diğer iki sinyalinin yanında durur: metrikler (zaman içinde toplulaştırılmış sayılar, örneğin bir gecikme histogramı) ve log’lar (kütük).

Üç şey gerçekten farklı ve GenAI uzlaşımlarının var olma nedeni de bu üçü:

İlginç olan payload metindir ve büyüktür. Payload, span’in taşıdığı asıl veri demek. Bir HTTP span’i bir yöntem ve bir durum kaydeder. Bir LLM span’inin en yararlı içeriği ise prompt ile tamamlamadır (completion: modelin ürettiği yanıt metni); bunlar kilobaytlarca tutar ve kullanıcı ne yazdıysa onu içerir. Bunun hacme etkisini Bölüm 34.4 ölçüyor, yükümlülüklerinize etkisini ise Bölüm 34.8 ele alıyor.

Maliyet bir öznitelik, sonradan akla gelen bir şey değil. Sıradan span’lerin bir süresi vardır. LLM span’lerinin ayrıca girdi ve çıktı token sayıları vardır ve bunlar paraya çevrilir. Bu da izi, “bu özellik neye mal oldu?” sorusunun doğal cevap yeri yapıyor. İzleme sistemlerine daha önce sorulmayan bir soru bu.

Arıza çoğu zaman bir hata değil. status=OK olan bir span, kendinden emin ama yanlış bir cevabı, uydurulmuş bir araç argümanını ya da adım tavanına çarptığı için durmuş bir ajanı içerebilir. Bölüm 33 tavana çarpmayı tam da bu nedenle ayrı ve açıkça raporlanan bir sonuç türü yaptı: taşıma katmanındaki hiçbir şey koşunun başarısız olduğunu bilmiyor.

34.2 Uzlaşımlar ve ne kadarının oturmuş olduğu

Kendi öznitelik adlarınızla ölçüm düzeneği kurmak, bir satıcının arayüzünü kullanmak, paylaşılan bir pano kurmak ya da başka bir sisteme geçmek isteyene kadar işe yarar. OpenTelemetry’nin GenAI semantic conventions (GenAI anlamsal uzlaşımları; bu bölümde kısaca “uzlaşımlar”) belgeleri, üzerinde anlaşılmış ortak sözlüktür: span’ler, öznitelikler ve metrikler için standart adlar; böylece her araç aynı şeyi aynı adla kaydeder. Bu alt bölümün ana mesajı kısaca şu: adlar hâlâ değişiyor, bu yüzden hedeflediğiniz sürümü sabitleyin; ama biçim öğretilecek kadar oturmuş. Aşağıdaki listeleri ezberlenecek değil, başvurulacak bir şey olarak okuyun. Bugünkü durumlarıyla ilgili iki olgu, tek tek öznitelik adlarından daha önemli.

Taşındılar. 2026 itibarıyla GenAI uzlaşımları, ana semantic-conventions deposundan ayrılarak kendi deposunda, open-telemetry/semantic-conventions-genai içinde yaşıyor; ana depodaki eski yollarda artık yalnızca bir yönlendirme notu var. Ayrılıktan önce yazılmış belgeler, blog yazıları ve ölçüm düzeneği kütüphaneleri, artık şartnameyi barındırmayan sayfaları gösteriyor.

Çoğu kararlı değil. Şartnamedeki her kalem bir kararlılık rozeti taşır. Development rozeti, kalemin hâlâ geliştirme aşamasında olduğunu ve değişebileceğini; Stable ise kalıcı olduğunu söyler. Bu bölüm için deponun 2026’daki bir anlık görüntüsünde span, ajan span’i ve metrik belgelerindeki rozetler sayıldı. (Ayrı öznitelikler değil işaretli kalemler sayıldı, çünkü bir öznitelik birden çok belgede işaretli olabilir. Commit de kaydedilmedi; sonraki sürümlerin farklı olmasını bekleyin.) Span uzlaşımlarındaki 308 işaretli kalemin 286’sı Development, yalnızca 22’si Stable; ajan ve metrik belgelerinde de oran aşağı yukarı aynı. Üstelik bu 22 kalem umduğunuz şey de değil: güncel depoda span belgesindeki her Stable rozeti, çekirdek uzlaşımlardan ödünç alınmış genel bir özniteliğe (error.type, server.address, server.port) ait; hiçbiri bir gen_ai.* adına ait değil. O anlık görüntüde yeni deponun etiketlenmiş (tagged) bir sürümü yoktu.

Development işaretli bir uzlaşım, öznitelik adlarını sürümler arasında değiştirebilir ve bu kalemlerin kabaca onda dokuzu öyle — her gen_ai.* özniteliği de dâhil. Bu, onlardan kaçınmak için bir neden değil (hâlâ tek ortak sözlük onlar); ama ölçüm düzeneğini hangi sürüme göre kurduysanız o sürümü sabitlemek, bunu kaydetmek ve bir sürüm geçişine hazırlıksız yakalanmak yerine onu önceden beklemek için bir neden.

Bununla birlikte biçim, öğretilecek kadar kararlı. Span adları serbest metin değil, kalıplı:

Şartnamenin tanımladığı hâliyle span adlandırma
işlem span adı örnek
bir model çağrısı {gen_ai.operation.name} {gen_ai.request.model} chat llama3.2:3b
bir araç çağrısı execute_tool {gen_ai.tool.name} execute_tool lookup
bir erişim {gen_ai.operation.name} {gen_ai.data_source.id} retrieval kb-main — aramanın kendisi için erişim işlemini kullanın, embeddings’i vektörleri üreten çağrıya bırakın; bunlar tek span değil iki span
bir ajan çağrısı invoke_agent {gen_ai.agent.name} invoke_agent maintenance-bot; ajanın adı yoksa yalnızca invoke_agent

İşlem adları açık bir enum’dur: iyi bilinen değerlerden oluşan ama genişletilebilen bir liste. Şartnamenin kendi ifadesiyle, listedeki değerlerden biri uyuyorsa onu kullanmak ZORUNDASINIZ (MUST); uymuyorsa kendi değerinizi tanımlayabilirsiniz (MAY). O liste, çalışma grubunun bir ajanı ne olarak gördüğünü ortaya koyuyor: chat, text_completion, generate_content, embeddings, retrieval, execute_tool, plan, invoke_agent, create_agent, invoke_workflow, fetch_response, artı bir bellek işlemleri ailesi (oluşturma, arama, güncelleme, silme). Bir izleme şartnamesine bir planlama aşamasının, embedding (gömme) çağrısından ayrı bir erişim işleminin ve bellek işlemlerinin girmesi, Bölüm 23, Bölüm 20 ve Bölüm 26’nın vardığı yeri adilce özetliyor. Liste büyüyor; buradakini kopyalamak yerine güncelini kontrol edin.

Yalnızca span belgesinde 65 öznitelik var; akılda tutulması gerekenler ise birkaç tane:

gen_ai.operation.name        chat, execute_tool, invoke_agent, ...
gen_ai.provider.name         kimin servis ettiği
gen_ai.request.model         ne istediğiniz
gen_ai.response.model        neyin cevapladığı — her zaman aynısı değil
gen_ai.usage.input_tokens    prompt ağırlıklı iş yüklerinde baskın maliyet (31. bölüm)
gen_ai.usage.output_tokens
gen_ai.conversation.id       bir oturumu birbirine diken şey
gen_ai.agent.name            birkaç taneniz varken hangi ajan
gen_ai.tool.name             hangi araç
gen_ai.input.messages        prompt — bkz. "Telemetride hassas veri"
gen_ai.output.messages       tamamlama

Bunlardan ikisi daha yakından bakmayı hak ediyor. Bir takma adla (“latest” gibi sürümsüz bir adla) çağırdığınızda gen_ai.request.model o takma adı, gen_ai.response.model ise isteği gerçekte karşılayan tarihli sürümü gösterir; yani takma ad kullanıldığında ikisi zaten hep farklıdır. Asıl sinyal, sağlayıcı takma adı yeni bir sürüme kaydırdığında gen_ai.request.model aynı kalırken gen_ai.response.model’in değişmesidir. Bu, Bölüm 32’de ele alınan sabitleme (pinning) problemidir: ikisini de kaydederseniz izlerinizde görünür, yalnızca istediğiniz modeli kaydederseniz görünmez. gen_ai.conversation.id ise bir span yığınını yeniden oynatabileceğiniz bir oturuma çeviren şey.

Metrikler de benzer biçimde kalıplı ve içlerinden biri tanıdık gelmeli:

gen_ai.client.token.usage             türe göre token
gen_ai.client.operation.duration      çağrı başına uçtan uca
gen_ai.server.time_to_first_token     31. bölümün TTFT'si, metrik olarak
gen_ai.server.time_per_output_token   token başına decode süresi (1 / decode hızı)
gen_ai.execute_tool.duration
gen_ai.invoke_agent.duration

İlk satır şimdiden değişti; bu da kararsız adlar konusunda yukarıda söyleneni kanıtlıyor. Bu bölümün anlık görüntüsünden sonra şartnamenin ana dalı, girdi ve çıktı token’larını tek bir histogramda karıştıran gen_ai.client.token.usage yerine gen_ai.client.inference.usage.input_tokens ve gen_ai.client.inference.usage.output_tokens gibi ayrı sayaçlar getirdi; bunlara önbellekten okunan girdi ve akıl yürütme çıktısı için alt kümeler de eşlik ediyor. Bir panoyu bu adların üzerine kurmadan önce güncel adları kontrol edin.

Süre metrikleri histogramdır, bu yüzden bir pano onları yüzdelikler olarak gösterir: tipik istek için medyan (p50), kullanıcıların asıl şikâyet ettiği yavaş kuyruk için p95 ya da p99. Ortalamayı değil kuyruğu izleyin; birkaç çok uzun ajan koşusu, kaç kullanıcının beklediğini söylemeden ortalamayı kaydırır.

Bölüm 31’deki servis ölçümleri ayrı bir alıştırma değil; standart metriklerden ikisi. Uzlaşıma göre ölçüm düzeneği kurarsanız prefill/decode ayrımına yakın bir şeyi tek seferlik bir deney olarak değil, bir pano olarak elde edersiniz. İki çekince var. Birincisi, gen_ai.server.* metriklerini model sunucusunun kendisi raporlar; yani bunları yalnızca kendi işlettiğiniz ve uzlaşımı uygulayan bir sunucudan alırsınız. Barındırılan bir API’yi çağırırken yalnızca istemci tarafını görürsünüz; güncel şartname orada akışlı çağrılar için gen_ai.client.operation.time_to_first_chunk metriğini tanımlıyor. İkincisi, “yakın” “aynı” demek değil: şartnamenin kendi tanımına göre TTFT (ilk token’a kadar geçen süre), prefill’in yanı sıra sunucu kuyruğunda beklenen süreyi de içerir; istemciden ölçüldüğünde buna ağ da eklenir. Dolayısıyla yükselen bir TTFT’nin nedeni uzayan bir prompt da olabilir, meşgul bir sunucu da; ikisini ancak sunucu tarafındaki bir ayrıştırma birbirinden ayırabilir.

34.3 Hiyerarşi ve her kimliğin hangi düzeyde kaydedileceği

Bir iz, ancak düzeyler tutarlıysa gezilebilir. Beş düzey var: oturum (bir kullanıcının, belki günlere yayılan konuşması), koşu (tek bir kullanıcı isteği), onu karşılayan ajan ve ajanın içinde yaptığı model çağrıları ile araç çağrıları. Şekildeki gibi tek ajanlı bir sistemde koşu ile ajan aynı invoke_agent span’idir; birden çok ajan varsa her biri koşunun içinde kendi invoke_agent span’ini alır.

Bir ajan koşusu, span'ler olarak
OTURUM · gen_ai.conversation.id · çok koşu, tek kullanıcı conv-042 günler KOŞU · tek kullanıcı isteği invoke_agent maintenance-bot 2,6 s ADIMLAR · dönüşümlü model çağrısı ve araç çağrısı chat llama3.2:3b execute_tool chat llama3.2:3b execute_tool chat MODEL SPAN'LERİNDE usage.input_tokens · usage.output_tokens · response.model maliyet burada kaydedilir, her üst düzeye toplanır ARAÇ SPAN'LERİNDE tool.name · call.arguments · call.result ajanın gerçekte ne yaptığı

Beş düzey ve onları gezilebilir kılan iki kimlik: koşular boyunca aynı kalan bir konuşma kimliği ve koşu başına bir iz kimliği. Token sayıları model span’lerinde durur ve yukarı doğru toplanır; üst düzeylerdeki her şey bu sayılarla yapılan basit bir aritmetik. Öznitelik adları gen_ai. ön eki olmadan gösterildi. Burada ölçülen koşular ortalama 4,8 span tuttu: bir ajan span’i, 2,4 model çağrısı ve 1,4 araç çağrısı. Kutular süreyi değil sırayı gösteriyor; iz arayüzleri aynı ağacı zaman ekseninde kayan çubuklarla (şelale görünümü) çizer ve orada her çubuğun uzunluğu o span’in süresidir.

Yaygın hata, iz sınırını yanlış düzeyde çizmektir ve bunun iki biçimi var. Birincisi, bütün koşuları tek bir ize koymak: bir haftalık konuşma gezilemeyen tek bir ağaca dönüşür. İkincisi, her adıma ayrı bir iz vermek: bu kez koşunun kendisi kaybolur. Hem “bana bu isteği göster” hem de “bana bu kullanıcının haftasını göster” sorularını destekleyen biçim koşu başına bir iz, koşular boyunca tek bir konuşma kimliğidir.

Ağaç süreç ve ağ sınırlarında da kopmamalı. Çok ajanlı bir sistemde başka bir serviste çalışan bir alt ajan (Bölüm 28) ya da bir MCP sunucusu (Bölüm 27) ayrı bir süreçtir; onun span’leri ancak iz bağlamı çağrıyla birlikte taşınırsa aynı ize bağlanır. HTTP çağrılarında bunu W3C Trace Context’in traceparent başlığı yapar; GenAI deposundaki MCP uzlaşımı ise bağlamı her MCP isteğinin params._meta alanında taşımayı öngörüyor.

34.4 Bir iz neye mal olur

Ölçüm düzeneği çoğu zaman maliyeti önceden tahmin edilmeden kurulur; fatura da sonra gelir. Aşağıda beş ajan koşusu var; span’ler yukarıdaki gibi biçimlendirildi:

 task  spans  chat  tool    bytes  w/o content
    1      4     2     1     2467         1363
    2      6     3     2     4059         2029
    3      6     3     2     4260         2032
    4      4     2     1     2489         1370
    5      4     2     1     2562         1388

spans per run        4.8
bytes per run        3,167
  without content    1,636
content share        48.3%

Burada “içerik”, prompt ve tamamlama metni demek (gen_ai.input.messages ve gen_ai.output.messages); “yapı” ise geri kalan her şey — adlar, kimlikler, zamanlamalar, token sayıları. Hacmin yarısı içerik — ve bunlar oyuncak prompt’lar: burada içerik %48,3’tü ve yapı sabitken yalnızca prompt büyüdüğünde bile içeriğin payı hızla artıyor; aşağıdaki izdüşüm bunu gösteriyor. Yukarıdaki koşularda prompt çağrı başına ortalama 301 token tuttu. Bölüm 14 gerçekçi, tek seferlik bir isteği 890 prompt token’ı olarak ölçtü; Bölüm 31’in ana örnek prompt’u ise 4.247 token’dı. Ölçülen yapı koşu başına 1.636 baytta sabit tutulup ölçülen 1.531 baytlık içerik prompt boyutuyla doğru orantılı ölçeklendiğinde:

Prompt boyutuna karşı iz hacmi, yapı sabit tutulmuş
çağrı başına prompt boyutu koşu başına bayt içerik payı yalnız yapının katı
301 token (burada ölçülen) 3.167 %48,3 1,9
890 token (Bölüm 14) 6.163 %73,4 3,8
4.247 token (Bölüm 31) 23.238 %93,0 14,2

İzdüşümü bir tahmin değil, bir büyüklük mertebesi olarak okuyun. İzdüşüm, tamamlamaları da prompt’larla birlikte ölçekliyor; oysa cevaplar bağlamla büyümez (bu yüzden içeriği biraz abartır). Bir ajanın büyüyen geçmişini her adımda yeniden gönderdiğini de hesaba katmıyor (bu yüzden içeriği olduğundan az gösterir).

Ayda bir milyon koşuda bu, 4,8 milyon span ve yalnızca yapı için 1,6 GB’a karşılık gerçekçi prompt’lar da kaydedildiğinde 6,2 GB demek. Aradaki dört kata yakın farkın tamamı içeriği kaydetme kararından geliyor; uzun bağlamda bu fark on dört kata çıkıyor.

Yani prompt’ları kaydetme kararı aynı anda bir depolama kararı, bir saklama kararı ve bir mahremiyet kararıdır; bir varsayılanı açık bırakarak değil, bilinçli olarak verilmelidir. Uzlaşımlar mesaj özniteliklerini Opt-In (isteğe bağlı, açıkça etkinleştirilen) olarak işaretler; yani uzlaşıma uyan bir ölçüm düzeneği, siz açana kadar içeriği kaydetmez. Ama aralarında OpenLLMetry’nin de bulunduğu bazı satıcı SDK’ları içeriği varsayılan olarak kaydeder. Alışıldık çözüm örneklemektir: her koşuda yapı, küçük bir yüzdede ve her hatada içerik.

Bu çözümü anlatmak için bir terim daha gerekiyor, çünkü bir OpenTelemetry örnekleyicisi (sampler) izlerin tamamını tutar ya da atar; içeriği atıp geri kalanı tutamaz. Baş örneklemesi (head sampling) kararını iz başlarken verir; o anda koşunun başarısız olup olmayacağını henüz kimse bilmez. Kuyruk örneklemesi (tail sampling) iz tamamlandıktan sonra karar verir — genellikle telemetriyi alan, dönüştüren ve ileten ayrı bir süreç olan OpenTelemetry Collector’da — bu yüzden hata içeren her izi tutabilir. Dolayısıyla içerik örneklemesi genellikle iki yoldan kurulur: her iz, içerik öznitelikleri silinmiş olarak dışa aktarılır; kuyruk örneklemeli ikinci bir yol ise hatalı izleri ve küçük bir rastgele payı içerikle birlikte eksiksiz tutar. Alıştırma 7 bunu kurmanızı istiyor.

İçerik örneklemesinin iki yolu
yol neyi tutar nasıl
içeriksiz yol her izin yapısı: adlar, kimlikler, süreler, token sayıları içerik öznitelikleri dışa aktarmadan önce silinir; örnekleme yok
tam yol hatalı izler ve küçük bir rastgele pay, içerikle birlikte kuyruk örneklemesi, genellikle Collector’da

Bu ayrımın maliyet atfı için de bir sonucu var. Token sayıları izlerde durduğu için izlerin yalnızca bir kısmını tutan bir örnekleme, harcamanın da yalnızca bir kısmını gösterir. Maliyeti izlerden hesaplayacaksanız her izi (içeriksiz yolun yaptığı gibi) tutun; ya da maliyeti örneklemeden etkilenmeyen token metriklerinden (gen_ai.client.token.usage ya da onun yerini alan sayaçlar) hesaplayın.

34.5 Maliyeti kullanıcıya, takıma ve özelliğe bağlamak

Model span’lerindeki token sayıları, Bölüm 38’in birim ekonomisini mümkün kılan şeydir; mekanizması da gösterişsiz: gruplamak isteyeceğiniz boyutları span’e koyun, çünkü onları geriye dönük ekleyemezsiniz.

Şuna dikkat edin: uzlaşımlar parayı değil token’ı kaydeder. Maliyet, token sayısı çarpı token başına fiyattır ve fiyat girdi, çıktı ve önbellekten okunan girdi için farklıdır. Şartnamedeki gen_ai.usage.cache_read.input_tokens, girdinin önbellekten karşılanan kısmını sayar; bu kısım gen_ai.usage.input_tokens’ın içindedir ve barındırılan sağlayıcılar onu indirimli faturalar (Bölüm 31). Fiyat tablosu izde değil, kodunuzda ya da arka ucunuzda durur. Onu sürümlü tutun: fiyatlar değişir ve geçen ayın harcaması geçen ayın fiyatlarıyla hesaplanmalıdır.

Neredeyse her zaman istenen dört boyut var ve hiçbiri GenAI uzlaşımlarında yok, çünkü bunlar modelin değil sizin boyutlarınız: kullanıcı kimliği, takım ya da kiracı (tenant), özellik ve ortam.

Bunları iliştirmek kulağa geldiği kadar basit değil ve bariz yol işe yaramıyor. OpenTelemetry’de span öznitelikleri miras alınmaz: kök span’e user.id yazmak onu hiçbir alt span’e koymaz ve ne SDK ne de protokol bunu yayar. Bağlamla birlikte yayılan şey Baggage’dır (çağrılar boyunca bağlamla birlikte taşınan anahtar–değer çiftleri). Yani takım ve özellik gibi kimlik içermeyen anahtarları kökte baggage’e koyun ve gördüğü her span’e o baggage anahtarlarını kopyalayan bir span işlemcisi (span processor) kurun; opentelemetry-python’ın contrib paketlerindeki BaggageSpanProcessor bunu yapıyor. Kullanıcı kimliği ise baggage’e girmemeli, çünkü baggage sürecinizin dışına da, her giden çağrıyla birlikte yolculuk eder. Onu süreç içi durumdan (Python’da kökte ayarlanan bir contextvars değişkeninden) okuyup her span’e yazan kendi span işlemcinizle ekleyin; labın 3. adımı ikisini de kurduruyor. Ortam istisnadır: o, SDK’nın ürettiği her span’e iliştirilen Resource’a (telemetriyi üreten servisi ve ortamı tanımlayan ortak öznitelikler) aittir. Bazı arka uçlar öznitelikleri iz düzeyinde toplayıp miras alınıyormuş izlenimi verir; bu, şartnamenin değil arka ucun bir özelliğidir.

Bu boyutları metriklere taşırken bir ayrım gözetin: span öznitelikleri yüksek kardinaliteyi (çok sayıda farklı değeri) kaldırır, metrik etiketleri kaldırmaz. user.id bir span’de sorunsuzdur; aynı boyut bir metriğe etiket olarak eklenirse her kullanıcı ayrı bir zaman serisi açar ve metrik arka ucunun faturası patlar. Kullanıcı kimliği span’lerde kalsın; metriklere yalnızca takım, özellik ve ortam gibi düşük kardinaliteli boyutları ekleyin.

Raporlanması gereken sayı harcama değil, değer birimi başına harcamadır. Oturum başına maliyet, kullanıcıların bitirmediği bir özelliği kayırır (yarıda bırakılan oturumlar kısadır, bu yüzden ucuz görünür); Bölüm 30 aynı argümanı doğru cevap başına maliyet için yaptı. Bir bütçe incelemesinden sağ çıkan sayılar şunlardır: çözülen destek talebi (ticket) başına, tamamlanan görev başına ve kabul edilen öneri başına maliyet. Bunları hesaplamak için sonucun da izde olması gerekir.

34.6 Bir şikâyetten arızalı span’e

İzlemenin amacı, hata ayıklamanın bir esin işi olmaktan çıkıp bir yordama dönüşmesidir. İşe yarar bir yordam şöyle:

  1. Oturumu bulun. Kullanıcının bildiriminden gen_ai.conversation.id’ye ulaşın. Bu kimliğin yalnızca panonuza değil, destek sistemlerinize de ulaşması gerekir; nedeni bu.
  2. Koşuyu bulun. Her koşunun bir izi var ve izler zamana göre sıralı. Şikâyet “yanlıştı” ise aranan koşu genellikle şikâyetten hemen önceki koşudur. Log’larınız iz kimliğini taşıyorsa, log’ları da o iz kimliğiyle süzün; koşunun çevresinde olanlar orada görünür.
  3. Model span’lerini değil, önce araç span’lerini okuyun. Ajanın ne yaptığı gen_ai.tool.name ve argümanlarında görünür; bunları taramak prompt’ları taramaktan çok daha hızlıdır.
  4. Trajectory’nin saptığı ilk adımı bulun. Trajectory, ajanın izlediği çağrı, argüman, sonuç ve karar dizisidir. Bölüm 30’un ayrımı burada da geçerli: yanlış cevap genellikle yanlış karardan birkaç adım sonra gelir.
  5. Ancak ondan sonra o span’in prompt’unu ve tamamlamasını okuyun. İçeriği örnekleme sırasında attıysanız takılacağınız adım budur; hatalarda içeriği saklamanın gerekçesi de bu.
  6. Bunu bir teste çevirin. Bölüm 30’un regresyon disiplini: az önce okuduğunuz iz, hazır bir test senaryosudur.

34.7 OpenTelemetry’nin kapsamadıkları

Bunu açıkça söylemek gerekiyor, çünkü satıcılar bunu bulanıklaştırıyor. İzleme ne olduğunu kaydeder: hangi model, ne kadar sürdü, kaç token, hangi araçlar, hangi hatalar. Çıktının iyi olup olmadığı hakkında söyleyecek hiçbir şeyi yoktur.

Sadakat, doğruluk, güvenlik ve kalite, değerlendirme katmanının işidir (Bölüm 22, Bölüm 30 ve Bölüm 35); bunlar izlerden üretilmez, izlere iliştirilir. Bir hakem puanı bir span özniteliği olarak kaydedilebilir; ama izleme SDK’sı böyle bir puanı kendisi bilemez.

Pratik sonuç şu: “gözlemlenebilirliğimiz var” ile “işe yarayıp yaramadığını biliyoruz” farklı iddialardır. Yeşil span’lerle dolu bir pano, isteklerin üçte birinde kendinden emin biçimde yanlış cevap veren bir üründe de pekâlâ görülebilir.

34.8 Telemetride hassas veri

Prompt’lar, kullanıcı ne yazdıysa onu içerir; bir destek ürününde bu, adlar, adresler, sipariş numaraları ve ara sıra kart bilgileri demektir. Dolayısıyla gen_ai.input.messages’ı kaydetmek, kişisel veriyi gecikme histogramları için tasarlanmış bir sisteme kopyalamak demektir.

Bundan üç sonuç çıkıyor ve üçü de politika beyanı değil, mühendislik işi:

Sınırda, dışa aktarmadan önce maskeleyin. Dışa aktarmadan önce çalışıp veriyi temizleyen tek bir adım, bu işin tek seferde yapılabileceği tek yerdir. Arka uçta maskelemek, verinin çoktan iletildiği anlamına gelir; her ölçüm düzeneğinde ayrı ayrı maskelemek ise aynı işi beş kez yazmak demek. Bu, Bölüm 32’nin tek geçiş noktası (choke point) için yaptığı argümanın telemetriye uygulanmış hâli. Pratik bir pürüz: Python SDK’sında span, işlemcinin bitiş kancasına ulaştığında artık salt okunurdur; bu yüzden temizleme adımı çoğu zaman dışa aktarıcıyı saran bir katman olarak yazılır ya da kendi ağınızın içindeki bir OpenTelemetry Collector’da çalıştırılır (Collector’ın bir maskeleme, yani redaction işlemcisi var). Her iki durumda da kural aynı: metin, sizin denetiminizden çıkmadan önce temizlenir.

Telemetrinin de data residency ve saklama yükümlülükleri var. Data residency, verinin hangi ülke ya da bölgede tutulup işlenebileceğine dair kurallardır. Telemetri, veri tabanınızdaki kişisel verinin bir kopyasıdır ve bir izleme satıcısında duruyor olması onu bu yükümlülüklerden muaf kılmaz. Yükümlülüklerin kendisi Bölüm 38’de ele alınıyor.

İçeriği örneklemek yalnızca bir maliyet değil, bir mahremiyet denetimidir. Yukarıdaki deney konuyu bir depolama meselesi olarak ele aldı; ama bu, aynı zamanda her kullanıcının metnini saklamakla küçük bir örneklemi saklamak arasındaki farktır. İki kaygının aynı kararla çözülmesi işi kolaylaştırıyor: kararı iki gerekçeyi birden gözeterek verin.

34.9 Sezgi kontrolleri

Her birini açmadan önce cevaplayın. Birinci ve üçüncü, izlemenin ne olup ne olmadığıyla ilgili — bu katman kurulmak yerine satın alındığında en sık karıştırılan iki iddia. İkinci, dördüncü ve beşinci soru bölümün sayılarını ve adlarını taşıyor: bir izdeki içerik payı, sessiz bir model yükseltmesini görünür kılan iki öznitelik ve uzlaşımlardaki kararlılık oranı. Altıncısı ise hangi maliyet rakamının raporlanacağını soruyor.

Satıcıların ima ettiğinden daha azı; gerçekten değişen üç şey var.

Payload metin ve büyük, dolayısıyla hacme span sayısı değil prompt’lar hâkim. Maliyet sonradan akla gelen bir şey değil bir öznitelik, çünkü token sayıları paraya çevriliyor ve yukarı toplanıyor. Ve arıza çoğu zaman bir hata değil: status=OK olan bir span, kendinden emin ama yanlış bir cevabı ya da adım tavanına çarpmış bir koşuyu tutabilir.

Diğer her şey (bağlam yayılması, örnekleme, dışa aktarıcılar, arka ucunuz) zaten elinizde.

Bu aynı anda bir depolama, bir saklama ve bir mahremiyet kararı; öyleyse bir kez, bilinçli olarak verin.

Burada ölçüldüğü hâliyle içerik, 301 token’lık oyuncak prompt’larda iz hacminin %48,3’üydü. O içerik doğru orantılı ölçeklendiğinde Bölüm 14’ün gerçekçi 890 token’ında %73,4’e, Bölüm 31’in uzun bağlamlarında %93,0’a çıkıyor. Baytta dört ila on dört katlık bu farkın tamamı tek bir ayardan geliyor.

Alışıldık çözüm örneklemek: her koşuda yapı, küçük bir yüzdede ve her hatada içerik. Bu, hata ayıklamayı önemli olduğu yerde mümkün kılar ve her kullanıcının metnini saklamanızı önler.

Hayır; yanlış göstergeye bakıyorsunuz.

İzleme ne olduğunu kaydeder: modeller, süreler, token’lar, araçlar, istisnalar. Cevabın iyi olup olmadığını bilmez ve 900 ms’de akıcı bir yalan döndüren bir koşu, her taşıma katmanı ölçüsüne göre sağlıklı bir span’dir.

Kalite, değerlendirme katmanının işidir (Bölüm 22, Bölüm 30 ve Bölüm 35) ve izlere puan olarak iliştirilir. “Gözlemlenebilirliğimiz var” ile “işe yarayıp yaramadığını biliyoruz” farklı iddialardır.

Çünkü bir takma adın arkasındaki sürümün değiştiğini ancak ikisi birlikte gösterir.

gen_ai.request.model istediğiniz şey; gen_ai.response.model cevaplayan şey. Takma adla çağırdığınızda ikisi zaten farklıdır; önemli olan zaman içindeki değişim. Sağlayıcı sürümsüz bir takma adı yeni bir tarihli sürüme kaydırdığında — Bölüm 32’nin sessiz yükseltme problemi — ikincisi değişir, birincisi değişmez. İkisini de kaydederseniz yükseltme, olduğu gün izlerinizde görünür; yalnızca birini kaydederseniz bunu haftalar sonra, çıktı kalitesindeki bir gerilemeden öğrenirsiniz.

Yalnızca iki öznitelikle, görünmez bir bağımlılık değişikliği görünür hâle geliyor.

Beklenen bir şey ve çare, hangi sürümü hedeflediğinizi kaydetmiş olmak.

Uzlaşımlar 2026’da depo değiştirdi — open-telemetry/semantic-conventions-genai içine — ve burada sayıldığı hâliyle span belgesindeki işaretli kalemlerin 286’sı Development, yalnızca 22’si Stable. O anlık görüntüde yeni deponun etiketlenmiş bir sürümü yoktu.

Bu, onları kullanmamak için bir gerekçe değil; tek ortak sözlük olarak kalıyorlar ve onları anlayan bir satıcı arayüzü çok şey kazandırır. Tersine, sürümü sabitlemek, bu sabitlemeyi ölçüm düzeneğinin yanına kaydetmek ve bir sürüm geçişine hazırlıksız yakalanmak yerine ona baştan bütçe ayırmak için bir gerekçe.

Oturum başına maliyeti değil, değer birimi başına maliyeti.

Oturum başına maliyet, kullanıcıların tamamlamadığı bir özelliği kayırır ve birkaç adımda gerçek iş yapanı cezalandırır. Bölüm 30 aynı argümanı değerlendirme için doğru cevap başına maliyetle yaptı; burada bu, çözülen destek talebi başına, tamamlanan görev başına, kabul edilen öneri başına maliyet.

Bunu hesaplamak için sonucun izde olması gerekir; bu da kök span’de iki satırlık bir değişiklik. İhtiyaç duymadan önce ekleyin: kaydetmediğiniz bir boyuta göre gruplayamazsınız ve onu sonradan geri kazanmak, izleri ortak bir kimlik üzerinden başka bir sistemle birleştirmek demektir — o kimlik kaydedilmişse mümkün, ama bir pano süzgeci değil bir veri mühendisliği projesi.

34.10 Mülakat soruları

Kaynak konusunda — Bölüm 2’deki çekincenin aynısı. Bu sorular, kitabın kullandığı iki güvenilir açık kaynakta tekrar tekrar karşımıza çıkıyor; bunlara bu bölümün kendi deneyinin cevaplanabilir kıldığı sorular da ekleniyor.

34.10.1 Katmanı anlayıp anlamadığınızı sınayanlar

S: Bir LLM ajanını izlemek, bir mikroservisi izlemekten nasıl farklı?

Yapısal olarak farklı değil; span’ler, ebeveynler, bağlam yayılması ve mevcut arka ucunuz olduğu gibi geçerli. Üç şey farklı: payload metin ve hacme hâkim, dolayısıyla ilginç öznitelik bir durum kodu değil, kilobaytlarca metin; maliyet bir öznitelik, çünkü token sayıları paraya çevriliyor ve ağaçta yukarı toplanıyor; ve başarılı bir span yanlış bir cevap içerebilir, dolayısıyla status=OK koşunun işe yaradığının kanıtı değil.

S: Bir LLM span’ine ne koyardınız?

İşlem adı, sağlayıcı, istenen ve cevaplayan model, iki token sayısı, bir konuşma kimliği ve kendi boyutlarınız — kullanıcı, takım, özellik, ortam — çünkü kaydetmediğiniz şeye göre gruplayamazsınız. Sonra neyi her zaman kaydetmek yerine örnekleyeceğinizi söyleyin: hacmin çoğunu oluşturan prompt ve tamamlamayı.

S: Bu ne kadar telemetri üretecek?

Bir sayıyla değil, bir yöntemle cevaplayın. Koşu başına span çarpı trafik, artı koşu başına bayt — ve baytlara prompt’ların hâkim olduğunu belirtin. Burada oyuncak prompt’larda koşu başına 4,8 span ve 3,2 KB ölçüldü. Bölüm 14’ün gerçekçi 890 token’lık prompt’larına ölçeklendiğinde aynı yapıyla koşu 6,2 KB oluyor ve içerik bunun %73,4’ü; 4.247 token’lık bağlamlarda 23,2 KB ve %93,0. Yani tahmin neredeyse tümüyle içeriği kaydedip kaydetmediğinize dayanıyor.

34.10.2 Bir tane yayına alıp almadığınızı sınayanlar

S: Bir kullanıcı ajanın dün yanlış cevap verdiğini söylüyor. Anlatın.

Önce destek talebinden konuşma kimliği; bu da o kimliğin yalnızca panoya değil, destek sistemlerine de ulaşması gerektiği anlamına geliyor. Sonra şikâyetten önceki koşu, sonra model span’lerinden önce araç span’leri, çünkü ajanın ne yaptığını taramak ne okuduğunu taramaktan daha hızlı. Trajectory’nin saptığı ilk adımı bulun, çünkü yanlış cevap genellikle yanlış karardan birkaç adım sonra gelir. Sonra o span’in prompt’unu okuyun. Sonra onu bir regresyon testine çevirin.

S: LLM izlemesi ekledikten sonra izleme faturanız üç katına çıktı. Neden?

Neredeyse kesinlikle içerik yüzünden. Yapı küçük ve koşu başına kabaca sabit; prompt’lar öyle değil, bağlamla birlikte büyürler. Bu bölümün deneyinden yapılan izdüşüme göre, 301 token’lık prompt’lardan 4.247 token’lık prompt’lara geçmek, span sayısı aynı kalsa bile bir koşuyu 3,2 KB’den 23,2 KB’ye çıkarıyor. Çare, yapıyı her şeyde tutarken içeriği örneklemek ve hatalarda içeriği saklamak.

S: Kişisel veriyi izlerinizden nasıl uzak tutarsınız?

Dışa aktarmadan önce, dışa aktarıcıyı saran bir katmanda ya da kendi ağınızdaki bir Collector’ın maskeleme (redaction) işlemcisinde maskeleyin; böylece maskeleme beş yerde beş farklı biçimde değil, bütün ölçüm düzenekleri için tek seferde yapılır. (Python SDK’sında span işlemcisinin bitiş kancası span’i değiştiremediği için temizlik orada yapılamaz.) Sonra insanların kaçırdığı iki şeyi söyleyin: telemetri, aynı verinin bir kopyası olduğu için veri tabanıyla aynı data residency ve saklama yükümlülüklerini devralır; içerik örneklemesi de bir maliyet denetimi olduğu kadar bir mahremiyet denetimidir, bu yüzden gerekçelendirmesi iki kat kolay bir karardır.

34.11 2026 alet çantası

Bu bölümün deneyi bir modelden başka bir şey gerektirmedi, dolayısıyla birinci tablonun tek satırı var. İkincisini bir menü olarak değil, bir katmanlanma olarak okuyun: OpenTelemetry SDK’sı zemin; ölçüm düzeneği paketleri (OpenTelemetry’nin kendi paketleri, OpenInference ve OpenLLMetry’nin traceloop-sdk’sı) onun üstünde oturuyor ve span’leri üretiyor; Phoenix, Langfuse ve LangSmith ise bunların ürettiğini saklayıp gösteren, arayüzlü arka uçlar. Beta ve 1.0 öncesi sürüm numaralarına dikkat edin — yukarıdaki uzlaşım rozetleriyle aynı olgunluk sinyali onlar.

Bu sayıların geldiği yığın. Python 3.14.5, Apple Silicon
kütüphane kullanılan sürüm burada ne işe yarıyor
ollama 0.24.0 ölçüm düzeneği kurulmuş ajan koşuları için llama3.2:3b servis ediyor

Yukarıda kullanılmayan ama bilinmesi gerekenler:

Daha geniş ekosistem, yazım anındaki sürümler
proje sürüm ne zaman başvurursunuz
opentelemetry-sdk 1.44.0 izleme SDK’sının kendisi; diğer her şeyin üzerine kurulduğu satıcıdan bağımsız zemin
opentelemetry-instrumentation 0.65b0 otomatik ölçüm düzeneğinin altyapısı (opentelemetry-instrument komutu ve temel sınıflar); GenAI ölçüm düzenekleri ayrı paketler olarak yüklenir (ör. opentelemetry-instrumentation-openai-v2) — yayın öncesi sürüme dikkat, uzlaşımların kendi olgunluğuyla örtüşüyor
openinference-instrumentation 0.1.59 Arize’ın LLM çerçeveleri için ölçüm düzeneği, OTel uyumlu
arize-phoenix 20.4.0 yerelde çalıştırabileceğiniz açık kaynak bir iz arayüzü; neyin kaydedileceğini öğrenirken yararlı
langfuse 4.15.1 değerlendirme ve prompt yönetimi ekli, LLM odaklı izleme
traceloop-sdk 0.62.3 OpenLLMetry’nin SDK’sı, OTel’i LLM’e özgü varsayılanlarla sarmalıyor
langsmith 0.11.2 LangChain’in barındırılan izleme ve değerlendirme platformunun istemcisi; zaten LangChain ya da LangGraph üzerine kuruyorsanız doğal seçim

34.12 Lab: bir ajana ölçüm düzeneği kurun, sonra yalnızca ize bakarak hata ayıklayın

34.12.1 Adım 1 — bir ajana uzlaşıma göre ölçüm düzeneği kurun

Model span’leri ve araç span’leri oluşturun: şartnamenin söylediği gibi adlandırılsınlar ve gen_ai.operation.name’i, istenen ve cevaplayan modeli, iki token sayısını ve bir konuşma kimliğini taşısınlar. Uzlaşımların hangi sürümüne göre kurduğunuzu kaydedin; öznitelik adları değiştiğinde bu bilgiyi arayacaksınız.

34.12.2 Adım 2 — kendi iz hacminizi ölçün

Yirmi gerçekçi istek gönderin ve koşu başına span’i, koşu başına baytı ve içerik çıkarılmış hâldeki baytı kaydedin. Aylık trafiğinizle çarpın. Bunu içerik kaydını açmadan önce yapın; böylece sayı faturayı sonradan açıklamak yerine kararı baştan yönlendirir.

34.12.3 Adım 3 — kendi boyutlarınızı ekleyin

Kullanıcı, takım, özellik, ortam. Takım ve özelliği kökte baggage’e koyun, bir baggage span işlemcisi kurun ve her alt span’de göründüklerini doğrulayın. Görünmüyorlarsa işlemci eksiktir, çünkü span öznitelikleri kendiliğinden yayılmaz. Kullanıcı kimliğini, onu süreç içi durumdan okuyan ikinci bir span işlemcisiyle ekleyin (Python’da kökte ayarlanan bir contextvars değişkeni; bu, süreçten hiç çıkmaz). Ortam Resource’a gider.

Sonra baggage’in nereye gittiğini kontrol edin. Baggage, bağlamın ulaştığı her dış çağrıda bir HTTP başlığıyla yolculuk eder — model sağlayıcınıza ve üçüncü taraf araçlara giden çağrılar dâhil; yani baggage’e koyduğunuz her şeyi onlara da gönderirsiniz. Kullanıcı kimliğini oraya koymamanın nedeni bu. Span’leri dışa aktarmadan önce maskelemek bu yolu kapatmaz; o ayrı bir kanal. Takım ve özelliğin de dışarı çıkmasını istemiyorsanız yayıcıyı (propagator), baggage dış çağrılara enjekte edilmeyecek şekilde yapılandırın. Sonra bir günlük veri için özellik başına maliyeti çıkarın.

34.12.4 Adım 4 — değer birimi başına maliyet üretin

Sonucu — çözüldü, terk edildi, aktarıldı (escalation: vaka bir insana ya da daha güçlü bir modele devredildi) — kök span’e ekleyin ve çözülen görev başına maliyeti yeniden hesaplayın. Oturum başına maliyete ve çözülen görev başına maliyete göre çıkan iki sıralamayı karşılaştırın. Bir özelliğin sırası değişiyorsa, adım amacına ulaşmış demektir.

34.12.5 Adım 5 — bir arıza enjekte edin ve ne olduğunu bilmeden bulun

Başka biri bir şeyi bozsun: bayat veri döndüren bir araç, düşürülmüş bir adım tavanı, kırpılmış bir prompt. Sonra yalnızca izi kullanarak onu bulun ve kendinizi süreyle ölçün. Hangi ölçüm düzeneğini keşke kursaydım dediğinizi yazın; o liste bu labın asıl çıktısı.

34.12.6 Adım 6 — maskeleyin ve kanıtlayın

Dışa aktarmadan önce kişisel veriyi temizleyen bir adım ekleyin: dışa aktarıcıyı saran bir katman ya da kendi ağınızdaki bir Collector’ın maskeleme (redaction) işlemcisi. Python’da span işlemcisinin bitiş kancası işe yaramaz; span o noktada salt okunurdur. Bir e-posta adresi ve bir telefon numarası içeren bir istek gönderin, sonra arka ucunuzda ikisini de arayın. İkisinden birini bile bulmak bir bulgu değil, başarısız bir adımdır.

34.12.7 Teslim edilecekler

Trafiğinize ölçeklenmiş hâliyle, içerikli ve içeriksiz koşu başına span ve bayt sayılarınız; özelliğe göre çözülen görev başına maliyet tablosu; enjekte edilmiş arızayı bulmanın ne kadar sürdüğü ve keşke kursaydım dediğiniz ölçüm düzeneği; ve maskelemenin dışa aktarmadan önce gerçekleştiğine dair kanıt.

34.13 Alıştırmalar

  1. Faturadan önce hacim. Bir iş yüküne ölçüm düzeneği kurun, içerikli ve içeriksiz koşu başına span ve baytı ölçün ve aylık trafiğe ölçekleyin. Sonra içerik örnekleme oranınıza karar verin ve gerekçeyi yazın.

  2. Takma adı bulun. Barındırılan bir sağlayıcıya karşı bir hafta boyunca gen_ai.request.model ve gen_ai.response.model’i kaydedin. Takma adın hangi tarihli sürüme çözüldüğünü, gen_ai.response.model’in hafta içinde hiç değişip değişmediğini ve değişseydi neyi fark edeceğinizi raporlayın.

  3. Çözülen görev başına maliyet. Özelliklerinizin iki sıralamasını üretin — oturum başına maliyete göre ve çözülen görev başına maliyete göre. Yer değiştiren her özelliği açıklayın.

  4. Arızayı bilmeden hata ayıklama, süreli. Bir meslektaşınız bir arıza enjekte etsin. Yalnızca izi kullanarak bulun ve süreyi kaydedin. Keşke kursaydım dediğiniz ölçüm düzeneğini ekledikten sonra tekrarlayın ve karşılaştırın.

  5. Maskeleme sınaması. Ölçüm düzeneği kurulmuş yolunuzdan bir e-posta adresi ve bir telefon numarası içeren bir istek gönderin, sonra telemetri arka ucunuzda ikisini de arayın. İkisinden biri bile bulunuyorsa maskelemeniz yanlış yerde.

  6. Uzlaşım kayması. Kullandığınız bir ölçüm düzeneği kütüphanesini alın ve GenAI uzlaşımlarının hangi sürümünü hedeflediğini bulun. Öznitelik adlarını mevcut şartnameyle karşılaştırın ve neyin bozulacağını listeleyin.

  7. Hataları saklayan örnekleme. Başarılı koşuların %5’ini ve arızaların %100’ünü kaydeden bir içerik örneklemesi uygulayın. Gerçek trafikte hiçbir arızalı koşunun prompt’unu yitirmediğini doğrulayın.

34.14 Daha derine

Okumadan önce: işlettiğiniz bir sistemden bir iz açın ve yalnızca ondan “bu istek neye mal oldu?” sorusunu cevaplamayı deneyin. Cevaplayıp cevaplayamamanız bu bölümün konusunun tamamı.

Bu bölüm hiçbir makaleye atıf vermiyor, dolayısıyla alışıldık iki tablo yerine tek bir tablo var. Burada birincil kaynak şartname ve o da sürekli değişiyor. Yukarıda aktarılan orana güvenmek yerine kararlılık rozetlerini kendiniz kontrol edin; o oran belirli bir günde sayıldı.

Bu bölümün ötesi
kaynak ne olduğu
semantic-conventions-genai şartnamenin kendisi, güncel yerinde; herhangi bir öznitelik adına bel bağlamadan önce kararlılık rozetlerini okuyun
OpenTelemetry tracing concepts span’ler, bağlam yayılması ve yukarıdaki her şeyin sizde zaten olduğunu varsaydığı model
The trace SDK specification span işlemcilerinin ve dışa aktarıcıların tanımlandığı yer — maskelemenin dışa aktarmadan önce yapılabileceği kancalar ve hangisinde span’in hâlâ değiştirilebildiği
Sampling şartnamenin tanımladığı hâliyle baş ve kuyruk örneklemesi; her hatalı izi içeriğiyle birlikte eksiksiz tutmanızı sağlayan şey kuyruk örneklemesi
opentelemetry-python SDK ve bir span işlemcisinin gerçekte neye benzediğini okuyacağınız yer
openinference span’leri elle yazmamayı tercih ettiğinizde, yaygın ajan çerçeveleri için hazır ölçüm düzeneği
arize-phoenix yerelde çalıştırabileceğiniz bir iz arayüzü; neyi kaydetmiş olmayı dileyeceğinizi öğrenmenin en ucuz yolu
langfuse / openllmetry değerlendirme ekli LLM’e özgü izlemeye iki yaklaşım; Bölüm 35’e geçiş noktası da burası
LangSmith observability LangChain’in barındırılan, ticari karşılığı; izleri değerlendirmede kullanılan veri kümelerine nasıl çevirdiğini görmek için okuyun

34.15 Akılda kalması gerekenler

  • Bir ajan izi, üç farkla, bir dağıtık izdir. Payload metin ve hacme hâkim; maliyet sonradan akla gelen bir şey değil bir öznitelik, çünkü token sayıları paraya çevriliyor ve yukarı toplanıyor; ve arıza çoğu zaman bir hata değil, dolayısıyla status=OK olan bir span kendinden emin ama yanlış bir cevabı ya da tavanına çarpmış bir koşuyu tutabilir.

  • GenAI uzlaşımları taşındı ve çoğu kararsız. Artık ana semantic-conventions deposundan ayrılarak open-telemetry/semantic-conventions-genai içinde yaşıyorlar; ana deponun eski yollarında hâlâ yönlendirme notları duruyor. Bu bölüm için yapılan sayımda span belgesindeki işaretli kalemlerin 286’sı Development, 22’si Stable ve o anlık görüntüde yeni deponun etiketlenmiş bir sürümü yoktu; kararlı olanların arasında hiçbir gen_ai.* özniteliği yok. Kullanın (tek paylaşılan sözlük onlar), ama sürümü sabitleyin ve sabitlemeyi kaydedin.

  • Span adları serbest metin değil, kalıplıdır. Bir model çağrısı için {işlem} {model}, bir araç çağrısı için execute_tool {tool.name}, bir ajan için invoke_agent {agent.name}. Adları doğru koymak, başkasının hazırladığı bir panonun sizin izlerinizle de çalışmasını sağlar.

  • İstenen modelin yanı sıra cevaplayan modeli de kaydedin. Bir takma adın arkasındaki sürüm sessizce değiştiğinde istenen model aynı kalır, cevaplayan model değişir (Bölüm 32’nin problemi); iki öznitelik, görünmez bir bağımlılık değişikliğini görünür hâle getirir.

  • Bölüm 31’in ölçümleri standart metriklerdir. gen_ai.server.time_to_first_token ve gen_ai.server.time_per_output_token şartnamede yer alıyor; dolayısıyla prefill/decode ayrımı tek seferlik bir deney değil, bir pano olur. Ama yalnızca kendi işlettiğiniz bir model sunucusunda; barındırılan bir API’de yalnızca istemci tarafını görürsünüz.

  • İçerik kaydını açmadan önce telemetri hacmini tahmin edin. Burada ölçüldü: koşu başına 4,8 span ve 3.167 bayt, bunun %48,3’ü prompt ve tamamlama metni — ve bu, 301 token’lık prompt’lardaydı. Yapı sabit tutulup metin Bölüm 14’ün gerçekçi 890 token’ına ölçeklendiğinde 6.163 bayt ve %73,4 içerik; Bölüm 31’in 4.247 token’lık prompt’unda %93,0. Prompt’ları kaydedip kaydetmemek, izleme faturanızı dört ila on dört kat değiştiren bir karardır.

  • İçeriği örneklemek aynı anda bir maliyet ve bir mahremiyet denetimidir. Her koşuda yapı, küçük bir payda ve her hatada içerik; örnekleyici izleri bütün olarak tuttuğu ya da attığı için bu, bütün izler için içeriği silinmiş bir yol ve buna ek olarak kuyruk örneklemeli, tam bir yol gerektirir. Maliyeti izlerden hesaplıyorsanız içeriksiz yol her izi tutmalı. Dışa aktarmadan önce, dışa aktarıcıyı saran bir katmanda ya da kendi ağınızdaki bir Collector’da maskeleyin; böylece maskeleme beş yerde beş farklı biçimde değil, tek seferde yapılsın. Telemetrinin, kopyaladığı veri tabanıyla aynı data residency ve saklama yükümlülüklerini devraldığını da unutmayın.

  • Kendi boyutlarınız yalnızca kök span’e değil, her span’e ulaşmalı. Span öznitelikleri miras alınmaz; kökte yazılan kullanıcı, takım ve özellik, gruplayacağınız model span’lerine hiç ulaşmaz. Onları bir span işlemcisiyle her span’e kopyalayın ve kimliği belli eden hiçbir bilgiyi baggage’e koymayın, çünkü baggage dış çağrılarla da yolculuk eder. Kullanıcı kimliği span’lerde kalsın; metrik etiketlerine yalnızca düşük kardinaliteli boyutlar girsin. Ortam Resource’a, sonuç kök span’e gider. Kaydetmediğiniz bir boyuta göre gruplayamazsınız ve bir bütçe incelemesinin ihtiyaç duyduğu sayı oturum başına maliyet değil, çözülen görev başına maliyettir.

  • İzleme size ne olduğunu söyler, iyi olup olmadığını değil. Kalite, sadakat ve güvenlik değerlendirme katmanına aittir ve izlere puan olarak iliştirilir. Yeşil span’lerle dolu bir pano, kendinden emin biçimde yanlış cevaplar veren bir üründe de pekâlâ görülebilir.