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) →

Terminal demo: rhythm-lens flags an AI-generated draft with 4 of 4 core metrics in the AI direction, character burstiness at the bottom 1% of the human distribution, then passes a human-edited article with all 4 core metrics in the human band.
Two real runs: an AI-generated draft lands 4 of 4 core metrics in the AI direction; a human-edited article passes with all 4 in the human band. Every verdict cites its evidence line.

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

All products →

← Back to products