컨텍스트 엔지니어링: 프롬프트를 넘어 시스템을 설계하는 법
컨텍스트 엔지니어링: 프롬프트를 넘어 시스템을 설계하는 법
먼저 결론
컨텍스트 엔지니어링은 "프롬프트를 더 멋지게 쓰는 법"이 아닙니다. LLM이 지금 작업을 제대로 끝내도록, 필요한 정보만 골라서, 읽기 쉬운 형태로, 적절한 타이밍에 넣어주는 시스템 설계입니다.
프롬프트 엔지니어링이 한 번의 요청을 잘 쓰는 기술이라면, 컨텍스트 엔지니어링은 여러 번의 요청, 도구 호출, 검색 결과, 메모리, 사용자 선호, 파일, 로그, 출력 스키마를 한 흐름으로 묶는 기술입니다.
실무에서는 모델보다 컨텍스트가 먼저 흔들립니다. 정보가 부족하면 모델은 추측합니다. 정보가 너무 많으면 중요한 조건을 놓칩니다. 오래된 히스토리를 계속 넣으면 이전 결정을 현재 목표로 착각합니다. 검색 결과를 그대로 붙이면 노이즈가 답변을 오염시킵니다.
그래서 이 글은 컨텍스트 엔지니어링을 네 가지 동작으로 정리합니다.
- Write: 남겨야 할 정보를 밖에 쓴다.
- Select: 지금 필요한 정보만 고른다.
- Compress: 긴 정보를 줄이되 판단 근거는 남긴다.
- Isolate: 서로 다른 작업의 맥락을 분리한다.
이 네 가지를 설계하면 AI는 "한 번 대답하는 도구"에서 "작업을 이어서 처리하는 시스템"에 가까워집니다.
왜 이 글을 저장해야 하는가
AI 작업이 커질수록 실패 원인은 프롬프트 문장 하나가 아닙니다. 실패는 보통 아래에서 생깁니다.
| 실패 지점 | 겉으로 보이는 증상 | 실제 원인 |
|---|---|---|
| 히스토리 과다 | 답변이 장황하고 이전 이야기로 샌다 | 오래된 대화가 계속 컨텍스트에 남아 있음 |
| 검색 노이즈 | 근거가 많아 보이지만 핵심이 없다 | 관련 없는 문서까지 넣음 |
| 상태 유실 | 앞에서 정한 조건을 잊는다 | 중요한 결정이 저장되지 않음 |
| 형식 붕괴 | JSON, 표, 체크리스트가 깨진다 | 출력 스키마와 예외 규칙이 약함 |
| 작업 오염 | 글쓰기 톤이 코드 리뷰 기준과 섞인다 | 서로 다른 작업을 같은 컨텍스트에 넣음 |
OpenAI Cookbook의 세션 메모리 예제도 긴 멀티턴 에이전트에서 컨텍스트를 너무 많이 들고 가면 산만해지고, 너무 적게 보존하면 일관성을 잃는다고 설명합니다. 큰 컨텍스트 창이 있어도 정리되지 않은 히스토리, 중복 도구 결과, 노이즈 검색은 성능을 망칠 수 있습니다. 참고: OpenAI Cookbook - Context Engineering: Short-Term Memory Management
즉, 컨텍스트 엔지니어링의 목적은 많이 넣는 것이 아니라 잘 넣는 것입니다.
한 문장 정의
컨텍스트 엔지니어링은 LLM이 작업을 안정적으로 수행하도록 정보, 상태, 도구, 메모리, 출력 형식을 선택하고 배치하는 설계입니다.
조금 더 실무적으로 말하면 아래 질문에 답하는 일입니다.
- 무엇을 모델에게 보여줄 것인가
- 무엇을 모델 밖에 저장할 것인가
- 언제 다시 꺼내 넣을 것인가
- 어떤 형식으로 압축할 것인가
- 어떤 작업은 분리해서 처리할 것인가
- 결과가 맞는지 어떻게 검증할 것인가
프롬프트 엔지니어링과 다른 점
프롬프트 엔지니어링은 보통 "요청 문장"에 집중합니다.
너는 시니어 개발자야.
아래 코드를 리뷰해줘.
버그, 성능, 가독성 순서로 정리해줘.
컨텍스트 엔지니어링은 여기에 더 많은 질문을 붙입니다.
리뷰에 필요한 파일은 어떤 기준으로 고를 것인가?
전체 레포를 다 넣을 수 없다면 무엇을 압축할 것인가?
이전 리뷰에서 합의한 스타일 가이드는 어디에 저장할 것인가?
테스트 결과와 빌드 로그는 원문으로 넣을 것인가, 요약해서 넣을 것인가?
보안 관련 파일은 별도 컨텍스트로 격리할 것인가?
최종 출력은 사람이 읽는 리뷰인가, CI가 읽는 JSON인가?
프롬프트가 "이 일을 해줘"라면, 컨텍스트 엔지니어링은 "이 일을 하기 위해 필요한 작업 환경을 어떻게 구성할 것인가"입니다.
OpenAI의 하네스 엔지니어링 글에서도 에이전트가 큰 작업을 하려면 환경, 의도, 피드백 루프를 설계해야 한다고 설명합니다. 특히 레포 지식은 하나의 거대한 지시문보다 구조화된 docs/를 시스템 오브 레코드로 두고, 짧은 안내 문서는 지도처럼 쓰는 방식이 효과적이었다고 정리합니다. 참고: OpenAI - Harness engineering
1. Write: 기억할 것은 밖에 쓴다
Write는 현재 대화창 안에만 두면 사라질 정보를 외부 상태로 남기는 동작입니다. 여기서 외부 상태는 파일, DB, 벡터 저장소, 세션 메모리, 작업 로그, 사용자 프로필, 결정 기록이 될 수 있습니다.
언제 Write가 필요한가
- 사용자의 선호가 다음 작업에도 반복해서 필요할 때
- 프로젝트 규칙, 용어, 금지 사항이 계속 재사용될 때
- 긴 작업의 중간 결정이 다음 단계에 영향을 줄 때
- 에이전트가 도구를 여러 번 호출하며 상태를 이어가야 할 때
- 실패 원인을 다음 실행에서 피해야 할 때
나쁜 Write
사용자가 좋아하는 스타일: 깔끔함.
너무 추상적입니다. 다음 실행에서 어떤 행동으로 바꿔야 하는지 알 수 없습니다.
좋은 Write
user_style:
language: ko-KR
tone: 존댓말, 직접적, 과장 금지
avoid:
- "원하면 해드리겠습니다" 식의 열린 결말
- 근거 없는 칭찬
- 일반론만 나열하는 글
prefer:
- 먼저 결론
- 실제 적용 예시
- 검수 가능한 체크리스트
좋은 메모리는 모델이 다음 행동을 바꾸게 만듭니다.
OpenAI Cookbook의 장기 메모리 예제도 구조화된 사용자 프로필과 메모리 노트를 상태 객체로 관리하고, 필요한 시점에 주입하는 패턴을 보여줍니다. 중요한 포인트는 내부 시스템의 모든 필드를 덤프하지 말고, 의사결정에 도움이 되는 토큰만 넣어야 한다는 점입니다. 참고: OpenAI Cookbook - Context Personalization
Write 템플릿
[저장할 메모리 후보를 추출해줘]
입력:
아래 대화/작업 로그에서 다음 실행에도 재사용할 가치가 있는 정보만 골라라.
저장 기준:
- 사용자의 반복 선호
- 프로젝트 고유 규칙
- 이미 결정된 방향
- 다시 확인하면 시간 낭비인 사실
- 다음 실행의 품질을 바꿀 수 있는 제약
제외 기준:
- 일회성 감탄
- 임시 상태
- 이미 문서화된 일반 지식
- 개인정보나 민감 정보
- 불확실한 추정
출력 형식:
YAML 형태로 작성한다.
- memory_candidates:
- type:
- text:
- reason:
- reuse_scene:
- confidence: high|medium|low
2. Select: 지금 필요한 것만 고른다
Select는 저장된 정보 중 현재 작업에 필요한 것만 골라 컨텍스트에 넣는 동작입니다. 많은 RAG 실패가 여기서 납니다. 검색을 했다는 사실이 중요한 것이 아니라, 검색된 것 중 무엇을 넣을지 정하는 것이 중요합니다.
Select가 약할 때 생기는 문제
사용자: 이 기능의 버그 원인을 찾아줘.
시스템: 관련 있어 보이는 파일 80개, 최근 커밋 40개, 이슈 30개를 모두 넣음.
모델: 답변은 길지만 원인은 못 찾음.
컨텍스트가 많아질수록 모델은 더 똑똑해지는 것이 아니라 더 산만해질 수 있습니다.
Select 기준
| 기준 | 질문 | 예시 |
|---|---|---|
| 관련성 | 지금 질문에 직접 답하는가 | 에러 메시지가 나온 파일 |
| 최신성 | 현재 상태와 맞는가 | 최신 커밋 이후 문서 |
| 권위 | 신뢰할 수 있는 원천인가 | 공식 문서, 코드 원본 |
| 독립성 | 중복이 아닌가 | 같은 내용을 반복하는 블로그 제외 |
| 실행성 | 답변에 실제로 쓰이는가 | 설정값, 로그, 테스트 결과 |
Select 템플릿
[컨텍스트 선별자]
목표:
아래 후보 자료 중 현재 작업에 넣을 자료만 선택한다.
현재 작업:
{{task}}
후보 자료:
{{candidate_contexts}}
선택 기준:
1. 작업 해결에 직접 필요한 자료만 선택한다.
2. 같은 내용을 반복하는 자료는 가장 권위 있는 원천 1개만 남긴다.
3. 오래된 자료와 최신 자료가 충돌하면 충돌 사실을 표시한다.
4. 불확실한 자료는 "참고"로 낮은 우선순위에 둔다.
출력:
| 선택 | 자료명 | 이유 | 사용 위치 | 위험 |
|---|---|---|---|---|
3. Compress: 줄이되 판단 근거는 남긴다
Compress는 긴 정보를 짧게 만드는 동작입니다. 단순 요약과 다릅니다. 좋은 압축은 원문을 줄이면서도 의사결정에 필요한 근거, 숫자, 제약, 예외를 보존합니다.
나쁜 압축
회의에서는 일정과 디자인에 대해 논의했고, 몇 가지 수정 사항이 있었다.
이 문장은 안전해 보이지만 쓸모가 없습니다. 무엇을 언제까지 누가 해야 하는지 사라졌습니다.
좋은 압축
결정:
- 2026-04-30까지 모바일 배너 제거
- 라이트 테마에서 게시판 헤더 대비 개선
- 배포 전 관리자 테이블 색상 확인
보류:
- 콘텐츠 리팩터링은 아직 하지 않음
- DB 반영은 초안 검수 후 진행
위험:
- 기존 untracked 파일이 많아 커밋 분리 필요
좋은 압축은 나중에 작업을 이어받을 사람이 다시 실행할 수 있어야 합니다.
OpenAI Cookbook의 세션 메모리 예제는 트리밍과 요약을 구분합니다. 트리밍은 오래된 턴을 버리는 방식이라 예측 가능하고 빠르지만, 장기 조건을 잃을 수 있습니다. 요약은 긴 맥락을 유지할 수 있지만 요약 드리프트 위험이 있습니다. 그래서 중요한 사실은 구조화된 요약으로 남기고, 최근 도구 결과는 원문에 가깝게 보존하는 식의 절충이 필요합니다.
Compress 템플릿
[작업 이어받기용 압축]
아래 긴 대화/로그를 다음 작업자가 바로 이어서 실행할 수 있게 압축해라.
반드시 보존:
- 사용자의 최신 요청
- 이미 완료한 작업
- 아직 하지 않은 작업
- 파일 경로
- 명령어
- 결정된 제약
- 실패와 원인
- 다음 액션
버릴 것:
- 인사
- 반복 설명
- 감정적 표현
- 이미 해결된 추측
출력 형식:
## 현재 목표
## 완료
## 남은 작업
## 중요 제약
## 참고 경로
## 다음 명령
4. Isolate: 섞이면 망가지는 작업은 분리한다
Isolate는 서로 다른 목적의 컨텍스트를 분리하는 동작입니다. 하나의 긴 대화에 모든 것을 계속 넣으면, 모델은 어떤 기준을 우선해야 하는지 헷갈립니다.
분리해야 하는 경우
- 글쓰기와 코드 리뷰처럼 평가 기준이 다른 작업
- 의료, 금융, 법률처럼 안전 경계가 강한 작업
- 검색, 초안 작성, 편집, 배포처럼 단계별 실패 비용이 다른 작업
- 서로 다른 고객이나 프로젝트의 정보가 섞이면 안 되는 작업
- 한 작업의 임시 가정이 다른 작업의 사실처럼 쓰이면 안 되는 경우
Isolate 예시
콘텐츠 개선 작업을 한 컨텍스트에 모두 넣으면 이런 문제가 생깁니다.
리서치 자료, 초안, 편집 피드백, DB 업데이트 SQL, 배포 로그가 한 대화에 섞임.
모델이 아직 검수 전인 초안을 확정본으로 착각함.
분리하면 이렇게 됩니다.
1. research.md: 근거와 링크만 저장
2. draft.md: 독자가 읽을 본문만 작성
3. feedback.md: 편집 피드백과 수정 이유 저장
4. publish-log.md: DB 반영 여부와 배포 상태 기록
Isolate 템플릿
[작업 분리 설계]
현재 목표:
{{goal}}
섞이면 안 되는 정보:
- {{sensitive_or_noisy_context}}
작업을 아래 단위로 분리해라.
출력:
| 작업 단위 | 필요한 컨텍스트 | 제외할 컨텍스트 | 완료 기준 | 산출물 |
|---|---|---|---|---|
실무 워크플로우: 컨텍스트를 설계하는 7단계
1단계: 작업의 성공 기준을 먼저 쓴다
성공 기준:
- 독자가 바로 복사해 쓸 수 있는 템플릿 5개 이상
- 공식 문서 근거 2개 이상
- 위험한 영역은 면책과 검증 경계 포함
- DB 반영 전 검수용 초안으로 저장
성공 기준이 없으면 컨텍스트 선택도 흔들립니다.
2단계: 필요한 정보와 불필요한 정보를 나눈다
필요:
- 현재 DB 원문
- 참고 샘플 문서
- 공식 문서 링크
- 기존 사이트 톤
불필요:
- 오래된 빌드 산출물
- 중복 블로그
- 검수 전 추측
3단계: 저장할 상태를 정한다
작업이 한 번에 끝나지 않으면 상태 저장이 필요합니다.
content_rewrite_state:
current_batch:
- context-engineering-write-select-compress-isolate
- prompt-architect-master-guide
- medical-expert-agent-prompt
publish_policy: "DB 반영 전 초안 검수"
style:
- 먼저 결론
- 실무 템플릿
- 실패 사례
- 체크리스트
4단계: 검색 결과를 선별한다
공식 문서가 있으면 공식 문서를 우선합니다. 블로그는 보조 자료입니다. 의료, 금융, 법률은 기관, 논문, 공식 가이드라인 우선입니다.
5단계: 긴 자료를 압축한다
자료를 그대로 붙이지 말고, 아래 구조로 줄입니다.
문서명:
핵심 주장:
실무에 쓸 포인트:
주의할 점:
본문에 넣을 위치:
6단계: 결과물을 구조화한다
최종 글도 컨텍스트입니다. 다음 작업자가 다시 읽고 이어갈 수 있게 제목, 표, 템플릿, 체크리스트를 고정합니다.
7단계: 실행 로그를 남긴다
어떤 자료를 봤는지, 어떤 기준으로 제외했는지, 무엇을 DB에 반영했는지 남깁니다. 나중에 "왜 이렇게 썼지?"를 줄이는 것이 컨텍스트 엔지니어링의 핵심입니다.
바로 복사해서 쓰는 마스터 템플릿
너는 컨텍스트 엔지니어다.
내 목표는 {{goal}}이다.
아래 정보를 보고, LLM 작업에 넣을 컨텍스트 설계를 해줘.
[작업 목표]
{{task_goal}}
[후보 자료]
{{candidate_materials}}
[제약]
- 토큰 낭비를 줄일 것
- 최신 요청을 우선할 것
- 검수 전 초안과 확정본을 구분할 것
- 불확실한 정보는 사실처럼 쓰지 말 것
[출력]
1. 반드시 넣을 컨텍스트
2. 넣지 말아야 할 컨텍스트
3. 외부에 저장할 메모리
4. 압축이 필요한 자료
5. 분리해야 할 작업
6. 최종 프롬프트 구조
7. 실패 가능성과 방지책
결과가 이상할 때 디버깅하는 법
답변이 뻔할 때
원인: 컨텍스트에 구체적인 사례, 실패 로그, 독자 상황이 없습니다.
수정:
일반론 금지.
아래 실제 상황을 기준으로 설명해라.
- 독자:
- 현재 문제:
- 이미 시도한 방법:
- 실패한 이유:
- 결과물이 쓰일 위치:
답변이 길기만 할 때
원인: Select가 약합니다. 자료를 너무 많이 넣었습니다.
수정:
아래 자료 중 최종 답변에 실제로 인용할 5개만 남기고 나머지는 제외해라.
각 제외 이유도 한 줄로 써라.
앞에서 정한 조건을 잊을 때
원인: Write가 약합니다. 결정 사항이 상태로 저장되지 않았습니다.
수정:
지금까지 확정된 결정만 "작업 계약서"로 압축해라.
이후 답변은 이 계약서를 최우선 기준으로 삼아라.
검색 자료가 답변을 오염시킬 때
원인: 검색 결과를 검증 없이 넣었습니다.
수정:
자료를 공식 문서, 논문, 블로그, 의견 글로 분류해라.
공식 문서와 논문을 우선하고, 의견 글은 참고로만 처리해라.
작업이 서로 섞일 때
원인: Isolate가 약합니다.
수정:
리서치, 초안 작성, 편집, 배포를 별도 산출물로 분리해라.
검수 전 초안은 배포 지시로 해석하지 마라.
체크리스트
- 지금 작업의 성공 기준이 한 줄로 쓰여 있는가
- 모델이 봐야 할 정보와 보지 않아야 할 정보가 나뉘었는가
- 장기 기억으로 남길 정보가 구조화되어 있는가
- 검색 결과를 권위와 관련성 기준으로 선별했는가
- 긴 히스토리를 이어받기용 요약으로 압축했는가
- 의료, 금융, 법률, 보안 등 위험 영역은 분리했는가
- 출력 형식이 사람이 검수하거나 시스템이 파싱할 수 있는가
- 실패했을 때 무엇을 바꿔야 하는지 기록했는가
주의할 점
컨텍스트 엔지니어링은 모든 정보를 모델에게 넣는 기술이 아닙니다. 오히려 덜 넣기 위해 더 많이 설계하는 기술입니다.
가장 위험한 방식은 "혹시 모르니 다 넣자"입니다. 이 방식은 토큰 비용을 늘리고, 모델을 산만하게 만들고, 오래된 정보가 새 결정을 덮게 만듭니다.
또 하나의 위험은 요약을 사실처럼 믿는 것입니다. 요약은 압축된 해석입니다. 중요한 계약 조건, 의료 수치, 금융 데이터, 코드 diff, 에러 로그는 가능하면 원문 링크나 원문 스니펫을 함께 남겨야 합니다.