Skip to content

ADR-14: AI 기반 스펙 문서 생성 파이프라인

🇺🇸 English Version

날짜작성자리포지토리
2026-01-18@KubrickCodeworker, web, infra

배경

문제 정의

Specvital 플랫폼에서 테스트 파일 컬렉션을 사람이 읽을 수 있는 스펙 문서로 자동 변환 필요. 두 가지 인지 작업 포함:

  1. 분류: 도메인 및 기능별 테스트 그룹화 (의미적 이해)
  2. 변환: 테스트 이름을 동작 설명으로 변환 (언어 생성)

요구사항

요구사항설명
규모수천 개의 테스트가 있는 리포지토리 처리 (청크당 최대 500개 이상)
비용대량 처리를 위한 비용 효율적 모델 선택 필요
일관성청크 간 도메인 할당의 일관성 유지
신뢰성프로덕션 시스템에 장애 허용 및 우아한 저하 필요
지연Gemini 서버 측 5분 타임아웃이 요청당 범위 제약

제약사항

제약사항영향
PostgreSQL 백엔드기존 River 큐 인프라와 캐싱 통합
Content-Hash 캐싱(content_hash, language, model_id)로 문서 인덱싱
Worker 아키텍처기존 워커 서비스 패턴과 통합 필수
쿼터 시스템캐시 히트 시 사용자 쿼터 미소비 (ADR-13)

결정

Google Gemini 모델을 사용하는 2단계 AI 파이프라인과 대규모 리포지토리 처리를 위한 순차적 청킹 및 앵커 전파 채택.

파이프라인 아키텍처

Phase 1: 분류 (gemini-2.5-flash)
├── 입력: 테스트 파일 + 도메인 힌트
├── 청킹: 청크당 최대 500개 테스트, 50K 토큰
├── 출력: 도메인 그룹화, 기능 할당, 신뢰도 점수
└── 앵커 전파: 청크 간 도메인 결정 유지

Phase 2: 변환 (gemini-2.5-flash-lite)
├── 입력: 기능별 테스트 배치
├── 동시성: 최대 5개 병렬 API 호출
├── 출력: 테스트 이름 → 동작 설명
└── 폴백: 실패 시 원본 테스트 이름 + 0.0 신뢰도

설정

파라미터근거
Phase 1 타임아웃270초Gemini 5분 서버 제한 이하
Phase 2 전체 타임아웃7분대규모 기능 세트 처리 허용
Phase 2 기능 타임아웃90초부분 성공을 위한 기능별 격리
Phase 2 동시성5API 속도 제한과 처리량 균형
청크 간 지연5초청크 간 속도 제한 준수
청크당 최대 테스트500504 오류 방지를 위해 1000에서 축소
청크당 최대 토큰50,000응답 60초 이내 유지
Thinking 모드비활성화구조화된 작업의 비용 최적화

신뢰성 패턴

메커니즘Phase 1Phase 2
서킷 브레이커 임계값5회 실패3회 실패
재시도 횟수3회2회
백오프 전략지수적지수적
속도 제한기전역 공유전역 공유

캐싱 전략

  • 캐시 키: (content_hash, language, model_id)
  • 캐시 히트 시 쿼터 소비 없이 기존 문서 반환
  • 계층적 스키마: spec_documents → spec_domains → spec_features → spec_behaviors

검토한 옵션

A. LLM 제공자 선택

옵션결론
Gemini 2.5 Flash (선택)1M 토큰 컨텍스트, $0.30/1M 비용 효율적, Phase 2용 Flash-Lite
Claude 3.5/Opus 4.5우수한 추론이나 $5/1M (17배 비쌈), 200K 컨텍스트 제한
GPT-4o/GPT-5.x광범위한 생태계이나 $2-3/1M, 128K 컨텍스트 제한

선택 근거:

  • 비용 효율성: Flash $0.30/1M, Flash-Lite $0.10/1M 토큰
  • 컨텍스트 윈도우: 1M 토큰 용량으로 복잡한 청킹 없이 대규모 테스트 파일 처리
  • 작업 적합성: 분류와 변환은 고급 추론이 필요 없는 구조화된 작업
  • 2단계 가용성: 분류 품질용 Flash, 대량 변환용 Flash-Lite

B. 파이프라인 아키텍처

옵션결론
2단계 (분류 → 변환) (선택)관심사 분리, 다른 비용 프로필, 독립적 실패 도메인
단일 패스 파이프라인더 단순하나 디버깅 어려움, 전부 아니면 전무 실패
의미적 분석 포함 다중 패스최고 품질이나 3+ API 호출, 복잡한 오케스트레이션

선택 근거:

  • 작업 전문화: 분류와 변환은 다른 최적 프롬프팅 전략 보유
  • 비용 최적화: Phase 2에서 더 저렴한 Flash-Lite 모델 사용
  • 실패 격리: Phase 2 실패 시 Phase 1 분류 손실 없이 폴백 가능
  • 독립적 튜닝: 각 단계 개별 최적화 가능

C. 대규모 리포지토리 처리

옵션결론
앵커 전파를 통한 순차 청킹 (선택)예측 가능한 메모리, 앵커를 통한 일관된 도메인 할당
병렬 청킹최대 처리량이나 청크 간 도메인 불일치
스트림 처리최소 메모리이나 문서 간 컨텍스트 없음

선택 근거:

  • 일관성: 앵커 도메인이 청크 간 전파되어 "기능 드리프트" 방지
  • 속도 제한 준수: 청크 간 지연(5초)이 자연스럽게 API 제한 준수
  • 디버깅 용이성: 명확한 청크 경계로 특정 입력 부분집합의 문제 재현 가능
  • 메모리 예측 가능성: 고정 청크 크기로 OOM 방지

구현 세부사항

모델 설정

결정론적 출력 설정:

파라미터근거
Temperature0.0재현 가능한 출력을 위한 무작위성 제거
Seed42일관된 분류를 위한 고정 시드
MaxOutputTokens65,536잘림 방지를 위한 Gemini 최대값
ResponseMIMETypeapplication/json구조화된 출력 강제
ThinkingBudget0동적 Thinking 오버헤드 비활성화

토큰 사용량 추적

비용 모니터링을 위한 분석별 실시간 토큰 추적:

go
type TokenUsage struct {
    CandidatesTokens int32   // 출력 토큰
    Model            string  // 모델 식별자
    PromptTokens     int32   // 입력 토큰
    TotalTokens      int32   // 입력 + 출력 합계
}
  • GenerateContentResponse.UsageMetadata에서 추출
  • analysis_id별 Phase 1/2 호출 전체 집계
  • 구조화된 로그 출력: specview_token_usage

근거: Google AI Studio 사용량 통계는 약 1일 지연되어 커스텀 추출 없이는 실시간 리포지토리별 비용 추적 불가능.

청크 크기 진화

504 DEADLINE_EXCEEDED 오류 해결을 위한 점진적 축소:

반복테스트/청크결과
초기10,000JSON 잘림
v23,000대규모 리포에서 여전히 504 오류
v31,000개선되었으나 간헐적 타임아웃
최종500안정적인 15-25초 처리 시간

프롬프트 엔지니어링

Phase 1 (분류):

  • 신뢰도 점수화를 통한 분류 제약 조건
  • 출력 형식을 위한 언어별 지침
  • 분석 결과의 도메인 힌트 통합

Phase 2 (변환):

  • "명세 표기법" 스타일: 동작이 아닌 완료 상태
  • 예: "사용자가 성공적으로 인증됨" ("사용자가 인증할 수 있어야 함" 아님)
  • 다운스트림 필터링을 위한 신뢰도 점수화

오류 처리 흐름

Phase 1 실패
├── 재시도 (지수 백오프로 최대 3회)
├── 연속 5회 실패 후 서킷 브레이커 작동
└── 작업 실패 표시, 부분 결과 없음

Phase 2 실패 (기능별)
├── 재시도 (최대 2회)
├── 폴백: 원본 테스트 이름 + 0.0 신뢰도
└── 다른 기능 처리 계속

재시도 가능 오류 패턴:

go
retryablePatterns := []string{
    "rate limit", "quota exceeded", "too many requests",
    "service unavailable", "internal server error", "timeout",
    "connection reset", "connection refused", "temporary failure",
}

JSON 파싱 오류 처리: Gemini가 간헐적으로 잘린 JSON 응답 반환. JSON 파싱 오류는 RetryableError로 래핑하여 지수 백오프를 통한 자동 재시도 트리거.

데이터 흐름

┌─────────────────────────────────────────────────────────────────────┐
│                    SpecView 생성 파이프라인                          │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ┌─────────────┐     ┌─────────────────────┐     ┌──────────────┐  │
│  │ Analysis    │────▶│  Phase 1: 분류      │────▶│ Phase 2:     │  │
│  │ 결과        │     │  (gemini-2.5-flash) │     │ 변환         │  │
│  │ + 힌트      │     │                     │     │ (flash-lite) │  │
│  └─────────────┘     └─────────────────────┘     └──────┬───────┘  │
│                                                          │          │
│                                                          ▼          │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │                     PostgreSQL                               │   │
│  │  spec_documents                                              │   │
│  │    └── spec_domains                                          │   │
│  │          └── spec_features                                   │   │
│  │                └── spec_behaviors                            │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

결과

긍정적

영역이점
비용 효율성$0.10/1M 토큰의 Flash-Lite로 Phase 2 비용 60%+ 절감
신뢰성서킷 브레이커와 폴백으로 완전한 실패 대신 저하된 운영 보장
확장성청킹으로 예측 가능한 리소스로 모든 규모의 리포지토리 처리
캐시 통합Content-hash 캐싱으로 중복 처리 및 쿼터 소비 방지
관측 가능성2단계 분리로 명확한 메트릭 경계 제공
일관성앵커 전파로 도메인 명명 일관성 유지

부정적

영역트레이드오프
지연순차 청킹으로 리포지토리 크기에 비례한 처리 시간 증가
벤더 종속깊은 Gemini 통합으로 제공자 변경 시 마이그레이션 노력 필요
지원 중단 위험Gemini 2.5 Flash 2026년 6월 지원 중단 예정
품질 한계복잡한 테스트 계층 구조에서 Gemini 분류 정확도가 Claude보다 낮음
폴백 품질Phase 2 폴백(원본 테스트 이름)은 의미적 개선 미제공
Thinking 비활성화비용 최적화로 잠재적 품질 향상 교환

기술적 시사점

측면시사점
스키마계층적: spec_documents → spec_domains → spec_features → spec_behaviors
캐시 키(content_hash, language, model_id)로 모델 버전 인식 캐싱 가능
타임아웃 설계270초 Phase 1 타임아웃으로 Gemini 5분 서버 제한 이하 유지
동시성 모델전역 공유 속도 제한기가 단계 간 조정
오류 복구신뢰도 점수화로 저품질 변환의 다운스트림 필터링 가능

참조

Open-source test coverage insights