05 Khép kín vòng lặp
Biến một lỗi production đã được review thành dữ liệu vàng, evaluator chính sách nghiệp vụ đã hiệu chỉnh và cơ chế bảo vệ traffic tương lai.
Điểm khởi đầu
Mô-đun 04 kết thúc bằng một annotation của
con người đã hoàn tất cho chat_turn có thẩm quyền từ Mô-đun 03. Hãy chuẩn bị sẵn SQL
đã sửa và bảng ghi nhận nguồn gốc:
source=production-feedback
source_trace_id=<authoritative Chat trace ID>
failure_category=stale-business-policy
source_policy_version=policy-v1
annotation_id=<completed task ID when available>Trace production ban đầu có sql-execution-success=true và user-thumbs=false.
Lượt 👎 giúp tìm ra trace đáng review; annotation đã hoàn tất mới cung cấp chẩn đoán
và bản sửa làm ground truth.
Vòng lặp đánh giá và cải tiến liên tục
Mô-đun này đóng một lượt của vòng lặp:
- phản hồi người dùng làm lộ điểm mù trong evaluator online hiện tại;
- con người điều tra và phê duyệt bản sửa;
- sự cố đã review được đưa vào bộ dữ liệu vàng;
- bản baseline và candidate chạy trên cùng bộ dữ liệu đã mở rộng;
- evaluator tổng quát được hiệu chỉnh offline trước khi bật online; và
- traffic tương lai tiếp tục thu thập cả điểm evaluator lẫn phản hồi người dùng.
Bước cuối rất quan trọng: triển khai evaluator tốt hơn không loại bỏ vai trò của phản hồi người dùng. Evaluator chỉ đo được các khía cạnh có trong catalog chính sách và prompt của nó. Một lượt 👎 trong tương lai có thể phát hiện chính sách còn thiếu, yêu cầu mơ hồ hoặc một kiểu lỗi khác, rồi khởi động lại chính vòng lặp này.
Mục tiêu
Vượt qua năm cổng bằng chứng: promotion, baseline, candidate, calibration, rồi enable và replay. Dùng cấu hình chiến thắng từ Mô-đun 02 cho cả hai experiment để phiên bản chính sách là thay đổi có chủ đích duy nhất.
Chạy mọi lệnh bên dưới từ ClickHouse_Demos/workshops/agent_arena:
cd ClickHouse_Demos/workshops/agent_arena
source .env
export WINNER_MODEL="${WINNER_MODEL:-qwen3.7-flash}"
export WINNER_PROMPT="${WINNER_PROMPT:-P2_fewshot}"
export WINNER_CONFIG_ID="${WINNER_CONFIG_ID:-qwen3.7-flash__P2_fewshot}"Giá trị mặc định là cấu hình chiến thắng đã được kiểm chứng của workshop. Nếu lớp chọn config_id
khác, hãy đặt cả ba biến theo model/prompt đó và giữ nguyên qua mọi cổng.
Cổng bằng chứng 1 — Promote sự cố đã review
Tạo reviewed.json tại thư mục gốc của lab với ba bản ghi sau. Thay thế hai placeholder
ở mọi vị trí trước khi chạy promotion. Nếu Langfuse không hiển thị annotation task ID,
hãy xóa annotation_id khỏi cả ba bản ghi thay vì để placeholder; trường này không bắt buộc,
nhưng các trường nguồn gốc production khác là bắt buộc.
[
{
"id": "prod-active-001",
"question": "How many active customers do we have?",
"golden_sql": "SELECT uniqExact(customer_id) FROM v_orders WHERE order_ts >= now() - INTERVAL 30 DAY AND status NOT IN ('cancelled', 'returned')",
"tier": 2,
"ordered": false,
"source": "production-feedback",
"source_trace_id": "<paste the Module 03 Chat trace ID>",
"failure_category": "stale-business-policy",
"source_policy_version": "policy-v1",
"annotation_id": "<paste the completed task ID>"
},
{
"id": "prod-active-002",
"question": "What is our active customer count right now?",
"golden_sql": "SELECT uniqExact(customer_id) FROM v_orders WHERE order_ts >= now() - INTERVAL 30 DAY AND status NOT IN ('cancelled', 'returned')",
"tier": 2,
"ordered": false,
"source": "production-feedback",
"source_trace_id": "<paste the Module 03 Chat trace ID>",
"failure_category": "stale-business-policy",
"source_policy_version": "policy-v1",
"annotation_id": "<paste the completed task ID>"
},
{
"id": "prod-active-003",
"question": "How many customers qualify as active under our business definition?",
"golden_sql": "SELECT uniqExact(customer_id) FROM v_orders WHERE order_ts >= now() - INTERVAL 30 DAY AND status NOT IN ('cancelled', 'returned')",
"tier": 2,
"ordered": false,
"source": "production-feedback",
"source_trace_id": "<paste the Module 03 Chat trace ID>",
"failure_category": "stale-business-policy",
"source_policy_version": "policy-v1",
"annotation_id": "<paste the completed task ID>"
}
]Chỉ prod-active-001 là câu hỏi chính xác từ trace có phản hồi người dùng.
prod-active-002 và prod-active-003 là hai cách diễn đạt do người review tạo ra từ
cùng sự cố đã điều tra. Để kiểm toán, cả ba dùng chung source trace và annotation đã hoàn tất;
chúng không đại diện cho hai trace feedback production bổ sung. Cả ba input đều chủ đích
gọi metric khách hàng đang hoạt động được quản trị, nên baseline không thể trông khỏe mạnh
bằng cách kiểm tra các phép đếm không liên quan.
Promote lô đã review:
source .env
.venv/bin/python -m scripts.promote_to_golden reviewed.jsonKết quả phải có ba dòng prepared prod-active-*, sau đó là:
promoted 3 question(s) into the 'arena-golden' datasetMở Langfuse → Datasets → arena-golden và kiểm tra metadata của từng item mới.
Xác minh source=production-feedback, cùng một source_trace_id thật,
failure_category=stale-business-policy và source_policy_version=policy-v1.
Bộ nguồn trong repo có 20 câu hỏi YAML. q019 và q020 được giữ lại làm few-shot
prompt holdout, nên một project sạch bắt đầu với 18 Experiment item trong arena-golden.
Ba lần promotion này nâng dataset sạch lên 21 item. Project dùng lại có thể chứa thêm
approved item; hãy ghi lại provenance đó thay vì xóa để ép số lượng, và yêu cầu baseline
với candidate dùng cùng một tập item ID.
reviewed.json là trạng thái runtime có thể thay đổi, đã được ignore, và là luồng chính của workshop.
--synthetic-fixture được track chỉ là phương án dự phòng để diễn tập có thể lặp lại.
Nó không đại diện cho annotation của con người và không đáp ứng cổng bằng chứng của mô-đun này.
Hai chế độ loại trừ lẫn nhau; không chạy fixture tổng hợp sau một lần promotion thật.
Script promotion xác thực toàn bộ batch, SQL chỉ đọc và nguồn gốc bắt buộc trước khi truy vấn ClickHouse hoặc ghi dataset item. Sau đó script đọc metadata hiện có và từ chối ID xung đột có nguồn gốc production khác. Nếu bước kiểm tra không thể xác lập nguồn gốc an toàn, script dừng mà không ghi dữ liệu. Chỉ lặp lại promotion thật khi bản ghi xung đột có nguồn gốc production hoàn toàn giống nhau.
Cổng bằng chứng 2 — Chạy baseline policy-v1
Trước tiên, provision judge dựa trên catalog cho các experiment. Lệnh này tạo online observation rule ở trạng thái tắt:
source .env
.venv/bin/python -m scripts.provision_online_evaluators \
--business-policy-experimentsKết quả phải có experiment rule enabled=True; online rule enabled=False.
Xác nhận online rule vẫn tắt trong Langfuse trước khi tiếp tục.
Tạo hậu tố duy nhất cho lần thực hành này, rồi chạy model và prompt đã chọn trên bộ dữ liệu mở rộng với chính sách lỗi thời:
export LOOP_RUN_SUFFIX="${LOOP_RUN_SUFFIX:-$(date +%Y%m%d-%H%M%S)}"
export BASELINE_RUN_ID="online-loop-baseline-${LOOP_RUN_SUFFIX}"
export CANDIDATE_RUN_ID="online-loop-candidate-${LOOP_RUN_SUFFIX}"
.venv/bin/python -m eval.harness --run-id "$BASELINE_RUN_ID" \
--policy-version policy-v1 --models "$WINNER_MODEL" --prompts "$WINNER_PROMPT" \
--wait-for-score business-policy-adherenceHarness nối --policy-v1 vào release ID. Trên mỗi trace, harness chờ đúng ba tên score
của experiment: correctness, agent-arena-llm-judge và business-policy-adherence.
Không tiếp tục nếu lệnh timeout hoặc thiếu bất kỳ score nào.
Trong Langfuse Experiments, ghi số lượng item và correctness tổng hợp của baseline. Sau promotion, hãy kỳ vọng 21 item trong một project sạch. Project dùng lại có thể có thêm approved item, và response của provider có thể thay đổi, vì vậy cổng phát hành là phép so sánh đối chứng bên dưới thay vì một aggregate bị hard-code.
Cổng bằng chứng 3 — Chạy candidate policy-v2
Không thay đổi dataset, model, prompt hay run suffix; hãy chạy candidate:
.venv/bin/python -m eval.harness --run-id "$CANDIDATE_RUN_ID" \
--policy-version policy-v2 --models "$WINNER_MODEL" --prompts "$WINNER_PROMPT" \
--wait-for-score business-policy-adherenceGhi aggregate thực tế của candidate, rồi so sánh hai run trong Langfuse và yêu cầu:
- dataset item ID và số lượng item giống hệt nhau;
- cả ba mục
prod-active-*đều chuyển từcorrectness=0dướipolicy-v1sangcorrectness=1dướipolicy-v2; - mọi item có trước
prod-active-*đều được so sánh theo từng item, không có regression từcorrectness=1xuốngcorrectness=0; và - correctness tổng hợp của candidate không thấp hơn baseline.
Dừng nếu một item có sẵn bị regression. Một candidate sửa sự cố bằng cách phá vỡ hành vi đã biết vẫn chưa vượt qua cổng phát hành.
Cổng bằng chứng 4 — Hiệu chỉnh judge chính sách tổng quát
business-policy-adherence không phải “evaluator riêng cho khách hàng đang hoạt động”.
Nó nhận câu hỏi, SQL được tạo và catalog metric đầy đủ của policy-v2, tự xác định metric
được quản trị nào áp dụng rồi trả về PASS, FAIL hoặc NOT_APPLICABLE. Cùng một thiết kế
có thể kiểm tra khách hàng đang hoạt động, doanh thu, tỷ lệ chuyển đổi và biên lợi nhuận gộp
mà không tạo evaluator riêng cho từng cách diễn đạt câu hỏi.
Trước khi bật cho observation production, hãy kiểm tra các item Experiment sau:
| Trường hợp hiệu chỉnh | Run/item | business-policy-adherence bắt buộc |
|---|---|---|
| SQL khách hàng đang hoạt động lỗi thời | baseline prod-active-001 | FAIL |
| SQL khách hàng đang hoạt động đã sửa | candidate prod-active-001 | PASS |
| chính sách doanh thu | candidate q005 | PASS |
| chính sách chuyển đổi từ xem sang mua | candidate q018 | PASS |
| phép đếm khách hàng đơn giản | candidate q001 | NOT_APPLICABLE |
Lặp lại phép kiểm tra khách hàng đang hoạt động cho prod-active-002 và prod-active-003.
Đọc cả reasoning lẫn category của judge: reasoning phải nêu chính sách áp dụng và đánh giá
SQL theo chính sách đó. Phép đếm đơn giản phải giữ NOT_APPLICABLE, chứng minh judge không
ép mọi câu hỏi đếm vào chính sách khách hàng đang hoạt động.
Giữ online rule ở trạng thái tắt nếu bất kỳ category nào sai, thiếu score bắt buộc, structured output sai định dạng hoặc phép so sánh correctness có regression. Hiệu chỉnh offline trên experiment là bước bắt buộc vì cho phép kiểm tra false pass và false fail trên các ví dụ đã biết trước khi evaluator ảnh hưởng đến giám sát production.
Cổng bằng chứng 5 — Bật và replay trên policy-v2
Chỉ bật observation rule sau khi vượt qua tất cả cổng hiệu chỉnh:
source .env
.venv/bin/python -m scripts.provision_online_evaluators \
--enable-business-policy-onlineKết quả phải có đúng tên rule agent-arena-business-policy-online với enabled=True.
Lệnh fail-closed nếu không tìm thấy score Experiment business-policy-adherence trong phạm vi
dataset; các bước kiểm tra hiệu chỉnh thủ công ở trên vẫn là cổng chất lượng.
Dừng server policy-v1. Trong terminal thứ nhất, khởi động candidate và giữ tiến trình chạy:
source .env
AGENT_ARENA_POLICY_VERSION=policy-v2 \
.venv/bin/uvicorn serving.api:app --port 8100Trong terminal thứ hai, định nghĩa helper nhận câu hỏi và chỉ trả trace ID sau khi xác nhận
response policy-v2 thành công:
source .env
export WINNER_CONFIG_ID="${WINNER_CONFIG_ID:-qwen3.7-flash__P2_fewshot}"
ask_trace() {
local question="$1"
local body
body=$(.venv/bin/python -c \
'import json,sys; print(json.dumps({"question": sys.argv[1], "config_id": sys.argv[2]}))' \
"$question" "$WINNER_CONFIG_ID")
curl -fsS http://localhost:8100/ask \
-H 'content-type: application/json' -d "$body" | \
.venv/bin/python -c \
'import json,sys; data=json.load(sys.stdin); assert data["policy_version"] == "policy-v2" and data["outcome"] == "ok"; print(data["trace_id"])'
}Đặt câu hỏi về khách hàng đang hoạt động và doanh thu một lần. Dùng tên score của online
observation rule agent-arena-business-policy-online, không dùng tên score Experiment:
ACTIVE_TRACE=$(ask_trace "How many active customers do we have?")
.venv/bin/python -m scripts.verify_online_scores "$ACTIVE_TRACE" \
sql-execution-success=true agent-arena-business-policy-online=PASS
REVENUE_TRACE=$(ask_trace "What was revenue in the last 30 days?")
.venv/bin/python -m scripts.verify_online_scores "$REVENUE_TRACE" \
sql-execution-success=true agent-arena-business-policy-online=PASSCâu hỏi tỷ lệ chuyển đổi có biên ngẫu nhiên đã được kiểm chứng. Hỏi một lần và giữ trace đó.
Nếu serving outcome khác ok, hoặc thiếu/sai các score bắt buộc chính xác, hãy thử lại cùng
câu hỏi và cấu hình tối đa một lần. Khối lệnh sau giữ cả hai lần thử hiển thị:
ask_conversion() {
local body
body=$(.venv/bin/python -c \
'import json,sys; print(json.dumps({"question": sys.argv[1], "config_id": sys.argv[2]}))' \
"What is our view-to-purchase conversion rate for the last 7 days?" \
"$WINNER_CONFIG_ID")
curl -fsS http://localhost:8100/ask \
-H 'content-type: application/json' -d "$body" | \
.venv/bin/python -c \
'import json,sys; data=json.load(sys.stdin); assert data["policy_version"] == "policy-v2"; print("\t".join((data["trace_id"], data["outcome"])))'
}
IFS=$'\t' read -r CONVERSION_TRACE_1 CONVERSION_OUTCOME_1 <<< \
"$(ask_conversion)"
if .venv/bin/python -m scripts.verify_online_scores "$CONVERSION_TRACE_1" \
sql-execution-success=true agent-arena-business-policy-online=PASS; then
CONVERSION_SCORES_1=pass
else
CONVERSION_SCORES_1=fail
fi
if [ "$CONVERSION_OUTCOME_1" = ok ] && [ "$CONVERSION_SCORES_1" = pass ]; then
CONVERSION_RESULT_1=pass
else
CONVERSION_RESULT_1=fail
fi
printf 'conversion_attempt=1 trace_id=%s outcome=%s exact_scores=%s result=%s\n' \
"$CONVERSION_TRACE_1" "$CONVERSION_OUTCOME_1" \
"$CONVERSION_SCORES_1" "$CONVERSION_RESULT_1"
CONVERSION_TRACE_2=not-run
CONVERSION_OUTCOME_2=not-run
CONVERSION_SCORES_2=not-run
CONVERSION_RESULT_2=not-run
if [ "$CONVERSION_RESULT_1" != pass ]; then
IFS=$'\t' read -r CONVERSION_TRACE_2 CONVERSION_OUTCOME_2 <<< \
"$(ask_conversion)"
if .venv/bin/python -m scripts.verify_online_scores "$CONVERSION_TRACE_2" \
sql-execution-success=true agent-arena-business-policy-online=PASS; then
CONVERSION_SCORES_2=pass
else
CONVERSION_SCORES_2=fail
fi
if [ "$CONVERSION_OUTCOME_2" = ok ] && [ "$CONVERSION_SCORES_2" = pass ]; then
CONVERSION_RESULT_2=pass
else
CONVERSION_RESULT_2=fail
fi
fi
printf 'conversion_attempt=2 trace_id=%s outcome=%s exact_scores=%s result=%s\n' \
"$CONVERSION_TRACE_2" "$CONVERSION_OUTCOME_2" \
"$CONVERSION_SCORES_2" "$CONVERSION_RESULT_2"
if [ "$CONVERSION_RESULT_1" != pass ] && \
[ "$CONVERSION_RESULT_2" != pass ]; then
printf '%s\n' \
'STOP: conversion failed twice; preserve both traces and investigate.' >&2
false
fiKhông tiếp tục retry cho đến khi có kết quả đạt. Nếu cả hai lần đều thất bại, giữ lại hai trace, để nguyên kết quả hiển thị và đưa bằng chứng mới qua cùng vòng lặp annotation của con người, cải thiện dữ liệu vàng và hiệu chỉnh đối chứng.
Chỉ sau khi kiểm tra tỷ lệ chuyển đổi đạt, hãy hỏi câu đếm đơn giản một lần:
PRODUCT_TRACE=$(ask_trace "How many products are there?")
.venv/bin/python -m scripts.verify_online_scores "$PRODUCT_TRACE" \
sql-execution-success=true agent-arena-business-policy-online=NOT_APPLICABLEEvaluator online chạy bất đồng bộ. Theo mặc định, verifier polling tối đa 180 giây; score còn chờ xử lý không đồng nghĩa với score không đạt.
Duy trì vòng lặp
Giữ tính năng 👍/👎 sau khi triển khai. Theo dõi những mâu thuẫn như
agent-arena-business-policy-online=PASS đi cùng user-thumbs=false; đây là ứng viên
giá trị cao cho annotation queue tiếp theo. Review của con người quyết định cần sửa chính sách,
prompt, dữ liệu hay evaluator. Các trường hợp được phê duyệt quay lại arena-golden, rồi
candidate tiếp theo lặp lại chuỗi baseline → candidate → calibration → guarded enablement.
Rule của workshop lấy mẫu 100% trace đủ điều kiện để mọi học viên đều thấy bằng chứng. Đây là thiết lập giảng dạy, không phải mặc định production. Tỷ lệ lấy mẫu thực tế phải cân nhắc lưu lượng, chi phí đánh giá, độ trễ, rủi ro và phạm vi sự cố cần phát hiện.
Bằng chứng hoàn tất
- Root trace production ban đầu vẫn hiển thị
sql-execution-success=truevà Booleanuser-thumbs=false. - Annotation task của con người trong
production-investigation-<session>đã hoàn tất với bản sửa được xác minh vàapproved-for-golden=true. - Cả ba item vàng đều có nguồn gốc
production-feedbackthật; bạn phân biệt được một câu hỏi người dùng với hai cách diễn đạt do người review tạo. - Baseline và candidate dùng cùng dataset mở rộng, model và prompt; candidate sửa cả ba item đã promote mà không tạo regression về correctness.
- Calibration trên Experiment tạo đúng
FAIL,PASSvàNOT_APPLICABLEdưới tên scorebusiness-policy-adherence. - Observation rule tắt trong lúc calibration và chỉ được bật sau khi mọi cổng đạt.
- Trace khách hàng đang hoạt động, doanh thu và tỷ lệ chuyển đổi có
agent-arena-business-policy-online=PASS; số lượng sản phẩm đơn giản cóagent-arena-business-policy-online=NOT_APPLICABLE. - Bạn có thể giải thích vì sao đánh giá online và phản hồi người dùng tiếp tục bổ sung cho nhau sau khi triển khai.