AI의 비결정성을 활용하여 i18n 작업 가속화하기
Created at 2026년 02월 15일
•Updated at 2026년 02월 15일
•By 강병준
AI의 번역 품질이 올라오면서 엄청난 병목으로 다가왔던 번역 작업은 현재 크게 개선되었고, 14개국의 언어를 10초 안에 처리하는 시대가 왔습니다. 그렇다면 개발 과정에서의 다국어 작업으로 인한 병목도 해소되었을까요?
그렇지 않았습니다.
개발자는 여전히 번역키를 만들기 위해 직접 백오피스에서 번역이 필요한 값에 대한 번역 과정을 거치거나, 누군가에게 다국어를 적용하기 위해 “번역 키 추가 부탁드려요~”와 같은 요청을 해야만 했었습니다. 물론 이 프로세스는 충분히 효율적으로 짜여져 지금까지는 큰 병목 지점이 아니었습니다.
하지만 AI를 보조 도구로서 활용하고, 병렬 작업이 일상이 된 지금 이 프로세스는 더 이상 효율적인 프로세스가 아니게 되었습니다. 정확히 말하자면 점점 작업이 가속화되는 시점에서 이 작업은 그 속도를 따라가지 못하고 오히려 전체 흐름을 지연시키게 되었습니다.
작업을 진행하는 도중 백오피스로 이동하여 다국어 값을 추가하는 것, 추가된 다국어 값을 복사해서 코드에 적용하는 것 모두 AI로 인해 컨텍스트 스위칭이 잦아진 현재로서는 단순히 5분, 10분을 잃는 것이 아닙니다. AI가 만들어낸 설계와 본질에 집중해야 할 집중력을 잃게 만드는 치명적인 요소입니다.
오늘은 이 병목의 구조를 뜯어보고, 이 문제를 어떻게 해결했는지를 공유하겠습니다.
i18n(internationalization) 시스템 구조

현재 i18n이 관리되는 시스템 구조를 살펴보면 백오피스에서 개발자 혹은 담당자가 한국어를 입력하고 번역을 클릭하면, 14개국 언어(영어, 일본어, 중국어 등)로 번역되고 저장됩니다. 그러면 서버는 이를 DB에 키-값 쌍으로 관리하고, 클라이언트는 앱 실행 시 현재 Locale에 해당하는 번역 데이터를 가져와서 사용합니다.
AI 번역 덕분에 프로세스가 안정화되었고, 번역이라는 병목도 해결된 듯 했습니다. 하지만 번역이 10초, 5초, 3초로 점차 줄어들고 개발 속도가 가속화되자 프로세스의 한계가 드러나기 시작했습니다.
- 맥락을 고려한 i18n 키 네이밍 (
my-page.profile.username) - i18n 추가로 인한 컨텍스트 스위칭 (IDE ↔ 백오피스 전환 등)
- i18n 누락 (브랜드 신뢰도 저하 등)
이 뿐만이 아닙니다. 팀에서는 개발 과정에서 우선 한국어로 빠르게 개발을 진행하다보니 i18n이 적용되지 않은 상태임에도 불구하고 AI 코드 리뷰에서는 i18n에 대한 언급을 하지 않도록 지침을 주어야했고, 결과적으로 실제 i18n 누락도 잡지 못하는 AI 코드 리뷰의 역설이 발생하고 있었습니다.
문제점을 모아두고 관찰하니, 문제들의 공통점이 보였습니다.
“개발자가 진행하는 작업 흐름, 한 세션 안에서 i18n이 완결되지 않는다는 것”
만약 한 세션 안에서 i18n을 포함한 모든 작업을 할 수 있다면 작업이 가속화되지 않을까요? 하나의 대화 세션이 하나의 작업이 된 지금, 저는 AI가 대화 세션 안에서 대화 내용을 바탕으로 도메인을 이해하고 i18n 생성을 자동화할 수 있도록 프로세스를 설계하기 시작했습니다.
AI를 도메인에 녹이기
"A 기능 구현해줘"라는 짧은 메시지만 전달해도 AI는 AskUserQuestion 툴로 의도를 물어보고, 검증 방식과 성공 기준을 요청한 후 작업을 진행할 정도로 똑똑해졌습니다. 하지만 이미 컨벤션과 도메인으로 겹겹이 쌓인 프로덕트에서는 레거시 패턴을 참고하거나, 도메인 규칙을 고려하지 않은 코드를 작성하기도 합니다.
i18n 자동화도 마찬가지입니다. AI에게 도메인 규칙을 제공하지 않으면 도메인 맥락을 고려하지 않은 i18n 키를 만들어낼 수 있고, 백오피스에 등록 전 특정 언어 값이 누락되진 않았는지를 검증하지 않으면 유지보수를 위해 이전 프로세스보다 더 큰 비효율을 만들어낼 수도 있습니다.

그렇기에 위와 같이 예측 가능하고 신뢰할 수 있는 검증된 프로세스를 만들 수 있도록 했습니다. AI의 비결정적 판단은 적극 활용하되, 그 결과물이 저장되기 전에 반드시 검증하는 방식으로 말이죠. 그래서 먼저 한 세션 안에서 i18n을 완결하려면 어떤 단계들이 필요할지 정리했습니다.
- 변경사항 파악 (
git diff) - 한국어 텍스트 + 맥락 추출
- 14개 언어로 번역 (Admin API)
- 번역 결과 검증
- 서버에 저장 (Admin API)
- 코드에서 한국어를 i18n 변환 함수(
t('key'))로 치환
이 플로우를 관찰하면 흥미로운 패턴이 보입니다.
1-2단계와 6단계는 맥락을 이해하고 판단해야하는 비결정적 영역으로 “이 텍스트가 번역 대상인가?”, “어떤 키 이름이 적절한가?”, “어디에 i18n을 적용하면 될까?”와 같은 질문에 답해야 하는 상황이 오는데 이는 AI가 가장 잘하는 것입니다. 반면 3-5단계는 정해진 규칙대로 실행되어야 하고, 검증을 반드시 필요로 하는 결정적 영역입니다.
결정적으로 동작해야하는 플로우를 스크립트화하여 묶으면 다음과 같이 단계가 변경됩니다.
- 변경사항 파악 (
git diff) - 한국어 텍스트 + 맥락 추출
pnpm i18n:create명령어 실행 ---> 결정적 영역- 코드에서 한국어를 i18n 변환 함수(
t('key'))로 치환
AI에게 비결정성을 위임하기
i18n 생성을 위해 매번 세션에서 "git diff로 변경사항 파악해줘", "한국어 추출해줘", "맥락 고려해서 키 설계해줘", "구조화된 형태로 출력해줘"를 요청하고 티키타카하는 방식은 매번 효율적으로 동작하기 어렵습니다.
경우에 따라 예상치 못한 동작이 발생할 수 있습니다. 예를 들어, 브랜치가 최신이 아니라고 판단해 git pull을 수행하거나, 스킬 지침 대신 코드베이스의 기존 키를 참고하거나, 주석의 한국어를 i18n 대상으로 오인하는 것처럼 말이죠.
이러한 문제를 팀원 누구나 일관성있고, 쉽게 사용할 수 있도록 하기 위해 i18n 자동화의 워크플로우 전반과 규칙을 담은 지침을 Claude Skills로 만들었습니다.
---
name: i18n-generator
description: 한국어 텍스트를 i18n 키로 변환, t() 함수 적용
---
# i18n Generator Skill
변경사항에서 한국어 정적 텍스트를 추출하고, i18n 키를 생성하여 자동으로 적용하는 스킬입니다.
## 워크플로우
1. 변경사항 파악 (`git diff`)
2. 한국어 텍스트 + 맥락 추출
3. pnpm i18n:create 명령어 실행
4. 코드에서 한국어를 i18n 변환 함수(`t('key')`)로 치환
## 실행 방법
### 단계 1. 변경사항 파악
변경사항을 파악할 때는 ...
### 단계 2. 한국어 텍스트 + 맥락 추출
...이제는 i18n 생성을 위한 티키타카 없이 /i18n-generator 명령어 하나로 누구나 쉽고 빠르게 실행할 수 있습니다.
물론 항상 효율적으로 동작한다는 것을 보장할 수는 없습니다. "변경사항 파악" 단계와 같이 구체적이지 않은 단계에 대해서는 상황에 따라 다르게 동작할 수 있는데, 이런 경우라면 현재 브랜치에서 base 브랜치 대비 변경된 파일 목록을 가져오는 스크립트를 작성하여 이를 보완할 수 있습니다.
여기까지가 AI에게 맡긴 비결정적 영역입니다. 이제 결정적 영역인 번역과 검증, 저장 과정을 다뤄보겠습니다.
스크립트로 결정성을 보장하기
Admin API를 통해 i18n을 등록하는 스크립트를 만드는 것은 간단합니다. 하지만 결정성을 보장하려면 적절한 안전장치가 필요합니다.
가드레일
AI에게 번역과 구조화를 모두 맡기면 비결정성이라는 본질적인 위험이 따릅니다. 같은 입력을 주더라도 매번 다른 결과가 나올 수 있기 때문입니다.
이러한 문제를 방지하기 위해 3단계에 걸쳐 검증 로직을 추가하였습니다.
1. 스크립트 실행 전

스크립트 실행 전에 AskUserQuestion을 통해 키, 한국어 값, 그룹 ID, 설명이 올바르게 설계되었는지 확인합니다. 이 과정이 100% 완벽하진 않지만, 진입점에서의 최소한의 가드레일 역할을 합니다.
2. Admin API 사용 전 검증
/**
* CLI 인자에서 --values를 파싱하고 검증하는 로직
*/
function parseAndValidateValues(args: string[]): I18nValue[] {
const valuesIndex = args.indexOf('--values');
// 1. values 인자 검사
if (valuesIndex === -1 || !args[valuesIndex + 1]) {
throw new Error(`❌ --values 인자가 필요합니다.
사용법: pnpm i18n:create --values '[{"key": "...", "value": "한국어", "groupId": "5", "description": "..."}]'
그룹 ID 예시:
5: 홈화면
34: 기타 워딩
37: 범용워딩`);
}
let values: I18nValue[];
// 2. JSON 파싱 검증
try {
values = JSON.parse(args[valuesIndex + 1]);
} catch {
throw new Error('❌ JSON 파싱 실패. 올바른 JSON 형식인지 확인하세요.');
}
// 3. i18n 개수 검증
if (!Array.isArray(values) || values.length === 0) {
throw new Error('❌ 최소 1개 이상의 i18n 값이 필요합니다.');
}
// 4. 필수 필드 검증
for (const item of values) {
if (!item.key || !item.value || !item.groupId) {
throw new Error(
`❌ 각 항목에 key, value, groupId가 필요합니다.\n 문제 항목: ${JSON.stringify(item)}`,
);
}
}
return values;
}Admin API 사용 전 4단계의 검증을 거칩니다.
여기서 핵심은 에러 메시지의 구체성입니다. AI가 인자를 잘못 전달했을때 발생할 위험을 줄이면서도, 에러 메시지를 통해 수정하고 올바른 인자를 전달할 수 있도록 제공합니다.
3. DB 저장 전 검증
/**
* 번역 결과 검증 로직
*/
function validateTranslations(
originalText: string,
translations: TranslationValue[],
): { valid: boolean; errors: string[] } {
const errors: string[] = [];
const originalReplaceValues = getReplaceValues(originalText);
for (const translation of translations) {
// 1. 치환 문자열 일치 검증
const translatedReplaceValues = getReplaceValues(translation.text);
if (!isSameArrayValue(originalReplaceValues, translatedReplaceValues)) {
errors.push(
`[${translation.language}] 치환 문자열 불일치 - 원본: ${JSON.stringify(originalReplaceValues)}, 번역: ${JSON.stringify(translatedReplaceValues)}`,
);
}
// 2. 특수문자 검증
if (hasInvalidChar(translation.text)) {
errors.push(`[${translation.language}] 유효하지 않은 특수문자(\\b) 포함`);
}
}
return { valid: errors.length === 0, errors };
}DB에 저장하기 전 원본 값과 번역 값을 비교하는 마지막 단계로 2가지의 검증을 거칩니다.
- i18n에 변수를 사용한 치환 문자열 일치 검증
- Safari에서 렌더링 이슈 방지를 위한 특수문자 검증
원자적 저장
데이터베이스의 원자성(Atomicity) 원칙을 AI 자동화 시스템에 적용해야 합니다. 원자성이란 "모든 작업이 완전히 성공하거나, 아예 실행되지 않거나" 둘 중 하나만 보장하는 성질입니다.
14개 언어로 번역하는 과정에서 일부 언어만 실패하면 어떻게 될까요? 영어, 일본어는 있는데 태국어만 없는 불완전한 데이터가 DB에 저장됩니다. 특정 국가 사용자는 문구를 볼 수 없게 되고, 이는 브랜드 신뢰도에 치명적입니다. 더 큰 문제는 AI 기반 플로우에서는 어떤 언어가 누락됐는지 파악하기 어렵다는 점입니다.
async function main() {
// 입력값 검증
try {
// Admin 인증
const token = await adminLogin();
// 키 레벨: Promise.allSettled - 부분 성공 허용
const settledResults = await Promise.allSettled(
values.map((item) => processI18nItem(token, item))
);
// settledResults 성공/실패 결과 정리
// 실패한 키는 로그에 기록
} catch (error) {
// ...
}
}
async function processI18nItem(token: string, item: I18nValue) {
// 언어 레벨: Promise.all - 하나라도 실패 시 throw
const translationResults = await Promise.all(
TARGET_LANGUAGES.map(async (lang) => {
const translated = await translateText(token, item.value, lang);
return { language: lang, text: translated };
})
);
// 번역 결과 검증: 치환 문자열/특수문자 확인
const validation = validateTranslations(item.value, translationResults);
if (!validation.valid) {
throw new Error(`번역 검증 실패: ${validation.errors.join(', ')}`);
}
// 모든 언어가 성공할 시 DB에 저장
await createI18nTranslation(token, {
key: item.key,
groupId: item.groupId,
values: [{ language: 'KOREAN', text: item.value }, ...translationResults],
});
return { success: true, key: item.key };
}원자성을 보장하기 위해 키 레벨과 언어 레벨에서 서로 다른 Promise 전략을 사용하였습니다.
키 레벨에서는 Promise.allSettled를 사용합니다. 100개의 키를 처리하는데 1개가 실패했다고 나머지 99개를 포기할 수는 없습니다. 각 키의 성공/실패를 독립적으로 처리하고, 실패한 키는 로그에 남겨 재처리할 수 있게 하였습니다.
반면 언어 레벨에서는 Promise.all을 사용합니다. 하나의 키에서 14개 언어를 번역할 때 영어, 일본어는 있는데 태국어가 없다면 그 키는 사용할 수 없습니다. 하나라도 실패하면 즉시 전체를 중단하고, 해당 키를 DB에 저장하지 않습니다.
$ pnpm i18n:create --values '[{"key":"my-page.profile-email","value":"이메일: {email}","groupId":"28", description: "마이페이지 프로필 > 이메일 표시}]'
[1/4] 입력 검증 중...
✓ 키 형식 검증 통과: my-page.profile-email
✓ groupId 유효성 확인: 28
[2/4] 14개 언어 번역 중...
✓ en: Email: {email}
✓ ja: メール: {email}
✓ zh-CN: 电子邮件: {email}
✓ th: อีเมล: {email}
... (10개 생략)
[3/4] 번역 검증 중...
✓ 파라미터 일치 확인 (원본: ["{email}"], 번역: ["{email}"])
✓ 특수문자 검증 통과
[4/4] Admin API 저장 중...
✓ POST /api/translations/batch
✓ 14개 언어 저장 완료
완료: 1개 키, 14개 언어, 소요시간 3.2초이렇게 만들어진 스크립트는 위와 같이 동작하며 AI의 비결정성과 큰 조화를 이룹니다. AI가 맥락을 파악해 키를 설계하고, 스크립트가 번역과 검증을 보장하며, 원자적 저장으로 데이터 일관성을 지킵니다.
그렇다면 처음에 언급했던 문제들은 실제로 어떻게 해결되었을까요?
- 키 네이밍 병목 → AI가 맥락과 SKILL.md 컨벤션을 참고해 자동 설계
- 컨텍스트 스위칭 → 대화 세션 내에서
/i18n-generator스킬 하나로 처리 - i18n 누락 → 개발 단계에서 즉시 적용 가능, i18n 누락 최소화
- AI 코드 리뷰 역설 → PR 시점에 이미 적용되어 정상 체크 가능
마치며
이번 글에서는 기존 플로우를 관찰하고, 에이전틱 플로우를 직접 설계하여 가속화에 기여한 사례를 바탕으로 작성해보았습니다.
이 과정에서 제가 느낀 점은 LLM 모델의 비결정성이 점차 신뢰할 수 있는 수준까지 올라오면서 이러한 진화에 발맞춰 나아가기 위해서는 단순히 AI의 비결정성에 기대는 것이 아닌, 비결정성을 최대한 활용하되 AI를 제어하고 적재적소에 배치할 수 있는 역량을 기르는 것이 핵심이라는 점이었습니다.
앞으로의 AI는 지금보다 더 빠른 속도와 신뢰성을 가진 형태로 진화하고 우리를 보조하겠지만, 개인이 아닌 팀과 기업에서 이를 사용하기 위해서는 충분한 안전장치들이 필요할 것이니까요.
긴 글 읽어주셔서 감사합니다.