
Claude Skills by jeffreytse
github.com/jeffreytseUse when building LLM-powered features that require consistent, reliable outputs across varied inputs, or when prompt quality is causing inconsistent application behavior
Use when crafting or improving prompts for large language models — including system prompts, user-facing instructions, evaluation prompts, RAG query templates, agent tool descriptions, or any text that instructs an LLM to perform a task. Trigger when prompt outputs are inconsistent, too long, off-format, or incorrect.
Use when designing a retrieval-augmented generation (RAG) pipeline for grounding LLM outputs in external knowledge
Use when building LLM applications that need to answer questions about proprietary, recent, or domain-specific knowledge that is not in the model's training data
Use when LLM outputs are used to make decisions, generate content, answer questions, or drive application logic — to detect hallucinations, verify factual grounding, and prevent over-reliance on unverified AI-generated content.
Use when building a test suite to evaluate LLM model performance, prompt quality, or AI system behavior
Use when a system must create families of related objects and must remain independent of how those objects are created — so that swapping one product family for another requires no changes to client code.
Use when designing modules, services, or class hierarchies — especially when callers depend on concrete implementations, when swapping one provider requires changing multiple call sites, or when tests require the real implementation to run.
Use when you need to use an existing class but its interface is incompatible with what your code expects — converting one interface into another without modifying either.
Use when you need to vary both an abstraction and its implementation independently — avoiding an exponential class hierarchy that results from combining them through inheritance.
Use when constructing a complex object requires many steps or parameters — especially when the same construction process should produce different representations, or when telescoping constructors become unreadable.
Use when more than one object may handle a request and the handler isn't known a priori — letting you pass the request along a chain of handlers until one handles it, without coupling the sender to any specific handler.
Use when you need to parameterize objects with operations, queue or log requests, support undoable operations, or implement transactional behavior — by encapsulating each request as an object with a uniform execute interface.
Use when designing modules, services, or functions — especially when units are hard to reuse independently, replacements require touching many files, or combining two features requires coupling their internals.
Use when you need to represent part-whole hierarchies of objects and want clients to treat individual objects and compositions of objects uniformly — without special-casing leaf vs. container nodes.
Use when designing relationships between classes or modules — especially when tempted to extend a class to reuse its behavior, or when an inheritance hierarchy is becoming deep or brittle.
Use when deciding which non-UI class should handle a system operation or external event — especially when business logic leaks into UI handlers, or when the same system operation is triggered from multiple interfaces (web, CLI, API).
Use when deciding which class should be responsible for creating instances of another class — especially when object creation is scattered across the codebase, or when constructors are called in classes that have no other relationship to the created object.
Use when you need to add responsibilities to individual objects dynamically — without modifying the class and without the combinatorial explosion that results from subclassing every combination of features.
Use when naming variables, functions, classes, modules, or directories — especially when new team members struggle to connect code to domain concepts, or when domain experts and engineers use different terms for the same thing.
Use when designing complex business software where the domain logic is the primary source of complexity and where miscommunication between technical and business teams causes bugs
Use when a class's internal state is accessed or mutated from outside — especially when callers reach into fields directly, when invariants are violated by external setters, or when internal data structures leak into the public API.
Use when you want to provide a simple, unified interface to a complex subsystem — reducing the number of objects clients must interact with and lowering the coupling between client code and subsystem internals.
Use when a class must create objects but should not be responsible for deciding which concrete class to instantiate — letting subclasses or configuration determine the type at runtime.
Use when an application creates a very large number of fine-grained objects whose combined memory cost is prohibitive — by sharing the intrinsic (immutable) state across instances and storing only extrinsic (context-specific) state outside.
Use when assigning responsibilities to classes — especially when a class is hard to name, does work unrelated to its core concept, or a single change requires understanding an entire class to avoid breaking something.
Use when two components are directly coupled and that coupling causes problems — especially when changing one component forces changes in the other, or when a component cannot be tested without its direct dependency.
Use when deciding which class should be responsible for a computation, validation, or operation — especially when the same data is accessed from multiple places to perform the same calculation, or when a class delegates all its work to another class that holds the actual data.
Use when deciding whether a class should extend another — especially when tempted to inherit for code reuse, when instanceof checks appear in callers, or when an override weakens the parent's contract.
Use when you need to interpret sentences in a simple language — defining a grammar as a class hierarchy where each rule is a class and interpreting an expression is traversing that hierarchy.
Use when you need to access elements of a collection sequentially without exposing its underlying representation — decoupling traversal logic from the collection's data structure.
Use when a class reaches through intermediate objects to access deep properties, when a change to an internal object forces changes in unrelated callers, or when code chains method calls three or more levels deep.
Use when assigning responsibilities to classes — especially when a change to one class ripples into many others, classes are hard to test in isolation, or reusing a class requires dragging in unrelated dependencies.
Use when many objects communicate with each other in complex, tangled ways — centralizing all interaction in a mediator object so that components only talk to the mediator, not to each other.
Use when you need to capture and restore an object's internal state — for undo/redo, rollback, or snapshot functionality — without exposing or violating the object's encapsulation.
Use when reviewing or refactoring an OOP codebase — especially when classes are hard to name, methods reach into other objects' internals, or responsibilities feel wrong but it's unclear exactly why.
Use when a change in one object must automatically notify and update an open-ended set of dependent objects — without the subject knowing which specific objects depend on it.
Use when designing a framework, library, API, or developer tool and deciding how much of the stack to curate for users vs. how much to leave open for user assembly — especially when targeting a specific use case or audience.
Use when behavior varies based on type — especially when if/switch statements check the type of an object to decide what to do, or when adding a new variant requires editing an existing class.
Use when a point of variation or instability is identified in a design — especially when a third-party dependency, algorithm, or external interface is likely to change and other components should not be affected.
Use when creating a new object by copying an existing instance is cheaper or simpler than constructing from scratch — especially when object initialization is expensive or when the exact type of object to create is determined at runtime.
Use when you need to control access to an object — adding lazy initialization, access control, logging, caching, or remote access — without changing the object's interface or the client's code.
Use when no domain class is a suitable home for a responsibility — especially when assigning a responsibility to a domain object would violate high cohesion or low coupling by introducing infrastructure concerns (database, email, logging) into domain objects.
Use when exactly one instance of a class must exist across the entire application — such as a configuration store, connection pool, or logger — and global access to that instance is required.
Use when designing or reviewing classes and modules in OOP code — especially when tests are hard to write, changes ripple unexpectedly, or classes accumulate unrelated responsibilities.
Use when an object's behavior changes based on its internal state and the logic for each state is complex — replacing large conditional chains with state objects where each state encapsulates its own behavior.
Use when replacing a legacy system or component incrementally without a full rewrite, by routing traffic progressively from the old system to a new implementation.
Use when you have multiple algorithms or behaviors that can be swapped for a given task — encapsulating each algorithm in its own class and making them interchangeable at runtime.
Use when multiple classes share the same algorithm skeleton but differ in specific steps — defining the invariant structure once in a base class and letting subclasses override only the varying parts.
Use when designing tools, services, CLIs, or modules — especially when a component accumulates responsibilities over time, changes to one feature break unrelated features, or the component is hard to test in isolation.