Hermes를 위한 Karpathy 가이드라인
Andrej Karpathy의 관찰에서 파생된, 일반적인 LLM 코딩 실수를 줄이기 위한 행동 지침입니다.
절충점: 이 가이드라인은 속도보다 신중함을 우선시합니다. 사소한 작업(오타 수정, 명백한 한 줄짜리 수정)의 경우 판단을 사용하세요 — 모든 변경에 전체 엄격함이 필요한 것은 아닙니다.
이 스킬을 로드해야 하는 경우
다음 경우 항상 활성화:
- 새 코드를 작성할 때
- 기존 코드를 편집할 때
- 코드를 리뷰할 때
- 코드를 리팩토링할 때
- 코드 변경을 계획할 때
다음 경우에만 건너뜁니다:
- 사용자가 명시적으로 "그냥 빨리 해"라고 말한 경우
- 순수 구성 파일(YAML, JSON, env)
- 사용자가 일회용임을 확인한 임시 프로토타입
네 가지 원칙
1. 코딩 전에 생각하기
추측하지 마세요. 혼란을 숨기지 마세요. 절충점을 표면화하세요.
무엇이든 구현하기 전에:
- 가정을 명시적으로 밝히세요. 확실하지 않으면 물어보세요.
- 해석이 여러 개인가요? 제시하세요 — 조용히 선택하지 마세요.
- 더 간단한 접근 방식이 있나요? 말하세요. 필요하면 반대 의견을 제시하세요.
- 명확하지 않은 것이 있나요? 멈추세요. 혼란스러운 점을 말하고 물어보세요.
나쁜 예:
"이제 내보내기 기능을 구현하겠습니다." [가정을 가지고 진행]
좋은 예:
"구현하기 전에 다음을 명확히 해야 합니다:
- 모든 사용자를 내보내나요, 아니면 필터링된 사용자를 내보내나요? (개인정보 보호 영향)
- 파일 다운로드, API 엔드포인트, 아니면 백그라운드 작업인가요?
- 어떤 필드인가요? 일부는 민감할 수 있습니다. 선호하는 것은 무엇인가요?"
테스트: 코드를 작성하려고 하는데 가정을 밝히지 않았다면, 잘못하고 있는 것입니다.
2. 단순함 우선
문제를 해결하는 최소한의 코드. 추측성 코드는 없습니다.
규칙:
- 요청된 것 이상의 기능은 없습니다.
- 단일 사용 코드에 대한 추상화는 없습니다.
- 요청되지 않은 "유연성" 또는 "구성 가능성"은 없습니다.
- 불가능한 시나리오에 대한 오류 처리는 없습니다.
- 200줄을 작성했는데 50줄로 가능하다면 다시 작성하세요.
스스로에게 물어보세요: "시니어 엔지니어가 이것이 너무 복잡하다고 말할까요?" 그렇다면 단순화하세요.
나쁜 예:
# 단일 할인 계산을 위한 전략 패턴, 추상 기본 클래스, 구성 시스템...
class DiscountStrategy(ABC):
@abstractmethod
def calculate(self, amount: float) -> float: pass
class PercentageDiscount(DiscountStrategy):
# 50+ 라인
좋은 예:
def calculate_discount(amount: float, percent: float) -> float:
return amount * (percent / 100)
복잡성을 추가해야 할 때: 실제로 필요할 때만 추가하세요. 요구 사항이 발생하면 나중에 리팩토링하세요.
3. 수술적 변경
반드시 필요한 것만 건드리세요. 자신의 변경으로 인한 부분만 정리하세요.
기존 코드를 편집할 때:
- 인접한 코드, 주석 또는 서식을 "개선"하지 마세요.
- 고장나지 않은 것을 리팩토링하지 마세요.
- 다르게 하고 싶더라도 기존 스타일을 따르세요.
- 관련 없는 죽은 코드를 발견하면 언급하세요 — 삭제하지 마세요.
변경으로 인해 사용하지 않는 항목이 생기면:
- 여러분의 변경으로 인해 사용되지 않게 된 import/변수/함수를 제거하세요.
- 요청받지 않은 한 기존의 죽은 코드는 제거하지 마세요.
테스트: 변경된 모든 줄은 사용자의 요청에 직접적으로 연결되어야 합니다.
나쁜 예:
- def upload_file(file_path, destination):
+ def upload_file(file_path: str, destination: str) -> bool:
+ """파일을 대상에 업로드합니다. 로깅 포함."""
+ logger.info(f"{file_path}를 {destination}에 업로드 중")
try:
- with open(file_path, 'rb') as f:
+ with open(file_path, "rb") as f:
[타입 힌트, docstring 추가, 따옴표 스타일 변경 — 요청되지 않은 사항들]
좋은 예:
+ import logging
+ logger = logging.getLogger(__name__)
+
def upload_file(file_path, destination):
+ logger.info(f'업로드 시작: {file_path}')
try:
with open(file_path, 'rb') as f:
[요청된 로깅만 추가했습니다. 기존 스타일을 따릅니다.]
4. 목표 지향 실행
성공 기준을 정의하세요. 확인될 때까지 반복하세요.
명령형 작업을 검증 가능한 목표로 변환하세요:
| 대신... | 다음과 같이 변환... |
|---|---|
| "유효성 검사 추가" | "잘못된 입력에 대한 테스트를 작성하고, 통과하도록 만드세요" |
| "버그 수정" | "버그를 재현하는 테스트를 작성하고, 통과하도록 만드세요" |
| "X 리팩토링" | "전후에 테스트가 통과하는지 확인하세요" |
| "작동하게 만들기" | "'작동'의 의미를 정의하고, 테스트를 작성하고, 확인하세요" |
여러 단계 작업의 경우 간단한 계획을 명시하세요:
1. [단계] → 확인: [검사]
2. [단계] → 확인: [검사]
3. [단계] → 확인: [검사]
강력한 성공 기준은 독립적으로 반복할 수 있게 합니다. 약한 기준 ("작동하게 만들기")은 지속적인 명확화가 필요합니다.
나쁜 예:
"인증 코드를 검토하고 개선하겠습니다." [명확한 기준 없이 변경을 진행]
좋은 예:
"인증을 수정하려면 성공 기준이 필요합니다. 문제: 비밀번호 변경 후 사용자가 로그인 상태를 유지합니다. 계획:
- 테스트 작성: 비밀번호 변경 → 이전 세션 무효화
- 수정 구현
- 테스트 통과 + 회귀 없음 확인 1단계부터 시작하겠습니다."
Hermes와의 통합
이 스킬은 다른 Hermes 스킬과 함께 작동합니다:
- [[test-driven-development]] — 원칙 4(목표 지향)와 함께 사용하세요. TDD는 검증 루프입니다.
- [[systematic-debugging]] — 원칙 1(코딩 전에 생각하기)과 함께 사용하세요. 먼저 디버깅하고, 그 다음에 수정하세요.
- [[writing-plans]] — 원칙 4와 함께 사용하세요. 여러 단계 작업에는 검증이 포함된 계획이 필요합니다.
- [[requesting-code-review]] — 리뷰 중에 네 가지 원칙 모두 적용됩니다.
안티패턴 빠른 참조
| 원칙 | 안티패턴 | 수정 방법 |
|---|---|---|
| 코딩 전에 생각하기 | 형식, 필드, 범위를 조용히 가정함 | 가정을 나열하고 명확히 질문하세요 |
| 단순함 우선 | 단일 함수에 전략 패턴 사용 | 복잡성이 필요할 때까지 하나의 함수 사용 |
| 수술적 변경 | 버그를 수정하면서 따옴표 스타일을 바꿈 | 문제를 해결하는 줄만 변경하세요 |
| 목표 지향 | "검토하고 개선하겠습니다" | "테스트 작성 → 수정 → 확인" |
핵심 통찰력
Karpathy로부터:
"LLM은 특정 목표를 달성할 때까지 반복하는 데 매우 뛰어납니다... 무엇을 할지 알려주지 말고 성공 기준을 제시하고 지켜보세요."
좋은 코드는 내일의 문제를 성급하게 해결하지 않고, 오늘의 문제를 간단하게 해결합니다.
제대로 작동하는지 확인하는 방법
다음과 같은 경우 이 가이드라인이 효과를 보고 있는 것입니다:
- diff에서 불필요한 변경이 줄어듦 — 요청된 변경만 나타납니다.
- 과도한 복잡성으로 인한 재작성 감소 — 코드가 처음부터 간단합니다.
- 구현 전에 명확성을 위한 질문 — 실수 후가 아닙니다.
- 깔끔하고 최소한의 PR — 무분별한 리팩토링이나 "개선"이 없습니다.
전체 예제
각 원칙에 대한 자세한 전후 예제는 references/EXAMPLES.md를 참조하세요.