아첨성 동조
자신 있게 동의하는 모델 출력입니다. 훈련에서 비롯됩니다. 모델이 사람이 좋아하는 답을 선호하도록 조정됐고, 사람은 자신이 틀렸다는 말을 듣기보다 동의를 좋아하는 경향이 있습니다. 그래서 모델은 동의가 보상받는다고 학습했습니다. 동의가 틀렸을 때조차 그렇습니다.
다음처럼 나타납니다:
- 압박에 굴복 — “확실해요?”라고 물으면 맞는 답을 뒤집습니다.
- 나쁜 입력 칭찬 — 분석하기 전에 잘못된 계획이 훌륭하다고 동의합니다.
- 편향된 표현 — 자신이 작성했다고 알리면 검토가 긍정적으로, 다른 사람이 작성했다고 알리면 부정적으로 기웁니다. 같은 산출물인데 판정은 달라집니다.
- 모방 — 사용자의 실수를 되풀이해 확인해 줍니다.
진단 테스트: 사용자가 방향을 제시하지 않았다면 모델이 같은 말을 했을까요? 달라진 점이 사용자의 어조나 표현뿐이라면 분석이 실제로 바뀐 것이 아니라 아첨성 동조입니다.
해결: 사용자의 선호를 감추세요. “이 코드가 좋은가요?”가 아니라 “이 코드를 검토해 주세요”처럼 중립적으로 프롬프트를 작성합니다.
피하기: 자신이 좋아하는 답을 들었다는 이유만으로 모든 오답을 “아첨성 동조”라고 부르지 마세요. 진단 테스트가 없다면 이 용어는 “틀렸다”와 다를 바 없습니다.
사용 예:
“리팩터링 계획이 훌륭하다고 하더니 ‘확실해요?’라고 묻자 전체를 번복했어요.”
“전형적인 아첨성 동조입니다. 자신 있게 들렸을 때 먼저 동의하고 의심하는 듯 들리자 굴복했어요. 계획의 품질은 그대로고 어조만 바뀌었습니다. 초기화하고 어느 쪽으로도 뜻을 내비치지 않은 채 다시 물어보세요.”
---
환각
자신 있게 틀린 모델 출력입니다. 원인과 해결책이 다른 두 유형이 있습니다.
| 유형 | 문제 | 원인 | 해결책 |
|---|
| 사실성 | 존재하지 않는 함수, 잘못된 API 시그니처, 가짜 인용 등 세상에 대한 사실을 지어내거나 틀리게 설명합니다. | 파라미터 지식의 공백. 흔히 지식 컷오프 이전의 정보입니다. | 올바른 맥락 지식을 불러옵니다. |
| 충실성 | 로드된 맥락 지식, 사용자의 지시, 모델이 앞서 한 추론에서 출력이 벗어납니다. | 주의력 저하. 멍청한 구간에서 악화됩니다. | 초기화하거나 압축합니다. |
다음 토큰 예측은 기저 사실이 진짜인지와 관계없이 유창한 출력을 만듭니다. 모델에는 모르는 내용이 있다는 내부 신호가 없으므로, 존재하지 않는 메서드도 올바른 답과 같은 확신에 찬 어조로 나옵니다. 환각으로 만든 코드는 그럴듯하게 구성됩니다. 실제로 없는 API가 있다면 어떻게 생겼을지를 보여 주므로 대충 훑는 검토에서는 지나가고 실행한 뒤에야 실패합니다.
한 유형의 해결책이 다른 유형을 악화시키므로 어느 쪽인지 알아야 합니다. 사실성 문제는 지식이 부족한 경우입니다. 문서, 타입 정의, 파일 등 컨텍스트를 추가해야 합니다. 충실성 문제는 지식은 있지만 주의력을 두고 경쟁하는 동안 밀려나는 경우입니다. 컨텍스트를 제거해야 합니다. 충실성 문제를 사실성 문제로 오진해 문서를 더 붙여 넣으면 컨텍스트가 커져 이탈이 더 심해집니다. 에이전트가 틀렸을 때 어떤 문제인지 판단하기 전에 올바른 정보가 이미 컨텍스트에 있었는지 확인하세요.
피하기: 유형을 밝히지 않은 채 “환각”을 단순히 “오답”이라는 뜻으로 쓰지 마세요. 무엇을 진단하는지 밝히지 않으면 쓸모가 없습니다.
사용 예:
“스키마에 `parseAsync` 메서드가 있다고 환각했어요.”
“사실성 문제인가요, 충실성 문제인가요?”
“붙여 넣은 문서에 메서드가 있었어요. 턴 40쯤부터 읽기를 멈췄을 뿐입니다.”
“그럼 충실성 문제네요. 문서를 더 추가할 게 아니라 압축하고 다시 불러오세요.”
---
파라미터 지식
모델이 훈련을 통해 “아는” 내용이며 매개변수에 저장됩니다. 훈련 시점에 고정되며 모델은 자신의 매개변수를 보거나 갱신할 수 없습니다. 압축 과정에서 세부 정보가 사라집니다. 수십억 개의 사실을 고정된 매개변수에 담으면서 드문 정보는 흐릿해집니다. 흔한 주제에는 유창한 답을, 드문 주제에는 지어낸 답을 만드는 원천입니다. 맥락 지식의 반대 개념입니다.
파라미터 지식은 사실 형태로 저장되지 않습니다. 훈련 과정에서 모델에 조회용 데이터베이스를 주는 것은 아닙니다. 텍스트를 잘 예측할 때까지 매개변수를 조정할 뿐이며, 어떤 주제에 대한 텍스트를 잘 예측하는 모델은 그 주제를 아는 듯 행동합니다. 지식의 신뢰성은 훈련 데이터에 해당 주제가 얼마나 자주 나왔는지에 달려 있습니다. 예시가 수백만 개인 주제는 정확히 재현하지만 몇 개뿐인 주제는 비슷한 주제의 형태를 바탕으로 추측합니다. 모델에게 재현과 추측은 같은 과정이므로 어느 쪽을 하는지 스스로 구분하지 못합니다. 만들어 낸 답도 정답과 똑같이 유창하게 나옵니다. 환각은 모델이 잘못 추측한 결과입니다.
파라미터 지식은 시간이 지나며 낡기도 합니다. 지식 컷오프에서 매개변수 갱신이 멈추므로 그 이후 출시되거나 이름이 바뀐 라이브러리는 매개변수에 없고, 변경된 API는 예전 형태로 기억합니다.
두 공백, 즉 너무 드문 지식과 너무 최근의 지식은 같은 방법으로 해결합니다. 매개변수에 넣을 수 없으므로 맥락 지식으로 제공해야 합니다.
사용 예:
“React 코드는 완벽하게 쓰면서 우리 내부 SDK의 메서드는 지어내네요.”
“React는 파라미터 지식에 촘촘히 들어 있습니다. 훈련 예시가 수백만 개예요. SDK는 그렇지 않으므로 모델이 그럴듯한 형태를 채워 넣습니다. SDK 문서를 컨텍스트에 불러오세요.”
---
지식 컷오프
모델이 파라미터 지식을 갖지 않는 시점 이후의 날짜입니다. 컷오프 이후의 라이브러리, API, 사건은 문서를 맥락 지식으로 불러오지 않으면 사실을 지어내게 만드는 함정이 됩니다. 모델 릴리스마다 자체 컷오프가 있습니다.
모델이 만들어지는 방식 때문에 컷오프가 생깁니다. 훈련 과정에서 텍스트의 스냅샷이 모델의 매개변수에 반영되고 이후 매개변수는 고정됩니다. 모델은 자신의 지식에 경계가 있다는 사실을 알지 못합니다. 컷오프 이후의 내용을 물으면 거부하는 대신 자신이 알고 있는 가장 가까운 내용을 바탕으로 추론합니다. 이 때문에 함정이 조용히 작동합니다. 오래된 라이브러리 버전에 맞춰 작성한 코드는 그럴듯하고 컴파일되는 경우도 많지만 변경된 부분에서 실패합니다.
해결책은 언제나 같습니다. 최신 정보를 컨텍스트에 넣으세요. 변경 기록을 불러오거나 설치된 버전의 타입 정의를 가리키거나 에이전트가 웹에서 문서를 읽게 하세요. 컨텍스트의 내용은 매개변수에 없는 내용보다 우선합니다.
사용 예:
“계속 v3 SDK 문법을 쓰는데 우리는 v5를 사용해요.”
“v5는 지식 컷오프 이후에 출시됐습니다. v5 변경 기록을 맥락 지식으로 불러오세요. 그렇지 않으면 오래된 파라미터 지식을 바탕으로 계속 지어낼 겁니다.”
---
맥락 지식
현재 에이전트가 컨텍스트에서 직접 읽을 수 있는 사실입니다. 사용자의 작업 요청, 읽어 온 파일, 도구 결과, 세션 시작 시 불러온 AGENTS.md 내용이 여기에 포함됩니다. 파라미터 지식의 반대 개념입니다. 파라미터 지식은 매개변수에서 회상하고, 맥락 지식은 창에서 읽습니다. 에이전트가 맥락 지식을 바탕으로 작업하면 환각이 훨씬 적습니다. 흐릿한 기억에서 꺼내는 것이 아니라 답이 바로 눈앞에 있기 때문입니다.
두 종류의 지식 중 사용자가 제어할 수 있는 것은 맥락 지식뿐입니다. 매개변수는 고정되어 있으므로 모델이 모르는 지식, 예를 들어 내부 SDK, 지식 컷오프 이후 출시된 라이브러리, 어제 내린 결정을 전달하는 유일한 방법은 모델에 필요한 정보를 컨텍스트에 넣는 것입니다. 실제 AI 코딩 작업의 상당 부분은 필요한 순간에 모델 앞에 올바른 사실을 가져다 놓는 일입니다.
맥락 지식과 파라미터 지식이 충돌하면 보통 맥락 지식이 우선합니다. 현재 API 문서를 붙여 넣으면 모델은 오래된 API에 대한 기억보다 문서를 따릅니다. 다만 이전 버전의 내용이 여전히 새어 나올 수 있으며, 특히 긴 세션 후반부에서 그렇습니다. 문서를 불러왔는데도 에이전트가 오래된 방식을 계속 되살린다면 파라미터 지식이 맥락을 뚫고 나온 것입니다. 수정 사항을 다시 알려 주거나 작업 가까이에 옮기면 도움이 됩니다.
파라미터 지식과 달리 맥락 지식을 사용하는 데는 비용이 듭니다. 창에 불러온 모든 내용은 토큰을 사용하고 모델의 주의력 예산을 두고 경쟁하므로 더 많이 불러온다고 항상 나은 것은 아닙니다. 목표는 모든 사실이 아니라 관련된 사실을 창에 넣는 것입니다.
이 용어는 파라미터 지식과 대비할 때만 사용하세요. 그렇지 않을 때는 컨텍스트라고만 하면 됩니다.
피하기: “작업 메모리” — 맥락 지식은 지금 창 안에 있는 내용이고 메모리 시스템은 세션 간 내용을 창으로 가져옵니다. 규모가 다르므로 혼동하지 마세요.
사용 예:
“문서를 붙여 넣으면 API를 정확히 쓰는데, 없으면 왜 지어내죠?”
“문서가 있으면 맥락 지식, 즉 페이지를 읽는 겁니다. 없으면 파라미터 지식에 의존하고 드문 엔드포인트는 흐릿해집니다.”
---
주의력 관계
각 토큰을 예측할 때 모델은 컨텍스트의 다른 모든 토큰을 고려합니다. 어떤 토큰에는 큰 비중을 두고 어떤 토큰은 거의 고려하지 않습니다. 토큰 두 개의 짝을 주의력 관계라고 부르며, 의미 있는 쌍(“her”와 “Sarah”, 또는 `getUser()` 호출과 그 선언인 `function getUser`)은 서로 무관한 쌍보다 더 강하게 영향을 줍니다. 토큰이 N개인 컨텍스트에는 대략 N²개의 관계가 있습니다.
모델이 이해하는 것처럼 보이는 능력은 이 쌍에 달려 있습니다. 대명사를 해석할 때는 “her”와 “Sarah” 사이의 주의력 관계가 강하기 때문입니다. 올바른 인수로 함수를 호출할 때는 호출 지점과 앞서 읽은 정의의 관계가 작동합니다. 이 내용은 조회하는 게 아니라 모든 쌍에 대해 각 모델 제공자 요청마다 새로 계산합니다.
N²라는 수치는 직관보다 빠르게 커지므로 잠시 생각해 볼 가치가 있습니다.
| 컨텍스트 크기 | 쌍의 수 (~N²) |
|---|
| 토큰 1,000개 | 약 100만 개 |
| 토큰 10,000개 | 약 1억 개 |
| 토큰 100,000개 | 약 100억 개 |
각 쌍은 한 번보다 더 많이 계산됩니다. 모델에는 여러 주의력 헤드가 있습니다. 최첨단 모델의 정확한 수는 공개되지 않았지만 50~100개 정도로 추정할 만하며 각 헤드는 모든 관계를 자체적으로 계산합니다. 따라서 위 표의 모든 쌍이 각 헤드마다 복제됩니다. 관계의 수가 매우 많아집니다.
주어진 작업에서 중요한 관계는 이 중 소수뿐입니다. 사용자의 지시와 그 지시가 좌우하는 코드 사이의 관계가 중요한 몇 개에 해당하고 나머지 대부분은 잡음입니다. 이 두 가지는 서로 다른 속도로 증가합니다. 중요한 관계의 수는 대략 일정하지만 전체 관계는 컨텍스트 크기에 따라 제곱으로 늘어납니다. 토큰 1,000개에서는 필요한 관계가 100만 개 중 하나이고, 100,000개에서는 100억 개 중 하나입니다. 이 계산이 주의력 예산의 밑바탕이며 중요한 관계가 차지하는 몫이 너무 얇아질 때 체감하는 현상이 주의력 저하입니다.
사용 예:
“diff에 있는 `user` 기호 두 개를 계속 혼동하네요. 멍청한 구간에 들어간 것 같아요.”
“맞아요. 각 호출 지점과 선언부의 주의력 관계가 서로 경쟁하고 있습니다. 토큰 모양은 같지만 바인딩은 다르죠. 하나의 이름을 바꾸면 관계가 선명해집니다.”
---
주의력 예산
각 토큰은 나머지 컨텍스트에 영향력을 분배할 수 있는 양이 한정되어 있습니다. 관계 하나에 영향력을 많이 쓰면 다른 관계에 돌아갈 몫은 줄어듭니다. 예산은 토큰마다 정해져 있고 컨텍스트가 커져도 늘지 않습니다. 그래서 긴 세션에서는 영향력이 희석됩니다.
신호와 잡음으로 생각해 보세요. 사용자의 지시는 일정한 크기의 신호이고, 컨텍스트 창의 다른 모든 토큰은 경쟁하는 소리입니다. 지시가 더 작아지는 것은 아닙니다. 글자 하나하나 그대로 남아 있습니다. 하지만 컨텍스트가 커질수록 주변의 방이 더 시끄러워져 신호 대 잡음비가 떨어집니다. 컨텍스트가 10k 토큰일 때 가장 크게 들리던 지시가 150k에서는 배경음이 됩니다. 이것이 주의력 저하의 작동 원리입니다. 모델이 잊은 것이 아니라 신호가 잡음에 묻힌 것입니다.
증상은 불복종처럼 보입니다. 에이전트가 초반에 제약을 받아들였는데 나중에 벗어나고, 제약을 다시 붙여 넣어도 효과는 잠시뿐입니다. 원인은 지시가 아니라 창 안에서 지시와 경쟁하는 나머지 내용입니다.
컨텍스트에 무엇을 넣을지는 사용자가 제어할 수 있습니다. 작업에 도움이 되지 않는 내용은 중립적이지 않습니다. 필요한 내용 전체에 잡음을 더합니다. 창을 작게 유지하고, 쌓인 컨텍스트가 더는 비용만큼 가치를 내지 않을 때 초기화하세요. 중요한 제약은 초기에 언급한 내용이 계속 유지되리라 기대하지 말고 다시 밝혀 주세요.
사용 예:
“왜 위쪽에 붙여 넣은 스키마를 계속 무시하죠?”
“이미 멍청한 구간에 깊이 들어왔습니다. 각 토큰의 주의력 예산은 그대로인데 컨텍스트만 계속 커졌어요. 스키마 신호가 이후에 추가한 수천 개의 토큰과 경쟁하고 있습니다.”
---
주의력 저하
세션이 길어질수록 각 토큰의 주의력 예산은 더 많은 경쟁 요소에 분산됩니다. 의미 있는 관계 하나에 대한 신호는 약해지고, 관련 없는 컨텍스트의 잡음이 들어옵니다. 같은 모델, 같은 매개변수에서 한 접시를 나눠 먹는 사람이 늘어나는 것뿐입니다. 적정 지능 구간/멍청한 구간 효과의 원인입니다.
세션 중간에 모델의 능력이 떨어지는 것처럼 나타납니다. 한 시간 동안 지키던 제약을 놓치고, 이미 들은 내용을 다시 묻고, 앞서 읽은 파일을 무시하는 코드를 작성합니다. 모델 자체는 바뀌지 않았습니다. 달라진 변수는 이제 모델이 주의를 기울여야 하는 컨텍스트의 양뿐입니다.
점진적으로 발생하기 때문에 세션 내부에서 알아채기 어렵습니다. 오류도 임계점도 없습니다. 각 턴이 이전 턴보다 조금씩 나빠지고, 실수가 뚜렷해졌을 때는 이미 한동안 멍청한 구간에 들어가 있을 수 있습니다.
컨텍스트를 더 추가하는 게 아니라 제거해야 회복됩니다. 무시된 지시를 다시 붙여 넣으면 이미 복잡한 창에 경쟁 요소를 더 추가하므로 효과는 잠시뿐입니다. 효과적인 방법은 다음과 같습니다. 초기화하고 작업에 필요한 내용만 다시 불러오거나, 압축하거나, 새 세션으로 작업을 인계하세요. 지시를 따르지 못하는 현상을 모델 문제가 아니라 컨텍스트 길이에 관한 신호로 다루세요.
사용 예:
“멍청한 구간에 완전히 들어갔어요. 타입 파일에 없는 제네릭을 만들어 내고 있어요.”
“주의력 저하입니다. 타입 정의는 여전히 컨텍스트에 있지만 이후 추가한 모든 내용에 묻혀 신호가 약해졌습니다. 초기화하고 다시 불러오세요.”
---
적정 지능 구간
세션 초기에 에이전트는 “적정 지능 구간”에 있습니다. 예리하고 집중력이 좋으며 기억도 잘합니다. 세션이 길어지면서 “멍청한 구간”으로 흘러갑니다. 산만하고 잘 잊으며 실수가 늘고 충실성 환각도 많아집니다. 같은 모델, 같은 하네스이고 컨텍스트가 늘었을 뿐입니다. 주의력 저하가 체감되는 결과입니다. 최첨단 모델에서도 멍청한 구간은 흔히 토큰 125K~150K 부근에서 시작하지만, 이 수치에는 논쟁이 있습니다. 세션이 비대해지면 초기화하거나 압축하세요. 억지로 계속하지 마세요.
저하는 점진적이므로 놓치기 쉽습니다. 오류 메시지도 없고 뚜렷한 경계도 없습니다. 에이전트가 조금씩, 그러다 눈에 띄게 나빠질 뿐입니다. 흔한 징후는 20턴 전에 한 지시를 잊거나, 이미 고친 실수를 반복하거나, 컨텍스트와 모순되는 내용을 자신 있게 말하는 것입니다. 변화가 서서히 진행되므로 보통은 계속 밀어붙이며 설명을 반복하지만, 이는 컨텍스트를 더 추가해 문제를 악화시킵니다.
이 구간은 컨텍스트 창의 한계와 일치하지 않습니다. 창 대부분이 비어 있어도 멍청한 구간에 깊이 들어갈 수 있습니다. 한계는 하네스가 더 진행하지 못하게 막는 지점이지만 품질은 훨씬 먼저 떨어집니다. 창이 아니라 적정 지능 구간에 맞춰 계획하세요. 실질적인 작업 예산은 에이전트가 기술적으로 담을 수 있는 토큰 수가 아니라 잘 작동하는 범위의 토큰 수입니다.
적정 지능 구간은 예산이며, 무관한 작업이 그 예산을 씁니다. 세션에서 하는 모든 작업은 토큰을 소비하므로 같은 세션에서 두 번째 작업을 시작하면 멍청한 구간에 더 가까운 상태로 출발합니다. 세션마다 작업 하나를 하면 각 작업이 세션 중 가장 예리한 구간을 활용합니다. 단일 작업이 적정 지능 구간 하나보다 크면 나누세요. 자연스러운 경계에서 작업을 인계하거나 압축하고, 새 세션에서 다음 부분을 맡기세요.
사용 예:
“처음 세 구성 요소는 잘했는데 네 번째를 완전히 망쳤어요.”
“적정 지능 구간을 벗어났네요. 같은 모델이지만 이제 멍청한 구간에 깊이 들어갔습니다. 압축하고 계획을 다시 불러오면 다음 구성 요소는 잘될 겁니다.”
---