매글프 개발 일지 25.09.25
2025. 09. 25·published in 1일1글
- 최근에 개발한 댓글 제안 기능. 요즘 영 퀄리티가 떨어진 것 같다는 느낌을 받는다. 코드를 바꾼 건 없는데. 진짜로 퀄리티가 떨어졌을까? 떨어졌다면 왜인지 어떻게 알 수 있을까. 지금은 이걸 모니터링할 도구가 하나도 없다.
- LLM이 대중화되면서 해외 뉴스레터/팟캐스트에서는 ‘Eval’ 이라는 키워드가 많이 나온다. Eval이 중요하다느니 AI PM의 필수 스킬이라느니.. Eval은 결국 LLM 서비스의 품질을 측정하는 것을 말한다. 마치 일반 앱의 QA 같은 것이다.
- 이걸 잘하기 위해서는 일반 QA와 달리 몇 가지 또 알아야할 것들이 있는데 왠지 이런 부분도 배워두면 좋겠다. 내가 무언가를 건드렸을 때 LLM 퀄리티가 떨어지지 않았음을 알아야 변경을 할 수 있을테니까.
- 연속 일수 기능의 버그가 계속 남아있다. 제대로 측정을 못하는 엣지케이스가 있고, 연속 일수가 잘못 올라가버리는 현상이 발생한다. 일단 연속 일수 로직이 복잡한 것도 있는데, 애초에 디버깅이 어렵게 설계한 잘못인 것 같다.
- ‘A 유저의 B 시간 대 글쓰기’라는 이벤트를 가지고, 이벤트가 발생했을 때 해당 유저의 신규 상태 (연속 일수 유지 중, 회복 가능, 회복 불가능) 이라는 상태를 추론해내고 업데이트한다.
- 그 업데이트와 동시에 연속 일수도 직접 DB에 업데이트하게 된다. 문제는 DB에 상태를 직접 쓰기 때문에, 시간이 지나면서 도대체 어떤 이벤트가 어떤 로직의 문제가 있어서 DB의 일수가 이렇게 변했는지 알수가 없다.
- 우리 팀 서버 개발자에게 물어보니 이런 경우는 이벤트 소싱 패턴이라는 것을 쓴다고 한다. 이벤트가 발생한 시점에, 상태를 계산해서 기록해두고 버리는 것이 아니라 이벤트는 발생한 그대로 적재해두고, 상태가 필요한 시점에 여태까지의 이벤트를 차례차례 계산을 해서 현재의 상태를 알아내는 것이다.
- 개발자만 아는 말을 해서 좀 더 쉽게 식당에 비유해보자.
- 전자(지금 방식)는 재료가 입고되는 시점에 미리 조리를 다해두고 냉장고에 넣는 것이다.
- 후자(이벤트 소싱 패턴)는 재료가 입고되면 그대로 냉장고에 두고 주문이 들어왔을 때 꺼내서 조리하는 것이다.
- 이벤트 소싱 패턴을 썼다면 뭐가 다를까? 재료를 그대로 냉장고에 쌓아두는 것에는 별다른 로직이 없다. 즉 냉장고(DB) 내에 잘못된 데이터가 들어있을 확률은 낮아진다. 주문된 요리가 잘못되었을 때 어디서 조리가 잘못되었는지 쉽게 재현이 가능해진다.
- 반면 이미 냉장고에서 꺼냈는데 잘못되어있는 경우는 어디서부터 문제가 발생한 건지 추적이 어렵다.
- 이런 ‘주문 후 즉시 조리’ 구조는 금융 앱에서 거래 내역을 통해 잔액 상태를 추론할 때도 쓰인다. 거래내역이라는 건 꽤나 복잡 (승인 취소, 입금, 출금, 결제 취소, 뭐시기 뭐시기..)하고 버그가 절대 있으면 안되기 때문이다. 사실 우리가 잔액을 주문할 때 냉장고에는 그 동안의 모든 거래의 내역 (어디에서 어디로 +, -라는 정보)만 저장되어있을 뿐이다. 잔액을 주문을 받은 시점에 계산해서 준다.
- 물론 이런 방법이 있는 걸 몰랐던 건 아니지만 나는 처음에 과도하게 복잡하다고 생각했다. (버그가 별로 없을 줄…) 게다가 주문 후 즉시 조리의 문제점은 당연하게도 주문 후 음식이 나올 때까지 오래걸린다는 점이다.
- 나는 MAU 26의 작은 서비스로서 상시 인스턴스가 아니라 서버리스 방식을 쓰고 있다. 식당에 다시 비유하자면 알바비를 줄 돈을 아끼기 위해 항상 카운터에 대기하는 알바를 두지 않았다. 대신 ‘필요시 연락 바람 010-XXXX-XXXX’라고 써붙여두었다는 말이다. 그러니 연락을 받고 가게에 나타나는 시간도 고려해야하고, 여기에 냉장고에 쟁여둔 글쓰기 내역으로부터 연속 일수와 잔디 그래프를 계산해주는 시간까지 고려하면 너무 늦지 않겠냐 이 말이다.
- 하지만 냉장고에서 차가운 버그들을 꺼내가면서 괴로워하고 있자니 역시 이 방법은 틀렸다라는 생각이 들었다. 이번 주말에는 꼭 구조 자체를 바꿔서 신선한 연속 일수를 되돌려놓아야겠다.