Communitygithub.com

patrón-de-caché-por-hash-de-contenido

Almacena en caché resultados costosos de procesamiento de archivos usando hashes SHA-256 del contenido, independiente de la ruta, con invalidación automática y separación de capas de servicio. Útil cuando el procesamiento repetido de archivos es lento y los resultados deben guardarse en caché e invalidarse según el contenido, no la ruta.

¿Qué es patrón-de-caché-por-hash-de-contenido?

Este patrón resuelve el problema del almacenamiento en caché de resultados costosos de procesamiento de archivos (como análisis de PDF, extracción de texto o procesamiento de imágenes) mediante el uso de hashes SHA-256 del contenido del archivo como clave de caché. A diferencia de la caché basada en ruta, este enfoque sobrevive a cambios de nombre o movimiento de archivos, y se invalida automáticamente cuando el contenido cambia. Está diseñado para herramientas CLI, pipelines de procesamiento por lotes y cualquier escenario donde el mismo archivo pueda procesarse varias veces. El patrón separa la lógica de caché en una capa de servicio independiente (SRP), manteniendo las funciones de procesamiento puras y sin conocimiento de la caché. Soporta Python, usa archivos JSON nombrados por hash para búsqueda O(1), y maneja la corrupción de caché de forma segura. Ideal para desarrolladores que construyen pipelines de archivos o herramientas CLI con opciones --cache/--no-cache.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/everything-claude-code/tree/main/skills/content-hash-cache-pattern

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Patrón de Caché de Archivos por Hash de Contenido

Almacena en caché resultados costosos de procesamiento de archivos (análisis de PDF, extracción de texto, análisis de imágenes) usando hashes SHA-256 del contenido como claves de caché. A diferencia de la caché basada en ruta, este enfoque sobrevive a cambios de nombre/movimiento de archivos y se invalida automáticamente cuando el contenido cambia.

Cuándo Activarlo

  • Construir pipelines de procesamiento de archivos (PDF, imágenes, extracción de texto)
  • El costo de procesamiento es alto y los mismos archivos se procesan repetidamente
  • Se necesita una opción --cache/--no-cache en la CLI
  • Se desea añadir caché a funciones puras existentes sin modificarlas

Patrón Principal

1. Clave de Caché Basada en Hash de Contenido

Usa el contenido del archivo (no la ruta) como clave de caché:

import hashlib
from pathlib import Path

_HASH_CHUNK_SIZE = 65536  # Fragmentos de 64KB para archivos grandes

def compute_file_hash(path: Path) -> str:
    """SHA-256 del contenido del archivo (fragmentado para archivos grandes)."""
    if not path.is_file():
        raise FileNotFoundError(f"Archivo no encontrado: {path}")
    sha256 = hashlib.sha256()
    with open(path, "rb") as f:
        while True:
            chunk = f.read(_HASH_CHUNK_SIZE)
            if not chunk:
                break
            sha256.update(chunk)
    return sha256.hexdigest()

¿Por qué hash de contenido? Renombrar/mover archivo = acierto de caché. Cambio de contenido = invalidación automática. No se necesita archivo índice.

2. Dataclass Inmutable para la Entrada de Caché

from dataclasses import dataclass

@dataclass(frozen=True, slots=True)
class CacheEntry:
    file_hash: str
    source_path: str
    document: ExtractedDocument  # El resultado en caché

3. Almacenamiento de Caché Basado en Archivos

Cada entrada de caché se almacena como {hash}.json — búsqueda O(1) por hash, sin necesidad de archivo índice.

import json
from typing import Any

def write_cache(cache_dir: Path, entry: CacheEntry) -> None:
    cache_dir.mkdir(parents=True, exist_ok=True)
    cache_file = cache_dir / f"{entry.file_hash}.json"
    data = serialize_entry(entry)
    cache_file.write_text(json.dumps(data, ensure_ascii=False), encoding="utf-8")

def read_cache(cache_dir: Path, file_hash: str) -> CacheEntry | None:
    cache_file = cache_dir / f"{file_hash}.json"
    if not cache_file.is_file():
        return None
    try:
        raw = cache_file.read_text(encoding="utf-8")
        data = json.loads(raw)
        return deserialize_entry(data)
    except (json.JSONDecodeError, ValueError, KeyError):
        return None  # Tratar corrupción como fallo de caché

4. Capa de Servicio Envolvente (SRP)

Mantén la función de procesamiento pura. Añade la caché como una capa de servicio separada.

def extract_with_cache(
    file_path: Path,
    *,
    cache_enabled: bool = True,
    cache_dir: Path = Path(".cache"),
) -> ExtractedDocument:
    """Capa de servicio: verificar caché -> extracción -> escribir caché."""
    if not cache_enabled:
        return extract_text(file_path)  # Función pura, sin conocimiento de la caché

    file_hash = compute_file_hash(file_path)

    # Verificar caché
    cached = read_cache(cache_dir, file_hash)
    if cached is not None:
        logger.info("Acierto de caché: %s (hash=%s)", file_path.name, file_hash[:12])
        return cached.document

    # Fallo de caché -> extraer -> almacenar
    logger.info("Fallo de caché: %s (hash=%s)", file_path.name, file_hash[:12])
    doc = extract_text(file_path)
    entry = CacheEntry(file_hash=file_hash, source_path=str(file_path), document=doc)
    write_cache(cache_dir, entry)
    return doc

Decisiones Clave de Diseño

DecisiónJustificación
Hash SHA-256 del contenidoIndependiente de la ruta, se invalida automáticamente al cambiar el contenido
Nombrado de archivos {hash}.jsonBúsqueda O(1), sin necesidad de archivo índice
Capa de servicio envolventeSRP: la extracción sigue siendo pura, la caché es una preocupación separada
Serialización manual a JSONControl total sobre la serialización de dataclasses inmutables
Corrupción devuelve NoneDegradación suave, reprocesa en la siguiente ejecución
cache_dir.mkdir(parents=True)Creación perezosa del directorio en la primera escritura

Mejores Prácticas

  • Hashea el contenido, no las rutas — las rutas cambian, la identidad del contenido no
  • Fragmenta archivos grandes al hashear — evita cargar archivos enteros en memoria
  • Mantén las funciones de procesamiento puras — no deben saber nada sobre la caché
  • Registra aciertos/fallos de caché con hashes truncados para depuración
  • Maneja la corrupción con gracia — trata las entradas de caché inválidas como fallos, nunca falles

Anti-Patrones a Evitar

# MALO: Caché basada en ruta (se rompe al mover/renombrar archivos)
cache = {"/ruta/al/archivo.pdf": resultado}

# MALO: Añadir lógica de caché dentro de la función de procesamiento (violación de SRP)
def extract_text(path, *, cache_enabled=False, cache_dir=None):
    if cache_enabled:  # Ahora esta función tiene dos responsabilidades
        ...

# MALO: Usar dataclasses.asdict() con dataclasses inmutables anidadas
# (puede causar problemas con tipos anidados complejos)
data = dataclasses.asdict(entry)  # Usa serialización manual en su lugar

Cuándo Usarlo

  • Pipelines de procesamiento de archivos (análisis de PDF, OCR, extracción de texto, análisis de imágenes)
  • Herramientas CLI que se benefician de opciones --cache/--no-cache
  • Procesamiento por lotes donde los mismos archivos aparecen en diferentes ejecuciones
  • Añadir caché a funciones puras existentes sin modificarlas

Cuándo NO Usarlo

  • Datos que siempre deben estar frescos (fuentes en tiempo real)
  • Entradas de caché que serían extremadamente grandes (considera streaming en su lugar)
  • Resultados que dependen de parámetros más allá del contenido del archivo (por ejemplo, diferentes configuraciones de extracción)

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/claude-api

Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.

affaan-m/everything-claude-code

End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches. Use when planning or executing a multi-channel product launch, or producing landing page, email, social, or ad copy.

affaan-m/everything-claude-code

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/everything-claude-code-conventions

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.

affaan-m/gget

gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

affaan-m/literature-review

Systematic literature-review workflow for academic, biomedical, technical, and scientific topics, including search planning, source screening, synthesis, citation checks, and evidence logging.

affaan-m/motion-ui

Production-ready UI motion system for React/Next.js. Use when implementing animations, transitions, or motion patterns.

affaan-m/project-guidelines-example

Example project-specific skill template based on a real production application.

affaan-m/pubmed-database

Direct PubMed and NCBI E-utilities search workflows for biomedical literature, MeSH queries, PMID lookup, citation retrieval, and API-backed literature monitoring.

affaan-m/scholar-evaluation

Structured scholarly-work evaluation for papers, proposals, literature reviews, methods sections, evidence quality, citation support, and research-writing feedback.

affaan-m/uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

Skills relacionados