feat(v2): 实现SQLite对公租赁经验加工与卡片预审轨迹闭环

This commit is contained in:
2026-10-01 13:38:03 +08:00
parent 9c351b08d3
commit fa4163b2d0
60 changed files with 2111 additions and 59 deletions
+38
View File
@@ -23,10 +23,48 @@ def ratio(numerator, denominator):
return str((n / d).quantize(Decimal("0.0001"), rounding=ROUND_HALF_UP))
def applicability_checks(skill, values, sources):
"""One predicate implementation for deterministic and model Skills (BR-66)."""
fields = []
def matches(condition):
field = condition['field']; fields.append(field)
value = values.get(field)
if value is None:
return None
expected = condition.get('threshold', condition.get('value'))
op = condition['operator']
if op == 'eq' and isinstance(expected, bool):
return value == expected
try:
a, b = number(value), number(expected)
return {'eq': a == b, 'lt': a < b, 'lte': a <= b, 'gt': a > b, 'gte': a >= b}[op]
except (ValueError, KeyError):
return None
conditions = [matches(c) for c in skill.get('conditions', [])]
exceptions = [matches(c) for c in skill.get('exceptions', [])]
exception_field = skill.get('exception_field')
if exception_field:
fields.append(exception_field)
exceptions.append(values.get(exception_field) not in (None, '', False))
result = ('not_applicable' if False in conditions or True in exceptions else
'unknown' if None in conditions or None in exceptions else None)
if result is None:
return None
return [{'code': skill.get('code', skill['id'] + '.applicability'),
'title': skill.get('title', skill['name']) + '适用性', 'result': result,
'fields': fields, 'evidence_ids': [r['id'] for f in fields for r in sources.get(f, [])],
'basis_ids': [skill['id'] + '@' + skill['version']], 'severity': 'attention',
'suggested_action': '补充适用条件依据' if result == 'unknown' else '本次不适用,保留判定依据'}]
def execute_skill(skill, values, sources):
engine = skill.get("engine")
if engine not in EXECUTORS or engine == "model":
raise ValueError("不支持的确定性执行器")
gate = applicability_checks(skill, values, sources)
if gate is not None:
return {}, gate
checks, outputs = [], {}
fields = skill.get("inputs", [])
def check(code, title, result, refs, action="请核实材料与口径"):