흩어진 테크 블로그 글을 한곳에서 찾아 읽어요
여러 기술 블로그의 새 글을 제목·요약·태그로 검색하고 주제별·블로그별로 살펴볼 수 있어요. 글 상세와 원문은 로그인 없이 볼 수 있고, 로그인하면 읽음 표시와 즐겨찾기를 동기화하고 개인 노트를 저장할 수 있어요.
기업 기술 블로그별 최신 글 보기 → · 기획자·개발자별 활용 방법 →
여러 기술 블로그의 새 글을 제목·요약·태그로 검색하고 주제별·블로그별로 살펴볼 수 있어요. 글 상세와 원문은 로그인 없이 볼 수 있고, 로그인하면 읽음 표시와 즐겨찾기를 동기화하고 개인 노트를 저장할 수 있어요.
기업 기술 블로그별 최신 글 보기 → · 기획자·개발자별 활용 방법 →
네이버 사내 기술 교류 행사인 NAVER Engineering Day 10th 에서 발표되었던 세션을 공개합니다. 크림에서 통합 임베딩(Universal Embedding)은 어떻게 쓰일까? NAVER D2 | 크림에서 통합 임베딩(Universal Embedding)은 어떻게 쓰일까? naver.me 발표 내용 여러 엔티티를 한 공간에 담은 통합 임베딩과 범용 리트리벌이 크림 추천 곳곳에 쓰이는 방식, 운영하며 드러난 한계를 v2에서 해결한 과정, 그리고 확장 방향을 공유합니다. 발표 대상 추천 시스템의 후보 생성(Retrieval) 단계에 관심 있으신 분들 여러 서비스·지면에서 함께 쓰는 공용 임베딩을 설계하고 운영하고 싶으신 ML 엔지니어 조건(필터)이 걸린 벡터 검색의 지연과 메모리를 줄이고 싶으신 분들 구좌·서비스마다 늘어나는 추천 모델을 줄이고 싶은 추천·검색 조직의 엔지니어와 기획자 키워드 Recommendation System / Candidate Generation (Retrieval) Universal Embedding (Bi-encoder · Contrastive Learning) Matryoshka Representation Learning (MRL) Filtered Vector Retrieval (Roaring Bitmap · Brute-force vs ANN) Embedding Serving Optimization 목차 PART 1. 왜 통합 임베딩인가 2025년의 크림: 추천 구좌마다 모델이 따로 있었다 목표: 여러 목적에 쓸 수 있는 범용 임베딩 하나 구좌마다 ‘누구에게 · 무엇을 · 어떻게’가 다르다 통합 임베딩은 후보 생성에 직접, 랭킹에도 입력으로 설계 원칙: 모든 질문이 ‘벡터 + 조건’이 된다 PART 2. v1 모델 — 하나의 공간을 만들다 하나의 인코더가 검색어와 상품을 모두 읽는다 학습: InfoNCE를 받쳐 주는 일곱 가지 장치 학습은 상품 하나, 나머지는 모두 집계로 그림으로 보면: 모두가 상품 공간 위의 점 PART 3. v1 리트리벌 — 하나의 API로 꺼내 쓰다 질문 하나 = 요청 하나 조건별 상품 목록을 미리 만들어 두고 꺼내 쓰기 구좌 전용 모델 없이 붙은 첫 구좌들과 타겟 집단 추천 PART 4. 써 보니 드러난 v1의 한계 모델: 가끔 붕괴하고, 768차원은 무거웠다 리트리벌: 큰 조건을 감당하지 못했다 리트리벌: 조건을 자유롭게 조합할 수 없었다 v1의 한계, 한눈에 PART 5. v2 — 한계를 하나씩 걷어내다 모델 1차: 학습을 안정시키다 모델 2차: 하나의 벡터, 여러 해상도 (MRL) 좌표계: 회전으로 맞추려 했지만, 통하지 않았다 필터: Roaring Bitmap으로 조건을 실행할 때 조합 왜 근사 검색(ANN)이 아니라 후보 전부를 계산하나 점수 계산: 계산량은 그대로, 메모리 낭비만 없앴다 결과: 응답 지연은 약 4배 빠르게, 메모리는 1/6로 API: 조건 칸 하나 → 조건 리스트 v1의 한계 → v2의 처방 PART 6. 지금의 쓰임과 다음 확장 지금: 하나의 API가 채우는 지면과 구좌 비슷한 브랜드: 브랜드 벡터만으로는 부족했다 리트리벌 밖에서도 같은 벡터 다음으로 — 멀티벡터, 지면 확장, 마케팅 타겟팅 ◎ NAVER Engineering Day란? NAVER에서는 사내 개발 경험과 기술 트렌드를 교류를 할 수 있는 프로그램이 많이 있습니다. 그중 이제는 매회 평균 100개 이상의 발표가 이루어지는 NAVER Engineering Day를 빼놓을 수 없는데요. 2016년부터 시작된 ENGINEERING DAY는 실무에서의 기술 개발 경험과 새로운 기술과 플랫폼 도입 시 유용하게 활용될 수 있는 팁 등을 공유하며 서로 배우고 성장하는 네이버의 대표적인 사내 개발자 행사입니다.(관련 포스팅 보기) 올해 진행된 NAVER Engineering Day의 일부 세션을 공개합니다. [동영상 제공 채널 안내] 네이버 TV 서비스 종료로 인해 기존 네이버 TV 채널을 클립(@devrel_d2)으로 이동하였습니다. 앞으로
K-Metrics 제작 후기 #2 검색해도 안 나오는 SQL을 새로 만들다 최고운 AX팀 AI로 더 나은 일하는 방식을 고민하는 AI 엔지니어 업무의 언어를 이해하고, 함께 쿼리를 고치기까지 지난 편에서는 동료들이 업무에서 사용하고 확인한 쿼리를 모아, 자연어로 찾아 재사용하는 이야기를 했어요. 등록된 쿼리로 답할 수 있는 질문이라면 새 SQL을 만들지 않고도 업무를 시작할 수 있죠. 그렇다면 검색이 “못 찾았어요”라고 답한 요청은 어떻게 처리할까요? 등록된 쿼리가 다루지 않는 대상을 조회하거나, 다른 기준으로 집계해야 한다면 새로운 SQL이 필요합니다. 이번 편은 그다음을 다룹니다. 검색으로 답하기 어려운 요청을 K-Metrics가 어떻게 새로운 SQL로 만드는지, 그 과정에서 업무 용어를 해석하고 필요한 조건을 사용자와 확인하는 방법을 살펴볼게요. 만들어진 쿼리를 업무 의도에 맞게 이어서 고치는 과정도 함께 다룹니다. SQL 한 번을 생성하는 것만큼, 그 SQL을 사용자의 업무 의도에 맞게 다듬어 가는 과정에 집중했습니다. 질문이 SQL이 되기까지 “지난달 A상품 신규 가입 고객 수를 연령대별로 보여 줘”라는 요청을 예로 들어볼게요. 이 질문에 답하려면 무엇을 셀지, 어떤 데이터를 사용할지, 기간과 집계 기준을 어떻게 적용할지 정해야 합니다. K-Metrics는 질문을 요구사항으로 나누고, 테이블·컬럼과 조건을 정해 SQL을 작성한 뒤 검증해요. 문제가 있으면 필요한 단계로 돌아가고, 재시도 한도 안에서 해결되지 않으면 남은 문제를 정리해 반환합니다. SQL 생성과 검증·재시도 흐름 이 과정을 모델에게 한 번에 맡기지 않고 여러 단계로 나눈 데에는 이유가 있습니다. 왜 자율 에이전트보다 단계별 워크플로우가 필요했을까? 검색이나 스키마 조회를 도구로 제공하고, 모델이 다음 행동을 선택하도록 만들 수도 있습니다. 판단하고 도구를 사용한 뒤 그 결과로 다음 행동을 정하는 ReAct 방식이라면, SQL 생성 외의 정보 탐색까지 유연하게 연결할 수 있죠. 다만 이 서비스에서는 그 자유도보다 운영 중 처리 과정을 추적하고 통제할 수 있는 구조가 더 중요하다고 봤어요. 그 출발점은 모델에게 한 번에 맡기는 판단의 범위를 정하는 일이었습니다. 온프렘 LLM의 제한된 컨텍스트를 효율적으로 쓰기 위해 작업을 작은 목표로 나눴어요. 테이블을 고를 때는 요구사항과 후보 설명을, SQL을 작성할 때는 선택한 스키마와 확정된 계획을 전달합니다. 각 단계가 해야 할 일과 필요한 정보를 함께 좁힌 것이죠. 작업을 나누고 나니, 단계 사이에서 반드시 지켜야 할 순서도 분명해졌습니다. 특히 생성한 SQL의 검증을 모델에게 도구로 주고 ‘필요하면 호출해’라고 맡기고 싶지는 않았어요. SQL 작성 뒤에는 구조 검증으로 이어지고, 결과에 따라 의도 검증이나 수정으로 넘어가도록 경로를 정했습니다. 모델이 복구 방향을 제안하더라도, 이동할 수 있는 단계와 재시도·종료 조건은 코드가 관리하도록 했어요. 자율 에이전트와 단계별 워크플로우의 차이 이렇게 단계와 경로를 명시하면, 결과가 잘못됐을 때 되짚을 지점도 생깁니다. 최종 SQL만 보는 대신 요구사항 해석·테이블 선택·컬럼 매핑의 중간 결과를 따라가며 어느 판단에서 문제가 시작됐는지 확인할 수 있어요. 단계별 입출력을 기준으로 프롬프트 수정과 테스트의 출발점도 좁혀 볼 수 있습니다. LangGraph는 이 설계를 실행 흐름으로 옮기는 데 사용했습니다. 단계별 결과는 상태로 전달하고, 검증 결과에 따라 앞 단계로 돌아가는 분기와 반복은 조건부 연결로 표현했어요. LangGraph로도 자율 에이전트를 만들 수 있고, ReAct에도 검증과 재시도 제한을 붙일 수 있습니다. 결국 선택의 핵심은 프레임워크의 우열이 아니라, 판단은 모델에 맡기되 반드시 거쳐야 할 검증과 재시도·종료 조건은 코드로 관리하겠다는 것이었어요. 사내에서 쓰는 용어를 실제 조건으로 만들기 생성 흐름을 나눴다고 해서 모델이 우리 행의 업무까지 이해하지는 못 합니다. 사용자가 평소 쓰는 줄임말도 알아들어야 하고, 짧은 요청에 생략된 업무 기
2026년 8월 배민 앱에 Visual Intelligence를 연동했습니다. 이제 아이폰에서 Visual Intelligence를 실행하면, 검색 결과에서 비슷한 B마트 상품을 바로 확인하실 수 있습니다. 이 글에서는 먼저 Visual Intelligence가 어떤 기능인지 소개하고, 배민 앱에 연동한 과정을 살펴보겠습니다. 이어서 AI 에이전트를 활용해 이미지 검색을 구성한 이야기를 나눠 보겠습니다. Visual Intelligence 알아보고 연동하기 Visual Intelligence란? Visual Intelligence는 Apple Intelligence 기능 […] 아이폰 카메라로 B마트 상품을 찾는다고? first appeared on 우아한형제들 기술블로그.
안녕하세요. 무신사에서 ML Engineer로서 추천, CRM, 유저 속성, ML 플랫폼 등을 담당하고 있는 Core-E Personalization 팀의 김윤태입니다. 저희 팀에서는 개인화와 관련된 여러 문제를 풀고 그 문제를 서비스에 전달하기 위한 플랫폼을 만들어 가면서 개인화가 앞으로 어떤 방향으로 확장될 수 있을지 고민해 왔습니다. 개인화의 범위가 넓어질수록 ML로 풀어야 하는 문제도 달라집니다. 커머스의 검색과 추천, 광고, 앱 푸시, 쿠폰, 배너 등 다양한 채널이 각각 다른 목적에서 출발했고, 무신사와 29CM에서도 그랬습니다. 하지만 이들은 개인화가 확장될수록 점점 하나의 질문으로 수렴합니다. 이 고객에게 지금 무엇을 보여줄 것인가? 고객이 반응할 확률을 구하는 예측(prediction) 문제만 풀어서는 이 질문에 답할 수 없습니다. 반응할 확률이 높다고 해서 고객에게 모든 것을 무한정 보여줄 수는 없기 때문입니다. 하루에 보낼 수 있는 푸시의 수, 이번 달에 사용할 수 있는 쿠폰 예산, 한 화면에 담을 수 있는 상품의 수처럼 쓸 수 있는 자원에는 늘 한계가 있습니다. 반응 확률을 예측한 뒤에도, 그 한계 안에서 누구에게 무엇을 보여줄지는 따로 결정해야 합니다. 이런 문제를 풀기 위해 저희는 DeciML과 NeXA라는 두 개의 ML 플랫폼을 새로 만들었습니다. 두 플랫폼은 문제에 맞는 ML 모델을 학습하고 그 결과를 서비스까지 전달합니다. DeciML은 결정(decision) 문제를, NeXA는 발견(discovery) 문제를 다룹니다. 이 글은 두 플랫폼을 소개하는 시리즈의 첫 편입니다. 이번 편에서는 저희가 마주한 문제와 새로운 플랫폼이 필요했던 이유, 그리고 두 플랫폼이 맡을 역할과 설계 방향을 이야기합니다. 후속 편에서는 두 플랫폼의 구조와 적용 범위, 플랫폼 위에서 문제를 풀어 나간 사례를 차례로 다룹니다. The Problems Ahead 점수 예측만으로는 답할 수 없는 지점들 지금까지 많은 개인화 문제는 비교적 익숙한 형태로 풀 수 있었습니다. 고객과 상품, 혹은 고객과 콘텐츠의 조합마다 “이 고객이 반응할 확률은 얼마인가”를 예측하고 그 값을 기준으로 가장 점수가 높은 선택지를 고르는 방식입니다. 클릭률(CTR)이나 구매 전환율(CVR)처럼 하나의 점수를 잘 예측하는 것이 문제 해결의 핵심이었습니다. 하지만 서비스와 지면의 복잡도가 높아지고 개인화의 범위가 넓어질수록, 단순히 높은 점수를 고르는 것만으로 풀어낼 수 없는 문제가 발생합니다. 무엇을 보여줄지에 더해 제한된 자원을 누구에게 배분할지도 결정해야 하고 고객의 행동이 실제로 서비스의 개입 때문에 바뀌었는지도 알아야 합니다. 여러 지면의 결정을 함께 고려해야 하는 경우도 있고 새로운 발견 지면이 생길 때마다 그곳에 ML을 빠르게 적용해야 하기도 합니다. 이런 한계는 이미 서비스 곳곳에서 나타나기 시작했고 개인화가 진행될수록 더 다양한 형태로 늘어날 것입니다. 그중 지금 저희가 중요하게 보고 있는 네 가지 유형은 다음과 같습니다. Constrained Allocation. 오늘 보낼 수 있는 푸시가 한 통뿐이라면 누구에게 보내야 할까요? 하루에 보낼 수 있는 푸시 슬롯은 정해져 있고 쿠폰 예산에는 한도가 있습니다. 이때는 정해진 슬롯과 예산을 누구에게 배분할지 답해야 합니다. 점수는 배분의 입력이 될 수 있지만 배분 자체는 제약을 함께 고려해야 풀 수 있습니다. 누구에게 보낼지뿐 아니라 누구에게 보내지 않을지도 결정할 수 있어야 합니다. Incrementality. 앱 푸시의 클릭률을 높였는데 왜 앱 진입이나 구매 같은 비즈니스 지표는 그대로일까요? 원래 앱에 들어올 가능성이 높은 고객에게 푸시를 보냈다면, 클릭이라는 반응은 만들 수 있어도 푸시가 없었을 때와 비교해 실제 행동이 얼마나 달라졌는지는 알 수 없기 때문입니다. 중요한 것은 반응할 확률이 아니라, 개입이 실제로 만들어낸 변화가 얼마나 되는가입니다. 이를 알기 위해서는 개입이 있었을 때와 없었을 때의 차이를 추정해야 합니다. Cross-surface Coordination.
기획자의 코딩 이야기 #1 코딩을 모르는 기획자는 어떻게 코딩을 했을까? 2026.11.02 홍민지 BX팀 AI를 좋아하려고 노력하는 중입니다. 마감 2시간 전에 완벽하게 끝낸 사람이 있다? 제 얘기는 아닙니다. 미국 건축사의 상징인 건축가 프랭크 로이드 라이트가 낙수장(Fallingwater)이라는 건물을 지을 때의 에피소드예요. 그는 건축주에게 작업을 의뢰 받은 9개월 동안 아무것도 안 하다, 건축주가 ‘지금 보러 갑니다’ 라는 전화를 하고 운전해 오는 두 시간 동안 완벽한 도면을 그려내 보여줬다고 합니다. 이 일화, 라이트의 천재성을 엿볼 수 있긴 하지만 왠지 직장인이라면 공감 가지 않나요? 마감이 임박하면 초인적인 힘이 나오고, 끝내는 해내는 우리네 모습 같달까요. 누구나 한번 쯤 있는 경험이잖아요. 낙수장처럼 역사적인 의미를 갖는 작품까진 아닐지라도요. 저는 문제가 생겨야 해내는 타입인가 봅니다. 클로드 코드를 처음 만났을 때였습니다. 저는 개인 업무 일지를 만들어 보거나, 제가 좋아하는 ‘삼국지’ 뉴스레터 따위를 만들어 달라고 하고, 가끔 동료들 얼굴을 유명인사들과 합성하는 등의 놀잇감으로만 상대했습니다. 실제로 제가 하는 업무에 어떻게 적용해야 할지는 그려지지 않았습니다. 은행 특성 상 개발은 내부망에서만 할 수 있거니와 저 같은 사람이 개발할 수 있는 건 사실상 전무하다고 생각했거든요. 갖고 놀아보며 느낀 점은 있었습니다. ‘잘만 쓰면 대단하겠는데?’ 그렇지만 그런 생각을 품고 있을 뿐이었죠. 그러던 어느 날, 회사 블로그에 문제가 생겼습니다. 제가 플러그인을 하나 설치했는데, 갑자기 ‘치명적 오류’가 생겼다며 블로그가 제멋대로 닫혀 버린 것이었어요. 외부에 개발을 의뢰했던지라 즉시 대응하기가 쉽지 않았습니다. 제가 직접 해결하려면 ‘SSL 인증서…FTP 서버…’ 알 수 없는 단어들을 이해해야만 했습니다. ‘회사의 테스트 앱처럼, 블로그도 테스트 서버가 있다면 미리 플러그인을 설치해 볼 수 있었을 텐데…’ 아, 양심에 손을 얹고 이렇게 구체적으로 후회를 한 건 아닙니다. ‘어떻게 해야 되지’ 하는 막연한 답답함에 회사의 개발자들에게 자문을 구한 결과 정리된 워딩입니다.(후회도 뭘 알아야 하죠…) 클로드에게 이야기했습니다. ‘나는 개발에 대한 지식이 0인 사람이야. 워드프레스 기반의 블로그를 사전에 테스트 해볼 수 있는 테스트 페이지를 개발해야 해. ㄱㄱ’ 라고만 쳤는데요. 갑자기 블로그가 뚝딱 만들어지는 게 아니겠어요? 클로드 코드를 쓸 때 가장 중요한 것은 무엇일까? 답은 1 누르는 겁니다. 저는 클로드 코드가 낙수장 폭포수마냥 좔좔 작성해 나가는 코드에 1만 눌러주며 계속 진행하라는 명령을 주구장창 내렸습니다. 그 때마다 클로드 코드는 멋진 결과물을 보여주었죠. 몰라도 ‘1’을 누르면 됩니다. 생각보다 쉽게 나오는 결과물을 보니, 기존 블로그의 아쉬운 점들이 눈에 띄기 시작했습니다. ‘검색 기능이 이랬으면 좋겠고, UX는 이랬으면 좋겠고…포스팅은 이렇게 분류되면 좋겠고…’ 머릿속에 있는 모습들을 묘사하듯 프롬프트로 썼습니다. ‘반달 모양의 버튼을 누르면 다크 모드로 전환되는데, 이 버튼은 우하단에 플로팅되게 구현해줘. 버튼의 크기가 너무 크면 안되고, 전체 화면과 조화로워야 해’, 라는 식으로요. 클로드가 만들어준 결과물은 제 머릿속에 있는 낙수장보다 훌륭했습니다. 이제 욕심이 생기기 시작합니다. New Yorker 매거진 같은 해외 유수의 레퍼런스들을 대충 던져주며 ‘이렇게 만들어줘’ 라고 시켰습니다. 클로드를 대하는 제 태도는 영락없이 ‘직장에서 하면 빌런되는 짓’이었습니다. 그래도 꽤나 그럴 듯 하게 레퍼런스 포인트들을 반영하는 겁니다. 마음껏 괴롭혔습니다. 99%가 완성됐습니다. 테스트 페이지도 시키는 대로 구현했고, 블로그 본서버에 올릴 코드들도 개편되었습니다. 두 달을 내리 채워도 채워지지 않는, 1%의 어떤 것 그런데 아무리 시켜도, 클로드가 못 하는 게 있었습니다. 처음에 그려 넣은 검색창을 못 없애는 거예요! ‘타원형의 검색창을 만들어줘. 돋보기 버튼 위에 마우스 오버하면 검색창이
들어가며 안녕하세요. 미리캔버스 검색추천 스쿼드에서 데이터 분석가로 일하고 있는 윤지호입니다. 2026년 9월, 미리캔버스 에디터에 ‘AI 디자이너’ 기능이 추가됐습니다. 사용자가 채팅으로 원하는 작업을 요청하면 템플릿을 검색하거나 이미지를 생성하고, 캔버스에 있는 요소를 수정해 주는 AI 에이전트입니다. 이번 MVP에서 확인하고 싶었던 것은 사용자가 실제로 채팅을 통해 디자인 작업을 수행하려 하는지, 그리고 어떤 작업을 주로 요청하는지였습니다. 저는 이 프로젝트의 데이터 분석가로 참여해 PRD 단계의 이벤트 설계부터 실험 데이터 검증, 사용자 발화 분석, 배포 방향 제안까지 담당했습니다. 약 4주간의 A/B 테스트를 진행하면서 예상과 다른 사용자 행동을 여러 차례 발견했습니다. 특히 사용자가 에이전트를 한 번 사용한 뒤 돌아오지 않는 이유를 분석하는 과정에서 초기 가설을 수정해야 했고, 이를 바탕으로 제품의 개선 방향도 구체화할 수 있었습니다. 이번 글에서는 실험을 준비하면서 고민했던 지표 설계, 사용자 행동 분석 과정, 그리고 분석 결과가 실제 제품 의사결정으로 이어진 경험을 공유하려 합니다. 1. 사전 분석 시, 먼저 지표 설계를 통해 팀이 같은 숫자를 보게 했습니다 출시 전 저희가 확인하고 싶었던 질문은 크게 세 가지였습니다. 사용자는 채팅으로 디자인하는 경험을 원하는가? 외부 AI 서비스가 많은 상황에서 미리캔버스 에디터 안에서 채팅하는 것이 어떤 가치를 제공하는가? 여러 도구를 호출하는 에이전트의 응답이 느려지면 사용자는 이탈하는가? 이를 확인하기 위해 AI 디자이너의 노출 방식이 다른 세 개의 실험군과 에이전트가 없는 대조군을 구성했습니다. 국내 유료 에디터 2.0 사용자를 대상으로 9월 15일부터 10월 13일까지 약 4주간 실험을 진행했습니다. 분모를 합의하지 않으면 같은 데이터로 반대 결론이 나옵니다 실험을 준비하면서 먼저 정리해야 했던 지표 중 하나는 ‘도구 결과 채택률’이었습니다. AI 디자이너에는 하나의 결과를 반환하는 도구도 있고, 여러 결과를 목록으로 제공하는 도구도 있습니다. 그런데 이 두 유형을 동일한 기준으로 집계하면 채택률을 비교하기 어려웠습니다. 실제로 같은 템플릿 검색 도구라도 노출 이벤트를 기준으로 집계하는지, 사용자를 기준으로 집계하는지에 따라 채택률에 상당한 차이가 발생했습니다. 이런 상태에서는 지표를 확인하는 사람마다 서로 다른 숫자를 기준으로 기능의 성과를 판단할 수 있습니다. 이를 해결하기 위해 도구를 결과 반환 방식에 따라 단일 결과형과 목록형으로 구분하고, 각 유형에 적합한 분모를 정의했습니다. 이후 채택률을 집계할 때는 어떤 분모를 사용했는지 명시하도록 했습니다. 기존 대시보드에서 사용하던 정의와도 비교해 집계 기준을 맞췄습니다. 지표를 새롭게 정의하는 것뿐 아니라 기존에 확인하던 수치와 왜 차이가 발생하는지 설명하는 과정도 필요했습니다. 이렇게 집계 기준을 정리한 덕분에 이후 실험 결과를 비교하거나 도구별 성과를 분석할 때 일관된 기준을 적용할 수 있었습니다. 2. 이탈 유저 정의 및 유저 발화 분석 4주 동안 요청과 사용자는 목표보다 훨씬 많았습니다. 문제는 대화가 이어지지 않는 것이었습니다. 4주간의 실험에서 사용자 수와 요청 수는 모두 목표를 초과했습니다. 하지만 실제 사용 패턴을 살펴보니 아쉬운 부분도 있었습니다. 전체 대화 스레드의 절반 이상이 한 번의 요청으로 끝났고, 도구 결과 채택률도 출시 전 설정한 목표에 미치지 못했습니다. 에셋 전환율은 대조군과 큰 차이가 없었으며, 주간 리텐션 역시 기대했던 수준은 아니었습니다. 처음에는 응답 속도가 주요 원인일 것으로 예상했습니다. 도구 호출 응답시간의 중앙값이 30초를 넘었기 때문입니다. 사용자가 처음 에이전트를 경험했을 때 응답이 지나치게 느리면 다시 사용하지 않을 가능성이 있다고 생각했습니다. 하지만 실제 중단 비율을 살펴보니 응답 지연만으로 이탈을 설명하기는 어려웠습니다. 그래서 사용자가 어떤 요청을 보냈고, 그 요청이 실제로 처리됐는지 확인할 필요가 있었습니다. 먼저 분석 대상을 구체적으로 정의했
K-Metrics 제작 후기 #1 같은 지표를 물었는데 다른 숫자가 나오는 이유를 파보다 안상규 AX팀 AI로 혼자서는 어려웠던 일을 가능하게 만드는 AI/ML Engineer 안녕하세요, 케이뱅크 AX팀에서 AI/ML Engineer로 일하고 있는 안상규입니다. 요즘은 AI로 반복 업무를 덜고, 혼자서는 하기 어려웠던 일을 할 수 있게 돕는 일을 하고 있습니다. 동료들이 데이터를 더 쉽게 쓰도록 만드는 것도 그중 하나예요. 이런 회의, 한 번쯤 겪어 보셨을 겁니다. 각자 지표를 뽑아 왔는데 화면에 띄운 숫자가 서로 다릅니다. 그러면 본론에 들어가기 전에 어떤 기준으로 쿼리를 짰는지부터 확인해야 합니다. 쿼리를 열어 보면 테이블이 다르거나, 조건 하나가 빠졌거나, 기간을 잡는 기준이 달라요. 한참 걸려 맞춰도 그 결과가 공유되지 않으니, 다음 주에 누군가 같은 지표를 뽑으면 쿼리 확인부터 다시 시작합니다. 그래서 일단, 저희가 해야 할 목표를 두 가지로 정의해봤습니다. 1. 흩어진 쿼리를 하나로 통일하는 것 2. SQL을 몰라도 자연어로 필요한 쿼리를 찾을 수 있게 만드는 것 이렇게 탄생한 K-Metrics는 지표나 원하는 고객군을 자연어로 물으면, 누군가 이미 검증해 올려 둔 쿼리를 찾아 주고, 없으면 새로 만들어 주는 서비스입니다. 이번 포스팅에서는 ‘검색’ 기능에 대해서 이야기 해보려합니다. 숫자는 매번 다르고, 답을 받으려면 사람을 기다려야 하고 아까 앞에서 제가 알려드린 문제 상황, 기억하시죠? 정리하면 두 가지라 할 수 있는데요. 첫 번째는 숫자가 다른 겁니다. 두 번째는 기다림입니다. 두 문제 모두 검증된 쿼리가 공유 자산으로 존재하지 않는다는 것에서 시작되었다 생각했습니다. 누군가 이미 특정 쿼리를 짜고 검증까지 했는데도, 그 쿼리가 개인 PC의 파일이나 머릿속에만 있으면 다른 사람은 처음부터 다시 만들거나 그 사람을 찾아가야 합니다. 그런데 문제는 이뿐만이 아닙니다. 금융 회사, 특히 은행은 망 분리 정책에 따라 실제 고객 데이터가 있는 망과 직원들이 업무를 보는 망을 분리해 두어야 하는데요. 이중 사내 인트라넷처럼 임직원들이 사용하는 사내 서비스, 은행이 보유하고 있는 DB는 철저하고 엄격하게 사내망에만 존재해야 합니다. SQL을 작성해주는 에이전트는 있을 수 있어도, 그 SQL을 사내 시스템에서 실행하거나 실제 DB를 대상으로 돌릴 순 없습니다. 그림으로 표현하면 아래와 같습니다. 이렇듯 일반적인 text2SQL과 달리, 스스로 검산할 수 없는 K-Metrics는 틀린 쿼리를 그대로 사용자에게 보여 줄 위험성이 필연적으로 존재합니다. 일단 믿고 쓸 수 있는 서비스가 되려면 무엇을 지켜야 하는지 세 가지 조건으로 정리했습니다. 1. 같은 지표를 물으면 항상 같은 쿼리를 줄 것 2. 실행 결과 없이도 믿을 수 있는 근거를 보여 줄 것 3. 맞는 쿼리가 없으면 없다고 말할 것 사용자 중에는 쿼리에 익숙하지 않은 비개발자가 더 많을 수도 있습니다. 그래서 엉뚱한 쿼리를 자신 있게 내미는 상황을 가장 위험한 상황이라 판단했습니다. 지표를 통일하는 네 가지 방법 위의 세 조건을 기반으로, 네 가지 방향을 차례로 검토했습니다. 방법 통일 대상 한계점 ① 표준 쿼리 저장소만 두기 쿼리 파일 찾기 어려우면 안 쓰게 되고, 기간·조건은 매번 직접 수정 ② 대시보드로 계산 결과 모으기 계산 결과 조회 권한·망 협의가 먼저 필요 ③ 자연어를 SQL로 생성 없음 — 매번 새 SQL 검증되지 않은 SQL이 나옴 ④ 검증 쿼리 자산화 + 자연어 검색 검증된 쿼리 ← 선택 2번의 경우 대시보드로 결과가 나오기 때문에 데이터를 쉽게 해석할 수 있다는 장점은 있습니다. 하지만 데이터의 조회 권한 문제가 있기에 실현하는데 제약이 있습니다. 3번의 경우 등록된 쿼리가 없어도 답할 수 있다는 장점은 있지만, 매번 다른 SQL이 나와서 첫 번째 조건과 맞지 않았습니다. 결국엔 ④번 방향을 골랐습니다. 지표 정의나 계산 결과가 아니라 검증된 쿼리를 통일의 기준으로 삼고, 쿼리를 찾고 조건을 채우는 단계에 LLM을 활용했습니다. 검색이
토스 앱에서 사용자가 어떤 화면을 보고 무엇을 눌렀는지는 앱로그로 남아요. 토스는 이렇게 쌓이는 로그를 서비스 품질을 높이는 목적으로 사용해요. 그래서 로그를 처음부터 정확하고 일관되게 정의해야 분석 결과도 믿을 수 있어요. 이를 위해 로그를 전담해 설계하고 관리하는 DataOps Manager와 로그 명세를 한곳에서 관리하는 플랫폼인 로그센터가 있어요. DataOps Manager는 앱로그의 규칙과 맥락을 지키며 담당 도메인의 로그 명세를 정의하고 관리해요. 이번 글에서는 비개발자인 DataOps Manager들이 모여 로그센터에서 수동으로 진행하던 로그 정의 업무를 AI 스킬로 개선한 과정을 소개하려고 해요. 1. 로그 정의할 때 중요한 것들 앱 화면은 끊임없이 새로 생기고 바뀌어요. 그때마다 DataOps Manager(DOM)는 사용자의 행동을 어떤 로그로 기록할지, 그 로그에 어떤 파라미터를 함께 남길지 새로 정해야 해요. 로그를 정의할 때에는 다음 네 가지를 챙겨야 해요. 로그를 정의할 때에는 로그를 정해진 형식에 따라서, 도메인 안의 맥락을 이어서, 분석에 필요한 것만 남기면서, 정책과 안전을 지켜서 정의해야 해요. 로그 규칙은 '앱로그 백과사전'에 정리되어 있었어요. 하지만 로그를 정의할 때는 규칙뿐 아니라 도메인의 맥락과 히스토리도 중요해요. 기존 로그 명세를 직접 검색해 참고할 수는 있었지만, 도메인의 맥락은 담당 DOM의 머릿속에 남아 있는 경우가 많았어요. 그래서 각자가 가진 맥락과 경험에 의존해 로그센터에서 수동으로 로그를 정의하고 관리했어요. 한 사람이 정확하게 정의하기도, 모두가 일관되게 정의하기도 어려웠던 부분을 저희는 AI 스킬로 로그를 정의하는 방식과 과정 모두를 개선하고자 했어요. 2. 로그 정의 과정을 AI 스킬로 옮기기 로그를 정의할 때마다 앞에서 본 네 가지 규칙을 찾아보고 도메인의 맥락까지 기억하는 건 쉽지 않은 일이었어요. 그래서 한 DOM이 자신이 알고 있던 규칙과 경험을 살려, 로그 정의를 돕는 작은 스킬을 만들어 쓰기 시작했어요. 하지만 이 스킬은 만든 사람의 도메인과 경험에 묶여 있어서, 만든 사람은 편했지만 다른 사람이나 다른 도메인에서는 그대로 쓰기 어려웠어요. 그래서 저희는 이 스킬을 누가 어떤 도메인에서 작업하든 함께 쓸 수 있도록 제대로 풀어보기로 했어요. 로그를 정의할 때 거치는 판단과 순서를 개인의 머릿속이 아니라 스킬 안에 담으면, 매번 규칙을 외우지 않아도 되고 모든 도메인에서 같은 기준으로 정의할 수 있으니까요. 그렇게 만든 '로그 정의 스킬'은 로그 명세를 대신 찍어내는 생성기는 아니에요. 새 로그를 만들기 전에 '앱로그 백과사전'의 표준을 확인하고 도메인의 기존 로그 명세를 끝까지 조회해 재사용할 수 있는지 먼저 살피고, 실제 반영은 사람이 확정한 뒤에만 실행해요. (이 스킬은 사용자의 로그를 읽거나 처리하지 않아요.) 화면 하나의 로그를 정의해달라고 하면 로그 정의 스킬은 다음의 순서로 움직여요. 스킬은 화면 디자인을 살펴보고, 적절한 로그 명세 규칙을 확인한 뒤 재사용할 수 있는 부분을 검토해 로그 명세를 제안해요. DOM이 제안된 명세를 검토해 최종 확정하면, 스킬이 이를 시스템에 반영해요. 이 과정에서 스킬, 로그센터의 CLI(Command Line Interface)인 lctl, 로그센터는 역할을 나눠 맡아요. 스킬은 맥락에 따른 판단을 안내하고, 확신할 수 없는 부분은 사람에게 물어요. 로그 이름 형식처럼 기계가 판정할 수 있는 규칙은 lctl이 저장 전에 검사하고, 로그센터는 규칙에 맞지 않는 명세의 발행을 거절해요. 형식 규칙은 스킬에 적어두지 않고 실행할 때마다 lctl에 묻기 때문에, 규칙이 바뀌어도 스킬은 늘 최신 기준을 따를 수 있어요. 로그 정의 스킬이 판단하고 조율하면, 로그센터 CLI가 저장 전에 미리 걸러내고, 로그센터가 저장하며 최종 판정해요. 3. 개인 도구에서 팀 표준으로 로그 정의 스킬을 함께 쓰려니 개인이 사용할 때보다 고려해야 할 게 많았어요. 한 사람의 업무에 맞춰져 있던 안내를 여러 DOM이 활용할 수
글. 박수봉(Henby) / 서비스웹개발팀 안녕하세요. 서비스웹개발팀 헨비입니다. 9월 7일, 여기어때 해외투어 서비스를 오픈했습니다. 프론트엔드 담당 개발자는 두 명이었고, 웹과 앱 웹뷰를 하나의 코드베이스로 개발했습니다. 저는 웹 카테고리홈·상품 상세·주문서·예약내역·해외투어용 채팅을 맡았고, 검색바·헤더·푸터·예약내역 탭·찜 탭·회원탈퇴처럼 여러 서비스가 함께 쓰는 공통 화면도 담당했습니다. 3월 13일에 빈 앱을 만들고 9월 7일에 오픈까지 총 25주였습니다. 이 글은 그 25주 동안 어떤 것을 만들었고 어떤 판단을 했는지 정리한 기록입니다. 세 번의 신규 서비스, 개발 범위는 넓어지고 처리는 빨라졌습니다 여기어때에서 신규 서비스 프론트를 맡은 건 이번이 세 번째입니다. 2024년 가을 해외숙소 비회원 예약, 2025년 봄 패키지여행, 그리고 이번 해외투어까지입니다. 세 프로젝트를 같은 기준으로 비교해 보니 한 가지 흐름이 보였습니다. 저의 담당 범위는 점점 넓어지고 깊어졌습니다. 첫 번째 프로젝트에서는 주문서·예약완료·예약내역·조회 흐름을, 두 번째에서는 웹 PDP·홈 검색·채팅을 맡았습니다. 이번에는 웹과 앱을 합쳐 여덟 개 영역을 담당했고, 웹과 웹뷰를 동시에 개발했습니다. 반면 작업해야 할 레포 수는 줄었습니다. 첫 번째 프로젝트에서는 세 개, 두 번째에서는 두 개의 레포를 오갔지만, 이번에는 모노레포 하나와 채팅 레포 하나로 작업했습니다. QA 티켓은 77건, 55건, 280건으로 늘었지만 3일 내 처리율은 48%, 62%, 81%로 높아졌습니다. 범위와 티켓 수는 늘었지만 처리 속도는 빨라졌습니다. 그 변화를 만든 작업을 정리해 봤습니다. 모노레포에서 두 번째 서비스를 올렸습니다 해외투어는 모노레포에 올라간 두 번째 서비스였습니다. 첫 번째 서비스인 항공팀은 웹·모바일웹·웹뷰를 하나의 코드베이스로 운영할 기반을 이미 만들어 둔 상태였습니다. 구축 과정은 같은 팀 에릭이 쓴 “항공 프론트엔드 구축기” 열 편에 자세히 정리돼 있습니다. [링크] 저는 그 기반을 활용했습니다. 웹 레이아웃의 Provider 스택은 항공 레이아웃을 따라 3월 말에 구성했습니다. 현재 구조는 다음과 같습니다. <PlatformProvider value={{ platform: 'web', isWebAccess: true }}> <AppInitializer runtimeEnv={process.env.NEXT_PUBLIC_ENV} /> <AuthProvider initialUser={user}> <GtmTrackingProvider> <LoadingSpinnerProvider> <DialogProvider> <SnackbarProvider>{children}</SnackbarProvider> </DialogProvider> </LoadingSpinnerProvider> </GtmTrackingProvider> </AuthProvider> </PlatformProvider> 플랫폼 판정, 앱 초기화, 인증, 계측, 로딩, 다이얼로그, 스낵바의 순서는 항공과 같습니다. 앱 레이아웃은 첫 줄의 platform 값만 다릅니다. 앱과 웹의 로그인 분기, 브라우저 뒤로가기와 안드로이드 백키를 함께 처리하는 모달 구조, 팀 공통 디자인 시스템 YDS도 그대로 활용했습니다. 개발자 두 명이 화면 서른일곱 개를 만들어야 하는 상황에서 기반을 새로 만들기보다, 먼저 개발중인 항공에서 이미 검증한 구조를 재사용하는 편이 합리적이었습니다. 대신 서비스에만 필요한 구현으로 남지 않도록, 재사용 가능한 기능은 공유 패키지에 추가했습니다. 25주 동안 공유 패키지에 182건을 커밋했고 컴포넌트 파일 50개를 새로 만들었습니다. 이미지 전체 보기 모달을 공통화하고, 결제수단 UI를 패키지로 분리했으며, 화면에 묶여 있던 찜 API는 앱 공용으로 옮겼습니다. 공유 패키지를 수정하면 항공에 영향을 줄 수 있습니다. 그래서 서비스 브랜치는 master에서만 분기하고, 공유 패키지 변경은 서비스 브랜치 안에서 격리한 뒤 master 머지를 통해서만 다른 서비스에
미리캔버스 템플릿 디자이너는 유저 입장에서 고민하며, 누구나 쉽게 멋진 결과물을 만들 수 있도록 다양한 템플릿을 기획하고 설계합니다. 타겟과 목적에 맞춘 실험으로 전 세계 고객이 원하는 디자인을 완성하도록 돕는 사람들, 템플릿 디자인 팀의 유현님과 현아님의 이야기를 전해드립니다. Q. 안녕하세요, 유현님과 현아님! 자기소개 부탁드릴게요. 유현님: 안녕하세요. 미리캔버스 템플릿 디자인 파트 리드 유현입니다. 북미를 중심으로 글로벌 시장을 타겟으로 한 템플릿을 기획하고 디자인하며, 유저 반응을 분석하는 일을 하고 있어요. 미리캔버스가 전 세계에서 가장 쉽고 멋진 디자인 플랫폼으로 성장하도록 만드는 게 제 역할이에요. 현아님: 안녕하세요. 미리캔버스에서 템플릿 그래픽 디자인을 하는 현아입니다. 지금은 일본 미리캔버스 트라이브에 속해서 일본 템플릿 디자인을 연구하고 있어요. 누구나 편리하게 창의적인 표현을 할 수 있도록 만드는 일이 매력적으로 느껴져서 미리디에 합류했어요. Q. 두 분 모두 템플릿 디자이너로 시작해 지금은 파트 리드를 맡고 계신다고 들었어요. 그래서 궁금한데요, 템플릿 디자이너는 정확히 어떤 일을 하는 직무인가요? 유현님: 미리디 템플릿 디자이너는 고객이 쉽고 빠르게 디자인할 수 있도록 돕는 템플릿을 만드는 사람이에요. 디자인 경험이 적은 고객도 프레젠테이션이나 SNS 콘텐츠, 포스터 같은 결과물을 직접 만들 수 있어야 하다 보니, 유저가 쓰고 싶어 하는 미감을 담으면서도 사용이 편리한 디자인을 만드는 게 핵심이에요. 그래서 저희 파트는 주제 분석부터 레퍼런스 수집, 템플릿 제작, 내부 리뷰, 그리고 유저 반응 확인을 통한 인사이트 도출까지의 과정을 끊임없이 반복해요. 이 과정에서 저희 팀의 특징이 하나 있는데, 바로 적극적으로 디자인 실험을 한다는 점이에요. “북미 유저에게는 이런 디자인이 통할 것이다”라는 가설을 세우고, 그에 맞는 템플릿을 실제로 만들어 유저 반응을 확인한 다음, 그 결과로 다시 개선 방향을 정해요. 그래서 저는 저희 팀을 단순히 템플릿을 만드는 팀이 아니라, 디자인 전략을 기획하고 실험하고 성장시키는 팀이라고 생각해요. 현아님: 저도 비슷한 맥락에서, 템플릿 디자이너를 사용자가 자신의 메시지를 쉽고 효과적으로 표현하도록 돕는 디자인 솔루션 제안자라고 생각해요. 보기 좋은 디자인을 만드는 데서 끝나지 않고, 누가 어떤 상황에서 이 템플릿을 쓸지부터 고민한 다음 그 목적에 맞게 구성과 흐름을 설계해야 하거든요. 업종이나 콘텐츠 스타일에 따라 톤앤매너를 유연하게 바꾸는 것도 그래서 필요한 능력이고요. 결국 그렇게 만든 템플릿이 실제로 가입이나 콘텐츠 제작, 재방문 같은 행동으로 이어지도록 설계하는 것까지가 저희 역할이라고 생각해요. Q. 그 실험이 실제로는 어떻게 진행되는지 궁금해요. 최근 유저 반응이 특히 좋았던 템플릿은 어떤 거였나요? 유현님: 템플릿 디자인에서는 디자인 감도와 사용성 사이의 균형이 중요한데요, 저희 파트에서 진행한 실험 중 그 균형을 잘 맞춰서 반응이 좋았던 두 가지 스타일을 소개할게요. 첫 번째는 클레이 스타일 템플릿이에요. 북미 유저의 검색 키워드를 분석하다 보니 클레이 스타일에 대한 관심이 있다는 걸 확인했고, 그래서 내부적으로 클레이 에셋 제작 방식을 스터디한 뒤 주제에 맞는 3D 클레이 에셋을 직접 만들어 템플릿에 적용했어요. 그 결과 컨셉과 에셋이 잘 어우러져서, 관련 키워드를 검색하는 고객들이 템플릿과 요소를 다양하게 활용하는 모습을 확인할 수 있었어요. 👉🏻 베이지 심플 헬스케어 가이드 프레젠테이션 템플릿 만나러 가기 두 번째는 두들·기하학 도형 스타일 템플릿이에요. 24년부터 미리캔버스가 글로벌 시장에 진출한 만큼 글로벌 디자인 트렌드도 꾸준히 리서치하고 있는데, 이 스타일도 그 리서치에서 나온 컨셉 보드에서 출발한 실험이었어요. 편집 용이성을 높이기 위해 여백 중심의 레이아웃을 쓰고, 심플한 구조 안에 포인트가 되는 기하학 도형을 배치했더니, 단조롭지 않으면서도 유저가 자신의 개성을 표현할 수 있는 템플릿이 됐고 실제로 많은 고객이 선택했어요.
글. 김수비(소피) / 공통플랫폼개발팀 안녕하세요, 여기어때컴퍼니 공통플랫폼개발팀 소피입니다. 1편에서는 검색을 만들기 전에 바닥을 다졌습니다. Confluence와 Jira에 흩어진 문서를 증분으로 모으고, 검색에 쓸 수 없는 JSON을 Markdown으로 바꾸고, 이미지에는 대체 텍스트를 붙였습니다. 이미지가 보이지 않던 문제는 거기서 답이 됐습니다. 남은 문제는 하나였습니다. 맞는 키워드를 모르면 계속 헤매는 문제. 에이전트가 단어를 바꿔가며 검색과 열람을 6~7번씩 왕복하다 겨우 답을 내는, 느리고 비싼 검색이었습니다. 이건 문서를 잘 쌓아두는 것만으로는 풀리지 않습니다. 그 위에 얹을 검색이 따로 필요합니다. 이번 편이 그 검색 이야기입니다. 의미로 문서를 찾아내는 LightRAG와 문서가 놓인 자리를 따라 걷는 Navigator. 두 리트리버를 차례로 풀어보겠습니다. 프로젝트의 추상화된 전체 아키텍처 벡터 검색만으로는 부족했다 처음 떠올린 건 전통적인 RAG 구조였습니다. 문서를 잘게 잘라 임베딩해두고, 질문과 가까운 청크를 꺼내 모델에게 넘기는 방식입니다. 그런데 사내 질문에 대입해 보니 이 구조로는 부족했습니다. “공통 게이트웨이에 필터를 하나 추가하려면?”의 답은 가이드 문서, 요청 프로세스 문서, 과거 Jira 이슈에 등에 조금씩 나뉘어 있는데, 벡터 검색은 비슷한 청크를 꺼내줄 뿐 그 조각들이 서로 어떤 관계인지는 알려주지 않습니다. 조각을 잇는 일이 매번 모델의 추측으로 남고, 추측에 기댄 답은 틀리기 쉽습니다. 필요한 건 “비슷한 문서”가 아니라 “이 개념이 어디에서 어떻게 이어지는지”였습니다. LightRAG란 무엇인가 이 문제의식에 맞는 접근이 GraphRAG였습니다. 문서에서 개념(Entity)과 관계(Relation)을 미리 뽑아 지식 그래프로 만들어 두고, 검색할 때 그래프를 따라 관련 개념까지 함께 끌어오는 방식입니다. 문서를 넣는 시점에 “공통 게이트웨이”라는 개념과 “라우팅 요청 프로세스”라는 개념이 연결돼 있다는 것을 그래프로 만들어 두면, 검색 시점에는 그 연결을 따라가기만 하면 됩니다. 조각을 잇는 일을 매 질문마다 모델의 추측에 맡기는 대신, 인덱싱할 때 한번만 해두는 것입니다. GraphRAG 계열로 저희가 고른 것이 LightRAG입니다. LightRAG는 GraphRAG 방식을 경량화한 오픈소스 프레임워크로, 문서에서 Entity/Relation을 추출해 지식 그래프를 구성한 뒤 그래프 탐색과 벡터 검색을 결합합니다. LightRAG 지식 그래프 구성 예시 LightRAG의 구성은 다음과 같습니다. LightRAG 파이프라인 동작을 요약하면 문서를 넣으면 LightRAG가 토큰 단위로 청킹하고, 각 청크를 LLM에 넘겨 Entity와 Relation을 추출해 그래프를 쌓습니다. 그리고 Entity, Relation, 청크 원문 세 갈래를 각각 임베딩해 둡니다. 질문이 들어오면 LLM이 질문에서 키워드를 추출하고, 그 키워드로 세 벡터 인덱스와 그래프를 함께 탐색해 결과를 합칩니다. LightRAG에 문서 넣고 검색하기 LightRAG에 문서 넣기 파이프라인의 마지막 단계는 정제된 문서를 LightRAG에 업로드하는 것입니다. 여기서는 LightRAG의 동작 방식인 갱신 방식과 비동기 인덱싱 두 가지를 고려했습니다. LightRAG의 업로드 API에는 upsert가 없어서, 같은 ID로 다시 올리면 갱신되는 게 아니라 “duplicated”로 조용히 무시됩니다. 하루 세 번 문서를 증분으로 밀어 넣는 저희 파이프라인에서는 수정본이 그대로 버려지는 셈이라, 갱신을 삭제 → 삭제 완료 대기 → 재업로드 3단계로 풀었습니다. 삭제 역시 비동기라 요청 접수가 곧 완료는 아니기 때문에, 문서 목록을 재조회해 실제로 사라진 것을 확인한 뒤 재업로드합니다. 인덱싱도 비동기입니다. 업로드가 성공해도 뒤에서 도는 Entity 추출이 LLM 호출 한도(429)에 걸리면 문서는 failed로 남아, 파이프라인은 성공했는데 검색에서는 빠진 문서가 생깁니다. 그래서 인덱싱이 끝날 시점에 실
글. 박이슬(스노우) / 공통플랫폼개발팀 안녕하세요, 여기어때컴퍼니 공통플랫폼개발팀 스노우입니다. 1편에서는 Confluence와 Jira에 흩어진 문서를 모아 검색 가능한 형태로 바꿨고, 2편에서는 그 위에 LightRAG와 Navigator를 얹었습니다. 여기까지 오면 질문을 던졌을 때 답이 돌아옵니다. 그런데 만들고 나서 가장 오래 붙잡고 있었던 건 검색이 아니었습니다. 만든 것이 제대로 동작하는지 확인하는 일이었습니다. 이번 편은 그 이야기입니다. 질의를 던졌을 때 무엇이 오갔는지 보이게 만들고, 그게 맞는 답인지 채점하고, 그렇게 검증한 검색을 에이전트가 쓸 수 있게 내보내기까지. 그리고 마지막에는 그렇게 만든 도구가 지금 어디에서 어떻게 쓰이고 있는지까지의 이야기입니다. LLM Observability와 LLM 평가하기 LLM과 RAG는 잘 돌아가고 있는지 눈으로 확인하기 어려운 시스템입니다. LLM의 입출력은 자연어이다 보니, 지금 모델이 좋은 답변을 했는지 못했는지를 판단하기가 굉장히 어렵습니다. 답이 그럴듯하면 맞아 보입니다. 근거 문서들을 함께 돌려주니 더 그래 보입니다. 실제로는 엉뚱한 문서를 집어왔는데도 모델이 매끄럽게 문장을 만들어내면, 읽는 사람은 그걸 알아차리기가 어렵습니다. 비용도 마찬가지입니다. 문서 하나를 처리하는 데 LLM 호출이 몇 번이나 붙는지, 그게 한 달에 얼마가 되는지는 청구서가 오기 전까지 알 수 없습니다. 이런 문제점을 해결해주는 도구로써 최근에 LLM에 특화된 APM(Application Performance Monitoring)들이 나왔습니다. 그 중 저희는 Langfuse를 선택했습니다. LLM 애플리케이션에 특화된 오픈소스 관측 플랫폼으로, 요청 하나가 어떤 경로를 거쳤는지를 trace 단위로 기록하고 보여주는 모니터링 툴입니다. Langfuse trace 추적 예시 일반적인 APM과 다른 점은, 프롬프트와 응답 전문, 사용 토큰, 모델별 단가에 따른 비용이 호출마다 남는다는 점입니다. 검색 → 프롬프트 조립 → 생성으로 이어지는 여러 단계를 하나의 trace로 묶어 보여주기 때문에, 어느 단계에서 시간이 걸렸고 어디서 토큰이 나갔는지를 한 화면에서 확인할 수 있습니다. RAG 평가 파이프라인 구축 Langfuse를 붙이면서 어디에 시간과 비용이 나가는지 보이게 됐습니다. 다만 검색 결과가 좋은지 나쁜지는 여전히 알 수 없었습니다. trace에 남는 건 무엇이 오갔는지, 그게 맞는 답인지가 아니기 때문입니다. Langfuse에는 Experiment라는 이름으로 해당 기능을 지원하고 있습니다. 데이터셋을 만들고, 평가체계를 구축하고, 실험을 돌려 결과를 남기는 것까지 하나의 플랫폼 안에서 가능합니다. 이번 프로젝트에서는 이 기능을 최대한 활용하였습니다. 무엇을 물어볼 것인가 RAG 시스템을 평가하기 위해선, 먼저 평가대상인 질문-답변 쌍을 제작해야했습니다. 검색이 실패하는 방식은 하나가 아니기 때문에 먼저 사내 지식을 기반으로 답변할 수 있는 질문 유형을 일곱 가지로 나누고, 유형별로 질문과 정답 쌍을 작성했습니다. 유형을 나눠서 데이터셋을 생성한다면, 평가 이후 어디가 약한지가 점수와 함께 드러날 것이라고 생각했습니다. 검색이 제대로 됐는가 질문셋이 준비됐으니 이제 확인할 차례입니다. RAG에서 답이 틀리는 경로는 크게 둘인데, 애초에 엉뚱한 문서를 가져왔거나 문서는 맞는데 모델이 잘못 읽은 경우입니다 앞쪽은 정보 검색 분야에서 오래 쓰인 지표들로 확인할 수 있습니다. Recall@5 : 정답 문서가 상위 5개 안에 들어왔는가 Hit Rate : 정답 문서를 한 번이라도 회수했는가 MRR : 정답 문서가 몇 번째로 올라왔는가 질문마다 정답 문서를 지정해뒀기 때문에 리트리버가 돌려준 목록과 대조하면 자동으로 계산됩니다. Langfuse Python SDK로 데이터셋을 불러와 실험을 돌리고, 이 지표들을 계산하는 evaluator를 붙였습니다. LLM을 거치지 않으니 빠르고, 같은 입력에는 항상 같은 값이 나옵니다. 그래서 답은 좋아졌는가 (LLM-as-a-judg
GS SHOP 앱에는 백 여개에 달하는 추천 영역이 고객 탐색 경험을 돕고 있습니다. 고객의 쇼핑을 더 빠르고 편리하게 도와줄, 추천 알고리즘 개선 프로젝트에서 AI 개발 도구의 생산성을 활용해 돌파구를 찾고 성과를 만들어 낸 경험을 공유드립니다. 안녕하세요, GS 리테일 검색추천파트의 최원일입니다. 2025년 GS 리테일에 합류해 추천 시스템 전면 재구축 프로젝트를 진행하면서, 다수의 아이템 간(item-to-item, 이하 i2i) 추천 구좌가 공통으로 의존하는 핵심 모델이 있다는 사실을 알게 됐습니다. 이 모델의 성능을 개선하면 현재 운영 중인 여러 추천 영역의 비즈니스 지표도 함께 개선될 가능성이 높다고 판단해 프로젝트를 시작했습니다. 기존 i2i 모델은 ItemCF 계열의 통계 기반 머신러닝 모델입니다. 수년간 온라인 테스트에서 검증되며 좀처럼 이기기 어려운 강력한 베이스라인으로 자리 잡았습니다. 구현·운영 비용이 낮고 성능과 커버리지도 준수해, 시대별 SOTA 모델과의 경
조 게비아가 이끄는 백악관 내셔널 디자인 스튜디오가 미국 연방 조달청과 협업한 America.gov 웹사이트입니다. 미국 정부는 이 사이트를 연방 정보와 서비스를 찾는 단일 디지털 입구로 설명했습니다. America.gov는 사용자가 메뉴를 따라가지 않고 질문을 입력하는 방식으로 작동합니다. 답변은 공식 정부 웹사이트 정보를 바탕으로 제공됩니다. 사이트 설명에 따르면 2만 9천 개 이상의 정부 웹사이트 정보를 검색해 여권, 사회보장, 복지, […] Source
WORXPHERE 하이어링 센터에서 시작해 잡코리아로 확장한 지원자 관리 개편기 안녕하세요, 프로덕트 디자이너 김정민입니다. 이번 글에서는 하이어링 센터에서 시작해 잡코리아까지 이어진 지원자 관리 개편 과정을 소개합니다. PM·엔지니어와 함께 전반적인 제품 경험을 설계하며, 익숙한 서비스를 새롭게 바꾸기 위해 어떤 고민과 선택이 있었는지, 그 과정을 함께 봐주시면 좋겠습니다. 01. 문제 정의 가장 많이 쓰는 화면에서 발생하는 채용 경험의 단절 공고 등록 이후, 잡코리아에서 기업 회원이 가장 많이 방문하는 화면이 어디일까요? 바로 ‘지원자 관리’ 화면입니다. 최근 6개월 기준, 기업 서비스 전체 PV의 약 90%가 이 화면에서 발생할 만큼 사용 빈도가 높은 핵심 영역이죠. 하지만 핵심 화면임에도 불구하고, 기존의 지원자 관리는 지원자 목록 검색과 이력서 열람 정도의 기초적인 기능만 제공하고 있었습니다. 채용 담당자는 이력서를 확인한 이후의 채용 과정을 플랫폼 내에서 이어가기 어려웠고, 일부 업무를 외부 도구에 의존해야 했습니다. 이러한 채용 업무의 단절을 개선하고 플랫폼 내 경험을 완결 짓기 위해 채용 여정(ATS) 개편을 진행했습니다. 02. 개편 방향 하이어링 센터에서 시작한 ATS 개편을 잡코리아로 확장 이번 지원자 관리(ATS) 개편은 하이어링 센터에 구축한 지원자 관리 경험을 기존 잡코리아 기업 서비스로 확장하는 작업이었습니다. 하이어링 센터의 구조와 사용 경험을 기본 뼈대로 가져오되, 기존 잡코리아에서 제공하던 핵심 기능과 데이터를 통합해야 했죠. 단순히 새로운 화면을 옮기는 것이 아니라, 기존 사용자의 익숙한 업무 방식과 기능을 유지하면서 잡코리아의 지원자 관리 경험 전체를 하이어링 센터의 ATS 구조로 전환하는 과정이었습니다. 03. 데이터 분석 단순 마이그레이션을 넘어선 UX 개선의 필요성 개편에 앞서 최근 1년간 기업 회원의 활동 데이터를 살펴봤습니다. 그 결과, 전체 지원 건수 중 실제 채용 단계가 변경된 비율은 8.4%에 불과했는데요, 칸반 뷰, 팀 협업, 평가 도구 등을 제공하는 나인하이어의 채용 진행률이 29%인 것과 비교하면 약 3.5배 낮은 수준이었습니다. (*잡코리아: 2024.9~2025.9 / 나인하이어: 2026.3~2026.5 기준) 더 주목한 것은 결과 통보율이었는데요, 전체 지원자의 약 94%가 채용 결과를 통보받지 못하고 있었습니다. 두 지표를 함께 살펴보며, 플랫폼 안에서 채용 프로세스를 이어가기 어려운 구조가 낮은 채용 진행률과 결과 통보율에 영향을 미치고 있을 것이라는 가설을 세웠습니다. 이는 단순히 기업 회원의 업무 효율에 그치는 문제가 아니라, 장기적으로 지원자의 구직 경험과 플랫폼에 대한 신뢰에도 영향을 줄 수 있다고 판단했습니다. 04. 설계 원칙 파편화된 채용 업무를 하나의 흐름으로 연결 기존 화면을 분석해 보니, 버튼 배치나 레이아웃 같은 개별 UI 요소보다 채용 업무의 흐름이 곳곳에서 끊긴다는 문제점에 있었습니다. 대표적인 사례가 다중 선택 기능이었습니다. 여러 지원자를 선택하면, 목록과 액션 패널이 화면 양쪽으로 떨어져 있어 시선 이동이 잦았고, 뷰포트가 좁아지면 우측 패널이 화면 밖으로 밀려나는 문제도 있었습니다. 정보를 확인하는 과정에서도 비슷한 문제가 있었는데요, 과거 면접 제안 내역을 확인하려면 다시 ‘면접 제의’ 버튼을 눌러야 하는 구조였습니다. 정보를 조회하기 위해 실행 버튼을 거쳐야 하는 구조로 인해 조회와 실행의 맥락이 뒤섞여 있었고, 사용자가 현재 상태와 다음 행동을 직관적으로 파악하기 어려웠습니다. 결국 필요한 것은 개별 UI를 보기 좋게 다듬는 것이 아니라, 이력서 검토부터 심사, 커뮤니케이션, 일정 조율까지 각 채용 업무가 맥락을 잃지 않고 자연스럽게 이어지는 흐름을 만드는 것이었습니다. 이를 이번 개편의 핵심 설계 목표로 삼았습니다. 05. 경험의 확장 리스트의 익숙함을 유지한 듀얼 뷰와 벌크 액션 지원자 관리는 기업 회원의 사용 빈도가 높은 핵심 메뉴입니다. 그만큼 인터페이스의 급격한 변화는 기존 사용자의 업무 루틴을 깨뜨리고
“배포해줘” 한 줄로 끝나는 배포 — 전 직원이 쓰는 사내 플랫폼 구축기 글. 이단비(Tabie) / Service Factory팀 안녕하세요, 여기어때컴퍼니 Service Factory팀 타비입니다. 올해 초 팀을 옮긴 후 받은 첫 과제는 바이브코딩으로 서비스를 하나 만들어보는 것이었습니다. 여행 유튜브 영상을 AI가 요약해서 숙소 검색까지 이어주는 작은 웹 서비스를 단 며칠 만에 완성했습니다. 하지만 진짜 문제는 다 만든 다음이었습니다. 팀원들에게 결과물을 보여주려면 노트북 화면 공유만으로는 한계가 있었습니다. 결국 외부 호스팅 서비스에 결과물을 배포하고 링크를 공유했지만, 마음 한구석이 계속 불편했습니다. ‘사내에서 만든 결과물을 사외 서비스에 올려도 괜찮은 걸까’ 하는 의문 때문이었습니다. 문득 둘러보니 이는 저 혼자만의 문제가 아니었습니다. 당시는 회사가 전사적으로 AI와 바이브코딩을 막 확산하기 시작한 시기였습니다. 사외 서비스에 배포된 개인 작업물 링크들이 사내에 파편화되어 공유되는 모습이 눈에 들어왔고, 처음에는 이를 한곳에 모아두는 ‘갤러리 플랫폼’을 떠올렸습니다. 하지만 기획을 파고들수록 사외 서비스 파편화의 본질이 보였습니다. 바이브코딩 덕분에 비개발자 동료들도 서비스 ‘구축’까지는 가능해졌지만, 정적 웹 하나조차 사내망에 띄우지 못해 결국 사외 호스팅을 찾고 있었던 것입니다. 개발자인 저에게도 인프라 신청 절차가 높은 허들로 느껴지는데, 비개발 직군 동료들에게 배포는 넘을 수 없는 장벽이자 인프라 지식을 갖춘 개발자만의 영역으로 남아있었습니다. 갤러리에 모으는 건 다음 문제였습니다. 애초에 비개발자 동료들이 만든 결과물을 사내에 어떻게 쉽게 배포할 것인가가 먼저 풀어야 할 진짜 숙제였습니다. 목표가 완전히 바뀌었습니다. 지금 필요한 것은 갤러리가 아니라 ‘배포’ 그 자체였습니다. 외부 서비스를 빌리지 않고 딸깍 한 번으로 배포되는 사내 전용 플랫폼, 그렇게 바이브독 프로젝트가 시작되었습니다. 이 글에서는 사내 배포 플랫폼 바이브독을 만들고 운영해 온 과정을 정리합니다. 배포 과정에서 사용자가 느껴온 허들을 어떻게 하나씩 허물었는지, 그 편의를 위해 시스템은 무엇을 감당해야 했는지 차례로 이야기해 보겠습니다. 첫 커밋에서 첫 사용자 유입까지 7일 4월 초 전체 아키텍처의 밑그림을 그리고 인프라 구성을 요청했습니다. 복잡한 쿠버네티스 환경을 구축하는 대신, 서버 한 대에 바이브독을 올리는 심플한 정적 웹 호스팅 구조로 시작했습니다. 예상 트래픽이 사내 규모에 불과했고, 잠깐 서버가 멈춰도 고객 서비스에는 영향이 없는 내부용 워크로드였기 때문입니다. 초기 아키텍처를 잡을 때 위협 모델(Threat Model)도 함께 정의했습니다. 대전제는 ‘사용자는 신뢰할 수 있는 사내 구성원이며, 주된 위협은 외부의 악의적 공격보다 실수나 호기심에서 비롯된 보안 누출’이라는 점이었습니다. 이에 따라 제로 트러스트나 오토스케일링 같은 오버스펙은 과감히 덜어내고 당장 필요한 배포 기능에만 집중했습니다. 인프라 세팅이 완성되기를 기다리지 않고 바로 개발에 착수해 4월 8일 첫 커밋을 올렸고, 정확히 일주일 뒤인 15일에 개발 환경을 오픈했습니다. 첫 커밋 이후 단 7일 만에 배포가 되는 최소한의 뼈대만 만들어 열었던 셈입니다. 당장 동작하는 결과물로 사용자의 실제 반응을 보며 방향을 잡아나가는 바이브코딩의 철학을 그대로 적용했습니다. 첫 버전에 탑재한 핵심 기능은 코드를 받아 빌드하고 배포된 서비스 URL을 돌려주는 것 하나였으며, 이 단순한 시작은 이후 두 가지 큰 줄기로 발전하게 됩니다. 배포: 코드를 받아 서비스로 띄워주는 역할 API 프록시: 그 서비스가 외부 API나 DB를 호출할 때 대신 인증해 불러주는 역할 CLI에서 “배포해줘”로 개발 환경을 오픈한 날 비개발자 동료에게 CLI 배포 방법을 안내했지만, 이는 또 하나의 큰 장벽이었습니다. 표면적으로는 두 줄의 명령어였지만 터미널을 열고, 도구를 설치하고, 인증을 거치는 기반 환경 구축 자체가 ‘배포’가 아닌 또 다른 학습 과제였기 때문입니다. 사용자 피드
글. 박수봉(Henby) / Experience Development팀 안녕하세요. Experience Development팀 헨비(henby)입니다. 9월 7일, 여기어때의 해외투어 서비스를 오픈했습니다~ 그 동안 짧지만 밀도 높은 QA 기간을 보냈습니다. 프론트엔드 개발자는 총 두 명이었고, 저희는 웹과 웹뷰 모두를 처리하였고 저는 카테고리홈·상품 상세·주문서·예약내역·해외투어용 채팅을 맡았습니다. 또한 예약내역 탭·찜 탭·회원탈퇴처럼 여러 서비스가 함께 쓰는 공통 화면도 담당했습니다. 이 기간 동안 제게 배정된 QA 티켓은 총 280건이었습니다. 이 글에서는 이 280건을 AI 에이전트와 어떻게 처리했는지, 도움이 됐던 지점과 실패를 극복한 지점을 함께 정리해 보겠습니다. 1. 280건을 처리한 속도 이번 해외투어의 담당 QA티켓 280건은 전부 처리했습니다. 아주 빠르게요! 티켓이 들어온 날부터 처리될 때까지 걸린 시간을 재 보니, 절반 이상(56%)은 하루 만에 처리 됐고 10건 중 8건(81%)은 3일 안에 처리됐습니다. 하루에는 많게는 20건, 한 주에는 66건까지 티켓이 들어오기도 했습니다. 이 리드타임에는 QA와 PO의 검증 시간까지 들어 있습니다. 순수 개발 시간만 따로 보면 더 짧게 나올 겁니다. 다만 이번 QA에서 확인하고 싶었던 건 단순한 처리 속도 뿐만아니라 담당 범위의 정의 그리고 티켓 수가 늘어도 재요청 없이 재작업 없이 끝까지 처리할 수 있는 방식이 있는지를 회고 하고 싶습니다. 비교를 위해 티켓이 등록된 날부터 처리된 날까지를 같은 기준으로 계산했습니다. 제가 참여한 세 번의 대규모 QA를 놓고 봤습니다. 2024년 가을 해외숙소 비회원 예약 QA에서는 주문서·예약 완료·예약 내역·조회 흐름을 맡았습니다. 총 77건 중 23%를 하루만에, 48%를 3일 안에 처리했습니다. 2025년 봄 패키지여행 QA에서는 웹 PDP·홈 검색 영역·채팅을 맡았고, 총 55건 중 42%를 하루만에, 62%를 3일 안에 처리했습니다. 이번 해외투어 QA에서는 앱과 웹을 합쳐 일곱 개가 넘는 역대급 영역을 맡았습니다. 총 280건 중 56%를 하루만에, 81%를 3일 안에 처리했습니다. 프로젝트 성격과 QA 인원, 검증 흐름이 매번 같았던 것은 아닙니다. 그래서 이 수치만으로 AI가 속도를 높였다고 단정할 수는 없습니다. 다만 담당 범위와 들어오는 티켓 수가 커진 상황에서도 해결까지 걸린 시간이 줄었다는 점은 분명했습니다. 이 글에서는 그 차이를 만든 작업 방식을 정리하려 합니다. 사람은 원인과 방향을 판단하고, 에이전트는 재현·조사·기록처럼 확인에 드는 시간을 줄였습니다. 2. QA 티켓의 파이프라인 티켓 하나는 다섯 단계를 거칩니다. 먼저 티켓과 함께 제가 재현한 상황과 티켓에 적히지 않은 추가 정보를 에이전트에게 전달합니다. Local에서 재현하여 의심가는 구석이나 상세한 재현경로, 어떤 플랫폼에서 일어나는지 꼭 주세요! 아니라면 또 다른 재작업이 분명 생깁니다! 에이전트는 Jira에서 티켓 본문과 첨부를 읽고, 브라우저 자동화나 시뮬레이터로 문제를 다시 재현합니다. 콘솔·네트워크·적재 로그를 살펴 원인을 추적한 뒤 수정안을 제안합니다. 저는 원인과 제안이 맞는지 확인하고, 필요하면 정보를 더 보태 방향을 잡습니다. 수정이 끝나면 로컬에서 함께 확인 후 티켓 번호 규칙에 맞춰 커밋한 뒤 개발 환경에 배포합니다. 이 과정에서 저는 두 가지를 판단합니다. 에이전트가 짚은 원인이 맞는지, 그 수정안으로 반영할지, 재현·원인 추적·커밋은 에이전트가 맡습니다. 예를 들어 주문서 상세주소 칸에 한글이 입력되지 않는 티켓이 있었습니다. 재현 영상을 함께 전달하자, 에이전트는 입력 필터가 완성형 한글만 허용해 자모가 조합되는 중간 상태의 입력을 모두 막는다는 걸 찾아냈습니다. 완성형 검사 조건을 더 촘촘히 하자는 첫 제안은 IME 조합 자체를 무너뜨릴 수 있어 반려했습니다. 대신 자모까지 허용하도록 다시 제안받아 수락했고, 로컬에서 한글 조합이 정상적으로 되는 것을 확인한 뒤 배포했습니다. 이 과정에서 재작업을