stop-slop 深度实战:让 AI 写作告别"机器味"——从 AI Tells 识别到零痕迹输出的完全指南(2026)
"AI writing has patterns. Predictable phrases, structures, rhythms. This skill teaches Claude (or any LLM) to catch and remove them."
— Hardik Pandya, stop-slop 作者
引言:为什么你的 AI 文章一眼就被看穿?
2026 年,大语言模型已经渗透进每一个程序员的工作流。写技术文档、出方案、做 Code Review、生成测试用例——AI 帮我们省了大量时间。但一个尴尬的问题始终存在:
AI 写的东西,有一种说不出的"AI 味"。
编辑能看出来,导师能看出来,甚至连不懂技术的人,读两段也能感觉到"这不像人写的"。
这不是错觉。研究表明,主流 LLM 的输出在词汇分布、句法结构、转折模式上存在高度可识别的统计特征——这就是 AI Tells(AI 痕迹)。它不仅影响文章的可信度,在学术场景里甚至可能触发 AIGC 检测告警。
那么问题来了:能不能让 AI 自己学会"去 AI 化"?
GitHub 上本周 Trending 榜出现了一个很有意思的项目——stop-slop(8,098 ⭐,本周新增 3,770 ⭐),它给出的答案是:能,而且可以让 AI 自己改自己。
这篇文章带你完整拆解 stop-slop 的设计哲学、规则体系、实战集成方式,以及——最重要的——它背后的语言学原理。读完你能回答两个问题:
- AI Tells 到底是什么?为什么会有?
- 怎么系统性地让 AI 输出"像人写的"内容?
第一部分:AI Tells 到底是什么?
1.1 从统计视角理解"AI 味"
要解决问题,先得定义问题。
所谓 "AI Tells",指的是大语言模型输出中反复出现的、与人类自由写作有统计显著差异的语言特征。这些特征不是 bug,而是模型训练目标和数据分布的必然结果。
核心矛盾在于:LLM 的训练目标是"生成最可能正确的下一个 token",而人类写作的目标是"表达最有个性的思想"。
这两个目标产生的输出,在以下维度上存在系统性差异:
| 维度 | 人类写作 | LLM 生成 |
|---|---|---|
| 开篇方式 | 多变,常从具体场景切入 | 高度模式化:"在当今社会…"、"随着…的发展" |
| 连接词 | 稀疏,靠语义黏合 | 密集:"首先…其次…此外…总之" |
| 副词使用 | 克制,偶尔为之 | 泛滥:"显著地"、"深刻地"、"尤为重要地" |
| 句式节奏 | 长短交错,有呼吸感 | 均匀,像节拍器 |
| 观点表达 | 有立场,有保留,有矛盾 | 中立、全面、四平八稳 |
| 错误信息 | 会承认"我不知道" | 会编造细节来填补不确定性 |
stop-slop 把这些特征归纳成了可操作的规则集,而不是停留在"感觉"层面。
1.2 stop-slop 项目定位
stop-slop 的作者 Hardik Pandya 对这个问题的定义非常精准:
"A skill file for removing AI tells from prose."
它不是新模型,不是微调,不是 RAG 管道——它就是一个 skill file,一组结构化的指令,可以:
- 作为 Skill 加载进 Claude Code
- 上传到 Claude Projects 的知识库
- 直接拷贝进 Custom Instructions
- 嵌入任何 LLM 的 system prompt
本质上,它是在用 prompt engineering 的方式解决 prompt engineering 产生的问题——让模型在生成输出之前,先加载一套"反 AI 痕迹"的约束规则,然后自我审查、自我修正。
这种做法在工程上的最大优势是:零延迟、零成本、零依赖。不需要额外推理,不需要第二遍生成,不需要外部检测模型。
第二部分:stop-slop 规则体系深度拆解
项目目录结构非常清晰:
stop-slop/
├── SKILL.md # 核心指令
└── references/
├── phrases.md # 禁用短语清单
├── structures.md # 结构模式黑名单
└── examples.md # 改写前后对照
规则分为三个层次:词汇层、结构层、句子层。我们逐层拆解。
2.1 词汇层:Banned Phrases(禁用短语清单)
references/phrases.md 定义了一组必须消灭的短语模式,分为五大类:
2.1.1 Throat-clearing Openers(清嗓子式开篇)
这类短语在人类写作中偶尔出现,但在 LLM 输出中出现的频率是人类的 10 倍以上(基于 GPT-4 输出统计分析)。
典型违规示例:
❌ "在当今快速发展的数字化时代……"
❌ "随着人工智能技术的不断进步……"
❌ "本文将深入探讨……"
❌ "值得注意的是……"
❌ "总而言之……"
stop-slop 的改写策略: 直接删掉。这些句子在信息量上接近零,唯一的作用是拖延。直接开题。
❌ 改前:在当今快速发展的数字化时代,微服务架构已经成为构建大型系统的主流选择。
✅ 改后:微服务架构把单体系统拆成一组独立部署的服务,每个服务拥有自己的数据存储和通信协议。
注意区别:改后第一句就在给信息,而不是在铺垫氛围。
2.1.2 Emphasis Crutches(强调拐杖)
LLM 特别喜欢用副词来"强调"——因为它不知道什么重要,所以用副词来假装自己知道。
❌ "显著地提升了性能"
❌ "深刻地影响了系统设计"
❌ "尤为重要地"
❌ "毫无疑问"
❌ "显而易见"
stop-slop 的规则非常简单:杀光所有副词。不是"大多数",是"所有"。
这不是极端主义。原因很简单——如果一个观点真的很重要,它不需要副词来强调,它本身就有力量。需要副词来撑场面的句子,本身就不值得写。
❌ 改前:这个优化显著地提升了系统吞吐量,尤其在高并发场景下表现尤为突出。
✅ 改后:P99 延迟从 340ms 降到 42ms。高并发场景下,单节点 QPS 从 1.2k 提升到 8.7k。
看到区别了吗?数字自己会说话,不需要"显著地"。
2.1.3 Business Jargon(商务黑话)
这类词汇在 LLM 的预训练数据(网页、营销文案、企业博客)中高频出现,导致模型把它们学成了"默认正式表达"。
❌ "赋能" → 用具体的动词:让…能…、允许…、支持…
❌ "打通" → 连接、集成、桥接
❌ "端到端" → 从…到…的完整流程
❌ "痛点" → 具体问题、瓶颈、限制
❌ "最佳实践" → 可行方案、经过验证的做法
❌ "业界领先" → (直接删掉,永远是废话)
2.1.4 Vague Declaratives(模糊断言)
LLM 特别喜欢输出"正确的废话"——语法完美、逻辑通顺、但信息量为零的句子。
❌ "性能优化是一个持续的过程。"
❌ "选择合适的工具对于项目成功至关重要。"
❌ "不同场景下需要采用不同的策略。"
stop-slop 对这类句子的处理方式是:要么给具体条件,要么删掉。
❌ 改前:性能优化是一个持续的过程,需要结合具体场景进行分析。
✅ 改后:我们用了三步:先跑 perf 找热点,再用 flame graph 定位到 `json_serialize` 占 40% CPU,
最后把 serde 换成 simd-json,QPS 提升了 3 倍。
2.2 结构层:Structural Clichés(结构陈词滥调)
references/structures.md 定义了 6 种结构性模式,这些模式在 LLM 输出中的出现频率远高于人类写作。
2.2.1 Binary Contrasts(二元对立结构)
❌ "传统方案 X 有 A、B、C 三个问题;新方案 Y 解决了这些问题,同时还提供了 D 和 E。"
这种"黑-白"对比结构在营销文案中很常见,LLM 从训练数据中学到它之后,几乎在任何比较场景中都会自动套用。
人类写作的实际模式: 人类更常写"我们试了 X,遇到 A 问题,然后发现了 Y 的一个特性恰好能解决它,但 Y 也有自己的 trade-off…"——更非线性,更有探索感。
stop-slop 改写策略: 用叙事代替对比,用具体经历代替抽象比较。
❌ AI 味:单体架构在可维护性方面存在挑战,而微服务架构通过服务隔离解决了这一问题。
✅ 人味:我们 2023 年把支付服务从单体里拆出来,不是为了"可维护性"这种虚词——
直接原因是:每次发版,支付模块的一个 bug 能让整个系统挂掉。
2.2.2 Negative Listings(负面列表)
❌ "这个方法不是银弹,不能解决所有问题,也不适用于所有场景,而且还需要额外的配置。"
连续用"不"来定义事物,是 LLM 在"不知道该怎么正面描述"时的默认策略。
改写策略: 正面描述适用范围,而不是反面描述不适用范围。
2.2.3 Dramatic Fragmentation(戏剧性断句)
LLM 特别喜欢用短句+断句来制造"节奏感"——但它用得太均匀了,像节拍器。
❌ "性能崩了。为什么?锁竞争。怎么解?无锁队列。"
三句,每句不超过 6 个字,结构完全对称。人类不会这样写——人类要么写长句,要么断句但断得不规则。
stop-slop 规则: 禁止连续的 staccato 断句。如果你要断,断得有意义的——每句话断的原因应该不同。
2.2.4 False Agency(虚假能动性)
这是 stop-slop 识别出的一个非常深刻的 AI Tell:
❌ "错误被修复了。" ← 错误不会自己修复,是人修的
❌ "性能得到了提升。" ← 性能不会自己提升,是某个人做了某件事
❌ "决策浮现了出来。" ← 决策不会"浮现",是人做出的
❌ "投诉变成了修复。" ← 投诉不会"变成"修复
LLM 特别喜欢用被动语态 + 模糊主语,因为这让它听起来"客观"。但代价是:把所有实际行动的痕迹都擦掉了。
stop-slop 改写策略: 强制使用主动语态 + 明确主语。
❌ 改前:经过优化后,API 响应时间得到了显著提升。
✅ 改后:我们把 N+1 查询换成 batch fetch 之后,API P99 从 800ms 降到 90ms。
注意:"我们"是主语,"把…换成…"是动作。有主语,有动作,有结果。
2.2.5 Narrator-from-a-Distance Voice(远距离旁白音)
LLM 的输出总有一种"隔了一层"的感觉——像是在描述别人做的事情,而不是自己亲历的事情。
❌ "开发者可以使用这个工具来优化性能。"
❌ "用户可能会遇到这个问题。"
❌ "团队应该考虑采用以下策略。"
全是第三人称、全是在给"别人"提建议。人类写技术博客时,更多地使用第一人称或第二人称,更多地基于具体经历。
❌ AI 旁白:开发者可以通过引入缓存层来提升读取性能。
✅ 人声:我们加了一层 Redis 缓存,读取 QPS 从 2k 跳到 40k,但缓存一致性成了新麻烦——
最后用了 write-through + 后台异步刷新,trade-off 是写入延迟多了 15ms。
2.3 句子层规则
SKILL.md 定义了5 条句子级硬性规则:
| 规则 | 说明 |
|---|---|
| 禁止 Wh- 句子开头 | "什么是…"、"为什么会…"、"如何在…"——LLM 特别喜欢用疑问句做段落开头,人类很少这样 |
| 禁止 em dash(—) | 中文场景是"——",LLM 特别喜欢用破折号来做解释说明,频率远超人类 |
| 禁止 staccato 断句 | 连续短句(≤6字)超过 2 个就违规 |
| 禁止 lazy extremes | "完全"、"绝对"、"所有"、"从未"——LLM 喜欢用极端词,人类更爱用限定词 |
| 强制主动语态 | 每句话必须有明确的主语和执行动作 |
第三部分:质量评分体系——35/50 红线
stop-slop 最工程化的设计,是它提供了一套可操作的评分体系。
它定义了 5 个维度,每个维度 1-10 分,总分 50 分。低于 35 分必须重写。
3.1 五个维度详解
Directness(直接度)
衡量标准是:句子是在陈述/宣布,还是在铺垫/绕弯子?
❌ 低分(1-3):随着微服务架构在业界被广泛采用,越来越多的团队开始关注服务间通信的效率问题。
✅ 高分(8-10):gRPC 比 REST 快 5-10 倍,但前提是你的团队能接受 Protobuf 的 schema 管理成本。
高分特征:第一句就有信息、有立场、有具体对比。低分特征:花了 30 个字还在铺垫。
Rhythm(节奏感)
衡量标准是:句式是否有变化?
人类写作的节奏是:长句和短句交错,复杂句和简单句混合。LLM 的节奏是:均匀、像节拍器、每句结构相似。
❌ 低分节奏:微服务架构提升了系统可维护性。它支持独立部署。团队可以并行开发。
(三句结构完全相同,都是"主语 + 动词 + 宾语",像列表)
✅ 高分节奏:微服务最直观的好处是独立部署——支付模块挂了不会影响下单。
但代价是分布式事务。我们用了 Saga 模式,代码量直接翻倍。
(第一句长,有破折号解释;第二句短,有转折;第三句有具体数据)
Trust(信任度)
衡量标准是:文章是否尊重读者智商?
LLM 特别喜欢解释读者已经知道的东西,或者用"众所周知"、"显然"来跳过论证。
❌ 低信任:众所周知,HTTP 是一个无状态协议,因此在实现用户登录时需要引入 Session 机制。
("众所周知"是在假设读者无知,同时在逃避解释)
✅ 高信任:HTTP 不保存连接状态,所以服务器无法区分"这是同一个用户的第二个请求"和"这是新用户"。
Session 的本质就是:在第一次请求时给客户端发一个唯一 ID,后续请求带上这个 ID。
(直接解释,不假设,不跳过)
Authenticity(真实感)
衡量标准是:读起来像"一个有观点的人写的",还是像"一个没有立场的总结机器"?
❌ 低真实感:Rust 和 Go 各有优势,团队应根据具体场景选择合适的技术栈。
(完美的废话,没有任何信息量,没有任何立场)
✅ 高真实感:如果你的瓶颈在并发 IO,Go 的 goroutine 模型让你用最少的代码获得最好的性能。
但如果你在做嵌入式或者需要保证内存安全的高频交易,Rust 的零成本抽象是值得付出
学习成本的。我们两个都用了——Go 做 API 网关,Rust 做订单匹配引擎。
(有场景,有理由,有真实决策)
Density(信息密度)
衡量标准是:能不能删掉一些词而不丢失信息?
❌ 低密度:在进行性能优化的过程中,我们发现了一个非常重要的问题,
那就是数据库查询的效率还有很大的提升空间。
(42 个字,核心信息是:"数据库查询慢"——5 个字)
✅ 高密度:慢查询日志显示,首页 API 的 N+1 查询问题导致 P99 达到 2.3 秒。
(27 个字,包含:现象、根因、具体数据)
第四部分:实战集成——把 stop-slop 装进你的工作流
规则讲完了,怎么用起来?stop-slop 支持四种集成方式,覆盖从个人使用到团队流水线的各种场景。
4.1 方式一:Claude Code Skill(推荐)
如果你在用 Claude Code,这是最无缝的方式。
# 1. 克隆项目
git clone https://github.com/hardikpandya/stop-slop.git
# 2. 在 Claude Code 中加载为 Skill
# Claude Code 的 Skill 系统支持直接加载目录
# 将 stop-slop/ 文件夹路径添加到你的 Claude Code Skill 配置中
# 3. 使用方式:在任意写作任务前,Claude Code 会自动加载 SKILL.md 中的规则
实际效果:你让 Claude Code 帮你写技术文档,它会在生成之前先加载 stop-slop 规则,生成的初稿就已经去除了大部分 AI Tells。你仍然可以迭代,但起点高了很多。
4.2 方式二:Claude Projects 知识库
如果你用 Claude 的 Projects 功能来管理上下文:
- 把
SKILL.md和references/下的三个文件全部上传到 Project Knowledge - 在 Project Instructions 里加一句:
请严格遵守 stop-slop 规则进行写作。 - 之后这个 Project 下的所有对话,都会自动应用 stop-slop 规则
这种方式适合团队协作场景——比如你维护一个技术博客 Project,所有文章生成都自动去 AI 痕迹。
4.3 方式三:Custom Instructions(通用方案)
如果你用的不是 Claude,而是其他 LLM 平台(OpenAI、Gemini、Cursor…),可以直接把 SKILL.md 的核心规则拷贝进 Custom Instructions 或 System Prompt。
核心规则摘要(可直接复制):
写作时严格遵守以下规则:
1. 禁用短语:禁止"在当今…"、"随着…"、"值得注意的是"、"总而言之"等开篇套话;禁止"显著地"、"深刻地"等副词
2. 禁止商务黑话:"赋能"、"打通"、"端到端"、"痛点"、"最佳实践"
3. 禁止模糊断言:信息量为零的总结句必须删掉或补充具体条件
4. 禁止二元对立结构:不用"传统 X… 而现代 Y…"的对比框架
5. 禁止虚假能动性:不用被动语态掩盖行动主体,每句话必须有明确主语
6. 强制主动语态:宁可省略主语也不能用"被…了"的模糊表达
7. 禁止 Wh- 句子开头、禁止 em dash、禁止连续 staccato 断句
8. 写完后按 5 个维度评分(Directness/Rhythm/Trust/Authenticity/Density),总分低于 35/50 必须重写
4.4 方式四:API 调用时嵌入 System Prompt
如果你在代码里调用 LLM API 生成内容,可以在 system prompt 里加载 stop-slop 规则:
import openai
STOP_SLOP_RULES = """
你是技术内容写作者。写作时严格遵守 stop-slop 规则:
- 禁用所有副词(显著地、深刻地、尤为重要地…)
- 禁用开篇套话(在当今、随着、值得注意的是…)
- 禁用商务黑话(赋能、打通、端到端、痛点…)
- 强制主动语态,每句话有明确主语
- 禁止 Wh- 句子开头,禁止 em dash,禁止连续断句
- 写完后自评分 Directness/Rhythm/Trust/Authenticity/Density,
总分低于 35/50 则重写
"""
response = openai.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": STOP_SLOP_RULES},
{"role": "user", "content": "写一篇关于 Rust 异步运行时的技术文章"}
]
)
第五部分:实战案例——用 stop-slop 改写一段技术文章
光说规则不够,直接看效果。下面是一段典型的 AI 生成技术内容,以及用 stop-slop 规则改写前后的对比。
5.1 改写案例一:微服务架构入门
改前(AI 生成原版):
在当今快速发展的软件开发领域,微服务架构已经成为构建大型分布式系统的主流选择。与传统的单体架构相比,微服务架构通过将应用拆分为一组小型、独立的服务,每个服务专注于特定的业务功能,从而提升了系统的可维护性、可扩展性和容错能力。
值得注意的是,微服务架构并非没有挑战。服务间的通信、数据一致性、分布式事务以及服务发现等问题,都需要在设计和实施过程中予以充分考虑。此外,运维复杂度的增加也是团队在采用微服务架构时需要权衡的重要因素。
总而言之,微服务架构为现代软件开发提供了强大的灵活性,但团队在采用这一架构时,应当根据自身的技术实力和业务需求,做出审慎的决策。
问题分析(逐句标注):
[Throat-clearing] 在当今快速发展的软件开发领域,
[Binary Contrast] 与传统的单体架构相比,微服务架构通过…从而提升了…
[Vague Declarative] 可维护性、可扩展性和容错能力(三个虚词,无具体内容)
[Throat-clearing] 值得注意的是,
[Negative Listing] 并非没有挑战…都需要在…予以充分考虑…也是…重要因素
[Throat-clearing] 总而言之,
[Vague Declarative] 根据自身的…做出审慎的决策(完美的废话)
改后(应用 stop-slop 规则):
我们 2022 年把单体系统拆成微服务,直接原因是:订单模块的频繁发版导致整个系统每周宕机 2 次。拆完之后,订单服务可以独立发版,但代价来了——12 个服务之间的调用链让 debug 变成了"猜哪个服务慢了"的游戏。
我们踩了三个坑:
- 一开始用 REST 做服务间通信,延迟高得离谱——后来换成 gRPC,P99 从 180ms 降到 23ms,但 Protobuf schema 的版本管理又成了新麻烦。
- 分布式事务用 2PC,死锁概率比我们预想的高 10 倍——最后迁到 Saga 模式,代码量翻了 3 倍,但至少不再死锁了。
- 服务发现用了 Consul,但网络分区时出现了"脑裂"——两个服务实例都认为对方死了,各自处理了同一笔订单。
微服务不是银弹。如果你的团队少于 5 个人,单体 + 合理的模块划分可能比微服务更实际。
改写要点总结:
- 删掉了所有开篇套话,直接从具体经历开头
- 用"我们踩了三个坑"代替"值得注意的是…存在挑战"
- 每个观点都有具体数据或场景支撑
- 有立场("可能不是更实际"),而不是"团队应审慎决策"这种废话
5.2 改写案例二:Redis 缓存最佳实践
改前(AI 生成原版):
Redis 作为高性能的内存数据库,在现代 Web 应用中扮演着至关重要的角色。为了充分发挥 Redis 的性能优势,开发者应当遵循以下最佳实践:
首先,合理设置键的过期时间,避免内存溢出。其次,选择合适的持久化策略——RDB 适合对性能要求较高的场景,而 AOF 则能够提供更强的数据安全性。再者,应当避免使用复杂度超过 O(n) 的命令,以防止阻塞主线程。
此外,对于集群部署场景,建议采用 Redis Cluster 来实现数据的自动分片和高可用保障。通过遵循上述实践,团队能够显著提升应用的响应速度和系统稳定性。
改后(应用 stop-slop 规则):
Redis 最容易被误用的地方是:把它当成"无限大的快速 KV 存储"。我们曾经在 Redis 里存了 40GB 的 session 数据,然后 Redis 实例 OOM 了——重启之后,所有用户都被登出。
三个教训:
- 过期时间不是可选项。 所有 key 都必须有 TTL。我们的规则是:session 30 分钟,临时锁 5 秒,缓存数据根据业务语义设 1-10 分钟。不设 TTL 的 key 不允许合并到 main 分支。
- 持久化要同时开 RDB 和 AOF。 RDB 做快照,AOF 做增量。我们用的配置是
appendfsync everysec——每秒刷盘,最多丢 1 秒数据,写入性能影响在 5% 以内。- O(n) 命令是性能杀手。
KEYS *在生产环境跑过一次,Redis 阻塞了 12 秒,整个站点 502。后来统一用SCAN,并且对 Redis 命令做了复杂度审查——PR 里如果出现HGETALL对一个可能超过 1000 个 field 的 hash 操作,必须说明理由。集群方面,如果你不到 50GB 数据,别上 Redis Cluster——运维复杂度不值得。用主从 + Sentinel 够用了。
第六部分:stop-slop 的语言学原理——为什么这些规则有效?
规则是表面现象,理解背后的原理才能举一反三。stop-slop 的规则体系,实际上对应了计算语言学的几个核心概念。
6.1 Perplexity 与 Burstiness
这两个概念是 AI 生成文本检测的理论基础。
Perplexity(困惑度): 衡量模型对下一个词的不确定性。LLM 的生成策略(尤其是使用了 temperature=0 或低 temperature 时)会倾向于选择"最安全"的 token,导致输出在统计上比人类写作更"可预测"。
Burstiness(突发性): 人类写作的句式长度分布是高方差的——有时写 30 字的长句,有时写 3 个字的短句。LLM 的输出则更均匀。
stop-slop 的 Rhythm 规则(禁止均匀句式、禁止连续 staccato)本质上是在人为引入 Burstiness,让输出在统计上更像人类。
6.2 词汇分布的 Zipf 定律
人类自然语言的词频分布遵循 Zipf 定律——少数词出现极多次,大量词出现极少次。但 LLM 的输出词频分布更"平坦"——它倾向于使用训练数据中的"平均词",避开极端高频和极端低频的词。
这就是为什么 LLM 很少用俚语、方言、行业黑话、个人口头禅——这些东西在训练数据中出现频率不够高,模型不敢用。
stop-slop 的 Authenticity 规则(鼓励有立场、有场景、有个人视角)本质上是在对抗这种"向均值回归"的倾向。
6.3 主动语态与代理标记(Agentivity)
跨语言学研究显示,人类写作中主动语态的比例与作者的"责任感知"正相关——当你明确知道是谁做了什么,你更可能用主动语态。
LLM 没有"责任感知",所以它默认用被动语态——这样最安全,不需要指定主语。
stop-slop 强制主动语态 + 明确主语,实际上是在要求模型"假装自己有立场、有经历、有责任感"。这个 trick 在提示工程里有个名字:Framing as Experienced Agent。
第七部分:stop-slop 的局限性与争议
任何一个工具,只说好处不说局限是耍流氓。stop-slop 有几个值得讨论的问题。
7.1 规则冲突问题
stop-slop 的规则之间是存在张力的。比如:
- "禁止副词" vs "需要具体描述":有时副词是精确描述所必需的("显著地"不行,但"线性地"可能是技术上的准确描述)。
- "禁止 Wh- 开头" vs "需要引导读者":技术写作中,用疑问句做小节标题是常见且有效的(
"为什么选择 Rust?")。
实际使用时,需要对规则做场景化调整,而不是盲目全套照搬。
7.2 "去 AI 痕迹" vs "逃避检测"
这是一个伦理边界问题。stop-slop 的作者明确表示:这个工具的目标是提高写作质量,而不是帮助人们用 AI 写论文然后逃脱检测。
但客观上,stop-slop 确实能降低 AIGC 检测工具的识别率。这就是为什么有些人在学术场景里用它来"洗稿"——这不是 stop-slop 的设计初衷,但是可以被这样用。
作为技术人,我们需要明确:用 AI 辅助写作 ≠ 用 AI 代替思考。stop-slop 应该用来让你的 AI 辅助写作更流畅、更自然,而不是用来欺骗读者或审稿人。
7.3 对非英文语言的支持
stop-slop 的规则是基于英文写作特征设计的。中文场景下的 AI Tells 有显著差异:
| 中文 AI Tells | 英文版对应 |
|---|---|
| "在当今…"、 "随着…的发展" | "In today's world…" |
| "总而言之"、"综上所述" | "In conclusion…" |
| "它不仅…而且…" | "not only… but also…" |
| "显著地"、"深刻地" | "significantly"、"profoundly" |
| "需要注意的是" | "It is worth noting that" |
| 破折号"——"的过度使用 | em dash "—" 的过度使用 |
中文场景需要一套平行的规则集。目前 GitHub 上出现了一些衍生项目(如 stop-slop-zh 方向),但尚未形成标准。
第八部分:从 stop-slop 看 AI 写作的工具生态演进
把视角拉远一点。stop-slop 的出现,实际上反映了一个更大的趋势:AI 写作工具正在从"生成"走向"润色"和"风格控制"。
8.1 第一代:纯生成(2022-2023)
代表作:ChatGPT、Claude 1/2、GPT-4
特点:输入提示,输出完整文章。质量不稳定,AI 痕迹重。用户需要大量手动编辑。
8.2 第二代:迭代润色(2024)
代表作:Claude Projects、Custom GPTs、Notion AI
特点:通过系统提示词和知识库来控制输出风格。但仍然是在"生成"层面做控制,缺乏对输出质量的量化评估。
8.3 第三代:风格约束 + 质量评分(2025-2026)
代表作:stop-slop、taste-skill、compound-engineering-plugin
特点:
- 风格约束:在生成前加载风格规则(stop-slop 的 SKILL.md)
- 质量评分:生成后自动评估(stop-slop 的 35/50 评分体系)
- 循环重写:评分不达标则自动重写(部分工具支持)
stop-slop 是这个演进方向的一个标志性项目——它用极简的方式(一个 skill file)实现了风格约束 + 质量评分的完整闭环。
8.4 对程序员的意义
作为程序员,我们看待 stop-slop 的方式应该和看待一个 linter 一样:它是一套编码规范,只不过规范的是"写作风格"而不是"代码风格"。
就像我们会在 CI 里跑 ESLint、Black、golangci-lint 一样,未来我们可能会在写作流程里跑 stop-slop 规则检查——在文章发布之前,自动评分,低于阈值就打回重写。
第九部分:动手实战——自己实现一个 stop-slop 检查器
理论讲完了,动手写一个工具。我们用 Python 实现一个简化版的 stop-slop 检查器,能够:
- 检测 banned phrases
- 检测被动语态
- 给出 1-10 分的 Directness 评分
import re
from typing import List, Dict
class StopSlopChecker:
"""
简化版 stop-slop 检查器
检测 AI Tells 并给出质量评分
"""
# Banned phrases (简化版,完整版见 stop-slop/references/phrases.md)
BANNED_PHRASES = [
# 开篇套话
"在当今", "随着.*的发展", "值得注意的是", "总而言之",
"综上所述", "众所周知", "显然", "毫无疑问",
# 副词(中文)
"显著地", "深刻地", "尤为重要地", "特别地",
"完全地", "绝对地",
# 商务黑话
"赋能", "打通", "端到端", "痛点", "最佳实践",
"业界领先", " Corpus", "闭环",
]
def __init__(self):
self.issues = []
def check_banned_phrases(self, text: str) -> List[str]:
"""检测禁用短语"""
issues = []
for phrase in self.BANNED_PHRASES:
# 支持正则匹配(如 "随着.*的发展")
pattern = re.compile(phrase)
for match in pattern.finditer(text):
issues.append(f"[禁用短语] 第 {match.start()} 位: '{match.group()}'")
return issues
def check_passive_voice(self, text: str) -> List[str]:
"""检测中文被动语态(简化规则)"""
issues = []
# 中文被动语态特征:被…了、被…所、为…所
passive_patterns = [
r'被[^,。]{0,10}了',
r'被[^,。]{0,10}所',
r'为[^,。]{0,10}所',
]
for pattern in passive_patterns:
for match in re.finditer(pattern, text):
issues.append(f"[被动语态] '{match.group()}' — 建议改为主动语态")
return issues
def check_wh_starters(self, text: str) -> List[str]:
"""检测 Wh- 句子开头(中文对应:为什么、什么是、如何等)"""
issues = []
wh_patterns = ['为什么', '什么是', '如何', '怎样', '什么时候', '哪里']
for sentence in text.split('。'):
for wp in wh_patterns:
if sentence.strip().startswith(wp):
issues.append(f"[Wh-开头] 句子以 '{wp}' 开头: '{sentence.strip()[:30]}...'")
return issues
def score_directness(self, text: str) -> int:
"""
评分 Directness (1-10)
规则:
- 前 50 个字里有没有信息?有 = 高分,没有 = 低分
- 有没有具体数据?有 = +2 分
- 有没有"在当今/随着"等铺垫?有 = -3 分
"""
score = 5 # 基础分
first_50 = text[:50]
# 负面:开篇套话
if any(word in first_50 for word in ["在当今", "随着", "值得注意的是"]):
score -= 3
# 正面:具体数据
if re.search(r'\d+', text):
score += 2
# 正面:具体技术名词(简单启发式)
tech_keywords = ['Rust', 'Go', 'Python', 'Redis', 'gRPC', 'HTTP', 'API', 'JSON']
if any(kw in text for kw in tech_keywords):
score += 1
return max(1, min(10, score))
def score_authenticity(self, text: str) -> int:
"""
评分 Authenticity (1-10)
规则:
- 有"我/我们/我校/我团队"等第一人称 = +3
- 有"众所周知/显然/毫无疑问"等 = -2
- 有具体场景描述 = +2
"""
score = 5
if re.search(r'(我|我们|我校|我团队|我们组)', text):
score += 3
if any(word in text for word in ["众所周知", "显然", "毫无疑问"]):
score -= 2
if re.search(r'(我们试了|我们踩了|我曾经|上次)', text):
score += 2
return max(1, min(10, score))
def analyze(self, text: str) -> Dict:
"""完整分析"""
result = {
"banned_phrases": self.check_banned_phrases(text),
"passive_voice": self.check_passive_voice(text),
"wh_starters": self.check_wh_starters(text),
"scores": {
"directness": self.score_directness(text),
"authenticity": self.score_authenticity(text),
"total": 0
}
}
result["scores"]["total"] = (
result["scores"]["directness"] +
result["scores"]["authenticity"]
)
return result
def print_report(self, result: Dict):
"""打印检查报告"""
print("=" * 60)
print(" stop-slop 检查报告")
print("=" * 60)
print(f"\n📊 质量评分:")
print(f" Directness: {result['scores']['directness']}/10")
print(f" Authenticity: {result['scores']['authenticity']}/10")
print(f" 总分: {result['scores']['total']}/20 (stop-slop 满分 50,此为简化版)")
if result['banned_phrases']:
print(f"\n❌ 禁用短语 ({len(result['banned_phrases'])} 处):")
for issue in result['banned_phrases'][:5]: # 最多显示 5 条
print(f" - {issue}")
if result['passive_voice']:
print(f"\n⚠️ 被动语态 ({len(result['passive_voice'])} 处):")
for issue in result['passive_voice'][:5]:
print(f" - {issue}")
if result['wh_starters']:
print(f"\n⚠️ Wh-开头 ({len(result['wh_starters'])} 处):")
for issue in result['wh_starters'][:5]:
print(f" - {issue}")
print("\n" + "=" * 60)
# 使用示例
if __name__ == "__main__":
checker = StopSlopChecker()
test_text = """
在当今快速发展的软件开发领域,微服务架构已经成为主流选择。
随着云计算技术的不断进步,越来越多的企业开始采用微服务。
值得注意的是,微服务并非银弹。它被广泛应用于各大互联网公司。
为什么微服务如此流行?因为它提供了更好的可扩展性。
我们团队在2023年完成了单体到微服务的迁移,踩了不少坑。
"""
result = checker.analyze(test_text)
checker.print_report(result)
这个检查器虽然简化,但已经能覆盖 stop-slop 的核心检测逻辑。你可以把它集成进你的写作流程——比如绑定到 VS Code 的一个快捷键,写完一段后立即检查。
第十部分:总结与展望
10.1 stop-slop 的核心价值
用一句话总结 stop-slop 的价值:
它把"AI 写作质量"这个模糊的感性判断,变成了一套可操作、可检查、可量化的规则集。
这听起来简单,实际上非常难。文学和写作风格几千年来都是"只可意会不可言传"的东西,stop-slop 做了一个很有勇气的尝试——把"人味"拆解成可执行的规则。
无论你对这个尝试的最终效果是否满意,它提出的问题本身是值得思考的:当 AI 成为我们写作的一部分,我们如何保持"人"的部分?
10.2 对技术写作者的实用建议
结合 stop-slop 的规则,给经常用 AI 辅助写作的程序员几个具体建议:
- 把 stop-slop 规则加载进你的 AI 工作流——这是收益最高的改进,5 分钟配置,受益持续。
- 写完后自己读一遍——如果读起来"每个字都对,但读完什么也没记住",就说明 AI Tells 太重了,需要重写。
- 补充具体经历——AI 生成的是"平均知识",你补充的是"具体经历",后者才是读者记住的东西。
- 有立场——"A 和 B 各有优劣"是废话,"在我们的场景下选 A 因为…"是有信息量的话。
- 数据 > 形容词——"显著地提升"不如"从 340ms 降到 42ms"。
10.3 未来展望
stop-slop 只是一个开始。我预测在接下来 12 个月内,会出现:
- 多语言版本的 stop-slop(中文、日文、德文…)
- IDE 插件(实时 stop-slop 检查,类似 ESLint)
- 与 AIGC 检测工具的军备竞赛(检测工具进化 → stop-slop 规则进化 → 检测工具再进化…)
- "AI Tells 风格迁移"作为 LLM 的可配置参数(类似 temperature,用户可以调节"AI 味"的浓度)
后记:关于"人味"的终极思考
写到这里,有一个更深层的问题值得讨论:
为什么我们在乎"人味"?
从实用主义角度看:一篇文章的价值在于它传递的信息,而不是它"像谁写的"。如果 AI 写的一篇技术教程比人类写的更清晰、更准确、更容易理解,那"AI 味"有什么所谓?
这个问题我没有完整答案。但我倾向于认为:读者在乎的不是"谁写的",而是"有没有人在对面"。
人类写作的本质,不是信息传递,而是思想交流。交流的前提是:对面有一个人,有自己的立场、经历、偏见和局限。AI 的生成内容,缺的不是一个更华丽的句式——缺的是"人"的这个前提。
stop-slop 能帮你去掉"AI Tells",但它不能帮你补充"人的经历"。后者,还是得你自己来。
参考资料
- stop-slop GitHub 仓库
- Hardik Pandya 个人网站
- stop-slop SKILL.md 及 references/ 目录下的完整规则定义
- 相关学术文献:AI 生成文本检测、Perplexity & Burstiness 指标
文章字数:约 12,000 字
发布时间:2026-06-02
标签:AI写作, stop-slop, LLM, 提示工程, 技术写作