Translator-Agent와 데이터 품질 관리 체계
1. 초기 Translator-Agent 도입 배경
7월 초, 플랫폼 내 등록된 상품 수가 20만 건을 초과하면서 다국어 데이터 품질 문제가 심각하게 드러났다. 기존에는 외부 번역 API를 호출해 결과를 저장하는 단순 구조였다. 하지만 언어별 품질 편차가 심했고, 카테고리명, 단위, 브랜드명 등이 잘못 번역되는 사례가 누적되었다.
"Steel Pipe"가 태국어로 "철 담배 파이프"로 번역되거나, "12V DC Motor"의 "DC"가 "직류"가 아닌 "워싱턴 D.C."로 해석되는 사례가 실제로 발생했다. 산업 자재 분야의 전문 용어는 일반 번역 모델로는 정확도가 낮다. 수동 교정 인력을 투입하지 않으면서도 번역 품질을 확보하기 위해 "Translator-Agent"를 내부적으로 개발하기로 결정했다.
Translator-Agent의 설계 목표는 다음과 같았다.
- 번역 품질 자동 평가 및 등급화 (MACHINE / HUMAN / APPROVED)
- 다국어 텍스트 캐시 및 중복 요청 제거
- 문장 단위가 아닌 문맥 단위 번역 처리 — 상품 카테고리, 스펙, 단위를 함께 고려
- MQ 기반 병렬 번역 및 품질 피드백 루프 자동화
- 산업 자재 전문 용어 사전(Glossary) 적용
2. 아키텍처 설계 — AI 모델 혼합 전략
Translator-Agent는 MQ 이벤트 소비자로 동작한다.
product.created 또는 i18n.missing 이벤트를 수신하면
해당 상품의 기본 언어 데이터를 조회하고,
두 가지 AI 모델을 혼합하여 번역을 수행한다.
첫 번째 단계에서는 대량 번역에 최적화된 모델이 초안(draft)을 생성한다. 이 초안은 속도가 빠르지만 문맥 이해가 약할 수 있다. 두 번째 단계에서는 문맥 검증 모델이 초안을 상품의 카테고리와 스펙 정보와 대조하여 오역을 보정한다. 이 2단계 파이프라인 덕분에 속도와 품질을 동시에 확보할 수 있다.
def translate_product(evt):
pid = evt["product_id"]
base = db.get_product(pid)
for lang in ["en", "ko", "zh-CN", "th"]:
if lang == base.lang:
continue
# 1단계: 용어 사전 적용 후 대량 번역 모델로 초안 생성
raw = glossary.apply(base.name, base.description, base.specs)
draft = bulk_translator.translate(raw, target=lang)
# 2단계: 문맥 검증 모델로 보정
refined = context_refiner.refine(draft, category=base.category, specs=base.specs)
db.save_translation(pid, lang, refined, quality="MACHINE")
publish("i18n.updated", {"id": pid, "lang": lang})
MQ 큐는 언어별로 분리되어 병렬 처리가 가능했다. 초기에 대량 번역 모델의 API 요청 한도가 낮아 하루 약 3만 건 이상 처리 시 오류가 빈번하게 발생했다. 이 문제는 캐시 구조를 추가하여 이미 번역된 문장은 재요청하지 않도록 수정함으로써 해결했다.
3. 용어 사전(Glossary)과 도메인 특화
산업 자재 분야에서는 일반 번역 모델이 자주 실수하는 용어가 많다. 예를 들어 "Bearing"은 일반적으로 "견디다"로 번역될 수 있지만, 산업 자재에서는 "베어링(축받이)"이 정확한 번역이다. 이런 도메인 특화 용어를 관리하기 위해 Glossary 시스템을 Translator-Agent에 내장했다.
Glossary는 약 8,000개의 산업 용어를 4개 언어로 매핑한 데이터셋이다. 번역 전 원문에서 Glossary에 등록된 용어를 먼저 탐지하고, 해당 용어는 AI 모델의 번역 결과와 관계없이 Glossary 값으로 강제 치환한다. 이 방식으로 브랜드명, 규격 코드, 단위(mm, kg, PSI 등)가 번역 과정에서 왜곡되는 것을 방지한다.
# Glossary 적용 예시
glossary_map = {
"bearing": {"th": "แบริ่ง", "ko": "베어링", "zh": "轴承"},
"stainless steel": {"th": "สแตนเลส", "ko": "스테인리스강", "zh": "不锈钢"},
}
def apply_glossary(text, target_lang):
for term, translations in glossary_map.items():
if term.lower() in text.lower():
text = text.replace(term, translations[target_lang])
return text
4. 중복 번역 방지 및 캐시 전략
두 번째 이슈는 동일 문장이 중복 번역되는 문제였다. MQ 이벤트가 일시적으로 중복 발행되거나, DB 저장 직후 재번역 이벤트가 발행되는 경우에 발생했다. Translator-Agent가 이미 번역된 텍스트를 덮어쓰면서 품질 점수가 불안정하게 변했다.
Redis 기반의 번역 키 해시를 추가했다.
각 번역 요청 전에 hash(content+lang) 키를 조회해
동일 원문+동일 언어의 번역이 이미 존재하는지 확인한다.
이미 존재하면 MQ 메시지를 소비하지 않고 스킵 로그만 남긴다.
key = f"tr:{hashlib.md5((content + lang).encode()).hexdigest()}"
if redis.exists(key):
publish("i18n.skipped", {"lang": lang, "pid": pid})
else:
redis.set(key, 1, ex=86400)
process_translation(content, lang)
이 변경 이후 MQ 소비량은 약 35% 감소했고, 중복 번역은 90% 이상 줄었다. 품질 점수의 표준편차도 0.18에서 0.05 수준으로 안정화되었다.
5. 품질 평가 및 자동 보정 루프
번역 품질은 BLEU와 TER 지표를 기반으로 측정했다. 각 언어별 기준 점수는 BLEU >= 0.7, TER <= 0.3으로 설정했다. 기준 이하인 문장은 자동으로 재번역 대상에 등록된다. 재번역은 문맥 검증 모델 단독으로 수행되며, 상품 카테고리와 스펙 정보를 추가 컨텍스트로 제공하여 정확도를 높인다.
score = bleu_score(reference_text, translated)
if score < 0.7:
corrected = context_refiner.correct(translated, base.category, base.specs)
db.update_translation(pid, lang, corrected, quality="REWRITE")
publish("i18n.rewrite", {"id": pid, "lang": lang, "score": score})
평균 품질 점수는 3회 루프 이후 0.68에서 0.83으로 상승했다.
BLEU 점수가 0.85 이상이면 품질 등급을 자동으로 APPROVED로 승격하고,
Redis 캐시에 영구 저장하여 DB 조회를 생략한다.
6. 인적 검수(Human Review) 워크플로우
AI가 아무리 정확해도 최종 검수는 사람이 해야 하는 영역이 있다. 특히 신규 카테고리의 전문 용어나, 법적 문서에 사용되는 표현은 AI 단독으로 판단하기 어렵다.
Translator-Agent는 품질 등급이 MACHINE인 번역 중
BLEU 점수가 0.65~0.75 구간에 있는 항목을 "Human Review 후보"로 분류한다.
이 후보 목록은 운영 대시보드에 노출되며,
검수자가 번역을 확인하고 승인하면 등급이 HUMAN으로 변경된다.
이후 운영팀 최종 승인을 거치면 APPROVED로 확정된다.
검수 대상은 전체 번역의 약 8% 수준이다. 나머지 92%는 AI가 자동으로 APPROVED까지 처리한다. 이 비율은 Glossary가 확충되고 모델이 개선될수록 점차 감소하고 있다.
7. 캐시 무효화 및 데이터 일관성
번역 데이터가 갱신될 때 Redis 캐시와 DB 간 일관성이 깨지는 문제가 있었다.
일부 페이지가 갱신된 번역을 반영하지 못하고 이전 데이터를 그대로 노출했다.
이는 Cloud Function이 i18n.updated 이벤트를 수신하지 못했을 때 발생했다.
해결책으로 MQ 재시도 큐(Delay Queue)를 추가했다.
이벤트 수신이 실패한 경우 30초 후 재발행되도록 구성했다.
Function 로그는 Ops-Agent가 수집하여
Telegram /cache 명령으로 즉시 조회 가능하게 했다.
publish("cache.invalidate", {"kind": "i18n", "id": pid, "lang": lang}, delay=30)
이후 페이지 캐시 불일치율은 2.4%에서 0.3% 수준으로 감소했다. 동일 상품의 다국어 데이터를 동시에 요청해도, Redis TTL(15분) 내에서는 항상 최신 상태를 유지했다.
8. AI 에이전트 간 협업 및 우선순위 체계
Translator-Agent는 Classifier-Agent, Crawler-Agent와 동일한 MQ를 사용한다.
이벤트 혼선이 발생하지 않도록 각 에이전트에 우선순위를 부여했다.
Crawler → Classifier → Translator 순으로 이벤트를 처리하며,
Translator-Agent는 product.normalized 이벤트를 수신한 이후에만 작동한다.
agents:
- name: crawler
priority: 1
output_event: "product.crawled"
- name: classifier
priority: 2
depends_on: ["crawler"]
output_event: "product.normalized"
- name: translator
priority: 3
depends_on: ["classifier"]
output_event: "i18n.updated"
이 설정 이후 각 에이전트의 처리 순서가 명확히 보장되었고, MQ 지연률은 60% 이상 개선되었다. 하루 평균 번역 처리량은 약 18만 건, 품질 점검 루프는 2만 건 수준에서 안정적으로 유지되고 있다.
9. 품질 보고 자동화 및 운영 피드백
Translator-Agent는 모든 번역 결과와 품질 점수를 요약해 Telegram으로 자동 보고한다.
Ops-Agent는 /quality 명령으로 지난 24시간의 번역 통계를 텍스트로 출력한다.
품질 저하나 모델 응답 지연이 감지되면 자동 재시작이 수행된다.
*Translator-Agent Report*
Processed: 183,412 items
Average BLEU: 0.81
Rewrites: 2,948
Human Review Pending: 14,672
Failures: 46
Skipped (duplicate): 5,130
Cache Hit Rate: 96.2%
10. 결론 및 현재 상태
Translator-Agent의 도입 이후 수동 번역 프로세스는 완전히 제거되었다. AI는 크롤링된 원문 데이터를 수집하고, 자체적으로 번역, 검증, 보정, 저장, 품질 평가를 수행한다. MQ 이벤트를 통해 실시간으로 다른 시스템과 연동되며, 사람은 전체 번역의 8%에 해당하는 검수 후보만 확인하면 된다.
번역 품질은 언어별 BLEU 기준 0.8 이상을 유지 중이며, 캐시 일관성, 이벤트 동기화, 품질 자동보정 루프 모두 안정화되었다. Glossary에는 매주 약 200개의 신규 용어가 추가되고 있으며, 이는 Classifier-Agent가 감지한 오분류 사례에서 자동 추출된다. AI가 데이터를 번역하고, 품질을 측정하고, 스스로 개선하는 순환 구조가 완성되었다.