@yottameta/yotta-humanize 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,60 @@
1
+ # 24 类检测规则目录(patterns)
2
+
3
+ 元真的检测规则按「内容 / 语言 / 句式 / 沟通 / 废话」五组组织,每条规则含词表与句式正则。命中即产出 finding(规则号 / 名称 / 权重 / 上下文片段 / 建议)。
4
+
5
+ 权重含义:5 = 一眼 AI(强烈信号);4 = 明显 AI 腔;3 = 有 AI 痕迹;2 = 轻微(需结合上下文判断)。
6
+
7
+ ## 内容(content)
8
+
9
+ | 规则 | 名称 | 权重 | 命中示例 |
10
+ |---|---|---|---|
11
+ | HZ-01 | 空泛升华 | 5 | 标志着、彰显了、充分体现了、意义重大、里程碑、划时代、开启了新篇章 |
12
+ | HZ-02 | 套话开头 | 4 | 众所周知、毋庸置疑、在当今……背景下、随着……的发展 |
13
+ | HZ-03 | 套话结尾 | 4 | 综上所述、展望未来、未来可期、拭目以待、共创美好未来 |
14
+ | HZ-04 | 空话概括 | 3 | 从某种程度上说、在某种意义上、归根结底、说白了 |
15
+ | HZ-05 | 模糊归因 | 4 | 专家指出、研究表明、业内人士认为、据统计、相关数据显示 |
16
+ | HZ-06 | 绝对化断言 | 3 | 百分之百、任何情况下、绝不可能、必然导致、毫无疑问 |
17
+
18
+ ## 语言(language)
19
+
20
+ | 规则 | 名称 | 权重 | 命中示例 |
21
+ |---|---|---|---|
22
+ | HZ-07 | AI 黑话 | 5 | 赋能、抓手、闭环、颗粒度、链路、底层逻辑、顶层设计、方法论、沉淀、洞察、心智、范式、发力点、痛点、落地 |
23
+ | HZ-08 | 冗余强调 | 3 | 非常非常、十分十分、极其极其(叠用强调词) |
24
+ | HZ-09 | 同义堆叠 | 4 | 完善和优化、促进和推动、帮助和协助、提高和改善、加强和完善 |
25
+ | HZ-10 | 「我们」滥用 | 3 | 我们坚信、我们致力于、我们始终、我们深知 |
26
+ | HZ-11 | 名词化堆砌 | 3 | 问题的解决、能力的提升、水平的增强、建设的推进 |
27
+ | HZ-12 | 程度词堆积 | 2 | 更加深入地、更加有效地、更好地、进一步地 |
28
+
29
+ ## 句式(style)
30
+
31
+ | 规则 | 名称 | 权重 | 命中示例 |
32
+ |---|---|---|---|
33
+ | HZ-13 | 排比三连 | 4 | 不仅……而且……更……;既……又……还…… |
34
+ | HZ-14 | 机械列举 | 3 | 首先,/ 其次,/ 再次,/ 最后,/ 第一,/ 第二, |
35
+ | HZ-15 | 反问堆叠 | 2 | 难道不是吗、难道不、怎能、岂不、何尝不是 |
36
+ | HZ-16 | 破折号滥用 | 3 | 全文出现 3 处以上「——」 |
37
+ | HZ-17 | 引号滥用 | 2 | 给普通词加「“”」 |
38
+ | HZ-18 | 感叹号滥用 | 2 | 全文感叹号过多 |
39
+
40
+ ## 沟通(communication)
41
+
42
+ | 规则 | 名称 | 权重 | 命中示例 |
43
+ |---|---|---|---|
44
+ | HZ-19 | 聊天残渣 | 5 | 希望对你有所帮助、如果还有疑问、随时告诉我、让我们开始吧 |
45
+ | HZ-20 | 奉承讨好 | 4 | 很好的问题、你说得对、感谢你的提问、非常荣幸 |
46
+ | HZ-21 | 免责回避 | 3 | 由于篇幅有限、限于篇幅、这里不再赘述、在此不过多展开 |
47
+
48
+ ## 废话(filler)
49
+
50
+ | 规则 | 名称 | 权重 | 命中示例 |
51
+ |---|---|---|---|
52
+ | HZ-22 | 废话填充 | 2 | 其实,/ 就是说,/ 换句话说、换言之、也就是说 |
53
+ | HZ-23 | 无效转折 | 2 | 话说回来、换个角度、换个思路、再说一句 |
54
+ | HZ-24 | 重复声明 | 3 | 值得注意的是、不难发现、显而易见、值得一提的是、需要指出的是 |
55
+
56
+ ## 检测逻辑
57
+
58
+ - 每条规则 = 词表(原样匹配)+ 句式正则(re 编译),命中记录「匹配词 / 上下文片段」;
59
+ - 同一位置多条词命中会各自计入(如「标志着新时代的到来,意义重大」同时命中 HZ-01 的多个词);
60
+ - 统计突发性见 scoring.md,与规则命中共同合成 0-100 评分。
@@ -0,0 +1,48 @@
1
+ # 确定性改写规则(rewriting)
2
+
3
+ rewrite 子命令做「无歧义、改了必更好」的机械变换:词表替换、套话/残渣删除、标点限流。需要判断的改写(排比拆句、补来源、软化绝对化)只在 suggest 中给建议,不强行自动改。
4
+
5
+ ## 一、词表替换(黑话 → 大白话)
6
+
7
+ | 原词 | 替换 | 原词 | 替换 |
8
+ |---|---|---|---|
9
+ | 赋能 | 支持 | 抓手 | 切入点 |
10
+ | 闭环 | 流程 | 颗粒度 | 细致程度 |
11
+ | 链路 | 流程 | 底层逻辑 | 根本原因 |
12
+ | 顶层设计 | 整体规划 | 方法论 | 方法 |
13
+ | 沉淀 | 积累 | 洞察 | 发现 |
14
+ | 心智 | 观念 | 范式 | 模式 |
15
+ | 发力点 | 重点 | 痛点 | 难点 |
16
+ | 落地 | 落实 | 场景化 | 按情境 |
17
+ | 维度 | 角度 | 框架 | 结构 |
18
+
19
+ ## 二、套话删除
20
+
21
+ - 开头:众所周知,/ 在当今……背景下,/ 在当下,/ 近年来,/ 随着……的发展,等;
22
+ - 结尾:综上所述,/ 总之,/ 展望未来,/ 未来可期。等;
23
+ - 归因前缀:专家指出,/ 研究表明,/ 业内人士认为,/ 据统计,等(删前缀后保留原句内容;真实来源需人工补);
24
+ - 声明:值得注意的是,/ 不难发现,/ 显而易见,/ 值得一提的是,/ 需要指出的是,/ 必须强调的是,等。
25
+
26
+ ## 三、残渣 / 奉承 / 免责清理
27
+
28
+ - 聊天残渣:希望对你有所帮助。/ 希望这些内容对你有用。/ 如果你有任何问题,/ 如果还有疑问,/ 随时告诉我。/ 让我们开始吧。等;
29
+ - 奉承:很好的问题。/ 你说得对,/ 感谢你的提问。/ 非常荣幸 等;
30
+ - 免责:由于篇幅有限,/ 限于篇幅,/ 这里不再赘述。/ 在此不过多展开。等;
31
+ - 废话填充:换句话说,/ 换言之,/ 也就是说,/ 某种意义上,/ 其实,/ 就是说,等;
32
+ - 无效转折:话说回来,/ 换个角度,/ 换个思路,/ 再说一句,等。
33
+
34
+ ## 四、标点限流
35
+
36
+ - 破折号:全文超过 2 处「——」时,第 3 处起替换为逗号;
37
+ - 感叹号:全文超过 2 个「!」时,第 3 个起替换为句号;
38
+ - 空壳清理:合并连续逗号/句号,清理改写后残留的前导标点。
39
+
40
+ ## 五、改写输出
41
+
42
+ - 文本模式:改写前评分 → 改写后评分、修复清单(规则 / 次数 / 明细)、改写后全文;
43
+ - --json 模式:{ text, fixes[], before, after };
44
+ - 改写后再 analyze / score 一次,确认评分下降且原意未破坏。
45
+
46
+ ## 六、与 LLM 改写的关系
47
+
48
+ 元真 rewrite 是纯规则确定性改写,不调模型、可复现。若使用者希望做「判断级改写」(拆排比、补来源、调语气),可基于 suggest 输出的人工建议由 AI 智能体完成——那是使用方自己的模型调用,与元真引擎无关。
@@ -0,0 +1,50 @@
1
+ # 评分公式与统计量(scoring)
2
+
3
+ 元真的 AI 腔评分(0-100)由「规则分」与「统计分」合成,越高越像 AI 写的。
4
+
5
+ ## 规则分(pattern_score,0-100)
6
+
7
+ ```
8
+ 加权命中密度 = Σ(规则权重 × 该规则命中次数) / 字数 × 100
9
+ 密度分 = min(log2(密度 + 1) × 14, 60) # 密度越高分越高,对数压顶
10
+ 种类广度 = min(命中规则数 × 2, 20) # 命中的规则类型越多越可疑
11
+ 分组多样性 = min(命中分组数 × 4, 16) # 五组中命中越多组越可疑
12
+ 规则分 = min(密度分 + 种类广度 + 分组多样性, 100)
13
+ ```
14
+
15
+ ## 统计分(stats_score,0-100)
16
+
17
+ 中文统计量(字数 / 句数过少时不参与,避免小样本误判):
18
+
19
+ | 统计量 | 计算 | 说明 |
20
+ |---|---|---|
21
+ | 平均句长 | 每句 CJK 字数 + 数字/英文单词数 的均值 | 过长 > 30 字偏「书面腔」 |
22
+ | 句长波动 CV | 句长标准差 / 均值 | 低(< 0.25)= 句长均匀,AI 味 |
23
+ | 突发性 | 相邻句长差的均值 / 平均句长 | 低(< 0.3)= 节奏单调,AI 味 |
24
+ | 词汇多样性 | 连续双字(bigram)的 type-token ratio | 低(< 0.4)= 用词重复 |
25
+ | 逗号密度 | 每 100 字逗号数 | > 12 = 一逗到底 |
26
+
27
+ 统计分合成(仅当字数 ≥ 40 且句数 ≥ 3):
28
+
29
+ ```
30
+ 均匀度分量 u = clamp((0.5 - CV) / 0.35, 0, 1)
31
+ 突发性分量 b = clamp((0.6 - 突发性) / 0.5, 0, 1)
32
+ 多样性分量 t = clamp((0.6 - TTR) / 0.35, 0, 1)
33
+ 统计分 = round(100 × (0.4u + 0.35b + 0.25t))
34
+ ```
35
+
36
+ ## 综合评分(0-100)
37
+
38
+ ```
39
+ 若 规则分 = 0 且 统计分 = 0 → 0
40
+ 若 无规则命中 → min(round(统计分 × 0.12), 12) # 统计量单独不指控
41
+ 否则 → min(round(规则分 × 0.7 + 统计分 × 0.3), 100)
42
+ ```
43
+
44
+ 评分档位:≥ 70 明显 AI 腔;45-69 中度 AI 腔;20-44 轻度 AI 痕迹;< 20 基本像人写的。
45
+
46
+ ## 退出码(与元安 / 元审 / 元盾家族一致)
47
+
48
+ - 0 = 成功(评分低于阈值,或未启用 --gate);
49
+ - 1 = score --gate 且评分 ≥ --threshold(默认 45,可 --threshold 调整);
50
+ - 4 = 用法错误 / 致命异常。
@@ -0,0 +1,281 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """humanize_rules.py — YottaMeta 元真(yotta-humanize)中文 AI 腔检测规则表。
4
+
5
+ 24 类检测规则(按 内容/语言/句式/沟通/废话 五组),每类含词表 / 句式正则、
6
+ 权重(1-5)与改写建议。数据驱动:引擎按规则逐条扫描文本,命中即产出 finding。
7
+
8
+ 设计说明:
9
+ - 面向中文语料的 AI 腔特征(空泛升华、套话、黑话、排比、聊天残渣等),
10
+ 与英文 humanizer 类技能无共享代码,词表与句式均为中文自研整理。
11
+ - 每条规则字段:
12
+ id 规则编号(HZ-01 ~ HZ-24)
13
+ name 规则名(中文)
14
+ group 分组(content / language / style / communication / filler)
15
+ weight 权重 1-5(5 = 一眼 AI,1 = 轻微痕迹)
16
+ regexes 句式正则列表(re 对象或字符串)
17
+ words 词表(普通词,原样匹配)
18
+ suggestion 命中时的改写建议模板(可含 {word} 占位)
19
+ fix 机械改写映射:'pattern|replacement' 字符串列表或
20
+ callable(text) -> text(仅无歧义时可自动改)
21
+ """
22
+
23
+ # ── 基础工具 ────────────────────────────────────────────────────────────────
24
+
25
+ def esc(w):
26
+ """转义词表中的正则特殊字符。"""
27
+ import re
28
+ return re.escape(w)
29
+
30
+
31
+ # ── 规则表 ──────────────────────────────────────────────────────────────────
32
+
33
+ # 注意:改写映射只收「无歧义、改了必更好」的机械变换;需要判断的留 suggestion。
34
+ RULES = [
35
+ # ── 内容类(content)───────────────────────────────────────────────────
36
+ dict(
37
+ id="HZ-01", name="空泛升华", group="content", weight=5,
38
+ words=["标志着", "彰显了", "充分体现了", "意义重大", "里程碑",
39
+ "历史性", "划时代", "深远影响", "开启了新篇章",
40
+ "奠定了坚实基础", "具有重大意义", "起到了重要作用"],
41
+ regexes=[],
42
+ suggestion="把空泛升华换成具体事实:谁在何时做了什么、结果如何,而不是“标志着/彰显了”。",
43
+ fix=["充分体现了|体现了", "具有重大意义|很重要", "起到了重要作用|起了作用"],
44
+ ),
45
+ dict(
46
+ id="HZ-02", name="套话开头", group="content", weight=4,
47
+ words=["众所周知", "毋庸置疑", "毫无疑问", "在当今", "在当下",
48
+ "近年来", "随着时代", "随着社会"],
49
+ regexes=[r"随着[^,。;]{0,24}的(?:发展|进步|普及|到来|推进)[,,]", ],
50
+ suggestion="删掉模板化开头,直接从事实或结论进入正文。",
51
+ fix=["众所周知,|", "在当今[^,。]{0,12}背景下,|",
52
+ "在当下,|", "近年来,|"],
53
+ ),
54
+ dict(
55
+ id="HZ-03", name="套话结尾", group="content", weight=4,
56
+ words=["综上所述", "展望未来", "未来可期", "拭目以待",
57
+ "共创美好未来", "共同书写", "让我们一起", "值得期待"],
58
+ regexes=[],
59
+ suggestion="结尾落到具体结论或下一步动作,而不是“展望未来/未来可期”这类空话。",
60
+ fix=["综上所述,|", "总之,|", "展望未来,|", "未来可期。|。",
61
+ "让我们拭目以待|拭目以待"],
62
+ ),
63
+ dict(
64
+ id="HZ-04", name="空话概括", group="content", weight=3,
65
+ words=["从某种程度上说", "在某种意义上", "归根结底", "说白了",
66
+ "本质上来说", "实际上来说", "说白了就是", "换句话讲"],
67
+ regexes=[],
68
+ suggestion="删掉空话概括;如果这句没有新信息,直接删,不要“说白了”绕一圈。",
69
+ fix=["从某种程度上说,|", "在某种意义上,|", "归根结底,|",
70
+ "说白了,|", "本质上来说,|"],
71
+ ),
72
+ dict(
73
+ id="HZ-05", name="模糊归因", group="content", weight=4,
74
+ words=["专家指出", "专家认为", "研究表明", "业内人士认为",
75
+ "业内人士指出", "据统计", "有观点认为", "普遍认为",
76
+ "相关数据显示", "调查显示"],
77
+ regexes=[],
78
+ suggestion="要么给出真实来源(哪家机构/哪篇论文/哪份数据),要么直接删掉归因。",
79
+ fix=["专家指出,|", "专家认为,|", "研究表明,|", "业内人士认为,|",
80
+ "业内人士指出,|", "据统计,|", "有观点认为,|", "普遍认为,|",
81
+ "相关数据显示,|", "调查显示,|"],
82
+ ),
83
+ dict(
84
+ id="HZ-06", name="绝对化断言", group="content", weight=3,
85
+ words=["百分之百", "任何情况下", "绝不可能", "必然导致",
86
+ "一定会", "绝对会", "完全取决于"],
87
+ regexes=[r"毫无(?:疑问|争议)[,,。]?"],
88
+ suggestion="把“一定/必然/毫无疑问”改成“通常/往往会/大多数情况下”,给事实留余地。",
89
+ fix=["毫无疑问,|显然,", "毫无疑问|显然", "一定会|往往会",
90
+ "绝对会|往往会", "必然导致|往往导致", "百分之百|基本"],
91
+ ),
92
+ # ── 语言类(language)──────────────────────────────────────────────────
93
+ dict(
94
+ id="HZ-07", name="AI 黑话", group="language", weight=5,
95
+ words=["赋能", "抓手", "闭环", "颗粒度", "链路", "底层逻辑",
96
+ "顶层设计", "方法论", "沉淀", "洞察", "心智", "范式",
97
+ "发力点", "痛点", "落地", "场景化", "维度", "框架",
98
+ "抓手", "杠杆", "护城河", "第二曲线"],
99
+ regexes=[],
100
+ suggestion="把黑话换成大白话:赋能→支持、抓手→切入点、闭环→完整流程、链路→流程、底层逻辑→根本原因。",
101
+ fix=["赋能|支持", "抓手|切入点", "闭环|流程", "颗粒度|细致程度",
102
+ "链路|流程", "底层逻辑|根本原因", "顶层设计|整体规划",
103
+ "方法论|方法", "沉淀|积累", "洞察|发现", "心智|观念",
104
+ "范式|模式", "发力点|重点", "痛点|难点", "落地|落实",
105
+ "场景化|按情境", "维度|角度", "框架|结构"],
106
+ ),
107
+ dict(
108
+ id="HZ-08", name="冗余强调", group="language", weight=3,
109
+ words=["非常非常", "十分十分", "极其极其", "特别特别", "真的真的"],
110
+ regexes=[r"(非常|十分|极其|特别|相当|无比|异常|格外)(非常|十分|极其|特别|相当|无比|异常|格外)"],
111
+ suggestion="删掉叠用的强调词,一句里留一个就好;太多“非常”会让语气失真。",
112
+ fix=["非常非常|非常", "十分十分|十分", "极其极其|极其",
113
+ "特别特别|特别", "真的真的|真的"],
114
+ ),
115
+ dict(
116
+ id="HZ-09", name="同义堆叠", group="language", weight=4,
117
+ words=["完善和优化", "促进和推动", "帮助和协助", "提高和改善",
118
+ "加强和完善", "规划和部署", "支持和帮助", "鼓励和支持",
119
+ "推动和促进", "改进和完善"],
120
+ regexes=[],
121
+ suggestion="同义堆叠留一个动词即可(完善和优化→完善),两个词说的是一件事。",
122
+ fix=["完善和优化|完善", "促进和推动|推动", "帮助和协助|帮助",
123
+ "提高和改善|改进", "加强和完善|完善", "规划和部署|规划",
124
+ "支持和帮助|帮助", "鼓励和支持|支持", "推动和促进|推动",
125
+ "改进和完善|完善"],
126
+ ),
127
+ dict(
128
+ id="HZ-10", name="「我们」滥用", group="language", weight=3,
129
+ words=["我们坚信", "我们致力于", "我们始终", "我们深知",
130
+ "我们相信", "我们应该", "我们需要做的", "我们每个人都"],
131
+ regexes=[],
132
+ suggestion="“我们坚信/致力于”是宣传腔;改成具体做法或删掉主语直接说事。",
133
+ fix=["我们坚信|我们认为", "我们致力于|我们在做", "我们深知|我们知道"],
134
+ ),
135
+ dict(
136
+ id="HZ-11", name="名词化堆砌", group="language", weight=3,
137
+ words=["问题的解决", "能力的提升", "水平的增强", "意识的加强",
138
+ "建设的推进", "工作的开展", "质量的提高", "效率的提升"],
139
+ regexes=[],
140
+ suggestion="把“XX 的解决/提升/加强”改回动词句:直接说“解决了问题、提升了能力”。",
141
+ fix=["问题的解决|解决问题", "能力的提升|提升能力", "水平的增强|增强水平",
142
+ "意识的加强|加强意识", "建设的推进|推进建设", "工作的开展|开展工作",
143
+ "质量的提高|提高质量", "效率的提升|提升效率"],
144
+ ),
145
+ dict(
146
+ id="HZ-12", name="程度词堆积", group="language", weight=2,
147
+ words=["更加深入地", "更加有效地", "更好地", "进一步地",
148
+ "更为重要", "更为关键", "更为突出"],
149
+ regexes=[],
150
+ suggestion="程度词一多句子就发飘;删到零或留一个,用具体例子代替“更加”。",
151
+ fix=["更加深入地|深入地", "更加有效地|有效地", "进一步地|进一步",
152
+ "更为重要|更重要"],
153
+ ),
154
+ # ── 句式类(style)─────────────────────────────────────────────────────
155
+ dict(
156
+ id="HZ-13", name="排比三连", group="style", weight=4,
157
+ words=["不仅", "而且", "更让", "既能够", "又能够"],
158
+ regexes=[r"不仅[^,。]{2,20},?而且[^,。]{2,20},?更[^,。]{2,20}",
159
+ r"既[^,。]{2,16},又[^,。]{2,16},还[^,。]{2,16}"],
160
+ suggestion="排比三连是典型 AI 句式;拆成两三句,或只留最有信息量的一项。",
161
+ fix=[],
162
+ ),
163
+ dict(
164
+ id="HZ-14", name="机械列举", group="style", weight=3,
165
+ words=["首先", "其次", "再次"],
166
+ regexes=[r"(首先|其次|再次|最后)[,,]",
167
+ r"(第一|第二|第三|第四)[,,、]"],
168
+ suggestion="“首先/其次/再次/最后”一长串很机械;按内容自然过渡,别每段都编号。",
169
+ fix=[],
170
+ ),
171
+ dict(
172
+ id="HZ-15", name="反问堆叠", group="style", weight=2,
173
+ words=["难道不是吗", "难道不", "怎能", "岂不", "何尝不是"],
174
+ regexes=[],
175
+ suggestion="连续反问像在喊口号;留一个反问或改成陈述句更有力。",
176
+ fix=[],
177
+ ),
178
+ dict(
179
+ id="HZ-16", name="破折号滥用", group="style", weight=3,
180
+ words=[], regexes=[r"——"],
181
+ suggestion="破折号全文超过 3 处就显刻意;多余的换成逗号或直接断开句子。",
182
+ fix=[],
183
+ ),
184
+ dict(
185
+ id="HZ-17", name="引号滥用", group="style", weight=2,
186
+ words=[], regexes=[r"[“”]"],
187
+ suggestion="给普通词加引号很 AI(“赋能”“闭环”);去掉引号,或只给真正需要强调的词加。",
188
+ fix=[],
189
+ ),
190
+ dict(
191
+ id="HZ-18", name="感叹号滥用", group="style", weight=2,
192
+ words=[], regexes=[r"!"],
193
+ suggestion="感叹号满屏是营销腔;全文最多留一两个。",
194
+ fix=[],
195
+ ),
196
+ # ── 沟通类(communication)─────────────────────────────────────────────
197
+ dict(
198
+ id="HZ-19", name="聊天残渣", group="communication", weight=5,
199
+ words=["希望对你有所帮助", "希望这些内容对你有用", "如果你有任何问题",
200
+ "如果还有疑问", "随时告诉我", "让我们开始吧", "让我们开始",
201
+ "希望以上内容", "希望这个回答", "欢迎随时提问"],
202
+ regexes=[],
203
+ suggestion="删掉“希望对你有所帮助/随时告诉我”这类聊天机器人残渣,正文结尾干净利落。",
204
+ fix=["希望对你有所帮助。|", "希望这些内容对你有用。|", "如果你有任何问题,|",
205
+ "如果还有疑问,|", "随时告诉我。|", "让我们开始吧。|",
206
+ "让我们开始。|", "希望以上内容对你有用。|", "欢迎随时提问。|"],
207
+ ),
208
+ dict(
209
+ id="HZ-20", name="奉承讨好", group="communication", weight=4,
210
+ words=["很好的问题", "非常好的问题", "你说得对", "你说得很有道理",
211
+ "感谢你的提问", "非常荣幸", "您说得太对了", "好问题"],
212
+ regexes=[],
213
+ suggestion="删掉“很好的问题/你说得对”这类奉承开头,直接回答问题。",
214
+ fix=["很好的问题。|", "非常好的问题。|", "你说得对,|", "你说得很有道理,|",
215
+ "感谢你的提问。|", "非常荣幸|很荣幸", "您说得太对了。|"],
216
+ ),
217
+ dict(
218
+ id="HZ-21", name="免责回避", group="communication", weight=3,
219
+ words=["由于篇幅有限", "限于篇幅", "考虑到时间关系", "这里不再赘述",
220
+ "在此不过多展开", "不在此赘述", "受篇幅所限", "因时间有限"],
221
+ regexes=[],
222
+ suggestion="“限于篇幅/不再赘述”是 AI 缩水的遮羞布;要么给关键信息,要么别提。",
223
+ fix=["由于篇幅有限,|", "限于篇幅,|", "考虑到时间关系,|",
224
+ "这里不再赘述。|", "在此不过多展开。|", "不在此赘述。|",
225
+ "受篇幅所限,|", "因时间有限,|"],
226
+ ),
227
+ # ── 废话类(filler)────────────────────────────────────────────────────
228
+ dict(
229
+ id="HZ-22", name="废话填充", group="filler", weight=2,
230
+ words=["换句话说", "换言之", "也就是说", "某种意义上", "某种程度上"],
231
+ regexes=[r"(其实|就是说)[,,]"],
232
+ suggestion="“其实/就是说/换句话说”经常是废话;删掉后句子意思不变就删。",
233
+ fix=["换句话说,|", "换言之,|", "也就是说,|", "某种意义上,|",
234
+ "某种程度上,|", "其实,|", "就是说,|"],
235
+ ),
236
+ dict(
237
+ id="HZ-23", name="无效转折", group="filler", weight=2,
238
+ words=["话说回来", "换个角度", "换个思路", "再说一句", "另外一点"],
239
+ regexes=[],
240
+ suggestion="“话说回来/换个角度”是凑字数的转折;直接写下一段内容。",
241
+ fix=["话说回来,|", "换个角度,|", "换个思路,|", "再说一句,|"],
242
+ ),
243
+ dict(
244
+ id="HZ-24", name="重复声明", group="filler", weight=3,
245
+ words=["值得注意的是", "不难发现", "显而易见", "值得一提的是",
246
+ "需要指出的是", "必须强调的是", "需要强调的是", "特别值得注意的是"],
247
+ regexes=[],
248
+ suggestion="“值得注意的是/不难发现”是 AI 的提示词残留;删掉,让事实自己说话。",
249
+ fix=["值得注意的是,|", "不难发现,|", "显而易见,|", "值得一提的是,|",
250
+ "需要指出的是,|", "必须强调的是,|", "需要强调的是,|",
251
+ "特别值得注意的是,|"],
252
+ ),
253
+ ]
254
+
255
+ # 索引:按 id / 按 group
256
+ RULES_BY_ID = {r["id"]: r for r in RULES}
257
+ GROUPS = ("content", "language", "style", "communication", "filler")
258
+ GROUP_LABELS = {
259
+ "content": "内容(空泛/套话/归因)",
260
+ "language": "语言(黑话/堆叠/强调)",
261
+ "style": "句式(排比/列举/标点)",
262
+ "communication": "沟通(残渣/奉承/回避)",
263
+ "filler": "废话(填充/转折/声明)",
264
+ }
265
+
266
+ # ── 词表编译 ────────────────────────────────────────────────────────────────
267
+
268
+ def compile_rule(rule):
269
+ """把规则里的 regexes / words 编译成可执行的正则列表。"""
270
+ import re
271
+ pats = []
272
+ for rx in rule.get("regexes", []):
273
+ pats.append(re.compile(rx))
274
+ for w in rule.get("words", []):
275
+ pats.append(re.compile(esc(w)))
276
+ return pats
277
+
278
+
279
+ def compiled():
280
+ """返回 {rule_id: [compiled patterns]}。"""
281
+ return {r["id"]: compile_rule(r) for r in RULES}