Giting.
낮의 Giting
홈 › 스킬 › codelazy
안 만들어도 되는 것 사전 실물 캡처 사전 15항목 · 자체 제작
◆ 도입 후보

ponytail 재현 실험에서 'AI에게 게을러지라고 시키면 코드가 32% 준다'를 실측한 뒤(캐싱 27→17, 재시도 47→33, 중복제거 12→1), 그 개념을 우리 증상 사전 포맷으로 재구현했다. 철학 사다리를 리브랜드한 게 아니라, '안 만들어도 되는 것'을 증상별로 목록화하고 표준 대안·요청 문장·실측 before/after·확인법을 붙였다. 핵심 규율은 즉방형/분기형 구분이다. 캐싱·중복제거처럼 표준에 정답이 있는 건 바로 되돌리고, 설정 클래스·커스텀 예외·미들웨어처럼 추상화가 때로 정당한 건 무조건 '만들지 마'가 아니라 갈림길로 진단부터 시킨다. 과잉설계가 잦은 바이브코더에게 도입 후보.

실물부터, 설치 전에 전부 만져보세요

아래는 이미지가 아니라 이 스킬이 담고 있는 진짜 HTML입니다. 눌러 보세요.
안 만들어도 되는 것 · 15가지

AI는 시키면 다 만들어요
안 만들어도 되는 것까지

AI는 시키면 다 만든다. 문제는 '안 만들어도 되는 걸' 만들 때다. 이 사전은 부풀기 쉬운 지점을 증상별로 짚고, 표준 한 줄로 되돌리는 요청 문장을 준다. 실측한 before/after가 붙어 있다.

결과 캐싱을 직접 만든다실측 27줄 → 17줄
✗ 부풀린 코드
_cache = {}
def compute(a, b):
    key = (a, b)
    if key in _cache:
        return _cache[key]
    result = a + b  # 실제 계산
    _cache[key] = result
    return result
✓ 표준으로
from functools import cache

@cache
def compute(a, b):
    return a + b  # 실제 계산

이 함수 결과를 캐싱하고 싶어. 캐시를 직접 만들지 말고 functools.cache 로 해줘.

AI한테 시키는 공식

만들라고 하기 전에
한 번 묻게 해요

만들라고 하기 전에'이거 진짜 만들어야 돼?' 먼저표준으로 되면 그걸로
✕

이거 캐싱 기능 클래스로 하나 만들어줘

○

이거 캐싱하고 싶은데 파이썬 표준으로 되면 그걸로 해줘. 새로 만들지 말고

증상 찾기

이런 말이 나오면
표준부터 봐요

왼쪽이 AI에게 흔히 하는 말, 오른쪽이 이미 있는 해법이에요.

실측

중복 제거를 루프로 만든다

순서 유지 중복 제거는 표준 한 줄. dict.fromkeys. 한 줄이고 seen 집합 루프가 없으면 성공.

리스트 중복을 없애되 순서는 유지하고 싶어. 루프 말고 dict.fromkeys 한 줄로.

✗ 부풀린 코드
def dedup(items):
    seen = set()
    result = []
    for x in items:
        if x not in seen:
            seen.add(x)
            result.append(x)
    return result
✓ 표준으로
def dedup(items):
    return list(dict.fromkeys(items))
Claude Code 스킬

만들기 전에
AI가 먼저 멈춰요

스킬로 깔아 두면 부풀기 쉬운 지점에서 「이거 표준으로 돼요」를 먼저 말해요.

/plugin marketplace add hanmariyang/giting-skills

/plugin install codelazy@giting

GitHub에서 오픈소스 보기 ↗

01 표준이 이미 함 5

즉방형

"결과 캐싱을 직접 만든다"

실측 27줄 → 17줄
✗ 부풀린 코드
_cache = {}
def compute(a, b):
    key = (a, b)
    if key in _cache:
        return _cache[key]
    result = a + b  # 실제 계산
    _cache[key] = result
    return result
✓ 표준으로
from functools import cache

@cache
def compute(a, b):
    return a + b  # 실제 계산
처방: 표준 functools.cache 데코레이터 한 줄. 만들 게 없다. @cache 한 줄 붙였고 자작 캐시 딕셔너리가 없으면 성공.
즉방형

"개수 세는 딕셔너리를 직접 만든다"

✗ 부풀린 코드
counts = {}
for w in words:
    if w in counts:
        counts[w] += 1
    else:
        counts[w] = 1
✓ 표준으로
from collections import Counter
counts = Counter(words)
처방: 표준 collections.Counter. 세는 것도, 최다 뽑는 것도 다 있다. Counter 를 썼고 수동 if-else 카운트가 없으면 성공.
즉방형

"없는 키 기본값 처리를 직접 만든다"

✗ 부풀린 코드
groups = {}
for item in items:
    if item.cat not in groups:
        groups[item.cat] = []
    groups[item.cat].append(item)
✓ 표준으로
from collections import defaultdict
groups = defaultdict(list)
for item in items:
    groups[item.cat].append(item)
처방: 표준 defaultdict, 또는 값 조회는 dict.get(key, 기본값). defaultdict/get 을 썼고 'if key not in d' 초기화가 없으면 성공.
즉방형

"상수 모음을 클래스로 직접 만든다"

✗ 부풀린 코드
class Status:
    PENDING = 1
    ACTIVE = 2
    DONE = 3
    # 오타·중복·순회 전부 수동
✓ 표준으로
from enum import Enum

class Status(Enum):
    PENDING = 1
    ACTIVE = 2
    DONE = 3
처방: 표준 enum.Enum. 값 검증·이름·순회가 공짜로 딸려 온다. Enum 을 상속했고, 검증 없는 맨 상수 클래스가 아니면 성공.
즉방형

"임시 파일 경로를 직접 만든다"

✗ 부풀린 코드
import time, random
name = f"/tmp/tmp_{int(time.time())}_{random.randint(0,9999)}.txt"
# 충돌·정리 직접 관리
✓ 표준으로
import tempfile
with tempfile.NamedTemporaryFile(suffix=".txt") as f:
    ...  # 자동 정리
처방: 표준 tempfile. 경로 생성·정리·충돌 방지가 다 들어 있다. tempfile 을 썼고 수동 파일명 조합·랜덤이 없으면 성공.
증상유형이렇게 말해도AI에게 이렇게
"결과 캐싱을 직접 만든다" 즉방형 "캐시 클래스 만들어줘" · "같은 인자면 다시 계산 안 하게" · "메모이제이션 구현" 이 함수 결과를 캐싱하고 싶어. 캐시를 직접 만들지 말고 functools.cache 로 해줘.
"개수 세는 딕셔너리를 직접 만든다" 즉방형 "단어 빈도 세줘" · "몇 번 나왔는지 카운트" · "집계 딕셔너리" 이 리스트에서 각 항목이 몇 번 나오는지 세줘. 직접 딕셔너리 돌리지 말고 Counter 로.
"없는 키 기본값 처리를 직접 만든다" 즉방형 "키 없으면 빈 리스트로" · "그룹핑" · "기본값 딕셔너리" 키가 없을 때 기본값으로 처리하고 싶어. 수동 if 대신 defaultdict 나 dict.get 으로.
"상수 모음을 클래스로 직접 만든다" 즉방형 "상태값 상수 정의" · "타입 상수 클래스" · "매직 넘버 정리" 이 상태값들을 상수로 정리하고 싶어. 직접 클래스 만들지 말고 enum.Enum 으로.
"임시 파일 경로를 직접 만든다" 즉방형 "임시파일 이름 랜덤 생성" · "temp 폴더에 저장" · "충돌 안 나는 파일명" 임시 파일이 필요해. 파일명을 직접 만들지 말고 tempfile 로 안전하게.

02 한 줄이면 됨 3

즉방형

"중복 제거를 루프로 만든다"

실측 12줄 → 1줄
✗ 부풀린 코드
def dedup(items):
    seen = set()
    result = []
    for x in items:
        if x not in seen:
            seen.add(x)
            result.append(x)
    return result
✓ 표준으로
def dedup(items):
    return list(dict.fromkeys(items))
처방: 순서 유지 중복 제거는 표준 한 줄. dict.fromkeys. 한 줄이고 seen 집합 루프가 없으면 성공.
즉방형

"중첩 리스트 펴기를 재귀로 만든다"

✗ 부풀린 코드
def flatten(nested):
    result = []
    for sub in nested:
        for x in sub:
            result.append(x)
    return result
✓ 표준으로
from itertools import chain
flat = list(chain.from_iterable(nested))
처방: 한 겹이면 표준 itertools.chain 한 줄. 재귀는 진짜 깊이 모를 때만. 한 겹 평탄화면 chain 한 줄, 재귀 없으면 성공.
즉방형

"JSON 저장·로드를 클래스로 감싼다"

✗ 부풀린 코드
class JsonStore:
    def __init__(self, path): self.path = path
    def save(self, data):
        with open(self.path, 'w') as f: json.dump(data, f)
    def load(self):
        with open(self.path) as f: return json.load(f)
✓ 표준으로
import json
json.dump(data, open(path, 'w'), ensure_ascii=False, indent=2)
data = json.load(open(path))
처방: 저장·로드는 각각 한 줄. 클래스로 감쌀 게 없다. json.dump/load 직접 호출이고 래퍼 클래스가 없으면 성공.
증상유형이렇게 말해도AI에게 이렇게
"중복 제거를 루프로 만든다" 즉방형 "중복 없애줘 순서는 유지" · "unique 하게" · "겹치는 것 제거" 리스트 중복을 없애되 순서는 유지하고 싶어. 루프 말고 dict.fromkeys 한 줄로.
"중첩 리스트 펴기를 재귀로 만든다" 즉방형 "리스트 안 리스트 하나로" · "flatten" · "평탄화" 이 중첩 리스트를 한 겹 펴줘. 재귀 만들지 말고 itertools.chain 으로.
"JSON 저장·로드를 클래스로 감싼다" 즉방형 "JSON 저장 유틸" · "설정 파일 매니저" · "load/save 래퍼" 이 데이터를 JSON 파일로 저장/로드하고 싶어. 매니저 클래스 만들지 말고 json 으로 직접.

03 라이브러리 안 깔아도 됨 2

즉방형

"CSV 조금 다루는데 pandas 를 깐다"

✗ 부풀린 코드
import pandas as pd  # pip install pandas
df = pd.read_csv(path)
total = df['amount'].sum()
✓ 표준으로
import csv
total = sum(float(r['amount']) for r in csv.DictReader(open(path)))
처방: 표준 csv 모듈이면 충분하다. pandas 는 진짜 표 연산이 많을 때만. 'import csv' 이고 pandas 의존성이 없으면 성공.
분기형

"간단한 요청 하나에 무거운 클라이언트를 깐다"

✗ 부풀린 코드
import requests  # pip install requests
r = requests.get(url).json()
✓ 표준으로
import json, urllib.request
r = json.load(urllib.request.urlopen(url))
갈림길: GET/POST 몇 번, 단순 JSON / 세션·재시도·인증·풀링이 실제로 필요 단순 요청인데 새 의존성이 안 늘었으면 성공.
증상유형이렇게 말해도AI에게 이렇게
"CSV 조금 다루는데 pandas 를 깐다" 즉방형 "CSV 열 합계" · "csv 읽어서 계산" · "엑셀 데이터 처리" CSV 에서 amount 열 합계만 구하면 돼. pandas 깔지 말고 표준 csv 로.
"간단한 요청 하나에 무거운 클라이언트를 깐다" 분기형 "API 호출 라이브러리" · "http 요청 패키지" · "requests 설치" 이 API 를 호출하는데, 단순한 요청이면 표준 urllib 로 하고, 세션·재시도가 진짜 필요할 때만 라이브러리를 쓸지 먼저 알려줘.

04 안 시킨 추상화 3

분기형

"설정값 몇 개에 클래스 계층을 만든다"

✗ 부풀린 코드
class BaseConfig:
    def __init__(self): ...
class DevConfig(BaseConfig): ...
class ProdConfig(BaseConfig): ...
class ConfigFactory:
    def create(self, env): ...
✓ 표준으로
from dataclasses import dataclass

@dataclass
class Config:
    email: str = ""
    notify: bool = True
    theme: str = "light"
갈림길: 필드 몇 개, 환경 분기 없음 / 환경별(dev/prod)로 값이 실제로 갈림 dataclass 하나이고 안 시킨 상속 계층·팩토리가 없으면 성공.
분기형

"커스텀 예외 계층을 미리 만든다"

✗ 부풀린 코드
class AppError(Exception): pass
class ValidationError(AppError): pass
class NotFoundError(AppError): pass
# 아무도 종류로 분기 안 함
✓ 표준으로
raise ValueError("이메일 형식이 올바르지 않습니다")
갈림길: 그냥 '잘못된 입력'을 알리면 됨 / 호출부가 예외 종류로 분기 처리를 실제로 함 표준 예외로 됐거나, 커스텀이 실제 분기에 쓰이면 성공.
분기형

"싱글톤 패턴을 구현한다"

✗ 부풀린 코드
class DB:
    _instance = None
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
✓ 표준으로
# db.py: 모듈이 이미 싱글톤
connection = connect()  # import 하면 하나만 존재
갈림길: 그냥 하나만 있으면 되는 값·설정 / 지연 초기화·리소스 관리가 실제로 필요 모듈 전역·lru_cache 로 됐고 __new__/메타클래스 싱글톤이 없으면 성공.
증상유형이렇게 말해도AI에게 이렇게
"설정값 몇 개에 클래스 계층을 만든다" 분기형 "설정 관리 시스템" · "BaseConfig 상속" · "환경별 config 클래스" 설정값을 정리하고 싶어. 바로 만들지 말고 필드가 몇 개인지, 환경별로 갈리는지 보고 dataclass 하나로 될지 판단해서 알려줘.
"커스텀 예외 계층을 미리 만든다" 분기형 "예외 클래스 정의" · "에러 타입 계층" · "커스텀 익셉션" 여기서 에러를 던지고 싶어. 커스텀 예외 계층 만들지 말고, 표준 예외로 될지 아니면 호출부가 종류로 분기하는지 확인해서 정해줘.
"싱글톤 패턴을 구현한다" 분기형 "인스턴스 하나만" · "전역 객체" · "싱글톤 클래스" 이걸 하나만 존재하게 하고 싶어. 싱글톤 패턴 구현하지 말고, 모듈 전역이나 lru_cache 로 될지 먼저 판단해줘.

05 안 시킨 확장점 2

분기형

"안 시킨 미들웨어·훅 시스템을 판다"

✗ 부풀린 코드
class Pipeline:
    def __init__(self): self.middlewares = []
    def use(self, mw): self.middlewares.append(mw)
    def run(self, x):
        for mw in self.middlewares: x = mw(x)
        return x
# 미들웨어는 0개
✓ 표준으로
def process(x):
    return transform(x)  # 필요해지면 그때 확장
갈림길: 지금 훅이 0~1개 / 실제로 여러 곳이 끼어들어야 함이 지금 확인됨 지금 안 쓰는 확장점이 없으면 성공. 나중은 나중에.
분기형

"플러그인 로더를 미리 만든다"

✗ 부풀린 코드
import importlib, os
def load_plugins(folder):
    for f in os.listdir(folder):
        if f.endswith('.py'):
            importlib.import_module(...)  # 동적 발견
✓ 표준으로
HANDLERS = {"json": to_json, "csv": to_csv, "xml": to_xml}
result = HANDLERS[fmt](data)
갈림길: 선택지가 고정된 소수(2~5개) / 제3자가 실제로 플러그인을 추가하는 구조 고정 선택지가 딕셔너리 매핑이면 성공. 동적 스캔 없음.
증상유형이렇게 말해도AI에게 이렇게
"안 시킨 미들웨어·훅 시스템을 판다" 분기형 "확장 가능하게" · "훅 붙일 수 있게" · "플러그인 지원" 이 기능에 나중에 뭔가 끼울 수도 있는데, 지금 훅 시스템 만들지 말고 실제로 필요한 게 몇 개인지 보고 판단해줘.
"플러그인 로더를 미리 만든다" 분기형 "동적 로딩" · "플러그인 등록 시스템" · "확장 모듈 자동 발견" 동작을 이름으로 고르게 하고 싶어. 플러그인 로더 만들지 말고, 선택지가 고정이면 딕셔너리 매핑으로 될지 봐줘.
검수 리포트

AI는 시키면 다 만든다, 문제는 안 만들어도 되는 걸 만들 때다

"이거 캐싱 기능 하나 만들어줘"라고 하면 AI는 딕셔너리에 키를 넣고 꺼내는 캐시 클래스를 짓는다. 그런데 파이썬 표준에는 functools.cache 한 줄이 이미 있다. 우리가 ponytail을 재현하며 실측한 게 이거다. 게으르라고 시키자 같은 기능이 27줄에서 17줄로 줄었다.

이 사전은 그 실측을 제품으로 만든 것이다. 부풀기 쉬운 지점을 증상으로 짚는다. "캐시 클래스 만들어줘", "설정 관리 시스템 만들어줘", "플러그인 로더 만들어줘" 같은 말이 입구다. 각 항목에 무엇을 과하게 만들려는지(범인), 표준으로 되돌리는 처방, 그대로 복사해 시키는 요청 문장, 그리고 부풀린 코드와 표준 코드를 나란히 붙였다.

즉방형과 분기형: 추상화를 무조건 미워하지 않는다

이 사전의 규율은 하나다. 추상화 자체가 나쁜 게 아니라, 안 시킨·지금 안 쓰는 추상화가 부채다. 그래서 항목을 둘로 나눈다.

설정값 3개엔 dataclass 하나면 되지만, 환경별로 동작이 갈리면 계층이 정당하다. 그 경계를 판단하는 게 분기형이다.

재현 실측이 근거다

항목의 감소 수치는 지어낸 게 아니라 재현 실험에서 나왔다. 같은 주문(캐싱·재시도·중복제거)을 스킬 없이/게으름 규율 장착으로 격리 실행해 줄 수를 쟀다. 캐싱 27→17(-37%), 재시도 47→33(-30%), 중복제거 12→1. before/after 코드도 그 실측 산출물이다.

쓰는 법 세 가지

계보를 밝힌다

이 사전은 ponytail(별 136,406, MIT)의 "제일 게으른 시니어처럼" 정신에서 왔다. 그대로 옮긴 게 아니라, 철학 사다리 대신 우리 증상 사전 포맷(증상→표준 한 줄→요청 문장→실측 before/after→확인법)으로 재구현했다. ponytail 검수 리포트는 여기.