Agent ArenaClickHouse Workshops

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:

  1. phản hồi người dùng làm lộ điểm mù trong evaluator online hiện tại;
  2. con người điều tra và phê duyệt bản sửa;
  3. sự cố đã review được đưa vào bộ dữ liệu vàng;
  4. bản baseline và candidate chạy trên cùng bộ dữ liệu đã mở rộng;
  5. evaluator tổng quát được hiệu chỉnh offline trước khi bật online; và
  6. 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.json

Kết quả phải có ba dòng prepared prod-active-*, sau đó là:

promoted 3 question(s) into the 'arena-golden' dataset

Mở 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-experiments

Kế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-adherence

Harness 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-adherence

Ghi 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=0 dưới policy-v1 sang correctness=1 dưới policy-v2;
  • mọi item có trước prod-active-* đều được so sánh theo từng item, không có regression từ correctness=1 xuống correctness=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ỉnhRun/itembusiness-policy-adherence bắt buộc
SQL khách hàng đang hoạt động lỗi thờibaseline prod-active-001FAIL
SQL khách hàng đang hoạt động đã sửacandidate prod-active-001PASS
chính sách doanh thucandidate q005PASS
chính sách chuyển đổi từ xem sang muacandidate q018PASS
phép đếm khách hàng đơn giảncandidate q001NOT_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-online

Kế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 8100

Trong 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=PASS

Câ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
fi

Khô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_APPLICABLE

Evaluator 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=true và Boolean user-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-feedback thậ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, PASS và NOT_APPLICABLE dưới tên score business-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.

Trên trang này

Track your progress?

Optional. We email a link to confirm your address; progress records once you open it.

Please use your work email address, not a personal one.

Progress tracking also requires accepting the current Terms of Service in Privacy settings.

VI