에이전트 서비스를 만들었다. 커리어에 대해 대화하고 채용공고를 추천받는다. 그런데 대화는 설계대로 흐르지 않았다.
온보딩을 이렇게 설계했다. 하나씩 묻고, 답하면 채우고, 다 채우면 넘어간다. 단순한 플로우였다.
실제 대화는 안 그랬다. 유저가 "몇 퍼센트 남았냐"고 물으면 에이전트는 "잠시만 기다려주세요"만 반복했다. 이미 받은 번호를 다음 날 또 물었다. 유저는 짜증을 냈다. 계속해서 오류를 체크했고 수정했다. 하나를 막으면 안 그려본 대화가 또 나왔다.
왜 그렇게 헤매고 있던건지 이유를 생각해봤다.
이건 내가 만들던 서비스랑 개념이 달랐던 것 = 에이전트 서비스
확률 기반 서비스다. 정해진 인풋에 정해진 아웃풋이 나오는 게 아니다. 같은 말을 넣어도 매번 다르게 나온다. 오류를 "고쳤다"가 아니라 "일어날 확률을 줄였다"까지만 말할 수 있다. 경우의 수를 다 막는다는 개념이 없다.
적재되며 쌓이는 서비스다. 기존 서비스에서 잘못된 입력은 그 요청 하나로 끝난다. 에이전트는 대화를 기억하고 프로필을 쌓아간다. 한 번 잘못 읽은 값이 그 자리에서 안 끝난다. 대화 내내 살아남아 계속 끼어든다. 어제 받은 번호를 오늘 또 물은 것처럼.
맥락을 읽는 서비스다. 기존 서비스는 입력의 형식이 정해져 있다. 숫자 칸엔 숫자가 들어온다. 에이전트한테 유저는 그냥 말한다. 다급하게 묻고, 짜증 내고, 딴 데로 샌다. 그 말을 뭘로 읽을지 정할 기준은 코드 안에 없다. 맥락을 읽어야 한다.
그래서 계속 돌렸다
이런 프로덕트는 방법이 없다. 계속 구조화하고 수정하고 무한 이터레이션 돌려보는 것. 확률이라 실제로 넣어보기 전엔 뭐가 나올지 모른다. 설계로 미리 막을 수가 없다. 그리고 내가 했던 설계와 실제 나오는 결과와 어떤이유때문에 다른 결과가 나오는건지 아웃풋을 보고, 고치고, 다시 넣는 수밖에 없다.
그래서 한 달 넘게 돌리고 있다. 모델을 바꾼다. 그 모델에 맞춰 프롬프트를 깎는다. 돌려본다. 안 되면 원인을 찾고 고친다. 또 안 되면 모델을 바꾼다. 그러면 프롬프트를 처음부터 다시 깎는다. 시스템 프롬프트를 붙였더니 에이전트가 20초, 30초 뒤에 답했다. 그 속도면 유저가 쓸 이유가 없다. 다시 깎는다.
저울 위엔 늘 세 개가 있다. 유저 경험, 성능, 가격. 프롬프트를 늘리면 똑똑해지는 대신 느려지고 비싸진다. 모델을 낮추면 싸지는 대신 대화가 얕아진다. 하나를 잡으면 하나가 흔들린다. 이 사이를 오가면서 유저 경험을 맞춰간다. 서비스가 주려는 것과 유저가 겪는 것. 그 둘이 만나는 지점을 찾는 일이다.
이건 사이드 프로젝트다. 둘이서 남는 시간에 붙였다 뗐다 한다. 그래서 한달동안 몰입하는 시간 없이 짬짬히 계속 하고 있다.
지금 어디까지 왔나
한 달 넘게 돌리고 있다.
모델을 바꾼다. 그 모델에 맞춰 프롬프트를 깎는다. 돌려본다. 안 되면 원인을 찾고 고친다. 또 안 되면 모델을 바꾼다. 그러면 프롬프트를 처음부터 다시 깎는다. 시스템 프롬프트를 붙였더니 에이전트가 20초, 30초 뒤에 답했다. 그 속도면 유저가 쓸 이유가 없다. 다시 깎는다. 같은 자리를 몇 바퀴째 도는지 모르겠다.
저울 위엔 늘 세 개가 있다. 유저 경험, 성능, 가격. 프롬프트를 늘리면 똑똑해지는 대신 느려지고 비싸진다. 모델을 낮추면 싸지는 대신 대화가 얕아진다. 하나를 잡으면 하나가 흔들린다. 이 사이를 오가면서 유저 경험을 맞춰간다. 서비스가 주려는 것과 유저가 겪는 것. 그 둘이 만나는 지점을 찾는 일이다.
답이 없어서 도는 게 아니다. 뭘 해야 하는지는 안다. 재료가 확률이라 매번 돌려봐야만 아는 거다. 이건 사이드 프로젝트다. 둘이서 남는 시간에 붙였다 뗐다 한다. 몰입할 시간을 통으로 낸 적도 없다. 한두 시간씩, 꾸역꾸역.
그래도 최소 기능은 하나씩 붙었다. 완벽한 통제는 아직 멀었다. 그래도 초기 서비스로 볼 만한 적정점은 거의 찾은 것 같다. 대화를 다 설계할 수는 없다. 어디로 튀든 받아낼 폭을, 돌려보는 만큼 넓혀가는 중이다.
* 커리어 에이전트는 아래 링크에서 사용해보실 수 있습니다.
https://pf.kakao.com/_CMXpn