test(aihr): enforce pilot completion gate
This commit is contained in:
+7
-2
@@ -536,6 +536,8 @@ public class AihrPracticeSeedService {
|
||||
ensureCalibrationTable();
|
||||
int trainingCount = count("SELECT COUNT(*) FROM aihr_practice_session WHERE tenant_id = ? AND mode = 'mobile'", TENANT_ID);
|
||||
int pendingAssignments = count("SELECT COUNT(*) FROM aihr_practice_assignment WHERE tenant_id = ? AND status = '待训练'", TENANT_ID);
|
||||
int assignmentTotal = trainingCount + pendingAssignments;
|
||||
boolean completionReady = assignmentTotal > 0 && trainingCount * 100 >= assignmentTotal * 80;
|
||||
int reviewed = count("SELECT COUNT(*) FROM aihr_practice_session WHERE tenant_id = ? AND mode = 'mobile' AND status = '已复盘'", TENANT_ID);
|
||||
CalibrationStats calibrationStats = calibrationStats();
|
||||
AihrSopSeedService.SopReviewStats sopStats = sopSeedService.sopReviewStats();
|
||||
@@ -552,7 +554,9 @@ public class AihrPracticeSeedService {
|
||||
StringBuilder csv = new StringBuilder();
|
||||
appendCsvRow(csv, "metric", "value");
|
||||
appendCsvRow(csv, "training_count", trainingCount);
|
||||
appendCsvRow(csv, "completion_rate", percent(trainingCount, trainingCount + pendingAssignments));
|
||||
appendCsvRow(csv, "completion_rate", percent(trainingCount, assignmentTotal));
|
||||
appendCsvRow(csv, "completion_rate_target", "80.0%");
|
||||
appendCsvRow(csv, "completion_rate_ready", completionReady);
|
||||
appendCsvRow(csv, "average_score", String.format(java.util.Locale.ROOT, "%.1f", averageScore == null ? 0 : averageScore));
|
||||
appendCsvRow(csv, "alert_count", alertCount);
|
||||
appendCsvRow(csv, "review_rate", percent(reviewed, trainingCount));
|
||||
@@ -566,7 +570,8 @@ public class AihrPracticeSeedService {
|
||||
appendCsvRow(csv, "sop_answer_usable_rate", percent(sopStats.usable(), sopStats.total()));
|
||||
appendCsvRow(csv, "sop_answer_usable_target", "80.0%");
|
||||
appendCsvRow(csv, "sop_answer_usable_ready", sopStats.total() > 0 && sopStats.usable() * 100 >= sopStats.total() * 80);
|
||||
appendCsvRow(csv, "pilot_metric_ready", calibrationStats.total() >= 20
|
||||
appendCsvRow(csv, "pilot_metric_ready", completionReady
|
||||
&& calibrationStats.total() >= 20
|
||||
&& calibrationStats.matched() * 100 >= calibrationStats.total() * 70
|
||||
&& sopStats.total() > 0
|
||||
&& sopStats.usable() * 100 >= sopStats.total() * 80);
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
| 4 | 管理端 `/train/practice` | 选择训练记录 → 人工校准评分 → 导出试点 CSV | 导出包含训练次数、完训率、平均分、预警数、主管复盘率、AI/人工分档一致率、SOP 可用率 |
|
||||
| 5 | 模型成本闸门 | 设置 `AIHR_AI_RUNTIME_ENABLED=false` 后重启后端 → 调 `/api/aihr/model/chat` | 返回 `cost-guard-fallback`,chat/asr/tts 走现有文本兜底,不影响训练闭环 |
|
||||
|
||||
试点正式验收前,用 `AIHR_PILOT_STRICT=true ./scripts/demo-check.sh` 检查 M5 样本闸门;样本不足时应失败,不用静态演示 marker 代替真实试点数据。
|
||||
试点正式验收前,用 `AIHR_PILOT_STRICT=true ./scripts/demo-check.sh` 检查 M5 样本闸门;完训率、校准样本、AI/人工分档一致率和 SOP 可用率未达标时应失败,不用静态演示 marker 代替真实试点数据。
|
||||
|
||||
## 录屏兜底
|
||||
|
||||
|
||||
@@ -57,8 +57,11 @@ check_pilot_samples() {
|
||||
return
|
||||
fi
|
||||
|
||||
local scenario_count calibration_stats calibration_count calibration_matched sop_total sop_usable sop_pending
|
||||
local scenario_count training_count pending_assignments assignment_total calibration_stats calibration_count calibration_matched sop_total sop_usable sop_pending
|
||||
scenario_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM aihr_practice_scenario WHERE tenant_id = '000000' AND position = '生活顾问' AND enabled = 1")"
|
||||
training_count="$(pilot_sql_scalar "SELECT COUNT(*) FROM aihr_practice_session WHERE tenant_id = '000000' AND mode = 'mobile'")"
|
||||
pending_assignments="$(pilot_sql_scalar "SELECT COUNT(*) FROM aihr_practice_assignment WHERE tenant_id = '000000' AND status = '待训练'")"
|
||||
assignment_total=$(( training_count + pending_assignments ))
|
||||
calibration_stats="$(pilot_sql_scalar "
|
||||
SELECT COUNT(*) AS total,
|
||||
COALESCE(SUM(CASE
|
||||
@@ -77,10 +80,12 @@ check_pilot_samples() {
|
||||
sop_total="$(pilot_sql_scalar "SELECT COUNT(*) FROM aihr_sop_answer_review WHERE tenant_id = '000000' AND status = '已评审'")"
|
||||
sop_usable="$(pilot_sql_scalar "SELECT COALESCE(SUM(CASE WHEN usable = 1 THEN 1 ELSE 0 END), 0) FROM aihr_sop_answer_review WHERE tenant_id = '000000' AND status = '已评审'")"
|
||||
sop_pending="$(pilot_sql_scalar "SELECT COUNT(*) FROM aihr_sop_answer_review WHERE tenant_id = '000000' AND status <> '已评审'")"
|
||||
echo "OK: pilot gates scenarios=${scenario_count}/12 calibration=${calibration_count}/20 consistency=${calibration_matched}/${calibration_count} sop_usable=${sop_usable}/${sop_total} sop_pending=${sop_pending}"
|
||||
echo "OK: pilot gates scenarios=${scenario_count}/12 completion=${training_count}/${assignment_total} calibration=${calibration_count}/20 consistency=${calibration_matched}/${calibration_count} sop_usable=${sop_usable}/${sop_total} sop_pending=${sop_pending}"
|
||||
|
||||
[[ "${AIHR_PILOT_STRICT:-false}" != "true" ]] || {
|
||||
(( scenario_count >= 12 )) || fail "pilot enabled scenarios ${scenario_count}/12"
|
||||
(( assignment_total > 0 )) || fail "pilot completion samples missing"
|
||||
(( training_count * 100 >= assignment_total * 80 )) || fail "pilot completion rate below 80% (${training_count}/${assignment_total})"
|
||||
(( calibration_count >= 20 )) || fail "pilot calibration samples ${calibration_count}/20"
|
||||
(( calibration_matched * 100 >= calibration_count * 70 )) || fail "pilot AI/human band consistency below 70%"
|
||||
(( sop_total > 0 )) || fail "pilot SOP review samples missing"
|
||||
|
||||
Reference in New Issue
Block a user