모노레포가 거대하면 Claude Code의 답변이 벗어날 수 있습니다. 경계 설정, 로컬 요약, 반복 가능한 워크플로로 답변의 정확성을 유지하는 방법을 알아보세요.

모노레포에서 Claude Code가 예측 불가능하게 느껴지는 이유는 단순합니다: 레포가 모델이 한 번에 작업 메모리에 담을 수 있는 양보다 큽니다.
“컨텍스트”란 Claude가 이 작업을 위해 본 파일, 스니펫, 노트, 지침과 그로부터 추론한 내용을 합친 것입니다. 핵심 정보가 빠지면 Claude는 빈칸을 추측으로 메웁니다. 큰 레포일수록 이런 일이 더 자주 발생합니다.
세 가지 실패 모드는 자주 반복됩니다:
첫째, 놓친 파일들. 한 폴더에서 안전해 보이는 변경이 실제로는 공유 타입, 설정 규칙, 또는 다른 곳에 정의된 빌드 단계에 의존할 수 있습니다. 그 의존성이 컨텍스트에 없으면 Claude는 자신 있게 잘못된 파일을 수정하거나 진짜 진실의 원천을 보지 못해 중간에 멈출 수 있습니다.
둘째, 잘못된 유사성. 모노레포는 종종 서로 닮아 보이는 여러 패키지를 포함합니다: 인증 모듈 두 개, API 클라이언트 세 개, 또는 비슷한 폴더 구조를 가진 여러 React 앱 등. Claude는 이들 간의 패턴을 섞어 잘못된 패키지의 헬퍼를 업데이트하거나 “거의 맞는” 모듈명에서 임포트할 수 있습니다.
셋째, 시간에 따른 변화(타임 드리프트). 큰 코드베이스에는 같은 일을 하는 오래된 방법과 새로운 방법이 공존합니다. Claude가 오래된 파일만 본다면(컨텍스트에 있다면) 팀이 이미 옮겨간 최신 패턴 대신 구식 패턴(더 이상 권장되지 않는 설정 옵션, 레거시 API 등)을 복사할 수 있습니다.
현실적인 예: 청구 UI에 작은 변경을 요청했는데, Claude가 앱별 래퍼를 보지 못해 다른 앱들에서 공유로 쓰이는 payments 컴포넌트를 편집해 버리는 경우가 있습니다.
목표는 Claude에게 레포 전체를 보여 주는 것이 아닙니다. 목표는 질문에 답하는 데 충분한, 더 작고 의도적인 입력을 제공하는 것입니다: 변경하려는 패키지, 그 직접적인 의존성, 그리고 타입과 설정의 진실의 원천 한두 개. 또한 “건들지 말 것” 영역(다른 앱들, 인프라, 생성된 코드)을 분명히 말하고 어떤 패키지가 해당 동작을 소유하는지 확인하세요.
정확성은 얼마나 많은 코드를 붙여 넣었는지보다 작업을 얼마나 명확히 설명했는지에 더 좌우됩니다.
원하는 결과를 먼저 정하세요: 특정 수정, 리팩터, 또는 답변. “코드에 대한 질문”은 높은 수준에 머물러도 되지만, “변경을 하라”는 요청은 경계, 입력, 성공 체크가 필요합니다.
무엇을 공유하기 전에 다음 문장을 완료하는 한 문장을 쓰세요: “끝난 뒤에 나는 ...할 수 있어야 한다.” 예: “패키지 X의 유닛 테스트를 실패 없이 실행할 수 있다” 또는 “엔드포인트 Y의 API 응답에 새 필드를 볼 수 있다.” 이 문장은 레포가 거대할 때의 북극성(star)이 됩니다.
변경의 경우, 변경이 옳음을 증명할 수 있는 가장 작은 증거 집합을 공유하세요: 진입점, 관련 타입/인터페이스나 스키마, 실패하는 테스트 하나 또는 재현 단계와 기대 결과, 그리고 이 경로에 영향을 주는 설정(라우팅, 기능 플래그, 빌드 또는 린트 규칙). 필요하다면 패키지의 간단한 폴더 맵을 추가해 Claude가 각 디렉터리의 용도를 이해하게 하세요.
무엇을 보지 말아야 할지도 명확히 하세요. 예: “생성된 파일, 벤더 폴더, 빌드 출력물, 스냅샷, 락파일은 내가 요청하지 않는 한 무시하라.” 이렇게 하면 불필요한 시간 낭비와 검토하지 않을 곳에 대한 수정을 막을 수 있습니다.
또한 불확실성에 대한 기대치를 설정하세요. Claude에게 추측 대신 가정과 미지수를 표시하게 하세요. 예: “이 함수가 어디서 호출되는지 볼 수 없으면 그렇게 표시하고, 찾는 방법 2가지를 제안하라.”
큰 모노레포에서 모델이 ‘도움이 된다며’ 작업 범위를 넓히는 순간 정확성이 떨어집니다. 해결책은 간단합니다: 변경 요청 전에 무엇이 범위 안이고 무엇이 범위 밖인지 정의하세요.
레포가 조직된 방식에 맞는 경계부터 시작하세요: 패키지, 서비스, 앱, 또는 공유 라이브러리 등. 예를 들어 “체크아웃 UI 업데이트”라면 경계는 아마도 한 앱 패키지이지, ‘checkout’이라는 단어가 나타나는 모든 곳이 아닙니다.
Claude가 그 범위 안에 머물도록 도와주는 신호로는 폴더 관습(apps/, services/, packages/, libs/), 패키지 매니페스트(내보내기와 의존성), 공개 진입점(index 파일, export된 컴포넌트, 핸들러), 그리고 테스트(의도된 표면을 드러내는 경우가 많음)가 있습니다. 폴더 내부의 README는 가장 빠른 경계 표식이 될 수 있습니다.
경계는 브리지(bridge)를 이름으로 지정할 때 가장 잘 작동합니다. Claude가 건드려도 되는 특정 인터페이스를 명확히 하고 나머지는 금지하세요. 일반적인 브리지로는 HTTP API 계약, 이벤트 토픽과 페이로드, 공유 타입, 또는 소수의 export 함수들이 있습니다.
또한 변경이 영향을 미치면 안 되는 “건들지 말 것” 영역을 명시하세요. 흔한 예: 인프라 및 배포 설정, 보안 및 인증 로직, 청구/결제, 데이터 마이그레이션과 프로덕션 스키마, 다수 팀이 사용하는 공유 라이브러리 등.
도움이 되는 구체적 프롬프트 예시:
“packages/cart/ 및 그 테스트 내부만 변경하세요. packages/types/의 공유 타입은 읽어도 되지만 수정하지 마세요. infra, auth, billing은 건드리지 마세요.”
정확성은 변경하고자 하는 영역의 작고 안정적인 지도를 제공할 때 향상됩니다. “로컬 요약”이란 그 지도입니다: 빠르게 읽을 수 있을 만큼 짧고, 추측을 막을 만큼 구체적이어야 합니다.
각 요약은 10~20줄 정도로 유지하세요. 변경 범위만 건드리는 신규 팀원에게 넘긴다고 생각하고 평이한 언어와 코드 속 실제 이름(폴더, 패키지, export된 함수)을 사용하세요.
유용한 로컬 요약은 다음 다섯 가지 질문에 답합니다:
한 줄의 “gotchas”를 추가하세요. 이 항목은 숨은 캐시, 기능 플래그, 마이그레이션 단계, 조용히 실패하는 것 등 값비싼 실수를 막습니다.
다음은 복사해서 쓸 수 있는 간결한 템플릿입니다:
Local summary: <package/service name>
Purpose: <1 sentence>
Scope: <what to touch> | Not: <what not to change>
Entry points: <files/routes/commands>
Public surface: <exports/endpoints/events>
Data sources: <tables/collections/queues/caches>
Conventions: errors=<how>, logging=<how>, tests=<where/how>
Gotchas: <flags/caching/migrations/edge cases>
예: 청구(billing) 패키지를 편집하는 경우, 인보이스를 만드는 정확한 함수, 데이터베이스 테이블 이름, 재시도 가능한 오류에 대한 규칙을 적으세요. 그러면 Claude는 공유 인증, 설정, 또는 관련 없는 패키지로 돌아다니지 않고 그 경계에 집중할 수 있습니다.
최고의 요약은 Claude가 필요할 때 볼 수 있는 요약입니다. 설명 대상 코드 옆에 두어 무시하기 어렵고 업데이트하기 쉬운 위치에 두세요. 예를 들어 각 패키지, 서비스, 또는 앱 디렉터리에 짧은 SUMMARY.md(또는 README.md의 섹션)를 두는 것이 좋습니다.
간단하고 반복 가능한 구조가 도움이 됩니다. 사람들이 유지관리하도록 짧게 유지하세요:
YYYY-MM-DD - <무엇이 변경되었는지 한 문장>요약은 예측 가능한 이유로 오래됩니다. 요약 업데이트를 별도의 작업으로 보지 말고 타입 정의 업데이트처럼 작업 완료의 일부로 취급하세요.
다음 상황에서 요약을 업데이트하세요: 리팩터로 구조나 이름이 바뀔 때, 새로운 모듈이 주요 방법이 되었을 때, API/이벤트/스키마가 변경되었을 때(테스트가 통과하더라도), 패키지 간 경계가 이동했을 때, 또는 의존성이 제거/교체되었을 때.
실용적인 습관: 변경을 머지할 때 무엇이 바뀌었는지 한 줄의 “Last updated”를 추가하세요. Koder.ai 같은 도구가 코드 변경을 빠르게 도와줄 수 있지만, 요약이 미래의 변경을 정확하게 유지하게 하는 핵심입니다.
정확성은 대화의 속도와 페이싱에도 좌우됩니다. 모델이 거대한 스냅샷에서 추측하도록 하기보다 작은 조각으로 컨텍스트를 얻도록 하세요.
어떤 편집도 하기 전에 Claude가 보고 있는 것과 필요한 것을 설명하도록 요청하세요. 좋은 지도는 짧습니다: 관련 패키지, 흐름의 진입점, 테스트나 타입이 어디에 있는지.
프롬프트 예시:
“이 변경의 지도를 만들어라: 관련 패키지, 주요 흐름, 그리고 가능성 있는 터치 포인트를 적으세요. 아직 코드 제안은 하지 마세요.”
좁은 슬라이스를 고르세요: 하나의 기능, 하나의 패키지, 한 사용자 흐름. 경계를 명확히 하세요(예: “packages/billing-api만 변경. shared-ui나 infra는 건드리지 마세요.”).
통제를 유지하는 워크플로:
Claude가 뭔가를 놓치면 그것을 말해야 합니다. 다음을 쓰게 하세요: (1) Claude가 하고 있는 가정, (2) 그 가정을 반증할 수 있는 방법, (3) 확인을 위해 다음에 필요한 파일들.
예: Invoice 응답에 필드를 추가해야 하는데, Claude가 핸들러, DTO/타입 정의, 테스트 하나를 요청합니다. 당신은 그 파일들만 공유합니다. 채팅 기반 빌더를 쓰든 수동으로 하든 같은 규칙을 적용하세요: 필요한 최소 파일만 제공한 뒤 더 필요할 때만 확장하세요.
잘못된 수정을 방어하는 최선의 방법은 프롬프트 안에 작은 “계약”을 적어넣는 것입니다: 무엇을 건드릴 수 있는지, 성공을 어떻게 판단할지, 지켜야 할 규칙을 명시하세요.
지키기 쉬운 경계로 시작하세요. 수정이 허용되는 곳을 명확히 하고, “건들지 말 것”을 이름으로 적어 유혹을 없애세요.
계약 템플릿 예:
packages/payments/ 아래 파일만 수정할 것.packages/auth/, infra/ 또는 공유 설정을 수정하지 말 것.그런 다음 수락 기준을 정의하세요. 수락 기준이 없으면 Claude는 보기에는 맞는 코드를 만들 수 있지만 레포의 실제 규칙을 어길 수 있습니다.
스타일 제약도 중요합니다. 코드베이스가 이미 사용하는 패턴을 따르도록 지시하세요. 예: “이 패키지의 기존 에러 헬퍼를 사용하라; 새 의존성을 추가하지 말 것; 함수 이름은 camelCase를 따를 것; 새로운 아키텍처 레이어를 도입하지 말 것.”
마지막으로 어떤 편집도 하기 전에 짧은 변경 계획을 요구하세요:
“편집 전에 3–5개 파일과 예상되는 정확한 동작 변화를 적어라. 승인을 기다려라.”
예시:
“청구 총액의 반올림 오류 수정. packages/billing/src/와 packages/billing/test/의 테스트만 편집. 수락 기준: pnpm -C packages/billing test 및 타입체크. 기존 money utils를 사용하고 API 타입을 다시 작성하지 마라. 먼저 4단계 계획을 제시하라.”
한 번에 너무 많은 것을 주는 것이 모노레포에서 잘못된 수정을 만드는 가장 빠른 길입니다. 큰 코드 더미를 붙여 넣으면 모델은 특정 디자인 대신 일반적인 패턴으로 되돌아가는 경향이 있습니다.
또 다른 함정은 아키텍처를 추측하게 하는 것입니다. 실제 진입점을 보여주지 않으면 모델은 그럴듯해 보이는 첫 파일을 골라 로직을 연결할 수 있습니다. 실제로 정확성은 소수의 “진실의 원천”(진입 모듈, 라우터, 서비스 레지스트리, 패키지 경계 문서)에 달려 있습니다. 그것들이 컨텍스트에 없으면 모델은 빈칸을 채웁니다.
이름도 함정을 만듭니다. 모노레포에는 ui, ui-kit, shared-ui처럼 비슷한 패키지가 있고, 같은 이름의 헬퍼(date.ts 등)가 여러 곳에 존재합니다. 두 곳의 스니펫을 섞으면 Claude는 한 파일을 패치하면서 다른 파일을 기준으로 추론할 수 있습니다. 예: 버튼 스타일을 변경하라고 하면 packages/ui/Button.tsx를 수정하지만 실제 앱은 packages/ui-kit/Button.tsx를 임포트하는 경우가 있습니다. diff는 괜찮아 보이지만 프로덕션에서는 아무 변화가 없습니다.
설정(config)도 조용한 드리프트의 원인입니다. 동작은 env 변수, 기능 플래그, 빌드 설정, 워크스페이스 툴에 따라 달라질 수 있습니다. 이를 언급하지 않으면 Claude는 “이상한” 체크를 제거하거나 빌드 단계를 깨트리는 코드를 추가할 수 있습니다.
드리프트 신호(레드 플래그):
패키지 간 임포트를 기본값으로 두지 마세요. 범위를 의도적으로 확장하지 않는 한 편집은 지역적으로 유지하세요.
정확한 수정을 얻는 가장 빠른 방법은 양이 아니라 한도를 먼저 두는 것입니다. 좋은 프롬프트는 약간 엄격하게 느껴져야 합니다: Claude가 어디를 볼지, 무엇을 무시할지, “완료”가 무엇인지 알려줍니다.
코드를 붙여 넣기 전에 작업을 레포의 한 지점에 고정하는 짧은 서문을 쓰세요. 패키지, 정확한 폴더, 구체적 목표를 명시하세요. 그런 다음 로컬 요약(목적, 핵심 의존성, 중요한 규약)과 변경의 기준이 되는 진입 파일을 포함하세요.
체크리스트:
<>package</>path에서만. 목표: <one sentence>. 다른 것은 묻지 않는 한 무시.<5-10 줄>. 진입 파일: <path/to/file>.<...>. 변경 금지: <folders/files or APIs>. 유지해야 할 동작: <what must stay true>.Claude가 경계 밖의 변경을 제안하면 그것을 신호로 삼으세요: 프롬프트를 더 엄격히 하거나 범위를 의도적으로 확장하고 다시 명시하세요.
예를 들어 레포에 apps/web-store(React 앱)와 packages/ui-kit(공유 버튼, 입력, 스타일)이 있고, 장바구니 페이지에 “나중에 저장(Save for later)” 버튼을 추가하고 ui-kit의 새 SaveIcon을 쓰길 원한다고 합시다. 다른 건 건드리지 않아야 합니다.
요청 전에 경계 역할을 하는 두 개의 로컬 요약을 만드세요. 짧고 구체적이며 중요 항목에 대해 의견을 갖도록 하세요.
# apps/web-store/LOCAL_SUMMARY.md
Purpose: Customer shopping UI.
Entry points: src/routes.tsx, src/pages/cart/CartPage.tsx
Cart rules: cart state lives in src/cart/useCart.ts
Do not touch: checkout flow (src/pages/checkout), payments, auth.
Tests: npm test -w apps/web-store
# packages/ui-kit/LOCAL_SUMMARY.md
Purpose: shared UI components.
Exports: src/index.ts
Icons: src/icons/*, add new icons by exporting from index.
Do not touch: theming tokens, build config.
Tests: npm test -w packages/ui-kit
그 후 루프를 촘촘히 유지하세요:
CartPage와 ui-kit 아이콘으로 한정. checkout/auth 수정 없음.”CartPage, useCart, ui-kit 아이콘, ui-kit index 등).변경 후 문서화로 미래 컨텍스트를 작게 유지하세요:
한 사람에게 잘 맞아도 팀 전체에 안 통하면 부족한 것은 보통 반복 가능성입니다. “좋은 컨텍스트 위생”을 기본으로 만드세요, 개인 습관이 아니라 팀 표준으로 만드세요.
누구나 복사해서 채워 쓸 수 있는 프롬프트 골격을 저장하세요. 짧지만 엄격하게 유지하세요. 목표(“완료”가 무엇인지), 허용 범위, 필수 경계(및 이유), 로컬 요약, 출력 계약(먼저 계획, 그다음 파일별 diff와 테스트)을 포함하세요.
아무도 하지 않는 큰 월간 리뷰 대신, 변경이 동작, 의존성, 또는 API를 바꾸면 PR에서 요약을 함께 업데이트하도록 하세요.
간단한 규칙: 동료가 “이거 어디에 있지?” 또는 “이게 무엇에 의존하나?”라고 물어본다면 그 요약은 이미 오래된 것입니다.
채팅 우선 워크플로를 선호한다면 Koder.ai가 이런 반복 스타일을 더 안전하게 만들어줄 수 있습니다. 계획 모드는 편집 전에 범위와 경계에 합의하게 도와주고, 스냅샷과 롤백은 추측이 틀렸을 때 빠르게 되돌릴 수 있게 해줍니다.
Claude는 진짜 진실의 근원(source of truth)을 “볼” 수 없을 때 정확도가 떨어집니다.
큰 모노레포에서는 모델이 의존성 파일을 놓치거나, 비슷한 패키스들을 혼동하거나, 컨텍스트에 있던 오래된 패턴을 그대로 복사하는 일이 자주 발생합니다.
레포 전체를 넣으려고 하지 마세요. 변경이 올바른지 증명할 수 있는 최소한의 집합으로 시작하세요.
좋은 기본값은:
동작을 고정하는 파일들을 공유하세요. 이름 때문에 관련 있어 보이는 모든 파일을 주지 마세요.
실용적인 집합은:
레포 구조와 맞는 하나의 경계를 선택하세요: 패키지, 앱, 서비스 등.
그다음 범위를 명시적으로 적고, 범위 밖인 것을 분명히 하세요. 예시 제약:
packages/cart/ 및 그 테스트만 수정하세요.”모노레포에는 비슷하게 보이는 모듈들(ui, ui-kit, shared-ui)이나 중복된 헬퍼(date.ts 등)가 많습니다.
Claude는 올바른 아이디어를 잘못된 패키지에 적용하거나, ‘거의 맞는’ 모듈명에서 임포트할 수 있습니다. 정확한 패키지와 진입점을 명시해 이를 방지하세요.
로컬 요약(local summary)은 변경하려는 정확한 영역의 짧은 지도이며 보통 10–20줄로 작성합니다.
포함할 내용:
요약은 설명 대상 코드 옆에 두어 찾기 쉽고 업데이트하기 쉽게 하세요.
간단한 기본값:
SUMMARY.md나 README.md의 작은 섹션으로 두기Last updated 줄을 갱신하기Claude에게 추측하지 말고 가정과 미지수를 플래그로 표시하라고 지시하세요.
유용한 규칙:
작은 조각으로 컨텍스트를 얻도록 강제하는 촘촘한 루프를 사용하세요:
프롬프트에 작은 ‘계약’을 써 넣고 지키도록 하세요:
이렇게 하면 리뷰가 쉬워지고 의도치 않은 크로스 패키지 수정이 줄어듭니다.