개발/AI

[프롬프트] persona drift 대응 생성 지점 context 재주입

jykim23 2026. 6. 25. 21:45
반응형

부제: 시스템 프롬프트가 안 먹힐 때 — 생성 지점에 한 번 더

먼저 이건 자주 쓰는 기술이 아니라 치트키에 가깝다. 시스템 프롬프트로 안 되는 게 확인됐을 때, 마지막에 꺼내는 카드다. 남발하면 부작용이 있어서, 왜 통하는지와 언제 쓰면 안 되는지를 같이 적는다.

증상

대화가 길어지면 봇의 말투가 흐트러졌다. 응답 옆에 괄호로 부연을 달거나((이건 좀 우려돼요)), 무대지시처럼 상황을 설명하거나, 시스템 내레이션조로 사용자를 진단하듯 말했다. 원래 페르소나에서 벗어난, 이른바 OOC(out-of-character)다.

시스템 프롬프트 맨 위에 말투 규칙을 분명히 적어 뒀는데도 그랬다.

왜 생기나

대화가 길어질수록, 생성 지점에서 시스템 프롬프트까지의 거리가 멀어진다.

  • 1턴째: 시스템 프롬프트 → 사용자 메시지 (가깝다)
  • 10턴째: 시스템 프롬프트 → [8턴 분량의 히스토리] → 사용자 메시지 (멀다)

모델은 다음 토큰을 만들 때 가까운 맥락에 더 큰 가중치를 둔다. 그래서 위쪽의 말투 규칙은 attention을 잃고, 모델은 가까이 있는 최근 대화의 관성을 따라간다. 이건 모델 버그가 아니라 attention의 성질이다. 관련해서 persona drift를 측정한 연구도 있다 — 정적 시스템 프롬프트는 대략 여덟 턴 만에 일관성이 30% 넘게 떨어지고, 생성 지점에 규칙을 다시 넣으면 후반 안정성이 개선된다고 보고한다 (arXiv:2402.10962). OOC를 유형화한 연구도 "시스템 설명조로 새는 것"을 흔한 실패로 든다 (arXiv:2506.19352).

여기서 핵심은 "규칙을 더 세게 쓰자"가 아니라 **"규칙을 더 가까이 두자"**다.

정리한 방식 — 생성 지점에 재고정

말투의 핵심 한 줄을, 매 턴 사용자 메시지 바로 뒤(생성 지점 직전)에 다시 넣었다.

... 이전 히스토리 ...
<user_message>
(이번 사용자 입력)
</user_message>
<reminder>
응답은 사용자에게 할 말만 담는다. 응답·행동·시스템을 따로 논평하는
곁다리 코멘트를 붙이지 않는다. (응답에 구조를 주는 것은 코멘트가 아니다.)
</reminder>

두 가지를 지켰다.

  • 격리: 이 <reminder>는 LLM에 보낼 때만 붙이고, 저장·요약·메모리에는 절대 넣지 않는다. 저장에 섞이면 "말투 규칙에 대한 규칙"이 기억에 쌓이는 메타 루프가 생긴다. 저장 전에 이 태그를 떼는 처리를 따로 뒀다.
  • 에코 금지: 이건 모델이 원래 알고 있던 것처럼 조용히 따르게 하고, "주입된 규칙에 따르면…" 같은 말로 되읊지 않게 했다.

결과

오염된 긴 스레드에서 100회 반복해 비교했다. OOC가 21회에서 한 자릿수로 줄었고, 마크다운 구조는 그대로 유지됐다. 규칙을 더 강하게 쓴 게 아니라, 같은 규칙을 가까이 옮겼을 뿐이다.

남발하면 안 되는 이유

  • 토큰 비용: 매 턴 붙으니 대화가 길수록 누적된다.
  • 과잉 규제: 생성 지점에 규칙을 잔뜩 쌓으면 모델이 규칙 지키기에만 매달려 응답이 경직된다.
  • 목표를 좁게: 한 가지 증상(여기선 OOC)만 겨냥해야 한다. 페르소나 전체를 매 턴 다시 정의하려 들면 다른 규칙과 충돌한다.

그래서 치트키다. 시스템 프롬프트로 되는 건 거기서 끝내고, 안 될 때만 꺼낸다.

정리

  • 대화가 길어지면 위쪽 시스템 프롬프트는 attention을 잃는다 (persona drift)
  • 해결의 본질은 "더 세게"가 아니라 "생성 지점에 더 가까이"
  • 재고정 문구는 저장·요약·메모리와 격리하고, 모델이 되읊지 않게 한다
  • 비용·과잉규제 때문에 한 증상만 좁게 겨냥하고, 최후의 카드로 쓴다

같은 규칙도 어디에 두느냐에 따라 먹히기도, 안 먹히기도 했다.

반응형