
Session, Trace & Span dalam Observabilitas LLM: Salah Satunya Bukan Level Struktural
Halaman terms Datadog, hasil Google #1 untuk LLM observability sessions traces spans, hanya mendefinisikan dua dari tiga kata itu. Bukan tiga. Kata yang hilang memetakan ke gen_ai.conversation.id, dan alasan hilangnya: spec OpenTelemetry tidak pernah menjadikannya level struktural. Kalau kamu butuh alasan untuk observabilitas itu sendiri, mulai dari sini. Artikel ini melanjutkan dari titik itu: model datanya.
Poin Penting
- Span bersarang di dalam trace; trace berkelompok menjadi session. Sarangnya berjalan dari dalam ke luar: span, lalu trace, lalu session.
- Span adalah satu operasi berwaktu. Trace adalah satu request end-to-end. Session adalah satu percakapan multi-turn.
- Konvensi GenAI OpenTelemetry mendefinisikan span dan atribut
gen_ai.conversation.id. Mereka tidak mendefinisikan level session. - ID trace dan span propagasi otomatis lewat context. Session ID tidak. Kamu yang set, di setiap turn.
Session vs Trace vs Span, Sekilas Pandang
Dalam observabilitas LLM, span adalah satu operasi berwaktu (panggilan model, langkah retrieval), trace adalah pohon span yang dihasilkan satu request, dan session mengelompokkan banyak trace dari percakapan yang sama. Sarangnya berjalan ke dalam: span di dalam trace, trace di dalam session. Pengelompokan ketiga adalah yang tidak seperti kelihatannya.
| Level | Apa yang dibungkus | Berapa lama hidupnya | Siapa yang set ID | Apa yang dijawab | Jumlah tipikal per percakapan |
|---|---|---|---|---|---|
| Session | Banyak trace dari satu percakapan user | Menit hingga hari; berakhir saat timeout tidak aktif atau close eksplisit (ditentukan vendor) | Kamu, manual, di setiap turn | Apakah seluruh percakapan ini sukses? | 1 |
| Trace | Satu request atau turn end-to-end | Milidetik hingga detik | Otomatis (SDK / OTel) | Apa yang terjadi di turn ini? | Biasanya 5–20 |
| Span | Satu operasi: retrieval, panggilan model, panggilan tool | Sub-milidetik hingga detik | Otomatis (SDK / OTel) | Langkah mana yang lambat, salah, atau mahal? | Kira-kira 3–30 per trace |
Angka jumlah dan masa hidup itu adalah rentang tipikal yang bisa kamu harapkan di chatbot RAG atau loop agen, bukan pengukuran dari tes terkontrol. Angkamu akan berbeda. Yang tidak akan berbeda: baris Session adalah yang bukan level struktural di spec, dan bagian "Session: Level yang Kemungkinan Diciptakan Tool Kamu" membuktikannya.
Apa Itu Span, dan Apa Itu Kind Span?
Span adalah satu operasi berwaktu dengan nama, timestamp mulai, timestamp akhir, kode status, dan sekantong atribut key-value. Dalam tracing LLM, atribut adalah tempat data berguna berada: gen_ai.usage.input_tokens, gen_ai.usage.output_tokens, dan gen_ai.request.model memberitahu berapa biaya operasi dan model mana yang menjalankannya.
Span adalah satu operasi, bukan satu panggilan fungsi
Setiap span membawa pointer parent span ID (kosong di root span) yang membentuk tree. Kantong atributnya terbuka: kamu lampirkan context apa pun yang kamu butuhkan. Konvensi span GenAI OpenTelemetry (status: Development) mewajibkan gen_ai.operation.name dan gen_ai.provider.name di setiap span GenAI, dan merekomendasikan atribut pemakaian token di atas.
Satu aturan praktis dari halaman terms Datadog: span LLM, Workflow, dan Agent boleh menjadi root span; span Tool, Task, Embedding, dan Retrieval tidak boleh. Itu aturan Datadog, bukan aturan universal, tapi hanya mereka vendor yang menyatakannya, dan itu menyelamatkanmu dari membangun trace yang mulai di panggilan tool tanpa parent.
Jenis span: ide yang sama, lima kosakata
Setiap tool butuh cara untuk bilang "span ini panggilan model" versus "span ini retrieval". Mereka hanya tidak sepakat soal kata:
| Tool | Istilahnya untuk "jenis operasi" | Nilai |
|---|---|---|
| OpenTelemetry GenAI | Atribut gen_ai.operation.name | 15 nilai yang sudah dikenal (chat, embeddings, execute_tool, invoke_agent, retrieval, dan 10 lainnya); satu WAJIB dipakai jika berlaku, nilai custom diizinkan jika tidak ada yang cocok |
| Datadog | Span kind | LLM, Workflow, Agent, Tool, Task, Embedding, Retrieval |
| OpenInference / Phoenix | Span kind | CHAIN, LLM, TOOL, RETRIEVER, RERANKER, EMBEDDING, AGENT, GUARDRAIL, EVALUATOR, PROMPT |
| Langfuse | Tipe observation | generation, span, event |
| LangSmith | Tipe run | LLM, chain, tool, retriever |
Spec OpenInference mendaftar sepuluh jenis. Datadog mendaftar tujuh. OTel mengambil jalur ketiga: registry atribut GenAI mempublikasikan 15 nilai yang sudah dikenal untuk gen_ai.operation.name (chat, create_agent, create_memory, create_memory_store, delete_memory, delete_memory_store, embeddings, execute_tool, generate_content, invoke_agent, invoke_workflow, plan, retrieval, search_memory, text_completion) dan menyatakan bahwa jika salah satunya berlaku, nilai itu WAJIB dipakai; nilai custom BOLEH dipakai hanya jika tidak ada yang cocok. Jadi ini enum semi-terbuka, bukan ketiadaan enum. Tiga daftar, tiga panjang, dan tanpa keselarasan di antaranya. Kalau kamu sedang memilih tool, jurang kosakata ini lebih penting daripada daftar fitur, karena inilah yang akan menjadi kunci dashboard dan filter alert kamu.
Apa Itu Trace, dan Kenapa Bentuk Tree Penting?
Trace adalah pohon span yang dihasilkan satu request. Satu root span duduk di puncak; semua span lain menggantung di bawahnya lewat edge parent-span-ID. Bentuk tree adalah intinya: log datar memberitahu ada sesuatu yang lambat, tapi tree memberitahu langkah mana yang lambat dan langkah mana yang menghasilkan output buruk.
chat_request (root) 2,340ms
├── retrieval 410ms
│ └── rerank 85ms
├── chat gpt-4o 1,720ms
└── tool_call: search_calendar 190msBaca tree itu dan diagnosisnya langsung: 74% latensi duduk di panggilan model, bukan retrieval. Log datar berisi lima timestamp memberi total yang sama tapi tanpa atribusi.
Loop agen membuat tree ini lebih dalam dan lebih lebar daripada request RAG biasa. Setiap panggilan tool melahirkan sub-tree sendiri; satu turn agen lima langkah bisa dengan mudah menghasilkan 30+ span di bawah satu root. Itu normal, dan itulah alasan pertanyaan granularitas span di bawah ini ada.
Perbedaan antara tracing dan logging juga penting di sini: logging merekam event, tracing merekam kausalitas. Kalau kamu masih menimbang apa yang di-log versus apa yang di-trace, artikel best practices logging LLM kami menarik garis itu.
Session: Level yang Kemungkinan Diciptakan Tool Kamu
Tidak. Session bukan level struktural dalam konvensi GenAI OpenTelemetry. Spec mendefinisikan span dan atribut gen_ai.conversation.id (wajib kondisional, "when available", status: Development), dideskripsikan sebagai pengidentifikasi unik untuk percakapan atau thread yang dipakai untuk mengkorelasikan pesan. Para vendor lalu membangun objek session mereka sendiri di atas atribut itu. Tidak ada pihak lain di SERP ini yang menyatakan status spec secara lugas, jadi inilah dia.
Konsekuensinya adalah kalimat yang menjadi alasan seluruh artikel ini ada:
Session adalah kunci pengelompokan, bukan parent span. Ia tidak propagasi seperti trace ID; kamu yang set sendiri di setiap turn.
Lewatkan satu turn dan turn itu jatuh keluar dari session. Tidak ada propagasi context otomatis untuknya.
Kapan session dimulai dan berakhir?
Ditentukan vendor. Beberapa tool membuka session di trace pertama yang membawa conversation ID baru dan menutupnya saat timeout tidak aktif (Langfuse default ke window yang bisa dikonfigurasi). Yang lain meminta panggilan close eksplisit. Spec tidak bilang apa-apa soal siklus hidup karena spec tidak memodelkan session sebagai objek.
Apa yang terbawa antar-turn, dan apa yang tidak?
Context window model bukan session. Session adalah kunci pengelompokan di atas trace-trace independen. Setiap turn mendapat trace sendiri, root span sendiri, jumlah token sendiri. Yang terbawa adalah atribut conversation ID yang kamu stempelkan di setiap root span. Yang tidak terbawa: latensi, pemakaian token, struktur span. Itu semua per-trace.
Apa yang diukur metrik level session?
Hal-hal yang tidak bisa diukur satu trace: resolution rate (apakah percakapan memecahkan masalah user?), turns-to-answer (berapa trace sebelum user mendapat yang dibutuhkan?), dan percakapan yang ditinggalkan (session tanpa sinyal penutup). Menjalankan eval di trace live pada level session adalah cara kamu menangkap kegagalan multi-turn yang terlihat baik-baik saja per turn.
Kodenya, netral vendor
Snippet ini hanya memakai primitif OTel yang stabil. Tanpa SDK vendor. Ia membuat root span untuk satu turn, child span untuk retrieval, child untuk panggilan model, dan men-set gen_ai.conversation.id agar tiga turn masuk ke satu session:
from opentelemetry import trace
tracer = trace.get_tracer("my-llm-app")
SESSION_ID = "conv-8f3a2c" # same value on every turn
def handle_turn(user_message: str):
with tracer.start_as_current_span("chat_request") as root:
# You set this. It does not propagate automatically.
root.set_attribute("gen_ai.conversation.id", SESSION_ID)
with tracer.start_as_current_span("retrieval") as ret:
ret.set_attribute("gen_ai.operation.name", "retrieval")
docs = retrieve(user_message)
with tracer.start_as_current_span("chat gpt-4o") as llm:
llm.set_attribute("gen_ai.operation.name", "chat")
llm.set_attribute("gen_ai.provider.name", "openai")
llm.set_attribute("gen_ai.request.model", "gpt-4o")
response = call_model(user_message, docs)
llm.set_attribute("gen_ai.usage.input_tokens", 1_204)
llm.set_attribute("gen_ai.usage.output_tokens", 312)
return responsePanggil handle_turn tiga kali dengan SESSION_ID yang sama dan ketiga trace berkelompok di bawah satu session di backend mana pun yang membaca atribut itu. Ubah ID-nya dan kamu memulai session baru. Itulah seluruh mekanismenya.
Kami Membaca Dokumen Lima Vendor Berdampingan. Mereka Tidak Sepakat.
Pada 30 Juli 2026 kami membaca dokumen model data terkini dari Langfuse, LangSmith, OpenInference / Phoenix, dan Datadog secara berdampingan, plus spec span GenAI OpenTelemetry. Empat dari lima menyebut objek yang sama dengan nama berbeda. Hanya satu yang memperlakukan session sebagai objek kelas satu, bukan atribut. Halaman terms Datadog, hasil Google #1 untuk kueri ini, tidak mendefinisikan session sama sekali.
| Konsep | OTel GenAI semconv | Langfuse | LangSmith | OpenInference / Phoenix | Datadog |
|---|---|---|---|---|---|
| Seluruh percakapan | Atribut gen_ai.conversation.id | Session (pengelompokan trace opsional) | Thread (lewat metadata session_id / thread_id) | Atribut span session.id | Tidak didefinisikan di halaman terms |
| Satu request | Trace | Trace | Trace ("kumpulan run") | Trace | Trace |
| Satu operasi | Span | Observation (span / generation / event) | Run ("span yang mewakili satu unit kerja") | Span dengan span kind | Span dengan span kind |
Satu catatan sumber soal baris pertama: session.id OpenInference tidak ada di spec traces yang ditautkan di atas, yang mencakup sepuluh jenis span. Ia didefinisikan di file konvensi semantik OpenInference yang bersaudara sebagai pengidentifikasi unik untuk session. Dua file, satu spec.
Kami tidak mengarang perbandingan lintas vendor; FutureAGI juga mempublikasikan tabel OTel-vs-vendor. Dua tambahan kami adalah baris session (FutureAGI melewatkannya) dan jebakan kata-sama-arti-beda: "observation" Langfuse dan "run" LangSmith adalah objek yang sama dengan span, sementara span kind Datadog dan OpenInference adalah kosakata berbeda untuk ide yang sama.
Langfuse menyebutnya observation, LangSmith menyebutnya run, Datadog menyebutnya span. Objek yang sama, tiga dashboard yang rusak saat kamu migrasi.
Itu bacaan kami soal biaya migrasi, bukan klaim vendor. Tapi itulah alasan filter tersimpan, konfigurasi eval, dan aturan alert yang dikunci ke "observation" atau "run" berhenti bekerja di hari kamu ganti tool. Kamu tidak mengganti nama field. Kamu mengganti nama level. Kalau kamu sedang menimbang dua tool spesifik itu, perbandingan Langfuse vs LangSmith kami membahas lebih dalam soal percabangan ini.
Pembaca mungkin juga sudah punya Opik, PostHog, Sentry, atau Weights & Biases di stack mereka; Google mengaitkan keempatnya dengan llm tracing, dan masing-masing memetakan konsep-konsep ini sedikit berbeda. Memilih yang tepat? Rangkuman platform observability kami mencakup lapangan ini.
Satu catatan kesegaran: konvensi GenAI sudah pindah ke repository sendiri, keluar dari repo semantic-conventions utama. Path lama opentelemetry.io/docs/specs/semconv/gen-ai/ sekarang hanya membawa pointer.
ID Mana Masuk ke Mana?
Trace ID mengidentifikasi satu request dan propagasi lewat context secara otomatis. Span ID mengidentifikasi satu operasi di dalam trace itu, juga otomatis. Correlation ID (atau request ID) datang dari web tier kamu sebelum tracing dimulai, dan inilah yang paling sering orang tertukar dengan trace ID. Session ID adalah yang aneh: milikmu untuk di-set, manual, di setiap turn.
| ID | Di-set oleh | Cakupan | Sering tertukar dengan |
|---|---|---|---|
| Trace ID | Otomatis | Satu request; propagasi lewat context | Correlation ID dari web tier kamu |
| Span ID | Otomatis | Satu operasi | , |
| Parent span ID | Otomatis | Membentuk tree; kosong di root span | , |
| Session / conversation ID | Kamu, manual, setiap turn | Banyak trace | Dikira propagasi otomatis. Ternyata tidak. |
| User ID | Kamu, manual | Banyak session | Session ID |
| Request / correlation ID | Web tier kamu, sebelum tracing dimulai | Satu request HTTP | Trace ID (ini yang paling sering) |
Aturan praktisnya: lampirkan gen_ai.conversation.id sebagai atribut span di root span setiap turn, dan stempelkan user ID di sampingnya. Lewatkan satu turn dan metrik level session kamu diam-diam kehilangan turn itu.
Satu peringatan soal kardinalitas: user ID dan session ID adalah nilai kardinalitas tinggi. Itu penting untuk tagihan indexing backend kamu, yang adalah masalah bagian berikutnya.
Seberapa Granular Sebuah Span Seharusnya?
Dua mode kegagalan, keduanya umum:
Terlalu banyak span. Satu span per panggilan fungsi memberi kamu trace 400 span yang tidak bisa dibaca siapa pun dan tagihan per-span yang tidak disetujui siapa pun. Backend hosted (Datadog, Langfuse Cloud) mematok harga berdasarkan volume span. Loop agen yang cerewet yang menginstrumentasi setiap penggabungan string akan menghabiskan free tier dalam satu sore.
Terlalu sedikit span. Satu span untuk "seluruh chain" memberitahu lambat tapi tidak di mana. Akhirnya kamu menambahkan print statement lagi, yang justru seharusnya diganti oleh tracing.
Patokan umumnya (dan ini patokan, bukan pengukuran): span batas-batas tempat keputusan atau panggilan eksternal terjadi.
- Langkah retrieval: span.
- Panggilan rerank: span.
- Setiap panggilan model: span.
- Setiap panggilan tool: span.
- Setiap pemeriksaan guardrail: span.
- Transformasi in-process murni (format string, parsing JSON, perakitan prompt): atribut di parent span, bukan span sendiri.
Soal kardinalitas, sampling, dan retensi:
- Atribut kardinalitas tinggi (user ID, prompt lengkap) menggembungkan biaya storage. Sample atau potong.
- Kebanyakan backend membolehkan sampling di level trace. Simpan 100% trace error; sample happy path.
- Window retensi bervariasi: 7 hari di free tier, 30–90 hari di paket berbayar. Putuskan sebelum kamu butuh datanya.
Untuk model biaya aktual di balik volume span dan harga per-span, lihat panduan monitoring biaya LLM kami. Kami tidak membangunnya ulang di sini.
Cara Techsy Menyikapi Ini
Untuk pekerjaan agen klien, kami menstandardisasi tiga aturan:
- Satu trace per turn. Jangan pernah gabung dua turn user ke satu trace, bahkan jika agen loop secara internal.
- Session ID distempelkan di setiap root span, di-set di kode aplikasi, tidak pernah dianggap propagasi otomatis.
- Jenis span dijaga di set tetap yang kecil (retrieval, inference, tool, guardrail) agar dashboard selamat dari pergantian vendor.
Aturan ketiga adalah yang dilewati tim, dan yang menyelamatkan migrasi. Kalau kosakata span kamu terikat ke enum satu vendor, setiap alert dan tampilan tersimpan rusak di hari kamu ganti.
Kalau kamu sedang membangun sistem agen dan ingin pendapat kedua soal arsitektur tracing, dapatkan konsultasi gratis.
Tentang Penulis
Mert Batur adalah Co-Founder Techsy.io, tempat tim mengirimkan agen AI, sistem otomasi, dan pipeline voice/SDR untuk klien B2B. Ia menulis soal stack tooling LLM yang benar-benar dipakai tim Techsy di production. Terhubung di LinkedIn.
Pertanyaan yang Sering Diajukan
Apa itu span dalam distributed tracing?
Span adalah satu unit kerja berwaktu: punya nama, waktu mulai, waktu akhir, status, dan sekumpulan atribut. Span saling terhubung lewat referensi parent-span-ID, membentuk tree. Di aplikasi LLM, span biasanya membungkus satu panggilan model, satu retrieval, atau satu pemanggilan tool.
Apa itu span di Datadog?
Di LLM Observability Datadog, span adalah operasi berwaktu yang sama, tapi Datadog menambahkan taksonomi span kind: LLM, Workflow, Agent, Tool, Task, Embedding, dan Retrieval. Hanya kind LLM, Workflow, dan Agent yang boleh menjadi root span. Taksonomi ini spesifik Datadog; bukan bagian dari standar OpenTelemetry.
Apa empat pilar observabilitas?
Empat pilarnya adalah log, metrik, trace, dan (tergantung kerangka siapa) profil atau event. Trace adalah pilar tempat artikel ini berada. Kasus LLM menambahkan kerutan: pemakaian token dan identitas model adalah atribut di span trace, bukan stream metrik terpisah, yang meruntuhkan dua pilar menjadi satu kueri.
Apa empat golden signal observabilitas?
Latensi, traffic, error, dan saturasi. Untuk sistem LLM, latensi berarti time-to-first-token dan total waktu generasi; traffic berarti request per detik per model; error berarti span gagal (kode status ERROR); saturasi berarti habisnya budget token atau kedalaman antrean. Signalnya sama; satuannya beda.
Apakah session bagian dari spesifikasi OpenTelemetry?
Bukan sebagai level struktural. Konvensi span GenAI OTel mendefinisikan gen_ai.conversation.id sebagai atribut wajib kondisional ("when available") untuk mengkorelasikan pesan dalam percakapan atau thread. Ia duduk di span. Vendor seperti Langfuse dan LangSmith membangun objek session atau thread mereka sendiri di atasnya.
Apa bedanya trace ID, span ID, dan correlation ID?
Trace ID mengidentifikasi satu request dan propagasi otomatis melewati semua layanan downstream. Span ID mengidentifikasi satu operasi di dalam trace itu. Correlation ID (atau request ID) dihasilkan oleh web tier kamu sebelum tracing dimulai dan adalah nilai yang paling sering orang kira trace ID. Mereka tumpang tindih di cakupan tapi berasal berbeda.
Berapa banyak span seharusnya satu trace?
Tidak ada jawaban tetap, tapi rentang tipikal adalah 3–30 untuk request RAG dan 10–50+ untuk loop agen dengan banyak panggilan tool. Patokannya: span panggilan eksternal dan titik keputusan, bukan transformasi in-process. Kalau trace kamu melebihi 100 span, kemungkinan kamu over-instrumenting.
Apakah "observation" Langfuse sama dengan span?
Ya. Observation Langfuse adalah objek yang sama dengan span OTel: satu operasi berwaktu dengan atribut. Langfuse membagi observation menjadi tiga tipe (generation, span, event) sedangkan OTel memakai gen_ai.operation.name. Kalau kamu sedang mengevaluasi tool yang membaca trace kamu, rangkuman tool evaluasi LLM kami mencakup mana yang menerima kedua kosakata.
Bagaimana mengelompokkan percakapan chatbot multi-turn ke satu session?
Set pengidentifikasi percakapan yang sama di root span setiap turn. Dalam istilah OTel, itu gen_ai.conversation.id. Di Langfuse, kamu mengoper session_id saat membuat trace. Di LangSmith, kamu men-set metadata session_id atau thread_id. Lewatkan satu turn dan turn itu jatuh keluar dari pengelompokan.
Apakah saya butuh session jika hanya menangani request satu turn?
Mungkin tidak. Session ada untuk mengkorelasikan banyak trace ke satu percakapan. Jika setiap request independen (API klasifikasi, perangkum satu kali), metrik level trace sudah cukup. Tambahkan session saat kamu butuh metrik lintas turn: resolution rate, turns-to-answer, atau biaya level percakapan. Panduan evaluasi LLM kami membahas kapan eval level session sepadan.
Versi Singkatnya
Span bersarang di dalam trace; trace berkelompok menjadi session. Sarangnya nyata, tapi spec hanya menstrukturkan dua dari tiga level. gen_ai.conversation.id adalah atribut yang kamu set sendiri, bukan parent span yang propagasi. Dan vendor yang kamu pilih hari ini menamai objek-objek ini berbeda dari vendor yang akan kamu pakai 18 bulan lagi, jadi jaga kosakata span kamu kecil dan portabel.
Kalau kamu sedang memilih platform, mulai dengan perbandingan platform observability kami. Kalau kamu membangun eval di atas trace kamu, panduan evaluasi LLM melanjutkan dari sini.