ADR-009 — LLM column name normalisation + description generation (Phase 2-4)
| 항목 | 값 |
|---|---|
| Status | Proposed (2026-05-25 — #849 Phase 2-4 design) |
| Date | 2026-05-25 |
| Decider | GenD 코어팀 + AI/LLM owner |
| Related Epic | #849 (LLM-based column normalisation + COMMENT/description + Text2SQL) |
| Related ADR | ADR-002 (Alembic), ADR-006 (Ontology Layered Packaging) |
| Phase 1 Status | ✅ Merged — PR #1062 (column_metadata table + Catalog API comment join) |
본 ADR 의 한 줄 결정: Phase 1 의
column_metadataPG 백엔드를 토대로, Phase 2 (UI option panel) / Phase 3 (LLM normalisation endpoint) / Phase 4 (Text2SQL agent 프롬프트 enrichment) 를 직렬 수행한다. 사용자가 옵트인 한 컬럼 정규화 + 설명 자동 생성이 catalog 의 가시 description 으로 적재되어 Text2SQL agent 가 자동 활용한다.
컨텍스트
#848 의 괄호 안 영문 우선 정규화는 한국 데이터셋의 일반적 패턴을 풀어주지만, 패턴 부합 안 하는 컬럼은 여전히 col_{idx} fallback. Iceberg 테이블에 컬럼 description / comment 가 없어 Text2SQL Agent 가 의미 파악 어려움.
Phase 1 (PR #1062, 2026-05-25) 으로 column_metadata 테이블과 Catalog API 의 comment join 이 완료되어, 이제 LLM 기반 정규화 작업이 backend foundation 위에서 가능.
결정
Phase 2 — UI option panel (이번 Step)
위치: ui/src/components/ingestion/CsvIngest/MappingStep.tsx (또는 동등 매핑 단계).
┌─────────────────────────────────────────────────────────┐
│ ☐ LLM 자동 정규화 사용 │
│ 추가 지침 (선택): │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 예: "한국어 약어는 풀어쓰고, 시간 컬럼은 │ │
│ │ timestamp 라는 단어를 포함하라" │ │
│ └─────────────────────────────────────────────────┘ │
│ [ 일괄 정규화 실행 ] │
└─────────────────────────────────────────────────────────┘
가드:
- 체크박스 옵트인 — 기본 OFF. CSV ingestion 흐름의 비파괴 옵션.
- ≤50 컬럼 제한 — 50 초과 시 disabled + "컬럼 수가 많아 LLM 정규화를 사용할 수 없습니다" toast.
- 결과 inline 표시 — 컬럼당
suggested_name/suggested_comment/reasoning을 매핑 표에 추가. 사용자가 수동 수정 유지. - 재실행 가능 — "다시 정규화" 버튼이 이전 결과를 덮어쓰지 않고 새 row 로 표시 (history).
Phase 3 — LLM normalisation endpoint
POST /api/v1/ingestion/csv/staging/{staging_id}/llm-normalize
Body: {
additional_guidance?: str, # ≤1000 chars
max_columns?: int = 50 # hard cap 50
}
Response (201): {
staging_id,
suggestions: [
{
source_index: int,
original_name: str,
suggested_name: str, # must match _IDENTIFIER_RE
suggested_comment: str, # ≤500 chars
reasoning: str # 사람용 설명
}, ...
],
llm_provider: "anthropic",
llm_model: "claude-sonnet-4-20250514",
tokens_used: int,
cost_usd: float,
}
구현:
llm_proxy_service.call_with_context재사용 (Anthropic + prompt caching).- 샘플 데이터 분석:
- numeric 컬럼: 상/중/하위 sample 5개 + min/max/avg.
- string 컬럼: 유니크 sample 랜덤 5개.
- timestamp/date: 가장 최근/오래된 3개.
- 사용자
additional_guidance는 system prompt 의 별도 section 으로 주입 (prompt injection 방어 위해 strict text-only). - 429 retry: 메모리
feedback_anthropic_caching_retry의 _RETRYABLE_STATUS_CODES 패턴. - 사용량 로그:
LlmCallLog테이블 (이미 존재) 에 audit 적재. - 결과는 응답으로만 반환 —
column_metadata적재는 commit 단계에서.
Phase 4 — Text2SQL agent 프롬프트 enrichment
apps/api/src/gend_api/services/ai_*가 카탈로그 컬럼을 가져올 때ColumnDetail.comment가 있으면 Trino 프롬프트의 schema 블록에COMMENT 'desc'형태로 자동 포함.- 토큰 한도 관리:
comment가 컬럼당 ≤200 token 으로 truncate (긴 텍스트는…로 잘림). 테이블 컬럼 수가 많을 때 (≥30)comment우선 truncate. - 프롬프트 캐싱: schema 블록은 cache_control ephemeral 로 marking (메모리
feedback_anthropic_caching_retry).
Phase 2 → Phase 4 데이터 흐름
영향
- 영향 자식 이슈: #849 (본 ADR 의 Phase 2-4 구현). Phase 1 (#1062) 이미 머지.
- 새 의존: anthropic SDK (이미 사용). prompt caching key (메모리
feedback_anthropic_caching_retry). - 비용: Sonnet 4 + caching 사용 시 50 컬럼 정규화 1회 ≈ $0.001-0.003 (입력 캐시 hit 가정). admin 권한 한정 / 일일 한도 (10회/사용자) 적용.
- 회귀 가드:
- Phase 3 endpoint: prompt injection (additional_guidance 에 system role override 차단) 회귀 가드 테스트.
- Phase 3 endpoint: max_columns 50 hard cap 검증.
- Phase 4:
ColumnDetail.comment가None인 컬럼은 schema 블록에서-- no description으로 표기 (Text2SQL 에 알려줘 hallucination 방지).
- 운영: LlmCallLog 에 normalisation 호출이 audit 으로 적재되어 PII 마스킹 / DLP 후처리 대상.
비목표
- multi-table 일괄 정규화: 본 Phase 는 staging 1건 단위. 여러 테이블 동시 정규화는 Phase 5+ 로 미루기.
- 자동 PII 식별: Phase 4 의 comment 가 PII 후보를 암시하더라도
PIIColumnRegistry등록은 별도 (PIIService.scan_columns()). - 다국어 description: 본 Phase 는 KO/EN 단일. multi-lang 은 향후
language파라미터 추가로 확장. - 사용자 편집 후 LLM 재학습: 본 Phase 는 one-shot. RLHF / 사용자 수정 패턴 학습은 별도.
재검토 트리거
- LLM 비용 / latency 가 사용성 한계 초과 → embedding-only fallback (의미 유사도 기반 normalisation).
- Iceberg / Hive COMMENT round-trip 지원 →
column_metadata의 source-of-truth 위치 재검토 (PG only vs Iceberg sync). - Text2SQL agent 의 토큰 한도 (200k 등) 초과 → schema 블록 lazy-load 또는 RAG 화.