Feat/agent mode #1

Closed
tmm621 wants to merge 85 commits from feat/agent-mode into main
2 changed files with 80 additions and 9 deletions
Showing only changes of commit 7d5c82e0e2 - Show all commits
+1 -1
View File
@@ -23,7 +23,7 @@ L1_RULES: list[tuple[str, list[str], float]] = [
("编辑输出", ["WRITE AFTER", "WRITE BEFORE"], 0.80),
("文件编成", ["ORGANIZATION IS"], 0.99),
("替代索引", ["ALTERNATE RECORD KEY"], 0.99),
("マッチング", ["re:WS-[-\\w]*KEY"], 0.65),
("マッチング", ["re:WS-[\\w-]*KEY"], 0.65),
]
# ── 冲突解决规则 ─────────────────────────────────────────────────────────
+79 -8
View File
@@ -334,6 +334,73 @@ def _path_llm_assisted(
# ── 主入口 ────────────────────────────────────────────────────────────────────
# ── 匹配子类型解析 ──────────────────────────────────────────────────────────
_MATCHING_SUBTYPE_RULES = [
# (match_fn, subtype)
# 按优先级从高到低排列
]
def _resolve_matching_subtype(
result: dict,
cobol_source: str,
structure: dict,
) -> dict:
"""匹配程序的子类型区分后处理。
在 classify_program 判定为 マッチング 后,进一步区分子类型:
- 1:1 マッチング / 1:N / N:1 / M:N / M:N→M 等
Args:
result: classify_program 的返回结果。
cobol_source: 原始 COBOL 源码。
structure: extract_structure 的返回结构。
Returns:
更新后的 result,增加 "subtype" 字段。
"""
category = result.get("category", "")
if "マッチング" not in category and "キーブレイク" not in category:
return result # 非匹配程序不做子类型区分
src_upper = cobol_source.upper()
import re
# 0. 二段階マッチング — 已在规则引擎中处理
if "二段階" in category:
result["subtype"] = "二段階"
return result
# 1. M:N→MxN 直積 — 特征: WRITE + WS-SAVE-KEY + 3 文件
if structure.get("file_count", 0) >= 3 and 'WS-SAVE' in src_upper:
result["subtype"] = "M:N→MxN"
return result
# 2. 混合匹配 (WS-PREV-KEY 存在)
if 'WS-PREV-KEY' in src_upper:
result["subtype"] = "混合"
return result
# 3. 检查键变量命名模式
key_vars = set(re.findall(r'WS-[\w-]*KEY[A-Z0-9-]*', src_upper))
# 不对称键名 → 1:N 或 N:1 (WS-MAST-KEY + WS-TRAN-KEY)
has_master = any('MAST' in k for k in key_vars)
has_tran = any('TRAN' in k for k in key_vars)
if has_master and has_tran:
result["subtype"] = "1:N"
return result
# 4. 多个键名 → 多文件匹配 (M:N 模式)
if len(key_vars) >= 3 and structure.get("file_count", 0) >= 2:
result["subtype"] = "M:N"
return result
# 5. 对称键名 → 默认为 1:1
result["subtype"] = "1:1"
return result
def classify_program(cobol_source: str, llm: Any = None) -> dict:
"""完整程序类型判定管道。
@@ -419,20 +486,24 @@ def classify_program(cobol_source: str, llm: Any = None) -> dict:
# 路径 A: keyword >= 90% -> 直接输出
if max_keyword_confidence >= 0.90:
logger.info("[pipeline] 路径 A: keyword 高确信度 (%.2f)", max_keyword_confidence)
return _path_keyword_direct(keyword_info, structure)
result = _path_keyword_direct(keyword_info, structure)
# 路径 B: keyword 50-89% -> 规则引擎
if max_keyword_confidence >= 0.50:
elif max_keyword_confidence >= 0.50:
logger.info("[pipeline] 路径 B: keyword 中确信度 (%.2f) -> 规则引擎", max_keyword_confidence)
return _path_rule_engine(keyword_info, structure)
result = _path_rule_engine(keyword_info, structure)
# 路径 C: keyword < 50% -> LLM 辅助
if llm is not None:
elif llm is not None:
logger.info("[pipeline] 路径 C: keyword 低确信度 (%.2f) -> LLM 辅助", max_keyword_confidence)
return _path_llm_assisted(keyword_info, structure, llm)
result = _path_llm_assisted(keyword_info, structure, llm)
# LLM 不可用: 使用规则引擎兜底
logger.info("[pipeline] 路径 C(fallback): keyword 低确信度 (%.2f) -> 规则引擎兜底", max_keyword_confidence)
result = _path_rule_engine(keyword_info, structure)
result["method"] = "rule_engine_fallback"
else:
logger.info("[pipeline] 路径 C(fallback): keyword 低确信度 (%.2f) -> 规则引擎兜底", max_keyword_confidence)
result = _path_rule_engine(keyword_info, structure)
result["method"] = "rule_engine_fallback"
# ── 第 4 步: 匹配子类型区分(仅对匹配/键中断程序)──
result = _resolve_matching_subtype(result, cobol_source, structure)
return result