프롬프트 버전 관리 시스템 도입기

문제 상황

제품에 AI 기능이 6개로 늘어나면서 프롬프트가 코드 곳곳에 흩어져 있었다. 프롬프트를 수정할 때마다 배포가 필요했고, 어떤 버전이 더 나은지 비교하기 어려웠다.

설계 방향

  • 프롬프트를 코드에서 분리
  • 버전별로 관리하고 롤백 가능하게
  • A/B 테스트 지원
  • 비개발자도 수정 가능한 UI

구현

PostgreSQL에 간단한 스키마를 만들었다.

CREATE TABLE prompts (
  id UUID PRIMARY KEY,
  key VARCHAR(255) UNIQUE NOT NULL,
  version INTEGER NOT NULL,
  content TEXT NOT NULL,
  variables JSONB,
  is_active BOOLEAN DEFAULT false,
  created_at TIMESTAMP DEFAULT NOW()
);

프롬프트 로더는 캐싱을 적용했다.

class PromptManager {
  private cache = new Map<string, string>();

  async getPrompt(key: string, variables?: Record<string, string>) {
    let template = this.cache.get(key);
    
    if (!template) {
      const result = await db.query(
        'SELECT content FROM prompts WHERE key = $1 AND is_active = true',
        [key]
      );
      template = result.rows[0]?.content;
      this.cache.set(key, template);
    }

    return this.interpolate(template, variables);
  }
}

A/B 테스트

같은 key에 여러 버전을 활성화하고 traffic_split 컬럼으로 분배 비율을 설정했다. 사용자 ID 해시값으로 일관되게 버전을 할당하는 방식이다.

const hash = createHash('md5').update(userId).digest('hex');
const bucket = parseInt(hash.substring(0, 8), 16) % 100;
// bucket 값으로 버전 선택

결과

  • 프롬프트 수정 후 즉시 반영 (배포 불필요)
  • 버전별 성능 지표 수집으로 개선 방향 명확화
  • 기획자가 직접 프롬프트 테스트 가능

간단한 구조지만 AI 기능 개선 속도가 2배 빨라졌다. LangSmith 같은 전문 도구도 있지만, 우리 규모에선 직접 만든 게 더 유연했다.