$ cat ./blog/gen-ai/production-rag-evaluation.md
seriesRAG từ cơ bản đến nâng caobài 5

Production RAG Evaluation: đo chất lượng sau khi deploy

Bài thứ năm và cũng là bài cuối trong series RAG từ cơ bản đến nâng cao: vì sao pass benchmark chưa đảm bảo production tốt, một trace phải giữ gì để truy được nguyên nhân, online evaluation nên chạy bất đồng bộ ra sao, sampling phân bổ theo ngân sách thế nào, metric biến thành SLI, SLO và alert bằng cách nào, năm loại drift của một hệ RAG, evaluation khác guardrail ở đâu, và vòng lặp đưa lỗi thật trở lại golden dataset.

~/diagrams/production-rag-evaluation/production-eval-loop.htmltương tác
mở riêng ↗
HìnhNăm bước trên hàng chính là vòng lặp chất lượng ở production: deploy, trace, chấm điểm ngoài critical path, phát hiện lỗi hoặc drift, rồi biến lỗi thật thành regression case cho lần deploy sau. Hàng dưới là chuyện xảy ra khi vòng lặp bị cắt ở bước bốn - team biết có lỗi, đọc biểu đồ, sửa tạm, đóng incident, và vài tháng sau gặp lại đúng lỗi đó vì không có case nào canh gác nó.
vòng lặp chínhbước đóng vòngchỗ vòng lặp bị cắt

Bốn bài trước đi gần hết vòng đời của một hệ RAG trước khi nó ra ngoài production:

Kiến trúc
    -> Retrieval
    -> Metric
    -> Benchmark
    -> Regression test
    -> Quality gate
    -> Deploy

Nếu regression suite pass, retrieval benchmark tốt hơn và các metric như Faithfulness, Answer Relevancy hay Contextual Recall đều đạt threshold, ta có cơ sở để tự tin hơn khi deploy.

Nhưng còn một câu hỏi chưa được trả lời: sau khi deploy thì sao?

Bộ benchmark ở bài trước chỉ đại diện cho những failure mode mà team đã biết và đã đưa vào dataset. Production thì chứa cả một thế giới mà dataset chưa nhìn thấy: user mới, cách diễn đạt mới, typo, tiếng lóng, hội thoại nhiều lượt, thực thể hiếm, tài liệu mới, chính sách vừa đổi, ngôn ngữ mới, traffic tăng đột biến, provider đổi backend, index vừa rebuild.

Vì vậy hai câu này hoàn toàn có thể cùng đúng:

PASS offline benchmark
FAIL production

Offline evaluation trả lời: hệ thống có vượt qua những bài test chúng ta đã biết không?

Production evaluation trả lời một câu khác: trong traffic thật, hệ thống đang thất bại ở đâu, kể cả những failure mode chúng ta chưa biết là nó tồn tại?

Nếu bài benchmark hỏi “version mới có tốt hơn version cũ không”, thì bài này hỏi “làm sao giữ một hệ RAG tốt sau khi nó đã tiếp xúc với thế giới thật, và làm sao để chính thế giới thật đó dạy ngược lại cho bộ test của mình”.


01Pass benchmark chưa có nghĩa là production sẽ tốt

Giả sử có 1.000 golden test case và phiên bản v14 đạt:

Contextual Recall       0.91
Contextual Precision    0.88
Faithfulness            0.95
Answer Relevancy        0.93

Không có regression đáng kể so với v13. CI xanh. Team deploy.

Một tuần sau user bắt đầu gửi những câu như:

"bản cho sg thì sao?"
"ERR-PAY-942 vừa đổi chưa?"
"Policy đó có áp dụng cho intern remote ở Việt Nam không?"
"Không phải policy cũ, tôi hỏi cái vừa update hôm qua."

Những câu này có thể không giống chút nào với phân bố của golden set ban đầu. Điều đó xảy ra không phải vì ai làm sai, mà vì evaluation dataset về bản chất chỉ là một mẫu của hành vi mong muốn tại thời điểm viết ra nó. Microsoft mô tả evaluation set cho RAG đúng theo nghĩa đó và nhấn mạnh rằng tập này cần được cập nhật khi usage và requirement thay đổi.

~/diagrams/production-rag-evaluation/coverage-gap.htmltương tác
mở riêng ↗
HìnhHai đường xuất phát từ hai nguồn câu hỏi khác nhau và dẫn tới hai kết luận khác nhau. Đường trên đi từ golden dataset qua benchmark tới một chữ PASS đúng trên những gì đã biết. Đường dưới đi từ traffic thật qua nhóm query nằm ngoài phân bố tới những lỗi chưa ai viết test cho chúng. Hai đường chỉ gặp nhau ở một chỗ duy nhất là trace và online evaluation - nơi cả hai loại kết quả cùng hiện ra.
đường offlinechỗ hai đường gặp nhauđường production

Cách hình dung ngắn gọn: offline benchmark giảm known uncertainty — ta biết mình quan tâm tới query rewriting, hybrid retrieval, reranker, chunk size, prompt, model, nên chủ động test chúng. Production làm lộ unknown uncertainty — hành vi người dùng mới, cấu trúc nguồn mới, từ vựng mới, cụm query bất ngờ, cấu hình lệch, thay đổi phía nhà cung cấp, dữ liệu cũ, lỗi phân quyền.

Hai thứ đó bổ sung cho nhau chứ không thay nhau.


02Monitoring RAG không chỉ là CPU, RAM và latency

Khi nghe từ monitoring, backend engineer thường nghĩ tới CPU, memory, request rate, HTTP 5xx, p95 latency. Những metric đó vẫn cực kỳ quan trọng. Nhưng với một RAG application, service có thể trả HTTP 200, latency bình thường, CPU bình thường — và vẫn trả về một câu trả lời sai hoàn toàn.

Từ góc nhìn hạ tầng đó là SUCCESS. Từ góc nhìn người dùng đó là FAILURE.

~/diagrams/production-rag-evaluation/observability-layers.htmltương tác
mở riêng ↗
HìnhCùng một request được nhìn qua ba lớp khác nhau. Lớp hạ tầng biết latency, lỗi và chi phí nhưng không phân biệt được câu trả lời đúng với câu trả lời sai. Lớp pipeline biết 3,4 giây đó nằm ở chặng nào và evidence đã đi qua những bước nào. Lớp chất lượng mới trả lời được câu hỏi cuối cùng là câu trả lời này có dùng được không, và tín hiệu của nó đến từ nhiều nguồn chứ không chỉ từ LLM judge.
ba lớp quan sátlớp pipelinecâu hỏi mỗi lớp trả lời

Microsoft mô tả RAG monitoring quanh ba yêu cầu lớn là quality, cost và latency, và nhấn mạnh rằng vì RAG có nhiều component ảnh hưởng lẫn nhau nên cần quan sát cả từng component lẫn end-to-end.

Lớp vận hành

request count        p50 / p95 / p99 latency
error rate           embedding latency
timeout rate         retrieval latency
availability         reranker latency
retry rate           LLM latency
queue depth          time-to-first-token
input tokens         output tokens
context tokens       cost per request

OpenTelemetry hiện đã có GenAI semantic conventions cho nhiều loại telemetry như model, token usage và operation duration, đồng thời định nghĩa cả các field cho retrieval query và retrieved document.

Lớp pipeline

Metric vận hành có thể nói “request mất 3,4 giây” nhưng không nói 3,4 giây đó nằm ở đâu:

Query rewrite          220 ms
Embedding               30 ms
Dense retrieval         45 ms
BM25                    18 ms
Fusion                   2 ms
Reranker               210 ms
Context builder          8 ms
Generation            1820 ms

Không trace từng stage thì mọi hồi quy latency đều biến thành một câu duy nhất: “RAG chậm”. Chất lượng cũng vậy — retrieval sai, reranking sai, context sai hay generation sai đều bị gộp thành “câu trả lời tệ”.

Lớp chất lượng

Không phải tín hiệu nào cũng phải là LLM-as-a-Judge. Lớp này gộp nhiều loại: metric tất định như tỷ lệ retrieval rỗng hay thiếu citation, LLM judge như Faithfulness và Answer Relevancy, phản hồi người dùng, sự kiện sản phẩm, và kết quả nghiệp vụ.


03Trace là đơn vị quan sát quan trọng nhất của RAG

Muốn biết một answer được tạo ra như thế nào, ta phải giữ lại execution path của nó. DeepEval định nghĩa trace là toàn bộ execution của một LLM application, còn span là một scope nhỏ hơn bên trong trace — có thể là retriever, tool, một LLM call hoặc một component riêng.

TRACE rag_request_82f1
├── query_rewrite
├── retrieval
│    ├── dense_search
│    └── bm25_search
├── rank_fusion
├── reranker
├── context_builder
└── generation
~/diagrams/production-rag-evaluation/trace-span-anatomy.htmltương tác
mở riêng ↗
HìnhTrace là toàn bộ một request, span là từng chặng bên trong nó. Cột giữa là ba span mà hầu như hệ RAG nào cũng nên có: viết lại câu hỏi, đi tìm evidence, và sinh câu trả lời. Cột phải là dữ liệu tối thiểu mỗi span phải giữ để sáu tháng sau còn lần ngược được - đủ để biết ý câu hỏi đã lệch chưa, evidence nào thực sự đi vào prompt, và phiên bản prompt nào đang chạy lúc đó.
trace và span conspan retrievaldữ liệu mỗi span giữ

Vì sao điều này quan trọng đến thế? Giả sử user báo: “Câu trả lời này đang dùng policy cũ.”

Nếu log chỉ có:

{ "query": "...", "answer": "..." }

thì gần như không biết bắt đầu từ đâu. Nhưng nếu trace giữ đủ chuỗi từ câu hỏi gốc, câu hỏi đã viết lại, filter được áp, danh sách chunk lấy về kèm điểm, thứ hạng sau fusion, thứ hạng sau rerank, context cuối cùng và prompt đã chạy, thì có thể lần ngược:

Query: "What is the current password rotation policy?"

retrieval
├── policy-2024    score=0.88
└── policy-2026    score=0.85

reranker
1. policy-2024
2. policy-2026

answer: "180 days"

Root cause ở đây nhiều khả năng nằm ở version filtering, freshness của nguồn hoặc reranking — chứ không nhất thiết nằm ở LLM. Microsoft cũng nhấn mạnh production trace logging nên ghi cả input, output và các bước trung gian như retrieved document, chính là để phân biệt lỗi retrieval với hallucination ở generation.


04Thiết kế trace schema: log gì và version gì

Tracing nên bắt đầu bằng một câu hỏi rất cụ thể:

Sáu tháng sau, khi có một incident, những dữ liệu nào tôi cần để dựng lại request này?

~/diagrams/production-rag-evaluation/trace-schema.htmltương tác
mở riêng ↗
HìnhBốn nhóm field xếp theo đúng thứ tự một request đi qua: định danh để nối các mảnh lại, phiên bản để biết cấu hình nào đang chạy, trạng thái retrieval để biết evidence nào được chọn, trạng thái generation để biết prompt nào đã sinh ra câu trả lời. Nhánh dưới là lựa chọn về quyền riêng tư - giữ document_id và chunk_id thay vì sao chép nguyên văn tài liệu sang telemetry backend.
chuỗi field chínhtrạng thái retrievalnhánh riêng tư

Định danh

request_id      session_id
trace_id        conversation_id
timestamp       turn_id
environment

Phiên bản ứng dụng

rag_version           embedding_model
prompt_version        embedding_version
model_name            reranker_model
model_version         index_version
chunking_version      retrieval_config_version

Đây là nhóm hay bị bỏ quên nhất, và cũng là nhóm có giá trị chẩn đoán cao nhất. Nếu dashboard cho thấy Faithfulness rơi từ 0.93 xuống 0.77 và mốc rơi trùng đúng lúc prompt_version = 27 bắt đầu nhận traffic, thì việc điều tra ngắn đi rất nhiều.

Ở bài trước ta đã version hoá cấu hình cho một experiment offline. Ở production, cùng ý tưởng đó nhưng gắn vào từng request, vì tại một thời điểm có thể có nhiều cấu hình cùng chạy:

{
  "rag_config": "rag-v24",
  "prompt": "qa-prompt-v17",
  "embedding": "embed-v5",
  "retriever": "hybrid-v3",
  "reranker": "reranker-v2",
  "index": "kb-2026-09-08"
}

Khi nghi ngờ có hồi quy, ta so sánh giữa các cohort cấu hình thay vì đoán.

Trạng thái retrieval

original_query      candidate IDs
rewritten_query     candidate scores
filters             reranker input
dense_k             reranker scores
sparse_k            selected evidence
fusion_method

Không nhất thiết phải log toàn văn tài liệu nếu privacy, storage hoặc governance không cho phép. Có thể chỉ log document_id, chunk_id, version, điểm và thứ hạng, rồi lấy nội dung từ nguồn khi điều tra và người điều tra có quyền. OpenTelemetry cũng cảnh báo rằng nội dung query và tài liệu có thể chứa dữ liệu nhạy cảm.

Đánh đổi nằm ở chỗ: nếu muốn chạy Faithfulness judge bất đồng bộ thì evaluator vẫn cần context để chấm. Một kiến trúc hợp lý là để trace giữ metadata, còn một worker đánh giá có quyền tự lấy nội dung theo id — thay vì nhân bản nội dung nhạy cảm vô hạn trong telemetry backend.

Trạng thái generation

model            input_tokens
temperature      output_tokens
prompt_version   finish_reason
latency          answer

05Component-level và end-to-end nằm trong cùng một trace

DeepEval có một mapping rất hợp với RAG: trace ứng với end-to-end evaluation, span ứng với component-level evaluation. Trace-level test case đại diện cho một run hoàn chỉnh, còn mỗi span có thể mang test case riêng để chấm một retriever hoặc một LLM call.

~/diagrams/production-rag-evaluation/component-vs-e2e.htmltương tác
mở riêng ↗
HìnhCùng một bộ metric nhưng gắn ở hai độ cao khác nhau thì chẩn đoán được hai thứ khác nhau. Root trace giữ góc nhìn người dùng và trả lời câu hỏi cuối cùng là câu trả lời có giải quyết được vấn đề không. Ba span bên trong trả lời ba câu hỏi hẹp hơn: evidence được tìm ra sao, evidence nào thật sự vào prompt, và câu trả lời được sinh thế nào. Chỉ khi đọc chúng theo cặp thì mới phân biệt được lỗi context với lỗi generation.
root tracecontext spanmetric gắn tại span

Giá trị thực tế nằm ở chỗ đọc kết quả theo cặp. Nếu:

End-to-end   = FAIL
Retriever    = FAIL
Faithfulness = PASS

thì cách đọc hợp lý là: model bám vào context, nhưng context sai. Việc cần làm nằm ở retrieval.

Ngược lại nếu:

Retriever    = PASS
Faithfulness = FAIL

thì evidence đã đúng nhưng generation không sử dụng nó đúng. Việc cần làm nằm ở prompt và hành vi sinh nội dung.

Chỉ nhìn một con số tổng thì hai trường hợp này trông giống hệt nhau, và đó chính là lý do component-level evaluation tồn tại.


06Online evaluation phải nằm ngoài critical path

Trong lúc phát triển, chạy evaluator ngay sau khi component kết thúc rồi in điểm ra là hoàn toàn hợp lý. Nhưng user ở production thì không nên phải chờ LLM judge.

Giả sử:

RAG generation      1.8 s
Faithfulness judge  1.2 s
Answer Relevancy    1.1 s

Nếu chạy tuần tự thì latency người dùng cảm nhận được leo lên khoảng 4.1 s. Và ngoài latency, judge còn trở thành một dependency mới của request path: judge rate limit hoặc judge lỗi sẽ kéo theo cả sản phẩm.

~/diagrams/production-rag-evaluation/async-eval-path.htmltương tác
mở riêng ↗
HìnhHàng trên là đường của user: một request vào pipeline, câu trả lời được sinh ra và trả về ngay, không chờ bất kỳ judge nào. Hàng dưới là đường của evaluation: pipeline xuất một bản sao trace, bản sao đó đi qua hàng đợi tới judge, điểm kèm lý do được ghi vào metrics store rồi mới lên dashboard và alert. Điểm mấu chốt là hàng dưới có thể chậm, có thể lỗi, có thể chạy lại, mà hàng trên không bị ảnh hưởng.
critical pathcâu trả lời trả vềđường evaluation

MLflow production tracing khuyến nghị đúng kiến trúc này: ghi trace bất đồng bộ và chạy automatic online evaluation trên các trace đang đến. DeepEval cũng phân biệt hai chế độ khá rõ — metrics trên @observe là blocking, dùng cho development và testing; production thì dùng metric_collection với evaluation bất đồng bộ.

Mental model khi triển khai với DeepEval

from deepeval.tracing import (
    observe,
    update_current_span,
    update_current_trace,
)


@observe(type="retriever")
def retrieve(query: str):
    documents = search(query)

    update_current_span(
        input=query,
        retrieval_context=[doc.text for doc in documents],
    )

    return documents


@observe(
    type="llm",
    metric_collection="rag-generation-production",
)
def generate(query: str, documents):
    context = build_context(documents)
    return llm.generate(query=query, context=context)


@observe(metric_collection="rag-end-to-end-production")
def answer(query: str):
    docs = retrieve(query)
    output = generate(query, docs)

    update_current_trace(input=query, output=output)
    return output

API cụ thể có thể thay đổi theo phiên bản DeepEval nên implementation thật vẫn nên đối chiếu tài liệu của phiên bản đang dùng. Thứ đáng giữ lại là kiến trúc: retriever span cho telemetry thành phần, LLM span cho telemetry generation, root trace cho telemetry end-to-end, và production metric collection được xử lý ngoài critical path.

Cũng cần phân biệt hai thứ hay bị gộp làm một: deepeval là thư viện evaluation mã nguồn mở, còn luồng online eval qua metric collection trong tài liệu hiện tại gắn với Confident AI như backend quan sát. Nếu không dùng backend đó, raw tracing vẫn có thể đưa sang một observability stack khác, nhưng phần chấm điểm sẽ phải tự dựng.


07Online eval không có nghĩa là chấm 100% request

Giả sử hệ thống nhận 10 request mỗi giây, tức khoảng 864.000 request mỗi ngày. Nếu mỗi request chạy ba judge thì con số trở thành khoảng 2,6 triệu lần gọi judge mỗi ngày. Rất ít sản phẩm chịu được chi phí đó chỉ để quan sát.

Vì vậy production evaluation gần như luôn cần sampling. Cả MLflow lẫn DeepEval đều cho phép điều chỉnh tỷ lệ lấy mẫu ở tầng trace và tầng judge.

Nhưng sampling không nên chỉ là random 10%.

~/diagrams/production-rag-evaluation/sampling-streams.htmltương tác
mở riêng ↗
HìnhTraffic không được lấy mẫu bằng một tỷ lệ duy nhất mà tách thành nhiều dòng trả lời các câu hỏi khác nhau. Dòng ngẫu nhiên cho ước lượng chất lượng toàn cục và là dòng duy nhất không thiên lệch. Dòng tín hiệu xấu lấy toàn bộ những request đã có dấu hiệu hỏng. Dòng rủi ro cao lấy theo giá của một lần sai chứ không theo lưu lượng. Phần ngân sách còn lại dành cho những query lạ - chính là nơi dataset đang thiếu.
dòng ngẫu nhiêndòng tín hiệu xấudòng rủi ro và query lạ

Ngẫu nhiên — ví dụ 5% toàn bộ request. Mục tiêu là ước lượng phân bố chất lượng chung. Đây là dòng duy nhất cho ước lượng không thiên lệch.

Theo tín hiệu xấu — chấm 100% những request có dấu hiệu bất thường:

thumbs_down             timeout
empty_retrieval         fallback
low_rerank_score        no_citation
user_rephrased_immediately

Theo mức rủi ro — không phải query nào cũng có cùng giá của một lần sai. Một câu FAQ đơn giản khác hẳn một câu về quy trình bảo mật:

support FAQ             5%
policy                  30%
security procedure     100%

Theo độ mới — nếu phân tích embedding hoặc classifier phát hiện chủ đề mới, thực thể mới, ngôn ngữ mới hay intent mới thì tăng tỷ lệ chấm. Đây chính là cách dùng production để đi tìm những query nằm ngoài vùng golden dataset đã phủ.

Tỷ lệ nên khác nhau theo từng loại tín hiệu

Một sample_rate = 10% áp cho mọi thứ vừa tốn vừa thiếu. Faithfulness là LLM judge nên đắt; kiểm tra retrieval rỗng là phép so sánh tất định nên gần như miễn phí; latency thì vốn đã có sẵn trong telemetry.

Latency            100% (telemetry)
Empty retrieval    100% (tất định, rẻ)
Faithfulness        10% ngẫu nhiên + dòng có mục tiêu
Human review       0.1% + toàn bộ incident

Sampling là bài toán ngân sách

Giả sử traffic một triệu request mỗi ngày, chi phí chấm một trace là 0.003 đô, ngân sách quan sát là 300 đô mỗi ngày. Tỷ lệ trung bình tối đa vì vậy là 300 / (1.000.000 x 0.003) = 0.10, tức 10%.

Nhưng thay vì rải đều 10% đó, có thể phân bổ:

5%    ngẫu nhiên làm nền
100%  nhóm rủi ro cao
100%  request có phản hồi tiêu cực
phần còn lại cho query lạ

Cũng nên theo dõi chi phí quan sát như một khoản riêng, tách khỏi chi phí phục vụ:

application_cost_per_request
evaluation_cost_per_evaluated_request
evaluation_cost_per_total_request

Nếu RAG serving tốn $0.004 mỗi request và online eval trung bình $0.001 mỗi request, thì quan sát đang chiếm thêm khoảng 25% chi phí phục vụ. Đó là một con số nên được nói ra chứ không nên để nó tự lớn lên.


08Bẫy lớn nhất của sampling: sample có bias làm dashboard sai nghĩa

Giả sử ta chấm 5% ngẫu nhiên cộng với 100% số request bị thumbs-down, rồi gộp tất cả vào một con số:

Faithfulness = 0.71

Con số này không còn là ước lượng không thiên lệch cho toàn bộ production traffic, vì mẫu đã chủ động chứa nhiều lỗi hơn thực tế. Nghịch lý là chiến lược sampling càng tốt cho chẩn đoán thì con số trung bình càng dễ bị đọc sai.

Cách xử lý là dashboard phải biết sampling_policy của từng dòng và tách bạch chúng:

Ước lượng chất lượng chung
└── chỉ từ dòng ngẫu nhiên

Phân tích lỗi
└── từ dòng có mục tiêu

Chất lượng nhóm rủi ro cao
└── từ tầng rủi ro cao

Một mẫu dùng để ước lượng và một mẫu dùng để chẩn đoán là hai thứ khác nhau, và chúng không nên bao giờ được cộng chung vào một ô trung bình.


09Từ metric tới SLI, SLO và alert

Một con số như Faithfulness = 0.82 không tự trả lời được câu hỏi “production có đang unhealthy không”. Cần chuyển raw evaluation result thành tín hiệu ở mức dịch vụ.

Google SRE định nghĩa SLI là một phép đo định lượng cho một khía cạnh của dịch vụ, còn SLO là mục tiêu đặt cho phép đo đó.

~/diagrams/production-rag-evaluation/sli-slo-alert.htmltương tác
mở riêng ↗
HìnhBốn tầng biến điểm thô thành một việc để làm: quy từng trace về pass hoặc fail rồi tính tỷ lệ thành SLI, đặt mục tiêu theo cửa sổ thời gian thành SLO, chuyển vi phạm thành chính sách cảnh báo có kèm ngưỡng tuyệt đối lẫn mức tụt so với nền, rồi mới gọi người. Hàng dưới là chuyện xảy ra khi bỏ tầng gộp ở giữa - mỗi lần judge fail là một alert, và sau vài ngày thì không ai còn tin cảnh báo nữa.
bốn tầng chínhchính sách cảnh báokhi bỏ tầng gộp

Một SLI chất lượng cụ thể

Quy mỗi request đã chấm về PASS hoặc FAIL, rồi định nghĩa:

Faithfulness Pass Rate
= số request pass Faithfulness / số request đã được chấm

Ví dụ chấm 10.000 request, 9.750 pass, tức tỷ lệ pass 97,5%. Một SLO minh hoạ có thể là >= 97% trong cửa sổ trượt 7 ngày.

Đây không phải ngưỡng phổ quát. Nó phải được calibrate theo mức rủi ro của sản phẩm, mức độ hiệu chuẩn của judge, chính sách lấy mẫu, tỷ lệ dương tính giả và mức nghiêm trọng của từng loại lỗi. Quy trình calibrate bằng nhãn người thật đã được nói ở bài trước, và nó vẫn đúng ở đây.

Tương tự với retrieval và latency:

Eligible Retrieval Rate
= số request có >= N chunk đủ liên quan / số request retrieval đã chấm

Latency SLO
99% request dưới 4 giây, hoặc p95 dưới 3 giây

Đừng gọi người vì từng lần judge fail

Judge có nhiễu. Traffic có phương sai. Một request tệ không nhất thiết là một sự cố. Alert nên gộp theo cửa sổ thời gian, theo tỷ lệ, theo mức nghiêm trọng, theo segment và luôn kèm kích thước mẫu. Google SRE nhấn mạnh chiến lược cảnh báo phải cân bằng độ chính xác, độ phủ, thời gian phát hiện và thời gian reset; cảnh báo quá nhạy sẽ tạo ra rất nhiều sự kiện không đáng hành động.

Ngưỡng tuyệt đối và mức tụt so với nền phải cùng tồn tại

Giả sử ngưỡng tối thiểu là 0.75 và chất lượng bình thường dao động quanh 0.90 - 0.92. Sau một lần deploy, con số về 0.79.

Nhìn theo ngưỡng thì đây là PASS. Nhưng chất lượng vừa tụt khoảng 12 điểm. Vì vậy nên có hai loại cảnh báo song song:

Alert A: pass rate thấp hơn SLO
Alert B: pass rate tụt quá X so với baseline ổn định

Một metric vẫn nằm trên ngưỡng hoàn toàn có thể đang hồi quy nghiêm trọng.


10Slicing: số trung bình có thể che mất production failure

Giả sử Answer Relevancy tổng thể là 0.91. Cắt theo ngôn ngữ:

English       0.94
Vietnamese    0.72
Japanese      0.90

Cắt theo tenant:

Tenant A      0.93
Tenant B      0.94
Tenant C      0.61

Cắt theo loại query:

FAQ                 0.96
Policy              0.91
Multi-hop           0.71
Conversational      0.66

Aggregate metric có thể trông rất khỏe chỉ vì phần lớn traffic là câu hỏi dễ. Vì vậy trace metadata phải hỗ trợ cắt lát theo language, tenant, product, query_type, source, risk_level, rag_version, model, prompt_version, index_version.

Một sự cố thật có thể chỉ tồn tại trong một giao điểm hẹp:

Vietnamese + multi-turn + policy + prompt-v18

Số trung bình toàn hệ thống gần như không dịch chuyển. Không có metadata đủ giàu thì sự cố đó vô hình.

Dashboard cho biết có vấn đề hay không. Slice cho biết vấn đề nằm ở đâu. Trace cho biết tại sao.

Dashboard nên trả lời bốn câu hỏi

Một dashboard tốt không phải nơi nhét càng nhiều biểu đồ càng tốt. Nó nên giúp trả lời nhanh: người dùng có đang gặp vấn đề không, vấn đề nằm ở lớp nào, bắt đầu từ khi nào, và version hay segment nào liên quan. Một cấu trúc bốn tầng phục vụ đúng bốn câu đó:

PRODUCT      số request | phản hồi | tỷ lệ giải quyết
QUALITY      faithfulness | relevance | retrieval
PERFORMANCE  p95 latency | lỗi | token | chi phí
CHANGE       query mix | model | prompt | index | source

Ở tầng chất lượng, đừng chỉ hiện Faithfulness 0.88. Nên hiện đủ bối cảnh:

Faithfulness Pass Rate

Current      88%
7d baseline  94%
Delta        -6%
N            2,141

Kích thước mẫu cực kỳ quan trọng: 60% trên 5 mẫu khác hoàn toàn 60% trên 50.000 mẫu.

Ở tầng thay đổi, nên vẽ mốc deploy, đổi prompt, rebuild index, đổi embedding hay đổi provider ngay trên chuỗi thời gian chất lượng. Tương quan không chứng minh nhân quả, nhưng nó cho engineer một điểm bắt đầu để điều tra.


11Drift trong RAG không chỉ là model drift

RAG là một hệ thống có nhiều bộ phận chuyển động, nên nó có nhiều kiểu lệch hơn một mô hình đơn lẻ.

~/diagrams/production-rag-evaluation/rag-drift-map.htmltương tác
mở riêng ↗
HìnhBa loại lệch có thể xảy ra khi không ai sửa một dòng code nào. Query drift đến từ phía người hỏi, knowledge drift đến từ phía tài liệu, retrieval drift đến từ phía chỉ mục. Cột phải là tín hiệu cụ thể để phát hiện từng loại, và điểm chung của cả ba là chúng chỉ lộ ra khi có ai đó theo dõi phân bố theo thời gian chứ không phải theo từng request.
ba loại driftknowledge drifttín hiệu phát hiện

Query drift. Tháng đầu user hỏi "What is our leave policy?". Sáu tháng sau họ hỏi "Can a Vietnam-based contractor carry unused annual leave into the next calendar year?". Độ dài tăng, độ cụ thể tăng, multi-hop tăng, thực thể mới và thuật ngữ mới xuất hiện. Golden dataset cũ có thể không còn đại diện. Tín hiệu cần theo dõi: phân bố độ dài, phân bố ngôn ngữ, phân bố intent, phân bố cụm embedding, tỷ lệ thực thể mới, độ sâu hội thoại, tỷ lệ rewrite. Không cần bắt đầu bằng một statistical drift detector phức tạp — một biểu đồ query mix theo thời gian đôi khi đã đủ để thấy shift lớn.

Knowledge drift. Đây là loại riêng của RAG: nguồn sự thật đổi từ Policy 2025 sang Policy 2026 nhưng index vẫn còn bản cũ, hoặc tệ hơn là chứa cả hai và bản cũ lại xếp hạng cao hơn. Chỉ số nên có:

Freshness Lag = indexed_at - source_updated_at

kèm một SLO nếu độ tươi là yêu cầu nghiệp vụ, ví dụ 95% cập nhật nguồn hiện diện trong retrieval trong vòng 15 phút.

Retrieval drift. Không đổi dòng code nào, nhưng index tăng từ 100 nghìn chunk lên 20 triệu chunk. Cạnh tranh giữa các candidate thay đổi, và một tài liệu từng đứng hạng 2 có thể rơi xuống hạng 18. Theo dõi phân bố điểm retrieval, phân bố điểm rerank, tỷ lệ retrieval rỗng, độ đa dạng nguồn và độ trùng top-k giữa các mốc thời gian.

Model và provider drift. Không nên giả định rằng tên model không đổi thì hành vi chắc chắn không đổi. Trace nên giữ requested_model, response_model, deployment và provider để phân biệt.

Configuration drift. Một phiên bản RAG không chỉ là một Git commit — nó là tổ hợp prompt, embedding, retrieval_k, fusion, reranker, quy tắc ghép context, LLM và index. Đây chính là lý do phần 04 nhấn mạnh việc gắn rag_config vào mọi trace.


12Evaluation và guardrail không phải cùng một thứ

Hai cơ chế này hay bị gộp làm một vì chúng dùng chung công cụ, nhưng mục tiêu của chúng khác nhau và vị trí trong kiến trúc cũng khác nhau.

~/diagrams/production-rag-evaluation/eval-vs-guardrail.htmltương tác
mở riêng ↗
HìnhCùng xuất phát từ một câu trả lời ứng viên nhưng hai nhánh làm hai việc khác nhau. Nhánh trên đo: chấm sau khi user đã nhận trả lời, lưu điểm kèm lý do, dùng để học và cải thiện. Nhánh dưới chặn: kiểm tra đồng bộ trước khi câu trả lời rời khỏi hệ thống, và khi không đạt thì chặn, sinh lại hoặc chuyển cho người thật. Nhánh dưới tốn latency nên chỉ dành cho những yêu cầu không thể sửa sau.
đường evaluationphân tích và cải thiệnđường guardrail

Evaluation đo một câu trả lời đã sinh ra, lưu lại metric và dùng nó để học, theo dõi, so sánh và gỡ lỗi. Guardrail kiểm tra một câu trả lời ứng viên và quyết định có cho nó đi ra ngoài hay không.

Một Faithfulness judge chạy bất đồng bộ là công cụ tốt để theo dõi. Nhưng nếu yêu cầu là không được lộ tài liệu mật, thì access control phải được thực thi ngay trong retrieval, trước khi context đi vào LLM — lọc ở tầng hiển thị là quá muộn, vì mô hình đã đọc nội dung đó rồi. Tương tự với rò rỉ PII, hành động nguy hiểm hoặc vi phạm chính sách: tùy mức rủi ro mà chúng cần kiểm soát đồng bộ.

Guardrail chống hallucination trông như thế nào

Trong nhóm yêu cầu chống bịa đặt, những cơ chế thường dùng là:

  • Bắt buộc citation. Mỗi claim trong câu trả lời phải gắn với ít nhất một chunk_id trong context. Câu trả lời không có citation sẽ bị chặn hoặc bị sinh lại.
  • Abstain khi thiếu evidence. Nếu retrieval rỗng, hoặc điểm rerank cao nhất dưới ngưỡng, hệ thống trả về câu “không tìm thấy trong tài liệu” thay vì cố trả lời. Tỷ lệ abstain đúng chỗ là một metric đáng theo dõi riêng.
  • Kiểm tra grounding đồng bộ rút gọn. Một phiên bản rẻ và nhanh của Faithfulness chỉ kiểm tra các con số, ngày tháng và tên riêng trong câu trả lời có xuất hiện trong context hay không. Nó không thay được judge đầy đủ, nhưng chặn được một nhóm lỗi rất hay gặp với chi phí thấp.
  • Sinh lại có giới hạn. Khi kiểm tra thất bại, sinh lại tối đa một hoặc hai lần rồi chuyển sang câu trả lời an toàn, thay vì lặp vô hạn.

Quyết định đo hay chặn là một quyết định kiến trúc và rủi ro, không phải một lựa chọn công cụ. Chặn đồng bộ tốn latency và thêm một dependency vào request; đo bất đồng bộ thì rẻ nhưng không ngăn được lần sai đầu tiên. Chọn theo giá của một lần sai.


13Từ triệu chứng tới tầng đang hỏng

Một cảnh báo kiểu “chất lượng câu trả lời tụt” mới chỉ là triệu chứng. Để đi tiếp cần một failure taxonomy và một thứ tự kiểm tra cố định.

~/diagrams/production-rag-evaluation/failure-taxonomy.htmltương tác
mở riêng ↗
HìnhBốn câu hỏi đi theo đúng thứ tự pipeline, vì không tầng nào sửa được lỗi của tầng đứng trước nó. Evidence có lọt vào candidate set không, context có giữ nguyên evidence đó không, model có bám vào evidence không, và cuối cùng index có khớp với nguồn thật không. Trả lời không ở bước nào thì tầng đang hỏng nằm ở bước đó, và mỗi tầng lại có một danh sách chỗ cần kiểm tra riêng.
thứ tự kiểm trakiểm tra dữ liệutầng đang hỏng

Lỗi retrieval. Biểu hiện: contextual recall thấp, độ liên quan thấp, tài liệu đúng vắng mặt. Chỗ cần kiểm tra: query rewrite, metadata filter, dense search, BM25, RRF, retrieval_k, trạng thái index.

Lỗi reranking. Đây là chỗ dễ bỏ sót nhất, vì tài liệu đúng thực sự có trong candidate set:

rank 11 trước rerank  ->  rank 32 sau rerank

Chỗ cần kiểm tra: reranker model, cách biểu diễn query, việc cắt ngắn tài liệu, độ dài candidate, thiên lệch theo version.

Lỗi context. Retriever và reranker đúng, nhưng context builder làm rơi evidence, cắt ngắn nó, xếp sai thứ tự hoặc chèn thêm bản trùng đã cũ. Trace cần so sánh được output của reranker với context cuối cùng.

Lỗi generation. Evidence đúng và đủ, nhưng câu trả lời thêm claim không được hỗ trợ, bỏ qua evidence hoặc trả lời sai câu hỏi. Lúc này Faithfulness và hành vi sinh nội dung mới là nghi phạm.

Lỗi dữ liệu. Ứng dụng hoàn toàn đúng so với index, nhưng index sai so với thế giới thật:

source updated 14:00
index still old at 17:00

Đây là lỗi freshness và phải sửa ở pipeline nạp dữ liệu, không phải ở prompt.


14Incident runbook cho một quality incident

Giả sử alert báo: Faithfulness pass rate 92% -> 71%.

~/diagrams/production-rag-evaluation/incident-runbook.htmltương tác
mở riêng ↗
HìnhNăm bước theo thứ tự bắt buộc, và bước đầu tiên là nghi ngờ chính thiết bị đo chứ không phải hệ thống. Sau khi tín hiệu được xác thực mới soi mốc thay đổi, rồi cắt lát để biết nhóm nào hỏng, rồi đọc trace mẫu để biết tầng nào hỏng, rồi mới giảm thiểu. Hàng dưới là hai cái bẫy hay gặp nhất: kết luận RAG hỏng trong khi thứ hỏng là evaluator, và đọc số trung bình trong khi một tenant đang sập.
năm bước điều trađọc trace mẫubẫy thường gặp

Bước 1 — xác thực tín hiệu. Kích thước mẫu có đủ không, judge backend có khỏe không, sampling có vừa đổi không, judge version có vừa đổi không. Rất phí công khi debug RAG trong lúc thứ hỏng thật ra là evaluator.

Bước 2 — soi mốc thay đổi. Deploy, prompt, model, index, đợt nạp tài liệu, reranker.

Bước 3 — cắt lát. Ngôn ngữ, tenant, loại query, phiên bản RAG, nguồn tài liệu. Ví dụ:

All traffic            71%
├── English            91%
└── Vietnamese         42%
    ├── Policy         31%
    ├── FAQ            88%
    └── Technical      84%

Bước 4 — đọc trace mẫu. Chọn 5 tới 20 ca lỗi tiêu biểu và phân loại chúng theo taxonomy ở phần 13. Trong ví dụ trên, trace có thể cho thấy bước rewrite đang làm sai thuật ngữ pháp lý ở các câu hỏi chính sách tiếng Việt.

Bước 5 — giảm thiểu rồi sửa gốc. Rollback prompt query-rewrite về v17 để dừng thiệt hại, sau đó mới sửa gốc.

Bước 6 — tạo tài sản regression. Đưa chính những trace đã hỏng vào evaluation dataset.

Một incident chỉ thật sự đóng khi nguyên nhân gốc được hiểu và lỗi đã tái lập được, chứ không phải khi biểu đồ xanh trở lại.

Postmortem cho quality incident

Một sự cố chất lượng xứng đáng có postmortem như một sự cố độ tin cậy:

## Impact          user nào, bao nhiêu request
## Detection       alert nào phát hiện, hay user báo
## Timeline        deploy / index update / lỗi đầu tiên / giảm thiểu
## Root Cause      dữ liệu, retrieval, context, generation hay evaluator
## Why offline tests missed it
## Corrective Actions

Trong đó câu hỏi quan trọng nhất không phải “vì sao RAG sai”, mà là:

Vì sao hệ thống đánh giá không phát hiện được điều này trước khi deploy?

Vì mỗi incident không chỉ nên cải thiện RAG. Nó phải cải thiện cả bộ đánh giá. Ví dụ: lỗi là query rewrite tiếng Việt sai ở hội thoại nhiều lượt — thì phần sửa RAG là prompt rewrite mới, còn phần sửa evaluation là bổ sung golden hội thoại tiếng Việt và thêm một slice dashboard cho nhóm đó.


15Human feedback: tín hiệu mà LLM judge không thay thế được

LLM-as-a-Judge giúp mở rộng quy mô đánh giá. Nhưng chuyên gia domain biết những thứ judge không thể tự biết. Ví dụ với một chính sách nội bộ vừa được duyệt ngoại lệ hôm qua: judge không thể biết điều đó nếu evidence nó nhận được chưa chứa thay đổi ấy, trong khi một người làm nhân sự nhìn phát là nói được “câu trả lời này đã lỗi thời”.

Vì vậy production evaluation nên có ba tầng phản hồi: tín hiệu tự động, phản hồi người dùng cuối, và đánh giá của chuyên gia. MLflow hiện cho phép gắn feedback và expectation trực tiếp vào production trace và xem đó như một nguồn dữ liệu cho cải tiến liên tục.

Thumbs-down chưa đủ

Một UI chỉ có hai nút thích và không thích thì tốt hơn không có gì, nhưng nó không giải thích nguyên nhân. Feedback có cấu trúc hữu ích hơn nhiều:

Thông tin sai          Nguồn đã lỗi thời
Thiếu thông tin        Bịa đặt
Sai nguồn              Không liên quan
Quá dài dòng           Quá chậm

Và feedback phải gắn trace_id để mở đúng execution path:

{
  "trace_id": "rag_82f1",
  "rating": "negative",
  "category": "outdated_source",
  "comment": "Policy changed last week"
}

Từ đó có thể lọc toàn bộ lỗi outdated_source và xem chúng có cùng một nguyên nhân gốc hay không.

Tín hiệu yếu vẫn chỉ là tín hiệu yếu

Ở production thường không có expected_output, nên evaluation phải dựa nhiều hơn vào metric referenceless và các tín hiệu gián tiếp như thumbs up/down, tỷ lệ hỏi lại, tỷ lệ fallback, số lần click citation, tỷ lệ chuyển cho người thật.

Nhưng cần nhớ: tín hiệu yếu không phải ground truth. User không bấm thumbs-down chưa chắc câu trả lời đúng. User hỏi lại chưa chắc câu trước sai. Click citation chưa chắc citation đó hỗ trợ claim. Vì vậy production quality nên kết hợp nhiều tín hiệu thay vì suy diễn mạnh từ một con số duy nhất.

Judge cũng cần được đánh giá

LLM judge không phải oracle. Nó có thể dương tính giả, âm tính giả, thiên lệch theo văn phong, nhạy cảm với cách đặt câu và thay đổi hành vi giữa các phiên bản model. Vì vậy nên định kỳ lấy một mẫu có nhãn người thật và dựng confusion matrix giữa judge và người, rồi theo dõi độ chính xác, độ phủ và mức đồng thuận.

Một nguyên tắc thiết kế thí nghiệm quan trọng: đừng đổi judge model và RAG system trong cùng một lần. Nếu thứ hai chạy RAG v10 + Judge A mà thứ ba chạy RAG v11 + Judge B và điểm rơi từ 0.89 xuống 0.82, thì không thể biết đó là hồi quy của RAG, là thay đổi hiệu chuẩn của judge, hay cả hai. Khi cần đổi judge, hãy chạy một cửa sổ chồng lấn — cùng một tập trace đi qua cả Judge A lẫn Judge B — để đo độ dịch của thang điểm trước.

Ưu tiên hàng đợi review của con người

Human review đắt, nên đừng review ngẫu nhiên mọi thứ với cùng mức ưu tiên:

P0   lỗi rủi ro cao về bảo mật hoặc pháp lý
P1   phản hồi tiêu cực kèm faithfulness thấp
P2   cụm query mới xuất hiện
P3   kiểm định chất lượng ngẫu nhiên

Mục tiêu là phân bổ ngân sách review vào chỗ có kỳ vọng thu được nhiều thông tin nhất.


16Production trace phải trở thành nguồn cho evaluation dataset

Đây là bước quan trọng nhất của cả bài, và cũng là bước hay bị bỏ qua nhất.

Một lỗi production xảy ra. Nếu team chỉ sửa, deploy, đóng incident, thì sáu tháng sau lỗi tương tự hoàn toàn có thể quay lại. Thay vào đó, chuỗi đúng phải là:

lỗi thật -> gom nhóm -> chọn đại diện -> gắn nhãn -> golden -> regression test

MLflow hiện cho phép xây evaluation dataset từ chính các trace đã có và mô tả tương tác production lịch sử như một nguồn rất hữu ích để tạo dataset phản ánh tình huống thật. DeepEval cũng hướng tới vòng lặp đưa production trace trở lại evaluation dataset để tiếp tục test trong development.

~/diagrams/production-rag-evaluation/trace-to-golden.htmltương tác
mở riêng ↗
HìnhBốn bước biến một trace lỗi thành tài sản regression: gom các trace lỗi theo nguyên nhân chứ không theo câu chữ, chọn vài case đại diện thay vì giữ cả nghìn biến thể, để curator bổ sung ground truth mà trace thô không có, rồi mới đưa vào suite. Nhánh dưới là chuyện xảy ra khi bỏ bước gom nhóm - dataset phình lên thành kho log, chi phí chấm tăng theo, còn khả năng phát hiện lỗi thì không tăng tương ứng.
quy trình curatebước gắn nhãnnếu bỏ bước gom nhóm

Không phải trace nào cũng nên thành golden

Nếu đưa tất cả vào thì dataset phình to, độ trùng lặp tăng, chi phí đánh giá tăng và chi phí bảo trì tăng. Golden dataset không phải kho log.

Một case đáng curate khi nó đại diện cho một failure mode mới, một tình huống nghiệp vụ quan trọng, một phân bố query mới, một edge case quan trọng, một hành vi dễ hồi quy hoặc một tình huống rủi ro cao. Và nên khử trùng lặp theo intent, theo loại lỗi, theo nguồn và theo cấu trúc câu hỏi. Nếu production có 1.000 biến thể của cùng một ý:

"What about contractors in VN?"
"Vietnam contractors?"
"Does this apply to contractor Vietnam?"

thì không cần giữ cả 1.000. Gom cụm, chọn vài case đại diện, rồi mới viết expectation cho chúng.

Trace thô chưa phải một golden tốt

Một trace chỉ có input, actual_output và retrieval_context. Curator phải bổ sung phần mà production không có:

{
  "input": "Can Vietnam contractors carry unused leave over?",
  "expected_output": "...",
  "expected_sources": ["leave-policy-2026#contractors"],
  "tags": ["policy", "vietnam", "contractor", "carry-over"],
  "origin": "production_failure",
  "failure_type": "query_rewrite"
}

Hai field origin và failure_type đáng để bắt buộc. Chúng biến dataset thành một thứ đọc được như lịch sử những gì team đã học, chứ không phải một đống case không rõ vì sao tồn tại.


17Checklist trước khi gọi một hệ RAG là production-ready

Tracing

  • Mọi request có trace id.
  • Có span cho các chặng retrieval và generation quan trọng.
  • Lưu version của RAG, prompt, model và index.
  • Có thể dựng lại được evidence đã dùng.
  • Có latency theo từng component.

Chất lượng

  • Có metric end-to-end.
  • Có tín hiệu component-level cho retrieval và generation.
  • Có đường phản hồi của con người.
  • Có cắt lát theo các cohort quan trọng.

Online evaluation

  • Judge không chặn request của user.
  • Có chiến lược sampling, và mỗi tín hiệu có tỷ lệ riêng.
  • Có ngân sách chi phí đánh giá được theo dõi tách bạch.
  • Judge được version hoá và định kỳ hiệu chuẩn với nhãn người.

Monitoring

  • Có dashboard đủ cả chất lượng, độ trễ và chi phí.
  • Có so sánh với baseline, không chỉ so với ngưỡng.
  • Có SLI và SLO rõ ràng.
  • Alert có hành động kèm theo, không chỉ là thông báo.

Drift

  • Theo dõi query mix.
  • Theo dõi độ tươi của tri thức.
  • Theo dõi version của retrieval và index.
  • Theo dõi cấu hình model và prompt.

Riêng tư

  • Có chính sách logging và redaction.
  • Không log nội dung nhạy cảm vô tội vạ.
  • Có kiểm soát truy cập cho trace.
  • Có chính sách lưu trữ và xoá.

Cải tiến liên tục

  • Lỗi production được review.
  • Lỗi tiêu biểu được curate thành golden.
  • Golden có nguồn và expectation rõ ràng.
  • Regression suite được cập nhật.
  • Mỗi incident cải thiện cả ứng dụng lẫn bộ đánh giá.

Nếu thiếu đúng đoạn lỗi thật -> golden -> regression thì monitoring vẫn chỉ là quan sát. Nó chưa trở thành một hệ thống biết học.


Evaluation không phải một giai đoạn, nó là một vòng lặp

RAG evaluation không kết thúc khi CI pass. Một hệ thống trước deploy có thể được đánh giá bằng một dataset hữu hạn và cho ra chữ PASS. Nhưng phân bố ở production không đứng yên: user thay đổi, tri thức thay đổi, index thay đổi, model thay đổi, prompt thay đổi. Và chính những lỗi thật đó mới cho ta biết evaluation dataset còn thiếu gì.

Vì vậy kiến trúc cuối cùng của production evaluation không nên là:

Deploy -> Dashboard

mà là:

Deploy -> Trace -> Evaluate -> Detect -> Diagnose
       -> Curate -> Golden -> Regression -> Improve -> Deploy

Nếu cần cô đọng cả bài thành một câu:

Production RAG Evaluation không phải là chấm điểm response sau khi deploy; nó là cơ chế biến traffic thật thành phản hồi có cấu trúc để hệ thống ngày càng khó hồi quy hơn.

Series này bắt đầu bằng câu hỏi “RAG được xây như thế nào” và kết thúc bằng một câu hỏi trưởng thành hơn: làm thế nào để một hệ RAG tự tạo ra dữ liệu cần thiết cho phiên bản tiếp theo của chính nó? Khi production trace, automated evaluation, human feedback, failure analysis và golden dataset nối lại thành một vòng kín, RAG mới thực sự trở thành một hệ thống vận hành được, đo được và cải tiến được — thay vì một demo có retrieval.


Tài liệu tham khảo

Trương Đức Dũng

AI Engineer - Hà Nội

Tập trung vào LLM, RAG và các hệ thống AI cần chạy ổn định trong môi trường vận hành thật.