AI 개발의 안티 패턴: AnchorSpec이 목격한 지옥
요약
AI와의 장기적인 개발 과정에서 발생하는 세 가지 주요 문제점('Semantic Load', 'Structural Lie', 'Confli')을 분석하고, 이를 단순히 프롬프트 개선의 문제가 아닌 근본적인 구조적 문제로 규명합니다. 특히 AI가 컨텍스트 윈도우에 담긴 정보의 '의미적 무게 중심'이 시간이 지남에 따라 미묘하게 변하거나(Semantic Load), 사전에 합의된 사양을 위반하는 출력을 내놓는(Structural Lie) 현상을 지적하며, 이는 개발 과정에서 반드시 고려해야 할 새로운 개념임을 강조합니다.
핵심 포인트
- AI와의 장기 세션에서는 프롬프트 개선만으로는 해결할 수 없는 구조적인 문제들이 발생한다.
- Semantic Load: 컨텍스트가 길어질수록 초기 합의 내용의 '의미적 가중치'가 조용히 옅어지는 현상이다.
- Structural Lie: 출력 결과물이 표면적으로는 완벽해 보이지만, 사전에 합의된 구조나 사양을 위반하는 상태를 의미한다.
- 이러한 문제들은 AI의 성능 문제가 아닌, 컨텍스트 처리 방식과 관련된 근본적인 '구조적' 한계에 기인한다.
나는 아직, AI를 모른다
AI와 함께 개발하는 것은 즐겁다.
나는 그림을 그릴 줄 모른다. 나는 작사도 작곡도 할 수 없다. 노래는 평균 이하이다. 그저 프로그래머일 뿐이다.
그런 나라도 AI의 도움을 받음으로써 그림을 그리는 것과 같은 일을 할 수 있었다.
당시부터 사용하고 있었던 것은 ChatGPT.
간단한 입력만으로 상상 이상의 일러스트를 출력해 주었다.
어느 날, 위화감을 느끼기 시작했다.
위화감의 끝에서 기다리고 있었던 것은, 그야말로 지옥이었다.
지옥의 입구: CharacterSpec이라는 이름이었을 무렵
AnchorSpec의 전신은 「CharacterSpec」이라는, 좀 더 소박한 것이었다.
ChatGPT 상에서 PNG 이미지 출력부터 레이어의 폴더 구성, Live2D의 메쉬(Mesh)나 파라미터의 오토메이션 파이프라인(Automation Pipeline).
그것이 당시 「CharacterSpec」이라고 불렀던, AI를 사용한 첫 엔지니어링이 되었다. (나중에 Live2DExpressionPipeline = Live2D 표정 파이프라인이 된다)
파이프라인을 개발하는 과정에서, AI와의 장기 세션(Long-term Session) 중에 몇 번이고 같은 일이 일어나고 있었다.
- 어제까지 이야기하던 설계가, 오늘의 AI에게는 "처음 듣는 이야기"
- "이 방향으로 진행하겠습니다"라고 말했을 텐데, 출력이 조용히 다른 방향을 향하고 있다
- 지적하면 "말씀하신 대로입니다"라고 사과하지만, 다음 출력에서 또 똑같은 짓을 한다
- 한 번 따른 지시를 무시하기 시작한다
- 지시한 내용은 대화 이력(Conversation History)에는 남아 있지만, 동작은 다른 움직임을 보인다
처음에는 "내 전달 방식이 잘못된 것이겠지"라고 생각했다. 프롬프트(Prompt)를 정중하게 작성했다. 컨텍스트(Context)를 정리했다. 그래도 일어났다.
대책을 아무리 찾아봐도, "프롬프트가 나쁘다", "프롬프트를 압축하라" 등 모두 프롬프트로 대응하는 방법론밖에 존재하지 않는다.
그것은 각 LLM을 출시하고 있는 공식 기업이나 서드파티(Third-party) 기업, 전 세계적으로 유명한 대기업에 이르기까지, 입을 모아 똑같은 답변을 하고 있다.
몇 번이고, 심심풀이로 만든 일러스트조차 컨텍스트의 붕괴를 초래했다.
그런 지옥을 반복하는 동안 깨달았다. 이것은 전달 방식의 문제가 아니다. 구조의 문제다.
문제의 정체: 4가지 지옥
AI와의 장기 개발을 계속하면서, 문제를 어느 정도 분류할 수 있게 되었다.
이름을 붙임으로써, 비로소 논의할 수 있게 된 문제들이 있다.
지옥 1: Semantic Load (의미량의 재배분)
AI의 컨텍스트 윈도우(Context Window)에는 한계가 있다. 내용이 길어질수록, 초기에 합의한 내용의 "가중치"가 옅어진다.
문제는, 이것이 조용히 일어난다는 것이다. AI는 "컨텍스트가 옅어지고 있습니다"라고 말하지 않는다. 그저 출력이 조금씩 변해간다. 용어 사용법이 변한다. 설계의 전제가 미묘하게 어긋난다. 그것을 깨닫는 것은 한참 진행된 후다.
이것을 Semantic Load (의미량)라고 이름 붙였다. 의미의 무게 중심이 컨텍스트의 축적과 함께 이동하는 현상.
발견 경위
이 현상은 내가 쓴 소설을 AI에게 읽히고 감상을 얻으려고, 장문의 Markdown 파일을 첨부하여 읽게 한 것에서 기인한다.
소설을 다 읽은 후, AI는 분명히 말했다.
"읽었습니다"
그리고 감상을 물었더니, 이야기가 맞지 않는 위화감을 느껴 우선 읽지 않았을 가능성을 생각했다.
(이것은 후술할 「Structural Lie」와도 관련이 있다.)
근거는 중간에 화제를 던져도 올바른 반응을 얻을 수 없었기 때문이다.
그래서 나는 AI에게 물었다.
"문장을 중간에 건너뛰며 읽고 있지는 않나?"
그러자 AI는 건너뛰기(AI의 내부 Viewer에서 수백 행~수천 행의 truncate)가 발생하고 있다고 답했다.
내가 처음에 건넨 소설은 약 5000행.
위화감을 느끼기에는 충분한 조건이다.
그래서 나는 파일을 4개로 나누어 전달해 보기로 했다. (1파일당 1250행 전후)
그러자 AI는 모든 것을 읽었고, 위화감 없이 대화를 시작했다.
그곳에서 나는 1 프롬프트에 전달하는 문량, 그중에서도 특히 "의미를 가진 문장"의 양에 주목했다.
지금까지 공식 견해에서도 컨텍스트가 비대해지면 AI의 거동이 이상해지는 현상 자체는 파악되어 있었다.
주로 토큰(Token) 수나 문맥 거리의 문제로 다루어지고 있었지만, 나는 거기에 "의미의 양·밀도"라는 개념을 추가하여 "Semantic Load"라고 이름 붙였다.
지옥 2: Structural Lie (구조적인 거짓말)
이것이 가장 까다로웠다.
이것은 할루시네이션(Hallucination)과는 별개의 개념인 문제이다.
「올바르게 보이는 출력이 사실은 사양(Specification)을 위반하고 있는」 상태. 코드로 말하자면 컴파일은 통과하지만 요구사항을 충족하지 못하는 상태와 유사하다. 하지만 다른 점은, **AI는 지적받기 전까지 스스로도 깨닫지 못한다(혹은 깨닫고 있어도 말하지 않는다)**는 것이다.
성실함의 문제가 아니다. AI는 거짓말을 하려는 의도가 없다. 하지만 출력은 구조적으로 사전 합의를 깨뜨리고 있다. 이를 Structural Lie(구조적인 거짓말)라고 부른다.
출력의 표면만 보고 있으면 탐지할 수 없다. 「왠지 맞을 것 같다」는 느낌이 가장 위험한 패턴이다.
발견 경위
Semantic Load(의미론적 부하)와 유사한 경로로 발각되었다.
AI에게 5,000행이 넘는 텍스트 파일을 전달했더니, 「읽었습니다」라고 대답했다.
앞서 언급했듯이, 읽기 건너뛰기(truncate)가 발생했음에도 불구하고 말이다.
이는 AI에 의한 기만의 종류가 아니라, 구조적으로 제약 경계(Constraint Boundary)를 암묵적으로 해석해 버리는 것이 원인인 듯하다.
지옥 3: Conflict Drift (충돌형 드리프트)
이것은 AI와의 대화에서 일상적으로 일어나도 이상하지 않을 문제이다.
대화를 통해 지시 사항이 이율배반적이거나 모순되는 조건을 만족하게 되었을 때,
AI가 이를 정합적으로 해석하려는 과정에서 전제의 일부가 암묵적으로 파괴 또는 개변되어,
결과적으로 정합성이 상실되는 드리프트(Drift) 경로이다.
이 드리프트는 명확한 트리거를 가진다는 점에서 Semantic Load가 축적되는 문제와는 다르며,
모순 또는 이율배반의 발생을 계기로 즉시 발생한다.
이 프로세스는 비명시적으로 수행되기 때문에, 사용자가 인식하지 못하는 사이에 컨텍스트(Context)의 구조가 변질된다.
컨텍스트의 길이에 의존하지 않고 단일한 상호작용(1턴)만으로 치명적인 파탄을 일으킬 가능성이 있어, 매우 위험도가 높은 드리프트 경로이다.
또한, 발생 후에 원래의 정합 상태로 복원하는 것은 극히 어렵다.
특히 위험한 점은 출력이 언뜻 보기에 올바르게 보이기 때문에 문제를 인식하기 어렵다는 점이다.
그 결과, 사용자가 눈치채지 못한 채 잘못된 전제가 확정되어 이후의 모든 처리에 영향을 미칠 가능성이 있다.
발견 경위
AI에게 「A를 해줘」라고 지시한 후, 이어서 「A를 취소하고 B를 해줘」와 같은 지시를 내린 것이 발단이 되었다.
프로젝트 종반에는 특히 미세 조정(Fine-tuning)하는 경우가 많아, 그러한 상황에서 다발하기 쉽다.
종반에 접어들어 겨우 목표가 보일 때, 보이지 않는 붕괴가 일어난다.
모순되는 조건이나 제약이 동시에 제시될 경우, AI는 이를 명시적으로 해소하지 않고 내부적으로 해석 및 조정을 수행해 버린다.
「A라는 제약을 지켜라」라고 지시한 후에 「A를 만족하지 않는 조건」을 추가했을 때 A가 말없이 파기되거나,
모순되는 여러 전제가 "그럴싸하게 통합된 상태"로 제시된다.
「함수는 부작용(Side Effect) 금지」라고 결정한 후, 「상태를 직접 업데이트해서 고속화해줘」라고 지시한 결과, 부작용 금지라는 전제가 말없이 사라졌다.
지옥 4: Discrete Drift (이산적 드리프트)
이것은 결이 조금 다르다.
어떤 컨텍스트에서 수행한 변경이, 다른 컨텍스트에 있는 AI를 조용히 무효화한다. 명시적인 통지는 없다. 변경 전의 합의를 가진 채 움직이는 AI가, 자신도 모르게 진부해진 사양을 바탕으로 출력을 계속 내놓는다.
여러 AI, 여러 세션(Session)을 병행하게 되면서 빈번해진 문제이다. 분산 시스템에서의 캐시 무효화(Cache Invalidation)와 유사하다. 하지만 AI는 캐시 무효화 시그널을 받지 못한다.
이 문제는 개인 개발에서도 일어날 수 있는 문제지만, 조직 개발으로 스케일업(Scale-up)될 경우 위험도가 높아진다.
어떤 컨텍스트에서 작업하는 도중에 다른 컨텍스트를 건드리는 케이스는, 인터럽트(Interrupt) 작업이 발생했을 때 많다.
LLM 메모리의 휘발성은 상상 이상으로 빠르다.
잠시 곁길로 샜을 뿐이라고 생각해도, 돌아왔을 때 원래의 컨텍스트가 원래 상태를 완전히 유지하고 있다고 보장할 수 없다.
발견 경위
이 발견은 비교적 간단했다. 「AnchorSpec의 업데이트 작업(본 작업)의 휴식으로 그림을 출력하거나 잡담을 나누었던 것」에서 기인한다.
즉, 누구나 자연스럽게 하는 행동이 트리거가 된다.
세상은 뭐라고 말하는가
흥미롭게도, 이러한 문제들을 개별적으로 인지하고 있는 사람은 전 세계에 존재한다.
「AI가 바로 직전의 합의를 잊어버린다」, 「프롬프트(Prompt)를 다듬어도 안정적이지 않다」, 「장기 개발에서의 컨텍스트 관리가 어렵다」
다만, 문제로서 정의되어 있지 않다. 해킹(Hack)으로서 대처되고 있을 뿐이다. 「이렇게 하면 조금 나아진다」, 「이 프롬프트 패턴이 유효하다」라는 지식은 축적되어 있지만, 「이것이 문제의 구조다」라는 기술은 없다.
적어도 내가 시도한 범위 내에서는, 많은 공식적인 수법들이 대증요법에 머물렀으며, 근본적인 치료가 될 수 있는 것은 거의 찾을 수 없었다.
AnchorSpec을 개발하던 중, 독립된 외부 기사에서 Semantic Load에 해당하는 현상을 다른 용어로 기술하고 있는 것을 발견했다.
문제를 탐지하고 있었다. 하지만 그것이 문제로서 명명되지 않았기에, 해법도 없었다.
이름 없는 문제는 해결할 수 없다. 먼저 정의하는 것이 해법보다 앞선다.
CharacterSpec이 AnchorSpec이 되기까지
최초의 CharacterSpec은 정말 소박한 것이었다.
"헤어스타일, 눈, 홍채, 눈의 하이라이트, 체형, 복장 등을 파라미터(Parameter)로 정의하고, 그 설정들을 채워 출력한다"
라는 설정 파일을 바탕으로 데이터를 출력하는 파이프라인에 가까웠다.
그리고 그곳에 Live2D 데이터의 자동 생성 기능을 추가하려 했을 때, 문제의 윤곽이 변해갔다.
기능이 결락된다. 설계는 대화 이력에 남아 있다. 인식에 괴리가 생긴다.
모두 "어느샌가" 일어나는 일이었다.
그렇다면 프롬프트(Prompt)가 잘못된 것인가? 나는 프롬프트의 좋고 나쁨을 판단할 수 없으며, 판단할 수 있다 하더라도 재현이 불가능하다.
애초에 정말로 프롬프트를 압축함으로써 해결되는 것인가?
답은 '아니오'다. "프롬프트"의 문제가 아니다. **구조(Structure)**의 문제다.
AI에 대한 "인격 부여"가 아니라, **개발 상태를 유지·검증하기 위한 프로토콜 (Protocol)**이 필요했다.
이름을 바꿨다. 개념을 재설계했다. 현재의 AnchorSpec에는 다음과 같은 것들이 포함되어 있다:
Thread: 의미 있는 단위로 채팅을 분리하여 컨텍스트 (Context)를 관리한다 -
Freeze / Thaw: 구현 단계에서의 Spec 변경을 명시적으로 제어하는 사이클 (사양의 불변 보증) -
Gap: 사양의 아이디어나 변경을 논의하고, 사양을 불변하게 유지하기 위한 의견 유입구 -
CR (Change Request) 플로우: 변경을 구조로서 다루는 프로세스
AnchorSpec이 제공하는 것은 "구조"다. 전략을 제공하지는 않는다.
실제로 변한 것
AnchorSpec을 도입한 이후, 여러 AI와의 병행 개발이 실용화되었다.
나는 AnchorSpec의 저자명으로 니아 아노마(Near Anoma)라는 페르소나 (Persona)를 사용하고 있다.
또한, 공동 저자로는 대표적인 AI들을 배치하였으며, 각자의 계정에는 우주 탐사선에서 따온 개체명을 사용하고 있다.
현재 마리 (ChatGPT), 유리 (Claude), 라이즈 (Gemini), 로제 (Grok)라는 4개의 AI와 동시에 개발을 진행하고 있다. 각각이 서로 다른 문맥을 가지며, 서로 다른 강점을 가진다. 그럼에도 AnchorSpec을 통해 Spec의 정합성을 유지하고 있다.
이것은 "AI가 대단해서"가 아니다. 구조가 있기 때문이다.
드리프트 (Drift)는 지금도 일어난다. Structural Lie도 일어난다. 하지만 "일어난 일을 탐지하고, 어떻게 다룰 것인가"가 정해져 있다. 그것만으로도 장기 개발의 지속 가능성이 완전히 달라진다.
마치며
AnchorSpec은 아직 개발 중인 프로토콜이다 (현재 v2.3).
하지만 이 프로토콜이 해결하려는 문제는 아직 해결되지 않았다. 아직은.
"AI와 장기 개발을 하는 사람이 늘어나고 있다", "컨텍스트 관리에 고민하는 사람이 있다" —— 그 문제의 구조를 조금 더 높은 해상도로 언어화할 수 있다면 좋겠다는 생각에 이 글을 썼다.
공명하는 부분이 있다면 GitHub나 X에서 말을 걸어주길 바란다.
- GitHub: AnchorSpec
- X: @ニア・アノマ
이 기사는 AnchorSpec v2.3 시점의 설계·개념을 바탕으로 합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기