비개발자 → 개발자 전직 준비생용 하네스 엔지니어링 학습 노트.
“무엇을 만들었나”가 아니라 “왜 그렇게 결정했고, 무엇을 포기했나(트레이드오프)” 를 읽는 훈련용.
대상: Claude Code · Codex · oh-my-claudecode(OMC) · gajae-code · ouroboros · fable-ish · 내 패턴.
한 줄 요약
하네스 설계의 절반은 “똑똑하지만 거짓 보고하는 모델을 어떻게 못 믿을 것인가”를 코드로 못박는 일이다. 7종을 가로지르는 10개 원칙·8개 트레이드오프를 익히면 “기능을 더한다”가 아니라 “위험과 비용을 어디에 쓸지 고른다”는 엔지니어의 눈이 생긴다.
왜 배우나: “AI에게 다 맡기기”의 함정을 피하고 “됐는지 증명하기”를 습관으로 만드는 사고 틀을 얻기 위해.
그림
하네스의 네 기둥과, 그 위에서 7종이 서로 다른 무게중심으로 내리는 설계 결정의 흐름.
flowchart TD
M["언어모델<br/>(다음 토큰만 예측, 자기보고는 못 믿음)"]
M --> C["① 컨텍스트<br/>무엇을 보여줄지"]
M --> T["② 툴<br/>읽기·쓰기·실행"]
M --> G["③ 가드레일<br/>위험한 짓 차단"]
M --> V["④ 검증 루프<br/>진짜 됐는지 확인"]
C --> D["설계 결정<br/>= 네 기둥의 무게중심을<br/>어디에 둘 것인가"]
T --> D
G --> D
V --> D
D --> TO["트레이드오프<br/>무엇을 얻으면 무엇을 잃나"]
TO --> H["7종 하네스의 서로 다른 선택"]
flowchart LR
A["모호한 요청"] -->|① 모호성 게이트| B["명확한 작업"]
B -->|② 위험도 분류| C["작업 실행"]
C -->|"③ 컨텍스트=예산"| D["변경 산출물"]
D -->|④ 다층 가드레일| E["안전 통과"]
E -->|"⑤ 검증자=작업자 분리"| F["완료 증명<br/>(코드로 강제)"]
F -->|⑥ 세션 넘는 영속화| G["다음 세션 재주입"]
G -.같은 실수 반복 금지.-> A
쉽게 풀기
”하네스(harness)“가 뭔가
하네스 = 언어모델을 실제로 일하게 만드는 바깥 껍데기다. 모델은 “속독·암산 천재이지만 책상 밖으로 나가본 적 없는 사람”이라, 혼자서는 다음 단어만 맞힐 뿐 파일을 열거나 코드를 실행하지 못한다. 이 천재를 코딩 직원으로 바꾸려면 옆에서 ① 컨텍스트를 골라 책상에 올려주고, ② 툴을 쥐어주고, ③ 가드레일로 막고, ④ 검증 루프로 “진짜 됐는지” 확인해야 한다. 이 네 가지를 묶는 보조기구가 하네스다(말의 멍에·안전벨트 harness에서 온 말).
이 네 기둥을 누가 어떻게 짜느냐가 하네스의 정체성이고, 7종은 같은 문제를 서로 다른 무게중심으로 푼다. 그 차이가 곧 “설계 결정”이다.
모든 설계의 출발점
LLM은 똑똑하지만 거짓말(자기보고)을 한다. 그래서 좋은 하네스의 절반은 “모델을 어떻게 못 믿을 것인가”를 설계하는 일이다.
10개 원칙 — “상황 → 결정 → 이유”
외우지 말고 “나라면 어떤 트레이드오프를 고를까”를 상상하며 읽어라. 원칙들은 결국 아래 한 축으로 수렴한다 — 모델을 덜 믿고 더 가두기.
flowchart LR
subgraph 신뢰[모델을 못 믿는다]
P1["1 완료 코드강제"]
P2["2 검증자 분리"]
P10["10 코드>산문"]
end
subgraph 절약["비용·복잡도 관리"]
P4["4 컨텍스트=예산"]
P6["6 위험 비례"]
P8["8 표면 좁히기"]
end
subgraph 통제[변동성 가두기]
P3["3 모호성 게이트"]
P9["9 제한된 변환기"]
end
subgraph 축적[지식 살리기]
P5["5 다층 방어"]
P7["7 세션 영속"]
end
원칙 1 — “다 했다”는 말을 믿지 마라. 종료 시점에 검증 게이트를 놓고, 미검증이면 종료 자체를 막는다. 자기보고는 비용이 싸서 모델이 남발하니 관찰 가능한 증거(테스트 통과·diff·체크섬)만 믿는다.
비유: “다 풀었어요”라 해도 답안지로 채점하기 전엔 시험 끝을 인정 안 하는 감독관.
원칙 2 — 검증자와 작업자를 분리하라. 같은 에이전트가 짜고 스스로 승인하면 거짓 합격(false approval)이 난다. 검증을 독립 에이전트·세션·스크립트로 떼어 자기승인을 구조적으로 막는다.
비유: 출제자=채점자면 안 되는 이유. OMC는 거짓 합격 비용을 “정상 대비 10~100배”로 본다.
원칙 3 — 시작 전에 모호성을 없애라. “쇼핑몰 만들어줘”로 바로 들어가면 모델이 멋대로 가정하고 다 짠 뒤 “이게 아닌데”가 된다. 인터뷰로 모호성을 수치화해 임계값 아래로 떨어질 때까지 실행을 막는다. 앞에서 막는 게 압도적으로 싸다.
원칙 5 — 위험한 권한은 여러 겹으로 막아라. 정규식 한 줄은 우회된다(fable-ish 자체 측정: 위험 패턴 16개 중 4개만 잡힘). OS 샌드박스 + 실행 정책 + 정적 판정 + LLM 검토를 독립적으로 겹겹이 쌓아 한 겹이 뚫려도 다음이 잡게 한다(defense in depth).
원칙 6 — 안전·검증은 위험에 비례시켜라. 오타 수정에도 풀 검증을 돌리면 느려서 사용자가 하네스를 꺼버린다. quick/normal/deep/blocked로 분류해 검증 깊이를 차등한다.
원칙 7 — 상태를 세션 너머로 살려라. 결정·함정·관계를 디스크(마크다운/jsonl/SQLite/이벤트스토어)에 영속화하고 다음 세션에 재주입해 지식이 복리로 쌓이게 한다(Karpathy식 누적).
원칙 8 — 표면을 좁혀라. 스킬·모드·에이전트를 자꾸 더하면 모델이 일관되게 못 따르고 프롬프트 예산이 새고 라우팅이 복잡해진다. 의도적으로 수를 제한하고 좁은 워크플로우를 테스트로 못박는 게 낫다.
원칙 9 — 모델은 “제한된 변환기”로 써라. “알아서”라고 열어두면 매번 다른 결과(비결정성). 결정적 파이프라인의 양 끝(입력 준비·출력 검증)을 코드로 봉인하고 가운데의 LLM은 “정해진 변환”만 하게 가둔다.
비유: 요리사에게 “맛있게”가 아니라 “이 레시피대로 이 단계로”.
원칙 10 — 자동 강제와 산문 규칙을 구별하라.“런타임이 강제하지 않으면 규칙은 권고일 뿐” 이다. 정말 막아야 하는 건 훅·exit code·샌드박스로 코드 강제하고, 산문은 가이드로만.
핵심 정리
10개 원칙 한눈에
#
원칙
한 줄 핵심
1
완료를 코드로 강제
자기보고 대신 관찰 가능한 증거만 신뢰
2
검증자/작업자 분리
자기승인 금지 — 거짓 합격은 비대칭적으로 비쌈
3
모호성 게이팅
막연하면 실행 차단, 앞에서 막는 게 쌈
4
컨텍스트는 예산
풍부함보다 경제성을 1급 제약으로
5
다층 가드레일
정규식 한 겹 불신, 독립 방어선 중첩
6
위험 비례 차등
안전은 위험 있는 곳에만
7
세션 넘는 영속성
지식을 복리로 누적
8
표면 좁히기
기능 난립보다 방법론 못박기
9
제한된 변환기
비결정성을 좁은 구간에 가두기
10
코드 강제 vs 산문
코드만이 진짜 잠근다
모든 원칙은 “무언가를 얻으면 무언가를 잃는” 교환이다 — 아래에 원칙별로 “포기한 것”을 모았다.
펼쳐보기: 원칙별 "포기한 것"
1: 게이트가 빡빡할수록 안전하지만, 검증 불가능한 작업(디자인 토론 등)에서 흐름이 끊긴다. fable-ish는 “2회 차단 후 무조건 허용”으로 타협 → 대가로 deep 작업이 미검증 통과 가능.
2: 검증 에이전트를 한 번 더 돌리면 비용·지연 2배. 모든 작업에 적용하면 느리고 비싸다.
3: 게이트가 빡빡하면 “그냥 빨리 해줘”가 안 된다. 간단한 작업까지 심문당하는 마찰 → 위험도별 차등(원칙 6) 필요.
4: 아끼면 싸고 빠르지만 모델이 “전체 그림”을 못 봐 국소적 결정만. 풍부함 ↔ 비용/정밀도의 정면 교환.
5: 겹이 많을수록 안전하나 설치·디버깅·유지보수가 무거워진다(Codex 120+ 크레이트의 대가). 경량 도구(fable-ish)는 “우리는 보안 경계가 아니다”라고 솔직히 포기.
6: 분류가 휴리스틱이라 오분류 위험. “위험한데 quick으로 분류”되면 그대로 통과.
7: 파일은 단순·이식 쉬움 vs 구조화 쿼리·대규모 누적엔 약함. SQLite/이벤트소싱은 강력 vs 복잡·학습곡선·디버깅 부담.
8: 좁히면 일관·강제 쉬움 vs “이건 못 해요”가 늚. 넓히면 만능 vs 복잡도·파괴적 변경 빈발.