Files
AgentLab/backend/app/engine/validation.py
ThearchyHelios 9d8b41430e 完善口径管理、主动调查与后台任务,修复通用问题
- 完善口径编辑、只读试运行、统一质量验证与执行语义指纹
- 增加可执行指标约束、有预算的主动调查和过程评测
- 提取发布检查、证据读取与起草服务,支持任务停止、重试和检查点恢复
- 增加版本传递影响分析,修复并发覆盖、敏感值遮罩、异常评分及页面状态问题
- 修复 SQLite 复合查询追溯和 microVM 可选依赖缺失处理
- 纳入当前设计文档及部署配置调整

验证:相关主回归 3822 项通过,4 项跳过、8 项预期失败;补充回归通过。
前端构建、文案检查及 git diff --check 通过。
全量检查仍有环境权限、PostgreSQL 可选依赖和既有部署配置、SQLite 文件基线差异导致的未通过项。
2026-11-06 17:14:45 +08:00

66 lines
3.6 KiB
Python

"""执行状态与质量结论分开;试运行、正式出具和评测共用质量判定。"""
from __future__ import annotations
from typing import Any
def metric_quality(metric: dict[str, Any]) -> dict[str, Any]:
import math
checks: list[dict[str, str]] = []
def add(code: str, status: str, detail: str) -> None:
checks.append({"code": code, "status": status, "detail": detail})
if metric.get("status") != "ok" or metric.get("value") is None:
add("value", "fail", "指标没有可用值")
value = metric.get("value")
if isinstance(value, (int, float)) and not math.isfinite(value):
add("value", "fail", "指标值不是有限数值")
for key, reason in (("incomplete", "查询结果不完整"), ("no_data", "查询区间没有数据"),
("sql_check_failed", "来源 SQL 未通过检查")):
if metric.get(key):
detail_key = "sql_check_reason" if key == "sql_check_failed" else f"{key}_reason"
add(key, "fail", str(metric.get(detail_key) or reason))
if metric.get("recompute_ok") is False:
add("recompute", "fail", "指标复算不一致")
external = metric.get("external")
if isinstance(external, dict) and external.get("stale"):
add("external_stale", "fail", "外部常量已过期")
comparable = metric.get("comparability")
if isinstance(comparable, dict) and comparable.get("verdict") != "comparable":
add("comparability", "fail" if comparable.get("verdict") == "incomparable" else "unknown",
str(comparable.get("phrase") or "两期可比性尚未验证"))
if metric.get("comparability_skipped"):
add("comparability", "unknown", "两期可比性检查未完成")
for finding in metric.get("contract_findings") or []:
add("metric_contract", "fail", str(finding))
if metric.get("semantic_unverified"):
add("semantic_definition", "unknown", "业务描述与取数条件的一致性仍需审阅")
status = "fail" if any(c["status"] == "fail" for c in checks) else "unknown" if checks else "pass"
return {"status": status, "checks": checks}
def validation_report(metrics: list[dict[str, Any]], *, execution: str, trusted: bool) -> dict[str, Any]:
checks: list[dict[str, Any]] = []
if execution != "succeeded":
checks.append({"code": "execution", "status": "fail" if execution == "failed" else "unknown",
"detail": "执行未成功完成"})
if not trusted:
checks.append({"code": "evidence", "status": "unknown", "detail": "运行证据尚未封存或完整性核对未通过"})
if not metrics:
checks.append({"code": "metrics", "status": "unknown", "detail": "没有可验证的指标结果"})
for metric in metrics:
quality = metric.get("quality") or metric_quality(metric)
checks.extend({**c, "metric_id": metric.get("id"), "name": metric.get("name")} for c in quality["checks"])
status = "fail" if any(c["status"] == "fail" for c in checks) else "unknown" if checks else "pass"
return {"schema_version": 1, "execution": execution, "status": status, "checks": checks}
def additional_metric_gaps(metrics: list[dict[str, Any]]) -> list[str]:
"""既有出具检查之外的语义与可比性缺口。"""
codes = {"metric_contract", "semantic_definition", "comparability", "recompute"}
return [f"指标「{m.get('name') or m.get('id')}」:{c['detail']}" for m in metrics
for c in metric_quality(m)["checks"] if c["code"] in codes
and not (c["code"] == "comparability" and isinstance(m.get("comparability"), dict))]