Communitygithub.com

内容哈希缓存模式

使用 SHA-256 内容哈希缓存昂贵的文件处理结果(如 PDF 解析、文本提取、图像分析)——路径无关,自动失效,支持服务层分离。适用于重复文件处理较慢且应按内容而非路径进行缓存和失效的场景。

内容哈希缓存模式 是什么?

此技能提供了一种基于内容哈希的文件缓存模式,用于优化对昂贵文件处理操作(如 PDF 解析、文本提取、图像分析)的重复执行。与传统的基于路径的缓存不同,它使用文件内容的 SHA-256 哈希作为缓存键,这使得缓存能够抵抗文件移动或重命名,并且当内容实际发生变化时自动失效,无需依赖额外的索引文件。该模式遵循单一职责原则(SRP):将纯处理函数与缓存逻辑分离,通过一个服务层包装器(如 `extract_with_cache`)来协调缓存命中/未命中逻辑。每个缓存条目以 `{hash}.json` 的形式存储为单独文件,实现了 O(1) 的查找性能,并优雅地处理文件损坏(视为缓存未命中)。该模式支持在 Cursor、Claude Code 和 Codex 等 AI 辅助开发环境中实现,尤其适用于构建文件处理流水线、CLI 工具或批处理任务,其中相同文件可能在不同运行中重复出现。技能文档详细介绍了缓存键的生成方法、不可变数据类的定义、文件存储机制、服务层封装以及多个关键设计决策(如 SHA-256 选择、JSON 手动序列化、延迟目录创建等),同时明确列出了应避免的反模式。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/ECC/tree/main/skills/content-hash-cache-pattern

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

内容哈希文件缓存模式

使用 SHA-256 内容哈希作为缓存键,缓存昂贵的文件处理结果(PDF 解析、文本提取、图像分析)。与基于路径的缓存不同,此方法能够适应文件移动/重命名,并在内容发生变化时自动失效。

何时激活

  • 构建文件处理流水线(PDF、图像、文本提取)
  • 处理成本高且相同文件被重复处理
  • 需要一个 --cache/--no-cache CLI 选项
  • 希望为现有纯函数添加缓存而不修改它们

核心模式

1. 基于内容哈希的缓存键

使用文件内容(而非路径)作为缓存键:

import hashlib
from pathlib import Path

_HASH_CHUNK_SIZE = 65536  # 大文件按 64KB 分块

def compute_file_hash(path: Path) -> str:
    """文件内容的 SHA-256 哈希(对大文件进行分块处理)。"""
    if not path.is_file():
        raise FileNotFoundError(f"文件未找到:{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()

为什么使用内容哈希? 文件重命名/移动 = 缓存命中。内容变化 = 自动失效。无需索引文件。

2. 不可变数据类用于缓存条目

from dataclasses import dataclass

@dataclass(frozen=True, slots=True)
class CacheEntry:
    file_hash: str
    source_path: str
    document: ExtractedDocument  # 缓存的结果

3. 基于文件的缓存存储

每个缓存条目存储为 {hash}.json —— 通过哈希进行 O(1) 查找,无需索引文件。

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  # 将损坏视为缓存未命中

4. 服务层封装(单一职责原则)

保持处理函数纯净。将缓存添加为独立的服务层。

def extract_with_cache(
    file_path: Path,
    *,
    cache_enabled: bool = True,
    cache_dir: Path = Path(".cache"),
) -> ExtractedDocument:
    """服务层:检查缓存 -> 提取 -> 写入缓存。"""
    if not cache_enabled:
        return extract_text(file_path)  # 纯函数,无缓存知识

    file_hash = compute_file_hash(file_path)

    # 检查缓存
    cached = read_cache(cache_dir, file_hash)
    if cached is not None:
        logger.info("缓存命中:%s (hash=%s)", file_path.name, file_hash[:12])
        return cached.document

    # 缓存未命中 -> 提取 -> 存储
    logger.info("缓存未命中:%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

关键设计决策

决策理由
SHA-256 内容哈希路径无关,内容变化时自动失效
{hash}.json 文件命名O(1) 查找,无需索引文件
服务层包装器单一职责原则:提取保持纯净,缓存是独立关注点
手动 JSON 序列化完全控制不可变数据类的序列化
损坏时返回 None优雅降级,下次运行重新处理
cache_dir.mkdir(parents=True)在首次写入时懒创建目录

最佳实践

  • 哈希内容,而非路径 —— 路径会变化,内容标识不会
  • 对大文件进行分块哈希 —— 避免将整个文件加载到内存
  • 保持处理函数纯净 —— 它们不应知道缓存的存在
  • 记录缓存命中/未命中,附带截断的哈希以便调试
  • 优雅处理损坏 —— 将无效的缓存条目视为未命中,绝不崩溃

应避免的反模式

# 错误:基于路径的缓存(文件移动/重命名时会失效)
cache = {"/path/to/file.pdf": result}

# 错误:将缓存逻辑放在处理函数内部(违反单一职责原则)
def extract_text(path, *, cache_enabled=False, cache_dir=None):
    if cache_enabled:  # 现在此函数有两个职责
        ...

# 错误:对嵌套的不可变数据类使用 dataclasses.asdict()
# (可能导致复杂嵌套类型的问题)
data = dataclasses.asdict(entry)  # 应改用手动序列化

何时使用

  • 文件处理流水线(PDF 解析、OCR、文本提取、图像分析)
  • 受益于 --cache/--no-cache 选项的 CLI 工具
  • 批处理任务中相同文件出现在不同运行之间
  • 为现有纯函数添加缓存而不修改它们

何时不应使用

  • 必须始终保持新鲜的数据(实时数据流)
  • 缓存条目会非常大(考虑改用流式处理)
  • 结果依赖于文件内容之外的参数(例如不同的提取配置)

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/content-engine

Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.

affaan-m/ECC

Multi-platform content distribution across X, LinkedIn, Threads, and Bluesky. Adapts content per platform using content-engine patterns. Never posts identical content cross-platform. Use when the user wants to distribute content across social platforms.

affaan-m/fal-ai-media

Unified media generation via fal.ai MCP — image, video, and audio. Covers text-to-image (Nano Banana), text/image-to-video (Seedance, Kling, Veo 3), text-to-speech (CSM-1B), and video-to-audio (ThinkSound). Use when the user wants to generate images, videos, or audio with AI.

affaan-m/manim-video

日本語翻訳:このファイルは manim-video 用の日本語翻訳が必要です

affaan-m/remotion-video-creation

Remotion のベストプラクティス - React で動画を作成する。3D、アニメーション、音声、字幕、チャート、トランジションなどをカバーするドメイン固有の29のルール。

affaan-m/video-editing

AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.

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.

agent-self-evaluation

Use after completing any non-trivial task. The agent self-rates its output on 5 axes — accuracy, completeness, clarity, actionability, conciseness — with concrete evidence per criterion. Produces a structured 1-5 scorecard with specific improvement suggestions.

agent-sort

Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.

ai-first-engineering

Engineering operating model for teams where AI agents generate a large share of implementation output. Use when setting team process, review gates, or ownership rules for a codebase largely written by agents.

ai-regression-testing

Regression testing strategies for AI-assisted development. Sandbox-mode API testing without database dependencies, automated bug-check workflows, and patterns to catch AI blind spots where the same model writes and reviews code. Use when adding regression coverage to AI-assisted code, or when the same model both wrote and reviewed a change.

android-clean-architecture

Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns. Use when structuring modules, layers, or data flow in an Android or KMP project.

angular-developer

Generates Angular code and provides architectural guidance. Trigger when creating projects, components, or services, or for best practices on reactivity (signals, linkedSignal, resource), forms, dependency injection, routing, SSR, accessibility (ARIA), animations, styling (component styles, Tailwind CSS), testing, or CLI tooling.

相关技能