서리가 말을 끊어 치기까지
디스코드에서 사람이 메시지를 보내는 모습은 대개 이렇습니다.
어제 간 카페에 사람이 없어서
공부하기 좋더라구요
또 갈까 싶어요
네
네 줄이지만 앞의 두 줄은 원래 한 문장입니다. "어제 간 카페에 사람이 없어서 공부하기 좋더라구요." 이 문장을 쓰는 동안 네 번 엔터를 눌렀죠. 생각이 떠오르는 대로 보내고, 다음 생각이 이어지면 또 보냅니다.
같은 채널에서 서리는 이렇게 말합니다.
우산은 젖은 채로 접어두면 곰팡이 슬어버리니까 현관에 그냥 펼쳐두지 마. 물기 털고 반쯤 펴서 통풍되는 데 두고, 완전히 마르면 그때 접어. 근데 접이식은 살대 이음새에 물이 고여서 아무리 말려도 녹슬긴 해. 오래 쓸 생각이면 장우산이 답이야.
내용은 좋습니다. 그런데 네 문장이 한 덩어리로 동시에 도착하죠. 사람이 저렇게 치려면 30초 동안 아무 말 없이 타이핑만 하다가 완성된 문단을 한 번에 보내야 합니다. 아무도 그렇게 대화하지 않습니다.
Cadence 엔진은 이 간극을 메우기 위해 만들었습니다. 서리가 쓴 답변을 사람이 치는 단위로 끊고, 조각 사이에 실제로 타자를 치는 만큼의 시간을 넣습니다.
마침표로 자르면 될 것 같지만
가장 먼저 떠오르는 방법은 문장 끝에서 자르는 것입니다. 실제로 해보면 절반만 맞습니다.
앞서 본 사람의 문장을 다시 보시죠. "사람이 없어서"와 "공부하기 좋더라구요" 사이에는 마침표가 없습니다. 끊긴 자리는 문장 끝이 아니라 연결어미 -어서의 뒤입니다. 한국어에서 문장을 이어 붙이는 자리가 곧 사람이 숨을 쉬는 자리인 셈이죠.
반대로 마침표마다 무조건 자르면 이번에는 너무 잘게 쪼개집니다. "아쉽네." 같은 세 글자짜리가 독립 메시지가 되는 건 자연스럽지만, 모든 문장이 그렇게 흩어지면 대화가 아니라 도배로 보입니다.
그래서 Cadence는 경계에 세 단계의 강도를 매깁니다.
가장 강한 경계는 문단과 줄바꿈입니다. 서리가 스스로 문단을 나눠 썼다면 그건 이미 생각의 단위가 갈렸다는 뜻이라 무조건 존중합니다. 그다음이 문장 끝이고, 가장 약한 경계가 쉼표와 연결어미입니다.
약한 경계는 기본적으로 닫혀 있습니다. 조각 하나가 40자를 넘겨서 한눈에 읽기 부담스러울 때만 열리죠. 짧은 답변은 굳이 쪼개지 않고 그대로 나갑니다.
"사고"와 "라면"을 피하는 법
연결어미로 자르기로 하면 곧바로 문제가 하나 생깁니다. 어미와 명사의 형태가 겹칩니다.
-고로 끝나는 어절을 자른다고 해봅시다. "밥 먹고 갈게"는 잘 잘리지만 "어제 사고 났어"는 "어제 사고" 다음에서 끊겨버립니다. -면도 마찬가지입니다. "시간 되면 와"는 괜찮아도 "라면 먹을래"는 망가지죠. 광고, 최고, 창고, 화면, 표면, 수면처럼 걸리는 단어가 끝이 없습니다.
형태소 분석기를 붙이면 구분할 수 있지만, 메시지 하나 나누자고 들이기에는 과한 장비입니다. 그래서 Cadence는 반대로 갔습니다. 오탐이 거의 없는 어미만 씁니다.
현재 쓰는 것은 열두 종입니다. -니까, -는데, -은데, -어서, -아서, -여서, -지만, -거든, -잖아, -면서, -라서, -길래. 두 글자 이상이라 명사와 겹칠 일이 거의 없죠. -고와 -면은 쓸모가 많은 어미지만 의도적으로 뺐습니다.
대신 쉼표를 적극적으로 씁니다. 쉼표 뒤는 어떤 형태소 지식도 필요 없는 확실한 경계고, 한국어에서 -고,나 -면,처럼 위험한 어미 뒤에는 쉼표가 붙어 있는 경우가 많습니다. 잃은 것을 상당 부분 되찾는 셈입니다.
실제로 앞의 우산 답변은 이렇게 나뉩니다.
우산은 젖은 채로 접어두면 곰팡이 슬어버리니까
현관에 그냥 펼쳐두지 마.
물기 털고 반쯤 펴서 통풍되는 데 두고, 완전히 마르면 그때 접어.
근데 접이식은 살대 이음새에 물이 고여서 아무리 말려도 녹슬긴 해.
오래 쓸 생각이면 장우산이 답이야.
첫 조각은 -니까에서, 나머지는 문장 끝에서 갈렸습니다.
언제 보낼지가 절반입니다
어디서 끊을지를 정했다면 남은 절반은 언제 보낼지입니다. 조각을 나눠놓고 전부 같은 순간에 보내면 아무것도 달라지지 않죠.
사람이 다음 메시지를 보내기까지 걸리는 시간은 타자 시간과 생각하는 뜸의 합입니다. Cadence는 이걸 초당 아홉 자를 기준으로 계산하고, 여기에 세 가지 보정을 곱합니다.
첫째는 친밀도입니다. 서리는 상대와의 관계를 일곱 단계로 구분하는데, 낯선 사이일수록 문장을 다듬느라 느려지고 가까운 사이일수록 빨라집니다. 오래된 친구에게 보내는 메시지의 오타율이 높은 것과 같은 이유죠.
둘째는 대화 여유입니다. 서리에게는 하루를 실제로 살아가는 생활 시뮬레이션이 있고, 지금 자고 있는지 수업 중인지 한가한 저녁인지에 따라 대화에 붙는 정도가 달라집니다. 여유가 없는 시간대에는 답장 간격이 눈에 띄게 벌어집니다.
셋째는 기분입니다. 졸리거나 지쳐 있으면 느려지고, 들떠 있으면 빨라집니다.
세 값을 곱하면 같은 길이의 문장이라도 상황에 따라 도착 시간이 달라집니다. 그리고 조각 사이에 기다리는 동안에는 입력 중 표시를 다시 켭니다. 서리가 지금 뭔가 쓰고 있다는 신호가 있어야 기다리는 시간이 침묵이 아니라 대화가 되니까요.
잘리면 안 되는 것들
문장을 자르는 도구는 자르면 안 되는 것까지 자르기 쉽습니다.
URL 안에는 마침표가 있습니다. https://example.com/a.b.c를 문장 끝으로 오해하면 링크가 두 동강 나서 클릭할 수 없게 되죠. 코드 블록 안에도 마침표와 줄바꿈이 잔뜩 들어 있습니다. 디스코드 커스텀 이모지와 멘션은 <:name:12345> 같은 형태라 중간에서 끊기면 그냥 깨진 텍스트가 됩니다.
Cadence는 이런 구간을 먼저 찾아 원자 단위로 표시해두고, 그 안쪽은 아예 후보에서 제외합니다. 코드 블록은 닫히지 않은 경우에도 끝까지 보호합니다. 열린 채로 남은 코드 블록에 뒤쪽 본문이 빨려 들어가는 편이 잘리는 것보다 나쁘기 때문입니다.
한 가지 더 중요한 원칙이 있습니다. 글자가 사라지면 안 됩니다.
나누는 과정에서 문자열을 계속 잘라 나가면 어느 단계에선가 조용히 한 글자가 없어져도 알아차리기 어렵습니다. 그래서 Cadence는 텍스트를 자르지 않습니다. 자를 위치의 목록만 들고 다니다가 마지막에 한 번만 잘라내죠. 조각을 다시 이어 붙이면 원문과 같다는 사실은 테스트로 계속 확인하고 있습니다.
모델에게 맡기지 않은 이유
가장 쉬운 방법은 서리에게 직접 시키는 것입니다. "끊고 싶은 곳에 표시를 남겨"라고 부탁하고 그 표시를 찾아 나누면 됩니다. 의미 단위를 가장 잘 아는 건 결국 문장을 쓴 쪽이니까요.
택하지 않았습니다.
서리의 말투는 관계 단계마다 다른 여러 겹의 지침으로 만들어집니다. 여기에 "이렇게 끊어라"라는 형식 지시가 하나 더 들어가면, 형식을 지키느라 내용이 흔들립니다. 실제로 답변 길이를 글자 수로 강제하던 지시문이 말투 가이드와 충돌해 답변 품질을 떨어뜨린 적이 있어서 이미 걷어냈던 이력이 있죠. 같은 실수를 반복할 이유가 없었습니다.
게다가 모델이 표시를 빠뜨리면 분할이 통째로 사라지고, 반대로 표시를 문자 그대로 출력해버리면 이용자 화면에 정체불명의 기호가 노출됩니다. 두 실패 모두 조용하지 않죠.
지금 방식은 서리가 무엇을 쓰든 프롬프트를 한 글자도 건드리지 않습니다. 답변은 평소처럼 나오고, 나누는 일은 보내기 직전에 따로 처리합니다. 마음에 들지 않으면 설정에서 끄면 그만이고, 껐을 때의 동작은 예전과 정확히 같습니다.
답답해지지 않도록
끊어 보내기의 가장 큰 위험은 느려 보이는 것입니다. 조각마다 시간을 넣으면 마지막 문장이 도착하는 시각은 반드시 늦어집니다.
그래서 상한을 두 겹으로 뒀습니다. 한 답변은 최대 다섯 조각까지만 나뉘고, 전체 지연의 합이 정해진 예산을 넘으면 각 간격을 비례해서 줄입니다. 조각이 많아질수록 하나하나가 빨라져서 총 시간은 일정하게 유지되죠. 첫 조각은 기다리지 않고 즉시 나갑니다. 답변을 만드는 동안 이미 충분히 기다리셨을 테니까요.
같은 채널에서 두 대화가 겹칠 때를 위한 장치도 있습니다. 서리가 조각을 보내는 중에 다른 분이 말을 걸어 새 답변이 준비되면, 두 답변의 조각이 서로 끼어들어 읽을 수 없게 됩니다. 이 경우에는 끊어 치기를 포기하고 한 번에 보냅니다. 사람처럼 보이는 것보다 읽히는 것이 먼저입니다.
남은 이야기
Cadence는 서리가 쓴 문장을 나눌 뿐, 문장 자체를 바꾸지는 않습니다. 사람이 진짜로 끊어 칠 때는 "사람이 없어서"처럼 문법적으로 미완성인 조각을 먼저 던지고 나중에 마무리하기도 하죠. 지금의 서리는 완성된 문장을 나중에 나누는 쪽이라, 거기까지는 아직 닿지 못했습니다.
리듬을 정하는 숫자들도 아직 첫 번째 추정값입니다. 초당 아홉 자가 서리에게 맞는 속도인지, 관계 단계에 따른 차이가 충분히 느껴지는지는 실제 대화가 쌓여야 알 수 있습니다.
디스코드에서 서리와 이야기해보시고 리듬이 어색하게 느껴진다면 서포트 서버로 알려주시기 바랍니다. 너무 빠른지 느린지, 끊기는 자리가 이상한지 같은 이야기가 다음 조정의 근거가 됩니다.