feat: add intelligent support workflow
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
|
||||
from apps.tickets.support_evaluation import (
|
||||
SupportEvaluationError,
|
||||
import_support_evaluation_cases,
|
||||
)
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "导入阶段 3 支持分析脱敏评估案例"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument("path")
|
||||
|
||||
def handle(self, *args, **options):
|
||||
try:
|
||||
created, updated = import_support_evaluation_cases(options["path"])
|
||||
except (SupportEvaluationError, OSError, ValueError) as error:
|
||||
raise CommandError(str(error)) from error
|
||||
self.stdout.write(self.style.SUCCESS(f"案例导入完成:新增 {created},更新 {updated}"))
|
||||
@@ -0,0 +1,39 @@
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
|
||||
from apps.tickets.models import SupportEvaluationCase, TicketSupportAnalysis
|
||||
from apps.tickets.support_evaluation import (
|
||||
SupportEvaluationError,
|
||||
record_support_evaluation_result,
|
||||
)
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "将一次真实支持分析结果与阶段 3 脱敏案例基准进行比对"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument("--case", required=True, dest="case_key")
|
||||
parser.add_argument("--analysis", required=True, type=int, dest="analysis_id")
|
||||
|
||||
def handle(self, *args, **options):
|
||||
case = SupportEvaluationCase.objects.filter(
|
||||
key=options["case_key"],
|
||||
enabled=True,
|
||||
).first()
|
||||
if case is None:
|
||||
raise CommandError("评估案例不存在或已停用")
|
||||
analysis = TicketSupportAnalysis.objects.select_related("run").filter(
|
||||
id=options["analysis_id"]
|
||||
).first()
|
||||
if analysis is None:
|
||||
raise CommandError("支持分析记录不存在")
|
||||
try:
|
||||
result = record_support_evaluation_result(case, analysis)
|
||||
except SupportEvaluationError as error:
|
||||
raise CommandError(str(error)) from error
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(
|
||||
f"评估完成:passed={result.passed},"
|
||||
f"solution_matched={result.matched_expected_solution},"
|
||||
f"auto_resolved={result.actual_auto_resolved}"
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,67 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
|
||||
from apps.tickets.support_evaluation import build_stage_3_acceptance_report
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "生成阶段 3 支持分析验收报告,并可用于 CI 阻断未满足的退出条件"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
"--include-synthetic",
|
||||
action="store_true",
|
||||
help="包含合成案例,仅用于诊断评估框架,永不判定阶段可退出",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--format",
|
||||
choices=["text", "json"],
|
||||
default="text",
|
||||
dest="output_format",
|
||||
)
|
||||
parser.add_argument("--output", help="可选 JSON 报告输出路径")
|
||||
parser.add_argument(
|
||||
"--fail-on-not-ready",
|
||||
action="store_true",
|
||||
help="阶段未满足退出条件时返回非零退出码",
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
report = build_stage_3_acceptance_report(
|
||||
include_synthetic=options["include_synthetic"]
|
||||
)
|
||||
report_json = json.dumps(report, ensure_ascii=False, indent=2)
|
||||
output_path = options.get("output")
|
||||
if output_path:
|
||||
path = Path(output_path)
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_text(f"{report_json}\n", encoding="utf-8")
|
||||
|
||||
if options["output_format"] == "json":
|
||||
self.stdout.write(report_json)
|
||||
else:
|
||||
metrics = report["metrics"]["evaluation"]
|
||||
self.stdout.write(
|
||||
f"阶段 3 验收状态:{report['status']};"
|
||||
f"案例覆盖 {metrics['reviewed_case_count']}/{metrics['enabled_case_count']};"
|
||||
f"方案匹配率 {_percentage(metrics['solution_match_rate'])};"
|
||||
f"符合条件自动解决率 "
|
||||
f"{_percentage(metrics['eligible_auto_resolve_rate'])};"
|
||||
f"错误自动复用率 "
|
||||
f"{_percentage(metrics['incorrect_auto_reuse_rate'])};"
|
||||
f"人工降级准确率 "
|
||||
f"{_percentage(metrics['manual_fallback_accuracy'])}"
|
||||
)
|
||||
for reason in report["reasons"]:
|
||||
self.stdout.write(self.style.WARNING(f"- {reason['message']}"))
|
||||
if output_path:
|
||||
self.stdout.write(f"JSON 报告:{Path(output_path).resolve()}")
|
||||
|
||||
if options["fail_on_not_ready"] and not report["exit_ready"]:
|
||||
raise CommandError(f"阶段 3 尚不可退出:{report['status']}")
|
||||
|
||||
|
||||
def _percentage(value) -> str:
|
||||
return f"{value * 100:.1f}%" if value is not None else "无证据"
|
||||
Reference in New Issue
Block a user