콘텐츠로 이동

번역 결과의 `---]` 특수기호 발생 원인 및 해결 기획

번역 결과의 ---] 특수기호 발생 원인 및 해결 기획

섹션 제목: “번역 결과의 ---] 특수기호 발생 원인 및 해결 기획”
  • 한국어 원본 (/ko/v1/api/infrastructure-api/): 섹션 구분선으로 마크다운 수평선 --- 만 사용.
  • 영어 번역본 (/en/v1/api/infrastructure-api/): 동일 위치에 ---] 가 나타남 (괄호 ] 가 붙음).

예:

위치KO 원본EN 번역본
Base path 아래------]
각 ## 섹션 사이------]

즉, 원본에 있던 단독 ---(수평선)이 번역 후 ---] 로 바뀌는 현상이 반복됨.


1. 우리 파이프라인에서 ] 를 넣는지

섹션 제목: “1. 우리 파이프라인에서 ] 를 넣는지”
  • translate_docs.py 에서:
    • 코드블록은 ___MD_BLOCK_N___ 로 치환 후 복원.
    • 용어는 ___GLOSSARY_N___ 로 치환 후 복원.
  • 이 과정에는 ] 문자를 삽입하는 로직이 없음.
  • 링크 수정 등 다른 후처리도 번역 스크립트에는 없음.

우리 코드가 ] 를 직접 붙이지는 않음.

  • 번역 요청 시 본문 전체를 DeepL에 보냄.
  • 본문에는 마크다운 수평선인 단독 줄 --- 가 포함됨.
  • preserve_formatting=True 로 호출 중.

가능한 설명:

  • DeepL이 ---마크다운이 아닌 다른 토큰(예: 리스트, 링크 일부)으로 해석하고, 문맥상 “닫는 괄호”처럼 ] 를 보완해서 출력했을 가능성.
  • 또는 --- 만 있는 줄을 불완전한 구조로 보고 ---] 형태로 “정규화”했을 가능성.

실제로 원본은 --- 만 있고, 번역문은 같은 위치에 항상 ---] 이므로, 번역 단계(DeepL 응답)에서 ] 가 붙는 현상으로 보는 것이 타당함.

구분내용
원인DeepL API가 본문 내 단독 수평선 --- 를 받았을 때, 응답에서 해당 위치를 ---] 로 바꿔 반환하는 동작 (해석/보정 오류로 추정).
우리 코드] 를 새로 넣는 로직 없음. 번역 결과를 그대로 쓰기 때문에 DeepL 출력이 그대로 문서에 반영됨.

방안 A: 번역 결과 후처리 (권장)

섹션 제목: “방안 A: 번역 결과 후처리 (권장)”
  • 내용: DeepL 응답 문자열에서 ---]--- 로 치환.
  • 위치: translate_docs.py 에서 번역본 본문(body_en)을 최종 조합한 직후, 파일로 쓰기 전에 한 번만 적용.
  • 장점: 구현 단순, 기존 플로우 변경 적음, 다른 문서에서도 동일 패턴이 나오면 일괄 정리됨.
  • 주의: 본문에 진짜로 ---] 라는 문자열이 필요한 경우는 없을 것으로 가정 (마크다운/Starlight 관례상 수평선은 --- 만 사용).

방안 B: 번역 전에 수평선 마스킹

섹션 제목: “방안 B: 번역 전에 수평선 마스킹”
  • 내용: DeepL에 보내기 전에 단독 줄 --- 를 placeholder(예: ___HORIZONTAL_RULE___)로 치환하고, 번역 후 복원 시 --- 로 되돌림.
  • 장점: DeepL이 --- 를 건드리지 않으므로, 동일한 “해석 오류” 재발을 원천 차단 가능.
  • 단점: 코드블록/용어 placeholder와 동일한 방식으로 한 종류 더 관리해야 함. 정규식으로 “단독 줄 ---” 만 정확히 잡아야 함 (리스트 - item 과 구분 등).
  • 내용: DeepL 문서에서 tag_handling, ignore_tags, outline_detection 등으로 특정 문자열을 번역 대상에서 제외할 수 있는지 확인하고, --- 를 보호하는 설정이 있으면 적용.
  • 장점: API 레벨에서 해결 가능.
  • 단점: 해당 문법이 수평선 한 줄을 지원하는지, 그리고 우리 사용 방식(전체 본문 한 번에 번역)에 맞는지 검토 필요.

  1. 단기: 방안 A 적용
    • body_en 에 대해 ---]--- 치환을 한 번 수행.
    • 기존 EN 문서도 동일 치환으로 정리 가능.
  2. 선택: 재발이 계속되거나 다른 --- 관련 이상이 보이면 방안 B 도입 검토 (수평선 마스킹).
  3. 참고: DeepL 문서 확인 시 방안 C 가능 여부만 파악해 두고, 필요 시 나중에 적용.

  • 파일: scripts/translate_docs.py
  • 처리 시점: body_en 을 만들고, _restore_blocks / _restore_glossary 까지 모두 적용한 직후.
    그리고 dest_path.write_text(...) 로 쓰기 직전에,
    body_en 문자열에서 ---]--- 로 치환하면 됨.
  • 범위: 본문(body)만 대상으로 하면 됨. frontmatter의 --- 는 YAML 구분자이므로 건드리지 않음 (이미 별도로 조합하고 있음).

이대로 구현 시, /en/v1/api/infrastructure-api/ 등에서 보이던 ---]--- 로 정리될 수 있음.


추가: Markdown 전체 vs 문장만 추출 번역

섹션 제목: “추가: Markdown 전체 vs 문장만 추출 번역”

보내는 문서 포맷이 Markdown이라 DeepL이 구조 기호(---, ##, **, 링크 등)를 문맥에 따라 잘못 해석할 수 있음. ---] 는 그 한 사례.

방식설명장점단점
현행: 블록 단위코드블록/용어만 placeholder로 빼고, 나머지 본문을 통째로 DeepL에 전송.구현 단순, 문맥 유지, 호출 수 적음.Markdown 기호가 DeepL 입력에 포함되어 ---] 같은 보정 오류 가능.
문장·문단만 추출번역할 텍스트만 추출(문장/문단 단위) → DeepL에 순수 텍스트만 전송 → 번역 결과를 원본 구조에 다시 끼워 넣기.DeepL이 Markdown을 건드리지 않음; ---, ## 등은 우리가 그대로 유지.구조 파싱·매핑·재조립 로직 필요; 문단/리스트/헤딩 경계 정의가 포맷에 종속; 호출 수 증가 가능.

문장만 뽑아서 번역하는 방식 상세

섹션 제목: “문장만 뽑아서 번역하는 방식 상세”
  1. 추출 단계

    • Markdown을 구조 단위로 파싱: frontmatter, 헤딩(##), 리스트, 인용, 코드블록, 일반 문단(텍스트).
    • “번역 대상”은 일반 문단 텍스트만 선별 (인라인 강조 ** 는 제거하거나 placeholder).
    • 코드블록, 수평선 ---, 헤딩 라인, 링크 문법 등은 번역 API에 넣지 않고 위치만 기억.
  2. 번역 단계

    • 추출한 문장/문단 리스트만 DeepL에 전달 (순수 텍스트).
    • 각 조각을 번역한 뒤 같은 순서의 리스트로 보관.
  3. 재조립 단계

    • 원본 Markdown의 구조 템플릿에, 번역된 문장/문단을 인덱스대로 끼워 넣음.
    • 수평선·헤딩·코드블록은 원본 그대로 복원 → DeepL이 --- 를 볼 일이 없음.
  4. 고려사항

    • 문단 경계: 빈 줄 기준으로 나누면 대부분 안전. 문장 단위로 자르면 호출 수·비용 증가, 문맥 약화.
    • 리스트/테이블: 항목 텍스트만 추출해 번역 후 다시 넣어야 함.
    • 재사용성: “구조 파싱 + 추출 + 재조립”은 Markdown(또는 특정 포맷) 비즈니스 로직으로 두고, DeepL 호출·청킹·placeholder공통 엔진으로 분리하면, 나중에 다른 포맷(예: HTML, 평문)에도 같은 엔진을 쓸 수 있음.
  • 단기: 현행(블록 단위) 유지 + 후처리(---]---) 및 수평선 마스킹 등으로 Markdown 오염 최소화.
  • 중장기: DeepL을 다른 문서/포맷에서도 재사용하려면 핵심 기능(엔진)비즈니스 로직(포맷별 추출·재조립) 을 분리해 두고, 필요 시 “문장만 추출” 방식을 비즈니스 로직 한 옵션으로 추가하는 것이 좋음.