
Compose에서 Stable을 가볍게 보면 안 되는 이유: 베드 케이스로 본 안정성의 법칙 Part 1
Android Compose를 사용할 때 안정성(Stability) 은 결코 가볍게 넘길 수 없는 핵심 주제입니다. 안정성이 지켜져야만 Compose가 불필요한 재구성을 건너뛰고 성능을 유지할 수 있기 때문입니다. 이를 위해 개발자가 따라야 할 몇 가지 규칙이 존재하지만, 문서나 예제만으로는 모든 함정을 미리 알기 어렵습니다.이 글에서는 안정성 개념을 이미 기본적으로 이해하고 있는 개발자를 대상으로 합니다. 단순 개념 설명이 아니라, 직접 겪을 수 있는 베드 케이스(잘못 사용 한 사례) 를 통해 우리가 놓치기 쉬운 부분과 Compose 내부가 어떤 메커니즘으로 반응하는지 살펴보겠습니다.베드 케이스 실험recomposition이 발생했을 때, 일반 class, data class, @Stable, @Immutable 을 각각 적용했을 때 어떤 결과가 나타나는지 비교했습니다.Test version : kotlin 2.2.10, compose bom 2025.08.00테스트는 recomposition을 강제로 발생시키는 버튼을 포함한 TestScreen으로 구성하였습니다. 버튼을 누를 때마다 count 값이 증가하여 Column 내부가 recomposition 대상이 되도록 하여 어떤 경우에 recomposition skip 되는지 알아보겠습니다.@Composablefun TestScreen() { var count by remember { mutableIntStateOf(0) } Column { Button( onClick = { count++ }, // count 를 증가 시켜 recomposition 발생 ) { Text("count: $count") } // recomposition 대상 코드 TestClassContent(TestClass("$count TestClass Text")) }}class + var 프로퍼티 조합일반 class 와 가변 형태에서 테스트 결과 입니다. 테스트를 진행하는 Content 내부에는 Row 로 감싸진 Text Component 를 사용하며, TestClass 의 String를 통해 text 를 그리게 되어있습니다.class TestClass( var text: String,)@Composablefun TestClassContent(content: TestClass) { Row(modifier = Modifier.padding(10.dp)) { Text(text = content.text) }}val testClass by remember { mutableStateOf(TestClass("TestClass Text")) }TestClassContent(testClass)TestClassContent(TestClass("New TestClass Text"))TestClassContent(TestClass("$count TestClass Text"))rememb
9/2/2025

Compose에서 Stable을 가볍게 보면 안 되는 이유: 베드 케이스로 본 안정성의 법칙 Part 1
Android Compose를 사용할 때 안정성(Stability) 은 결코 가볍게 넘길 수 없는 핵심 주제입니다. 안정성이 지켜져야만 Compose가 불필요한 재구성을 건너뛰고 성능을 유지할 수 있기 때문입니다. 이를 위해 개발자가 따라야 할 몇 가지 규칙이 존재하지만, 문서나 예제만으로는 모든 함정을 미리 알기 어렵습니다.이 글에서는 안정성 개념을 이미 기본적으로 이해하고 있는 개발자를 대상으로 합니다. 단순 개념 설명이 아니라, 직접 겪을 수 있는 베드 케이스(잘못 사용 한 사례) 를 통해 우리가 놓치기 쉬운 부분과 Compose 내부가 어떤 메커니즘으로 반응하는지 살펴보겠습니다.베드 케이스 실험recomposition이 발생했을 때, 일반 class, data class, @Stable, @Immutable 을 각각 적용했을 때 어떤 결과가 나타나는지 비교했습니다.Test version : kotlin 2.2.10, compose bom 2025.08.00테스트는 recomposition을 강제로 발생시키는 버튼을 포함한 TestScreen으로 구성하였습니다. 버튼을 누를 때마다 count 값이 증가하여 Column 내부가 recomposition 대상이 되도록 하여 어떤 경우에 recomposition skip 되는지 알아보겠습니다.@Composablefun TestScreen() { var count by remember { mutableIntStateOf(0) } Column { Button( onClick = { count++ }, // count 를 증가 시켜 recomposition 발생 ) { Text("count: $count") } // recomposition 대상 코드 TestClassContent(TestClass("$count TestClass Text")) }}class + var 프로퍼티 조합일반 class 와 가변 형태에서 테스트 결과 입니다. 테스트를 진행하는 Content 내부에는 Row 로 감싸진 Text Component 를 사용하며, TestClass 의 String를 통해 text 를 그리게 되어있습니다.class TestClass( var text: String,)@Composablefun TestClassContent(content: TestClass) { Row(modifier = Modifier.padding(10.dp)) { Text(text = content.text) }}val testClass by remember { mutableStateOf(TestClass("TestClass Text")) }TestClassContent(testClass)TestClassContent(TestClass("New TestClass Text"))TestClassContent(TestClass("$count TestClass Text"))rememb
2025.09.02

좋아요

별로에요

데이터 자동 생성으로 생산성 향상 : Playwright로 3분 걸리던 계약 생성을 30초로!
데이터 자동 생성으로 생산성 향상 : Playwright로 3분 걸리던 계약 생성을 30초로!안녕하세요 여기어때컴퍼니 QA2팀 스칼렛입니다.오늘은 제가 Playwright를 활용하여 검증 과정에서 겪었던 비효율을 해소하고, 생산성을 극대화했던 경험을 공유하고자 합니다. 특히, 반복적인 수동 작업에 지쳐있던 분들이라면 이 글이 도움이 될 것이라고 생각합니다.기능 구현의 배경: ‘입점 계약’ 도입과 번거로움제가 참여했던 프로젝트는 파트너의 입점 계약 절차를 개선하는 내용이었습니다.기존에는 ‘내부 관리자 도구의 제휴점 정보’에서 직접 입력할 수 있었지만, 이제는 ‘입점 계약 플랫폼’을 통해서만 입력이 가능해졌습니다. 이 ‘입점 계약’은 수동으로 생성하거나, 이싸인온(eSignon, 전자계약)을 통해서만 생성할 수 있는데요.문제는 검증을 위해 필요한 계약 데이터를 수동으로 생성하는 데 있었습니다.숙소 카테고리 별로 계약 서식도 다르고 계약 내 입력 할 항목들도 많아 계약 한 건을 만드는 데 약 2~3분 정도가 소요되었고, 이는 단순 반복 작업의 연속이었습니다.이번에는 혼자서 프로젝트를 진행하여 제한된 시간을 효율적으로 활용하는 것이 매우 중요했기 때문에, 이러한 단순 작업을 줄이고 핵심적인 검증 작업에 더 집중하기 위해 데이터 자동 생성에 대해서 고려하게 되었습니다.왜 Playwright를 통한 자동화였나?Playwright는 웹 테스트 자동화 도구로 널리 알려져 있지만, 저는 데이터 자동 생성이라는 목표를 위해 이 도구를 선택했습니다. 테스트 자동화와 데이터 생성이라는 목적은 다르지만, Playwright의 강력한 기능들은 데이터 생성 작업에 특히 유용합니다. 제가 Playwright를 선택하게 된 이유는 다음과 같습니다.UI 레코딩 및 코드 생성: Playwright는 코드를 직접 레코딩하고 생성해주는 기능을 지원합니다. 이는 초기 개발 시간을 단축하고, UI 변경에 따른 유지보수를 더욱 쉽게 만듭니다. 로봇 프레임워크의 키워드 기반 방식은 유연하지만, Playwright의 코드 생성 방식은 직관적인 개발 경험을 제공합니다.빠른 실행 속도: Playwright는 브라우저와 직접 통신하여 Selenium보다 훨씬 빠르고 안정적으로 동작합니다. 특히 UI 레코딩 기반으로 자동화를 구축했을 때, 빠른 실행 속도는 대량의 데이터를 효율적으로 생성하는 데 필수적입니다.자동 대기(Auto-waiting): Playwright는 요소가 나타나거나 사라지는 것을 자동으로 기다려주므로, 타이밍 문제로 인한 불필요한 오류 발생 가능성이 현저히 낮아집니다. 로봇 프레임워크에서 수동으로 기다리는 명령을 추가하는 것보다 훨씬 편리하고 견고합니다.웹 테스트 자동화 도구인 Selenium 과의 비교Playwright 이전에는 웹 테스트 자동화 툴로 Selenium을 많이 사용했었는데요.표로 비교해보았습니다.→ 저는 테스트 자동화툴과 익숙하지 않았기때문에 초보자가 접근하기 쉬워야했고 codegen 기능을 통한 UI 레코딩 및 코드 생성과 빠른 실행 속도, 높은 안정성이
playwright
9/2/2025

데이터 자동 생성으로 생산성 향상 : Playwright로 3분 걸리던 계약 생성을 30초로!
데이터 자동 생성으로 생산성 향상 : Playwright로 3분 걸리던 계약 생성을 30초로!안녕하세요 여기어때컴퍼니 QA2팀 스칼렛입니다.오늘은 제가 Playwright를 활용하여 검증 과정에서 겪었던 비효율을 해소하고, 생산성을 극대화했던 경험을 공유하고자 합니다. 특히, 반복적인 수동 작업에 지쳐있던 분들이라면 이 글이 도움이 될 것이라고 생각합니다.기능 구현의 배경: ‘입점 계약’ 도입과 번거로움제가 참여했던 프로젝트는 파트너의 입점 계약 절차를 개선하는 내용이었습니다.기존에는 ‘내부 관리자 도구의 제휴점 정보’에서 직접 입력할 수 있었지만, 이제는 ‘입점 계약 플랫폼’을 통해서만 입력이 가능해졌습니다. 이 ‘입점 계약’은 수동으로 생성하거나, 이싸인온(eSignon, 전자계약)을 통해서만 생성할 수 있는데요.문제는 검증을 위해 필요한 계약 데이터를 수동으로 생성하는 데 있었습니다.숙소 카테고리 별로 계약 서식도 다르고 계약 내 입력 할 항목들도 많아 계약 한 건을 만드는 데 약 2~3분 정도가 소요되었고, 이는 단순 반복 작업의 연속이었습니다.이번에는 혼자서 프로젝트를 진행하여 제한된 시간을 효율적으로 활용하는 것이 매우 중요했기 때문에, 이러한 단순 작업을 줄이고 핵심적인 검증 작업에 더 집중하기 위해 데이터 자동 생성에 대해서 고려하게 되었습니다.왜 Playwright를 통한 자동화였나?Playwright는 웹 테스트 자동화 도구로 널리 알려져 있지만, 저는 데이터 자동 생성이라는 목표를 위해 이 도구를 선택했습니다. 테스트 자동화와 데이터 생성이라는 목적은 다르지만, Playwright의 강력한 기능들은 데이터 생성 작업에 특히 유용합니다. 제가 Playwright를 선택하게 된 이유는 다음과 같습니다.UI 레코딩 및 코드 생성: Playwright는 코드를 직접 레코딩하고 생성해주는 기능을 지원합니다. 이는 초기 개발 시간을 단축하고, UI 변경에 따른 유지보수를 더욱 쉽게 만듭니다. 로봇 프레임워크의 키워드 기반 방식은 유연하지만, Playwright의 코드 생성 방식은 직관적인 개발 경험을 제공합니다.빠른 실행 속도: Playwright는 브라우저와 직접 통신하여 Selenium보다 훨씬 빠르고 안정적으로 동작합니다. 특히 UI 레코딩 기반으로 자동화를 구축했을 때, 빠른 실행 속도는 대량의 데이터를 효율적으로 생성하는 데 필수적입니다.자동 대기(Auto-waiting): Playwright는 요소가 나타나거나 사라지는 것을 자동으로 기다려주므로, 타이밍 문제로 인한 불필요한 오류 발생 가능성이 현저히 낮아집니다. 로봇 프레임워크에서 수동으로 기다리는 명령을 추가하는 것보다 훨씬 편리하고 견고합니다.웹 테스트 자동화 도구인 Selenium 과의 비교Playwright 이전에는 웹 테스트 자동화 툴로 Selenium을 많이 사용했었는데요.표로 비교해보았습니다.→ 저는 테스트 자동화툴과 익숙하지 않았기때문에 초보자가 접근하기 쉬워야했고 codegen 기능을 통한 UI 레코딩 및 코드 생성과 빠른 실행 속도, 높은 안정성이
2025.09.02
playwright

좋아요

별로에요

유선과 무선의 협업으로 탄생한 끊김 없는 네트워크 비밀
오늘은 우리 삶의 필수템, 스마트폰 통신이 어떻게 더 촘촘하고 안정적으로 진화하고 있는지, 그 비밀스러운 내부 이야기를 살짝 공개하려고 합니다.'트럭이 전봇대를 박았는데 왜 내 폰이 안 터지지?' 같은 아찔한 상상, 한 번쯤 해보셨죠?바로 그 문제를 해결하기 위한 저희의 눈물겨운(?) 노력과 그 결과물,'Real Impact 커버리지맵(가칭)' 탄생 스토리를 지금 바로 시작합니다!😩 "우린 한 팀인데… 왜 따로 놀았을까?" 유선팀 vs 무선팀의 동상이몽통신사의 Lastmile 구간을 담당하는 대표적인 두 개의 조직이 있습니다.하나는 전국 방방곡곡에 중계기를 설치하고 최적의 통신 커버리지를 만드는 무선 조직!이들은 마치 명당 자리를 찾는 스나이퍼처럼, 중계기 위치와 안테나 각도에 영혼을 갈아 넣죠.무선팀: "여기 언덕에 중계기 뙇! 안테나 각도 30도 틀어서 저쪽 아파트 단지까지 신호 쏴줘야지! 빵빵 터져라!"* 끊김 없는 서비스를 위해 촘촘히 박혀 있는 무선 중계기다른 하나는 이 중계기들을 거미줄처럼 엮어주는 광케이블과 유선 장비를 관리하는 유선 조직!보이지 않는 땅속, 전봇대 위에서 안정적인 데이터 길을 만드는 도로 설계자 같은 존재랍니다.유선팀: "A중계기랑 B중계기는 이쪽 라인으로 묶고, C중계기는 만약을 위해 저쪽으로 돌려서 생존 루트 확보! 절대 끊기면 안 돼!"*모세혈관과 같이 전국 방방곡곡을 연결하는 유선망(선로 인프라+장비)문제는 이 두 전문가 집단이 각자의 미션에 너무 충실했다는 것!무선팀은 전파의 도달 범위에, 유선팀은 선로의 안정적인 연결에만 집중하다 보니,정작 '하나의 광케이블이 끊어졌을 때, 실제로 어떤 지역의 고객들이 얼마나 불편을 겪을까?' 에 대한 통합적인 답을 내리기 어려웠죠. 😱💡 "만약 이 선이 끊긴다면?" 발상의 전환이 만든 혁신강남역 한복판의 통신을 책임지는 중계기 10개가 하필이면 단 하나의 광케이블에 모두 연결되어 있다면?어느 날 갑자기 포크레인이 그 케이블을 '푹' 찍는 순간… 강남역 일대는 순식간에 통신 암흑지대가 되는.... 끔찍하죠? 😱하지만 만약 그중 3개의 중계기가 다른 길(광케이블)로 연결되어 있다면 어떨까요? 속도가 조금 느려질 순 있어도 카톡이나 검색 같은 최소한의 서비스는 유지될 수 있겠죠.이것이 바로 저희가 주목한 '생존 커버리지' 의 개념입니다.저희는 이 아이디어를 현실로 만들기 위해 두 가지 핵심 데이터를 융합하였습니다.ㅇ 프론트홀 토폴로지 (Fronthaul Topology): 어떤 중계기가 어떤 유선 장비와 광케이블에 연결되어 있는지 보여주는 '족보' 데이터! 📜ㅇ Atlas 맵: T맵 데이터를 포함, 수많은 모바일 기기가 실제로 어디서, 얼마나 원활하게 서비스를 이용하고 있는지 보여주는 '실시간 민심' 데이터! 🗺️*여기서 보여주는 색깔로 해당 지역에서 서비스 받은 from. 중계기를 구분합니다.이제 마법을 부릴 시간입니다! 유선망의 '족보'와 실시간 '민심' 데이터를 지도 위에서 합치고, 한단계, 한단계 분석해보았습니다.• None Logic : 서비스 out기준 Threshold : 60% 이하 (BIN 이내 서비스 out 40% 까지는 감내하겠음)위 분석 체계를 통해서 광케이블 하나를 지도 위에서 'OFF' 시켰을 때, 실제로 통신 서비스가 단절되는 '진짜' 영향 범위를 알 수 있게 되었습니다.기존에는 지도 위에 중계기 점들만 보고 '음, 이 지역은 중계기가 많으니 괜찮겠군' 하고 막연히 추측했다면,이제는 '아니, 이 케이블 하나 끊기면 여기 아파트 단지랑 저기 쇼핑몰 전체가 서비스 불능이네!' 하고 직관적으로 리스크를 파악할 수 있게 된 거죠.*특정선로에 연계된 커버리지 현황 및 서비스 아웃 분석 화면이 'Real Impact 커버리지맵'은 단순히 위험을 보는 것에서 그치지 않습니다.(To-Be)👨💻 똑똑한 망 설계: 새로운 광케이블을 어디에 깔아야 가장 효율적으로 위험을 분산시킬 수 있을지, 데이터 기반의 최적의 루트를 찾습니다. (삽질 방지!)🚨 선제적 위기관리(RM): 태풍이나 화재 등 재난 상황 발생 시, 가장 취약한 지역을 미리 파악하고 자원을 집중 투입해 골든타임을 확보할 수 있습니다.👍 고객 경험 레벨업: 고객들은 이제 '운 나쁘게' 통신이 끊기는 경험을 훨씬 덜하게 될 겁니다. 보이지 않는 곳에서 저희의 데이터가 여러분의 연결을 지킬테니!!🚀 연결의 미래, 데이터가 그 길을 밝힌다이제 저희는 더 이상 유선과 무선이라는 틀에 갇혀 세상을 보지 않습니다.고객이 느끼는 '실질적인 서비스 품질'이라는 단 하나의 목표를 향해, 데이터라는 강력한 무기를 손에 쥐었죠.'Real Impact 커버리지맵'은 그 위대한 여정의 첫걸음입니다.앞으로 AI와 머신러닝을 더해 미래의 장애를 예측하고, 스스로 네트워크를 최적화하는 단계까지 나아가는 것이 저희의 최종 목표랍니다.여러분의 손안에서 펼쳐지는 끊김 없는 세상, 기대되시죠? 😉
9/2/2025

유선과 무선의 협업으로 탄생한 끊김 없는 네트워크 비밀
오늘은 우리 삶의 필수템, 스마트폰 통신이 어떻게 더 촘촘하고 안정적으로 진화하고 있는지, 그 비밀스러운 내부 이야기를 살짝 공개하려고 합니다.'트럭이 전봇대를 박았는데 왜 내 폰이 안 터지지?' 같은 아찔한 상상, 한 번쯤 해보셨죠?바로 그 문제를 해결하기 위한 저희의 눈물겨운(?) 노력과 그 결과물,'Real Impact 커버리지맵(가칭)' 탄생 스토리를 지금 바로 시작합니다!😩 "우린 한 팀인데… 왜 따로 놀았을까?" 유선팀 vs 무선팀의 동상이몽통신사의 Lastmile 구간을 담당하는 대표적인 두 개의 조직이 있습니다.하나는 전국 방방곡곡에 중계기를 설치하고 최적의 통신 커버리지를 만드는 무선 조직!이들은 마치 명당 자리를 찾는 스나이퍼처럼, 중계기 위치와 안테나 각도에 영혼을 갈아 넣죠.무선팀: "여기 언덕에 중계기 뙇! 안테나 각도 30도 틀어서 저쪽 아파트 단지까지 신호 쏴줘야지! 빵빵 터져라!"* 끊김 없는 서비스를 위해 촘촘히 박혀 있는 무선 중계기다른 하나는 이 중계기들을 거미줄처럼 엮어주는 광케이블과 유선 장비를 관리하는 유선 조직!보이지 않는 땅속, 전봇대 위에서 안정적인 데이터 길을 만드는 도로 설계자 같은 존재랍니다.유선팀: "A중계기랑 B중계기는 이쪽 라인으로 묶고, C중계기는 만약을 위해 저쪽으로 돌려서 생존 루트 확보! 절대 끊기면 안 돼!"*모세혈관과 같이 전국 방방곡곡을 연결하는 유선망(선로 인프라+장비)문제는 이 두 전문가 집단이 각자의 미션에 너무 충실했다는 것!무선팀은 전파의 도달 범위에, 유선팀은 선로의 안정적인 연결에만 집중하다 보니,정작 '하나의 광케이블이 끊어졌을 때, 실제로 어떤 지역의 고객들이 얼마나 불편을 겪을까?' 에 대한 통합적인 답을 내리기 어려웠죠. 😱💡 "만약 이 선이 끊긴다면?" 발상의 전환이 만든 혁신강남역 한복판의 통신을 책임지는 중계기 10개가 하필이면 단 하나의 광케이블에 모두 연결되어 있다면?어느 날 갑자기 포크레인이 그 케이블을 '푹' 찍는 순간… 강남역 일대는 순식간에 통신 암흑지대가 되는.... 끔찍하죠? 😱하지만 만약 그중 3개의 중계기가 다른 길(광케이블)로 연결되어 있다면 어떨까요? 속도가 조금 느려질 순 있어도 카톡이나 검색 같은 최소한의 서비스는 유지될 수 있겠죠.이것이 바로 저희가 주목한 '생존 커버리지' 의 개념입니다.저희는 이 아이디어를 현실로 만들기 위해 두 가지 핵심 데이터를 융합하였습니다.ㅇ 프론트홀 토폴로지 (Fronthaul Topology): 어떤 중계기가 어떤 유선 장비와 광케이블에 연결되어 있는지 보여주는 '족보' 데이터! 📜ㅇ Atlas 맵: T맵 데이터를 포함, 수많은 모바일 기기가 실제로 어디서, 얼마나 원활하게 서비스를 이용하고 있는지 보여주는 '실시간 민심' 데이터! 🗺️*여기서 보여주는 색깔로 해당 지역에서 서비스 받은 from. 중계기를 구분합니다.이제 마법을 부릴 시간입니다! 유선망의 '족보'와 실시간 '민심' 데이터를 지도 위에서 합치고, 한단계, 한단계 분석해보았습니다.• None Logic : 서비스 out기준 Threshold : 60% 이하 (BIN 이내 서비스 out 40% 까지는 감내하겠음)위 분석 체계를 통해서 광케이블 하나를 지도 위에서 'OFF' 시켰을 때, 실제로 통신 서비스가 단절되는 '진짜' 영향 범위를 알 수 있게 되었습니다.기존에는 지도 위에 중계기 점들만 보고 '음, 이 지역은 중계기가 많으니 괜찮겠군' 하고 막연히 추측했다면,이제는 '아니, 이 케이블 하나 끊기면 여기 아파트 단지랑 저기 쇼핑몰 전체가 서비스 불능이네!' 하고 직관적으로 리스크를 파악할 수 있게 된 거죠.*특정선로에 연계된 커버리지 현황 및 서비스 아웃 분석 화면이 'Real Impact 커버리지맵'은 단순히 위험을 보는 것에서 그치지 않습니다.(To-Be)👨💻 똑똑한 망 설계: 새로운 광케이블을 어디에 깔아야 가장 효율적으로 위험을 분산시킬 수 있을지, 데이터 기반의 최적의 루트를 찾습니다. (삽질 방지!)🚨 선제적 위기관리(RM): 태풍이나 화재 등 재난 상황 발생 시, 가장 취약한 지역을 미리 파악하고 자원을 집중 투입해 골든타임을 확보할 수 있습니다.👍 고객 경험 레벨업: 고객들은 이제 '운 나쁘게' 통신이 끊기는 경험을 훨씬 덜하게 될 겁니다. 보이지 않는 곳에서 저희의 데이터가 여러분의 연결을 지킬테니!!🚀 연결의 미래, 데이터가 그 길을 밝힌다이제 저희는 더 이상 유선과 무선이라는 틀에 갇혀 세상을 보지 않습니다.고객이 느끼는 '실질적인 서비스 품질'이라는 단 하나의 목표를 향해, 데이터라는 강력한 무기를 손에 쥐었죠.'Real Impact 커버리지맵'은 그 위대한 여정의 첫걸음입니다.앞으로 AI와 머신러닝을 더해 미래의 장애를 예측하고, 스스로 네트워크를 최적화하는 단계까지 나아가는 것이 저희의 최종 목표랍니다.여러분의 손안에서 펼쳐지는 끊김 없는 세상, 기대되시죠? 😉
2025.09.02

좋아요

별로에요

[에이닷 4.0 QE 여정3] LLM 품질 평가의 진화: SPeCTRA 2.0 톺아보기
진화한 에이닷 4.0의 개편에이닷 3.0은 MainAgent, MusicAgent, StockAgent, MediaAgent, MovieAgent의 5개의 Agnet가 각각의 대화방으로 구성으로 개별성을 가지고 있었지만에이닷은 4.0으로 개편이 진행되었고 에이닷 3.0의 여러 Agent 대화방을 하나로 통합하는 OneAgnet로 진화하였습니다.여러 Agent를 하나로 통합되었기 때문에 검증에 대한 방법도 달리 진행이 필요했고 SPeCTRA도 2.0으로 변화를 준비하게 되었습니다.시작하며: SPeCTRA 1.0의 성과와 새로운 과제• None 효과적인 LLM 품질 평가 : 도구, 기준, 그리고 적용기 톺아보기(SPeCTRA)작년에 소개해드린 SPeCTRA 1.0은 기존의 수동적이고 주관적일 수 있는 LLM 답변 품질 평가를 자동화된 'LLM-as-a-judge' 방식으로 전환한 혁신적인 시도였습니다.로컬 PC 환경에서 클라이언트 로그를 직접 파싱하고, Java 기반의 배포 툴을 통해 QA/TE는 물론 유관부서 모두가 LLM 품질 테스트를 수행할 수 있게 함으로써 테스트 리소스의 효율을 극대화했습니다.하지만 여기서 멈추지 않았습니다.에이닷 4.0이 OneAgent로 개편됨에 따라 대규모 테스트의 연속성을 확보하고, 여러 팀 간의 협업을 더욱 원활하게 하며, 물리적 디바이스 연결의 한계를 극복하기 위한 새로운 과제가 주어졌습니다.더 높은 확장성, 향상된 협업, 그리고 안정적인 테스트 환경을 위해 SPeCTRA는 2.0으로의 진화를 시작했습니다.SPeCTRA 2.0의 핵심 변화: 무엇이 달라졌는가?SPeCTRA 2.0은 1.0을 계승하되, 데이터 흐름을 API 중심으로 완전히 재편하고 Web에서 구동되도록 개편되었습니다. 주요 변화는 다음과 같습니다.1. API 기반 테스트로의 전환가장 큰 변화는 테스트 실행 방식입니다.SPeCTRA 1.0이 로컬 PC에 연결된 모바일 클라이언트를 Appium, Logcat으로 제어하는 방식이었다면, SPeCTRA 2.0은 대화방의 API를 직접 호출하는 방식으로 전환되었습니다.이는 더 이상 테스트를 위해 물리적인 디바이스나 클라이언트 앱 실행 환경이 필요 없다는 것을 의미합니다.덕분에 테스트 환경 구축이 단순해졌고, CI/CD 파이프라인과의 연동이 더욱 유연해졌으며, API 기반의 동시 다발적인 테스트 수행으로 속도와 확장성 면에서 비약적인 발전을 이루었습니다.로컬 PC의 Excel 파일로 관리되던 테스트 시나리오와 결과 데이터는 이제 Google Sheets로 통합되었습니다.Google Sheets를 도입함으로써 얻는 이점은 명확합니다.• None 실시간 협업: QE팀이 동일한 테스트 시트 위에서 실시간으로 시나리오를 추가/수정하고, 평가 결과를 즉시 확인할 수 있습니다.• None 버전 관리 및 이력 추적: TestCase 모든 변경 사항이 기록되어 데이터의 정합성을 유지하기 용이합니다.• None 유연한 연동: Google Cloud 환경의 다른 서비스나 스크립트와 쉽게 연동하여 데이터 처리의 실시간 동기화 가능해졌습니다.3. 신뢰성 있는 로그 데이터 활용SPeCTRA 1.0에서는 실시간 클라이언트 로그를 파싱하여 LLM의 응답을 추출했습니다.이는 간편하지만, 로그 포맷이 변경되거나 유실될 경우 테스트의 안정성이 떨어질 수 있는 단점이 있었습니다.SPeCTRA 2.0에서는 중앙 로그 관리 시스템인 내부 시스템 로그의 결과 데이터를 활용합니다.정제되고 구조화된 로그 데이터를 API를 통해 가져옴으로써, LLM의 요청(request)과 응답(response)을 누락 없이 정확하게 확보할 수 있게 되어 테스트의 신뢰도를 크게 높였습니다.더군다나 LLM답변 추출에 그치지 않고 새롭게 도입된 Rewrite, Routing의 데이터도 함께 추출하여 실시간 동기화성을 더욱 극대화 했습니다.새로운 에이닷 4.0에는 사용자 기억 지양점인 Memory가 도입됨에 따라 SPeCTRA도 진화가 필요했습니다.기존의 1.0의 Judge Prompt는 그대로 사용하되 Memory 기능확인을 위한 추가 Prompt를 도입함하여 차별화를 두었습니다.SPeCTRA 2.0의 심장부: 자동화된 평가 아키텍처이 영역의 핵심은 'QA Judge Model'입니다.이 모델은 단순히 사용자의 질문과 LLM의 최종 답변만 보고 정답을 맞혔는지 평가하는 것을 넘어, 답변이 생성되기까지의 '과정'을 검증합니다.즉, LLM 에이전트의 '생각'의 흐름을 추적하여 평가하는 것입니다.SPeCTRA 2.0은 다양한 내부 API와 연동하여 에이전트의 동작을 다각도로 분석합니다.• None Reactive API: Access_Token을 기반으로 한 API 호출을 통해, 사용자 정보나 페르소나에 따른 개인화된 응답(Reactive) 결과가 올바르게 생성되었는지 확인합니다.• None Memory API: 대화에 적재된 기억(Memory)을 LLM 에이전트가 올바르게 조회하고 활용했는지 검증합니다.• None Rewrite & Routing API : 중앙 로그 시스템인 내부 시스템 로그를 통해 대화의 맥락을 어떻게 재구성(Rewrite)했는지, 그리고 Agent가 어떤 기능 Routing을 호출하려고 계획했는지까지 추적하여 평가의 정확도를 높입니다.이렇게 각 API를 통해 수집된 '과정' 데이터는 기존 SPeCTRA 1.0의 Safety, Performance, Tone & Manner, Accuracy를 포함하여SPeCTRA의 다차원적인 평가 기준(Prompt)과 결합되어 최종 평가 점수를 도출합니다.새로워진 SPeCTRA 2.0의 워크플로우SPeCTRA 2.0의 단순히 Data 추출를 API로 이전한 것에 그치지 않습니다. 아래 아키텍처 다이어그램의이 보여주듯, 평가의 '깊이'가 달라졌습니다.이러한 구조적 변화를 통해 SPeCTRA 2.0의 자동화된 품질 평가 워크플로우는 다음과 같이 더욱 견고하고 효율적으로 개선되었습니다.• None (Input) QA Google Sheets에 검증 시나리오를 작성합니다.• None (Process) 자동화 스크립트가 시나리오를 읽어 대화방 API를 이
java
9/2/2025

[에이닷 4.0 QE 여정3] LLM 품질 평가의 진화: SPeCTRA 2.0 톺아보기
진화한 에이닷 4.0의 개편에이닷 3.0은 MainAgent, MusicAgent, StockAgent, MediaAgent, MovieAgent의 5개의 Agnet가 각각의 대화방으로 구성으로 개별성을 가지고 있었지만에이닷은 4.0으로 개편이 진행되었고 에이닷 3.0의 여러 Agent 대화방을 하나로 통합하는 OneAgnet로 진화하였습니다.여러 Agent를 하나로 통합되었기 때문에 검증에 대한 방법도 달리 진행이 필요했고 SPeCTRA도 2.0으로 변화를 준비하게 되었습니다.시작하며: SPeCTRA 1.0의 성과와 새로운 과제• None 효과적인 LLM 품질 평가 : 도구, 기준, 그리고 적용기 톺아보기(SPeCTRA)작년에 소개해드린 SPeCTRA 1.0은 기존의 수동적이고 주관적일 수 있는 LLM 답변 품질 평가를 자동화된 'LLM-as-a-judge' 방식으로 전환한 혁신적인 시도였습니다.로컬 PC 환경에서 클라이언트 로그를 직접 파싱하고, Java 기반의 배포 툴을 통해 QA/TE는 물론 유관부서 모두가 LLM 품질 테스트를 수행할 수 있게 함으로써 테스트 리소스의 효율을 극대화했습니다.하지만 여기서 멈추지 않았습니다.에이닷 4.0이 OneAgent로 개편됨에 따라 대규모 테스트의 연속성을 확보하고, 여러 팀 간의 협업을 더욱 원활하게 하며, 물리적 디바이스 연결의 한계를 극복하기 위한 새로운 과제가 주어졌습니다.더 높은 확장성, 향상된 협업, 그리고 안정적인 테스트 환경을 위해 SPeCTRA는 2.0으로의 진화를 시작했습니다.SPeCTRA 2.0의 핵심 변화: 무엇이 달라졌는가?SPeCTRA 2.0은 1.0을 계승하되, 데이터 흐름을 API 중심으로 완전히 재편하고 Web에서 구동되도록 개편되었습니다. 주요 변화는 다음과 같습니다.1. API 기반 테스트로의 전환가장 큰 변화는 테스트 실행 방식입니다.SPeCTRA 1.0이 로컬 PC에 연결된 모바일 클라이언트를 Appium, Logcat으로 제어하는 방식이었다면, SPeCTRA 2.0은 대화방의 API를 직접 호출하는 방식으로 전환되었습니다.이는 더 이상 테스트를 위해 물리적인 디바이스나 클라이언트 앱 실행 환경이 필요 없다는 것을 의미합니다.덕분에 테스트 환경 구축이 단순해졌고, CI/CD 파이프라인과의 연동이 더욱 유연해졌으며, API 기반의 동시 다발적인 테스트 수행으로 속도와 확장성 면에서 비약적인 발전을 이루었습니다.로컬 PC의 Excel 파일로 관리되던 테스트 시나리오와 결과 데이터는 이제 Google Sheets로 통합되었습니다.Google Sheets를 도입함으로써 얻는 이점은 명확합니다.• None 실시간 협업: QE팀이 동일한 테스트 시트 위에서 실시간으로 시나리오를 추가/수정하고, 평가 결과를 즉시 확인할 수 있습니다.• None 버전 관리 및 이력 추적: TestCase 모든 변경 사항이 기록되어 데이터의 정합성을 유지하기 용이합니다.• None 유연한 연동: Google Cloud 환경의 다른 서비스나 스크립트와 쉽게 연동하여 데이터 처리의 실시간 동기화 가능해졌습니다.3. 신뢰성 있는 로그 데이터 활용SPeCTRA 1.0에서는 실시간 클라이언트 로그를 파싱하여 LLM의 응답을 추출했습니다.이는 간편하지만, 로그 포맷이 변경되거나 유실될 경우 테스트의 안정성이 떨어질 수 있는 단점이 있었습니다.SPeCTRA 2.0에서는 중앙 로그 관리 시스템인 내부 시스템 로그의 결과 데이터를 활용합니다.정제되고 구조화된 로그 데이터를 API를 통해 가져옴으로써, LLM의 요청(request)과 응답(response)을 누락 없이 정확하게 확보할 수 있게 되어 테스트의 신뢰도를 크게 높였습니다.더군다나 LLM답변 추출에 그치지 않고 새롭게 도입된 Rewrite, Routing의 데이터도 함께 추출하여 실시간 동기화성을 더욱 극대화 했습니다.새로운 에이닷 4.0에는 사용자 기억 지양점인 Memory가 도입됨에 따라 SPeCTRA도 진화가 필요했습니다.기존의 1.0의 Judge Prompt는 그대로 사용하되 Memory 기능확인을 위한 추가 Prompt를 도입함하여 차별화를 두었습니다.SPeCTRA 2.0의 심장부: 자동화된 평가 아키텍처이 영역의 핵심은 'QA Judge Model'입니다.이 모델은 단순히 사용자의 질문과 LLM의 최종 답변만 보고 정답을 맞혔는지 평가하는 것을 넘어, 답변이 생성되기까지의 '과정'을 검증합니다.즉, LLM 에이전트의 '생각'의 흐름을 추적하여 평가하는 것입니다.SPeCTRA 2.0은 다양한 내부 API와 연동하여 에이전트의 동작을 다각도로 분석합니다.• None Reactive API: Access_Token을 기반으로 한 API 호출을 통해, 사용자 정보나 페르소나에 따른 개인화된 응답(Reactive) 결과가 올바르게 생성되었는지 확인합니다.• None Memory API: 대화에 적재된 기억(Memory)을 LLM 에이전트가 올바르게 조회하고 활용했는지 검증합니다.• None Rewrite & Routing API : 중앙 로그 시스템인 내부 시스템 로그를 통해 대화의 맥락을 어떻게 재구성(Rewrite)했는지, 그리고 Agent가 어떤 기능 Routing을 호출하려고 계획했는지까지 추적하여 평가의 정확도를 높입니다.이렇게 각 API를 통해 수집된 '과정' 데이터는 기존 SPeCTRA 1.0의 Safety, Performance, Tone & Manner, Accuracy를 포함하여SPeCTRA의 다차원적인 평가 기준(Prompt)과 결합되어 최종 평가 점수를 도출합니다.새로워진 SPeCTRA 2.0의 워크플로우SPeCTRA 2.0의 단순히 Data 추출를 API로 이전한 것에 그치지 않습니다. 아래 아키텍처 다이어그램의이 보여주듯, 평가의 '깊이'가 달라졌습니다.이러한 구조적 변화를 통해 SPeCTRA 2.0의 자동화된 품질 평가 워크플로우는 다음과 같이 더욱 견고하고 효율적으로 개선되었습니다.• None (Input) QA Google Sheets에 검증 시나리오를 작성합니다.• None (Process) 자동화 스크립트가 시나리오를 읽어 대화방 API를 이
2025.09.02
java

좋아요

별로에요

3명의 개발팀이 만든 24시간 일하는 AI 동료
부사수도 없는 작은 팀에서 일해본 경험이 있나요? 그렇다면 이런 상황은 한번쯤 겪어보셨을 거예요. 팀원이 휴가를 가면 그 사람의 업무가 멈춰버리거나, 휴가중에도 업무를 해야하는… 결국 아무도 마음 편히 쉴 수 없는 상황 말이에요. 특히 시스템 관리나 데이터베이스 운영 같은 전문 업무는 더욱 그렇죠.오늘 소개할 사례는 바로 그런 현실적인 문제를 AI로 해결한 마이리얼트립 코어플랫폼팀의 이야기입니다. 코어플랫폼팀은 SRE, DBA, DevOps 등의 업무를 단 3명의 인원으로 처리하고 있기 때문에 그 누구보다도 AI 도입에 적극적이었어요. 처음에는 팀원을 보조하는 “AI 인턴”의 컨셉으로 시작해, 사내 개발자들이 직접 이용할 수 있는 AI 에이전트 시스템으로 발전시켰는데요, 오늘은 이 AI 에이전트 시스템을 개발한 천필수, 박성민님의 이야기를 소개하려고 합니다.소규모 팀의 큰 책임[108개 데이터베이스, 1명의 관리자]이 팀의 천필수님이 직면한 상황을 구체적으로 살펴보면 정말 현실적인 문제였어요.“현재 클러스터 기준으로만 해도 50여 대가 넘고, 인스턴스 기준으로 하면 총 108개 정도 되는 데이터베이스를 운영하는 DBA(Database Administrator)는 현재 저 한 명인 상황이에요.”이 숫자들을 보면 상황의 심각성이 느껴지죠. 한 사람이 108개의 데이터베이스를 관리한다는 것은 단순히 업무량이 많다는 차원을 넘어서, 시스템 전체의 안정성이 한 사람에게 의존하고 있다는 뜻이에요.[단일점 장애의 위험성]“DBA가 퇴근을 했거나 휴가를 가면, 그 108대에 대한 모든 DBA 요청이 블로킹되고 지연된다는 문제의식을 평상시에 갖고 있었습니다.”이런 상황을 IT 업계에서는 ‘단일점 장애(Single Point of Failure)’라고 부르는데, 마치 중요한 다리에 기둥이 하나밖에 없는 것과 같아요. 그 기둥에 문제가 생기면 전체 교통이 마비되는 것처럼, 한 명의 전문가에게만 의존하는 시스템은 매우 취약할 수밖에 없죠.호기심에서 시작된 AI 실험[계획된 혁신이 아닌 자연스러운 시작]흥미로운 점은 이 팀의 AI 도입이 거창한 디지털 트랜스포메이션 계획에서 시작된 게 아니라는 거예요.“처음부터 AI를 통해서 이런 문제를 해결하겠다는 건 아니었고요. 회사 내에서 AI를 활용해서 업무를 개선하는 많은 케이스들이 나오다 보니, 저도 단순히 우선 공부부터 해보겠다는 차원에서 시작했어요.”이런 접근 방식이 오히려 성공의 열쇠였을지도 몰라요. 부담 없는 실험으로 시작했기 때문에 실패에 대한 두려움 없이 다양한 시도를 할 수 있었거든요.[작은 실험에서 큰 발견]“처음에는 간단한 DB를 조회하는 MCP 도구를 구현해서 클로드 데스크톱에 붙여봤고, 테스트를 해보니 생각보다 범용 LLM 모델들이 데이터베이스를 굉장히 잘 알고 있다는 것을 확인할 수 있었습니다.”이 순간이 중요한 전환점이었어요. AI가 단순히 챗봇 수준이 아니라, 실제로 전문적인 데이터베이스 업무를 수행할 수 있다는 가능성을 발견한 거죠. 팀에서는 새로운 인턴 사원이 내 옆에서 업무를 보조해주는
9/2/2025

3명의 개발팀이 만든 24시간 일하는 AI 동료
부사수도 없는 작은 팀에서 일해본 경험이 있나요? 그렇다면 이런 상황은 한번쯤 겪어보셨을 거예요. 팀원이 휴가를 가면 그 사람의 업무가 멈춰버리거나, 휴가중에도 업무를 해야하는… 결국 아무도 마음 편히 쉴 수 없는 상황 말이에요. 특히 시스템 관리나 데이터베이스 운영 같은 전문 업무는 더욱 그렇죠.오늘 소개할 사례는 바로 그런 현실적인 문제를 AI로 해결한 마이리얼트립 코어플랫폼팀의 이야기입니다. 코어플랫폼팀은 SRE, DBA, DevOps 등의 업무를 단 3명의 인원으로 처리하고 있기 때문에 그 누구보다도 AI 도입에 적극적이었어요. 처음에는 팀원을 보조하는 “AI 인턴”의 컨셉으로 시작해, 사내 개발자들이 직접 이용할 수 있는 AI 에이전트 시스템으로 발전시켰는데요, 오늘은 이 AI 에이전트 시스템을 개발한 천필수, 박성민님의 이야기를 소개하려고 합니다.소규모 팀의 큰 책임[108개 데이터베이스, 1명의 관리자]이 팀의 천필수님이 직면한 상황을 구체적으로 살펴보면 정말 현실적인 문제였어요.“현재 클러스터 기준으로만 해도 50여 대가 넘고, 인스턴스 기준으로 하면 총 108개 정도 되는 데이터베이스를 운영하는 DBA(Database Administrator)는 현재 저 한 명인 상황이에요.”이 숫자들을 보면 상황의 심각성이 느껴지죠. 한 사람이 108개의 데이터베이스를 관리한다는 것은 단순히 업무량이 많다는 차원을 넘어서, 시스템 전체의 안정성이 한 사람에게 의존하고 있다는 뜻이에요.[단일점 장애의 위험성]“DBA가 퇴근을 했거나 휴가를 가면, 그 108대에 대한 모든 DBA 요청이 블로킹되고 지연된다는 문제의식을 평상시에 갖고 있었습니다.”이런 상황을 IT 업계에서는 ‘단일점 장애(Single Point of Failure)’라고 부르는데, 마치 중요한 다리에 기둥이 하나밖에 없는 것과 같아요. 그 기둥에 문제가 생기면 전체 교통이 마비되는 것처럼, 한 명의 전문가에게만 의존하는 시스템은 매우 취약할 수밖에 없죠.호기심에서 시작된 AI 실험[계획된 혁신이 아닌 자연스러운 시작]흥미로운 점은 이 팀의 AI 도입이 거창한 디지털 트랜스포메이션 계획에서 시작된 게 아니라는 거예요.“처음부터 AI를 통해서 이런 문제를 해결하겠다는 건 아니었고요. 회사 내에서 AI를 활용해서 업무를 개선하는 많은 케이스들이 나오다 보니, 저도 단순히 우선 공부부터 해보겠다는 차원에서 시작했어요.”이런 접근 방식이 오히려 성공의 열쇠였을지도 몰라요. 부담 없는 실험으로 시작했기 때문에 실패에 대한 두려움 없이 다양한 시도를 할 수 있었거든요.[작은 실험에서 큰 발견]“처음에는 간단한 DB를 조회하는 MCP 도구를 구현해서 클로드 데스크톱에 붙여봤고, 테스트를 해보니 생각보다 범용 LLM 모델들이 데이터베이스를 굉장히 잘 알고 있다는 것을 확인할 수 있었습니다.”이 순간이 중요한 전환점이었어요. AI가 단순히 챗봇 수준이 아니라, 실제로 전문적인 데이터베이스 업무를 수행할 수 있다는 가능성을 발견한 거죠. 팀에서는 새로운 인턴 사원이 내 옆에서 업무를 보조해주는
2025.09.02

좋아요

별로에요

1,000만 명이 들어와도 999만 명이 나가는 문제, 어떻게 해결했을까 | 언더커버 사일로 비하인드 5화: 계좌 사일로
챌린저스 여러분, 언더커버 사일로의 마지막 여정, ‘계좌 사일로’ 편에 오신 것을 환영합니다.이전의 네 가지 사일로가 모든 서비스가 겪는 보편적인 성장통에 대한 이야기였다면, 이번 편은 ‘토스는 금융 앱이다’라는 본질적인 질문에서 출발합니다. 수많은 규제와 제약 속에서, 토스마저 아직 정답을 찾지 못한 문제를 함께 풀어보는 시간이 될 텐데요. 토스의 가장 근본적인 고민이 담긴 마지막 과제, 그 비하인드 스토리를 지금부터 시작합니다.가장 토스다운 문제, 가장 어려웠던 출제언더커버사일로의 마지막 화는 ‘계좌 사일로’였습니다. 기획 단계부터 토스는 금융 앱이니까, 금융의 본질을 다루는 사일로 하나는 꼭 넣어야겠다고 생각했어요.그런데 문제가 있었습니다. 금융 기능은 관련된 사전 지식이 너무 많이 필요했어요. 첫 화였던 인플로우 사일로는 ‘신규 유저 확보’라는 보편적인 과제였고, 만보기는 ‘비용과 지속가능성’, 페이스페이는 ‘UX와 사용성’, 고양이는 ‘리텐션’에 집중했죠. 이 네 가지를 합치면 사실상 프로덕트의 전 과정을 훑는, 모든 메이커가 공감할 만한 문제들이었습니다.하지만 송금, 카드, 결제 같은 금융 도메인으로 들어가려고만 하면, 수많은 규제와 절차의 벽에 부딪혀 문제 출제가 번번이 막혔습니다. 챌린저들이 문제 하나를 제대로 풀기 위해, 몇 시간씩 사전 지식을 공부해야만 하는 상황을 만들고 싶지는 않았어요. 토스가 이미 찾은 정답을 그들에게 기대하는 것 자체가 불공평했죠. 그건 저희가 가진 모든 배경지식을 그들도 똑같이 가지고 있어야 한다는 뜻이니까요.‘토스도 정답을 모르는 문제’를 내기로 하다그래서 저희는 생각을 완전히 뒤집기로 했습니다. 만약 토스도 아직 답을 찾지 못한 문제를 내면 어떨까?그러면 챌린저들이 저희의 선택과 일치하는 정답을 내야 할 필요가 없어져요. 문제를 풀기 위한 최소한의 사전 지식만 드리고, 토스의 방식을 모르는 외부 메이커들의 날카로운 시선으로 최고의 해결책을 찾아보게 하는 거죠.이런 고민 끝에, 계좌 사일로가 가진 수많은 성공 경험을 과감히 제쳐두었습니다. 대신 규제 속에서도 신규 계좌 개설 인플로우와 전환율을 동시에 잡을 수 있는 전략을 짜는 것, 바로 이 오픈 퀘스천이 언더커버사일로의 마지막 과제가 되었습니다.마지막 과제: 당신도 챌린저입니다이제 여러분도 언더커버 사일로에 참여한 챌린저와 동등한 상황에서 문제를 풀어보실 수 있도록, 지금부터 저희가 마주한 두 가지 현실적인 제약을 먼저 공유해 드리겠습니다.첫째, 계좌 사업의 본질상 리텐션은 의미가 없습니다. 여러분도 아시다시피, 단기간에 여러 개의 계좌를 만드는 것은 제한되어 있죠. 사실상 한 명의 사용자는 평생 단 하나의 계좌만 만든다고 가정해야 합니다. 그렇기 때문에 이탈한 사용자를 다시 불러오는 리텐션 지표보다는, 일단 들어온 사용자가 실제로 계좌를 개설했는지를 보여주는 전환율이 가장 중요한 지표가 됩니다.둘째, 그런데 그 전환율이 너무나도 낮습니다. 토스는 이미 대한민국 국민의 절반이 쓰고 있고, 앱의 가장 좋은 자리인 홈 화면과 계좌 탭에 ‘계좌 만
9/2/2025

1,000만 명이 들어와도 999만 명이 나가는 문제, 어떻게 해결했을까 | 언더커버 사일로 비하인드 5화: 계좌 사일로
챌린저스 여러분, 언더커버 사일로의 마지막 여정, ‘계좌 사일로’ 편에 오신 것을 환영합니다.이전의 네 가지 사일로가 모든 서비스가 겪는 보편적인 성장통에 대한 이야기였다면, 이번 편은 ‘토스는 금융 앱이다’라는 본질적인 질문에서 출발합니다. 수많은 규제와 제약 속에서, 토스마저 아직 정답을 찾지 못한 문제를 함께 풀어보는 시간이 될 텐데요. 토스의 가장 근본적인 고민이 담긴 마지막 과제, 그 비하인드 스토리를 지금부터 시작합니다.가장 토스다운 문제, 가장 어려웠던 출제언더커버사일로의 마지막 화는 ‘계좌 사일로’였습니다. 기획 단계부터 토스는 금융 앱이니까, 금융의 본질을 다루는 사일로 하나는 꼭 넣어야겠다고 생각했어요.그런데 문제가 있었습니다. 금융 기능은 관련된 사전 지식이 너무 많이 필요했어요. 첫 화였던 인플로우 사일로는 ‘신규 유저 확보’라는 보편적인 과제였고, 만보기는 ‘비용과 지속가능성’, 페이스페이는 ‘UX와 사용성’, 고양이는 ‘리텐션’에 집중했죠. 이 네 가지를 합치면 사실상 프로덕트의 전 과정을 훑는, 모든 메이커가 공감할 만한 문제들이었습니다.하지만 송금, 카드, 결제 같은 금융 도메인으로 들어가려고만 하면, 수많은 규제와 절차의 벽에 부딪혀 문제 출제가 번번이 막혔습니다. 챌린저들이 문제 하나를 제대로 풀기 위해, 몇 시간씩 사전 지식을 공부해야만 하는 상황을 만들고 싶지는 않았어요. 토스가 이미 찾은 정답을 그들에게 기대하는 것 자체가 불공평했죠. 그건 저희가 가진 모든 배경지식을 그들도 똑같이 가지고 있어야 한다는 뜻이니까요.‘토스도 정답을 모르는 문제’를 내기로 하다그래서 저희는 생각을 완전히 뒤집기로 했습니다. 만약 토스도 아직 답을 찾지 못한 문제를 내면 어떨까?그러면 챌린저들이 저희의 선택과 일치하는 정답을 내야 할 필요가 없어져요. 문제를 풀기 위한 최소한의 사전 지식만 드리고, 토스의 방식을 모르는 외부 메이커들의 날카로운 시선으로 최고의 해결책을 찾아보게 하는 거죠.이런 고민 끝에, 계좌 사일로가 가진 수많은 성공 경험을 과감히 제쳐두었습니다. 대신 규제 속에서도 신규 계좌 개설 인플로우와 전환율을 동시에 잡을 수 있는 전략을 짜는 것, 바로 이 오픈 퀘스천이 언더커버사일로의 마지막 과제가 되었습니다.마지막 과제: 당신도 챌린저입니다이제 여러분도 언더커버 사일로에 참여한 챌린저와 동등한 상황에서 문제를 풀어보실 수 있도록, 지금부터 저희가 마주한 두 가지 현실적인 제약을 먼저 공유해 드리겠습니다.첫째, 계좌 사업의 본질상 리텐션은 의미가 없습니다. 여러분도 아시다시피, 단기간에 여러 개의 계좌를 만드는 것은 제한되어 있죠. 사실상 한 명의 사용자는 평생 단 하나의 계좌만 만든다고 가정해야 합니다. 그렇기 때문에 이탈한 사용자를 다시 불러오는 리텐션 지표보다는, 일단 들어온 사용자가 실제로 계좌를 개설했는지를 보여주는 전환율이 가장 중요한 지표가 됩니다.둘째, 그런데 그 전환율이 너무나도 낮습니다. 토스는 이미 대한민국 국민의 절반이 쓰고 있고, 앱의 가장 좋은 자리인 홈 화면과 계좌 탭에 ‘계좌 만
2025.09.02

좋아요

별로에요

MySQL Ver. 8.0 New Feature: Instant DDL Algorithm에 대한 이해
MySQL은 2000년대부터 웹서비스를 많이 사용하는 개발자들에 의해 많이 사용되었습니다. 오픈 소스로서 사용이 쉬웠을 뿐 아니라 개발자들이 다루기 쉽고 이해하기 쉬운 관계형 데이터베이스이기 때문입니다. 하지만, MySQL은 서비스가 잘되고 사용자가 늘어날수록 운영하기 쉽지 않았습니다. 서비스가 운영 중인 상황에서 Online DDL을 수행하기 어려웠기 때문입니다.하지만, MySQL Ver. 8.0 부터 ALTER DDL에 대한 사용성이 높아지게 되었습니다. DDL 수행 시간을 획기적으로 줄여주는 Instant 알고리즘 기반 DDL 처리 기능이 추가되었기 때문입니다. 이는 MySQL 엔지니어로 기대하던 기능입니다. 그래서, 해당 기능을 MySQL Ver. 8.0.19부터 사용해왔습니다.해당 기능을 도입 초기 부터 사용하면서 여러 문제들을 겪었고, 이후에 어떻게 로직을 변경해서 조치되었는지 엔지니어로서 궁금했습니다. Instant 알고리즘이 어떤 로직으로 구현되었기에 이와 같은 문제점들이 나타났는지, 현재는 어떻게 변경되어 문제를 해결하였는지 분석하는 것이 필요하다고 생각했고, 그래서 해당 내용을 분석하여 정리했습니다.MySQL은 초기에 DDL을 수행할 때, Copy 방식의 알고리즘으로 DDL을 수행했습니다.Copy 방식의 알고리즘은 가장 처음에 MySQL에서 소개된 알고리즘으로, DDL 수행 전반에 걸쳐 Read Lock을 확보한 상태에서, 변경된 구조의 임시 테이블(Table)을 만들고 데이터를 이동하는 방식입니다. 작업 수행 전반에 걸쳐 Read Lock을 먼저 확보해야 하므로 24시간 트래픽을 받아야 하는 서비스를 지원하는 MySQL에서는 서비스를 중지해야 하는 상황을 유발했습니다.이 문제를 해결하고자, MySQL은 In-Place 알고리즘을 개발해 장시간에 걸친 Lock 획득 상황을 제거했습니다. 하지만, 변경하려는 구조로 새 테이블을 만들고 데이터를 복사하여 처리하는 방식 자체는 변경된 것이 없었습니다. 그래서, 테이블의 데이터 사이즈가 커지면 커질수록 ALTER 수행 시 더 많은 공간을 확보해야 하고, 더 오랜 시간이 소요된다는 문제를 계속 가지고 있었습니다.이와 같은 MySQL이 가진 문제점을 해결하기 위해 새로운 Instant 알고리즘이 MySQL Ver. 8.0에 도입됐습니다.MySQL이 DDL 수행 시 사용하던 Copy/In-Place 알고리즘 방식의 문제점을 해결하고자 MySQL Ver. 8.0.12부터 Instant 알고리즘이 추가되어 컬럼(Column) 추가가 빠르게 수행될 수 있도록 기능 개선이 이루어졌습니다. 이 기능을 통해 물리적 구조를 변경하지 않고 오직 테이블의 메타 정보만 수정함으로써 테이블 크기에 관계없이 새로운 컬럼을 즉각 추가할 수 있게 되었습니다.다음은 MySQL Ver. 8.0.12에서 Instant 알고리즘을 사용해 컬럼을 추가한 결과입니다. 테이블 사이즈가 1.6GB임에도 0.01초 만에 컬럼이 추가된 것을 확인할 수 있습니다.하지만, 초기의 Instant 알고리즘은 다음과 같은 한계를 가지고 있었습니다.• 새로운 컬럼을 테이블의 마지막 컬럼으로만 추가할 수 있다.• DROP COLUMN은 지원되지 않는다.Instant 초기 버전에서 보여준 한계를 벗어나기 위해 MySQL Ver. 8.0.29부터 내부 설계가 변경되었고, 이를 통해 위치에 상관없이 컬럼을 추가/삭제할 수 있게 되었습니다.물론 Instant v2에서도 데이터영역의 물리적인 변경 없이 메타데이터(Metadata)만 수정하여 DDL을 수행합니다. 따라서, ADD 및 DROP COLUMN 작업에 소요되는 시간이 테이블 크기와 상관없이 거의 동일합니다.MySQL 8.0.29 에서 개선된 Instant Algorithm 의 기능사용하는 구문은 다음과 같습니다.이런 기능 개선을 위해 어떤 과정을 거쳤는지 좀 더 자세히 알아보도록 하겠습니다.MySQL Ver. 8.0.29부터 ROW_VERSION이라는 개념이 등장했습니다. ROW_VERSION은 테이블마다 독립적으로 기록되는 값으로, Instant 알고리즘을 통해 ALTER문이 수행된 횟수를 뜻합니다. 이 값은 테이블의 메타데이터를 저장하는 영역과 Row의 메타데이터를 저장하는 영역에 각각 저장됩니다.ROW_VERSION이 기록되는 방식을 좀 더 자세히 정리해 보면 다음과 같습니다.MySQL Ver. 8.0.29에서 ROW_VERSION은 64까지만 증가할 수 있다는 한계가 있습니다. 그래서 해당 제한값에 도달할 때까지만 Instant 알고리즘으로 DDL 수행이 가능하며, 그 이후부터는 다음과 같은 오류가 발생합니다.또한 ROW_VERSION이 64까지 증가된 후에 algorithm=instant를 명시하지 않고 DDL을 수행하면 In-place 알고리즘으로 동작합니다. 이 경우 의도치 않은 동작이 될 수 있기 때문에 주의가 필요합니다.테이블의 현재 ROW_VERSION 값은 INFORMATION_SCHEMA.INNODB_TABLES에서 확인 가능합니다. INNODB_TABLES 테이블에 TOTAL_ROW_VERSIONS라는 컬럼이 해당 테이블의 ROW_VERSION 값을 보여줍니다.테이블의 ROW_VERSION값이 64에 도달했더라도 더 이상 Instant 알고리즘을 사용하지 못하는 것은 아닙니다. ROW_VERSION값을 초기화하면 다시 Instant 알고리즘을 사용할 수 있습니다. ROW_VERSION 값을 초기화하기 위해서는 테이블 재구축을 진행하면 됩니다. 이때 사용할 수 있는 구문들은 다음과 같습니다.참고로 TRUNCATE TABLE 구문도 ROW_VERSION값을 초기화할 수 있습니다. 하지만, TRUNCATE TABLE 구문은 데이터를 모두 제거하는 구문이기 때문에 의미가 있을 것 같지는 않습니다.위의 설명과 같이 Instant v2 알고리즘은 Instant v1 알고리즘의 문제점을 해결했지만, 그래도 다음과 같은 한계점이 존재합니다.• FTS(Full-Text-Search) Index 존재 시 테이블에 사용이 불가능하다.• ROW_FORMAT=COMPRESSED 인 테이블에서는 사용이 불가능하다.• 임시
mysql
9/2/2025

MySQL Ver. 8.0 New Feature: Instant DDL Algorithm에 대한 이해
MySQL은 2000년대부터 웹서비스를 많이 사용하는 개발자들에 의해 많이 사용되었습니다. 오픈 소스로서 사용이 쉬웠을 뿐 아니라 개발자들이 다루기 쉽고 이해하기 쉬운 관계형 데이터베이스이기 때문입니다. 하지만, MySQL은 서비스가 잘되고 사용자가 늘어날수록 운영하기 쉽지 않았습니다. 서비스가 운영 중인 상황에서 Online DDL을 수행하기 어려웠기 때문입니다.하지만, MySQL Ver. 8.0 부터 ALTER DDL에 대한 사용성이 높아지게 되었습니다. DDL 수행 시간을 획기적으로 줄여주는 Instant 알고리즘 기반 DDL 처리 기능이 추가되었기 때문입니다. 이는 MySQL 엔지니어로 기대하던 기능입니다. 그래서, 해당 기능을 MySQL Ver. 8.0.19부터 사용해왔습니다.해당 기능을 도입 초기 부터 사용하면서 여러 문제들을 겪었고, 이후에 어떻게 로직을 변경해서 조치되었는지 엔지니어로서 궁금했습니다. Instant 알고리즘이 어떤 로직으로 구현되었기에 이와 같은 문제점들이 나타났는지, 현재는 어떻게 변경되어 문제를 해결하였는지 분석하는 것이 필요하다고 생각했고, 그래서 해당 내용을 분석하여 정리했습니다.MySQL은 초기에 DDL을 수행할 때, Copy 방식의 알고리즘으로 DDL을 수행했습니다.Copy 방식의 알고리즘은 가장 처음에 MySQL에서 소개된 알고리즘으로, DDL 수행 전반에 걸쳐 Read Lock을 확보한 상태에서, 변경된 구조의 임시 테이블(Table)을 만들고 데이터를 이동하는 방식입니다. 작업 수행 전반에 걸쳐 Read Lock을 먼저 확보해야 하므로 24시간 트래픽을 받아야 하는 서비스를 지원하는 MySQL에서는 서비스를 중지해야 하는 상황을 유발했습니다.이 문제를 해결하고자, MySQL은 In-Place 알고리즘을 개발해 장시간에 걸친 Lock 획득 상황을 제거했습니다. 하지만, 변경하려는 구조로 새 테이블을 만들고 데이터를 복사하여 처리하는 방식 자체는 변경된 것이 없었습니다. 그래서, 테이블의 데이터 사이즈가 커지면 커질수록 ALTER 수행 시 더 많은 공간을 확보해야 하고, 더 오랜 시간이 소요된다는 문제를 계속 가지고 있었습니다.이와 같은 MySQL이 가진 문제점을 해결하기 위해 새로운 Instant 알고리즘이 MySQL Ver. 8.0에 도입됐습니다.MySQL이 DDL 수행 시 사용하던 Copy/In-Place 알고리즘 방식의 문제점을 해결하고자 MySQL Ver. 8.0.12부터 Instant 알고리즘이 추가되어 컬럼(Column) 추가가 빠르게 수행될 수 있도록 기능 개선이 이루어졌습니다. 이 기능을 통해 물리적 구조를 변경하지 않고 오직 테이블의 메타 정보만 수정함으로써 테이블 크기에 관계없이 새로운 컬럼을 즉각 추가할 수 있게 되었습니다.다음은 MySQL Ver. 8.0.12에서 Instant 알고리즘을 사용해 컬럼을 추가한 결과입니다. 테이블 사이즈가 1.6GB임에도 0.01초 만에 컬럼이 추가된 것을 확인할 수 있습니다.하지만, 초기의 Instant 알고리즘은 다음과 같은 한계를 가지고 있었습니다.• 새로운 컬럼을 테이블의 마지막 컬럼으로만 추가할 수 있다.• DROP COLUMN은 지원되지 않는다.Instant 초기 버전에서 보여준 한계를 벗어나기 위해 MySQL Ver. 8.0.29부터 내부 설계가 변경되었고, 이를 통해 위치에 상관없이 컬럼을 추가/삭제할 수 있게 되었습니다.물론 Instant v2에서도 데이터영역의 물리적인 변경 없이 메타데이터(Metadata)만 수정하여 DDL을 수행합니다. 따라서, ADD 및 DROP COLUMN 작업에 소요되는 시간이 테이블 크기와 상관없이 거의 동일합니다.MySQL 8.0.29 에서 개선된 Instant Algorithm 의 기능사용하는 구문은 다음과 같습니다.이런 기능 개선을 위해 어떤 과정을 거쳤는지 좀 더 자세히 알아보도록 하겠습니다.MySQL Ver. 8.0.29부터 ROW_VERSION이라는 개념이 등장했습니다. ROW_VERSION은 테이블마다 독립적으로 기록되는 값으로, Instant 알고리즘을 통해 ALTER문이 수행된 횟수를 뜻합니다. 이 값은 테이블의 메타데이터를 저장하는 영역과 Row의 메타데이터를 저장하는 영역에 각각 저장됩니다.ROW_VERSION이 기록되는 방식을 좀 더 자세히 정리해 보면 다음과 같습니다.MySQL Ver. 8.0.29에서 ROW_VERSION은 64까지만 증가할 수 있다는 한계가 있습니다. 그래서 해당 제한값에 도달할 때까지만 Instant 알고리즘으로 DDL 수행이 가능하며, 그 이후부터는 다음과 같은 오류가 발생합니다.또한 ROW_VERSION이 64까지 증가된 후에 algorithm=instant를 명시하지 않고 DDL을 수행하면 In-place 알고리즘으로 동작합니다. 이 경우 의도치 않은 동작이 될 수 있기 때문에 주의가 필요합니다.테이블의 현재 ROW_VERSION 값은 INFORMATION_SCHEMA.INNODB_TABLES에서 확인 가능합니다. INNODB_TABLES 테이블에 TOTAL_ROW_VERSIONS라는 컬럼이 해당 테이블의 ROW_VERSION 값을 보여줍니다.테이블의 ROW_VERSION값이 64에 도달했더라도 더 이상 Instant 알고리즘을 사용하지 못하는 것은 아닙니다. ROW_VERSION값을 초기화하면 다시 Instant 알고리즘을 사용할 수 있습니다. ROW_VERSION 값을 초기화하기 위해서는 테이블 재구축을 진행하면 됩니다. 이때 사용할 수 있는 구문들은 다음과 같습니다.참고로 TRUNCATE TABLE 구문도 ROW_VERSION값을 초기화할 수 있습니다. 하지만, TRUNCATE TABLE 구문은 데이터를 모두 제거하는 구문이기 때문에 의미가 있을 것 같지는 않습니다.위의 설명과 같이 Instant v2 알고리즘은 Instant v1 알고리즘의 문제점을 해결했지만, 그래도 다음과 같은 한계점이 존재합니다.• FTS(Full-Text-Search) Index 존재 시 테이블에 사용이 불가능하다.• ROW_FORMAT=COMPRESSED 인 테이블에서는 사용이 불가능하다.• 임시
2025.09.02
mysql

좋아요

별로에요

특정 YouTube 영상의 댓글에 대한 자연어 분석 RAG 시스템 개발 with LangGraph + Qdrant
대학생 시절, 마음 맞는 친구들과 유튜브 채널을 운영한 적이 있습니다.당연히 거의 모든 영상이 별로 인기가 없었지만, 학과를 소개하는 영상 두개 정도가 꽤나 시청자 반응이 좋아 댓글이 많이 달렸습니다.시청자들이 우리의 영상에 대해 어떠한 반응을 하는지 궁금해 댓글을 여러번 읽었지만, 몇번 해보니 배부른 소리지만 꽤나 귀찮게 느껴졌습니다.제 천성이 게을러서 그런지 자연스레 더 편한 방법은 없을까 고민하게 되었습니다.시간이 흘러 AI 기술이 발전함에 따라 드디어 과거의 제 귀찮음을 기술적으로 해결할 수 있게 되었습니다.문제 정의: YouTube 댓글의 정보 과부하YouTube의 기본 댓글 시스템은 몇 가지 문제점을 가지고 있습니다:• None 정렬 옵션의 한계: '인기순'과 '최신순' 두 가지 정렬만 제공• None 검색 기능 부재: 특정 키워드나 주제로 댓글을 검색할 수 없음• None 전체 맥락 파악 어려움: 수천 개의 댓글을 일일이 읽어야 전체 반응을 알 수 있음• None 감정 분석 불가: 긍정/부정 반응의 비율이나 주요 감정을 파악하기 어려움이렇게 자연어로 질문하고 답을 받을 수 있다면 얼마나 편할까요?RAG는 검색(Retrieval)과 생성(Generation)을 결합한 방식입니다. 이 프로젝트에서 RAG를 선택한 이유:• None 정확성: 실제 댓글 데이터를 기반으로 답변• None 맥락 이해: 의미적으로 유사한 댓글들을 찾아 종합• None 유연성: 다양한 형태의 질문에 대응 가능• None 특징: 로 가장 관련성 높은 댓글 우선 수집• None 특징: 상태 기반 그래프로 복잡한 로직을 명확하게 표현YouTube API를 통해 관련성 높은 댓글 500개를 수집합니다:• None 로 YouTube 알고리즘이 선정한 중요 댓글 우선 수집• None 메타데이터(좋아요 수, 작성자 등) 함께 저장수집한 댓글을 OpenAI의 text-embedding-3-small 모델로 임베딩하여 Qdrant에 저장:사용자 질문 타입에 따라 다른 검색 전략을 적용합니다:전체 프로세스를 LangGraph로 orchestration:• None 댓글이 이미 수집되어 있으면 바로 검색으로 진행• None 각 노드가 독립적으로 동작하여 유지보수 용이• None 상태 관리로 전체 프로세스 추적 가능질문: "이 영상의 전반적인 반응이 어때?"기술로서 과거의 불편함을 일부 해결대학생 시절의 귀찮음이 몇 년 뒤 기술로 해결되는 경험은 꽤나 만족스러웠습니다.하루 만에 MVP를 만들어내고, 실제로 YouTube 영상의 댓글을 분석하며 "이 영상의 전반적인 반응이 어때?"라는 질문에 즉각적인 답변을 받을 수 있다는 것이 신기했습니다.특히 RAG 시스템을 통해 단순히 키워드 매칭이 아닌, 의미적으로 유사한 댓글들을 찾아 종합적인 인사이트를 제공할 수 있다는 점이 인상적이었습니다.하지만 MVP답게 여러 한계점도 명확합니다:• None 키워드 기반 쿼리 타입 분류: 현재 구현은 미리 정의한 키워드( , )로만 쿼리 타입을 판단합니다. 예를 들어 "전체"라는 단어가 없으면 포괄적 분석으로 인식하지 못합니다. LLM을 활용한 의미 기반 분류로 개선이 필요합니다.• None 고정된 검색 전략: 각 쿼리 타입별로 검색 개수(k=15, 20, 30)가 하드코딩되어 있어, 댓글 수나 질문 복잡도에 따른 동적 조정이 불가능합니다.• None 재수집의 비효율성: 새로운 댓글을 반영하려면 전체를 다시 수집해야 하는 구조입니다. 증분 업데이트 방식이 필요합니다.• None 언어 혼재 처리: 영어와 한국어가 섞인 댓글들을 처리할 때, 임베딩 품질이 일관되지 않을 수 있습니다.이 외에도 수많은 문제점들이 존재하는데, 앞으로의 스터디 기간을 통해 차차 개선해나가보도록 하겠습니다.
9/1/2025

특정 YouTube 영상의 댓글에 대한 자연어 분석 RAG 시스템 개발 with LangGraph + Qdrant
대학생 시절, 마음 맞는 친구들과 유튜브 채널을 운영한 적이 있습니다.당연히 거의 모든 영상이 별로 인기가 없었지만, 학과를 소개하는 영상 두개 정도가 꽤나 시청자 반응이 좋아 댓글이 많이 달렸습니다.시청자들이 우리의 영상에 대해 어떠한 반응을 하는지 궁금해 댓글을 여러번 읽었지만, 몇번 해보니 배부른 소리지만 꽤나 귀찮게 느껴졌습니다.제 천성이 게을러서 그런지 자연스레 더 편한 방법은 없을까 고민하게 되었습니다.시간이 흘러 AI 기술이 발전함에 따라 드디어 과거의 제 귀찮음을 기술적으로 해결할 수 있게 되었습니다.문제 정의: YouTube 댓글의 정보 과부하YouTube의 기본 댓글 시스템은 몇 가지 문제점을 가지고 있습니다:• None 정렬 옵션의 한계: '인기순'과 '최신순' 두 가지 정렬만 제공• None 검색 기능 부재: 특정 키워드나 주제로 댓글을 검색할 수 없음• None 전체 맥락 파악 어려움: 수천 개의 댓글을 일일이 읽어야 전체 반응을 알 수 있음• None 감정 분석 불가: 긍정/부정 반응의 비율이나 주요 감정을 파악하기 어려움이렇게 자연어로 질문하고 답을 받을 수 있다면 얼마나 편할까요?RAG는 검색(Retrieval)과 생성(Generation)을 결합한 방식입니다. 이 프로젝트에서 RAG를 선택한 이유:• None 정확성: 실제 댓글 데이터를 기반으로 답변• None 맥락 이해: 의미적으로 유사한 댓글들을 찾아 종합• None 유연성: 다양한 형태의 질문에 대응 가능• None 특징: 로 가장 관련성 높은 댓글 우선 수집• None 특징: 상태 기반 그래프로 복잡한 로직을 명확하게 표현YouTube API를 통해 관련성 높은 댓글 500개를 수집합니다:• None 로 YouTube 알고리즘이 선정한 중요 댓글 우선 수집• None 메타데이터(좋아요 수, 작성자 등) 함께 저장수집한 댓글을 OpenAI의 text-embedding-3-small 모델로 임베딩하여 Qdrant에 저장:사용자 질문 타입에 따라 다른 검색 전략을 적용합니다:전체 프로세스를 LangGraph로 orchestration:• None 댓글이 이미 수집되어 있으면 바로 검색으로 진행• None 각 노드가 독립적으로 동작하여 유지보수 용이• None 상태 관리로 전체 프로세스 추적 가능질문: "이 영상의 전반적인 반응이 어때?"기술로서 과거의 불편함을 일부 해결대학생 시절의 귀찮음이 몇 년 뒤 기술로 해결되는 경험은 꽤나 만족스러웠습니다.하루 만에 MVP를 만들어내고, 실제로 YouTube 영상의 댓글을 분석하며 "이 영상의 전반적인 반응이 어때?"라는 질문에 즉각적인 답변을 받을 수 있다는 것이 신기했습니다.특히 RAG 시스템을 통해 단순히 키워드 매칭이 아닌, 의미적으로 유사한 댓글들을 찾아 종합적인 인사이트를 제공할 수 있다는 점이 인상적이었습니다.하지만 MVP답게 여러 한계점도 명확합니다:• None 키워드 기반 쿼리 타입 분류: 현재 구현은 미리 정의한 키워드( , )로만 쿼리 타입을 판단합니다. 예를 들어 "전체"라는 단어가 없으면 포괄적 분석으로 인식하지 못합니다. LLM을 활용한 의미 기반 분류로 개선이 필요합니다.• None 고정된 검색 전략: 각 쿼리 타입별로 검색 개수(k=15, 20, 30)가 하드코딩되어 있어, 댓글 수나 질문 복잡도에 따른 동적 조정이 불가능합니다.• None 재수집의 비효율성: 새로운 댓글을 반영하려면 전체를 다시 수집해야 하는 구조입니다. 증분 업데이트 방식이 필요합니다.• None 언어 혼재 처리: 영어와 한국어가 섞인 댓글들을 처리할 때, 임베딩 품질이 일관되지 않을 수 있습니다.이 외에도 수많은 문제점들이 존재하는데, 앞으로의 스터디 기간을 통해 차차 개선해나가보도록 하겠습니다.
2025.09.01

좋아요

별로에요

WebFlux & Project Reactor 기반, 고성능 실시간 웹한글 문서 편집 시스템 전환기
웹한글 편집 서비스는 실시간 협업 환경에서 빈번한 I/O 작업이 발생하며, 수천 건의 편집 이벤트와 ‘붙여넣기’, ‘변경 추적’과 같은 기능을 통해 메가 바이트(MB) 단위의 데이터가 짧은 시간 안에 실시간으로 반영되어야 하므로 병목이 쉽게 발생할 수 있습니다. 이러한 처리 특성을 감당하기 위해서는 논블로킹 I/O 기반의 비동기 아키텍처가 필수적입니다.기존에는 Vert.x 기반의 논블로킹 아키텍처를 운영해왔으나, 내부적으로 블로킹 로직이 다수 존재해 비동기 처리의 이점을 충분히 활용하지 못했고, 점점 증가하는 사용량에 따른 처리 지연과 병목 현상이 누적되면서 구조적인 한계를 체감하고 있었습니다.이에 따라, 웹한글 백엔드를 Spring 생태계로 통합하고 유지 보수 효율성을 고려해 Spring WebFlux & Project Reactor 조합으로의 전환을 선택했습니다. 이 조합은 리액티브 스트림 표준을 따르며, 선언적이고 직관적인 방식으로 고성능 논블로킹 I/O 처리를 구현할 수 있어, 실시간 문서 편집 서비스에 보다 적합한 선택이었습니다.리액티브 시스템은 소프트웨어가 가져야 할 목표와 특징을 정의하는 ‘아키텍처 패러다임’입니다. 이는 대규모 트래픽, 잦은 장애 등 현대적인 애플리케이션 환경에 대응하기 위해 시스템이 어떻게 설계되어야 하는지에 대한 청사진을 제시합니다.리액티브 선언문(The Reactive Manifesto)에 따르면, 리액티브 시스템은 다음 네 가지 핵심 원칙을 반드시 지켜야 합니다.• 응답성 (Responsive): 시스템이 항상 신속하고 일관되게 응답해야 합니다.• 회복탄력성 (Resilient): 장애가 발생해도 시스템은 응답성을 유지해야 합니다.• 탄력성 (Elastic): 작업 부하가 변하더라도 시스템은 응답성을 유지해야 합니다.• 메시지 주도 (Message Driven): 컴포넌트 간 비동기 메시지를 통해 통신하여 느슨한 결합과 격리를 보장합니다.리액티브 시스템은 우리가 ‘왜’ 리액티브하게 만들어야 하는지에 대한 철학이자 목표입니다.Introduction to Reactive Programming :: Reactor Core Reference Guide 에 정의된 리액티브 프로그래밍은 데이터 스트림과 변화의 전파를 다루는 비동기 프로그래밍 패러다임입니다. 이는 곧, 사용되는 프로그래밍 언어를 통해 배열과 같은 정적인 데이터 스트림이나 이벤트 이미터와 같은 동적인 데이터 스트림을 쉽게 표현할 수 있게 된다는 것을 의미합니다.Reactive Streams 는 다양한 리액티브 프로그래밍 라이브러리들이 서로 원활하게 호환될 수 있도록 만든 기술 표준 명세(Specification)입니다. 이는 라이브러리들이 지켜야 할 최소한의 소통 규칙(API)으로, 자바의 인터페이스(Interface)와 비슷한 역할을 합니다.핵심 목표는 비동기 스트림 처리 과정에서 논블로킹 Backpressure(Non-blocking Backpressure)를 표준화하여, 가 의 처리 속도를 넘지 않도록 데이터 흐름을 안전하게 제어하는 것입니다. 이를 위해 Reactive Streams는 , , , 라는 4개의 핵심 인터페이스를 정의합니다.결과적으로 Project Reactor, RxJava, Akka Streams 같은 여러 라이브러리들이 모두 이 표준 인터페이스를 구현함으로써, 마치 JDBC 드라이버만 교체하면 다른 데이터베이스를 사용할 수 있는 것처럼 높은 상호 운용성을 확보하게 됩니다.Reactive Streams 명세에 정의된 4가지 핵심 인터페이스는 다음과 같습니다.3. Reactive Streams에서 Spring WebFlux로: 이론에서 실전으로지금까지 우리는 Reactive Streams가 무엇인지, 그리고 왜 필요한지에 대해 알아보았습니다. Reactive Streams는 논블로킹 Backpressure를 기반으로 라이브러리 간의 상호운용성을 보장하는 ‘기술 표준 명세(Specification)’였습니다.그렇다면 이 훌륭한 표준을 가지고 실제 웹 애플리케이션은 어떻게 만들 수 있을까요? 바로 이 지점에서 Spring WebFlux가 등장합니다.WebFlux는 Reactive Streams 명세를 완벽하게 구현한 Project Reactor 라이브러리를 기반으로 만들어진 스프링의 리액티브 웹 프레임워크입니다. 즉, WebFlux는 Reactive Streams라는 ‘이론’을 스프링 생태계에서 ‘실전’에 적용할 수 있도록 만든 핵심 도구인 셈입니다.WebFlux가 어떻게 기존의 Spring MVC와 다르며, Reactive Streams의 원칙을 통해 어떻게 더 적은 자원으로 높은 동시성 트래픽을 처리하는지 자세히 살펴보겠습니다.Spring 팀이 기존의 Spring MVC를 두고 WebFlux라는 새로운 리액티브 웹 프레임워크를 개발한 이유는 두 가지입니다.• 완전한 논블로킹 스택의 필요성: Servlet(서블릿) 3.1부터 논블로킹 I/O가 가능해졌지만, Filter, getParameter 등 대부분의 서블릿 API는 여전히 동기적(synchronous)이고 블로킹(blocking) 방식으로 동작했습니다. 이로 인해 Netty와 같이 널리 쓰이는 논블로킹 서버의 장점을 온전히 활용하기 어려웠고, 어떤 논블로킹 기술 위에서도 일관되게 동작하는 새로운 공통 API가 필요했습니다.• 함수형 프로그래밍의 부상: Java 8에 람다(Lambda) 표현식이 도입되면서, 비동기 로직을 선언적으로 구성할 수 있는 함수형 API의 가능성이 열렸습니다. 웹플럭스는 이러한 패러다임을 적극적으로 수용하여, 기존의 어노테이션 방식과 더불어 함수형 웹 엔드포인트(Functional Endpoints)를 제공하게 되었습니다.3.2. WebFlux의 두 가지 프로그래밍 모델WebFlux는 개발자에게 두 가지 선택지를 제공하며, 이는 하나의 애플리케이션 안에서 혼용할 수도 있습니다.• 어노테이션 기반 컨트롤러 (Annotated Controllers): Spring MVC와 거의 동일한 , 등의 어노테이션을 사용합니다. 덕분에 기존 MVC 개발자들도 쉽게 적응할 수 있으며, 리액티브 타
java
netty
spring
9/1/2025

WebFlux & Project Reactor 기반, 고성능 실시간 웹한글 문서 편집 시스템 전환기
웹한글 편집 서비스는 실시간 협업 환경에서 빈번한 I/O 작업이 발생하며, 수천 건의 편집 이벤트와 ‘붙여넣기’, ‘변경 추적’과 같은 기능을 통해 메가 바이트(MB) 단위의 데이터가 짧은 시간 안에 실시간으로 반영되어야 하므로 병목이 쉽게 발생할 수 있습니다. 이러한 처리 특성을 감당하기 위해서는 논블로킹 I/O 기반의 비동기 아키텍처가 필수적입니다.기존에는 Vert.x 기반의 논블로킹 아키텍처를 운영해왔으나, 내부적으로 블로킹 로직이 다수 존재해 비동기 처리의 이점을 충분히 활용하지 못했고, 점점 증가하는 사용량에 따른 처리 지연과 병목 현상이 누적되면서 구조적인 한계를 체감하고 있었습니다.이에 따라, 웹한글 백엔드를 Spring 생태계로 통합하고 유지 보수 효율성을 고려해 Spring WebFlux & Project Reactor 조합으로의 전환을 선택했습니다. 이 조합은 리액티브 스트림 표준을 따르며, 선언적이고 직관적인 방식으로 고성능 논블로킹 I/O 처리를 구현할 수 있어, 실시간 문서 편집 서비스에 보다 적합한 선택이었습니다.리액티브 시스템은 소프트웨어가 가져야 할 목표와 특징을 정의하는 ‘아키텍처 패러다임’입니다. 이는 대규모 트래픽, 잦은 장애 등 현대적인 애플리케이션 환경에 대응하기 위해 시스템이 어떻게 설계되어야 하는지에 대한 청사진을 제시합니다.리액티브 선언문(The Reactive Manifesto)에 따르면, 리액티브 시스템은 다음 네 가지 핵심 원칙을 반드시 지켜야 합니다.• 응답성 (Responsive): 시스템이 항상 신속하고 일관되게 응답해야 합니다.• 회복탄력성 (Resilient): 장애가 발생해도 시스템은 응답성을 유지해야 합니다.• 탄력성 (Elastic): 작업 부하가 변하더라도 시스템은 응답성을 유지해야 합니다.• 메시지 주도 (Message Driven): 컴포넌트 간 비동기 메시지를 통해 통신하여 느슨한 결합과 격리를 보장합니다.리액티브 시스템은 우리가 ‘왜’ 리액티브하게 만들어야 하는지에 대한 철학이자 목표입니다.Introduction to Reactive Programming :: Reactor Core Reference Guide 에 정의된 리액티브 프로그래밍은 데이터 스트림과 변화의 전파를 다루는 비동기 프로그래밍 패러다임입니다. 이는 곧, 사용되는 프로그래밍 언어를 통해 배열과 같은 정적인 데이터 스트림이나 이벤트 이미터와 같은 동적인 데이터 스트림을 쉽게 표현할 수 있게 된다는 것을 의미합니다.Reactive Streams 는 다양한 리액티브 프로그래밍 라이브러리들이 서로 원활하게 호환될 수 있도록 만든 기술 표준 명세(Specification)입니다. 이는 라이브러리들이 지켜야 할 최소한의 소통 규칙(API)으로, 자바의 인터페이스(Interface)와 비슷한 역할을 합니다.핵심 목표는 비동기 스트림 처리 과정에서 논블로킹 Backpressure(Non-blocking Backpressure)를 표준화하여, 가 의 처리 속도를 넘지 않도록 데이터 흐름을 안전하게 제어하는 것입니다. 이를 위해 Reactive Streams는 , , , 라는 4개의 핵심 인터페이스를 정의합니다.결과적으로 Project Reactor, RxJava, Akka Streams 같은 여러 라이브러리들이 모두 이 표준 인터페이스를 구현함으로써, 마치 JDBC 드라이버만 교체하면 다른 데이터베이스를 사용할 수 있는 것처럼 높은 상호 운용성을 확보하게 됩니다.Reactive Streams 명세에 정의된 4가지 핵심 인터페이스는 다음과 같습니다.3. Reactive Streams에서 Spring WebFlux로: 이론에서 실전으로지금까지 우리는 Reactive Streams가 무엇인지, 그리고 왜 필요한지에 대해 알아보았습니다. Reactive Streams는 논블로킹 Backpressure를 기반으로 라이브러리 간의 상호운용성을 보장하는 ‘기술 표준 명세(Specification)’였습니다.그렇다면 이 훌륭한 표준을 가지고 실제 웹 애플리케이션은 어떻게 만들 수 있을까요? 바로 이 지점에서 Spring WebFlux가 등장합니다.WebFlux는 Reactive Streams 명세를 완벽하게 구현한 Project Reactor 라이브러리를 기반으로 만들어진 스프링의 리액티브 웹 프레임워크입니다. 즉, WebFlux는 Reactive Streams라는 ‘이론’을 스프링 생태계에서 ‘실전’에 적용할 수 있도록 만든 핵심 도구인 셈입니다.WebFlux가 어떻게 기존의 Spring MVC와 다르며, Reactive Streams의 원칙을 통해 어떻게 더 적은 자원으로 높은 동시성 트래픽을 처리하는지 자세히 살펴보겠습니다.Spring 팀이 기존의 Spring MVC를 두고 WebFlux라는 새로운 리액티브 웹 프레임워크를 개발한 이유는 두 가지입니다.• 완전한 논블로킹 스택의 필요성: Servlet(서블릿) 3.1부터 논블로킹 I/O가 가능해졌지만, Filter, getParameter 등 대부분의 서블릿 API는 여전히 동기적(synchronous)이고 블로킹(blocking) 방식으로 동작했습니다. 이로 인해 Netty와 같이 널리 쓰이는 논블로킹 서버의 장점을 온전히 활용하기 어려웠고, 어떤 논블로킹 기술 위에서도 일관되게 동작하는 새로운 공통 API가 필요했습니다.• 함수형 프로그래밍의 부상: Java 8에 람다(Lambda) 표현식이 도입되면서, 비동기 로직을 선언적으로 구성할 수 있는 함수형 API의 가능성이 열렸습니다. 웹플럭스는 이러한 패러다임을 적극적으로 수용하여, 기존의 어노테이션 방식과 더불어 함수형 웹 엔드포인트(Functional Endpoints)를 제공하게 되었습니다.3.2. WebFlux의 두 가지 프로그래밍 모델WebFlux는 개발자에게 두 가지 선택지를 제공하며, 이는 하나의 애플리케이션 안에서 혼용할 수도 있습니다.• 어노테이션 기반 컨트롤러 (Annotated Controllers): Spring MVC와 거의 동일한 , 등의 어노테이션을 사용합니다. 덕분에 기존 MVC 개발자들도 쉽게 적응할 수 있으며, 리액티브 타
2025.09.01
java
netty
spring

좋아요

별로에요

if(kakao)25 컨퍼런스를 개최합니다.
‘이프 카카오 - if(kakao)25’ 컨퍼런스를 9월 23일부터 25일까지 경기도 용인 ‘카카오 AI 캠퍼스’에서 개최합니다. 아래 내용은 공식 보도자료로 배포한 내용과 동일합니다.가능성, 일상이 되다 - if(kakao)25올해로 7회를 맞는 이프 카카오는 카카오 그룹의 기술 경험과 성과를 공유하고 소통하는 행사다. 카카오는 이번 컨퍼런스의 슬로건을 ‘가능성, 일상이 되다’로 정하고, AI 대중화를 목표로 추진해온 다양한 성과와 결과물을 대거 선보인다. 특히, 그동안 카카오가 AI와 카카오톡을 핵심 축으로 역량을 집중해온 만큼, 카카오의 기술 혁신과 서비스 방향성을 심도 깊게 조망하는 자리가 될 예정이다.컨퍼런스 첫날인 23일, 정신아 대표가 카카오톡 개편과 신규 AI 서비스, 오픈AI 공동 프로덕트를 발표하며 가능성을 일상으로 만드는 카카오의 비전을 제시한다. 이어 홍민택 카카오 최고제품책임자(CPO)가 구체적인 카카오톡 개편 방향성과 서비스 형상을 선보이고, 김병학 카나나 성과리더는 자체 기술로 개발한 카나나 모델의 고도화 과정 및 성과를 발표한다.둘째 날에는 카카오의 AI 기술력을 심층적으로 다루는 세션들이 마련된다. 김병학 카나나 성과리더가 1일차에 이어 카나나 모델 활용 사례와 함께 에이전틱 AI(Agentic AI) 모델 개발 전략을 공유하며, 이상호 AI Safety&Quality 성과리더가 카카오 AI 윤리 및 안전을 위한 노력과 계획을 발표한다. 정규돈 최고기술책임자(CTO)는 지난 1년간 AI 네이티브 전환을 추진하며 인프라부터 서비스 릴리즈까지 전 영역에 AI를 적용해온 성과를 공유할 예정이다.이 밖에도 온디바이스 AI를 포함해 개방형 MCP 플랫폼인 ‘PlayMCP’ 등 AI 에이전트 생태계 확장을 위한 시도가 양일에 걸쳐 기조세션에서 발표되고, 카카오의 AI와 서비스를 이끄는 리더 및 개발자들이 연사로 참여해 기술 비전과 새로운 서비스를 소개한다. 기술 세션 외에도 광고, 디자인, 이모티콘 트렌드, 창작자와 함께하는 생태계 구축 등 폭넓은 주제의 세션이 펼쳐질 예정이다.마지막 날인 25일은 카카오 크루(임직원)을 위한 ‘크루 데이(Krew Day)’로, 카카오 그룹 개발자들이 기술 노하우를 공유하고 교류할 수 있는 특별 프로그램으로 진행된다. 행사장 내 마련된 체험존에서는 기조세션에서 소개되는 서비스를 비롯해 카카오가 자체 개발한 카나나 언어모델, 멀티모달 언어모델, 동영상 모델을 직접 체험해볼 수 있다.컨퍼런스 참가 신청은 8월 28일 낮 12시부터 9월 8일까지 ‘이프카카오’ 공식 홈페이지를 통해 가능하다. 신청자 중 추첨을 통해 최종 컨퍼런스 참가자가 선정되면 별도 채널을 통해 안내할 예정이다. 기조세션은 공식 홈페이지에서 라이브 스트리밍으로 제공돼 오프라인으로 현장을 찾지 못하는 경우에도 시청할 수 있으며, 전체 세션 영상은 행사 종료 후 업로드된다.카카오 관계자는 "이번 이프카카오는 가능성을 일상으로 실현하는 카카오의 끊임없는 변화와 기술력을 구체적으로 보여드리는 자리가 될 것"이라며, “앞으로도 카카오는 국민 누구나 일상에서 자연스럽게 AI를 경험할 수 있도록 접점을 확대해 ‘AI 대중화’를 선도해 나가겠다” 고 말했다. (끝)
9/1/2025

if(kakao)25 컨퍼런스를 개최합니다.
‘이프 카카오 - if(kakao)25’ 컨퍼런스를 9월 23일부터 25일까지 경기도 용인 ‘카카오 AI 캠퍼스’에서 개최합니다. 아래 내용은 공식 보도자료로 배포한 내용과 동일합니다.가능성, 일상이 되다 - if(kakao)25올해로 7회를 맞는 이프 카카오는 카카오 그룹의 기술 경험과 성과를 공유하고 소통하는 행사다. 카카오는 이번 컨퍼런스의 슬로건을 ‘가능성, 일상이 되다’로 정하고, AI 대중화를 목표로 추진해온 다양한 성과와 결과물을 대거 선보인다. 특히, 그동안 카카오가 AI와 카카오톡을 핵심 축으로 역량을 집중해온 만큼, 카카오의 기술 혁신과 서비스 방향성을 심도 깊게 조망하는 자리가 될 예정이다.컨퍼런스 첫날인 23일, 정신아 대표가 카카오톡 개편과 신규 AI 서비스, 오픈AI 공동 프로덕트를 발표하며 가능성을 일상으로 만드는 카카오의 비전을 제시한다. 이어 홍민택 카카오 최고제품책임자(CPO)가 구체적인 카카오톡 개편 방향성과 서비스 형상을 선보이고, 김병학 카나나 성과리더는 자체 기술로 개발한 카나나 모델의 고도화 과정 및 성과를 발표한다.둘째 날에는 카카오의 AI 기술력을 심층적으로 다루는 세션들이 마련된다. 김병학 카나나 성과리더가 1일차에 이어 카나나 모델 활용 사례와 함께 에이전틱 AI(Agentic AI) 모델 개발 전략을 공유하며, 이상호 AI Safety&Quality 성과리더가 카카오 AI 윤리 및 안전을 위한 노력과 계획을 발표한다. 정규돈 최고기술책임자(CTO)는 지난 1년간 AI 네이티브 전환을 추진하며 인프라부터 서비스 릴리즈까지 전 영역에 AI를 적용해온 성과를 공유할 예정이다.이 밖에도 온디바이스 AI를 포함해 개방형 MCP 플랫폼인 ‘PlayMCP’ 등 AI 에이전트 생태계 확장을 위한 시도가 양일에 걸쳐 기조세션에서 발표되고, 카카오의 AI와 서비스를 이끄는 리더 및 개발자들이 연사로 참여해 기술 비전과 새로운 서비스를 소개한다. 기술 세션 외에도 광고, 디자인, 이모티콘 트렌드, 창작자와 함께하는 생태계 구축 등 폭넓은 주제의 세션이 펼쳐질 예정이다.마지막 날인 25일은 카카오 크루(임직원)을 위한 ‘크루 데이(Krew Day)’로, 카카오 그룹 개발자들이 기술 노하우를 공유하고 교류할 수 있는 특별 프로그램으로 진행된다. 행사장 내 마련된 체험존에서는 기조세션에서 소개되는 서비스를 비롯해 카카오가 자체 개발한 카나나 언어모델, 멀티모달 언어모델, 동영상 모델을 직접 체험해볼 수 있다.컨퍼런스 참가 신청은 8월 28일 낮 12시부터 9월 8일까지 ‘이프카카오’ 공식 홈페이지를 통해 가능하다. 신청자 중 추첨을 통해 최종 컨퍼런스 참가자가 선정되면 별도 채널을 통해 안내할 예정이다. 기조세션은 공식 홈페이지에서 라이브 스트리밍으로 제공돼 오프라인으로 현장을 찾지 못하는 경우에도 시청할 수 있으며, 전체 세션 영상은 행사 종료 후 업로드된다.카카오 관계자는 "이번 이프카카오는 가능성을 일상으로 실현하는 카카오의 끊임없는 변화와 기술력을 구체적으로 보여드리는 자리가 될 것"이라며, “앞으로도 카카오는 국민 누구나 일상에서 자연스럽게 AI를 경험할 수 있도록 접점을 확대해 ‘AI 대중화’를 선도해 나가겠다” 고 말했다. (끝)
2025.09.01

좋아요

별로에요