defluff
以下摘录自该仓库的 README(片段) · 在 GitHub 读完整 README →
> *The deterministic slop check for AI-generated prose. Point it at a changelog, a doc, or an agent's own output and get back the filler phrases to cut — plus a CI exit code and a pinnable score, identical on every run. No model, no API key.*
Every flagged span carries no information, so cutting them loses nothing. Clean text, same tool, passes straight through:
What makes defluff worth installing over a one-off grep is the engine around the list: bring your own phrases, per-project overlays, and an MCP server your agents pick up with no wiring.
---
Install
Or on macOS/Linux via Homebrew:
That's it. No model download. No API key. Runs anywhere Python does.
---
Quick start
---
MCP server
Exposes three tools so any MCP-aware agent can self-check prose without bespoke wiring — including its own draft, before returning it.
Zero-install via uvx (recommended) — pulls the package and the mcp extra on first run:
Or install it and run the entry point directly:
Published to the MCP Registry as io.github.ahmedak/defluff (see server.json).
mcp-name: io.github.ahmedak/defluff
| Tool | Args | Returns |
|------|------|---------|
| slop_detect | text: str | slop_score, spans (text, category, weight, offsets), categories, lexicon_version |
| slop_add | pattern: str, category: str, scope: "user"\|"project" | adds a phrase to the lexicon overlay |
| slop_ignore | pattern: str, scope: "user"\|"project" | suppresses a phrase (e.g. domain jargon) |
---
Common use cases
- **Agent self-correction** — call slop_detect on a draft and revise the flagged phrases before returning it. Zero wiring, one session, no second model in the loop.
- **CI gate on generated content** — fail the build when an AI-drafted changelog or doc ships full of "furthermore" and "robust." Deterministic + exit codes + a pinnable lexicon is what an LLM-judge gate can't give you.
- **Writing assistant feedback** — highlight the exact phrases an editor would cut, instead of a vague "this sounds AI."
- **A reward *component* for fine-tuning** — see reward loops for caveats; on its own it's gameable.
---
Why defluff?
Every "AI detector" tries to classify *whether* text was AI-generated — a hard, unreliable problem. defluff asks a different question: **does this text contain removable filler?** That's deterministic, and it's true whether a human or an LLM wrote "at the end of the day."
proselint is the closest prior art — deterministic, no model — but emits yes/no warnings rather than a tunable density score, and isn't built around a list you swap, overlay, or pin.
A grep over a word list gives you raw hits. defluff gives you what you'd otherwise have to build around that list:
- **An MCP server** — agents self-check with zero wiring.
- **Markdown- and code-aware** — strips code fences, inline code, and URLs first.
- **Whole-word matching** — "foster" won't fire inside "fostering".
- **A normalized score** instead of a hit count — filler *density*, so one threshold works on a tweet or a 5,000-word doc.
- **Overlap handling** — "at the end of the day" overlapping "end of the day" counts each word once (longest-match-wins).
- **Exit codes, JSON, and char-offset spans** — drop into CI, pre-commit, and editor tooling.
- **A pinnable lexicon hash** — prove the ruler didn't move between runs.
Bring your own slop
One phrase per line (# comments and -/* markers ignored). These layer on top of the built-in defaults and report under a neutral custom category. For real categories and per-phrase weights, use a .json list (see Lexicon overlays).
Ready-made domain packs
| Pack | Catches | Pack | Catches |
|------|---------|------|---------|
| corporate-linkedin | office jargon | crypto-web3 | crypto hype |
| startup-vc | pitch-deck speak | pr-press-release | press-release boilerplate |