Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 2 — Anatomy của một Trace: Span, Run tree, Metadata

Đã đọc 0/8 mục · còn khoảng 3 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

Bài 2 — Anatomy của một Trace

Để debug agent hiệu quả, bạn phải "đọc" trace thành thạo như bác sĩ đọc X-quang. Bài này mổ xẻ cấu trúc chung mà LangSmith, Langfuse và Braintrust đều dùng, dù tên gọi hơi khác.

Trace, Span và Run tree

Một trace là cây các span (LangSmith gọi là "run", Langfuse gọi "observation"). Mỗi span có:

  • type: llm, tool, retriever, chain/agent, embedding.
  • input / output: dữ liệu vào và ra của span đó.
  • start_time / end_time: để tính latency.
  • parent_id: để dựng cây lồng nhau.
  • metadata & tags: gắn ngữ cảnh tùy ý.
Trace (root span, type=agent)
├─ Span type=retriever  input=query        output=[doc1, doc2]
├─ Span type=llm        input=prompt+docs  output=draft   tokens=1200
│   └─ (ghi nhận model, temperature, prompt template)
└─ Span type=tool       input={city:"HN"}  output={temp:31}

Hiểu cây này giúp bạn định vị: latency cao nằm ở retriever hay LLM? Lỗi nằm ở tool nào? Token phình ở span nào?

Ba loại thông tin phải luôn có trên span

  • Nội dung: input/output đầy đủ, không cắt xén (để tái hiện lỗi).
  • Số đo: token (prompt/completion), latency, chi phí, mã lỗi.
  • Ngữ cảnh: metadata giúp lọc và nhóm.

Metadata — thứ tạo ra khác biệt

Metadata biến một đống trace hỗn độn thành thứ phân tích được. Những trường nên gắn:

  • user_id, session_id — theo dõi hành trình 1 người dùng.
  • prompt_version, model, git_sha — biết trace thuộc phiên bản nào.
  • environment — dev / staging / prod.
  • feature hoặc agent_name — nếu bạn có nhiều agent.
  • Tags nghiệp vụ: customer_tier=vip, lang=vi.
Ví dụ gắn metadata (kiểu Langfuse/LangSmith, minh họa):

with trace_span(
    name="support_agent",
    metadata={
        "user_id": user.id,
        "prompt_version": "v7",
        "model": "claude-sonnet",
        "environment": "prod",
    },
    tags=["support", "lang:vi"],
) as span:
    result = agent.run(query)
    span.set_output(result)

Sau này bạn có thể lọc: "cho tôi mọi trace prompt_version=v7, environment=prod, có lỗi tool" — và điều tra chính xác.

Session (thread) và trace

Một session/thread gom nhiều trace của cùng một cuộc hội thoại nhiều lượt. Trace = 1 lượt, session = cả cuộc chat. Cả ba nền tảng đều hỗ trợ nhóm theo session_id/thread_id để xem toàn bộ hội thoại.

Các bước thiết kế schema trace của bạn

  • Vẽ ra sơ đồ các bước agent đi qua (plan → tool → tool → answer).
  • Quyết định span nào cần tách riêng (mỗi tool 1 span, mỗi LLM call 1 span).
  • Liệt kê metadata bắt buộc cho mọi span (dùng checklist dưới).
  • Chuẩn hóa quy ước đặt tên span (tool.search, llm.plan) để dễ lọc.
  • Quyết định cắt/che dữ liệu nhạy cảm (PII) trước khi gửi lên (xem bài 8).

Khung checklist metadata tối thiểu

TrườngVì sao cần
user_id / session_idTruy vết hành trình, gom hội thoại
prompt_version / git_shaSo sánh phiên bản
model + paramsBiết cấu hình sinh ra output
environmentTách prod khỏi dev khi phân tích
tags nghiệp vụLọc theo nhóm khách/tính năng

Sai lầm thường gặp

  • Gộp mọi thứ vào 1 span khổng lồ: không định vị được latency/lỗi ở đâu.
  • Cắt input/output cho "gọn": khi cần tái hiện lỗi thì thiếu dữ liệu.
  • Đặt tên span tùy hứng (step1, step2): sau này không lọc/nhóm được.
  • Quên gắn prompt_version: mọi so sánh A/B về sau trở nên mù mờ.
  • Log PII thô lên nền tảng: rủi ro tuân thủ; phải che trước khi gửi.
Nắm vững anatomy này, bạn đã sẵn sàng để bài 3 gắn tracing thật vào code.

Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi