거래처명이 바뀌어서 기존 문서를 전부 고쳐야 하는 일이 생깁니다. 제품 코드 체계를 정리하면서 수백 건의 항목명을 한 번에 바꾸기도 합니다. 엑셀의 모두 바꾸기처럼 한 번이면 될 것 같습니다.
문제는 바꾼 뒤에 무엇이 깨졌는지 확인할 방법이 없다는 점입니다. 수백 건을 눈으로 다 읽을 수는 없고, 안 읽으면 깨진 것을 모릅니다.
저희가 문서 수백 건의 문체를 일괄 변환하면서 쓴 방법을 정리합니다. 표현만 바꾸고 사실은 지키기 위해 쓴 절차입니다.
표현만 바꿨는데 단어가 망가졌습니다
문서의 문체를 평서체에서 경어체로 바꾸는 작업이 있었습니다. 내용은 그대로 두고 어미만 바꾸는 일이라 단순해 보였습니다.
초안을 확인하다가 이상한 문장을 발견했습니다. "서버다"가 "서법니다"로 바뀌어 있었습니다.
원인은 품사 판별이었습니다. 받침 없는 형용사를 경어체로 바꾸는 규칙이 명사 서술격에도 적용된 것입니다. 어미만 보면 둘이 같은 모양이라 구분되지 않습니다.
같은 패턴에 걸릴 표현이 45건이었습니다. 적용했다면 문서 곳곳에 뜻이 통하지 않는 단어가 남았을 것이고, 그중 일부는 제품명이나 기술 용어라 나중에 발견하기도 어려웠을 것입니다.
실무에서 같은 구조의 사고가 자주 납니다. 거래처명 "대한상사"를 "대한상사(주)"로 일괄 치환하면서 "대한상사물산"까지 함께 바뀌는 식입니다. 견적서에 그 이름이 남아 있으면 상대가 먼저 발견합니다.
변환 규칙을 카탈로그로 만들어 두었던 것이 도움이 됐습니다. 적용 전에 규칙이 걸릴 어절 98종을 뽑아 사람이 대조했고, 거기서 걸러냈습니다. 전체 문장을 다 볼 수는 없어도 규칙 목록은 볼 수 있습니다.
바뀌어도 되는 것과 안 되는 것을 나눕니다
일괄 변환의 전제는 "표현은 바뀌고 사실은 그대로"입니다. 이 전제를 검사로 만들려면 무엇이 사실인지 정해야 합니다.
사람이 지어내기 어려운 것들로 한정했습니다. 영문 식별자, 주소, 숫자입니다. 제품 코드나 환경 변수 같은 것은 문맥에 따라 바꿔 쓸 수 없고, 주소와 숫자도 마찬가지입니다.
반대로 조사, 어순, 문장을 나누거나 합치는 것은 자유롭게 바뀌어도 됩니다. 그것이 표현 변환의 목적입니다.
그래서 원문과 변환본에서 사실 토큰만 뽑아 집합으로 비교했습니다. 문장이 몇 개로 쪼개졌는지, 어순이 어떻게 달라졌는지는 보지 않습니다.
사라진 것과 생긴 것을 다르게 처리합니다
| 상황 | 의미 | 처리 |
|---|---|---|
| 원문에 있는데 변환본에 없음 | 사실이 유실됨 | 오류 |
| 원문에 없는데 변환본에 있음 | 없던 것이 생김 | 경고, 사람이 판단 |
사라진 토큰은 명백한 오류입니다. 문장을 다듬다가 제품명을 빼먹었거나 숫자가 날아간 것입니다.
새로 생긴 토큰은 판단이 필요합니다. 원문에 없던 제품명이나 숫자가 등장했다면 지어냈을 가능성이 있습니다. 다만 집합으로 비교하기 때문에 같은 단어가 몇 번 나왔는지는 보지 않습니다. 등장 횟수가 늘거나 줄어든 것은 이 검사에 걸리지 않습니다.
이 검사를 통과한 결과는 문장 459개를 바꾸면서 토큰 변화가 없었습니다. 평서체가 남은 문장도 없었습니다.
"검사 통과"라는 보고를 받으면 물어볼 것
여기서 분명히 해야 할 것이 있습니다. 토큰이 그대로라는 사실은 내용이 그대로라는 뜻이 아닙니다.
두 가지 예로 확인할 수 있습니다.
| 원문 | 변환본 | 토큰 집합 | 실제 |
|---|---|---|---|
| ServiceA 10건, ServiceB 20건 | ServiceA 20건, ServiceB 10건 | 같음 | 숫자가 뒤바뀜 |
| 이 기능을 지원합니다 | 이 기능을 지원하지 않습니다 | 같음 | 뜻이 정반대 |
첫 번째는 숫자를 서로 맞바꾼 것이고 두 번째는 부정을 넣은 것입니다. 둘 다 토큰 집합은 완전히 동일해서 검사를 통과합니다. 실제로 돌려봐도 통과합니다.
담당자 입장에서 이 두 사례가 어떤 의미인지 보면 분명합니다. 거래처별 단가가 서로 뒤바뀐 견적 문서, "지원합니다"가 "지원하지 않습니다"로 뒤집힌 제품 설명은 검사 통과 기록과 함께 그대로 배포됩니다.
그래서 이 검사의 이름을 "사실 보존 검사"가 아니라 "토큰 보존 검사"로 읽어야 합니다. 보장하는 것은 하나입니다. 원문에 있던 식별자·주소·숫자가 변환본에서 사라지지 않았다. 그 값들이 올바른 자리에 붙어 있는지, 서술의 방향이 유지됐는지는 보지 않습니다.
이 한계를 알고 쓰면 유용합니다. 일괄 변환에서 가장 자주 일어나는 사고가 "문장을 다듬다가 제품명이나 수치를 빠뜨리는 것"인데, 그것만은 확실히 잡습니다. 한계를 모르고 쓰면 위험합니다. 통과했으니 내용이 보존됐다고 믿게 됩니다.
규칙 목록을 먼저 봅니다
이 작업에서 얻은 순서는 이렇습니다.
먼저 변환 규칙을 목록으로 만듭니다. 바꾸는 조건을 코드에 흩어 두지 않고 한곳에 모으면 적용 전에 읽을 수 있습니다.
다음으로 그 규칙이 걸릴 대상을 추출합니다. 전체 문장이 아니라 규칙에 매칭되는 표현만 뽑으면 사람이 확인할 만한 분량이 됩니다. 앞의 98종이 그것입니다.
그다음 적용하고, 사실 토큰으로 검사합니다.
규칙 목록을 건너뛰고 바로 적용한 뒤 결과를 검사하면 어떻게 될까요. 사실 토큰 검사는 통과합니다. "서버다"가 "서법니다"가 되어도 식별자나 숫자는 그대로이기 때문입니다. 검사가 보지 않는 영역에서 망가집니다.
자동 검사와 사람의 확인은 보는 영역이 다릅니다. 하나로 다른 하나를 대신할 수 없습니다.
개발을 맡길 때 확인할 것
- 변환 규칙이 한곳에 모여 있어서 적용 전에 읽을 수 있는가
- 규칙이 걸릴 대상만 뽑아서 확인할 수 있는가
- 바뀌면 안 되는 것이 무엇인지 명시적으로 정의돼 있는가
- 검사가 사라진 것과 생긴 것을 구분하는가
- 그 검사가 보장하지 않는 범위를 문서에 적어 두었는가
마지막 항목이 실무에서 제일 중요합니다. 검사가 무엇을 못 잡는지 적혀 있지 않으면, 통과 기록만 보고 안심하게 됩니다.
문서뿐 아니라 데이터 정제나 시스템 이관에서도 같은 구조가 필요합니다. 바꿀 대상을 먼저 목록으로 뽑아 확인하고, 바꾸면 안 되는 것을 명시하고, 적용 후에 그것이 지켜졌는지 읽어서 대조하는 순서는 어느 쪽에서든 같습니다.



