AI가 왜 당신의 앱을 계속 처음부터 다시 만드는가 (그리고 이를 방지하는 방법)
요약
AI 코딩 도구가 세션 간 지속적인 메모리를 갖지 못해 발생하는 데이터 레이어 재구축 문제를 다룹니다. 에이전트가 이전 세션의 결정 사항을 알지 못해 스키마를 임의로 추론하며 발생하는 코드 불일치 현상과 그 원인을 분석합니다.
핵심 포인트
- AI 코딩 도구는 세션 간 지속적인 메모리가 없어 매번 새로운 컨텍스트로 시작함
- 데이터베이스 스키마와 같은 외부 정보는 에이전트가 추론을 통해 재발명할 위험이 있음
- 세션 간 컨벤션 불일치는 코드베이스의 멘탈 모델을 파괴하고 디버깅 비용을 높임
- 데이터 레이어는 코드 외부에 존재하여 AI가 정확한 진실의 근원을 파악하기 어려움
당신은 Cursor나 Claude Code가 정확하게 데이터 레이어 (data layer)를 구축하도록 세션을 보냈습니다. 테이블 구조, 관계, API 호출까지 모두 정확했습니다. 그러다 새로운 세션을 시작하고 새로운 기능을 요청하면, 에이전트 (agent)가 즉흥적으로 행동하기 시작합니다. 에이전트는 자신이 추론할 수 있는 것들로부터 스키마 (schema)를 다시 도출하고, 약간 다른 가정을 세우며, 당신은 이미 잘 작동하고 있던 데이터 모델 (data model)을 수정하느라 세션의 첫 20분을 허비하게 됩니다.
이것은 버그가 아닙니다. AI 코딩 도구들이 컨텍스트 (context)를 처리하는 방식에서 발생하는 예측 가능한 결과입니다.
세션이 처음부터 다시 시작되는 이유
Cursor, Claude Code, Codex와 같은 AI 코딩 도구들은 기본적으로 세션 간에 지속적인 메모리 (persistent memory)를 갖지 않습니다. 각 새로운 세션은 깨끗한 컨텍스트 윈도우 (context window)와 함께 시작됩니다. 에이전트는 다음 사항들을 알고 있습니다:
- 현재 읽을 수 있는 파일에 무엇이 들어있는지
- 현재 대화에서 당신이 말하는 내용
- AGENTS.md 또는 .cursor/rules 파일에 있는 내용
당신이 제공하지 않는 한, 에이전트가 알 수 없는 사항들은 다음과 같습니다:
- 파일에 기록되지 않은 이전 세션에서의 결정 사항들
- 당신의 데이터 모델 선택 뒤에 숨겨진 추론 과정
- 당신이 확정한 필드 이름 (field names), 테이블 이름 (table names), 그리고 관계 (relationships)
에이전트가 신뢰할 수 있는 스키마를 찾을 수 없을 때, 에이전트는 훈련된 대로 행동합니다. 즉, 사용 가능한 컨텍스트를 읽고 그럴듯한 무언가를 도출합니다. 만약 당신의 데이터베이스 스키마 (database schema)에 직접 접근할 수 없다면, "그럴듯하다"는 것은 추론을 통해 그것을 재발명한다는 것을 의미하며, 추론은 매번 조금씩 어긋나게 됩니다.
증상: 누적되는 불일치
재구축 문제는 시간이 지남에 따라 심화됩니다. 세션 1에서 에이전트는 사용자 식별자를 user_id라고 부릅니다. 세션 3에서는 한 파일에서는 userId를 사용하고 다른 파일에서는 id를 사용합니다. 세션 5에서는 새로운 기능이 profiles 테이블을 생성하는데, 에이전트가 users 테이블에 프로필 필드가 있다는 것을 몰랐기 때문에 기존 users 테이블과 부분적으로 중복되는 테이블을 만들게 됩니다.
이러한 개별적인 실수들은 그 자체로 치명적이지는 않습니다. 하지만 이들이 모이면 앱의 서로 다른 부분들이 동일한 데이터에 대해 조금씩 다른 멘탈 모델 (Mental Model)을 갖게 되는 코드베이스를 만들게 되며, 디버깅을 할 때 각 파일이 어떤 가정을 바탕으로 작동하고 있었는지 파악해야 하는 상황을 초래합니다.
데이터 레이어 (Data Layer)를 다시 유도하는 것이 가장 비용이 많이 드는 이유
모든 컨텍스트 (Context)를 다시 생성하는 비용이 동일하게 비싼 것은 아닙니다. UI 패턴은 다시 유도하기 저렴합니다. 기존 컴포넌트로부터 많은 것을 추론할 수 있기 때문입니다. 비즈니스 로직 (Business Logic)은 중간 정도의 비용이 듭니다. 대개 에이전트가 읽을 수 있는 코드 내에 인코딩되어 있기 때문입니다. 하지만 데이터 레이어 (Data Layer)는 다음과 같은 이유로 비용이 많이 듭니다.
- 진실의 근원 (Ground Truth)이 항상 코드에 있는 것은 아닙니다. 당신의 데이터베이스는 별도의 시스템에 존재합니다. 만약 에이전트가 데이터베이스를 쿼리할 수 없다면, 에이전트는 사용 가능한 마이그레이션 (Migration) 파일, 주석, 또는 API 응답 등을 읽게 되는데, 이는 불완전한 정보입니다.
- 컨벤션 (Conventions)은 중요하지만 눈에 보이지 않습니다. snake_case를 사용하기로 한 선택, 모든 테이블에 created_at 타임스탬프를 넣는 것, 이메일에 유니크 (Uniqueness) 제약을 거는 것 등은 애플리케이션 코드가 아니라 스키마 (Schema)와 당신의 머릿속에 존재합니다.
- 관계 (Relationships)가 항상 명시적인 것은 아닙니다. 마이그레이션 파일의 외래 키 (Foreign Key)는 에이전트에게 하나의 관계만을 알려줍니다. 시각적 데이터 모델 (Visual Data Model)은 아직 명시적인 코드가 없는 관계를 포함하여 모든 관계를 알려줍니다.
에이전트가 데이터 레이어를 잘못 유도하면, 단순히 틀린 코드를 얻는 것에 그치지 않습니다. 잘못된 모델과 내부적으로 일관성을 유지하는 코드를 얻게 되는데, 이는 명백하게 고장 난 코드보다 수정하기가 더 어렵습니다.
해결책: 스키마를 권위 있고 기계가 읽을 수 있게 만들기
스키마 우선 (Schema-first) 워크플로우는 재구축 사이클의 근본 원인을 차단합니다. 에이전트가 매 세션마다 데이터 모델을 다시 유도하는 대신, 권위 있는 최신 스키마를 직접 읽게 합니다. 이 해결책은 두 부분으로 나뉩니다.
파트 1: 에이전트가 읽을 수 있는 곳에 데이터 모델을 한 번만 정의하기
이는 당신의 데이터 모델이 단순히 당신의 머릿속이나 주석, 또는 README 파일이 아니라, 기계가 읽을 수 있는 어딘가에 존재해야 함을 의미합니다. 옵션은 다음과 같습니다:
- 자기 성찰(Introspection) 기능이 있는 라이브 데이터베이스: MCP 서버가 연결된 Postgres 데이터베이스를 사용하면, 에이전트가 각 세션 시작 시 실제 스키마(Schema)를 쿼리할 수 있습니다.
- 자기 성찰(Introspection) 기능이 활성화된 GraphQL API: GraphQL의 자기 성찰 쿼리는 모든 타입(Type), 필드(Field), 관계(Relationship)를 기계가 소비할 수 있도록 설계된 형식으로 전체 스키마를 반환합니다.
- 잘 관리된 스키마 파일: 리포지토리에 커밋된 TypeScript 인터페이스, Prisma 스키마 또는 GraphQL SDL 파일입니다. 동적이지는 않지만 읽기 쉽습니다.
파트 2: 에이전트에게 행동하기 전에 이를 읽으라는 규칙을 부여하기
"데이터베이스 관련 코드를 작성하기 전에 스키마를 자기 성찰(Introspect)하라"라고 명시된 AGENTS.md 또는 .cursor/rules 항목은, 기계가 읽을 수 있는 스키마를 에이전트가 건너뛰는 대신 능동적으로 사용하는 요소로 바꿔줍니다.
이 두 가지 변화를 결합하면, 에이전트는 추측에 기반한 모델이 아니라 당신의 데이터 레이어(Data layer)에 대한 정확한 모델을 가지고 매 세션을 시작하게 됩니다.
Momen이 이 패턴을 구현하는 방법
Momen은 바로 이 원칙을 중심으로 설계된 비주얼 백엔드(Visual backend)입니다. 당신은 Momen의 비주얼 에디터에서 테이블, 관계, 필드 타입, 제약 조건(Constraints)과 같은 데이터 모델을 한 번만 정의하면 됩니다. 에디터는 전체 모델을 자기 성찰(Introspection) 기능이 활성화된 타입 지정(Typed) GraphQL API로 노출합니다.
Claude Code나 Cursor가 플러그인 또는 MCP를 통해 Momen에 연결하면, 에이전트가 가장 먼저 하는 일은 스키마를 자기 성찰(Introspect)하는 것입니다. 새로운 세션의 첫 번째 프롬프트가 입력되기 전에 모든 필드 이름, 타입, 관계 및 사용 가능한 액션플로우(Actionflow)를 사용할 수 있습니다. 권위 있는 소스(Authoritative source)에 직접 접근할 수 있기 때문에 다시 유도(Re-derive)할 것이 아무것도 없습니다.
새로운 테이블을 추가하거나 필드 타입을 변경하면, 에이전트의 다음 세션에서 업데이트 사항이 자동으로 반영됩니다. 문서를 업데이트하거나 채팅창에 스키마 발췌본을 붙여넣을 필요가 없습니다. 당신은 모델을 변경하기만 하면 되고, 에이전트는 그 변경 사항을 읽습니다.
Momen의 API 레이어가 시각적 데이터 모델을 외부 도구에 어떻게 노출하는지에 대한 자세한 내용은 Beyond the Visual Editor를 참조하시고, 여러 세션에 걸친 스키마 우선 개발 (schema-first development)의 구체적인 사례는 How I Built a Legal Intake and Triage App with Claude Code and Momen Backend를 참조하세요.
Momen의 데이터베이스 설정 문서에는 에이전트가 읽게 될 스키마가 되는 데이터 모델을 설정하는 방법이 설명되어 있습니다.
실제 워크플로우 (The Workflow in Practice)
스키마 우선 (schema-first) 세션은 다음과 같이 진행됩니다:
- 새로운 세션이 시작됩니다. SessionStart 훅 (Claude Code의 경우) 또는 초기 MCP 연결 (Cursor의 경우)이 현재 스키마를 로드합니다.
- 에이전트가 권위 있는 (authoritative) 데이터 모델을 읽습니다. 당신이 아무것도 입력하기 전에 에이전트는 이미 모든 기존 테이블, 필드 이름, 타입, 그리고 관계를 알고 있습니다.
- 당신이 새로운 기능을 요청합니다. 에이전트는 당신의 실제 데이터 모델과 호환되는 코드 — 즉, 정확한 컬럼 이름, 정확한 타입, 정확한 관계 — 를 생성합니다.
- 당신이 데이터 모델을 업데이트합니다. Momen의 시각적 에디터에서 새로운 테이블이나 필드를 추가합니다. 스키마가 즉시 변경됩니다.
- 다음 세션이 새롭게 시작되지만, 정보가 반영된 상태로 시작됩니다. 에이전트는 업데이트된 스키마를 읽습니다. 에이전트는 새로운 테이블에 대해 알고 있습니다.
에이전트가 추측을 하지 않기 때문에 재구축 사이클 (rebuild cycle)이 깨집니다. 에이전트는 항상 읽을 수 있는 정확한 정보를 가지고 있습니다.
요약 (Summary)
AI 코딩 도구들이 당신의 앱을 처음부터 다시 만드는 이유는 세션 간에 당신의 데이터 모델에 접근할 수 없기 때문입니다. 그래서 도구들은 추론 (inference)을 통해 모델을 다시 도출하며, 이 추론 과정에서 드리프트 (drift, 편차)가 발생합니다. 해결책은 스키마 우선 개발 (schema-first development)입니다. 데이터 모델을 기계가 읽을 수 있고 자기 성찰 (introspectable)이 가능한 형식으로 한 번 정의하고, 에이전트가 행동하기 전에 이를 읽도록 규칙을 부여하는 것입니다.
Momen과 같은 시각적 백엔드 (visual backend)는 설계 단계부터 이를 간단하게 만들어 줍니다. 모델을 시각적으로 정의하고, GraphQL API가 이를 노출하도록 하며, AI 코딩 도구에 연결하면 에이전트가 매 세션마다 실제 데이터를 읽게 됩니다. 데이터 계층 (data layer)은 더 이상 불일치의 원인이 아니라, 매 세션을 이전보다 더 정확하게 만드는 안정적인 기반이 됩니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기