Skip to content

자동 번역 구조 ​

Guide Center은 원본 매뉴얼을 하나만 관리하고, 다른 언어의 번역본은 원본 콘텐츠 해시와 대상 언어를 기준으로 별도 캐시한다. 따라서 원본이 변경되지 않은 동안에는 같은 번역을 반복 생성하지 않는다.

현재 제공 범위 ​

현재 배포에는 translation_glossary_terms, translation_jobs, translation_memory 테이블과 관리자용 /admin/translations 화면이 포함되어 있다. 관리자는 원본 언어, 대상 언어, 회사 표준 용어, 표준 번역, 설명을 등록할 수 있다. 번역 요청은 중복 작업을 방지하는 고유 키를 사용해 QUEUED 상태로 저장하며, 이미 동일한 원본 해시의 캐시가 있으면 새 작업을 만들지 않는다.

외부 LLM 자격 증명은 아직 연결하지 않았다. translationService.ts의 TranslationProvider 인터페이스에 OpenAI 호환 API, 사내 LLM Gateway, 온프렘 모델 어댑터 중 하나를 주입하면 큐의 작업을 처리할 수 있다. 현재 상태 API는 queue-only를 반환하므로 운영자가 공급자 미연결 상태를 명확히 확인할 수 있다.

용어집 우선 정책 ​

번역 프롬프트를 생성할 때 전체 용어집에서 원본 언어가 일치하고 대상 언어가 일치하거나 공통 용어인 항목만 선택한다. 대상 언어가 지정된 항목을 우선 사용하며, 프롬프트에는 원본 용어·표준 번역·선택적 설명을 함께 전달한다. HTML 구조, 링크, 코드, 숫자, placeholder와 보안 민감값을 보존하도록 공급자 계약에 명시한다.

표기의 정본은 중앙 원장이다 (2026-10-11) ​

용어집을 로컬 테이블에만 두면 포털마다 다른 표기가 생겨 번역이 흔들린다. 그래서 번역은 PortalConsole 원장의 승인 용어를 먼저 쓴다.

  • server/termLinkDirectory.ts 의 fetchCentralTranslationPack() 이 /api/directory/v1/glossary/pack 을 호출해 승인·활성 용어만(초안 제외) 받아온다. 계약은 PortalConsole/docs/TRANSLATION_PACK.md.
  • server/translationGlossary.ts 의 resolveTranslationGlossary() 가 원장 용어를 먼저, 로컬 translation_glossary_terms 를 보조로 병합한다 — 같은 표기가 양쪽에 있으면 원장이 이긴다.
  • 원장이 설정되지 않았거나 조회가 실패하면 로컬 용어로 폴백하고 경고(guide_translation_glossary_central_failed)만 남긴다. 용어 조회 하나 때문에 번역 작업이 멈추면 안 된다.
  • 로컬 용어 테이블은 원장으로 옮겨지는 동안의 보조 수단이다 — 새 용어는 원장에 등록(scope=guide-center 또는 platform)하는 것이 기본이다.

필요한 환경변수는 기존 원장 클라이언트와 같다 — DIRECTORY_BASE_URL(또는 PORTAL_CONSOLE_ORIGIN), DIRECTORY_PORTAL_API_KEY(또는 PORTAL_CONSOLE_API_KEY).

번역 실행도 중앙에서 (2026-10-11) ​

용어집을 중앙으로 올린 다음 단계로, 번역 실행 자체를 콘솔로 모았다. 포털이 자기 콘텐츠를 넘기면 콘솔이 원장 용어(번역 팩)를 붙여 프롬프트를 만들고 ModelGateway 로 번역한다 — 프롬프트 규칙과 용어 표기가 모든 포털에서 같아진다.

  • server/centralTranslationClient.ts: POST /api/directory/v1/translation 호출(포털 API 키에 translation:invoke 스코프 필요). 계약은 PortalConsole/docs/TRANSLATION_PACK.md.
  • server/translationService.ts: resolveTranslationProviderName() 이 중앙 우선으로 공급자를 고른다 — 중앙이 설정되지 않았거나 GUIDE_TRANSLATION_PROVIDER=local 이면 로컬 모델(builtin-llm)로 폴백한다. 둘 다 없으면 기존처럼 queue-only(작업만 쌓고 대기).
  • 중앙이 돌려준 결과도 validateTranslationResult() 로 한 번 더 검증한다(URL·{{placeholder}}·%ENV%·식별자 보존). 모델이 구조를 흐트러뜨리면 작업이 실패하고 원문은 그대로 남는다.
  • translationProviderStatus() 에 central 이 추가됐다 — 화면에서 중앙/로컬 중 무엇으로 도는지 확인할 수 있다.

로컬 모델을 계속 쓰려면(폐쇄망 등) GUIDE_TRANSLATION_PROVIDER=local 을 설정한다. 중앙 번역이 일시적으로 죽었을 때의 우회로도 같은 값이다.

LLM이 만든 결과는 MACHINE_DRAFT로 번역 메모리에 저장하고, 관리자가 확인한 뒤 HUMAN_REVIEWED 또는 PUBLISHED로 변경한다. 잘못된 결과는 REJECTED로 남겨 재생성 대상과 운영 이력을 구분한다. 원본 해시가 바뀌면 이전 번역을 자동으로 덮어쓰지 않고 새 작업을 만든다.

다음 공급자 연결 시 필요한 작업 ​

공급자 어댑터는 TranslationProvider.translate()를 구현하고, 구조화된 title, summary, htmlBody 결과를 반환해야 한다. 운영 환경에서는 매뉴얼 본문과 용어집이 외부 서비스로 전송될 수 있으므로 데이터 분류, 사내망 경유 여부, 보존 정책, API 키 관리, 관리자 승인 정책을 먼저 확정해야 한다. 공급자가 없는 환경에서도 원본 콘텐츠와 기존 수동 번역본은 그대로 조회되어야 한다.