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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
295e2fa11f4e39c0ff1866513e1042ba893cd7c59c71f9c065b79d7020b2a9f3
|
|
| MD5 |
67bd5976034723f8feefbb91ad41b4ea
|
|
| BLAKE2b-256 |
a2513ca4944175646dfb1dfa2b582f0b71208926ecc7a2736d5148849b4ddc48
|
Provenance
The following attestation bundles were made for distill_score-0.2.0.tar.gz:
Publisher:
publish.yml on koktsgundars/distill-score
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
distill_score-0.2.0.tar.gz -
Subject digest:
295e2fa11f4e39c0ff1866513e1042ba893cd7c59c71f9c065b79d7020b2a9f3 - Sigstore transparency entry: 1005770441
- Sigstore integration time:
-
Permalink:
koktsgundars/distill-score@ad19a2092cad5107d59ad2723ade791d91eb5966 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/koktsgundars
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ad19a2092cad5107d59ad2723ade791d91eb5966 -
Trigger Event:
release
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3b37775cab634d6250dd3a7428d83f296dab1407d05e9cffba7180f9f27b6419
|
|
| MD5 |
befb93028003379bef42ad5698da4746
|
|
| BLAKE2b-256 |
0e43531894d8cbccd9cc8c602a4ef4f3de09c5bcf83fe4cd1fac860a570d186b
|
Provenance
The following attestation bundles were made for distill_score-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on koktsgundars/distill-score
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
distill_score-0.2.0-py3-none-any.whl -
Subject digest:
3b37775cab634d6250dd3a7428d83f296dab1407d05e9cffba7180f9f27b6419 - Sigstore transparency entry: 1005770444
- Sigstore integration time:
-
Permalink:
koktsgundars/distill-score@ad19a2092cad5107d59ad2723ade791d91eb5966 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/koktsgundars
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ad19a2092cad5107d59ad2723ade791d91eb5966 -
Trigger Event:
release
-
Statement type: