RAG로 코드 생성 품질을 통제하기

Kirogramer·2026년 1월 29일

AI

목록 보기
2/10
post-thumbnail

왜 AI가 뱉는 코드는 늘 아쉽게 느껴질까

요즘 개발자라면 누구나 한 번쯤 이런 경험이 있으실 겁니다.

  • 문법은 맞는데 우리 프로젝트 스타일은 아니다
  • 동작은 되지만 유지보수가 어려운 코드
  • “이렇게 짜면 안 되는데…” 싶은 구조
  • 팀 컨벤션, 레이어 구조, 네이밍을 전혀 고려하지 않은 코드

이 문제를 프롬프트로 해결하려고 하면 보통 이렇게 됩니다.

“클린하게 작성해줘”
“실무에서 쓰는 코드로 작성해줘”
“가독성 좋게”

하지만 결과는 늘 비슷합니다.
이유는 간단합니다.

LLM은 ‘좋은 코드’가 아니라
‘자기가 학습한 평균적인 코드’를 생성하기 때문입니다.

AI에게
“우리 팀에서 말하는 좋은 코드가 무엇인지”를 명확하게 알려주지 않으면, 원하는 결과는 나오지 않습니다.

이 지점에서 RAG는 선택이 아니라 필수가 됩니다.


이 글에서 말하는 RAG의 정의

이 글에서 다루는 RAG는 검색형 챗봇 이야기가 아닙니다.

“AI 코드 생성을 통제하기 위한 레퍼런스 주입 구조”

입니다.

즉, 코드 컨벤션, 아키텍처 규칙, 좋은/나쁜 코드 예제, 팀 내부 베스트 프랙티스를 검색 가능한 형태로 제공하고 AI가 그것을 기준으로 코드 생성을 하게 만드는 구조입니다.


프롬프트 기반 코드 생성의 구조적 한계

프롬프트는 ‘요청’일 뿐, ‘규칙’이 아닙니다

“React 컴포넌트를 클린하게 작성해줘”

AI 입장에서는 이런 의미입니다.

“클린하다고 여겨지는 수많은 방식 중 하나를 선택”

즉,

  • 함수형? 클래스형?
  • 비즈니스 로직 분리? 한 파일?
  • 네이밍 규칙?
  • 에러 처리 방식?

모두 AI의 재량입니다.

코드 스타일은 프롬프트로 고정되지 않습니다

아무리 길게 써도 이런 한계가 있습니다.

  • 다음 질문에서 다시 흔들림
  • 코드 길어질수록 일관성 붕괴
  • 프로젝트 맥락을 잊어버림

이건 LLM의 문제가 아니라 구조의 문제입니다.

RAG 기반 코드 생성의 핵심 아이디어

관점을 바꿔야 합니다

❌ “AI에게 잘 설명하자”
✅ “AI가 참고할 정답 코드를 제공하자”

AI는 생각하지 않습니다.
비슷한 패턴을 따라할 뿐입니다.


어떤 코드를 RAG에 넣어야 하는가

여기서 많은 분들이 실수합니다.

흔한 실수

  • 코드 전체 저장
  • 레거시 코드까지 모두 포함
  • 스타일이 섞인 코드

결과: AI도 갈피를 못 잡음


RAG에 적합한 코드의 조건

RAG에 넣을 코드는 다음 조건을 만족해야 합니다.

1.이 코드 스타일을 계속 유지하고 싶은가
2.신입에게 “이렇게 짜라”고 보여줄 수 있는가
3.나중에 고치고 싶지 않은 구조인가

이 질문에 “예”라고 답할 수 있는 코드만 넣어야 합니다.


예시: React 기준 좋은 코드 스니펫

// hooks/useUser.ts
export function useUser(userId: string) {
  return useQuery({
    queryKey: ['user', userId],
    queryFn: () => fetchUser(userId),
    staleTime: 5 * 60 * 1000,
  });
}

이 코드가 좋은 이유는 명확합니다.

  • 비즈니스 로직 분리
  • queryKey 규칙 명확
  • 옵션이 선언적으로 드러남

이런 코드만 RAG에 들어가야 합니다.

“좋은 코드 / 나쁜 코드”를 같이 넣어야 합니다

이게 굉장히 중요합니다.
AI는 “이건 하면 안 된다”를 명시적으로 알려줘야 잘 따릅니다.

나쁜 예제

useEffect(() => {
  fetch('/api/user')
    .then(res => res.json())
    .then(setUser);
}, []);

좋은 예제

const { data: user } = useUser(userId);

이 두 코드를 한 쌍으로 RAG에 넣고 메타데이터를 붙입니다.

{
  "type": "bad_example",
  "reason": "side-effect가 컴포넌트에 직접 포함됨"
}
{
  "type": "good_example",
  "reason": "데이터 로직을 hook으로 분리"
}

이 방식은 코드 품질을 비약적으로 안정화시킵니다.

코드 컨벤션을 “문서”가 아니라 “규칙”으로 주입하기

보통 컨벤션 문서는 이런 식입니다.

- hooks는 use로 시작한다
- 비즈니스 로직은 분리한다

하지만 AI에게는 너무 추상적입니다.

코드 컨벤션도 “예제 중심”으로

// ❌ 잘못된 네이밍
const getData = () => {}

// ✅ 컨벤션에 맞는 네이밍
const fetchUserProfile = () => {}
// ❌ 한 파일에 몰아넣은 로직
Component.tsx

// ✅ 역할 기준 분리
Component.tsx
useComponent.ts
component.type.ts

말보다 코드가 훨씬 강력합니다.


RAG 기반 코드 생성 흐름

1. 사용자 요청
2. 생성하려는 코드 유형 분류
   (컴포넌트 / 훅 / API / 유틸)
3. 해당 유형의 베스트 코드 검색
4. 컨벤션 / 금지 패턴 주입
5. 코드 생성

프롬프트 예시

아래 예제 코드와 동일한 스타일을 유지하세요.
나쁜 예제 패턴은 사용하지 마세요.

[좋은 예제]
...

[나쁜 예제]
...

이 한 줄 차이로 결과물의 일관성이 완전히 달라집니다.


RAG 기반 코드 생성이 가져오는 변화

기존

  • “이번엔 좀 괜찮네?”
  • 매번 결과물 검수
  • 코드 리뷰 비용 증가

이후

  • 스타일이 거의 고정됨
  • 리뷰 포인트 감소
  • AI를 “코드 생성기”가 아니라 팀원처럼 사용 가능

정해주고 시키는게 가장 효과가 좋습니다

AI 코드 품질은 모델보다 입력 코드의 품질에 좌우됩니다

RAG는 검색이 아니라 통제 장치

좋은 코드 예제를 모으는 과정 자체가 팀의 암묵지를 명문화하는 작업입니다
결국 RAG는 AI를 길들이는 가장 현실적인 방법입니다


AI에게 “잘 짜라”고 말하는 시대는 끝났습니다.
이제는

“이렇게 짜라”고
실제 코드를 보여줘야 하는 시대

입니다.

RAG는 AI를 똑똑하게 만드는 기술이 아니라 개발자의 기준을 강제하는 기술입니다.
이 관점에서 RAG를 설계하면 AI는 생각보다 훨씬 쓸만한 동료가 됩니다.

profile
기로그래머

0개의 댓글