프롬프팅만으로 컨텍스트 분리가 가능할까? (feat. Claude Code)

황고은·2026년 2월 8일

프로프트 - Propt

목록 보기
1/1

💡 Propt 프로젝트
한 번의 프롬프팅으로 여러 개의 답변을 얻을 수 있는 AI Agent용 MCP 도구입니다.
이번 글에서는 Propt 개발 중 가장 깊게 고민했던 '배치 실행 시 컨텍스트 분리' 경험을 공유합니다.
Propt가 궁금하다면, 레포지토리를 확인해보세요!


1. 문제의 시작: "이전 답변에 영향을 받지 마세요"

Propt의 핵심 기능 중 하나는 배치 실행입니다. 예를 들어 선생님이 학생 A, B, C의 생활기록부를 작성한다고 가정해 봅시다.

우리는 보통 이렇게 기대합니다.

  • A 학생: "A는 성실하고..."
  • B 학생: "B는 창의적이고..." (A의 내용과 무관하게 B만 평가)

하지만 LLM에게 한 번의 대화로 여러 명의 평가를 요청하면 문제가 발생합니다.
LLM이 답변을 생성할 때 앞서 생성한 A 학생의 평가 내용이 B 학생 평가에 영향을 미치는 컨텍스트 오염이 발생하기 때문입니다.

"A 학생의 보고서와 달리, B 학생은..."

이런 식의 비교 표현이 나오거나, 앞선 답변의 톤앤매너를 억지로 따라가는 문제가 발생했습니다.



2. 프롬프트로 컨텍스트 분리해보기

첫 번째 시도: "독립적으로 처리해주세요"

가장 먼저 시도한 방법은 강력한 System Instruction이었습니다.
"앞의 내용을 보지 말고 독립적으로 처리해!"라고 지시하면 될 것이라 생각했습니다.

## 처리 방식
각 항목을 **독립적으로** 처리해주세요.

**핵심 원칙:**
- 각 항목은 별개의 요청으로 취급
- 항목 간 참조나 비교 없이 개별 처리
- "다른 항목과 달리" 등의 비교 표현 사용 금지

결과는 어땠을까요?
얼핏 보면 성공한 것처럼 보였습니다. 학생 평가 예시에서는 비교 문구가 사라졌거든요.

하지만 '점심 메뉴 추천' 같은 창의성이 필요한 프롬프트에서 문제가 드러났습니다.
배치 실행을 돌렸더니 "상황별로 다양하게 추천해 드립니다"라며 메뉴가 겹치지 않게 일부러 다른 메뉴를 내놓는 현상이 발생했습니다.

즉, '다양하게' 주려고 노력한다는 것 자체가 이미 앞의 답변을 참조(Context Pollution) 하고 있다는 뜻이었습니다.

두 번째 시도: 구체적 금지 조건 명시

추상적인 지시가 문제라면, 구체적으로 금지하면 어떨까? 실행 가이드 상단에 금지 조건을 명시하는 방식으로 개선했습니다.

**주의사항:**
- 다른 항목의 내용을 언급하지 않음
- "다른 항목과 달리", "앞선 내용처럼" 등의 표현 사용 금지
- 각 응답은 해당 항목만 보고 작성한 것처럼 구성

"독립적으로 처리해주세요"는 모델이 해석하기 나름이지만, "'앞선 내용처럼'이라는 표현을 쓰지 마세요"는 탈출구가 없습니다. 이 방식으로 비교 표현은 확실히 사라졌고, 대부분의 경우 독립적인 결과를 얻을 수 있었습니다.

하지만 완벽하지는 않았습니다. 점심 메뉴 추천처럼 단순한 태스크에서는 여전히 앞선 응답을 의식한 흔적이 남아 있었습니다. 프롬프트 수준의 개선으로는 근본적인 한계가 있었던 겁니다.



3. 왜 프롬프트로 분리가 안 될까? 🤔

이 현상을 이해하기 위해 LLM의 작동 원리를 다시 파고들었고, LLM은 태생적으로 컨텍스트 분리가 불가능하다는 결론에 도달했습니다.

🧠 LLM은 자기회귀적(Autoregressive) 모델이다

LLM은 다음 단어를 예측할 때 '이전의 모든 텍스트'를 근거로 삼습니다.
단일 채팅창에서 [답변 A]가 생성되는 순간, 이것은 즉시 [답변 B]를 생성하기 위한 과거의 문맥(Context)이 되어버립니다.

🦜 디코딩 전략의 한계

논문 Closing the Curious Case of Neural Text Degeneration에서는, 확률이 높은 단어를 순서대로 선택하는 탐욕적 디코딩(Greedy Decoding)이 텍스트의 반복과 퇴행을 유발한다는 점을 지적합니다. 이 문제를 완화하기 위해 샘플링 기반 디코딩을 사용하더라도, 모델이 참조하는 컨텍스트 자체는 변하지 않습니다. 즉, 디코딩 전략을 바꿔도 이전 답변이 컨텍스트에 남아있는 한 영향은 피할 수 없습니다.

결국 프롬프트로 "참조하지 마"라고 하는 것은, "코끼리는 생각하지 마"라고 말하는 것과 똑같았습니다.



4. 해결책: 물리적 컨텍스트 분리 🔑

완벽하게 컨텍스트를 분리하기 위해서는 같은 세션을 사용하는 것이 아닌, 서로 다른 세션을 사용하면서 물리적으로 컨텍스트를 분리해야만 했습니다.

첫 번째 발견: Claude Code의 Task (Subagent)

처음 발견한 것이 Claude Code의 Task 도구(Subagent)였습니다.

Claude Code 환경에서 새로운 하위 에이전트(Subagent)를 생성해 작업을 위임하는 기능으로, 각 Subagent가 독립된 컨텍스트를 가집니다.

Subagent 구조

테스트 결과, 각 실행이 서로에게 전혀 영향을 주지 않는 완벽한 격리가 확인됐습니다.

하지만 문제가 있었습니다.

Subagent는 Claude Code에서만 지원되는 기능입니다. Propt는 Claude Desktop을 포함한 다양한 AI 에이전트에서 동작해야 하는 MCP 도구이므로, Claude Code 전용 기능에 의존할 수 없었습니다.

최종 선택: Headless Mode (claude -p)

그래서 선택한 것이 Claude의 Headless Mode입니다.

claude -p '사과의 건강 효과에 대해 분석해주세요' > "batch_result_A.md"
claude -p '사과의 요리 활용법에 대해 분석해주세요' > "batch_result_B.md"
claude -p '사과의 보관 방법에 대해 분석해주세요' > "batch_result_C.md"

claude -p 호출은 완전히 독립된 프로세스로 실행됩니다. Subagent와 동일한 수준의 컨텍스트 분리를 보장하면서도, 터미널이 있는 어디서든 실행할 수 있습니다.

비용 측면에서는 API를 N번 호출하는 것과 동일하지만, 별도의 백엔드 인프라 없이 CLI만으로 실행할 수 있다는 점이 장점입니다.

Propt의 propt_prepare_batch 도구는 템플릿과 변수 세트를 받아 이 명령어들을 자동으로 생성합니다.

const commands = items.map((item) => {
  const escapedPrompt = escapeForShell(promptWithInstruction);
  const toolsOption = needsTools ? " --allowedTools 'Bash,Write,Read,Edit'" : '';
  return `claude -p '${escapedPrompt}'${toolsOption} > "batch_result_${item.id}.md"`;
});

사용자는 MCP를 통해 자연어로 요청하기만 하면, Propt가 명령어를 생성하고 실행합니다. 단, claude -p는 Claude Code CLI이므로 실행 환경에 Claude Code가 설치되어 있어야 합니다.

Subagent (Task)Headless Mode (claude -p)
컨텍스트 분리완벽완벽
Claude Desktop 지원
Claude Code 지원
결과 수집부모가 자동 수집파일로 저장

Subagent가 더 깔끔한 방식이었지만, MCP 도구로서의 범용성을 위해 Headless Mode를 선택했습니다.



5. 그럼 Propt의 가치는 무엇인가?

"그냥 Claude에서 직접 claude -p (Headless 모드) 쓰면 되는 거 아니야?"라는 의문이 들 수 있습니다.
하지만 개발자가 아닌 일반 사용자가 터미널에서 JSON 파일을 만들고 명령어를 치는 것은 쉽지 않습니다.

Propt는 이 기술적 기능을 사용자 친화적인 경험(UX)으로 포장했습니다.

기능Claude Headless 모드Propt
사용 대상개발자/파워유저일반 사용자
실행 방법터미널 명령어 직접 입력MCP 도구로 자연어 대화
템플릿 관리❌ (파일로 직접 관리)✅ 웹 UI에서 저장/관리
변수 치환❌ (수동 수정){변수} 자동 치환

기술적으로는 Claude의 기능을 활용하지만, 템플릿 관리 + 변수 자동화 + 웹 UI를 결합하여 누구나 쉽게 LLM 배치 작업을 할 수 있도록 가치를 더했습니다.



6. 마치며

이번 프로젝트를 통해 "안 되면 되게 하라"는 식의 코딩보다는, "AI 모델의 특성을 이해하고 그에 맞춰 설계하는 것"이 얼마나 중요한지 깨달았습니다.

프롬프트 엔지니어링으로 해결하려던 문제를 모델의 아키텍처적 한계로 인식하고, 적절한 도구를 찾아 해결하는 과정 자체가 큰 배움이었습니다.

혹시 LLM으로 배치 작업을 구현하면서 비슷한 고민을 하고 계신 분들께 이 글이 도움이 되길 바랍니다!



Reference

profile
영차영차 열심히 개발 공부를 하고 있습니다.

0개의 댓글