8.1 KiB
pbl_validation 模块技能(M2 校验引擎)
定位
PBL 蓝图校验引擎:14 维校验 + 5 级质量状态(quality_state),阈值全部配置化常量, 输出固定契约的校验报告,供 pbl_compiler(发布门禁)、pbl_assessment(量规联动)、 前端蓝图编辑器(问题定位)消费。
挂载
# app/pbls.py init()
from pbl_validation.init import load_pbl_validation
load_pbl_validation() # 建表 + 注册 5 个契约 + 内置 14 维规则种子(幂等)
库名唯一来源:ServerEnv().get_module_dbname('pbl_validation'),禁止硬编码 DBNAME。
数据表(2 张)
| 表 | 用途 | 关键字段 |
|---|---|---|
pbl_validation_rule |
校验规则(14 维,script_type=1 规则 JSON 形态) |
tenant_id / rule_id / dim / weight / severity / enabled / rule_json(含 thresholds) |
pbl_validation_result |
校验结果(14 维得分 + 5 级质量状态) | tenant_id / result_id / blueprint_id / quality_state / total_score / dim_scores / dim_detail / report_json / fingerprint |
DDL:sql/pbl_validation.sql(幂等,含 14 条内置规则种子)。
契约接口(5 个,/pbl_validation/api/<name>.dspy)
| 接口 | 说明 | 必填入参 |
|---|---|---|
pbl_validation_run |
执行 14 维校验并落库,返回报告契约 | blueprint(dict 或 JSON 串);tenant_id 缺省取上下文 |
pbl_validation_get |
按 result_id 或 blueprint_id(最新一次)取报告 |
二者之一 |
pbl_validation_list |
分页列出结果,可按 blueprint_id/quality_state/keyword 过滤 |
— |
pbl_validation_rule_list |
列出规则 + 14 维元信息 + 生效阈值/默认阈值 | — |
pbl_validation_rule_save |
新增/更新规则(阈值配置化落库,脏阈值直接拒绝) | dim(D01~D14) |
pbl_validation_run 可选入参:blueprint_id / version / dims(只跑指定维度)/
thresholds(阈值覆盖)/ persist(0=dry-run 不落库)/ operator。
14 维清单
| 维度 | code | 名称 | 权重 | 核心 |
|---|---|---|---|---|
| D01 | structure_completeness | 结构完整性(7 类子对象齐备) | 1.2 | ★ |
| D02 | naming_quality | 命名规范 | 0.8 | |
| D03 | objective_alignment | 学习目标对齐 | 1.2 | ★ |
| D04 | driving_question | 驱动问题质量 | 1.0 | |
| D05 | role_design | 角色设计 | 1.0 | |
| D06 | scene_design | 场景设计 | 0.9 | |
| D07 | entity_model | 实体模型 | 0.9 | |
| D08 | task_chain | 任务链完整性 + 多路径覆盖率 mcRatio | 1.3 | ★ |
| D09 | rule_integrity | 规则引用完整性 | 1.1 | |
| D10 | assessment_rubric | 评估量规(权重和=1) | 1.2 | ★ |
| D11 | evidence_binding | 产出物/证据绑定 | 1.0 | |
| D12 | difficulty_balance | 难度平衡 | 0.7 | |
| D13 | duration_balance | 时长平衡 | 0.7 | |
| D14 | safety_compliance | 安全合规扫描 | 1.0 | ★ |
★ = 核心维度,任一 fail 直接把质量状态压到 Q1。
阈值配置化常量(constants.DEFAULT_THRESHOLDS)
Q-OPEN-8:mcRatio = 0.7(多路径覆盖率阈值)。其余关键项:
qualityBasicScore=0.40 / qualityGoodScore=0.70 / qualityExcellentScore=0.90、
minSubObjectKinds=7、objectiveCoverageRatio=0.8、roleTaskCoverageRatio=0.8、
taskEvidenceCoverageRatio=0.8、ruleRefIntegrityRatio=1.0、rubricWeightSum=1.0
(容差 0.01)、maxSafetyHits=0。
覆盖优先级(低→高):默认常量 → 规则记录 rule_json.thresholds → 接口入参 thresholds
(引擎内 rule_json 由接口层用「规则库阈值 + 入参阈值」合成,故入参最终生效)。
非法覆盖(未知 key / 类型不符 / 负数 / 比例 >1)被忽略并记入 threshold_ignored;
rule_save 侧则直接拒绝(fail-closed,不落脏配置)。
5 级质量状态规则(engine.decide_quality_state,自上而下短路)
| 规则 | 条件 | 结果 |
|---|---|---|
| R1 | 无维度结果 / 全部 skip | Q0_DRAFT |
| R2 | 存在 blocker 级问题 | Q1_INCOMPLETE |
| R3 | 核心维度(D01/D03/D08/D10/D14)有 fail | Q1_INCOMPLETE |
| R4 | 加权总分 < 0.40 | Q1_INCOMPLETE |
| R5 | 总分 ≥ 0.90 且无 warn/fail | Q4_EXCELLENT |
| R6 | 总分 ≥ 0.70 且核心维度全 pass | Q3_GOOD |
| R7 | 总分 ≥ 0.40 | Q2_BASIC |
| R8 | 兜底 | Q1_INCOMPLETE |
总分 = Σ(维度得分×权重) / Σ权重(skip 维度不计入分母)。维度得分:pass=1.0、warn=0.6、 fail/skip=0,D08/D10 等按覆盖率/权重和连续取值。
发布门禁:is_publishable() 要求 quality_state ∈ {Q3_GOOD, Q4_EXCELLENT}。
校验报告契约 pbl.validation.report/1.0
{
"contract": "pbl.validation.report/1.0",
"engine_version": "1.0.0",
"report_id": "vr_xxxx", "tenant_id": "t1",
"blueprint_id": "BP1", "version": "v1", "ruleset": "builtin-14d",
"created_at": 1730000000000, "elapsed_ms": 3,
"fingerprint": "sha256前32位(载荷+阈值,幂等复用)",
"quality_state": "Q4_EXCELLENT", "quality_label": "优秀", "quality_order": 4,
"quality_reasons": ["R5: 加权总分 0.9700 >= Q4 线 0.90 且无 warn/fail"],
"total_score": 0.97, "weighted_sum": 13.58, "weight_sum": 14.0,
"dim_count": 14, "dim_total": 14,
"state_summary": {"pass": 14, "warn": 0, "fail": 0, "skip": 0},
"severity_summary": {"blocker": 0, "major": 0, "minor": 0, "info": 0},
"issue_count": 0, "passed": true,
"dimensions": [{"dim":"D08","name":"任务链完整性","state":"pass","score":1.0,
"weight":1.3,"weighted_score":1.3,
"metrics":{"mcRatio":1.0,"mcRatio_threshold":0.7,"path_count":2,
"branch_exits_total":2,"branch_exits_covered":2,
"dangling":[],"cyclic_paths":0},
"issues":[]}],
"issues": [{"dim":"D08","code":"V-TASK-004","severity":"major",
"message":"多路径覆盖率 mcRatio=0.50 低于阈值 0.70(Q-OPEN-8)",
"path":"tasks.mcRatio","expected":0.7,"actual":0.5}],
"thresholds": {"mcRatio": 0.7, "...": "..."},
"threshold_ignored": [], "engine_errors": [],
"dimensions_meta": [{"dim":"D01","code":"structure_completeness","name":"结构完整性",
"weight":1.2,"desc":"..."}]
}
问题码索引
V-TENANT-001 租户缺失 · V-INPUT-001~004 载荷非法 · V-DB-001/002 库名或 sqlor 不可用 ·
V-STRUCT-001/002 结构 · V-NAME-001~004 命名 · V-OBJ-001~003 目标 ·
V-DQ-001~004 驱动问题 · V-ROLE-001~003 角色 · V-SCENE-001~003 场景 ·
V-ENT-001~003 实体 · V-TASK-001~005 任务链(004=mcRatio,005=环) ·
V-RULE-001/002 规则引用 · V-RUB-001~004 量规(004=权重和≠1) ·
V-EV-001~003 产出物 · V-DIFF-001~004 难度 · V-DUR-001~003 时长 ·
V-SEC-001~005 安全(破坏性 SQL / 危险命令 / 硬编码凭据 / 动态执行 / 不适宜内容) ·
V-ENGINE-001~003 引擎(禁用 / 返回类型 / 维度异常兜底 fail)。
陷阱
- 库名一律
ServerEnv().get_module_dbname('pbl_validation'),禁止硬编码 DBNAME。 - sqlor 只有
C/U/D/R/I/sqlExe;查询走pbl_common.api的q_all/q_one(已适配), 本模块api.q_all/q_one做了「优先 pbl_common、回落 sqlor.sqlExe」双通道。 - 所有读写强制带
tenant_id(pbl_common.api.tenant_id()),缺失即 fail-closed 报错。 - 新增契约需同步四处:
api.py定义 +API_REGISTRY+__init__.py导出 +init.pyenv 注册 +scripts/load_path.py的API_PATHS。 - 引擎是纯函数(无 DB/网络/随机),同载荷同阈值必得同报告;落库只在 api 层做。
- 单维度 checker 抛异常不会中断整体:引擎兜底记
fail+V-ENGINE-003(fail-closed)。 - 蓝图载荷支持 4 种形态:
{objects:[{kind:...}]}/{kinds:{task:[...]}}/ 顶层复数键(tasks/roles/...) /{blueprint:{...}}包装。
自测
cd modules/pbl_validation && python3 tests/test_validation_engine.py # 111 项断言全绿
python3 scripts/load_path.py # 打印路径与契约清单