3. 학습 인사이트 — 하네스 7종의 “설계 결정과 그 이유”

비개발자 → 개발자 전직 준비생용 하네스 엔지니어링 학습 노트. “무엇을 만들었나”가 아니라 “왜 그렇게 결정했고, 무엇을 포기했나(트레이드오프)” 를 읽는 훈련용. 대상: 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 — 시작 전에 모호성을 없애라. “쇼핑몰 만들어줘”로 바로 들어가면 모델이 멋대로 가정하고 다 짠 뒤 “이게 아닌데”가 된다. 인터뷰로 모호성을 수치화해 임계값 아래로 떨어질 때까지 실행을 막는다. 앞에서 막는 게 압도적으로 싸다.
  • 원칙 4 — 컨텍스트는 예산이다. 많이 넣을수록 비싸고, 핵심이 묻히고, 캐시가 깨진다. “지연 로딩”, “매니페스트만 반환”, “1태스크=1단위 fresh 실행”으로 아낀다.
    • 비유: 회의 자료를 다 쌓기보다 안건에 필요한 한 장만 그때 꺼내는 것.
  • 원칙 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 산문코드만이 진짜 잠근다

모든 원칙은 “무언가를 얻으면 무언가를 잃는” 교환이다 — 아래에 원칙별로 “포기한 것”을 모았다.

반복 등장한 8개 트레이드오프 축

각 축은 7종이 양 극단 사이 어디쯤에 자리잡았는지를 보여준다.

flowchart LR
    L["자율·풍부·유연<br/>ouroboros, 내 패턴"] <-->|어디에 설까| R["통제·경제·강제<br/>Codex, gajae-code"]
    L -.. "자율↔안전 / 컨텍스트↔비용 / 산문↔코드강제" ..-> R
한쪽 끝 (대표)반대쪽 끝 (대표)
자율성 ↔ 안전ouroboros, 내 패턴Codex(4중·fail-closed), gajae-code
컨텍스트 ↔ 비용/지연ouroboros(30세대), OMCClaude Code(지연로딩), 내 패턴
검증 강제력 ↔ 흐름 끊김gajae-code(sha256), 내 패턴(exit 2)fable-ish(2회 후 허용), OMC(ADVISORY)
모델 중립성 ↔ 수직 통합ouroboros(9 provider), OMCCodex(OpenAI 종속), Claude Code
단일 강력 ↔ 조합 가능Codex(단일), ouroboros(926py)Claude Code(플러그인·MCP), fable-ish
표면 넓힘 ↔ 좁힘OMC(만능·라우팅 복잡)gajae-code, fable-ish
영속성 단순(파일) ↔ 강력(DB)내 패턴·Claude Code(마크다운)ouroboros(이벤트소싱·감사)
코드 강제 ↔ 산문 유연Codex(Starlark·샌드박스)내 패턴·gajae·OMC(자기인정 약점)

실제 예시

각 원칙이 7종에서 어떤 메커니즘으로 구현됐는지 — 근거(프레임워크/메커니즘)를 그대로 보존한 매핑이다. 분량이 크므로 접어 둔다.


요약 & 셀프체크

3줄 요약

  1. 네 기둥(컨텍스트·툴·가드레일·검증)의 무게중심을 어디 두느냐가 “설계 결정”이고, 그 결정은 항상 무언가를 포기하는 트레이드오프다.
  2. 가장 성숙한 하네스일수록 모델에게 맡기고 가둔다 — 자기보고 불신, 검증자 분리, 코드 강제가 핵심.
  3. “지켜지지 않으면 사고 나는 것”만 코드로 잠그고 나머지는 산문으로 — 이 균형 감각이 엔지니어의 눈이다.

스스로 답해보기

  1. 에이전트가 “테스트 다 통과했습니다”라고 보고했다. 믿지 않으려면 내 하네스에 무엇을 둬야 하나? (힌트: 원칙 1·2)
  2. “오타 하나 고쳐줘”와 “결제 모듈 새로 만들어줘”에 같은 검증을 적용하면 안 되는 이유는? (힌트: 원칙 6)
  3. 문서에 “절대 rm -rf 하지 마”라고 써두면 충분할까, 아니라면 무엇으로 막아야 하나? (힌트: 원칙 5·10)

비개발자 전직 준비생을 위한 메타 교훈 5가지

  1. “되게 만들기”보다 “됐는지 증명하기”가 어렵다. 7종 모두 검증 루프에 가장 많은 설계를 쏟았다. 입문 시에도 “내 코드가 진짜 동작하는가”를 증거로 보는 습관을. (근거: fable-ish, gajae-code, 내 패턴)
  2. LLM은 동료가 아니라 “통제할 대상”이다. 똑똑하지만 거짓 보고를 한다는 전제에서 설계가 출발한다. “이 말이 사실인지 어떻게 확인하지?”를 항상 먼저 물어라.
  3. 제약이 자유보다 강하다. 성숙한 하네스(Codex, gajae-code, 내 패턴)일수록 모델을 맡기고 가둔다. 입문자도 작은 범위를 명확히 정의해 시키는 쪽이 결과가 좋다.
  4. 회고가 설계를 만든다. 내 패턴 v2는 v1의 3대 결함(slug중복·drift·frontmatter 비대)을 진단해 다시 설계됐다. 실패를 기록하고 구조로 되먹이는 것이 진짜 엔지니어링.
  5. 솔직한 한계 명시가 신뢰다. fable-ish는 “우리는 보안 경계가 아니다”, gajae-code는 “beta/미입증”을 명시했다. 모르는 것·못 하는 것을 적는 정직함이 좋은 기술 문서의 조건.

연결

Codex 교차검증 보존

본 노트의 원칙·트레이드오프 분류와 근거 매핑은 7종 프레임워크 분석(Claude Code · Codex · oh-my-claudecode · gajae-code · ouroboros · fable-ish · 내 패턴) 결과를 종합한 것이다. 각 근거의 메커니즘(sha256 영수증, exit 2 게이트, ambiguity ≤0.2, StablePrefix, 4중 가드레일, 이벤트소싱 등)과 자기인정 약점(내 패턴의 “규율이 산문 의존”, OMC의 verify-deliverables ADVISORY 비차단, gajae-code의 “.md 계약 의존”)은 원 분석에서 검증된 사실 그대로 유지했으며, 학습 흐름으로 재구성하는 과정에서 사실을 추가·변경하지 않았다.