OSS · Python CLI
rhythm-lens
Prose rhythm flattens before you notice. Measure it.
rhythm-lens measures the rhythm of Markdown in Japanese, English and Portuguese: sentence-length burstiness, syllable/mora variation, paragraph structure. It locates your document on measured distributions from two published papers and answers in percentiles, not vibes. Language is auto-detected; pass --lang to override.
View on GitHub Japanese paper (DOI) → Cross-lingual paper (DOI) →
The 4 core metrics
All seven measured LLMs drift the same way on these four. Direction is model-universal, magnitude is model-dependent. Effect sizes are taken from the paper.
| Metric | AI direction | Cohen's d |
|---|---|---|
Burstiness (characters) | lower = monotone | −0.96 |
Burstiness (morae) | lower = monotone | −0.80 |
Sentences per paragraph, CV | lower = uniform | −0.67 |
Sentence-length CV (characters) | lower = monotone | −0.56 |
Cross-lingual since v0.2.0
A follow-up paper re-ran the design in English and Portuguese with fresh pre-ChatGPT human corpora (853 Dev.to posts, 403 TabNews posts) against 7 LLMs each. The monotonization direction held in all 70 of 70 model×metric cells. So rhythm-lens ships calibrated baselines for three languages, each with its own frozen distribution.
| Language | Human baseline | Pooled burstiness d | Core metrics d < 0 |
|---|---|---|---|
| Japanese | 696 Qiita/Zenn articles | −0.96 | (per-model, 3rd paper) |
| English | 853 Dev.to posts (2019–2022) | −1.12 | 7/7 models |
| Portuguese | 403 TabNews posts (2022) | −1.03 | 7/7 models |
The direction of rhythm metrics ports across languages; only the thresholds are re-calibrated per language. Punctuation is the exception — comma density flips sign between English (+) and Portuguese (−), so it is a per-language dialect, not a shared accent.
Where the thresholds come from
No hand-tuned magic numbers. Every threshold, distribution and effect size is frozen-generated from the published data of the paper (Imoto 2026, DOI 10.5281/zenodo.21413035).
- Human side: 696 Qiita/Zenn technical articles written 2020-2022, before LLM assistance was common
- AI side: 350 documents generated by 7 LLMs (Claude 3 Haiku / Sonnet 4 / Opus 4 / GPT-3.5 Turbo / GPT-4o / GPT-OSS 20B / Llama 3.2 1B)
- The baseline file is deterministically rebuildable from the paper repository’s public CSVs, and the metric code matches the paper’s definitions, verified against the paper’s numbers
- Output shows where your document sits on the human distribution as a percentile, per metric
Install
pipx install git+https://github.com/kenimo49/rhythm-lens Dependencies are MeCab (mecab-python3 + unidic-lite, for Japanese) and pyphen (syllable approximation for English/Portuguese). No LLM, no API key, no network: fully local and deterministic.
Usage
One file in, one verdict out. Exit is instant on documents of ordinary article length.
rhythm-lens article.md # core metrics + verdict with evidence line
rhythm-lens article.md --all # all 12 metrics
rhythm-lens article.md --json # machine-readable output for CI / editor hooks Relationship to natural-japanese
This tool started from coji/natural-japanese (MIT). Its observation that AI smell lives in rhythm more than vocabulary became the starting point of the paper, and rhythm-lens follows its definitions for burstiness, mora approximation and sentence splitting. github.com/coji/natural-japanese
| natural-japanese | rhythm-lens | |
|---|---|---|
| Form | Agent Skill (an LLM reads and rewrites) | Deterministic CLI (no LLM) |
| Main goal | Fix the prose | Measure it and show the evidence |
| Thresholds | Practitioner observation | Published measured distributions (percentiles) |
Complementary layers rather than competitors: measure with rhythm-lens before and after fixing with natural-japanese.
Limits
- Three languages have baselines (ja/en/pt); other languages, including Spanish, have no calibrated distribution yet
- Calibrated on the technical-blog register; novels, poetry and chat logs follow different distributions
- Documents under 5 sentences are not judged (same minimum as the paper)
- YAML frontmatter is stripped before measuring
- Mora/syllable counts are approximated (UniDic for Japanese, pyphen for en/pt); read them alongside the character-based metrics
Related articles
Related developer tools
- claude-shift Multi-account Claude Code manager. Switch the active login, sync the two-file auth Claude Code actually reads (~/.claude/.credentials.json + ~/.claude.json), and watch 5-hour and weekly usage across all accounts. CLI + local API + Chrome extension.
- opencut-mcp MCP server that drives OpenCut classic from any MCP client. Playwright holds the editor session; twelve tools expose the timeline, media assets, and export pipeline. Runs against a fork of OpenCut classic.
- mcp-scorecard Pre-flight checks for MCP servers: passive token footprint, use-case scoping, security, and name safety. LLM-facing quality scorecard.
- 404 Games Ten single-file canvas mini games for your 404 page, inspired by famous error pages. Vanilla JS, zero dependencies, theme-aware. Live on this site's 404.