LLM in Production · Vận hànhLLM in Production · Operations

Vận hành LLM là đọc được từng lượt gọi.Operating an LLM means being able to read every call.

Chi phí, fallback, online eval và đổi model đều là những cách đọc lại cùng một trace. Dưới đây là trace của một request thật sự đã gặp sự cố — mỗi nhãn màu chỉ tới việc dùng đến phần đó.

Cost, fallback, online eval and model changes are all different readings of the same trace. Below is the trace of one request that hit an incident — each coloured tag points to the job that reads that part.

Trace waterfall: retrieve 180ms, model A times out with no first token after 3.0s, dashed handoff to fallback model B for 2.9s, guardrail 40ms, total 6.1s. 0s1s2s3s4s5s6s POST /ask retrieve.docs 180ms k=8 llm.call A ttft_timeout 3.0s llm.call B in=3812 out=402 cached=3100 ttft=410ms $0.0071 guardrail.output 40ms pass 01 trace_id=7f3a 02 usage, ttft, $ 03 fallback=true 04 sampled: 100% (fallback) 05 config=support@14 snapshot
Nét đứt tím = đường chỉ được chọn lúc chạy. Đoạn mờ đầu thanh B = TTFT. Thanh đỏ = lượt gọi hỏng, vẫn phải nằm trong trace.Purple dashed = a path chosen only at runtime. The faint start of bar B = TTFT. Red bar = the failed call, which still belongs in the trace.

Chọn cái nàoWhich one do you need

Số 01–05 là thứ tự xây: mỗi việc cần việc đứng trước nó. Nhưng trước hết, hỏi xem bạn đã cần việc nào chưa.

01–05 is build order: each job needs the one before it. But first, ask whether you need any of them yet.

Chưa cần gì cả, khi đủ cả bốnYou need none of it yet, when all four hold

  • Người dùng nội bộ, vài chục người, nhắn thẳng được cho bạn.
  • Mỗi request một lượt gọi model, không có agent loop.
  • Chưa cam kết uptime với ai.
  • Hoá đơn nhỏ tới mức không ai hỏi.
  • Users are internal, a few dozen, and can message you directly.
  • One model call per request, no agent loop.
  • No uptime commitment to anyone.
  • A bill small enough that nobody asks.

Phương án rẻ nhất: một wrapper, một bảngThe cheapest substitute: one wrapper, one table

llm_calls(
  request_id, ts, feature, user_id,
  model_requested, model_returned,
  input_tokens, output_tokens, cached_tokens,
  ttft_ms, total_ms, status, error,
  prompt_version, prompt_full
)

Cộng spend limit trên console, đúng ID model có phiên bản thay vì alias, timeout cho mọi lượt gọi. Khoảng 50 dòng code — và là schema bạn sẽ mang sang hệ thống tracing thật.

Plus a console spend limit, the exact versioned model ID instead of an alias, and a timeout on every call. About 50 lines of code — and the schema you'll carry into a real tracing system.

  1. Bạn có mở lại được prompt và chi phí của một request cụ thể hôm qua?Can you pull up the prompt and cost of a specific request from yesterday?Không → dừng ở đây cho tới khi làm được.No → stop here until you can.
    01 Trace
  2. Có ai từng hỏi "sao tháng này tốn thế" hoặc "sao chậm thế"?Has anyone asked "why is this month so expensive" or "why so slow"?
    02 Chi phí & độ trễ02 Cost & latency
  3. Provider sập một giờ thì sản phẩm sập theo, và điều đó có hậu quả?If your provider is down for an hour, does your product go down — and does it matter?Không hậu quả → bỏ qua. Batch job → xếp hàng lại thay vì fallback.Doesn't matter → skip. Batch jobs → re-queue instead of falling back.
    03 Fallback
  4. Bạn chỉ biết chất lượng giảm khi người dùng phàn nàn?Do you only learn quality dropped when users complain?
    04 Online eval
  5. Sắp đổi model — provider khai tử, hoặc có model mới rẻ hơn?About to change models — a retirement notice, or a cheaper new model?Cần 04 trước, nếu không canary chỉ thấy được lỗi 5xx.Needs 04 first, or the canary only sees 5xx errors.
    05 Đổi version05 Version change

Năm việc vận hànhFive operational jobs

01

Log và trace từng lượt gọiLog and trace every call

NhìnObserve

Mỗi request một trace, mỗi bước một span. Span LLM phải chứa prompt đã lắp xong — không phải template — cùng model thực trả về, token, TTFT và lỗi.

One trace per request, one span per step. The LLM span must hold the assembled prompt — not the template — plus the model that actually answered, tokens, TTFT and errors.

dùng cho
use for
Xử lý ticket hỗ trợ, gỡ lỗi agent nhiều bước, phân bổ chi phí, lấy test case từ request thật, audit
Answering support tickets, debugging multi-step agents, cost attribution, test cases from real requests, audit
được
gain
Điều tra sự cố từ vài giờ xuống vài phút; bắt được lúc alias âm thầm đổi model
Incident investigation from hours to minutes; catches an alias silently switching models
mất
lose
Giữ trace là giữ dữ liệu cá nhân; context dài làm dung lượng tăng nhanh; ghi đồng bộ cộng thẳng vào độ trễ
Kept traces are personal data you now hold; long contexts make storage grow fast; synchronous writes add latency

đánh đổitrade-offLưu bản ghi đầy đủ của mọi lượt gọi là đổi chi phí lưu trữ và trách nhiệm bảo vệ dữ liệu người dùng, lấy khả năng phát lại bất kỳ request nào trong quá khứ khi có chuyện.Keeping a full record of every call trades storage spend and the duty to safeguard user data for being able to replay any past request once something has gone wrong.

Dấu hiệu: có người chuyển cho bạn một câu trả lời sai từ tuần trước, và bạn chỉ đoán được tài liệu và lịch sử nào đã được đưa vào.

Tell: someone forwards a bad answer from last week and all you can do is guess which documents and history went into it.

02

Theo dõi chi phí và độ trễTrack cost and latency

NhìnObserve

Biến token và thời gian trong span thành hai câu trả lời: tiền chảy về đâu, người dùng chờ ở đâu — chia theo tính năng, người dùng, model. Thời gian chờ chủ yếu do số token ra quyết định.

Turns the tokens and timings in spans into two answers: where the money goes, where users wait — by feature, user and model. Waiting time is dominated by output tokens.

dùng cho
use for
Tìm tính năng ngốn tiền, bắt agent loop chạy hoang, định tuyến model, giữ SLA p95
Finding the feature eating the budget, catching runaway loops, model routing, holding a p95 SLA
được
gain
Cảnh báo theo giờ thay vì theo hoá đơn; đo được tác dụng của prompt caching — đọc cache rẻ hơn nhiều, nhưng ghi cache đắt hơn input thường (Claude: 1,25× với TTL 5 phút, 2× với 1 giờ)
Hourly alerts instead of invoice surprises; measurable prompt-caching savings — cache reads are far cheaper, but cache writes cost more than plain input (Claude: 1.25× for 5-min TTL, 2× for 1-hour)
mất
lose
Bảng giá tự giữ dễ lệch; token suy luận dễ bị tính thiếu; nhãn phân bổ không gắn bù được
Self-kept price tables drift; reasoning tokens get undercounted; attribution labels can't be backfilled

đánh đổitrade-offGắn mỗi lượt gọi với tiền và mili-giây là đổi công gắn nhãn phân bổ ngay từ đầu và bảo trì bảng giá, lấy khả năng chỉ đích danh tính năng nào đang tiêu tiền và bắt người dùng chờ.Tying every call to money and milliseconds trades up-front attribution labelling and price-table upkeep for the ability to name exactly which feature is spending money and making users wait.

Dấu hiệu: hoá đơn tăng gấp đôi và không ai chỉ ra được tính năng gây ra trong năm phút.

Tell: the bill doubles and nobody can name the responsible feature within five minutes.

03

Fallback khi provider sậpFall back when a provider goes down

Can thiệpIntervene

Chuỗi dự phòng định nghĩa trước: timeout, retry có ngân sách, circuit breaker, rồi cùng model qua kênh khác, model của provider khác, cuối cùng là chế độ suy giảm.

A predefined backup chain: timeout, budgeted retries, circuit breaker, then the same model via another channel, another provider's model, and finally degraded mode.

dùng cho
use for
Chat với khách hàng, hệ thống có cam kết uptime, giờ cao điểm chạm rate limit, luồng thanh toán/đăng ký
Customer chat, contractual uptime, peak-hour rate limits, checkout and sign-up flows
được
gain
Sự cố provider thành vài phút trễ thêm; circuit breaker chuyển ngay thay vì chờ hết timeout
Provider incidents become minutes of extra latency; the breaker switches instantly instead of burning the timeout
mất
lose
Prompt không chuyển nguyên vẹn sang model khác; không fallback sạch giữa stream; retry không ngân sách khuếch đại sự cố — SDK Anthropic đã mặc định retry 2 lần (timeout 10 phút), gateway retry chồng lên thì một request thành tối đa 9 lần gọi, nên chỉ retry ở một tầng
Prompts don't transfer intact; no clean fallback mid-stream; unbudgeted retries amplify the incident — the Anthropic SDK already retries 2 times by default (10-minute timeout), so a gateway retrying on top turns one request into up to 9 attempts; retry in one layer only

đánh đổitrade-offThêm đường fallback là đổi việc phải duy trì và eval thêm một tổ hợp model–prompt, lấy việc sự cố của provider không còn là sự cố của sản phẩm.Adding a fallback path trades the work of maintaining and evaluating one more model–prompt combination for a provider's incident no longer being your product's incident.

Dấu hiệu: trang trạng thái của provider đỏ đồng nghĩa với trang trạng thái của bạn đỏ.

Tell: the provider's status page turning red means yours turns red.

04

Tách trace để làm online evalSplit off traces for online eval

NhìnObserve

Lấy mẫu trace từ traffic thật, chấm điểm bất đồng bộ bằng kiểm tra cứng, LLM-as-judge và tín hiệu người dùng, rồi đưa ca hỏng về bộ eval offline.

Sample traces from real traffic, score them asynchronously with hard checks, LLM-as-judge and user signals, then move failures into the offline eval set.

dùng cho
use for
Phát hiện chất lượng trôi dạt, so sánh theo nhóm người dùng, đo sau mỗi lần triển khai, tìm loại lỗi mới
Detecting drift, comparing user segments, measuring after each deploy, finding new failure types
được
gain
Thấy suy giảm trước khi đủ người phàn nàn; bộ eval lớn lên từ lỗi thật; không thêm mili-giây nào cho người dùng
See decline before enough users complain; the eval set grows from real failures; adds no user latency
mất
lose
Không có đáp án chuẩn; judge thiên vị câu dài và vị trí; mẫu nhỏ bỏ sót đúng ca hiếm
No ground truth; judges favour length and position; small samples miss exactly the rare cases

đánh đổitrade-offChấm điểm traffic thật là đổi thêm một khoản chi cho model chấm và công hiệu chỉnh nó, lấy tín hiệu chất lượng trước khi người dùng phải lên tiếng.Scoring real traffic trades an extra spend on a judge model, and the work of calibrating it, for a quality signal before users have to speak up.

Dấu hiệu: cách duy nhất bạn biết chất lượng giảm là khi có người phàn nàn.

Tell: the only way you learn quality dropped is a complaint.

05

Đổi version model an toànChange model versions safely

Can thiệpIntervene

Coi đổi model là một lần triển khai: ghim đúng ID model (không alias kiểu "latest"; ID Claude hiện tại như claude-sonnet-5-5 không có hậu tố ngày), eval offline, shadow, canary tăng dần, rollback bằng một cờ cấu hình. Cấu hình có version gồm model, prompt, tool, effort/thinking — và tham số sampling chỉ khi provider còn cho phép: model Claude hiện tại trả lỗi 400 với temperature/top_p khác mặc định.

Treat a model change as a deploy: pin the exact model ID (no latest-style alias; current Claude IDs such as claude-sonnet-5-5 have no date suffix), offline eval, shadow, gradual canary, rollback with one config flag. The versioned config holds model, prompt, tools, effort/thinking — and sampling params only where the provider still allows them: current Claude models return a 400 for a non-default temperature/top_p.

dùng cho
use for
Provider khai tử model, chuyển sang model rẻ hơn, nâng cấp thế hệ, đổi model cho riêng một tính năng
Provider retirements, moving to a cheaper model, generation upgrades, per-feature model changes
được
gain
Rollback trong vài phút; shadow bắt thay đổi độ dài, định dạng, tỷ lệ từ chối; hết loại sự cố "không ai triển khai gì mà hành vi vẫn đổi"
Minutes to roll back; shadow catches length, format and refusal shifts; no more "behaviour changed with no deploy"
mất
lose
Shadow nhân đôi chi phí; canary trên traffic thấp thiếu mẫu; gần như luôn kéo theo một vòng sửa prompt
Shadow doubles cost; low-traffic canaries lack samples; almost always pulls in a round of prompt edits

đánh đổitrade-offĐưa model mới qua shadow và canary là đổi tốc độ nâng cấp và một khoản chi chạy song song, lấy khả năng rút lui trong vài phút thay vì phát hiện thoái lui qua khiếu nại.Putting a new model through shadow and canary trades upgrade speed and the cost of running in parallel for the ability to back out in minutes instead of discovering a regression through complaints.

Dấu hiệu: model ID trong code là alias, hoặc lần đổi model gần nhất là sửa một chuỗi rồi merge.

Tell: the model ID in code is an alias, or the last model change was editing a string and merging.

Bảng đánh đổiTrade-off table

Đọc hàng "phụ thuộc" từ trái sang phải sẽ thấy vì sao thứ tự xây là 01 → 05.

Read the "depends on" row left to right to see why the build order is 01 → 05.

01 Trace 02 Chi phí & độ trễ02 Cost & latency 03 Fallback 04 Online eval 05 Đổi version05 Version change
Bảo vệ khỏiProtects against Không điều tra đượcBeing unable to investigate Hoá đơn và thời gian chờ mất kiểm soátBill and wait times out of control Sự cố của providerProvider incidents Chất lượng trôi dạt âm thầmSilent quality drift Thoái lui khi nâng cấpRegressions on upgrade
Cần từ khiNeeded from Ngày đầu có người dùng thậtDay one with real users Khi có người hỏi về tiềnWhen someone asks about money Khi có cam kết uptimeWhen you commit to uptime Khi chất lượng là lý do người ta trả tiềnWhen quality is why people pay Trước lần đổi model đầu tiênBefore the first model change
Công dựngBuild effort Thấp — một wrapperLow — one wrapper Thấp, nếu 01 đã cóLow, if 01 exists Trung bìnhMedium Trung bình–caoMedium–high Trung bìnhMedium
Chi phí chạyRunning cost Lưu trữ, tăng theo trafficStorage, grows with traffic Gần như khôngAlmost none Khi fallback chạy và khi diễn tậpWhen fallback runs, and in drills Model chấm + công gán nhãnJudge spend + labelling time Tiền shadow, theo đợtShadow spend, per rollout
Thiếu nó, biết khiWithout it, you learn Không bao giờNever Nhận hoá đơnAt the invoice Provider sậpWhen the provider fails Khách phàn nànFrom complaints Khách phàn nànFrom complaints
Phụ thuộcDepends on —0101, 020101, 02, 04

Anti-patternsAnti-patterns

Sai lầmMistake Vì sao saiWhy it's wrong Sửa thế nàoFix
Log template thay vì prompt đã lắpLogging the template, not the assembled prompt Lỗi nằm ở phần được chèn vào, không ở templateBugs live in what gets inserted, not the template Ghi chuỗi cuối cùng gửi đi, kèm prompt_versionRecord the final string sent, plus prompt_version
Ghi log đồng bộ trên đường requestSynchronous logging on the request path Backend log chậm là người dùng chậmA slow log backend means slow users Exporter bất đồng bộ qua hàng đợiAsynchronous exporter through a queue
Theo dõi độ trễ trung bìnhTracking average latency Che phần đuôi mà người dùng nhớHides the tail users remember p95/p99, tách TTFT khỏi tổng thời gianp95/p99, TTFT split from total time
Chỉ cảnh báo khi tổng tháng vượt ngân sáchAlerting only on the monthly total Tới lúc chạm ngưỡng thì tiền đã điBy then the money is gone Cảnh báo theo tốc độ chi/giờ, trần cứng theo userHourly spend-rate alerts, hard per-user caps
Retry mọi lỗi, không giới hạnRetrying every error without limit Nhân tiền cho lỗi 400, dìm provider đang quá tảiMultiplies cost on 400s, drowns an overloaded provider Chỉ lỗi thử lại được; backoff, jitter, ngân sách retryRetryable errors only; backoff, jitter, retry budget
Retry ở cả SDK lẫn gatewayRetrying in both the SDK and the gateway 2 × 2 lần retry = tối đa 9 lần gọi, chờ gấp 9 lần timeout2 × 2 retries = up to 9 attempts, 9× the timeout Retry ở một tầng; max_retries=0 cho SDK nếu gateway retryRetry in one layer; SDK max_retries=0 if the gateway retries
Fallback chưa từng chạy thậtFallback that has never really run Hỏng đúng lúc cần: key hết hạn, hạn mức chưa xinBreaks when needed: expired keys, no quota Diễn tập định kỳ, ép một phần traffic đi đường fallbackRegular drills, force a share of traffic through it
Dùng nguyên prompt của model chính cho model fallbackReusing the primary prompt on the fallback model Prompt không chuyển nguyên vẹn giữa các modelPrompts don't transfer intact between models Prompt riêng cho từng model, cùng bộ evalOne prompt per model, same eval set
Alias -latest trong productionA -latest alias in production Hành vi đổi mà bạn không triển khai gìBehaviour changes with no deploy Ghim đúng ID model, ghi model_returnedPin the exact model ID, record model_returned
Đổi model bằng cách sửa chuỗi rồi triển khaiChanging models by editing a string Không rollback nhanh, không so trước/sau đượcNo fast rollback, no before/after comparison Cấu hình có version, shadow, canary, cờ rollbackVersioned config, shadow, canary, rollback flag
Judge thang 1–10, chưa hiệu chỉnhAn uncalibrated 1–10 judge Số trông chính xác nhưng không ổn địnhLooks precise, isn't stable Đạt/không đạt theo tiêu chí, hiệu chỉnh với ~100 nhãn người thậtPass/fail per criterion, calibrated on ~100 human labels
Lấy mẫu online eval hoàn toàn ngẫu nhiênPurely random online-eval sampling Bỏ sót đúng ca lỗi hiếmMisses exactly the rare failures 100% lỗi, 👎, fallback; phần còn lại lấy theo nhóm100% of errors, 👎, fallbacks; stratify the rest
Lưu PII trong trace, tính chuyện che sauStoring PII in traces, masking later Dữ liệu chưa che đã nằm trong kho và bản sao lưuUnmasked data is already stored and backed up Che lúc ghi, đặt thời hạn lưu từ đầuMask at write time, set retention up front

Ba câu cần nhớThree things to remember

  1. Trace là nền của mọi thứ còn lại. Chi phí, fallback, online eval và đổi model chỉ là những cách đọc lại cùng một bản ghi.Tracing is the foundation of everything else. Cost, fallback, online eval and model changes are different readings of one record.
  2. Fallback chưa diễn tập và judge chưa hiệu chỉnh là cảm giác an toàn, không phải an toàn.An undrilled fallback and an uncalibrated judge are a feeling of safety, not safety.
  3. Đổi model là một lần triển khai. Ghim version, đo trước, phát hành dần, rút lui bằng một cờ.A model change is a deploy. Pin, measure first, roll out gradually, roll back with one flag.