MetadataEnricher
On this page
Module: chunks.metadata_enricher
Import: from zerda.chunks import MetadataEnricher
Table of Contents
Purpose
MetadataEnricher is a post-processing step that runs after any chunker produces raw DocumentChunk objects. It adds:
- Keywords — top-N terms per chunk via TF-IDF
- Importance score — 0–1 float indicating chunk relevance/richness
- Keyword density — keyword count / total word count ratio
These fields are used by ChunkManager in its pipeline before deduplication.
Constructor
MetadataEnricher(
config: Optional[ChunkConfig] = None,
*,
extract_keywords: bool = True,
max_keywords: int = 10,
compute_scores: bool = True,
header_score_boost: float = 1.5,
)
Public Methods
enrich(chunks: List[DocumentChunk]) → List[DocumentChunk]
Mutates and returns the same list with enriched metadata. Modifies chunk.metadata.keywords, chunk.metadata.score, and chunk.metadata.keyword_density in-place.
Parameters:
Returns: the same list (mutated).
Side effects: none beyond modifying the passed chunks.
Empty list: returns immediately with no work.
Keyword Extraction
TF-IDF implemented without external libraries:
1. Stopword filtering (English + Arabic stopword sets embedded in code).
2. Word tokenization: split on whitespace, strip punctuation, lowercase,
minimum 2-character length.
3. Compute TF per chunk: word_count / total_words.
4. Compute IDF across all chunks: log(N / (1 + df)) where df = doc frequency.
5. TF-IDF score = TF × IDF.
6. Top-N by TF-IDF score → metadata.keywords (list of strings).
Single-chunk corpora get pure TF-based keywords (IDF=1 for all terms).
Scoring Algorithm
base_score = 0.0
+ keyword_density_contribution (weight 0.4):
min(keyword_density × 10, 1.0) × 0.4
+ length_contribution (weight 0.3):
sigmoid-like: min(char_count / 500, 1.0) × 0.3
+ position_contribution (weight 0.3):
early chunks score higher:
(1 - position/total_chunks) × 0.3
score = min(base_score, 1.0)
# Apply header boost:
if chunk_type == ChunkType.HEADER:
score = min(score × header_score_boost, 1.0)
Fields Written
Examples
Standalone Enrichment
from zerda.chunks import MetadataEnricher, StructureAwareChunker
chunker = StructureAwareChunker()
chunks = chunker.chunk(text, source="doc.md")
enricher = MetadataEnricher(max_keywords=5, header_score_boost=2.0)
enriched = enricher.enrich(chunks)
for c in enriched:
print(c.metadata.keywords, c.metadata.score)
Disable Scoring
enricher = MetadataEnricher(extract_keywords=True, compute_scores=False)
Custom Configuration
from zerda.chunks import ChunkConfig, MetadataEnricher
config = ChunkConfig(
extract_keywords=True,
keyword_max_count=15,
compute_chunk_scores=True,
header_score_boost=2.0,
)
enricher = MetadataEnricher(config=config)