📦 deps(thirdparty): update snapshots

This commit is contained in:
ci[bot]
2026-07-10 16:04:20 +00:00
parent 2bb0dc8c1d
commit 92c0c3f687
594 changed files with 55224 additions and 19038 deletions
@@ -0,0 +1,221 @@
#!/usr/bin/env python3
"""Quality checks for Maoxuan Product Agent sample outputs.
Usage:
quality_gate.py output1.md output2.md ...
The script catches common regressions:
- source/theory leakage
- English-dominant answers in Chinese work scenes
- vague advice without concrete next actions
- excessive question dumping in the "需要确认" section
- missing judgment, risk, or decision signal
"""
from __future__ import annotations
import re
import sys
from pathlib import Path
HARD_BANNED = [
r"毛泽东",
r"毛选",
r"矛盾论",
r"实践论",
r"教员",
r"毛主席",
r"同志",
r"阶级",
r"革命",
r"斗争",
r"主席指出",
r"《[^》]+》认为",
]
SOFT_BANNED = [
r"辩证",
r"唯物",
r"经典",
r"原文",
]
VAGUE_PATTERNS = [
r"提升用户体验",
r"加强沟通",
r"多看数据",
r"深入了解用户",
r"持续优化",
r"形成闭环",
r"赋能",
r"抓手",
r"打透认知",
]
JUDGMENT_HINTS = [
"问题判断",
"核心是",
"关键是",
"不是",
"当前最",
"先不要",
]
ACTION_HINTS = [
"行动建议",
"下一步",
"今天",
"本周",
"24 小时",
"48 小时",
"2 天",
"一周",
"两周",
"负责人",
"指标",
"验证",
"实验",
"灰度",
"",
"",
"暂停",
"停止",
]
DECISION_HINTS = [
"成功指标",
"失败指标",
"主指标",
"影响指标",
"护栏",
"全量",
"停止",
"暂停",
"复盘",
"监控",
"达标",
"不达标",
"决策",
"上线",
"回滚",
"留存",
"转化",
"回复率",
"复访",
"D7",
"7 日",
"7日",
]
RISK_HINTS = [
"风险提醒",
"不要",
"先不要",
"暂时不要",
"不建议",
]
def count_questions(text: str) -> int:
"""Count questions in the "需要确认" section only."""
match = re.search(
r"(?:^|\n)(?:#{1,3}\s*)?(?:\*\*)?需要确认(?:\*\*)?[^\n]*\n"
r"(?P<section>.*?)(?=\n(?:#{1,3}\s+|\*\*[^*\n]+?\*\*)|\Z)",
text,
re.DOTALL,
)
if not match:
return 0
section = match.group("section")
questions = 0
for line in section.splitlines():
stripped = line.strip()
if not stripped:
continue
# Count sentence-ending question marks. This ignores URL query strings
# such as https://example.com?a=1 while still catching two questions
# written on the same line.
questions += len(
re.findall(r"|\?(?=[\s\u4e00-\u9fff]|$)", stripped)
)
return questions
def chinese_ratio(text: str) -> float:
zh = len(re.findall(r"[\u4e00-\u9fff]", text))
en = len(re.findall(r"[A-Za-z]", text))
if zh + en == 0:
return 0.0
return zh / (zh + en)
def check_file(path: Path) -> tuple[list[str], list[str]]:
text = path.read_text(encoding="utf-8")
errors: list[str] = []
warnings: list[str] = []
for pattern in HARD_BANNED:
if re.search(pattern, text, re.IGNORECASE):
errors.append(f"exposes hard-banned source/style term: {pattern}")
for pattern in SOFT_BANNED:
if re.search(pattern, text, re.IGNORECASE):
warnings.append(f"contains review-needed term: {pattern}")
vague_hits = [p for p in VAGUE_PATTERNS if re.search(p, text)]
if vague_hits:
errors.append(f"contains vague phrase(s): {', '.join(vague_hits)}")
if chinese_ratio(text) < 0.72:
errors.append("answer is not Chinese-dominant enough")
if not any(hint in text for hint in JUDGMENT_HINTS):
errors.append("missing problem judgment")
if not any(hint in text for hint in ACTION_HINTS):
errors.append("missing concrete action hints")
if not any(hint in text for hint in DECISION_HINTS):
errors.append("missing metric/decision/review signal")
if not any(hint in text for hint in RISK_HINTS):
errors.append("missing risk or stop-doing guidance")
if count_questions(text) > 3:
errors.append("asks too many questions")
stripped_len = len(text.strip())
if stripped_len < 120:
errors.append("output is likely too thin")
if stripped_len > 2200:
errors.append("output is likely too verbose")
return errors, warnings
def main(argv: list[str]) -> int:
if not argv:
print("Usage: quality_gate.py output1.md output2.md ...", file=sys.stderr)
return 2
failed = False
for item in argv:
path = Path(item)
errors, warnings = check_file(path)
if errors:
failed = True
print(f"FAIL {path}")
for err in errors:
print(f" - {err}")
else:
print(f"PASS {path}")
for warning in warnings:
print(f" WARN {warning}")
return 1 if failed else 0
if __name__ == "__main__":
raise SystemExit(main(sys.argv[1:]))