# OpenTelemetry cho ứng dụng LLM: một lần đo, gửi trace sang cả Datadog lẫn Langfuse tự host

> Khi cả Datadog lẫn Langfuse đều đọc chung bộ thuộc tính GenAI của OpenTelemetry, FDE không còn phải chọn phe ngay từ dòng code đầu tiên.

Bản gốc: https://fdetimes.net/vi/cong-cu/opentelemetry-trace-ung-dung-llm/

Tháng 12/2025, Datadog thông báo sản phẩm LLM/Agent Observability của mình hỗ trợ native OpenTelemetry GenAI Semantic Conventions, áp dụng cho bộ quy ước từ phiên bản 1.37 trở lên.

Nghe như một dòng changelog, nhưng nó gỡ một nút thắt mà FDE nào làm dự án LLM cho doanh nghiệp cũng dễ gặp: đội vận hành của khách đã dùng Datadog, còn đội dữ liệu lại muốn giữ trace trong một Langfuse tự host.

Nếu mỗi backend đòi một SDK riêng, code ứng dụng sẽ dính chặt vào vendor đó. Một chuẩn chung làm thay đổi bài toán: Langfuse cũng tuyên bố nhắm tới tuân thủ cùng bộ quy ước GenAI của OpenTelemetry, nên một lần instrument có thể phục vụ cả hai phía.

Đây đúng là việc FDE hay phải làm ở site khách: thiết kế pipeline sao cho quyết định chọn công cụ của khách không kéo theo việc viết lại code ứng dụng.

## OTel GenAI thực ra chuẩn hóa cái gì?

OpenTelemetry vốn là chuẩn mở cho trace, metric và log. Phần GenAI bổ sung một bộ tên thuộc tính thống nhất cho các lời gọi mô hình, để backend nào nhận trace cũng hiểu span nào là lời gọi LLM và thuộc tính nào chứa thông tin gì.

Nguồn chính thức cần đọc đã chuyển chỗ. Các quy ước GenAI được tách khỏi repo semantic-conventions chung sang một repo riêng, semantic-conventions-genai, bao gồm spans, metrics và events cho GenAI client. Khi tranh luận với khách về một tên thuộc tính, hãy dẫn link repo mới này, đừng dẫn trang cũ.

Datadog mô tả cách dùng khá gọn: instrument ứng dụng LLM một lần bằng OTel, rồi xuất GenAI span qua pipeline OTel Collector sẵn có. Tài liệu của hãng còn nói rõ có thể gửi trace OTel thẳng vào mà không cần SDK Agent Observability hay Datadog Agent.

## Khi nào FDE nên dùng nó ở site khách?

Thử hình dung một khách hàng ngân hàng. Đội SRE muốn thấy độ trễ của agent ngay cạnh dashboard hạ tầng trên Datadog. Đội AI muốn đọc từng prompt và câu trả lời trong Langfuse chạy trên hạ tầng nội bộ. Nếu bạn cài hai SDK, mỗi thay đổi framework sẽ phải sửa hai lần, còn hai bên sẽ nhìn hai bức tranh lệch nhau.

Cách gọn hơn: instrument theo OTel GenAI, đẩy tất cả về một OTel Collector, rồi để Collector chia cùng một trace thành hai nhánh song song. Cách này càng hợp khi khách chưa chốt vendor, vì đổi backend về sau chỉ là sửa cấu hình exporter.

**Điểm mấu chốt:** Instrument theo chuẩn mở, để quyết định chọn vendor nằm ở file cấu hình chứ không nằm trong code.

## Một cấu hình Collector tối thiểu

Cấu hình xoay quanh hai chi tiết. Datadog định tuyến span OTLP vào Agent Observability nhờ header `dd-otlp-source=llmobs`. Langfuse, kể cả bản tự host, nhận trace OTLP tại endpoint `/api/public/otel`. Phác thảo có thể trông như sau, với endpoint và header xác thực điền theo tài liệu của từng bên:

```yaml
receivers:
otlp:
protocols:
http:
grpc:

exporters:
otlphttp/datadog:
endpoint: 
headers:
dd-otlp-source: llmobs
# thêm header API key theo tài liệu Datadog
otlphttp/langfuse:
endpoint: /api/public/otel
headers:
# thêm header xác thực theo tài liệu Langfuse

service:
pipelines:
traces:
receivers: [otlp]
exporters: [otlphttp/datadog, otlphttp/langfuse]
```

Với Langfuse, `otlphttp` là bắt buộc. Langfuse hỗ trợ OTLP qua HTTP, với cả HTTP/JSON lẫn HTTP/protobuf, nhưng chưa hỗ trợ gRPC.

Với Datadog thì khác: chọn `otlphttp` trong phác thảo này là để hai nhánh dùng chung một kiểu exporter, dễ đọc và dễ dò lỗi hơn, chứ không phải ràng buộc từ phía Langfuse. Nếu pipeline sẵn có của khách đã đẩy trace sang Datadog bằng exporter khác và đang chạy ổn, cứ giữ nguyên nhánh đó, chỉ thêm riêng một exporter HTTP cho Langfuse.

Giao thức Datadog chấp nhận ở endpoint của khách thì kiểm tra trong tài liệu Datadog trước khi đổi bất cứ thứ gì.

## Kiểm tra trước khi báo xong

Đừng dừng ở chỗ Collector khởi động không báo lỗi. Hãy gửi đúng một lời gọi LLM thử từ ứng dụng, rồi mở cả hai backend để tìm trace đó: Datadog ở màn hình LLM/Agent Observability, Langfuse ở danh sách trace của project.

Nếu trace chỉ hiện ở một bên, lỗi đã được khoanh vùng sẵn. Thiếu ở Langfuse thì xem lại giao thức HTTP, đường dẫn `/api/public/otel` và phiên bản đang chạy. Thiếu ở màn hình LLM của Datadog thì xem lại header `dd-otlp-source` và chuẩn quy ước mà framework phát ra.

## Ba cái bẫy trước buổi demo

Bẫy đầu tiên là gRPC, như đã nói ở trên. Bẫy thứ hai là phiên bản: Langfuse khuyên ai tự host mà gặp lỗi 4xx trên endpoint OTel thì nâng cấp lên bản mới nhất, và trang tài liệu ghi bản triển khai local cần từ v3.22.0 trở lên. Trước khi đổ lỗi cho cấu hình Collector, hãy hỏi khách đang chạy Langfuse bản nào.

Bẫy thứ ba nằm ở framework. Nhiều thư viện ra đời trước bản 1.37 của quy ước. Tài liệu Datadog hướng dẫn đặt biến môi trường `OTEL_SEMCONV_STABILITY_OPT_IN` để chúng phát trace tương thích 1.37+. Nếu Datadog nhận span nhưng không hiện trong màn hình LLM, đây là chỗ đầu tiên nên kiểm tra.

Cũng nên biết Datadog chấp nhận cả trace theo quy ước OpenInference, không chỉ OTel GenAI. Điều đó giúp khi khách đã instrument theo OpenInference, nhưng đừng coi đó là bảo đảm Langfuse sẽ hiểu y hệt. Điểm chung chắc chắn của hai bên là OTel GenAI.

## Học gì trước?

Hãy bắt đầu từ OTel Collector, không phải từ dashboard. Hiểu receiver, exporter và pipeline là đủ để dựng cấu hình trên trong một buổi chiều. Sau đó đọc phần spans trong repo semantic-conventions-genai và đối chiếu với trace thật mà framework của bạn phát ra.

Khi đọc JD của các vị trí FDE, để ý những cụm như "observability", "OpenTelemetry", "LLM tracing". Trong CV, một dòng như "dựng pipeline trace LLM theo OTel GenAI, xuất song song sang Datadog và Langfuse tự host" nói nhiều hơn danh sách tên công cụ.

Nếu khách còn đang cân nhắc công cụ observability, đừng đợi họ chốt. Một pipeline OTel đúng chuẩn cho phép bạn bắt đầu thu trace ngay hôm nay và để cuộc tranh luận đó diễn ra trong file YAML.

**Thử ngay tuần này:**

- Dựng Langfuse tự host bản mới, trỏ một exporter otlphttp của Collector vào /api/public/otel và gửi thử một trace từ ứng dụng LLM nhỏ.
- Mở repo semantic-conventions-genai của OpenTelemetry, đọc phần spans và liệt kê các thuộc tính gen_ai mà framework bạn đang dùng thực sự phát ra.
- Thêm vào CV một dòng mô tả pipeline trace LLM không phụ thuộc vendor: instrument bằng OTel, chia luồng qua Collector, ít nhất hai backend.

## Nguồn

- [Datadog Agent Observability natively supports OpenTelemetry GenAI Semantic Conventions](https://www.datadoghq.com/blog/llm-otel-semantic-convention/)

- [OpenTelemetry Instrumentation](https://docs.datadoghq.com/llm_observability/instrument/otel_instrumentation/)

- [OpenTelemetry (OTEL) for LLM Observability](https://langfuse.com/integrations/native/opentelemetry)

- [semantic-conventions/docs/gen-ai/gen-ai-spans.md at main · open-telemetry/semantic-conventions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-spans.md)

- [GitHub - open-telemetry/semantic-conventions-genai](https://github.com/open-telemetry/semantic-conventions-genai)
