Tự triển khai Langfuse (Self-Hosting): Hướng dẫn thực tế về LLM Observability

AI tutorial - IT technology blog
AI tutorial - IT technology blog

Sự chuyển dịch từ Logging truyền thống sang LLM Observability

Logging tiêu chuẩn hoạt động hoàn hảo để bắt lỗi 500 hoặc theo dõi mức tăng đột biến của CPU. Tuy nhiên, khi tôi triển khai chatbot dựa trên RAG đầu tiên của mình, hệ thống ELK hiện tại bỗng cảm thấy lỗi thời. Log truyền thống không thể giải thích tại sao mô hình lại đưa ra câu trả lời ảo giác (hallucination) hoặc tại sao một bước truy xuất cụ thể lại làm tăng thêm 4,2 giây độ trễ cho một truy vấn đơn giản.

Các ứng dụng LLM hoạt động như một “hộp đen”. Để debug chúng hiệu quả, bạn cần quan sát toàn bộ chuỗi thực thi. Điều này bao gồm prompt template chính xác đã sử dụng, các đoạn văn bản (chunks) được truy xuất từ vector database, đầu ra thô của mô hình và số lượng token chính xác. Sau sáu tháng quản lý quy trình AI trong môi trường production, tôi nhận thấy Langfuse là cách mạnh mẽ nhất để thu thập dữ liệu này mà không tốn quá nhiều chi phí.

So sánh các lựa chọn

Trước khi quyết định tự triển khai, tôi đã cânناسب ba con đường khác nhau để giám sát các pipeline AI của mình:

  • Logging tiêu chuẩn (ELK/Grafana): Đòi hỏi nỗ lực kỹ thuật tùy chỉnh rất lớn để trực quan hóa các trace lồng nhau. Nó cũng thiếu các công cụ tích hợp để so sánh các phiên bản prompt cạnh nhau.
  • Nền tảng trả phí (LangSmith): Tập hợp tính năng rất cao cấp, nhưng chi phí tăng dần theo quy mô. Với một dự án đạt 1 triệu trace mỗi tháng, bạn có thể dễ dàng phải trả mức phí vượt quá 100 USD/tháng chỉ cho việc giám sát. Nhiều khách hàng doanh nghiệp cũng thẳng thừng từ chối gửi các prompt nội bộ nhạy cảm đến một dịch vụ SaaS bên thứ ba.
  • Tự triển khai mã nguồn mở (Langfuse): Đây là giải pháp cân bằng. Bạn có một giao diện người dùng chuyên dụng để quản lý trace và prompt trong khi vẫn giữ mọi byte dữ liệu bên trong Đám mây riêng ảo (VPC) của mình.

Ưu và nhược điểm của việc tự triển khai

Khả năng kiểm soát là động lực chính ở đây. Mặc dù tự triển khai giúp tiết kiệm phí trên mỗi trace, nhưng nó đi kèm với các trách nhiệm vận hành mà bạn cần lưu ý.

Ưu điểm

  • Chủ quyền dữ liệu: Dữ liệu khách hàng và các prompt độc quyền của bạn không bao giờ rời khỏi hạ tầng của bạn. Điều này giúp đơn giản hóa đáng kể việc kiểm định tuân thủ GDPR và SOC2.
  • Chi phí dự đoán được: Thay vì hóa đơn hàng tháng biến động dựa trên lưu lượng sử dụng, bạn trả một mức giá cố định cho một container Node.js nhỏ và một thực thể PostgreSQL.
  • Tích hợp sâu: Chạy Langfuse cục bộ cho phép giảm độ trễ giữa ứng dụng và lớp giám sát, thường giữ mức overhead của trace dưới 150ms.

Đánh đổi

  • Bảo trì: Bạn tự chịu trách nhiệm sao lưu cơ sở dữ liệu, vá lỗi bảo mật và nâng cấp phiên bản.
  • Phân bổ tài nguyên: Đối với các ứng dụng có lưu lượng lớn, bạn sẽ cần quản lý thêm một thực thể ClickHouse cùng với Postgres để xử lý các truy vấn phân tích một cách hiệu quả.

Kiến trúc sẵn sàng cho Production

Hầu hết các ứng dụng quy mô vừa xử lý từ 5.000 đến 50.000 yêu cầu mỗi ngày hoạt động tốt nhất trên thiết lập dựa trên Docker. Đối với lớp dữ liệu, tôi thực sự khuyên dùng một dịch vụ được quản lý (managed service) như AWS RDS hoặc DigitalOcean Managed Databases. Sử dụng DB được quản lý đảm bảo bạn có sao lưu tự động và tính sẵn sàng cao mà không cần can thiệp thủ công. Tuy nhiên, để bắt đầu nhanh hoặc thử nghiệm cục bộ, một stack Docker Compose đầy đủ vẫn hoạt động tốt.

Các thành phần cốt lõi

Hệ thống dựa trên ba trụ cột chính:

  1. Langfuse Server: Một ứng dụng Node.js cung cấp API và dashboard web.
  2. PostgreSQL (v16): Nơi lưu trữ chính cho các trace, prompt và phản hồi từ người dùng.
  3. Redis: Xử lý bộ nhớ đệm và đảm bảo các tác vụ nền không gây nghẽn giao diện người dùng.

Triển khai từng bước

Bạn sẽ cần cài đặt Docker và Docker Compose. Tôi khuyên dùng một máy chủ có ít nhất 2 vCPU và 4GB RAM để đạt hiệu suất ổn định.

1. Cấu hình

Tạo một thư mục dự án và thêm tệp docker-compose.yml. Tránh sử dụng tag ‘latest’ cho môi trường production; việc ghim vào một phiên bản chính như ‘langfuse/langfuse:2’ ngăn chặn các thay đổi gây lỗi (breaking changes) làm hỏng hệ thống trong quá trình cập nhật tự động.

version: '3.5'

services:
  langfuse-server:
    image: langfuse/langfuse:2
    depends_on:
      - db
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - NEXTAUTH_URL=http://localhost:3000
      - NEXTAUTH_SECRET=su-dung-mot-chuoi-ngau-nhien-dai-o-day
      - SALT=mot-chuoi-salt-ngau-nhien-khac
      - DATABASE_URL=postgresql://postgres:password@db:5432/postgres
      - TELEMETRY_ENABLED=false

  db:
    image: postgres:16
    restart: always
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=postgres
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:

Khởi chạy stack bằng lệnh docker-compose up -d. Truy cập dashboard tại http://localhost:3000 để tạo tài khoản quản trị và tạo thông tin xác thực API.

2. Tích hợp Python

Việc tích hợp rất đơn giản. Nếu bạn sử dụng LangChain, đó chỉ là một callback đơn giản. Đối với những người sử dụng các lệnh gọi OpenAI thô, SDK decorator là cách gọn gàng nhất. Trước tiên, hãy cài đặt các gói cần thiết:

pip install langfuse openai

Đoạn mã sau đây minh họa cách bao bọc một hàm LLM để tự động ghi lại độ trễ, chi phí và metadata:

from langfuse.openai import openai
import os

os.environ["LANGFUSE_PUBLIC_KEY"] = "pk-lf-your-key"
os.environ["LANGFUSE_SECRET_KEY"] = "sk-lf-your-key"
os.environ["LANGFUSE_HOST"] = "http://localhost:3000"

def get_ai_response(user_input):
    # Wrapper này ghi lại toàn bộ chu kỳ request/response
    response = openai.chat.completions.create(
      model="gpt-4o",
      messages=[
          {"role": "system", "content": "Bạn là một trợ lý kỹ thuật."},
          {"role": "user", "content": user_input}
      ],
      name="production-chat-v1",
      metadata={"env": "production", "user_id": "user_99"}
    )
    return response.choices[0].message.content

print(get_ai_response("Làm cách nào để tối ưu hóa các truy vấn Postgres?"))

3. Đánh giá kết quả

Các trace xuất hiện trong dashboard của bạn theo thời gian thực. Trong một buổi debug gần đây, tôi nhận thấy điểm số ‘mức độ hữu ích’ (helpfulness) của chúng tôi giảm đáng kể sau khi cập nhật prompt. Bằng cách lọc các trace trong Langfuse, tôi phát hiện ra rằng một bước truy xuất cụ thể đang đưa 2.000 token tài liệu không liên quan vào ngữ cảnh. Nhiễu này đã làm LLM bối rối. Việc xác định điều này chỉ mất năm phút với một trace, trong khi lẽ ra phải mất hàng giờ đào bới log thủ công.

Vượt xa hơn việc theo dõi cơ bản

Observability chỉ là bước đầu tiên hướng tới một sản phẩm AI đáng tin cậy. Sức mạnh thực sự nằm ở “Scores” (Điểm số). Bạn có thể chấm điểm các câu trả lời thủ công trong dashboard hoặc tự động hóa quy trình bằng cách sử dụng LLM-as-a-judge. Bằng cách gán điểm số về mức độ liên quan cho mỗi trace, bạn có thể lọc ra 5% câu trả lời kém nhất. Điều này cho phép nhóm của bạn ngừng phỏng đoán và bắt đầu khắc phục các trường hợp biên (edge cases) cụ thể mà ứng dụng thực sự đang thất bại.

Nếu bạn đang tiến xa hơn một bản prototype đơn giản, bạn cần khả năng hiển thị. Việc thiết lập một instance Langfuse tự triển khai mất chưa đầy 30 phút. Nó cung cấp sự rõ ràng cần thiết để biến một thử nghiệm AI mong manh thành một dịch vụ ổn định, sẵn sàng cho production.

Share: