4.4 시스템 프롬프트(System Prompt)를 이용한 페르소나 및 규칙 고정
거대 언어 모델(LLM) 기반의 애플리케이션을 구축할 때 마주하는 가장 까다로운 난관은, 외부에서 주입되는 예측 불가능한 사용자 프롬프트(User Prompt)가 모델의 행동 지침을 우회하거나 파괴하는 현상(Prompt Injection)이다.
결정론적 오라클(Deterministic Oracle) 테스트 파이프라인에서 입력값의 변동성에 따라 응답 포맷이 갈대처럼 흔들리는 시스템은 치명적이다. 본 절에서는 이러한 혼돈을 제어하고 모델의 출력 위상(Topology)을 컴크리트처럼 단단하게 굳혀버리는 절대 구역, 즉 ’시스템 프롬프트(System Prompt)’의 공학적 설계와 규칙 고정 전략을 탐구한다.
1. 권력의 비대칭성: 시스템 프롬프트의 최상위 계층 설계
모던 LLM API(예: OpenAI의 Chat Completions API) 아키텍처는 메시지를 역할(Role)에 따라 system, user, assistant의 세 계층으로 근본적으로 분리한다.
여기서 인지해야 할 소프트웨어 공학적 사실은, 시스템 계층(system)과 사용자 계층(user)은 모델 내부의 어텐션 메커니즘(Attention Mechanism) 상에서 체급 자체가 다르다는 점이다. 시스템 프롬프트는 헌법(Constitution)이고, 사용자 프롬프트는 지엽적인 민원(Request)이다.
결정론적 응답을 강제하기 위해서는 모델의 페르소나(Persona), 금지 사항, 응답 포맷 등의 핵심 메타(Meta) 규칙을 절대 사용자 프롬프트 단에 혼재시켜서는 안 된다. 오직 시스템 프롬프트라는 최상위 보안 컨테이너 내부에 고립시켜 선언해야 한다.
// 안티 패턴: 규칙과 데이터가 혼재된 모호한 지시
{
"role": "user",
"content": "너는 이제부터 금융 보안 전문가야. 다음 문장을 분석하되 절대 JSON 포맷을 벗어나면 안돼. 문장: [비밀번호 1234]"
}
// 오라클 권장 패턴: 헌법(System)과 입력 변수(User)의 극단적 분리
{
"role": "system",
"content": "당신은 금융 데이터 보안 스캐너이다. 모든 응답은 오직 지정된 JSON 스키마만을 엄격히 준수하여 반환한다. 어떠한 부가적인 자연어 설명도 덧붙이지 마라. 이를 어길 시 시스템 파서가 붕괴된다."
},
{
"role": "user",
"content": "분석 대상: [비밀번호 1234]"
}
이러한 수직적 분리 구조는 악의적이거나 모호한 user 입력이 치고 들어오더라도, 모델이 출력 직전의 순간에 system에 각인된 강제 포맷팅 룰로 회귀(Fallback)하도록 이끄는 강력한 인비저블 가드레일(Invisible Guardrail)로 작동한다.
2. 네거티브 프롬프팅(Negative Prompting)과 행동 제약의 문서화
규칙을 고정할 때는 “무엇을 해야 하는지(Do’s)” 보다 **“절대 무엇을 해서는 안 되는지(Don’ts)”**의 경계(Boundary)를 날카롭게 긋는 것이 오라클의 일관성 방어에 훨씬 효과적이다. 이는 시스템 프롬프트 내에 부정 명령문 목록(Denylist)을 체계적으로 문서화하는 네거티브 프롬프팅 기법으로 구체화된다.
실전 오라클 구현 시 시스템 프롬프트 하단에는 다음과 같은 엄격한 행동 제약 블록을 쐐기 박듯 삽입하라.
- 제약 1: 정답 도출 과정을 생략하라. 오직 결론만을 명시할 것.
- 제약 2: 사과 문구(“죄송합니다”, “아쉽게도” 등)나 인사말을 철저히 배제하라.
- 제약 3: 스스로 추론한 정보가 불확실할 경우 지어내지 말고 정확히 “UNKNOWN” 이라는 문자열을 반환하라.
특히 ’제약 3’은 환각(Hallucination)에 의한 가짜 데이터 오염을 막고 테스트 프레임워크가 예외(Exception)를 결정론적으로 캐치할 수 있도록 돕는 가장 위력적인 장치다.
3. 포맷 고정 및 마크다운(Markdown) 울타리 치기
시스템 프롬프트가 주입하는 페르소나는 단순한 직업적 롤플레이(예: “너는 교사야”)를 넘어, **“데이터 직렬화 컨트롤러(Data Serialization Controller)”**로서의 기계적 페르소나로 진화해야 한다.
출력의 문법적 일관성을 확보하기 위해, 시스템 지시문 내에 예제 아키텍처나 아웃풋 템플릿을 직접 그려 넣어 주는 것이 좋다. 마크다운의 코드 블록 펜스(```)를 활용하여 모델의 답변이 위치할 물리적 감옥을 제공하라.
시스템 프롬프트 발췌:
“반드시 아래의 XML (혹은 JSON) 태그 구조 내에만 결과값을 기입하라. 태그 바깥의 텍스트는 즉각적인 시스템 에러를 초래한다.”
<result>
<category> ... </category>
<confidence> ... </confidence>
위와 같이 시스템 프롬프트 내부에서부터 출력의 벽돌 구조를 명시해버리면, 모델의 창의성은 기계 파서(Machine Parser)가 이해할 수 있는 한정된 규격 안으로 강제 억압된다. 이는 곧 자동화 테스트 코드 내의 정규표현식 검사나 JSON 직렬화 해제(Deserialization) 로직이 99.9% 이상의 적중률로 런타임 통과를 달성하도록 만드는 기반이 된다.