Skip to main content

Content quality scoring toolkit. Separates signal from noise.

Project description

distill

Content quality scoring toolkit. Separates signal from noise.

The internet is increasingly full of content that is structurally complete but informationally hollow. distill scores content on whether it's actually worth reading — regardless of who or what wrote it.

We don't care if it's AI-generated. We care if it's good.

Quick Demo

pip install distill-score
distill demo

This runs two samples through the scoring pipeline — a generic filler article and a practitioner's experience report — and shows the difference:

Sample A: Generic content
┌─────────────────────────────────┐
│  Grade: D  (Thin content)       │
│  Overall: ██████░░░░░░░░░ 0.33  │
└─────────────────────────────────┘
 substance   ███░░░░░░░░░░░░ 0.18  Low substance density — mostly filler
 epistemic   ██████░░░░░░░░░ 0.41  Low epistemic quality
 readability ████████░░░░░░░ 0.55  Adequate structure

Sample B: Expert content
┌─────────────────────────────────┐
│  Grade: A  (High substance)     │
│  Overall: ████████████░░░ 0.80  │
└─────────────────────────────────┘
 substance   █████████████░░ 0.85  High substance density
 epistemic   ████████████░░░ 0.78  Strong epistemic honesty
 readability ████████████░░░ 0.76  Well-structured and readable

What It Measures

Substance Density

Ratio of concrete, specific information (data points, named entities, code, examples) to filler (generic platitudes, SEO phrases, content-free hedging). Content that says something specific scores high. Content that sounds like it's saying something but isn't scores low.

Epistemic Honesty

Does the content engage honestly with uncertainty and tradeoffs? Expert content tends to be less absolutely confident than filler, because real expertise comes with awareness of edge cases. "This breaks down when your dataset exceeds 10GB" scores better than "guaranteed to work every time."

Readability

Structural quality — reading level, sentence variety, paragraph organization. Good content hits a sweet spot: complex enough to carry substance, clear enough to be accessible. Monotonous sentence structure (common in AI-generated text) scores low.

Usage

CLI

# Score a URL
distill score https://example.com/article

# Score a local file
distill score article.txt

# Score from stdin
cat article.txt | distill score -

# JSON output for programmatic use
distill score --json https://example.com/article

# See which phrases matched each scoring dimension
distill score --highlights https://example.com/article

# Per-paragraph breakdown (strongest/weakest sections)
distill score --paragraphs https://example.com/article

# Use specific scorers only
distill score -s substance,epistemic https://example.com/article

# List available scorers
distill list

Python Library

from distill import Pipeline

pipeline = Pipeline()
report = pipeline.score("""
    We reduced our CI build time from 18 minutes to 4 by parallelizing
    test suites and caching Docker layers. The main bottleneck was
    integration tests hitting a shared database — switching to per-suite
    ephemeral databases added complexity but eliminated flaky tests entirely.
""")

print(f"Grade: {report.grade}")  # Grade: B
print(f"Score: {report.overall_score:.2f}")  # Score: 0.71

for result in report.scores:
    print(f"  {result.name}: {result.score:.2f}{result.explanation}")

Custom Scorer Weights

# Emphasize substance, downweight readability
pipeline = Pipeline(weights={
    "substance": 2.0,
    "epistemic": 1.0,
    "readability": 0.5,
})

Select Specific Scorers

pipeline = Pipeline(scorers=["substance", "epistemic"])

Writing Custom Scorers

from distill.scorer import Scorer, ScoreResult, register
from typing import ClassVar

@register
class JargonScorer(Scorer):
    name: ClassVar[str] = "jargon"
    description: ClassVar[str] = "Penalizes unnecessary jargon and buzzwords"
    weight: ClassVar[float] = 0.5

    def score(self, text: str, metadata: dict | None = None) -> ScoreResult:
        # Your scoring logic here
        return ScoreResult(
            name=self.name,
            score=0.75,
            explanation="Moderate jargon usage.",
            details={"buzzword_count": 3},
        )

Install

pip install distill-score

# With ML-powered scorers (optional, requires GPU or patience)
pip install distill-score[ml]

# Development
git clone https://github.com/koktsgundars/distill-score.git
cd distill
pip install -e ".[dev]"
pytest

Philosophy

  • Quality over detection. We score content, not authorship.
  • Heuristics first. The core scorers require zero ML, zero API keys, zero GPU. They run anywhere.
  • Pluggable by design. Disagree with a scoring dimension? Write a better one and register it.
  • Transparent. Every score comes with an explanation and detailed breakdown.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

distill_score-0.2.0.tar.gz (80.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

distill_score-0.2.0-py3-none-any.whl (60.0 kB view details)

Uploaded Python 3

File details

Details for the file distill_score-0.2.0.tar.gz.

File metadata

  • Download URL: distill_score-0.2.0.tar.gz
  • Upload date:
  • Size: 80.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for distill_score-0.2.0.tar.gz
Algorithm Hash digest
SHA256 295e2fa11f4e39c0ff1866513e1042ba893cd7c59c71f9c065b79d7020b2a9f3
MD5 67bd5976034723f8feefbb91ad41b4ea
BLAKE2b-256 a2513ca4944175646dfb1dfa2b582f0b71208926ecc7a2736d5148849b4ddc48

See more details on using hashes here.

Provenance

The following attestation bundles were made for distill_score-0.2.0.tar.gz:

Publisher: publish.yml on koktsgundars/distill-score

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file distill_score-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: distill_score-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 60.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for distill_score-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3b37775cab634d6250dd3a7428d83f296dab1407d05e9cffba7180f9f27b6419
MD5 befb93028003379bef42ad5698da4746
BLAKE2b-256 0e43531894d8cbccd9cc8c602a4ef4f3de09c5bcf83fe4cd1fac860a570d186b

See more details on using hashes here.

Provenance

The following attestation bundles were made for distill_score-0.2.0-py3-none-any.whl:

Publisher: publish.yml on koktsgundars/distill-score

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page