ObservabilityOpenTelemetryLLM APIMonitoringProduction Engineering

Quan sát LLM API với OpenTelemetry (hướng dẫn 2026)

1 phút đọc

62% lỗi LLM sản xuất không được phát hiện bởi giám sát HTTP trong hơn 48 giờ. Mã trạng thái 200 OK nghĩa là máy chủ đã phản hồi —không phải câu trả lời đúng, ngữ cảnh truy hồi tươi hay agent không lặp qua 47 lời gọi công cụ thừa. Dashboard của bạn xanh trong khi ảo giác đến tay khách hàng trả phí và một hồi quy mẫu prompt đầu độc mọi phản hồi kể từ triển khai thứ Ba.

Hướng dẫn này xây dựng stack quan sát ba lớp —OTel nền, quy ước ngữ nghĩa GenAI, loại span OpenInference— biến mỗi request người dùng thành cây trace pháp y. Một lời gọi hàm đăng ký nó. Lấy mẫu đuôi giữ mọi trace lỗi mà không thổi bay ngân sách lưu trữ.

Vì sao dashboard giám sát của bạn mù với lỗi LLM

Vì sao APM chuẩn thất bại cho ứng dụng LLM

HTTP 200 không nghĩa là “câu trả lời đúng”. Nghĩa là máy chủ đã phản hồi. Dự án OpenTelemetry cung cấp định dạng wire và hạ tầng collector —nhưng ứng dụng LLM cần quy ước ngữ nghĩa trên nền tảng đó. APM chuẩn thất bại vì ứng dụng LLM thất bại theo cách mã trạng thái HTTP không thể biểu đạt:

  • Ảo giác. Model trả câu trả lời tự tin, định dạng đẹp. Mọi thông tin trong đó đều sai. Trạng thái HTTP: 200.
  • Từ chối thầm lặng. Model lẽ ra phải trả lời. Nó từ chối —lịch sự, JSON hoàn hảo. Trạng thái HTTP: 200.
  • Tăng vọt chi phí. Một request tạo 32,000 token suy nghĩ vì mức nỗ lực suy luận được đặt “high” cho tác vụ phân loại đơn giản. Trạng thái HTTP: 200. Không dashboard nào hiển thị số token suy nghĩ.

Bạn không cần thấy “request thành công”. Bạn cần thấy “độ liên quan ngữ cảnh truy hồi là 0.3, gây điểm faithfulness tạo sinh 0.4, nghĩa là người dùng nhận câu trả lời sai dù mọi thứ nhìn xanh”. Trace lời gọi embedding song song với hoàn tất chat là cần thiết khi chất lượng truy hồi giảm —instrument cả hai endpoint trong một trace lộ ra bức tranh đầy đủ.

Kiến trúc ba lớp

Không phải ba lựa chọn. Bạn cần cả ba.

Lớp 1: OpenTelemetry nền. Định dạng wire (OTLP), truyền ngữ cảnh (W3C trace context), pipeline collector. Đây là chất nền —mọi backend quan sát nói OTLP. Mọi microservice phát span OTel. Không lớp này, bạn khóa trong định dạng độc quyền nhà cung cấp. Có nó, bạn đổi backend không cần instrument lại dòng nào.

Lớp 2: Quy ước ngữ nghĩa OTel-GenAI. Thuộc tính span chuẩn hóa cho thao tác LLM: gen_ai.system (nhà cung cấp nào), gen_ai.request.model (phiên bản model nào), gen_ai.usage.input_tokensgen_ai.usage.output_tokens (tiêu thụ token), gen_ai.operation.name (chat so với embedding so với thực thi công cụ). Không lớp này, mọi span LLM của bạn trông giống hệt —không phân biệt được hoàn tất chat với lời gọi embedding.

Lớp 3: Loại span OpenInference. Mười bốn loại span nhận thức LLM mà quy ước GenAI chưa liệt kê: LLM, CHAIN, RETRIEVER, TOOL, EMBEDDING, AGENT, RERANKER, GUARDRAIL, EVALUATOR, CONVERSATION, VECTOR_DB và hơn thế. Không lớp này, trace pipeline RAG của bạn là danh sách phẳng lời gọi HTTP. Có nó, bạn thấy EMBEDDING —RETRIEVER —RERANKER —LLM như giai đoạn riêng —và biết chính xác giai đoạn nào thêm đỉnh độ trễ 800ms.

Cây trace là đơn vị hiểu tối thiểu

Một dòng log cô lập không chẩn đoán được vấn đề LLM. Câu hỏi không bao giờ “lời gọi API này trả gì?” Mà là “chuỗi nhân quả đầy đủ là gì: truy vấn người dùng —phân loại ý định —chunk truy hồi —điểm reranker —prompt cuối —phản hồi LLM —điểm đánh giá?” Cây trace bắt chuỗi đó. Một trace = bản ghi pháp y đầy đủ của một tương tác người dùng.

Vì sao quan sát là bắt buộc

Chi phí không có khả năng nhìn

Một vòng lặp agent không giám sát đốt $5,000 cuối tuần tại một triển khai tôi điều tra. Agent rơi vào vòng lặp gọi công cụ tối thứ Sáu —search_kb("return policy") trả “không có kết quả”, nên agent gọi search_kb("return policy EU"), rồi search_kb("return policy Europe"), rồi 44 biến thể nữa —mỗi cái một lời gọi API LLM đầy đủ kèm ngữ cảnh. Không ai để ý cho đến cảnh báo thanh toán thứ Hai.

Gán chi phí mỗi span —gen_ai.cost.input, gen_ai.cost.output, gen_ai.cost.total gắn vào mọi span LLM— bắt điều này trong vài phút, không phải nhiều ngày. Đặt cảnh báo: nếu bất kỳ trace đơn lẻ nào vượt $2.00 chi phí API tích lũy, kích hoạt thông báo. Chi phí hạ tầng cảnh báo ít hơn một sự cố cuối tuần.

Gán chi phí là lớp phát hiện. Cho lớp phòng ngừa —chiến lược caching, chọn tầng model và xử lý batch— xem hướng dẫn chiến lược tối ưu chi phí của chúng tôi.

Chất lượng không có khả năng nhìn

Di chuyển model từ GPT-4o sang GPT-5.5 trông sạch trên dashboard HTTP. Độ trễ cải thiện 15%. Tỷ lệ lỗi không đổi. Điều dashboard không cho thấy: model mới xử lý đầu ra có cấu trúc hơi khác —null xuất hiện trong ba trường chưa từng null trước đó. Định dạng là JSON hợp lệ. Logic kinh doanh tiêu thụ nó lặng lẽ vỡ.

Điểm đánh giá gắn span bắt điều này trong năm phút. Rubric đánh giá của bạn chạy liên tục trên trace sản xuất. Bất kỳ giảm faithfulness, tuân thủ ngữ cảnh hay tuân thủ định dạng nào kích hoạt cảnh báo —trước khi người dùng nhận ra, trước khi ticket hỗ trợ tích tụ, trước khi chỉ số chất lượng quý bị đánh. Cho pipeline CI/CD chạy các đánh giá này trước triển khai, xem hướng dẫn thử nghiệm và đánh giá của chúng tôi.

Tuân thủ không có khả năng nhìn

Kiểm toán viên SOC 2 Type II hỏi: “Cho xem bản ghi đầy đủ lời gọi API cho người dùng X ngày Y —dữ liệu nào gửi, model nào xử lý, cái gì trả về?” Nếu lời gọi API LLM của bạn không tạo trace có cấu trúc với chính sách lưu giữ đúng, câu trả lời là: “chúng tôi không thể”. Đó không phải phát hiện. Là hạn chế —một từ đắt hơn nhiều trong báo cáo kiểm toán.

Trace có cấu trúc thỏa mãn yêu cầu dấu vết kiểm toán. Cho kiểm soát truy cập và xử lý dữ liệu hoàn tất sẵn sàng SOC 2 —log truy cập có cấu trúc và chính sách lưu giữ căn chỉnh khung tuân thủ của bạn— đóng khoảng trống.

Cách thiết lập quan sát LLM

Bước 1: đăng ký một lời gọi

Một lời gọi hàm trong module khởi động. Vậy đó.

from fi_instrumentation import register, ProjectType, SemanticConvention

trace_provider = register(
    project_name="checkout_assistant",
    project_type=ProjectType.OBSERVE,
    semantic_convention=SemanticConvention.OPENINFERENCE,
    metadata={"git_sha": "abc123", "environment": "production"},
    batch=True,
)

from openinference.instrumentation.openai import OpenAIInstrumentor
from openinference.instrumentation.langchain import LangChainInstrumentor

OpenAIInstrumentor().instrument(tracer_provider=trace_provider)
LangChainInstrumentor().instrument(tracer_provider=trace_provider)

Tham số semantic_convention là quyết định kiến trúc then chốt ở đây. Đặt thành OPENINFERENCE, OTEL_GENAI hoặc OPENLLMETRY —code instrument của bạn không đổi. Chỉ tên thuộc tính trên span phát ra thay đổi. Điều này quan trọng khi đổi backend quan sát: Datadog mong một quy ước, Langfuse quy ước khác, SigNoz quy ước thứ ba. Một công tắc cấu hình. Không đổi code.

Phạm vi: 50+ framework Python, 39 gói TypeScript, 24 module Java, C#. OpenAI, Anthropic, LangChain, LlamaIndex, Haystack, DSPy —tất cả tự instrument.

Bước 2: làm giàu span

Span không user_id, session_idprompt_version là trẻ mồ côi. Bạn thấy cái gì xảy ra nhưng không cho ai hoặc với cấu hình nào.

from contextlib import contextmanager

@contextmanager
def using_attributes(**kwargs):
    # Attach attributes to the current span; all child spans inherit them
    with tracer.start_as_current_span("user-interaction") as span:
        for key, value in kwargs.items():
            span.set_attribute(key, value)
        yield span

with using_attributes(
    session_id="sess_a1b2c3",
    user_id="user_42",
    metadata={
        "prompt_template": "checkout_v3.2",
        "ab_bucket": "treatment",
        "feature_flag": "new_upsell_logic"
    }
):
    response = client.chat.completions.create(...)

Bộ thuộc tính tối thiểu mỗi trace: session.id, user.id, prompt.version, feature.id, tenant.id. Không chúng, dữ liệu trace không trả lời được “prompt checkout_v3.2 gây hồi quy hay thay đổi phiên bản model gây?” —câu hỏi đầu tiên bạn sẽ hỏi trong sự cố.

Bước 3: eval-as-span-attribute

Điểm đánh giá sống trong cơ sở dữ liệu riêng, cần join thủ công ID trace, là điểm không ai nhìn. EvalTag sửa điều này: khai báo evaluator lúc đăng ký, điểm của chúng ghi trực tiếp vào span gốc như thuộc tính gen_ai.evaluation.<rubric>.score —không thêm độ trễ request.

register(
    project_name="checkout_assistant",
    evaluators=[
        "GROUNDEDNESS",         # Are claims supported by retrieved context?
        "CONTEXT_ADHERENCE",    # Is the answer using the provided context?
        "PROMPT_INJECTION",     # Is there an injection attempt in the input?
        "TASK_COMPLETION",      # Did the model complete the requested task?
    ],
)

Evaluator chạy bất đồng bộ —người dùng nhận phản hồi không chờ chấm điểm. Điểm xuất hiện trên span trong vài giây. Dashboard của bạn cập nhật. Nếu GROUNDEDNESS rơi dưới 0.7 trong cửa sổ 5 phút, cảnh báo kích hoạt. Không pipeline đánh giá riêng. Không tương quan thủ công. Một cây trace, một nguồn sự thật.

Bước 4: lấy mẫu đuôi

Lấy mẫu đầu —“giữ 10% mọi trace ngẫu nhiên”— là mặc định của hầu hết thiết lập APM. Với ứng dụng LLM điều này sai thảm khốc. Lỗi hiếm. Chi phí bất thường hiếm. Đầu ra chất lượng thấp hiếm. Mẫu ngẫu nhiên 10% đồng đều vứt 90% trace thực sự quan trọng.

Lấy mẫu đuôi đảo ngược điều này: collector thấy trace đầy đủ trước quyết định giữ hay không. Quy tắc giữ:

  • Giữ 100% trace có lỗi (5xx, timeout, giới hạn tốc độ)
  • Giữ 100% trace có điểm đánh giá dưới ngưỡng
  • Giữ 100% trace có chi phí trên p95
  • Giữ 1–10% trace sạch, nhanh, đúng

Chi phí lưu trữ giữ kiểm soát. Trace bạn thực sự cần gỡ lỗi vẫn khả dụng.

Bước 5: lưu giữ ba tầng

Đừng trả giá ClickHouse cho dữ liệu tuân thủ quy định bạn truy cập mỗi năm một lần.

TầngLưu trữThời lượngNội dung
NóngClickHouse / InfluxDB14-30 ngàyMọi trace đã lưu giữ —dashboard trực tiếp và cảnh báo
ẤmCột (S3/Parquet)90 ngàyTrace đầy đủ —tuân thủ và gỡ lỗi hồi cứu
LạnhLưu trữ đối tượng (S3 Glacier)1-7 nămTrace nén —lưu giữ theo quy định

Tầng nóng cho vận hành. Tầng ấm cho gỡ lỗi sự cố quý trước. Tầng lạnh cho kiểm toán viên. Mỗi tầng tốn ít hơn khoảng một bậc độ lớn so với tầng trên.

Mẫu trace sản xuất cho khối lượng cụ thể

Topology trace RAG

Trace phẳng pipeline RAG vô dụng. Bạn cần thấy mỗi giai đoạn như span riêng:

EMBEDDING span [model: text-embedding-3-small, tokens: 450, latency: 32ms]
  → RETRIEVER span [vector_db: pgvector, top_k: 20, index: hnsw, latency: 8ms]
    → RERANKER span [model: bge-reranker-large, candidates: 20→5, latency: 45ms]
      → LLM span [model: gpt-4o, input_tokens: 2840, output_tokens: 380, latency: 1.2s]

Khi chất lượng truy hồi giảm, bạn nhìn span RETRIEVER —điểm tương đồng thấp? Kiểm tra model embedding có trôi dạt. Khi chất lượng tạo sinh giảm nhưng truy hồi nhìn ổn, bạn nhìn span LLM —chunk truy hồi được đưa đúng thứ tự? System prompt còn nguyên? Topology cho bạn biết nhìn đâu, không chỉ “có gì đó sai”. Cho kiến trúc pipeline RAG đầy đủ sau mẫu trace này, xem hướng dẫn RAG sản xuất của chúng tôi.

Topology trace agent

Agent LangGraph 6 nút trace phẳng là ác mộng gỡ lỗi. Bạn thấy 100 span. Không biết nút nào kích hoạt công cụ nào, công cụ nào lỗi hay vòng lặp bắt đầu đâu.

Topology đúng:

Root: AGENT span [session_id, user_id, task]
  —Reasoning span: "plan to answer user's question about order status"
    —TOOL span: lookup_order(order_id="ORD-12345") [latency: 180ms, status: success]
  —Reasoning span: "order found, now check shipping"
    —TOOL span: track_shipment(tracking_id="ZYX-987") [latency: 340ms, status: success]
  —LLM span: synthesis [model: claude-sonnet-4, input_tokens: 1520, output_tokens: 210]

Cho LangGraph cụ thể, thêm langgraph.node.name, langgraph.node.type và sự kiện cạnh điều kiện vào mỗi span. Không chúng, khi agent 6 nút của bạn kẹt trong vòng lặp, bạn không nói được nút nào là vấn đề. Có chúng, trace hiển thị như đồ thị topology —và nút lặp nhìn ra ngay. Cho mẫu điều phối đa agent tạo các trace này, xem hướng dẫn kiến trúc đa agent của chúng tôi.

Gán chi phí mỗi span

Mỗi span LLM mang gen_ai.cost.input, gen_ai.cost.output, gen_ai.cost.cache_readgen_ai.cost.total. Ở cấp gateway, duy trì ngân sách phân cấp: tổ chức —đội —người dùng —phiên. Tạo phân tách chi phí tháng theo đội, theo model, theo ca sử dụng —tự động, từ dữ liệu trace. Không đối soát thanh toán thủ công. Không “khoản mục AI là hộp đen”. Cho cấu hình throttling request theo người dùng và endpoint ngăn vòng lặp agent mất kiểm soát nổ ngân sách, xem tài liệu giới hạn tốc độ.

Lỗi quan sát tốn kém trong sản xuất

Instrument chỉ SDK nhà cung cấp

Bạn instrument SDK gốc Datadog vì đó là đường nhanh nhất đến dashboard. Sáu tháng sau, đội muốn đánh giá Langfuse cho trace riêng LLM. Mọi điểm gọi cần instrument lại.

Sửa: instrument bằng OTel. Nó là lớp trừu tượng. Đổi backend bằng cách đổi cấu hình exporter, không phải code instrument. SDK nhà cung cấp là mục tiêu đầu ra, không phải framework instrument.

Lấy mẫu ngẫu nhiên đồng đều

Tỷ lệ mẫu của bạn 10%. Bạn đang ngẫu nhiên vứt 90% trace —gồm trace người dùng bị tính phí đúp vì agent lặp, trace nỗ lực chèn prompt gần thành công, và trace một request tiêu thụ $18 token suy nghĩ.

Sửa: lấy mẫu đuôi. Collector thấy trace đầy đủ rồi quyết định. Lỗi, chi phí bất thường và đầu ra chất lượng thấp: giữ 100%. Trace sạch: giữ tỷ lệ nhỏ cho so sánh đường cơ sở.

Không topology LangGraph trong trace agent

Bạn triển khai agent đa nút. Trace hiển thị 87 span mỗi request người dùng trong danh sách phẳng. Thứ Ba tuần trước agent kẹt trong vòng lặp. Mất ba giờ xác định nút thủ phạm —vì “87 span phẳng” không cho bạn đồ thị thực thi.

Sửa: langgraph.node.namelanggraph.node.type trên mỗi span. Sự kiện cạnh điều kiện. Trình xem trace của bạn nên hiển thị agent như đồ thị, không danh sách.

Bỏ qua span gateway phát ra

Bạn trace code ứng dụng kỹ lưỡng. Nhưng bạn truy cập LLM qua nền tảng API thống nhất —span gateway (độ trễ phía nhà cung cấp, quyết định định tuyến, hit/miss cache, kích hoạt fallback) vô hình với tracer ứng dụng. Khi độ trễ tăng vọt, bạn không nói được là code mình, gateway hay nhà cung cấp.

Sửa: span gateway là phần trace của bạn. Nếu nền tảng API phát span OTel, cấu hình collector nhận chúng. Endpoint API thống nhất nghĩa là một điểm tích hợp cho quan sát gateway —thiết lập một lần, mọi lời gọi model được bao phủ.

Cho mẫu triển khai kết hợp quan sát với chuỗi fallback, logic retry và giám sát chi phí giữa các model, xem hướng dẫn tối ưu sản xuất.

Câu hỏi thường gặp

Tôi có cần cả ba lớp (OTel nền + GenAI + OpenInference)?

Có. OTel nền ngăn khóa nhà cung cấp. Quy ước ngữ nghĩa GenAI chuẩn hóa thuộc tính riêng model (số token, danh tính model) để dashboard không vỡ khi đổi nhà cung cấp. Loại span OpenInference cho bạn topology nhận thức LLM —không chúng, mọi span là “một lời gọi API” và bạn không phân biệt truy hồi, tạo sinh và thực thi công cụ.

Chi phí hiệu suất bao nhiêu?

Tạo span và đặt thuộc tính: dưới 1% ảnh hưởng độ trễ. Evaluator (EvalTag): không ảnh hưởng độ trễ hướng người dùng —chạy bất đồng bộ sau khi gửi phản hồi. Lấy mẫu đuôi: chạy trong collector, không trong tiến trình ứng dụng. Tổng chi phí không đáng kể so với độ trễ 200ms–10s của chính lời gọi API LLM. Cho giảm chi phí đầu vào trên trace lặp lại, chiến lược prompt caching kết hợp tự nhiên với gán chi phí cấp span.

Tự lưu trữ hay SaaS cho quan sát?

Tự lưu trữ: SigNoz (gốc OTel, dashboard GenAI) + ClickHouse + Grafana. Tốt nếu bạn đã chạy hạ tầng OTel. SaaS: Langfuse Cloud (trace trước, ClickHouse tinh chỉnh), Datadog LLM Observability. Tốt nếu muốn dashboard trong 10 phút. Trừu tượng OTel nghĩa là bạn có thể bắt đầu SaaS và di chuyển tự lưu trữ không cần instrument lại.

Làm sao che PII khỏi trace LLM?

Che tại collector —không phải code ứng dụng. Mẫu regex cho số thẻ tín dụng, SSN và địa chỉ email. Phân loại NER cho tên và địa chỉ vật lý. Quy tắc tùy chỉnh cho API key và token truy cập. Nguyên tắc: bí mật thô không bao giờ vượt ranh giới mạng của bạn. Chúng bị gỡ trong bộ xử lý collector trước khi xuất đến backend ngoài.

Đường đơn giản nhất đến quan sát LLM thống nhất?

Một điểm tích hợp. Khi mọi lời gọi model —GPT, Claude, Gemini, DeepSeek— chảy qua một endpoint API, bạn cấu hình xuất OTel một lần. Span gateway phát ra (độ trễ phía nhà cung cấp, quyết định định tuyến, tỷ lệ cache hit, kích hoạt fallback) đến định dạng sẵn cùng span ứng dụng. Không khâu trace từ ba SDK nhà cung cấp. Không tự hỏi đỉnh độ trễ trong code mình, gateway hay nhà cung cấp —vì cả ba trong cùng cây trace. Bắt đầu một API key cho mọi model và thấy trace thống nhất trên nền tảng TokSpan.

Quan sát cho ứng dụng LLM không phải mối lo “tổ chức trưởng thành”. Là mối lo “triển khai sản xuất đầu tiên”. Chi phí không có nó đo bằng sự cố cuối tuần, hồi quy chất lượng thầm lặng và hạn chế kiểm toán —tất cả đắt hơn thiết lập ba lớp mô tả ở đây.

Mẫu đăng ký mất một lời gọi hàm. Gắn eval-as-span mất không độ trễ thêm. Lấy mẫu đuôi giữ hóa đơn lưu trữ kiểm soát trong khi giữ mọi trace quan trọng. Bắt đầu một model trong một dịch vụ. Instrument nó. Xem cây trace một ngày. Bạn sẽ tìm thấy điều bạn không biết đang xảy ra —ai cũng vậy trong ngày đầu có quan sát thực.