글자가 아니라 의미 위치를 비교합니다
카맨틀에서 비슷한 단어를 찾는 출발점은 글자 모양이 아닙니다. '사과'와 '사기'는 앞 글자가 같지만 뜻은 멀고, '사과'와 '과일'은 글자는 다르지만 같은 장면에서 자주 만납니다. 카맨틀은 이런 차이를 보기 위해 단어를 숫자 위치로 바꿔 둡니다.
현재 어휘 벡터는 300차원입니다. 사람에게는 300차원 공간이 잘 떠오르지 않지만, 중요한 건 단어마다 긴 숫자 좌표가 있다는 점입니다. 두 단어의 좌표가 비슷한 방향을 보면 의미가 가까운 것으로 보고, 방향이 다르면 의미가 먼 것으로 봅니다.
그래서 플레이어가 어떤 단어를 보내면 서버는 그 단어와 현재 정답의 벡터를 비교합니다. 이때 사용하는 값은 cosine similarity입니다. 쉽게 말하면 두 단어가 같은 방향을 보고 있는지 재는 값입니다.
정답마다 가까운 단어 목록을 미리 만듭니다
문제는 속도입니다. 카카오톡 방에서 단어 하나가 들어올 때마다 전체 어휘를 전부 비교하면 응답이 느려집니다. 단어 게임은 답장이 늦으면 흐름이 끊기기 때문에, 런타임에서 모든 계산을 처리하는 방식은 맞지 않았습니다.
그래서 카맨틀은 답안지를 만들 때 무거운 일을 미리 합니다. 정답 후보를 고른 뒤, 각 정답마다 가까운 단어 top 1000을 계산해 `answer-topk.json`에 저장합니다. 이 목록에는 단어, 순위, 원본 유사도 점수가 들어갑니다.
또 top 1000 밖의 단어도 완전히 버리지 않습니다. 정답별 분포 기준점을 같이 저장해 둡니다. 이 기준점은 나중에 어떤 단어가 top 1000 안에는 없지만 대략 어느 구간쯤인지 추정하는 데 쓰입니다.
플레이 중에는 전체 단어를 다시 훑지 않습니다
실제 추측이 들어오면 먼저 그 단어가 유효한 어휘인지 확인합니다. 그다음 현재 방의 정답 ID를 기준으로 `answer-topk.json`을 읽고, 플레이어가 보낸 단어가 top 1000 안에 있는지 찾습니다. 있으면 순위와 점수를 바로 사용할 수 있습니다.
top 1000 안에 없더라도 무조건 포기하지 않습니다. 단어와 정답의 벡터를 직접 읽어 cosine 값을 계산합니다. 이 과정은 전체 어휘를 다시 훑는 것이 아니라, 필요한 두 단어의 벡터 행만 읽어서 dot product를 계산하는 방식입니다.
그렇게 얻은 원본 점수는 정답별 분포 기준점과 비교됩니다. 예를 들어 top 1000보다는 낮지만 특정 anchor보다 높다면, 플레이어에게 정확한 순위 대신 '대략 이 구간'이라는 형태로 알려줄 수 있습니다.
0-100점은 원본 유사도 그대로가 아닙니다
카맨틀이 보여주는 점수는 원본 cosine 값을 그대로 100배 한 값이 아닙니다. 원본 값은 모델과 단어 분포에 따라 체감이 다를 수 있습니다. 어떤 정답은 가까운 단어들이 촘촘하고, 어떤 정답은 가까운 단어가 드문드문 있습니다.
그래서 카맨틀은 정답별 top-K 경계와 분포 기준점을 이용해 표시 점수를 보정합니다. 정답은 100점이고, top-K 안쪽 단어는 높은 점수 구간에서 비교적 세밀하게 갈립니다. top-K 밖의 단어는 더 낮은 점수 구간으로 내려가지만, 완전히 같은 방식으로 뭉개지지는 않습니다.
이 보정 덕분에 플레이어는 원본 수학 점수보다 게임에 맞는 신호를 받습니다. 중요한 건 숫자 자체가 아니라, 이전 추측보다 가까워졌는지와 방 안에서 어떤 단어가 현재 가장 좋은 단서인지입니다.
카톡방 게임이라 더 보수적으로 만들었습니다
브라우저에서 혼자 하는 게임이라면 답장이 조금 늦어도 넘어갈 수 있습니다. 하지만 카카오톡 방에서는 여러 사람이 짧은 시간 안에 단어를 던집니다. 서버는 중복 추측, 현재 방의 최고 기록, 정답 여부, 다음 문제 전환까지 같이 처리해야 합니다.
그래서 카맨틀의 유사도 엔진은 계산기 하나가 아니라 운영 흐름의 일부입니다. 웹은 설명과 통계, 힌트 페이지를 맡고, API는 카카오톡 요청을 받아 큐에 넣고, 워커는 방 상태를 읽어 정답과 추측을 처리합니다. 유사도 계산은 이 흐름 안에서 최대한 짧게 끝나야 합니다.
결국 카맨틀에서 '비슷한 단어를 찾는다'는 말은 두 단어의 숫자 거리를 재는 일만 뜻하지 않습니다. 미리 계산한 답안지, 런타임 벡터 조회, 점수 보정, 방별 상태 관리를 합쳐서 플레이어가 이해할 수 있는 한 줄 답장으로 바꾸는 일입니다.