AI 랑 잘 일하기 위한 몇가지
April 21, 2026
요즘 AI 에이전트랑 하루종일 같이 일한다.
회사 일도, 사이드 도 대부분 Claude Code 를 옆에 띄워두고 같이 진행한다.
코드 생성에만 쓰는건 아니다.
PR 리뷰, 디버깅, 리팩토링, 문서 정리까지 웬만한건 다 같이 한다.
편하긴 정말 편한데, 그냥 풀어놓으면 큰 화를 면치 못할것이다.
타입 에러를 고치라니 any 로 때려버리고,(요즘엔 거의 없다..)
실패하는 테스트를 고치라니 테스트 자체를 지워버리고,
리팩토링을 하라니 멀쩡한 로직을 잘라먹고.
최근에는 모델들이 다을 우수해서인지 이제 기초적인 실수는 안하긴 한다.
요즘은 프롬프트만 열심히 짜는 게 아니라,
이 녀석들이 일하는 환경 자체를 설계하는 데 더 많은 시간을 더 써야 하는건
누구나 알 것이다.
흔히 말하는 하네스 엔지니어링(Harness Engineering) 이다.
하네스 엔지니어링은 짧게
개념 자체는 단순하다.
AI 에이전트가 보는 컨텍스트, 쓸 수 있는 도구, 권한, 실행 흐름 같은
AI 주변의 런타임 전체를 설계하는 일이다.
프롬프트가 무엇을 시킬지 라면, 하네스는 어디서 어떻게 일하게 할지 에 가깝다.
개념 설명보다 내가 실제로 뭘 해보고 어떻게 좋아졌는지가 더 쓸모 있을 것 같다.
최근 작업 중인 사이드 프로젝트에서 이렇게 세팅했더니 체감이 꽤 좋았다.
docs/ 와 .agent/ 를 연결하기
프로젝트 루트에 문서와 에이전트 설정을 따로 두었다.
docs/— 기능별 명세, 가이드라인, 테스트 전략 등 사람이 읽는 문서docs/HARNESS.md— 기능 ↔ 문서 ↔ 코드 매핑표 (진입점)docs/features/*.md— 기능별 상세 (관련 파일, DB 스키마, 로직, 테스트).agent/— 에이전트 전용 지침 (rules, skills, workflows, pipeline).claude/— Claude Code 전용 설정 (rules, skills)CLAUDE.md— 루트 진입점. 위 문서들로 가는 포인터만 얕게 둔다
핵심은 CLAUDE.md 를 얕게 유지 하는 부분이다.
기능 작업 전 반드시 docs/features/<feature>.md 를 먼저 읽어라 정도의 라우팅 지침만 넣고,
실제 도메인 지식은 docs/features/ 쪽에 분산시켜 두었다.
처음부터 모든 문서를 컨텍스트에 박지 않고, 필요할 때 해당 문서만 읽어오게 하는 방식이다.
이건 Anthropic 이 말하는
Just-in-time context loading 과 같은 개념인데,
직접 해보니 컨텍스트 낭비가 확연히 줄기는 줄어든 것 같다.
아마도…🤔
Skill / Subagent 로 역할 분리
전역 CLAUDE.md 에 모든 규칙을 다 때려넣는 대신,
역할이 명확한 작업은 슬래시 커맨드(.claude/skills/) 로 분리했다.
| Skill | 용도 |
|---|---|
/git-push |
커밋 컨벤션 + 푸시 절차 |
/i18n |
다국어 (ko.json / en.json 동시 업데이트) |
/tdd |
테스트 주도 개발 루프 |
/pipeline |
Plan → Execute → Verify 3-Agent 자동화 |
/pr-analyzer |
PR 리뷰 체크리스트 |
이 외에 추가적인 많은 기능들 등등.
이렇게 분리해두면 해당 작업을 할 때만 관련 지침이 컨텍스트에 로드된다.
i18n 작업 중에 DB 마이그레이션 규칙을 컨텍스트에 들고 있을 이유가 없기 때문이다
Hook 으로 자동 검증
커밋 직전과 세션 종료 시 자동으로
tsc --noEmit, eslint, test 를 돌리도록 hook 을 걸어두었다.
AI 가 테스트 통과했습니다 라고 말하는 걸 곧이곧대로 믿지 않기 위함이다.
통과했다 는 주장과 실제 통과 여부가 꽤 자주 어긋난다.
요즘들어 더 심해진듯? 🤔
이렇게 세팅한 뒤로, 세션 하나에 매번 반복해서 넣어야 하는 맥락이 확실히 줄었다.
내가 같은 주의사항을 말해주는 일도 줄었고,
이 기능 건드릴때 어떤 파일 봐야 해? 같은 예비 질문도 거의 사라졌다.
컨텍스트가 8할이다
하네스를 아무리 잘 설계해도 결국 AI 가 보는 건 컨텍스트다.
여기가 망가지면 다른건 의미가 없다.
처음엔 Claude 의 윈도우가 200k, 1M 까지 나왔으니
웬만하면 꽉 채워 써도 괜찮을 거라고 생각했다.
현실은 정반대였다.
왜 길어질수록 품질이 떨어지는가
Stanford 의 Lost in the Middle (Liu et al., 2023) 은
20개 문서(약 4,000 토큰) 만 넣어도 답변 정확도가
70~75% 에서 55~60% 로 떨어진다는 걸 실험으로 보였다.
생각보다 훅 떨어진다. 🙃
정답이 컨텍스트 맨 앞이나 맨 뒤에 있을 때 정확도가 가장 높고,
중간으로 갈수록 놓치는 U 자 커브 가 관찰된다.
원인은 단순히 토큰 수 초과 가 아니다.
Attention 가중치가 전체 컨텍스트에 분산되기 때문에,
입력이 길어질수록 특정 위치의 정보에 집중하기 어려워진다.
용량의 문제가 아니라 구조적인 한계에 가깝다.
결국 얘네도 집중력 총량이 정해져 있는 셈이다.
사람이랑 똑같네…
Chroma 의 2025년 Context Rot 연구는 이걸 더 넓게 보여준다.
GPT-4.1, Claude 4, Gemini 2.5, Qwen3 등 18개 프런티어 모델을 테스트했는데,
단순 retrieval 이나 텍스트 복제 같은 기초 과제에서도
입력 토큰이 길어질수록 예외 없이 성능이 떨어졌다.
잘난 모델들 다 모아놨는데 하나같이 긴 컨텍스트 앞에서는 헤매더라는 얘기. 🤡
쿼리와 정답의 의미적 유사도가 낮을수록 하락 속도가 더 가팔라진다.
요약하면, 긴 컨텍스트 윈도우가 있다는 것과
그 길이만큼 품질이 유지된다는건 다른 얘기다.
실제 제품에서는 한참 전에 품질이 깎여 나가기 시작한다.
머리는 좋은데 건망증이 심한 친구랄까? 🙃 좀 이상한데..
내 기준선
Claude Code 에서는 대략 이렇게 쓰고 있다.
- Opus 4.7 (기본 200k) — 컨텍스트
20 ~ 30%사이에서/clear - Opus 4.7 1M —
10%넘기기 전에/clear
숫자 자체보다 중요한 건 꽉 차기 전에 비운다 쪽이다.
위 연구들이 시사하는 건 한계치 근처에서 버티면 품질이 이미 깎이고 있다 이기 때문에
여유있게 끊어주는게 결과적으로 더 낫다.
클리어 하기 직전에는 중요한 결정이나 맥락을
CLAUDE.md, memory, handoff 파일로 내려두고,
다음 세션에서 필요한 것만 다시 읽게 한다.
Anthropic 공식 가이드도
unrelated task 사이에는 공격적으로 /clear 를 써라 를 권장한다.
한 세션에 무관한 주제 여러개를 이어가면 누적된 오해가 이후 판단을 흐리게 된다.
기능은 잘게 쪼개서 시키자
이건 사람한테 일 시킬 때랑 똑같은 얘기다.
한번에 10개를 다 해달라고 하면 반드시 어딘가는 부실하다.
나는 보통 이런 단위로 쪼개서 세션을 구분한다.
- 도메인 모델 / 타입
- 데이터 레이어 (DB, API, Resolver)
- 비즈니스 로직 / Service
- UI 컴포넌트
- 테스트
한 세션 한 관심사 정도로 유지하면 컨텍스트도 가볍고,
중간에 방향이 틀어졌을 때 되돌리기도 쉽다.
덤으로 내가 뇌를 비우고 🤡 AI 에 끌려다니는 것도 방지된다.
여러 AI 로 크로스 체크
Claude 하나에만 의존하지 않는 것도 같은 맥락이다.
설계, 리뷰, 리팩토링은 Claude 위주로 쓰고,
최신 문서나 레퍼런스 조사는 Gemini, 다른 관점이 필요할때는 ChatGPT 를 섞는다.
이게 왜 효과가 있는지도 최근 연구들이 설명해준다.
Self-consistency 는 같은 모델의 여러 샘플을 모아 다수결을 내는 기법인데,
Complementing Self-Consistency with Cross-Model Disagreement 는
이 방식의 한계를 지적한다.
모델이 틀린 답에 과도한 확신을 가지는 경우,
같은 모델을 여러 번 샘플링해도 똑같이 틀린 답이 반복된다.
자기 의심이 없는 모델의 다수결은 틀린 방향을 강화할 뿐이다.
목소리 큰 애들 여럿 모아봐야 틀린건 여전히 틀리다는 얘기다. 🤡
반면 서로 다른 학습 데이터와 구조를 가진 모델들에게 같은 질문을 던지면,
한쪽이 overconfident 하게 틀리는 경우에도 다른 쪽이 불일치를 보일 가능성이 높다.
이 cross-model disagreement 가 여기 뭔가 이상하다 는 신호가 된다.
불확실성을 정량화하는 지표로도 self-consistency 단독보다 더 잘 작동한다는게 해당 연구의 요지다.
실제로 써보면 서로의 약점을 신기할 정도로 잘 잡아낸다.
Claude 가 놓친 엣지 케이스를 Gemini 가 짚어주고,
Gemini 가 어색하게 쓴 타입 정의를 Claude 가 다듬는 식이다.
은근히 싸움 붙여놓는 재미도 있다. 🤔
한 모델의 편향을 덜 받는 것만으로도 의사 결정 품질이 눈에 띄게 올라간다.
중요한 설계 결정이나 보안 판단은 한 녀석에게만 맡기지 않는 쪽이 안전하다.
세션을 역할별로 나누기 — Plan / Execute / Verify
크로스 체크와 비슷한 아이디어를 한 모델 안에서 적용한 게
요즘 쓰고 있는 3-Agent 파이프라인이다.
- Plan Agent — 요구사항 분석, 코드베이스 조사, 계획 수립. 코드 수정 금지
- Execute Agent —
plan.md에 적힌 대로만 구현. 계획에 없는건 하지 않음 - Verify Agent — 테스트, 타입체크, 린트, 리뷰. 코드 수정 금지
세 에이전트는 각각 다른 세션(채팅) 에서 돌고,
handoff/ 폴더의 파일을 통해서만 소통한다.
내 프로젝트에서는 이런 식으로 배치돼 있다.
.claude/skills/pipeline/
├── SKILL.md
├── agents/
│ ├── planner.md
│ ├── executor.md
│ └── verifier.md
└── handoff/
├── plan.md
├── execution-log.md
└── verification.md
각 에이전트 지침에는 역할 제한을 명확히 박아둔다.
## 역할 제한 (Plan Agent Boundaries)
- 코드 수정 금지: `.ts`, `.tsx`, `.css`, `.json` 등
- 상태를 변경하는 명령 실행 금지 (`pnpm`, `git commit` 등)
- 허용: 파일 읽기, 디렉토리 탐색, 웹 검색, handoff 파일 작성
Verify 쪽도 비슷하게 문제를 발견해도 코드를 고치지 말고 verification 파일에만 적어라 를 강제한다.
재시도 루프가 돌 때 Plan 이 이 verification 파일을 읽고 계획을 새로 세운다.
장점
- 관심사가 분리된다. Plan 이 계획만 세우다 신나서 구현까지 해버리는 사고가 안 생긴다.
- 검증이 독립적이다. 같은 AI 가 짜고 검증하면 자기 코드에 관대해진다.
세션이 분리되면 컨텍스트가 깨끗한 상태에서 리뷰하게 된다.
앞서 말한 cross-model disagreement 의 단일 모델 버전이라고 봐도 된다. - 컨텍스트가 작게 유지된다. 각 세션은 자기 역할에 필요한 handoff 파일만 로드한다.
- 재시도 루프가 깔끔하다. Verify 가 FAIL 이면 해당
verification.md를 들고 Plan 을 다시 세우면 된다.
단점
- 오버헤드가 크다. 세션을 여러 개 띄워야 하고, handoff 파일 관리가 필요하다.
- 작은 작업엔 과하다. 오타 하나 고치려고 Plan / Execute / Verify 를 다 돌릴 이유는 없다.
- 핸드오프 품질이 곧 결과 품질이다.
plan.md가 부실하면 Execute 가 엉뚱한 걸 만든다.
결국문서로 정확히 소통하는 능력이 이 방식의 병목이다. - 완전 자동은 아니다. Plan 승인, Verify 결과 판단은 결국 사람이 한다.
설계 결정이 중요한 작업, 리팩토링, 기능 추가처럼
적당히 큰 단위에서 이 방식이 빛을 발한다.
버그 픽스나 스타일 수정 같은 단발성 작업은 한 세션에서 처리하는 편이 빠르다.
정리
정리하면 요즘 지키려는 규칙은 이렇다.
- 프롬프트 만큼 하네스(문서 배치, skill 분리, hook) 에도 시간을 쓴다
- CLAUDE.md 는 얕게, 실제 지식은
docs/features/로 밀어내 필요할때만 로드한다 - 컨텍스트는 꽉 채우지 않는다.
/clear에 인색하지 말자 - 기능은 잘게 쪼개고, 한 세션 한 관심사로 유지한다
- 같은 질문을 여러 모델에게 던져 cross-model disagreement 를 신호로 쓴다
- 큰 작업은 Plan / Execute / Verify 로 세션을 분리하고 handoff 파일로 묶는다
완벽한 방법은 당연히 아니다.
계속 써보고 바꾸고 있다.
결과물이 눈에 띄게 안정적인건 확실하다.
애초에 개발자라면 바이브 코딩을 하면 할수록 이거 해줘 만으로는
어림도 없다는걸 알게 된다.
초기에도 그랬고 현재까지도 그렇다.
미래는 모르겠다.
Anthropic 의 Mythos? 어마 무시해서 일반인에게 공개를 안한다고 하는데
저런 공포 마케팅을 너무 많이 봐서 아직은 믿음이 안간다..
Anthropic IPO 가 얼마 안남기도 했고. 🤡
쨌든 AI 를 잘 쓰는 일이 결국 AI 를 어떻게 가둬둘 것인가의 문제라는게
써볼수록 점점 더 명확해진다. 🥹