이미지 예외처리
외부 이미지는 항상 오류 가능성이 있기 마련입니다. 이를 시스템적으로 막아봅시다.
개요
가능하다면 모든 경우의 수에 대해 전부 뽑을 수 있는 게 좋겠지만, 그렇지 않은 경우도 있습니다.
(예를 들면, 남성향 시뮬레이션에서 남자 캐릭터가 부끄러워하는 장면은 비선호하는 경우가 꽤 있습니다.)
이때 해당 데이터를 누락시켜놓는다면 데이터가 없으니 오류가 발생합니다.
그렇다면 AI에게 이 캐릭터는 예외적으로 ~~와 같이 프롬프트를 짜면 어떻게 될까요?
아쉽게도 해당 프롬프트는 제대로 동작하지 않을 가능성이 매우 높습니다.
롤플레잉을 하면서 동시에 복잡한 시스템을 굴리는 것은 아직까지도 어려울 뿐더러, 성능 이슈도 있습니다.
따라서 이 경우, AI 프롬프트가 아닌 시스템 차원에서 예외처리를 해주어야 합니다.
본 페이지에서는 이미지 서버의 구조적 특성을 이용한 예외처리 기법을 알아봅니다.
규격화를 활용한 예외처리
간단히 말해, 모든 데이터를 빈틈없이 채우는 것을 규격화라 합니다.
(정식 명칭은 아닙니다. 제가 임의로 부르는 방법입니다.)
만들지 않을 데이터의 부분을 비워놓지 않는 대신, 무표정이나 기본 에셋을 대신 설정하는 방법입니다.
이렇게만 하여도 복잡한 시스템 없이 꽤 많은 오류를 예방할 수 있습니다.
간단한 예시를 이용해 설명하겠습니다.
예시
아래와 같이 두 명의 캐릭터가 있는 남성향 시뮬레이션을 만들고자 합니다.
각각 아래와 같은 에셋이 존재합니다.
markdown
1. 마법사 히로인
- 무표정
- 웃음
- 슬픔
- 화남
- 부끄러움
- 마법 시연
2. 용사 동료
- 무표정
- 웃음
- 슬픔
- 화남
- 검술 시연전우애를 만들기는 싫어서 용사 동료에서 부끄러움 에셋은 빼고,
마법사가 검술을 시연하거나 용사가 마법을 시연하는 것은 어색하여 제외하였습니다.
규격화를 위해서는 에셋 종류를 통합해야 합니다. 에셋 종류를 모두 모아놓는다면 아래와 같습니다.
markdown
- 무표정
- 웃음
- 슬픔
- 화남
- 부끄러움
- 마법 시연
- 검술 시연이후, 이미 있는 이미지만 먼저 기록해놓는다면 아래와 같습니다.
| 무표정 | 웃음 | 슬픔 | 화남 | 부끄러움 | 마법 시연 | 검술 시연 | |
|---|---|---|---|---|---|---|---|
| 마법사 | O | O | O | O | O | O | |
| 용사 | O | O | O | O | O |
이제 비어있는 이미지를 가장 비슷한 이미지로 중복해서 넣으면 됩니다.
예를 들어 마법사가 검술을 시전하는 것은 다소 어색해 보입니다.
주로 검술을 시전하는 경우 전투를 하고 있을 가능성이 높으니 마법 시연 이미지를 대신 넣습니다.
마찬가지로 용사의 마법 시연 이미지도 검술 시연 이미지를 중복하여 넣습니다.
용사가 부끄러워하는 상황인 경우, 일반적으로는 무표정, 츤데레적인 성격일 경우 화남을 넣는 식으로 대체합니다.
이런 식으로 비어있는 이미지에 대해 기본값으로 예외처리를 시켜줄 경우,
AI가 롤플레잉에 더욱 집중할 수 있게 해주는 장점이 있습니다.
순수하게 적절한 상황에 맞는 이미지 번호만 매핑해주면 되니 오류 염려가 적습니다.
프롬프트 역시 계산이 들어가있지 않으므로 단순화되며, 결과적으로 분량이 줄어드는 효과를 가집니다.
정규식을 이용한 예외처리
정규식 매크로를 활용하면 더욱 복잡한 상황도 예외처리를 설계할 수 있습니다.
캐릭터 코드
간혹 다른 이미지 호스팅 서비스를 이용하여 폴더명이 영문인 경우가 있습니다.
이 경우 캐릭터의 한글 이름을 그대로 링크에 대입하는 것은 어렵습니다.
이 경우, 조금은 번거롭더라도 각 캐릭터별로 매칭을 해주는 것이 현실적인 방법입니다.
예를 들어, 아래와 같은 상황을 가정해 보겠습니다.
markdown
"린" 캐릭터는 "rin" 폴더에 존재
"다인" 캐릭터는 "dain" 폴더에 존재
"엘리" 캐릭터는 "eli" 폴더에 존재
...이 경우, 아래와 같이 캐릭터별로 정규식을 구성하면 호환성을 깨지 않고 제작할 수 있습니다.
markdown
정규식: \{\{img::린/(.*?)\}\}
대체식: 
정규식: \{\{img::다인/(.*?)\}\}
대체식: 
...캡쳐 범위 제한
이미지의 숫자 범위는 1 ~ 15까지인데, 16이 오면 어떻게 해야 할까요? 17이 오면?
또한, 제3자의 캐릭터가 나와버려서 캐릭터명에 없는 데이터가 나온다면?
이 경우, 정확히 등록된 이미지만 정규식으로 바꾸도록 범위를 제한해볼 수 있습니다.
먼저 범위를 탐색해 봅시다. 다음과 같이 4개의 구역으로 나눌 수 있습니다.
각 구역의 이미지에 대해, 아래와 같이 구성해보고자 합니다.
- 둘 다 올바르면 출력
- 코드만 어긋난 경우 기본 코드로 변경하여 수정
- 캐릭터명만 어긋난 경우 익명의 실루엣 이미지로 수정
- 둘 다 어긋난 경우 숨김먼저 캐릭터 이름을 제한하는 방법입니다.
기존의 (.*?)가 모든 데이터를 캡처했다면, 아래와 같이 명시해줄 경우 특정 키워드만 캡처할 수 있습니다.
(키워드1|키워드2|키워드3|키워드4)파이프 (|) 기호를 사용하여 키워드 간 구분을 해줄 수 있습니다.
이때, 공백 역시 엄격하게 포함하기 때문에 파이프 앞뒤로 띄어쓰기는 하면 안됩니다.
이제 이를 이용하면, 4개의 매크로를 이용해 범위를 명확히 하여 외부 이미지 찐빠를 99% 잡아낼 수 있습니다.
markdown
설정: 캐릭터명은 "린", "다인", "엘리"만, 이미지 번호는 1 ~ 10까지만
숫자 구간 정규식: ([1-9]|10)
[매크로 1]
- 정규식: \{\{img::(린|다인|엘리)/([1-9]|10)\}\}
- 대체식: 
[매크로 2]
- 정규식: \{\{img::(린|다인|엘리)/(.*?)\}\}
- 대체식: 
[매크로 3]
- 정규식: \{\{img::(.*?)/([1-9]|10)\}\}
- 대체식: 
[매크로 4]
- 정규식: \{\{img::(.*?)\}\}
- 대체식: (없음)💡 2, 3번 매크로 설명
2번 매크로의 경우 숫자 부분을 (.*?) 기호 (아무거나)로 설정하였습니다.
이는 조건에 맞는 경우(1 이상 10 이하)는 이미 매크로 1에서 대체되었기 때문에, 올바른 이미지는 여기에 걸리지 않습니다.
3번 매크로 역시 동일한 원리입니다.
조건에 맞는 경우(린, 다인, 엘리)는 이미 매크로 1에서 대체되었기 때문에, 마찬가지로 여기 걸리지 않습니다.