资讯动态

拆解“AI味”:从“不是……而是……”到文本检测与改写

发布时间:2026/10/25 2:15:15 来源:尧图企业网站定制
判断一段文字有没有 AI 味很多人第一反应是去找“不是……而是……”这个句式。只要看到它就给作者扣一顶帽子。这个判断方式太粗糙了。这个句式在中文里存在的时间比大模型长得多论文、技术文档、产品评审、甚至菜谱里都有它在干活。它本身只是一个“先排除、再立论”的结构谈不上好坏。真正的问题是很多人把这个句式当成了替代思考的填充物。否定掉一个没人主张的观点再给出一个人人都知道的结论句子结构完整、逻辑看起来闭合但读完什么也没得到。删掉这一整句文章的损失为零。这才是 AI 味的来源——信息密度为零而不是语法本身。这篇文章想做的事情很具体把“AI 味”这个模糊的感受拆成可操作的判断标准说清楚“不是……而是……”在什么条件下是有效的论证工具、在什么条件下是废话生产线然后给出一套可以照着改的流程以及一个能跑起来的文本检测脚本。如果你平时要写技术博客、项目文档、方案评审、周报或者要调教模型输出的文风这篇文章里的判断标准和改写方法都可以直接用。1. 先把问题说清楚AI 味到底是不是句式背的锅先说结论不是。但也不能说完全没关系。“AI 味”这个词其实是读者的一种体感描述它指向的是一组可观察的文本特征句子长度整齐得像用尺子量过、抽象名词密集赋能、闭环、抓手、生态、每段开头都有一个总结性的引导句、论证永远停留在“重要性”层面而进不到“怎么做”层面、段落之间靠“值得注意的是”“更重要的是”这类连接词硬接。这些特征叠加起来读者会形成一种直觉这段话像是被生产出来的不像被写出来的。“不是……而是……”之所以容易被当成靶子是因为它在上述特征里出现频率特别高。大模型在训练数据里见到大量这类对比结构学会了一个偷懒策略遇到需要展开论述的地方先虚构一个对立面再给出自己的立场句子立刻显得有层次。问题是这个对立面往往是模型自己立起来的稻草人读者根本没这么想过。举个常见的例子。假设要写一段关于 Redis 缓存穿透的说明缓存穿透不是简单的性能问题而是系统设计层面的架构问题。这句话语法上没问题但它什么也没说。读者既不知道缓存穿透是什么也不知道它为什么是“架构问题”更不知道该怎么处理。否定项性能问题是一个没人主张的观点肯定项架构问题是一个没有操作含义的标签。这就是典型的零信息量对比。同样的话题换一种写法缓存穿透指的是查询一个数据库里也不存在的 key请求每次都绕过缓存打到数据库。它和缓存击穿的区别在于击穿是热点 key 过期瞬间的并发冲击穿透是恶意或错误的 key 持续无效查询。前者靠互斥锁和逻辑过期解决后者必须靠布隆过滤器或空值缓存拦截。这段没有一个“不是……而是……”但信息量是上一段的十倍。区别不在于用没用那个句式而在于作者有没有真的把机制讲清楚。所以这篇文章要处理的核心问题可以归结为一句话读者反感的不是对比结构而是用对比结构包装的空洞。只要你能保证否定项是真实存在的误解、肯定项带有新增事实这个句式完全可以用而且用得越多越显得思路清晰。2. “不是……而是……”为什么这么好用结构与认知原理要判断一个工具什么时候该用、什么时候不该用得先知道它为什么有效。这个句式的底层是一个“纠正模型”。人类理解新信息时会先激活已有的认知框架然后把新信息往里塞。如果新信息和旧框架冲突理解成本就会上升。“不是 A而是 B”的作用是先明确告诉读者“请把你脑子里的 A 关掉”再给出 B。这样读者不需要自己去做冲突检测理解路径被缩短了。它在三种场景下确实不可替代第一种破除普遍误解。比如“Java 的 String 不是引用传递而是传递引用的副本”。这里 A引用传递是初学者真实持有的错误认知否定它是必要动作B 则给出了准确机制。这种用法有明确的教学价值。第二种纠正概念混淆。比如“熔断不是限流而是对下游故障的快速失败响应”。限流和熔断经常被初学者混为一谈先否定再区分能让边界立刻清晰。第三种划清技术选型的适用边界。比如“这个消息队列不是用来做实时 RPC 的而是用来做削峰和异步解耦的”。这句话在技术评审里很有用它直接否定了错误用法。注意这三种场景的共同点否定项 A 是真实存在于读者脑子里的东西。这是判断这个句式用得好不好的第一道关卡。如果 A 是作者自己编出来凑结构的那这个句式就退化成了修辞表演。再看认知负荷的角度。这个句式其实是把一个复合命题拆成了两个短句降低了单句的信息密度从而降低了阅读难度。对于复杂概念这是好事但对于本来就简单的结论这就是把一句话拆成两句说读者会觉得被灌水。这也是为什么技术文档里适度使用没问题而营销文案里大量使用会让人反感——后者的内容本来就撑不起这个结构。这里可以给出一个粗略的经验值一篇三千字的技术文章里这个句式出现三到五次是正常的论证需要出现十五次以上基本就可以判定为结构依赖了。后文我会给一个脚本把这个统计自动化。3. 被误判为 AI 味的三个真实原因大部分人把矛头指向句式是因为没找到真正的病灶。把常见的“AI 味”文本拆开看问题基本落在下面三类。3.1 否定项是稻草人读者根本没这么想这是最高频的问题。作者为了让对比成立先虚构一个对立观点。很多开发者以为微服务就是把单体拆小其实不是拆分粒度的问题而是服务边界划分的问题。问题在于稍微有点经验的开发者都知道微服务不是“拆小”这么简单。这个“很多开发者以为”是一个没有出处的泛指读者读到会本能地产生抵触——我没这么以为你在跟谁说话更麻烦的是这类句子往往连着出现。第一段否定一个假想敌第二段再否定一个假想敌读三屏之后读者会发现作者花了大量篇幅在跟空气辩论真正的方法论一句没说。修正方式很直接如果找不到真实的反方观点就不要设否定项直接给结论加证据。上句可以改成微服务的难点在服务边界划分不在拆分粒度。拆得太细会导致跨服务调用链变长一次业务请求可能要串联五六个服务任何一环超时都会拖垮整体响应时间拆得太粗又失去了独立部署的意义。判断边界是否合理可以看两点这个服务能不能独立发版它的数据表有没有被其他服务直接读写。同样的意思但每句话都带具体事实。3.2 肯定项没有新增事实换了个说法而已第二类问题的特征是否定项和肯定项在信息层级上是平的只是换了个词。这不是一个技术问题而是一个管理问题。读者读完会问然后呢技术问题和管理问题分别意味着什么谁该负责怎么推进这句话如果不加后续内容等于把一个问题重新贴了个标签。判断方法很简单把这句话删掉看上下文是否还成立。如果成立说明它是纯装饰删。如果不成立说明它承担了结构功能保留。这个方法我在改稿时用得最多它比任何词表都可靠。3.3 密度过高且节奏雷同读者的疲劳感第三类问题不是单句的问题是整体节奏的问题。当一篇文章每隔两三段就来一次同样的对比结构读者会产生强烈的模式识别进而产生“这段我可以跳过”的预判。这其实和代码里的重复代码是一个道理。一段逻辑复制粘贴五次代码审查一定会打回来因为它增加了维护成本同样的句式反复出现读者的阅读成本也在上升因为每次都要重新走一遍“否定—肯定”的解析路径而收益是递减的。解决方式不是禁用而是换着来。同样的纠正意图可以用“A 和 B 的区别在于……”“真正影响结果的是……”“如果按 A 的思路做会……按 B 的思路做则……”。句式一变读者的解析负担就散了。总结一下这一节AI 味 稻草人否定 零增量肯定 高密度重复。三条命中两条读起来就会发飘三条全中基本就是机器生产的味道了。4. 环境准备搭一个文本 AI 味检测脚本光靠手感判断容易自我欺骗尤其是自己写的稿子。这一节我们写一个脚本来做量化检测。环境要求不高Python 3.8 及以上脚本只用标准库不装第三方包任意文本编辑器待检测的文本文件UTF-8 编码支持.md和.txt脚本检测四个维度检测维度说明参考阈值对比句式密度“不是……而是……”每千字出现次数低于 3 次为健康套话词命中赋能、闭环、抓手、生态化等抽象名词每千字低于 2 次段落长度方差段落字数的标准差过小说明节奏过于均匀低于 30 时提示引导句占比以“值得注意的是”“更重要的是”开头的段落比例低于 15% 为健康先写词表配置文件。文件路径tools/ai_style_words.json{ contrast_patterns: [ 不是[^。\\n]{0,40}?而是, 并非[^。\\n]{0,40}?而是, 与其说[^。\\n]{0,40}?不如说 ], buzzwords: [ 赋能, 闭环, 抓手, 生态化, 多维度协同, 全面打通, 底层逻辑, 顶层设计, 具有重要意义 ], lead_in_phrases: [ 值得注意的是, 更重要的是, 需要指出的是, 综上所述, 总而言之, 不难发现 ] }这里说明一下为什么把buzzwords和lead_in_phrases分开前者是名词层面的空洞后者是连接词层面的冗余两者的修改策略不同。抽象名词需要替换成具体对象冗余连接词直接删掉就行。接着写检测脚本。文件路径tools/ai_style_check.py#!/usr/bin/env python3 # -*- coding: utf-8 -*- 文本 AI 味特征检测脚本仅依赖标准库 import json import re import statistics import sys from pathlib import Path CONFIG_PATH Path(__file__).parent / ai_style_words.json def load_config(path: Path) - dict: with path.open(r, encodingutf-8) as f: return json.load(f) def read_text(path: Path) - str: return path.read_text(encodingutf-8) def split_paragraphs(text: str) - list: 按空行切分段落过滤掉代码块和标题行 raw_blocks re.split(r\n\s*\n, text) paragraphs [] in_code_block False for block in raw_blocks: stripped block.strip() # 检测代码块边界 fence_count stripped.count() if fence_count % 2 1: in_code_block not in_code_block continue if in_code_block or not stripped: continue if stripped.startswith(#): continue paragraphs.append(stripped) return paragraphs def count_patterns(text: str, patterns: list) - int: total 0 for pattern in patterns: total len(re.findall(pattern, text)) return total def count_words(text: str, words: list) - dict: hits {} for word in words: c text.count(word) if c 0: hits[word] c return hits def analyze(path: Path, config: dict) - None: text read_text(path) paragraphs split_paragraphs(text) char_total len(re.sub(r\s, , text)) if char_total 0: print(文件为空跳过检测) return per_1k char_total / 1000.0 contrast_count count_patterns(text, config[contrast_patterns]) buzz_hits count_words(text, config[buzzwords]) lead_hits count_words(text, config[lead_in_phrases]) para_lengths [len(re.sub(r\s, , p)) for p in paragraphs] var statistics.pstdev(para_lengths) if len(para_lengths) 1 else 0.0 lead_para sum( 1 for p in paragraphs if any(p.startswith(ph) for ph in config[lead_in_phrases]) ) lead_ratio lead_para / len(paragraphs) if paragraphs else 0.0 print(f文件{path}) print(f正文总字数不含空白{char_total}) print(f段落数{len(paragraphs)}) print(- * 40) print(f对比句式命中{contrast_count} 次 f密度 {contrast_count / per_1k:.2f} 次/千字) print(f套话词命中{sum(buzz_hits.values())} 次 f密度 {sum(buzz_hits.values()) / per_1k:.2f} 次/千字) if buzz_hits: print(f 明细{buzz_hits}) print(f引导句开头段落{lead_para} 段占比 {lead_ratio:.1%}) if lead_hits: print(f 明细{lead_hits}) print(f段落长度标准差{var:.1f}) print(- * 40) warnings [] if contrast_count / per_1k 3: warnings.append(对比句式密度偏高检查否定项是否为稻草人) if sum(buzz_hits.values()) / per_1k 2: warnings.append(抽象名词过多替换为具体对象或删除) if var 30 and len(paragraphs) 5: warnings.append(段落长度过于均匀节奏可能显得机械) if lead_ratio 0.15: warnings.append(引导句占比过高多数可直接删除) if warnings: print(检测提示) for w in warnings: print(f - {w}) else: print(未触发阈值提示。注意脚本只做量化参考不代表文本质量合格。) if __name__ __main__: if len(sys.argv) 2: print(用法python ai_style_check.py 文件路径) sys.exit(1) cfg load_config(CONFIG_PATH) analyze(Path(sys.argv[1]), cfg)这个脚本有三个设计取舍值得说明。第一段落切分时主动跳过了代码块和标题。如果不跳过“不是……而是……”出现在代码注释里也会被计入统计导致误报。技术博客的代码块占比往往很高这个过滤是必要的。第二用标准差而不是平均值来衡量段落长度节奏。平均值反映不了分布的均匀程度。一篇段落都是 150 字的文章和一篇段落长短交错的文章平均字数可能一样但阅读体验差别很大。标准差低到 30 以下通常意味着作者在按固定模板填充。第三输出的是提示而不是评分。文本质量没法用一个数字概括给个 72 分反而会误导人。脚本的价值在于把“感觉有点怪”变成“这里密度偏高了回去看看”。跑起来试试cd tools python ai_style_check.py ../drafts/my-article.md如果提示找不到文件先确认路径是相对于当前工作目录的Windows 下如果中文输出乱码在命令前加chcp 65001切换到 UTF-8 代码页。5. 核心流程把句式用对的四步法有了检测手段接下来是改稿流程。这套流程我建议按顺序走别跳步。5.1 第一步逐个定位问“否定项是真实存在的吗”把文中所有对比句式标出来逐句问自己我说的 A目标读者真的会这么想吗判断依据是读者画像。写给完全没接触过这个技术的新手“消息队列不是数据库”这种否定是有价值的因为新手确实可能把它当存储用。写给三年经验的工程师同样的话就是废话。如果答案是“读者不会这么想”两条路删掉否定项直接给结论或者换一个读者真的持有的误解。后者更难但价值更高。5.2 第二步检查肯定项是否带增量删掉否定部分只看肯定部分问这句话提供了新的事实、新的机制、新的判断标准吗如果只是把 A 换了个同义标签那就是零增量。补救方式有两种补机制说清楚 B 是怎么运作的为什么 A 不行。补边界说清楚 B 在什么条件下成立什么条件下失效。技术写作里补边界往往比补机制更有价值因为它直接告诉读者什么时候该用、什么时候别用。5.3 第三步控制密度做句式替换统计全文出现次数超过每千字三次就开始替换。替换不是简单换个词而是换一种组织信息的思路。原句式可替换表达适用场景不是 A而是 BA 和 B 的区别在于……概念对比不是 A而是 B真正决定 X 的是……归因分析不是 A而是 B如果按 A 做会……按 B 做则……方案对比不是 A而是 BB 解决了 A 无法处理的……引入新方案不是 A而是 B常见的做法是 A但在……场景下 A 会失效破除默认认知注意最后一行它保留了“破除误解”的功能但把结构从“否定—肯定”改成了“默认—例外”读起来更自然也更适合工程文档。5.4 第四步通读看段落长度是否过于均匀这一步针对节奏。把全文段落字数列出来如果连续五六段都在 150 到 180 字之间说明你在按固定模板写作。真实的技术写作节奏应该是起伏的概念解释可以长一点操作步骤可以短一点关键结论用一句话单独成段。长短交错本身就是一种强调手段。6. 完整改写实战六组技术文档前后对比前面讲的是方法这一节给具体案例。以下是六组真实的改写对比场景取自技术文档和项目方案里最常见的写法。6.1 场景一解释缓存与数据库的关系改写前缓存不是数据库的替代品而是数据库的加速层。问题否定项“替代品”是个稻草人没人真的认为缓存能替代数据库肯定项“加速层”是标签没有操作含义。改写后缓存只存数据库的一部分数据而且随时可能失效。它的作用是把高频读取的请求拦在数据库前面降低数据库压力。所以缓存设计的第一原则不是“存什么”而是“存丢了会怎样”——能容忍回源的数据才适合放缓存账户余额这类必须强一致的字段缓存只能作为读加速写操作仍然要落到数据库并处理失效。这版把“不是……而是……”压缩到了一个小句里而且它服务的是一个真实的设计决策缓存什么不是修辞。6.2 场景二说明索引失效改写前索引失效不是数据库的 bug而是 SQL 写法不符合索引使用条件。问题这句话把责任推给了开发者但没有告诉读者哪些写法会失效。读者读完还是不知道该怎么办。改写后索引失效多数情况是 SQL 的写法让优化器无法使用索引。常见的几种在索引列上做函数运算WHERE YEAR(create_time) 2024、隐式类型转换字符串列传数字、前导通配符LIKE %abc、以及在联合索引上跳过最左列。排查时先看EXPLAIN输出的type字段出现ALL基本就是全表扫描。改写后没有用对比句式但给出了四类具体原因和一条排查命令可操作性完全不同。6.3 场景三技术选型说明改写前我们选择的不是 MySQL而是 PostgreSQL。问题这是把决策过程简化成了结论。读者会问为什么代价是什么改写后我们最终选了 PostgreSQL主要原因是业务需要存储 JSON 字段并对其中的键做索引查询。MySQL 的 JSON 类型虽然也支持但函数索引的表达能力有限复杂查询需要额外建生成列。代价是团队对 PostgreSQL 的运维经验不足所以上线前补了备份恢复演练和慢查询监控这两块的配置写在部署文档的第三节。这版保留了决策结论但补上了依据和代价。技术选型文档里代价比理由更重要因为理由往往事后能补代价是当场就要承担的。6.4 场景四代码审查意见改写前这里的写法不是最优的而是存在性能隐患的。问题这是典型的评审废话。作者既没指出问题在哪也没给出替代方案被评审的人只能干瞪眼。改写后这个循环里每次都调用findById查库N 条数据就是 N 次查询。改成先收集 ID 列表用findAllById一次性查出来再在内存里做映射可以把查询次数从 N 降到 1。如果列表可能很大注意分批单次 IN 的参数不要超过一千个。评审意见的价值在于可执行。指出问题只是第一步给出改法和边界条件才算完整。6.5 场景五说明日志级别改写前日志不是越多越好而是要分级管理。问题正确的废话。“分级管理”是一个标签读者不知道具体怎么分。改写后日志分级的实用判断标准是“谁会看”。ERROR 给值班同学看必须包含可定位的信息请求 ID、用户标识、出错的具体参数。WARN 给排查问题时看记录那些不影响本次请求但值得关注的异常。INFO 记录关键业务节点用于事后还原链路。DEBUG 只在本地开发时打开不要带到生产环境——高并发下 DEBUG 日志的 IO 开销足以拖慢整个服务。这一段把“分级”落到了“谁看、看什么、什么时候关”每一级都有明确的动作。6.6 场景六方案评审结论改写前这个方案不是不可行而是需要进一步评估。问题这是会议纪要里最常见的和稀泥句式既没给结论也没给下一步。改写后方案在当前数据量下可行但有两个风险点需要先确认一是单表预估半年后到两千万行分库分表的改造成本要提前算进去二是依赖的第三方接口没有 SLA 承诺需要补一个降级方案。这两点确认后再进入开发评估结论记在评审文档的第七节。改写后给出了明确结论可行、具体风险数据量、第三方依赖和下一步动作确认后开发任何一条都可以直接跟进。把这六组对比放在一起看会发现一个规律改写后很少用对比句式但对比关系反而更清晰了。因为对比关系是靠具体事实撑起来的不是靠句式标签贴上去的。这也是整篇文章最核心的判断。7. 运行结果解读与失败时的排查顺序用第 4 节的脚本跑一段真实文本输出大概长这样文件drafts/my-article.md 正文总字数不含空白4820 段落数21 ---------------------------------------- 对比句式命中18 次密度 3.73 次/千字 套话词命中11 次密度 2.28 次/千字 明细{底层逻辑: 4, 闭环: 3, 赋能: 2, 抓手: 2} 引导句开头段落5 段占比 23.8% 明细{值得注意的是: 3, 更重要的是: 2} 段落长度标准差22.6 ---------------------------------------- 检测提示 - 对比句式密度偏高检查否定项是否为稻草人 - 抽象名词过多替换为具体对象或删除 - 段落长度过于均匀节奏可能显得机械 - 引导句占比过高多数可直接删除怎么读这个结果三个要点。第一密度高不等于要全删。3.73 次每千字意味着四千八百字里有十八次。这里面可能有六次是有效的论证剩下的十二次需要处理。目标是压到十次以下不是压到零。第二套话词明细比总数更有用。总数告诉你“多了”明细告诉你“哪个词被用滥了”。如果“底层逻辑”出现四次说明你在反复用一个没有操作含义的词替代具体机制这四处都需要展开。第三标准差和引导句占比要结合看。标准差低加上引导句占比高通常意味着文章是按“引导句 三段论证 小结”的固定模板写的。这种模板在商业文案里有效在技术文档里会让读者失去耐心。如果脚本跑不起来按这个顺序排查ModuleNotFoundError确认 Python 版本脚本只用标准库正常不会有这个问题如果报错检查是不是文件名和标准库模块冲突比如你的脚本叫json.py。FileNotFoundError确认ai_style_words.json和脚本在同一目录或者改脚本里的CONFIG_PATH。输出中文乱码Windows 终端执行chcp 65001或者用 VS Code 的集成终端。统计结果明显偏小检查文件编码是不是 UTF-8GBK 编码的中文可能被读成乱码导致匹配失败。段落数统计异常脚本跳过了代码块和标题行如果文章以代码为主段落数偏少是正常的。8. 常见问题与排查思路问题现象可能原因排查方式解决方案改完还是觉得有 AI 味病灶不在句式在信息密度随机抽三段删掉每段的第一句和最后一句看是否还能读懂如果能读懂说明首尾句是装饰删掉或换成具体事实不知道否定项是不是稻草人没有明确的读者画像写文章前先写一行“本文读者是___他们已经知道___不知道___”用这行字反查每个否定项超纲的保留不超纲的删除删掉对比句式后行文变散删了结构却没补内容检查删掉的位置上下文是否还有过渡换成“A 和 B 的区别在于……”或直接补一句具体事实做承接整篇文章段落长度惊人地一致按模板写作每段一个论点加两句话解释用脚本看标准差主动打乱关键结论单独成段操作步骤用短段概念解释用长段脚本统计的段落数和实际不符代码块边界识别失败检查代码块是不是不成对或者用了非常规围栏统一用三个反引号成对出现词表漏掉了一些高频套话不同领域的套话不同把自己常写的领域里的抽象词收集一遍定期往ai_style_words.json的buzzwords里追加评审意见被反馈“说了等于没说”只给了判断没给动作检查每条意见是否包含“问题定位 改法 边界”补齐三要素缺哪个补哪个这张表里最值得展开的是第一行。很多人改稿时盯着句式改改完还是觉得不对因为真正的病灶在信息密度。判断方法很粗暴但有效随机抽三段把每段的第一句和最后一句删掉看剩下的内容还能不能读懂。如果能读懂说明首尾两句是装饰如果读不懂说明这两句承担了实质信息保留。这个方法之所以有效是因为 AI 生成的文本有一个稳定特征段首给总结段中给展开段尾给收束。三段式完整得挑不出毛病但删掉首尾之后中间那段往往撑不起一个完整的论点。人类写的技术文章恰恰相反开头可能直接进细节结论藏在中间段落边界不那么工整。9. 最佳实践把写作规范落到个人和团队前面讲的是“怎么改”这一节讲“怎么从一开始就少犯错”。9.1 个人写作三个可以立刻执行的习惯习惯一写完先写禁用清单再逐条自查。我自己的清单是四条不用“随着……的发展”开头、不用“本文将介绍”、不用没有出处的“很多开发者认为”、每段至少包含一个具体名词类名、命令、参数、数字。前三条治套路第四条治空洞。习惯二先把事实列出来再写句子。写技术方案时我习惯先列一个事实清单涉及哪些表、哪些接口、预估 QPS 多少、超时时间设多少、失败后怎么回滚。列完这些文章的结构自然就有了不需要靠句式去撑。习惯三朗读一遍。这个方法老土但管用。AI 味重的句子读起来会卡——因为它信息密度低脑子读完没留下东西读到下一句时上下文已经断了。你自己读着不顺的地方读者一定也不顺。9.2 团队协作把主观判断变成可讨论的标准个人改稿靠手感团队协作就得靠标准否则评审意见会变成“我觉得这段有点怪”这种没法落实的反馈。可以落地的做法有三个层次。第一层建立领域词表。每个团队的业务抽象词不一样通用词表覆盖不到。把团队文档里反复出现但没人说得清具体含义的词收集起来放进ai_style_words.json的buzzwords。这个词表本身就是一份领域术语说明书。第二层把检测脚本接到 CI 上。如果团队用 Git 管理文档仓库可以加一个提交前检查#!/usr/bin/env bash # 文件路径.git/hooks/pre-commit # 说明文档改动提交前跑一次 AI 味检测只提示不阻断 CHANGED$(git diff --cached --name-only --diff-filterACM | grep -E \.(md|txt)$) if [ -z $CHANGED ]; then exit 0 fi for FILE in $CHANGED; do echo 检测$FILE python tools/ai_style_check.py $FILE || true done exit 0注意最后的exit 0和|| true。这两个是刻意的设计检测结果只做提示不阻断提交。文本质量是主观判断用硬性门槛卡提交会让团队产生抵触最后大家会去想办法绕过检查反而失去意义。给个脚本让你自己看愿意改就改效果比强制好。第三层评审模板化。把第 6 节那六组对比当成团队内部的修改示例评审时直接说“参考示例三的写法”比说“这段写得不够具体”有效得多。9.3 边界什么时候不必纠结 AI 味说句实在的不是所有文本都值得在这上面花时间。内部周报、会议纪要、临时沟通的文档能说清楚就行读者是自己的同事上下文充足不需要额外的信息密度。真正需要打磨的是三类对外发布的技术博客和教程、需要跨团队传阅的设计文档、会长期留在仓库里被别人反复读的 README 和注释。这三类文本的读者没有上下文全靠文字本身传递信息句式空洞的代价最高。还有一个容易被忽略的边界面向模型的提示词也适用这套判断标准。如果你在写 system prompt里面全是“你不是一个助手而是一个专家”这类对比结构模型其实抓不到有效约束。换成具体的行为描述——“回答前先确认用户的操作系统和版本”“涉及删除操作时先提示备份”——效果会好很多。这个道理和写给人看是一样的约束要具体到可执行标签没有用。最后留一个可以马上做的事打开你最近写的一篇技术文档用第 4 节的脚本跑一遍看对比句式密度和套话词明细挑出密度最高的两段用第 5 节的四步法改一遍。改完自己读一遍感受一下差别。这个动作做三次你对 AI 味的判断会从“感觉不对”变成“知道哪里不对、知道怎么改”这时候再看到“不是……而是……”你就不会急着下结论了——你会先看它的否定项站不站得住肯定项带不带东西。这两问一出好句子和坏句子就分开了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑