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.1.0.tar.gz (23.6 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.1.0-py3-none-any.whl (25.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: distill_score-0.1.0.tar.gz
  • Upload date:
  • Size: 23.6 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.1.0.tar.gz
Algorithm Hash digest
SHA256 b448c8d32631b410f526792929091710f955f351ec9dcab01ffc2ee1dadef70e
MD5 9bc002042a1da918bc279a055bdc2ff9
BLAKE2b-256 cd4f2f7bb4147b79482b0fbb85722ab46c3308a9ae6a69a210dd05be68d7e17e

See more details on using hashes here.

Provenance

The following attestation bundles were made for distill_score-0.1.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.1.0-py3-none-any.whl.

File metadata

  • Download URL: distill_score-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 25.4 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.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8c0083574dcf962a9f966f70283270659b4c82002d9f8a3646b5409dc4a1ab1a
MD5 f8f5f49b5483225714832ee062651c67
BLAKE2b-256 1344832f88e1445c5bffa0d9d83517969ad641de8575c87f04e59e6d39c40e3f

See more details on using hashes here.

Provenance

The following attestation bundles were made for distill_score-0.1.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