AI Meeting Cheat-sheet 기획 및 개발
why- Yess의 타겟 고객은 서비스 비즈니스를 제공하는 에이전시, 스튜디오 등입니다. 이들이 프로젝트 성사 과정에서 겪는 실제 문제에 깊게 파고들어 PMF 검증을 전제로 한 피처 기획을 제안했습니다.
- 일정 기간 동안 개발자와 기획자의 구분 없이 모든 팀원이 기획을 진행했습니다. 그 과정에서 고객들이 세일즈의 가장 앞 단계인 미팅 준비에 가장 많은 시간을 할애하고 그만큼 어려움을 느낄 것이라는 가설을 세웠고, 인터뷰를 통해 실제 문제임을 확인했습니다. 이 문제를 해결하기 위해 Meeting Cheat-sheet이라는 주제로 Lo-fi 와이어프레임을 직접 그리면서 기획하였습니다.
- AI로부터 실시간으로 받는 데이터를 심리스한 스트리밍 UI/UX로 제공하기 위해 기술적으로 여러 방법을 시도했습니다. 내부적으로 사용중인 텍스트 에디터와 웹소켓 라이브러리에 의존성이 있다 보니 복잡도를 제거한 환경에서 테스트해보는 것이 도움이 되었습니다. 팀원들과 해커톤에 참가해 Vercel AI SDK를 활용해 보거나 rxjs로 자체적인 스트리밍 모듈을 구현해 보기도 했습니다. 그러나 실제 제품에 적용하면 여전히 복잡도가 높아지고 일관적인 동작이 보장되지 않았습니다. 이를 해결하기 위해 응답에 스트리밍 관련 플래그 데이터가 포함되는 Server Driven 방식을 제안하였고 팀 내 논의를 거쳐 서버와 클라이언트 사이의 웹소켓 라이브러리 레벨에서 해당 작업을 수행하는 절충안을 선택 후 개선하였습니다.
- Meeting Cheat-sheet을 기점으로 고객의 세일즈 과정을 돕는 기능들인 프로젝트의 맥락 분석, 미팅 요약, 제안서 생성 등의 주요 피처들이 기획되었습니다. 이 피처들이 모여 Yess 1.0의 AI Sales Copilot이 완성되었고 Yess와 같은 도메인에서 이미 규모가 큰 서비스들이 있음에도 불구하고 AI-native로서는 첫 플레이어로 선보이는 기반이 되었습니다.
- 기획 단계에서 고객이 실제 상황에 필요로 하는 UX는 무엇일지를 가장 많이 고민했고, 네이밍에 대한 아이디어도 이런 접근을 통해 도출하였습니다.
- AI를 다룰 때 UX 목표를 정의하는 것이 중요하다는 것을 배웠습니다. AI 스트리밍을 구현하는 방법은 다양하지만 난이도와 복잡도를 기준으로 선택하기보다도 목표를 기준으로 선택하는 것이 시간을 더 절약하는 방법입니다. 자연스러운 대화의 느낌을 주는 것이 목표라면 스트리밍이 좋은 방법일 수 있지만 AI의 응답을 최대한 빠르게 전달하는 것이 목표라면 스트리밍은 불필요할 수도 있기 때문입니다. 마찬가지로 AI 자체도 수단에 불과하기 때문에 목표를 세분화하여 꼭 필요하고 도움이 되는 영역에서 적절하게 사용하는 것이 중요합니다.
새로운 에디터 라이브러리 점진적 도입
why- Yess 웹앱에서 문서 편집은 가장 초창기부터 있었고 앞으로도 사라지지 않을 중요한 기능인 만큼 에디터 라이브러리에 대한 의존도가 높습니다. 기존에 도입된 quill 라이브러리의 경우 유지보수가 더디고, 커스터마이즈에 유연하지 않은 점 때문에 포크 버전을 코드베이스 내에 별도로 관리하게 되면서 정상적인 버전 관리의 혜택도 받기 어려운 형태였습니다. 게다가 포크 버전의 코드가 type strict하지 않은 점은 기능을 빠르고 안정적으로 개발하는 데 허들이 되고 있었습니다. 앞으로는 Generative AI를 도입하여 더욱 인터랙티브한 요구사항에 대응해야 하는 상황을 고려했을 때 새로운 에디터 라이브러리 도입이 필요하다고 판단했습니다.
- ProseMirror 기반의 tiptap 라이브러리를 검증 대상으로 선정하고 몇 회차에 걸쳐 POC를 진행했습니다. 어려운 문제를 대하는 부담을 덜 수 있도록 스프린트 범위 바깥에서 페어 프로그래밍 형태로 진행했습니다.
- POC 후 실제 스프린트에서 Workflow Automation 기능의 이메일 내용 편집기를 구현하기 위해 tiptap을 부분 도입했습니다. 예상하지 못한 문제들이 발생했을 때 ProseMirror의 데이터 구조를 잘 알지 못해서 헤매기도 했지만 팀원들의 도움으로 함께 트러블 슈팅을 하면서 새로운 라이브러리의 러닝 커브를 넘을 수 있었습니다.
- 간단한 기능부터 부분적으로 도입하고 나니 핵심 기능에 대한 POC는 비교적 부담이 덜해졌습니다. 처음부터 동시 수정 및 AI streaming을 새 에디터로 구현하고자 했으면 훨씬 큰 블랙박스를 감당하기 어려워 선택하지 못했을 것입니다.
- 기획적으로 편집 가능한 영역에 대해 요구사항이 주어졌을 때 빠르게 시도할 수 있게 되었습니다. 기존의 quill 기반 모듈만 있을 때와는 달리 안정적인 타입 시스템과 긍정적인 개발자 경험의 도움을 받을 수 있는 tiptap이라는 선택지가 추가되었기 때문에 점진적으로 확대 적용하고 있습니다.
- 러닝 커브가 가파르더라도 팀의 도움으로 함께 넘으면 더 수월하고 빠르다는 것을 배웠습니다. 도움에만 의지하지 않고 스스로 노력하는 것도 중요하지만, 정말 도움이 필요할 때는 요청하는 것 역시 중요합니다. 또한 도움을 요청할 때는 문제 상황에 대해 지금까지 파악한 내용과 앞으로 어떤 부분을 해결해야 하는지를 명확하게 정리해서 전달해야 합니다.
Widget SDK 성능 개선
why- Yess는 사용자가 자신의 웹사이트에 코드 스니펫을 심어서 고객 문의 창구로 사용할 수 있는 자바스크립트 위젯 SDK를 제공합니다. 이 위젯 내에서 고객 문의를 입력받는 Inquiry Form의 첫 로드까지 시간이 5초 정도로 긴 현상이 있었습니다. 로딩이 거의 필요하지 않은 blazingly fast한 경험을 제공하기 위해 성능 개선을 진행하였습니다.
- 위젯이 처음 구현될 당시 Inquiry Form은 별도의 단독 서비스로 제공되고 있는 기능이었기 때문에, 공개된 Inquiry Form의 URL을 iframe에 띄우는 형식으로 구현되었습니다. 다만 위젯 SDK 역시 iframe으로 동작하고 있기 때문에 이는 iframe 중첩 현상으로 인한 추가적인 네트워크 요청으로 이어졌습니다. 네트워크 요청의 응답 속도를 개선하는 것도 고려할 수 있는 방안이지만 조금 더 근본적인 방향성을 고민한 결과 모노레포 전환을 실행하기로 했습니다. Yess에는 이처럼 별도 서비스로도 동작할 수 있는 기능이 여러 개 있고 서로 연관성을 가질 가능성도 높은 Vertical SaaS 제품이기 때문에, 그 특수성을 고려하여 웹앱과 위젯이 멀티 레포로 분리되어 있던 구조를 모노레포로 통합하였습니다.
- 여러 개의 앱이 서로를 빌드 타임에 참조할 수 있는 환경이 구성되어 위젯 내 Inquiry Form의 로딩 시간이 제거되었습니다. 또한 모노레포 구조가 정착되면서 공통 코드를 관리하기 용이해졌고, 공통 코드를 기반으로 새로운 앱을 구성하고 배포 환경을 마련하는 것이 간편해졌습니다.
- 작지 않은 규모의 레거시 코드베이스에 대해 근본적인 구조 변경을 가하는 작업이었기 때문에 노가다와 예상치 못한 빌드 에러를 해결하는 과정의 연속이었습니다. 하지만 blazingly fast한 경험 제공이라는 목표가 뚜렷했기 때문에 필요한 과정으로 인지하고 팀이 함께 노력할 수 있었습니다. 개발 전략을 설득하고 실행하는 데 있어서도 working backwards 방법론이 유효하다는 것을 배웠습니다.