스탯 판정과 문맥 파악
스탯 판정과 문맥 파악 : 코드가 먼저 정하고 AI는 설명만
이번에 한 작업은 크게 두 가지다.
TAB 스탯창 분석에서 누가 잘했는지를 AI가 아니라 코드가 먼저 판정하게 바꿨다.
대화가 이어질 때 “내 영웅이 누구인지”, “지금 누구 얘기를 하는지”를 잘못 잡던 문제를 고쳤다.
그 밖에 문서 검색을 손봤고, 솜브라의 역할 변경과 새 영웅 독트린도 반영했다.
1. 스탯 판정은 코드가 먼저 한다
TAB 스탯창 사진을 올리면 처치, 데스, 피해량, 치유량 같은 숫자를 읽어서 피드백을 준다.
처음에는 읽은 숫자를 그대로 AI에게 넘기고 잘한 점과 아쉬운 점을 쓰게 했다.
그런데 같은 영웅인데도 판마다 “딜을 더 해라”, “힐을 더 해라”처럼 말이 달라졌다.
약점이 없는 판에서도 아쉬운 점을 억지로 만들어 냈다.
그래서 AI를 부르기 전에 코드가 지표마다 강점 / 비슷 / 약점을 먼저 정해 두고, AI에게는 “아쉬운 점은 약점 판정에서만 써라”라고 시켰다.
약점이 없으면 아쉬운 점도 쓰지 않는다.
같은 유형끼리 비교한다
같은 힐러여도 메르시와 아나는 하는 일이 다르다.
메르시의 피해량을 아나와 비교하면 메르시는 항상 못한 사람이 된다.
그래서 영웅을 여섯 유형으로 나누고, 같은 유형끼리만 비교하게 했다.
| 역할 | 유형 |
|---|---|
| 탱커 | 경감형 / 비경감형 |
| 딜러 | 메인 딜러 / 서브 딜러 |
| 힐러 | 메인 힐러 / 서브 힐러 |
경감형 탱커는 방벽이나 보호막처럼 피해를 막아 주는 스킬이 있는 탱커다.
이런 스킬이 있으면 막아 낸 피해(경감량)가 원래 높게 나온다. 그래서 스킬이 없는 탱커와 경감량을 비교하면 안 된다.
유형은 코드에 영웅 목록을 적어 두지 않고 오버워치 정리 문서에서 읽어 온다.
딜러와 힐러는 문서에 있는 메인·서브 분류를 그대로 쓰고, 탱커는 스킬에 방벽 같은 태그가 있는지로 정한다.
분류를 바꾸고 싶으면 문서만 고치면 된다.
종합 점수로 순위 매기기
“누가 제일 잘했어?”라는 질문에 답하려면 순위가 필요하다.
지표마다 점수를 매기고, 유형별 비중을 곱해서 더했다.
1
2
3
4
지표 점수 = 내 수치 / (내 수치 + 비교 대상 평균) × 100
(50점이면 비교 대상과 같다. 데스는 반대로 계산한다)
종합 점수 = 우리팀 같은 포지션과 비교 50% + 상대팀 같은 포지션과 비교 50%
상대 스탯이 없으면 우리팀과의 비교만 쓴다.
비중은 유형마다 다르다. 예를 들어 서브 딜러는 처치 35%, 도움 15%, 피해 25%, 데스 25%다.
이 비중은 실측해서 얻은 값이 아니라 유형별 역할을 보고 내가 직접 정한 값이다.
스탯창 결과 표 아래에는 “우리팀 순위” 표가 붙는다.
힐을 적게 한 게 아니라 힐할 일이 적었던 경우
치유량이 상대 힐러보다 낮다고 해서 “힐을 더 해라”라고 하면 안 된다.
우리 팀이 피해를 덜 받았다면 힐할 일 자체가 적었던 것이다.
그래서 힐러의 치유량은 그 팀이 받은 피해와 같이 본다.
받은 피해 대비 치유 비율이 상대 힐러들과 비슷하면 약점으로 보지 않는다.
우리 탱커나 딜러가 상대보다 훨씬 많이 죽었다면,
치유량이 낮은 이유를 힐러가 아니라 많이 죽은 탱커나 딜러의 교전 방식에서 찾아 알려 준다.
메르시 같은 메인 힐러는 공격을 할지 말지가 선택이다. 그래서 피해량이 낮아도 지적하지 않고, 딜을 했으면 칭찬한다.
채팅 순위도 코드 순위대로
스탯표의 순위 표에서는 일리아리가 1위였는데, 채팅으로 “누가 제일 잘했어?”라고 물으면 솔저76을 1위라고 답했다.
AI가 종합 점수를 무시하고 처치 수만 보고 순위를 다시 매긴 것이다.
프롬프트에 지시를 더 세게 쓰는 대신, AI가 쓴 답변에서 “1위 영웅…” 문단을 찾아 코드가 계산한 순서대로 다시 놓았다.
“잘한 순서”, “등수”, “MVP”도 순위 질문으로 보게 했다.
2. 스탯창 사진을 질문과 함께 보내기
예전에는 사진을 고르는 순간 바로 분석이 시작됐다.
“누가 제일 못했어?”만 묻고 싶어도 전체 피드백을 다 받은 뒤에야 질문할 수 있었다.
지금은 사진을 고르면 입력창 위에 첨부만 해 두고, 질문과 같이 보낸다.
1
2
질문 있음 : 스탯 표만 만들고 바로 질문에 답한다 (표는 답변 위에 접어서 붙인다)
질문 없음 : 예전처럼 표 + 팀·개인 피드백
질문이 있으면 피드백을 만드는 AI 호출 2번을 건너뛰어서 답도 빨리 나왔다.
새 스탯창을 올리면 앞 판에서 남은 내 영웅과 스탯은 지운다.
사진에서 내 행을 못 알아봤을 때, 예전 판의 영웅을 기준으로 답하는 문제가 있었기 때문이다.
3. 되묻기 정리
챗봇은 정보가 부족하면 버튼으로 되묻는다.
그런데 안 물어도 되는 질문에 되묻거나, 엉뚱한 걸 되묻는 경우가 많았다.
영웅을 먼저 묻기
“상대 딜러가 뒤로 와서 힐러를 죽여”처럼 영웅 이름이 하나도 없는 질문에는 역할 버튼(탱커/딜러/힐러)으로 되물었다.
그런데 역할만 알아서는 일반적인 답밖에 못 한다.
그래서 “내 영웅과 상대 영웅을 알려주세요. 예: 나 아나, 상대 겐지 트레이서”를 먼저 묻게 했다.
사용자가 답하면 원래 질문 뒤에 붙여서 다시 답한다.
“트레이서”처럼 이름만 답하면 내 영웅인지 상대 영웅인지 알 수 없다.
이때는 “트레이서, 내 영웅인가요 상대 영웅인가요?”를 한 번 더 묻는다.
되묻지 않아도 되는 질문
아래 질문들은 역할을 되묻지 않고 바로 답하게 했다.
“캣 궁 언제 써?”처럼 영웅 한 명의 스킬이나 궁극기를 묻는 질문
“납치한다냥은 누구에게 써야 해?”처럼 스킬 이름만 말한 질문. 문서의 스킬 표에서 그 스킬의 영웅을 찾는다.
“라인이랑 잘 어울리는 딜러는 뭐야?”처럼 질문 안에 역할이 이미 있는 질문
“본인에게도 피해를 받는 영웅은 뭐가 있어?”처럼 내 역할과 상관없는 사실을 묻는 질문
4. 픽 질문은 추천 카드로
“라인이랑 잘 어울리는 딜러는 뭐야?” 같은 질문을 픽 질문으로 보게 했다.
전에는 이런 질문도 일반 운영 질문처럼 답해서, 누구에게나 해당하는 “바로 할 것 3가지”가 붙었다.
지금은 픽 질문이면 추천 영웅 카드로 답한다.
결론 한 문장, 영웅마다 그 아군과 잘 맞는 이유, 공통으로 주의할 점이 있으면 카드 아래에 ⚠ 한 줄을 붙였다.
추천 이유가 영웅 운영과 안 맞던 문제
처음 만든 카드에 “트레이서 : 라인하르트 방벽으로 생존 보조”가 나왔다.
트레이서는 방패 뒤에 서는 영웅이 아니라 옆으로 돌아 들어가는 영웅이다.
AI가 두 영웅이 평소 어디에 서는지 모른 채 그럴듯한 이유를 지어낸 것이다.
그래서 문서에서 “기본 위치”와 “협업” 줄을 꺼내 같이 넘기고, 이걸 근거로 이유를 쓰게 했다.
조합 질문 이어서
픽 질문 다음에 “안란이랑은 어때?”라고 하면 라인하르트와 안란의 궁합으로 답한다. 전에는 안란 혼자 운영하는 법이 나왔다.
“오리사와 캐서디가 있을 때 누구한테 나노를 줘?”는 조합 평가가 아니라 “기본은 OO, 이럴 땐 OO”로 답한다.
“좋은 딜러랑 힐러 추천해줘”처럼 역할을 두 개 말하면 두 역할을 섞어서 추천한다. 전에는 힐러만 나왔다.
5. 대화가 이어질 때 문맥 잡기
이번 작업에서 가장 많이 고친 부분이다.
챗봇은 매 질문마다 AI에게 “내 영웅, 상대, 아군, 질문 의도”를 뽑게 하고, 앞 대화에서 기억해 둔 정보와 합친다.
문제가 많이 나온 곳은 이 합치는 과정이었다.
언급만 한 영웅을 내 영웅으로 잡음
“안란 플레이는 어떻게 해?” 다음에 “캣은 어떻게 활용해?”라고 물었더니, AI가 안란을 내 영웅으로, 캣을 아군으로 돌려줬다.
이전 대화를 참고하라고 넘긴 정보를 보고 안란을 그대로 이어받은 것이다.
“프레야 상승 기류를 활용해 탈출하는 거 아니지 않아?”에서는 프레야가 내 영웅이 됐다.
그 뒤로 모든 추천이 딜러로만 좁혀졌다.
그래서 기준을 이렇게 잡았다.
AI가 준 “내 영웅”은 사용자가 직접 밝혔을 때만 받는다.
“나 겐지인데”, “겐지로 하는데” 같은 표현이나 “나”, “내가” 같은 말, 스탯 입력이 없으면 버린다.
그냥 이름만 나온 영웅은 “이번 질문의 주제 영웅”으로만 본다.
내 영웅을 너무 빨리 잊음
반대로 “나는 솔저76인데 …” 다음에 “어떻게 안 죽고 딜을 하지?”라고 하면 영웅을 다시 물었다.
두 번째 질문에는 “나”라는 말이 없어서 솔저76을 이어받지 못한 것이다.
지금은 5분 안에 밝힌 내 영웅은 바뀌었다는 신호가 없으면 계속 유지한다.
지운 정보가 다음 턴에 되살아남
상대 정보가 한 턴 걸러 사라졌다가 돌아오고, 영웅을 바꾼 다음 턴에는 예전 상대와 아군이 돌아왔다.
원인은 저장 방식이었다.
질문을 처리하는 함수 안에서는 정보를 지웠는데, 대화 기록에는 지웠다는 사실을 쓰지 않았다.
대화 기록은 바뀐 값만 덮어쓰는 방식이라, 지운 값은 기록에 그대로 남아 있다가 다음 턴에 다시 읽혔다.
그래서 지운 항목은 빈 값으로 덮어쓰게 고쳤다.
상대 판단은 AI에게 맡기기
“지금 상대하려는 영웅”은 예전에 AI가 준 값과 규칙을 섞어서 정했다.
그런데 규칙이 상대를 나열한 문장의 첫 영웅이나 앞 턴의 상대를 골라 버려서 오히려 틀렸다.
실제 대화 50턴을 3번씩 돌려서 상대 영웅(target)을 맞힌 비율을 재 봤다. 섞은 결과가 0.69, AI 혼자가 0.94였다.
규칙을 하나씩 빼 봤다.
상대를 2명 이상 나열만 한 턴에는 규칙이 target을 채우지 않게 했더니 0.93까지 올랐다. 그래도 AI 혼자(0.97)보다는 낮았다.
그래서 규칙으로 상대를 추론하는 부분을 아예 빼고, AI가 준 값만 쓰기로 했다.
그 값이 아군이거나 내 영웅일 때만 지운다. 이렇게 하니 0.98이 나왔다.
남은 한 칸은 텍스트로 입력한 스탯에서 상대 이름 칸에 “힐러 1”이 들어간 경우였다.
등록된 영웅 이름만 후보로 쓰게 고쳤고 target은 1.00이 됐다.
다만 규칙을 전부 뺄 수는 없었다.
“그럼 카운터는 뭐야?”처럼 이름이 없는 후속 질문에는 AI가 상대를 항상 비워서 돌려준다.
프롬프트에 “이번 메시지에 이름이 있을 때만 채워라”라고 적어 놨기 때문이다.
이 경우에는 직전에 말한 상대를 그대로 이어받게 남겨 뒀다.
측정 점수에는 이 이어받기의 효과가 나타나지 않았다.
이어받기를 넣든 빼든 점수가 똑같았는데, 측정에 쓴 50턴 중에 이름 없는 후속 질문이 없어서 이어받을 일 자체가 없었기 때문이다.
대신 실제 AI 응답을 확인해서 이어받기가 필요하다는 걸 봤다.
이걸 확인하다가 버그도 하나 찾았다.
챗봇은 상대 영웅을 2턴 연속 말하지 않으면 상대 정보를 지운다.
그런데 규칙이 상대를 못 찾고 AI만 상대를 알아본 턴을 “상대를 말하지 않은 턴”으로 세고 있었다.
그러면 다음 턴에 “그럼 카운터는 뭐야?”처럼 이름 없이 물었을 때 이미 2턴째가 되어 상대 정보가 지워졌다.
이제 AI가 상대를 알아본 턴은 “상대를 말한 턴”으로 세서, 말하지 않은 턴의 횟수를 0으로 되돌린다.
앞 답변을 되묻는 질문
“역으로 당할 수 있다는 게 어떤 경우야?”는 영웅 이름이 없어서 새 질문으로 처리됐고, 역할 버튼이 떴다.
“탈출 할 수 있다고 하는 근거는 뭐야?”처럼 앞 답변에 이의를 다는 질문도 마찬가지였다.
그래서 직전 답변을 기억해 두고, 질문이 앞 답변을 가리키면 그 답변을 근거로 해당 부분만 답하게 했다.
이의를 제기한 질문이면 맞는지 먼저 답하고, 틀렸으면 인정하게 했다.
그 밖의 문맥 수정
두 글자 이하 영웅 이름은 단어 첫머리에 있을 때만 영웅으로 본다.
“시에라인데”의 “라인”이 라인하르트로 잡히던 문제를 막기 위해서다.
과거 실제 사용자 메시지 124개에 적용해 보니 인식 결과가 바뀐 메시지는 0개였다.
정상적으로 인식되던 이름이 깨지지는 않는다는 뜻이다.
6. 문서 검색 개선
챗봇은 질문과 비슷한 내용을 오버워치 정리 문서에서 찾아 AI에게 같이 넘긴다(RAG).
문서는 800자 정도의 조각으로 잘라 두고, 질문과 뜻이 가까운 조각을 찾는다.
조각에 영웅 이름이 없었다
“리퍼 스킬 알려줘”를 물었는데 리퍼의 스킬 조각을 찾지 못했다.
조각을 열어 보니 본문에 “리퍼”라는 단어가 없었다.
문서를 제목 단위로 자르면서 영웅 이름(상위 제목)은 조각 바깥 정보로만 남았기 때문이다.
그래서 조각 본문 앞에 제목 경로를 붙였다.
1
2
딜러 > 리퍼 (Reaper) > 스킬 데이터
(조각 본문)
정답 조각을 미리 표시해 둔 질문 25개로 재 봤더니, 상위 10개 안에 정답 조각이 들어온 비율이 0.64에서 0.72로 올랐다.
스킬 질문만 따로 보면 0.32에서 0.83이다.
스킬 성질로 영웅 찾기
“본인에게도 피해를 받는 영웅은 뭐가 있어?”를 물으면, 문서에서 본인도 피해 태그가 붙은 12명 중 2명만 답했다.
이런 영웅의 스킬은 문서 곳곳에 흩어져 있어서, 비슷한 조각 몇 개를 찾는 방식으로는 다 모을 수 없다.
문서의 스킬 줄에 자가 피해 같은 태그를 붙였다.
이 태그로 “태그 → 영웅 → 스킬” 표를 만들고, 질문이 이런 성질을 물으면 AI가 맞는 태그를 고르게 했다.
그 태그의 영웅 목록을 통째로 넘기고, 목록에 없는 영웅 줄은 답변에서 지운다.
그 밖의 검색 개선
사용자가 “궁”이라고 써도 검색할 때는 “궁극기”로 바꿔서 찾는다. “궁합”, “궁금”은 바꾸지 않는다.
이름을 생략한 후속 질문은 앞에서 얘기하던 영웅 이름을 붙인 검색어를 맨 앞에 둔다.
800자 경계에서 잘려 스킬 이름이 없는 조각은, AI에게 넘길 때 원문에서 그 줄을 찾아 어느 스킬 설명의 이어지는 부분인지 붙여 준다.
검색어 여러 개를 한 번에 묶어서 계산한다. 찾아오는 문서는 기존 방식과 완전히 같다.
실제 대화 흐름에서 같은 질문끼리 비교하면 검색 시간 중앙값이 1.33초에서 0.76초로 줄었다.
7. 답변 다듬기
역할을 고정했을 때 다른 역할 영웅 이름을 “다른 영웅”으로 바꿨더니 “다른 영웅 : 갈고리로”처럼 누구 얘기인지 모를 줄이 남았다.
이름을 바꾸지 않고 그 추천 줄을 지우는 방식으로 바꿨다.
문서가 역할을 돌격/공격/지원으로 적어 놓아서 AI가 “오리사(돌격)”처럼 섞어 썼다. 화면에는 탱커/딜러/힐러로 통일해서 보여 준다.
스탯을 보고 답할 때 “바로 할 것 3가지”는 이미 끝난 판 얘기라 어색해서 “다음 판에 해볼 것 3가지”로 바꿨다.
8. 상성표와 화면
상성표의 유불리 표시를 불리 / 유리 / 팽팽으로 바꿨다. 비어 있는 “상황에 따라 갈림” 묶음은 숨긴다.
상성 설명 문장을 공략 가이드 말투로 다시 만들었다. “궁”, “딜” 같은 줄임말과 은어는 풀어 쓴다.
답변 아래 추천 질문 버튼은 누르면 바로 보내진다. 전에는 입력창에 채운 뒤 Enter를 눌러야 했다.
9. 솜브라 역할 변경과 독트린 추가
패치로 솜브라가 딜러에서 힐러가 됐고, 새 영웅 독트린이 나왔다.
영웅 표에서 솜브라를 힐러로 옮기고 독트린을 넣어서 54명이 되었다.
상성표에 적힌 솜브라 줄 중 다른 영웅 표에 있는 것은 딜러 시절 기준의 판정이다.
그래서 솜브라는 솜브라 자기 표에 적힌 판정만 쓰고, 다른 영웅 표의 솜브라 줄은 무시한다.