Harness vs context engineering: 하네스 엔지니어링은 prompt 및 context engineering과 어떻게 다른가
Prompt engineering은 하나의 요청을 다듬고, context engineering은 매 단계에서 모델의 창에 어떤 정보가 들어갈지 정하며, harness engineering은 지침, 도구, 환경, 상태, 피드백까지 포함한 에이전트 주변 전체를 설계합니다. 앞의 두 가지는 모델 호출 하나 안에서 작동하고, harness는 시스템 전체와 긴 작업에 적용되며 여기서 목표는 답이 아니라 검증된 결과입니다.
요약: 같은 작업의 세 가지 계층
Prompt engineering은 "어떻게 물을까"에, context engineering은 "모델은 지금 무엇을 알아야 하나"에, harness engineering은 "에이전트는 어떤 환경에서 일하고 자신이 틀렸다는 것을 어떻게 아는가"에 답합니다. 이들은 서로 경쟁하는 접근법이 아니라 중첩된 계층입니다. 좋은 프롬프트는 좋은 context의 일부이고, 신중하게 짜인 context는 harness의 구성 요소 중 하나입니다.
혼동이 생기는 이유는 셋 모두 모델의 행동을 바꾸지만, 지렛대가 다르기 때문입니다. 에이전트가 테스트를 실행할 수 없다면 프롬프트의 어떤 문장도 그것을 고치지 못합니다. 에이전트가 어제의 결정을 잊는다면 문제는 요청의 문장이 아니라 상태가 어디에 저장되는가에 있습니다. harness vs context engineering의 차이를 이해하면 몇 주를 아낄 수 있습니다. 환경이 망가졌을 때 지침을 다시 쓰지 않게 되기 때문입니다.
Prompt engineering: 한 요청의 표현
Prompt engineering은 요청 텍스트에 대한 작업입니다: 역할, 과제, 응답 형식, 예시(few-shot), 제약, 단계의 순서. 작업 단위는 모델 호출 하나입니다. 결과는 응답으로 평가합니다: 맞는가, 올바른 형식인가, 모델이 엇나갔는가?
일반적인 기법:
- 출력 형식을 명확히 설명하기(JSON 스키마, 표, 목록);
- 2~3개의 예시 제공하기: "입력 → 올바른 출력";
- 답하기 전에 단계별로 추론하도록 요청하기;
- 지침과 데이터를 명확한 구분자로 나누기;
- 하지 말아야 할 것을 나열하기.
Prompt engineering은 "입력 하나 — 응답 하나" 유형의 작업에 잘 맞습니다: 분류, 정보 추출, 번역, 템플릿에 따른 텍스트 생성. 한계는 모델이 행동하기 시작할 때 드러납니다: 도구를 호출하고, 파일을 바꾸고, 수십 단계를 연달아 수행할 때. 그때 품질은 한 문장이 아니라 모델을 둘러싼 환경 전체에 달려 있습니다.
Context engineering: 모델 창에 무엇이 들어가는가
Context engineering은 매 단계마다 context 창의 내용을 관리하는 일입니다. 창은 제한되어 있고, 긴 세션에서 에이전트는 명령 출력, 파일 내용, 대화 기록을 쌓아 갑니다. 목표는 필요한 것이 항상 거기 있고 불필요한 것은 없게 하는 것입니다.
여기에 포함되는 것:
- 선택: 작업에 따라 어떤 파일, 문서, 코드 조각을 불러올지 (검색, RAG, 필요할 때 읽기);
- 압축: 긴 기록의 요약, 명령 출력 자르기, 세션 compaction;
- 구조: 진입 파일은 목차처럼, 세부 내용은 에이전트가 필요할 때 여는 별도 문서에;
- 격리: 곁가지 작업을 깨끗한 context를 가진 subagent에 맡겨 주 흐름이 오염되지 않게 하기.
Context engineering의 측정 기준은 이것입니다: 에이전트가 올바른 규칙이나 사실을 적시에 찾았는가, 아니면 잡음에 빠졌는가? 전형적인 증상: 규칙이 CLAUDE.md에 적혀 있지만 에이전트가 어기는 경우. 파일이 다섯 페이지이고 규칙이 나머지 내용 속에 묻혀 버렸기 때문입니다.
Harness engineering: 모델 주변의 모든 것
Harness("마구")는 에이전트가 일하는 환경입니다. 모델은 이 안에서 순환에 한 번 들어가는 하나의 구성 요소입니다. 나머지 모든 것, 즉 지침, 도구, 환경, 상태, 피드백은 엔지니어가 설계합니다. Harness engineering은 에이전트가 코드를 쓰기만 하는 것이 아니라 실행하고, 검사하고, 자신의 실수를 알고, 다음 세션에서 멈춘 자리에서 이어 가도록 보장합니다.
하네스를 다섯 구성 요소로 나누면 유용합니다:
| 구성 요소 | 포함 내용 | 고장의 신호 |
|---|---|---|
| 지침 | AGENTS.md / CLAUDE.md, skills, 문서, ADR | "모두가 아는" 관례를 어김 |
| 도구 | shell, 테스트, linter, 디버거, 브라우저, MCP 서버 | 에이전트가 "하고 싶은데 못 한다": 필요한 명령에 접근 불가 |
| 환경 | 의존성 잠금 파일, 런타임 버전, Docker/devcontainer, git worktree, sandbox | 매 세션이 환경을 고치는 데서 시작 |
| 상태 | PROGRESS.md, feature_list.json, DECISIONS.md, git 기록 | 새 세션이 어디서 멈췄는지 모름 |
| 피드백 | make check, E2E 테스트, hooks, 루브릭, 독립 평가자 | "완료"와 현실이 일치하지 않음 |
이 그림에서 context engineering은 처음 두 구성 요소 안에 살고 있습니다: 지침과 도구 출력이 창에 어떻게 들어오는지를 정합니다. 하네스는 context에 담을 수 없는 것을 추가합니다: 작동하는 검사 명령, 재현 가능한 환경, 재시작을 견디는 상태 파일.
비교표
| 기준 | Prompt engineering | Context engineering | Harness engineering |
|---|---|---|---|
| 작업 단위 | 하나의 요청 | 매 단계의 모델 창 | 전체 시스템: 에이전트, 저장소, 환경, 프로세스 |
| 무엇을 바꾸나 | 요청 텍스트 | 창 안 정보의 구성과 순서 | 도구, 환경, 상태 저장, 검사 |
| 시간 범위 | 초 단위 | 한 세션 | 여러 세션, 몇 시간과 며칠 |
| 무엇을 측정하나 | 응답의 품질 | 에이전트가 필요한 것을 찾았는가, 창이 넘치지 않았는가 | 실제로 작동 상태까지 도달한 작업의 비율; "완료"와 검증 사이의 차이 |
| 전형적인 산출물 | 시스템 프롬프트, 예시 | 문서 구조, RAG, compaction, subagent | AGENTS.md, 검사 스크립트, hooks, Docker, feature_list.json, PROGRESS.md |
| 결과는 누가 검사하나 | 사람이 응답을 읽음 | 사람 또는 모델 | 기계: 테스트, linter, E2E, 독립 평가자 |
| 언제 한계에 부딪히나 | 모델이 행동하기 시작할 때 | 에이전트에게 지식이 아니라 능력이 부족할 때 | 작업에 사람의 결정(제품, 위험)이 필요할 때 |
프롬프트와 context만으로 부족한 이유
고전적인 이야기: 팀은 에이전트가 실수하는 것을 보고 일주일 동안 다섯 페이지짜리 AGENTS.md를 씁니다. 그래도 에이전트는 커밋 전에 linter를 실행하지 않습니다. 원인은 텍스트에 없습니다. 에이전트에게 올바른 권한의 shell이 없고, linter가 이미지에 설치되어 있지 않은 것입니다. 이것은 도구와 환경의 문제였는데, 지침으로 해결하려 한 것입니다.
두 번째 이야기: 에이전트는 재시작 후 이전에 무엇을 시도했는지 기억하지 못해서, 세 번째 세션 연속으로 같은 버그를 고치려 합니다. 세션 안의 context engineering은 여기서 도움이 되지 않습니다. 창이 비워지기 때문입니다. 필요한 것은 상태 구성 요소입니다: 에이전트가 시도와 결정을 적는 파일, 그리고 작업을 시작하기 전에 그것을 읽으라는 규칙.
세 번째 이야기가 가장 비쌉니다: 에이전트는 "완료"라고 쓰고, 단위 테스트는 초록색이지만 기능은 작동하지 않습니다. "주의 깊게 검사해"라는 프롬프트도, 창에 문서를 더 넣는 것도 에이전트에게 독립적인 검사를 주지 못합니다. 그것을 줄 수 있는 것은 기계의 피드백뿐입니다: 엔드투엔드 테스트, 검증 스크립트, 또는 작업자의 추론을 보지 않는 별도의 평가자.
일반적인 결론: 프롬프트와 context는 모델이 무엇을 생각하는지에 영향을 줍니다. 하네스는 모델이 무엇을 할 수 있는지, 그리고 행동 후에 무엇을 알게 되는지에 영향을 줍니다.
모델을 바꾸는 것이 해답이 아닌 이유
불안정한 에이전트에 대한 흔한 반응은 더 강력한 모델을 쓰는 것입니다. 보통 이것으로는 문제가 해결되지 않습니다. 같은 모델이 잘 짜인 저장소에서는 노련한 시니어처럼 일하지만, 검사 명령과 스택 설명이 없는 저장소에서는 헤맵니다. 더 강력한 모델이라고 해서 팀의 관례를 저절로 알지 못하고, 접근 권한이 없는 데이터베이스에 접근하지 못하며, 아무도 실행하지 않은 깨진 migration을 알아차리지도 못합니다.
하네스는 새 모델이 나왔다고 쓸모없어지지 않습니다. 지침, 재현 가능한 환경, 검사는 모든 모델에 필요합니다. 달라지는 것은 얼마나 많은 수작업 지시가 필요한지뿐입니다. 강력한 모델에게는 불변 조건이면 충분합니다("데이터는 도메인 경계에서 검증한다"), 단계별 지시는 필요 없습니다.
어느 계층을 고쳐야 하는지 알아보는 법
실험보다 증상으로 진단하는 것이 더 빠릅니다:
| 증상 | 문제가 있는 곳 | 무엇을 할까 |
|---|---|---|
| 응답 형식이 틀리고 모델이 과제를 이해하지 못함 | Prompt | 형식을 명확히 하고 예시를 추가 |
| 규칙은 적혀 있지만 에이전트가 적용하지 않음 | Context / 지침 | 진입 파일을 목차 수준으로 줄이고, 세부 내용은 필요할 때 여는 문서로 옮기고, 핵심 규칙을 검사로 바꾸기 |
| 세션 중간에 에이전트가 초기 결정을 "잊음" | Context | compaction, 곁가지 작업용 subagent, 상태 파일에 기록 |
| 에이전트가 "실행할 수 없다"고 말함 | 도구 | 명령 접근 권한, MCP 서버, 권한 설정 |
| 세션이 의존성 설치와 환경 수리로 시작됨 | 환경 | 잠금 파일, Docker/devcontainer, init.sh 스크립트 |
| 새 세션이 어제 무엇을 했는지 다시 묻는다 | 상태 | PROGRESS.md, 상태가 있는 기능 목록, 체크포인트 커밋 |
| "완료"인데 기능이 작동하지 않음 | 피드백 | E2E, Definition of Done, 검증 스크립트, 독립 평가자 |
하네스는 어디서부터 시작할까
처음부터 구축한다면 실용적인 순서는 이렇습니다: 피드백 → 지침 → 상태 → 환경 → 도구. 피드백이 먼저인 이유는, 그것 없이는 다른 변경의 효과를 측정할 수 없기 때문입니다. "작동하는지 아닌지"를 정직하게 답해 주는 명령이 없다면, 지침의 모든 개선은 눈대중으로 평가하게 됩니다.
최소한의 시작은 대략 다음과 같습니다:
# AGENTS.md (일부)
## 검증 방법
- make check # lint, 타입, 단위 테스트
- make e2e # 엔드투엔드 시나리오
기능은 두 명령이 모두 코드 0으로 끝났을 때만 완료다.
## 규칙
- MUST: 모든 SQL 쿼리는 매개변수화한다
- MUST: 커밋 전에 make check를 실행한다
- 결제 세부 사항: docs/payments.md (작업이 결제와 관련될 때 읽는다)
마지막 줄에 주목하세요: 이것이 하네스 안의 context engineering입니다. 진입 파일은 교과서가 아니라 지도이며, 세부 내용은 "언제"라는 조건에 따라 불러옵니다.
각 구성 요소의 기여도 측정하기
하네스에는 프롬프트에는 없는 지표가 있습니다: 에이전트가 "완료"라고 했지만 독립 검사가 확인하지 못한 작업의 비율. 이를 verification gap이라고 합니다. 최근 10개 작업을 골라, 각각에 대해 에이전트가 "완료"라고 했는지, 검사를 통과했는지 기록하세요. 나온 비율이 변경 사항을 비교할 기준선이 됩니다.
어떤 구성 요소가 효과를 내는지 알아보려면 ablation 방법을 씁니다: 모델과 작업 세트는 고정하고, 구성 요소를 하나씩 끄면서 하락을 봅니다. 두 가지를 기억하세요. ablation보다 먼저 실패 기록을 만드세요. 병목을 더 빨리 보여 줍니다. 그리고 하락이 0이라고 해서 구성 요소가 쓸모없는 것은 아닙니다. 선택한 작업들이 그것을 쓰지 않았을 수 있습니다.
흔한 실수
- 프롬프트 파일을 하네스로 착각하기. 지침은 다섯 구성 요소 중 하나입니다. 레시피 선반이 있다고 주방이 되는 것은 아닙니다.
- 도구 부재를 텍스트로 해결하기. 에이전트 환경에서 테스트가 실행되지 않는데 "항상 테스트를 실행하라"고 쓰는 것은 소용없습니다.
- 지침을 부풀리기. 파일이 길수록 중요한 규칙이 읽히지 않을 확률이 높아집니다. 중요한 규칙은 실행 가능한 검사로 바꾸세요.
- 에이전트의 자체 보고를 믿기. 자신의 작업을 평가하는 모델은 결과를 좋게 보이게 하는 경향이 있습니다. 검사는 스크립트나 깨끗한 context의 별도 에이전트가 해야 합니다.
- 하네스를 한 번 만들고 방치하기. 코드처럼 낡아 갑니다: 규칙이 현실에서 벗어나고, 명령이 바뀝니다. 정기적으로 검토해야 합니다.
마무리
Prompt engineering은 요청의 표현을 다듬고, context engineering은 모델 창의 정보를 고르고, harness engineering은 도구, 환경, 상태, 검사를 포함한 에이전트의 전체 환경을 설계합니다. 에이전트가 오래 일하며 스스로 코드를 바꿀 때 하네스가 결정적이 됩니다. "에이전트가 완료라고 했다"를 "시스템이 작동함을 확인했다"로 바꿔 주기 때문입니다. 따라서 harness vs context engineering은 "둘 중 하나"의 문제가 아닙니다. context는 하네스의 일부이고, 증상이 가리키는 계층을 고쳐야 합니다. 이 주제는 결제 백엔드 프로젝트를 중심으로 한 실습 과정에서 다룹니다.
자주 묻는 질문
하네스 엔지니어링이 prompt engineering을 대체하나요?
아니요, 포함합니다. 지침의 표현은 여전히 중요하지만, 그것은 도구, 환경, 상태, 피드백과 함께 있는 다섯 구성 요소 중 하나일 뿐입니다.
작은 수정에만 에이전트를 쓴다면 하네스가 필요한가요?
최소한의 하네스는 항상 필요합니다. 스택과 검사 명령이 적힌 지침 파일이 그것입니다. 기능 목록과 평가자까지 갖춘 전체 세트는 긴 작업과 팀에서 빛을 발합니다.
context engineering과 RAG는 어떻게 다른가요?
RAG는 context engineering의 한 기법입니다: 관련 조각을 찾아 불러오는 것. Context engineering은 더 넓어서, 기록 압축, 문서 구조, subagent에서의 하위 작업 격리까지 포함합니다.
하네스에서 무엇을 가장 먼저 만들어야 하나요?
피드백입니다. 결과가 작동하는지 기계가 알려 주는 명령 말이죠. 이것이 없으면 다른 개선의 효과를 측정할 수 없습니다.
이 접근법은 Claude Code에만 적용되나요?
아닙니다. 원칙은 일반적입니다: AGENTS.md는 여러 에이전트가 읽고, 검사 스크립트, Docker, 상태 파일, E2E 테스트는 특정 도구에 묶여 있지 않습니다.
이 주제는 “Harness Engineering: инженерия надёжности AI-агентов” 강의에서 실습과 함께 자세히 다룹니다.
- Что такое harness engineering: почему AI-агент ломается из-за среды, а не модели
- Из чего состоит harness AI-агента: инструкции, инструменты, среда, состояние, обратная связь