<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>GS리테일 DX블로그</title>
    <link>https://gsretail.tistory.com/</link>
    <description>GS리테일이 만들어가는 다양한 DX(Digital Transformation) 경험을 소개합니다.</description>
    <language>ko</language>
    <pubDate>Thu, 23 Jul 2026 09:14:55 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>GS리테일</managingEditor>
    <image>
      <title>GS리테일 DX블로그</title>
      <url>https://tistory1.daumcdn.net/tistory/4989123/attach/58a7f5e31e36487fa2ff16ba2d38e9a7</url>
      <link>https://gsretail.tistory.com</link>
    </image>
    <item>
      <title>[사내 지식 AI 만들기 ⑤&amp;middot;수집] 좋은 답변의 90%는 검색 전에 결정된다 &amp;mdash; Notion 회사와는 차원이 다른 20년치 수집</title>
      <link>https://gsretail.tistory.com/95</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1998&quot; data-origin-height=&quot;882&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tPH10/dJMcabSn8uU/4cDoq9AyMaWhWALMT6cVXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tPH10/dJMcabSn8uU/4cDoq9AyMaWhWALMT6cVXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tPH10/dJMcabSn8uU/4cDoq9AyMaWhWALMT6cVXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtPH10%2FdJMcabSn8uU%2F4cDoq9AyMaWhWALMT6cVXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1998&quot; height=&quot;882&quot; data-origin-width=&quot;1998&quot; data-origin-height=&quot;882&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;GIGO, 그런데 우리 건 차원이 다르다&lt;/h2&gt;
&lt;p&gt;RAG에는 오래된 격언이 있다. &lt;strong&gt;&amp;quot;쓰레기를 넣으면 쓰레기가 나온다(Garbage In, Garbage Out).&amp;quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;그런데 사내 지식은 — 쓰레기인지 아닌지조차 애매했다. 작년에 폐기된 규정인데 멀쩡해 보이는 문서, 부서마다 다르게 부르는 용어, 같은 내용이 세 군데에 흩어진 중복, 그리고 &lt;em&gt;절대 새어 나가면 안 되는 개인정보&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;1탄~4탄에서 검색·권한·대화·채널을 아무리 잘 만들어도, 들어온 지식이 엉망이면 답도 엉망이다. &lt;strong&gt;좋은 검색의 대부분은 검색 알고리즘이 아니라 _수집 단계_에서 결정된다.&lt;/strong&gt; 그리고 개인정보 한 건이 새어나가면 그건 &amp;quot;틀린 답변&amp;quot;이 아니라 &lt;strong&gt;보안 사고&lt;/strong&gt;다. 사내 지식은 &amp;quot;얼마나 정확한가&amp;quot;와 &amp;quot;얼마나 위험한가&amp;quot;를 동시에 조심해야 하는, 일반 GIGO보다 한 단계 무거운 문제였다.&lt;/p&gt;
&lt;h2&gt;Notion 하나 쓰는 회사 vs 20년 Excel·PPT 쓴 회사&lt;/h2&gt;
&lt;p&gt;다른 회사 이야기를 들으면 부러울 때가 있다. 처음부터 지식을 &lt;strong&gt;Notion 하나&lt;/strong&gt; 같은 단일 도구에 모아 쓰는 회사는, 도서관을 신축 설계도 한 장으로 짓는 것과 같다. 소스가 하나고, 게다가 &lt;strong&gt;Notion은 태생이 마크다운&lt;/strong&gt; — 텍스트 구조가 이미 깔끔해서 파싱이 거의 공짜다. 서가 규칙이 처음부터 하나다.&lt;/p&gt;
&lt;p&gt;우리는 달랐다. &lt;strong&gt;20년 넘게 Excel·PowerPoint·사내 게시판·메일로 지식을 쌓아온&lt;/strong&gt; 회사였다. 여기서 진짜 난이도는 &amp;quot;소스가 많다&amp;quot;가 아니라 &lt;strong&gt;&amp;quot;20년치 이질적 포맷&amp;quot;&lt;/strong&gt; 자체다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Excel: 표, 병합 셀, 여러 시트, 수식 결과값, 셀 안에 줄바꿈으로 욱여넣은 문단.&lt;/li&gt;
&lt;li&gt;PowerPoint: 텍스트가 도형·표·이미지 안에 흩어져 있고, 발표 흐름은 사람 머릿속에만 있다.&lt;/li&gt;
&lt;li&gt;게다가 &lt;strong&gt;표를 이미지로 캡처해 붙인&lt;/strong&gt; 문서도 흔하다 — 그 안의 글자는 텍스트가 아니라 그림이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Notion 회사가 &amp;quot;책을 그대로 서가에 꽂는&amp;quot; 일이라면, 우리는 &lt;strong&gt;책을 펼쳐 표·도형·이미지에서 글자를 발라내는&lt;/strong&gt; 일부터 해야 했다. 통째로 다시 지을 순 없었다 — 이미 그 안에 20년치 지식이 살고 있었으니까. 그래서 만든 건 &amp;quot;하나의 표준 서가&amp;quot;가 아니라, &lt;strong&gt;소스마다 맞춘 전용 손수레(connector)&lt;/strong&gt; 였다. Confluence, Jira, SharePoint, 게시판, Teams… 소스마다 다른 문·다른 포맷에 맞춰 각각의 connector를 만들고, 그 손수레들이 정해진 시간에 각 소스를 도는 &lt;strong&gt;순회 일정(scheduler)&lt;/strong&gt; 을 짰다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1950&quot; data-origin-height=&quot;814&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vwbZe/dJMcagGgKrS/OF6UrxYRbFInSbDrygTBHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vwbZe/dJMcagGgKrS/OF6UrxYRbFInSbDrygTBHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vwbZe/dJMcagGgKrS/OF6UrxYRbFInSbDrygTBHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvwbZe%2FdJMcagGgKrS%2FOF6UrxYRbFInSbDrygTBHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1950&quot; height=&quot;814&quot; data-origin-width=&quot;1950&quot; data-origin-height=&quot;814&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;검수대(Ingestion Gate)&lt;/h2&gt;
&lt;p&gt;포맷을 발라 텍스트를 얻었다고 끝이 아니다. 도서관에 책을 들이기 전, 검수대를 뒀다. 모든 문서는 색인되기 전에 이 게이트를 통과한다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[소스] → 파싱 → 한국어 전처리 → 청킹 → (검수대: ingestion gate)
                                          ├─ 품질: 너무 짧거나 깨진 문서?
                                          ├─ 보안: PII/기밀? → 격리(quarantine)
                                          └─ 메타: 권한 태깅(tenant/kb/tier/acl)
        → 중복 제거 → 임베딩 → 저장(Qdrant)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1902&quot; data-origin-height=&quot;824&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MhVNC/dJMcadCzZPo/DLlkXGeCpUl4facDQMlkXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MhVNC/dJMcadCzZPo/DLlkXGeCpUl4facDQMlkXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MhVNC/dJMcadCzZPo/DLlkXGeCpUl4facDQMlkXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMhVNC%2FdJMcadCzZPo%2FDLlkXGeCpUl4facDQMlkXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1902&quot; height=&quot;824&quot; data-origin-width=&quot;1902&quot; data-origin-height=&quot;824&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;100G를 통째로 나를 수는 없다 — 분할과 델타&lt;/h2&gt;
&lt;p&gt;소스 하나가 워낙 커서(대용량), 손수레로 한 번에 다 나르려면 트럭 몇 대로도 부족했다. 두 가지를 했다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;분할(partition)&lt;/strong&gt;: 큰 자료 뭉치를 통째로 나르지 않고, 감당할 수 있는 단위로 쪼개서 나른다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;델타(delta)&lt;/strong&gt;: 매번 소스 전체를 다시 뒤지지 않는다. fingerprint로 &lt;strong&gt;지난번과 달라진 부분만&lt;/strong&gt; 골라 옮긴다 — 안 그러면 순회할 때마다 도서관 하나를 통째로 다시 옮기는 셈이 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;946&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2g2ax/dJMcahyl6cy/Winvcd2hEJexgLJ6lzoObk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2g2ax/dJMcahyl6cy/Winvcd2hEJexgLJ6lzoObk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2g2ax/dJMcahyl6cy/Winvcd2hEJexgLJ6lzoObk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2g2ax%2FdJMcahyl6cy%2FWinvcd2hEJexgLJ6lzoObk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2000&quot; height=&quot;946&quot; data-origin-width=&quot;2000&quot; data-origin-height=&quot;946&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;여러 소스를 돌다 보면 같은 문서가 이름만 바꾼 채 여러 곳에 꽂혀 있는 것도 발견한다 — 그대로 다 꽂으면 사용자는 같은 답을 세 번 받거나, 서로 다른 버전의 답을 받는다. 그래서 서가에 꽂기 전, 마지막으로 한 번 더 골라내는 절차(중복 제거)를 거친다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;수집 스택:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;소스 connector : Confluence / Jira / SharePoint / 사내 게시판 / Teams — 소스별 어댑터
포맷 파싱      : Excel / PPT / PDF / 문서 — 표·도형·이미지에서 텍스트 추출
증분 크롤      : fingerprint 기반 변경분만 재수집
워크플로       : Temporal(스케줄·재시도·크롤 상태 추적)
PII 스크럽     : 정규 포맷 + 우회 케이스(하이픈 없는 번호 등) 규칙 엔진
중복 제거      : 해시 → 근사중복 → 의미중복 다단계 파이프라인
임베딩/저장    : 청킹 → 임베딩(OpenAI) → Qdrant(1탄의 통합 컬렉션, 권한 태그 포함)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1900&quot; data-origin-height=&quot;836&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOhW32/dJMcag0rp1w/xIzHPKYI7OfSQCcH1BUhvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOhW32/dJMcag0rp1w/xIzHPKYI7OfSQCcH1BUhvk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOhW32/dJMcag0rp1w/xIzHPKYI7OfSQCcH1BUhvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOhW32%2FdJMcag0rp1w%2FxIzHPKYI7OfSQCcH1BUhvk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1900&quot; height=&quot;836&quot; data-origin-width=&quot;1900&quot; data-origin-height=&quot;836&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;심화 — 검수대는 무엇을 막고, 우리는 어디서 데였나&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;이 절은 깊다. 검수대가 실제로 어떻게 판정하고, 대용량 수집이 어디서 터졌는지 궁금한 분을 위한 detail이다. 바쁘면 체크리스트로 건너뛰어도 좋다.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;① 검수대 판정 — 무엇을 막고, 무엇을 통과시키나&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;게이트는 결과를 네 갈래로 나눈다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if verdict in {보안 위반: PII·기밀}:     action = QUARANTINE   # 색인 안 함, 격리
elif core_fail &amp;gt;= 2:                     action = REJECT       # 핵심 품질 다중 실패
elif core_fail == 1:                     action = HOLD         # 재작업 여지
elif core_warn:                          action = PROCEED      # 로그만, 색인은 진행 (아래 ②)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;핵심은 &lt;strong&gt;보안 위반(PII·기밀)만 색인을 막는 하드 블록(격리)&lt;/strong&gt; 이고, 나머지 품질 문제는 정도에 따라 REJECT/HOLD로 나뉜다는 것. &amp;quot;정확도&amp;quot;와 &amp;quot;위험도&amp;quot;를 같은 잣대로 다루지 않는다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;② 영리한 선택 — 경미한 경고(WARN)는 색인을 막지 않기로&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;처음엔 품질 경고(WARN)도 색인을 막았다. 그랬더니 문제가 생겼다 — 사소한 경고 하나 때문에 &lt;strong&gt;멀쩡한 문서가 0청크로 저장돼 검색에 안 잡히는&lt;/strong&gt; 일이 벌어졌다. 그래서 정책을 뒤집었다: &lt;strong&gt;Core WARN은 PROCEED(로그만 남기고 색인은 진행)&lt;/strong&gt;. 막아서 얻는 안전보다, 막아서 잃는 &amp;quot;있는데 안 나오는 지식&amp;quot;이 더 컸기 때문이다. 게이트의 목적은 &amp;quot;완벽한 것만 통과&amp;quot;가 아니라 &amp;quot;위험한 것만 차단&amp;quot;이었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1922&quot; data-origin-height=&quot;476&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bi1DCn/dJMcah6fcpN/1zSpgYuXkxA54w9Woshmk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bi1DCn/dJMcah6fcpN/1zSpgYuXkxA54w9Woshmk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bi1DCn/dJMcah6fcpN/1zSpgYuXkxA54w9Woshmk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbi1DCn%2FdJMcah6fcpN%2F1zSpgYuXkxA54w9Woshmk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1922&quot; height=&quot;476&quot; data-origin-width=&quot;1922&quot; data-origin-height=&quot;476&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;③ 숫자, 정직하게&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;여기도 자랑할 실측 %는 없다. 아래 ④의 사고를 고친 뒤 &amp;quot;0청크 → 정상 청크 + 한글 근거 복원&amp;quot;을 확인한 정성적 결과가 전부다. 없는 숫자는 안 만든다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;④ 우리가 처음엔 틀렸다 — chunks=0의 진범은 파일명 길이였다&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;대용량 재적재 중, 어떤 소스의 문서들이 &lt;strong&gt;인제스트했는데 청크가 0개&lt;/strong&gt;로 나왔다. 원인을 다섯 번 오진했다: PostgreSQL 갭 → S3 키 불일치 → 버킷 IAM 권한 → boto3 버전 → 인코딩(ASCII rekey). 다 아니었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1340&quot; data-origin-height=&quot;848&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbIQZN/dJMcado6MIT/TjZvmVLlqX6mNmIuo9DkBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbIQZN/dJMcado6MIT/TjZvmVLlqX6mNmIuo9DkBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbIQZN/dJMcado6MIT/TjZvmVLlqX6mNmIuo9DkBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbIQZN%2FdJMcado6MIT%2FTjZvmVLlqX6mNmIuo9DkBK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;604&quot; height=&quot;382&quot; data-origin-width=&quot;1340&quot; data-origin-height=&quot;848&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;진범은 어이없게도 &lt;strong&gt;파일명 길이&lt;/strong&gt;였다. 리눅스 파일시스템의 파일명 한계는 &lt;strong&gt;255바이트&lt;/strong&gt;인데, 그 소스의 한글 파일명은 인코딩하면 283바이트로 그 한계를 넘었다. 그래서 다운로드가 로컬에 저장되는 순간 &lt;code&gt;ENAMETOOLONG&lt;/code&gt;으로 실패했는데 — 이걸 넓은 &lt;code&gt;except: continue&lt;/code&gt;가 삼키면서 겉으로는 &lt;strong&gt;&amp;quot;S3 object not found&amp;quot;&lt;/strong&gt; 로 위장됐다. 있는 파일을, 없다고 보고하고 있었던 것이다.&lt;/p&gt;
&lt;p&gt;고친 방식: 다운로드 로컬 파일명을 원본 키 대신 &lt;strong&gt;짧은 해시(sha256 앞 16자)&lt;/strong&gt; 로 쓰고, 사용자에게 보일 제목(한글 citation)은 원본 키에서 따로 유도했다. 그리고 그 broad except의 마스킹을 걷어내 진짜 에러가 드러나게 했다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# S3 키 basename이 로컬 255바이트 한계를 넘으면 ENAMETOOLONG →
# 이전엔 &amp;quot;S3 object not found&amp;quot;로 위장됐다. 짧은 해시명으로 우회.
safe_name = hashlib.sha256(key.encode(&amp;quot;utf-8&amp;quot;)).hexdigest()[:16] + Path(key).suffix&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;교훈 두 개. &lt;strong&gt;하나의 증상(chunks=0)이 다섯 개의 서로 다른 원인을 가릴 수 있다.&lt;/strong&gt; 그리고 &lt;strong&gt;넓은 &lt;code&gt;except&lt;/code&gt;는 사고를 고치는 게 아니라 숨긴다&lt;/strong&gt; — 3탄에서 본 &amp;quot;같은 증상, 다른 원인&amp;quot;이 수집 파이프라인에서 다시 나타난 셈이다.&lt;/p&gt;
&lt;h2&gt;들이기 전에 고민한 것들 (체크리스트)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PII redaction&lt;/strong&gt; — 주민번호·카드·전화·이메일을 &lt;em&gt;들어오기 전에&lt;/em&gt; 스크럽한다. 표준 포맷뿐 아니라 &lt;em&gt;우회 케이스&lt;/em&gt;(하이픈 없는 번호, 공백 구분, 국제 포맷)까지. 한 번 새면 영속 저장소에 남는다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;중복(dedup)&lt;/strong&gt; — 같은 문서가 여러 소스에 → 다단계 파이프라인으로 거른다(해시 → 근사 중복 → 의미 중복 → 충돌 탐지).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;신선도(freshness)&lt;/strong&gt; — 오래된 규정이 최신처럼 답하면 그게 사고다. 소스별 신선도 SLA를 두고, 늦으면 경보·재수집.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;권한 메타&lt;/strong&gt; — &lt;em&gt;수집 시점에&lt;/em&gt; 출입증(2탄의 tenant/kb/tier)을 박아야 한다. 검색 시점에 뒤늦게 권한을 붙일 수 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;970&quot; data-origin-height=&quot;1042&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uAcGV/dJMcaa0gUtf/yKcamKZZdRVZNAzt5OJy51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uAcGV/dJMcaa0gUtf/yKcamKZZdRVZNAzt5OJy51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uAcGV/dJMcaa0gUtf/yKcamKZZdRVZNAzt5OJy51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuAcGV%2FdJMcaa0gUtf%2FyKcamKZZdRVZNAzt5OJy51%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;460&quot; height=&quot;494&quot; data-origin-width=&quot;970&quot; data-origin-height=&quot;1042&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;한 줄로&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;좋은 답변은 좋은 검색에서, 좋은 검색은 좋은 저장에서, 좋은 저장은 — &lt;strong&gt;좋은 수집&lt;/strong&gt;에서 시작한다.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;h2&gt;시리즈를 마치며&lt;/h2&gt;
&lt;p&gt;저장(1) → 권한(2) → 대화(3) → 채널(4) → 그리고 그 모든 것의 출발점, 수집(번외). 한 바퀴를 돌았다.&lt;/p&gt;
&lt;p&gt;우리가 내내 붙잡은 원칙 하나로 닫는다: &lt;strong&gt;구조를 만드는 것은 시작이지 끝이 아니다.&lt;/strong&gt; &amp;quot;저장이 잘 됐나?&amp;quot;가 아니라 &lt;strong&gt;&amp;quot;각 사용자의 질문에 근거 있게 답했나?&amp;quot;&lt;/strong&gt; 를 — 실제 사용자가, 측정된 품질로, 운영 경로에서 증거와 함께 — 확인할 때, 비로소 완료다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;시리즈&lt;/strong&gt;: &lt;a href=&quot;https://gsretail.tistory.com/89&quot;&gt;1탄 저장&lt;/a&gt; · &lt;a href=&quot;https://gsretail.tistory.com/90&quot;&gt;2탄 권한&lt;/a&gt; · &lt;a href=&quot;https://gsretail.tistory.com/92&quot;&gt;3탄-1부 대화&lt;/a&gt; · &lt;a href=&quot;https://gsretail.tistory.com/93&quot;&gt;3탄-2부 대화&lt;/a&gt; · &lt;a href=&quot;https://gsretail.tistory.com/94&quot;&gt;4탄 채널&lt;/a&gt; · &lt;strong&gt;번외 수집 (이 글)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock undefined&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;22787.jpg&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;960&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/02zUJ/btsMAMg3Wtb/7LuKJYntKKZdzNzAcaQAs0/tfile.dat&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/02zUJ/btsMAMg3Wtb/7LuKJYntKKZdzNzAcaQAs0/tfile.dat&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/02zUJ/btsMAMg3Wtb/7LuKJYntKKZdzNzAcaQAs0/tfile.dat&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F02zUJ%2FbtsMAMg3Wtb%2F7LuKJYntKKZdzNzAcaQAs0%2Ftfile.dat&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;80&quot; height=&quot;960&quot; data-filename=&quot;22787.jpg&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;960&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;김헌기 Darion&lt;/strong&gt; · AX본부 &amp;gt; AI데이터부문 &amp;gt; AI혁신지원팀&lt;/p&gt;
&lt;p&gt;AI 및 공통 Tech 기반의 기술 표준화 업무를 수행하고 있습니다. 동료들과 함께 기술 문화 만들기와 낯선 기술자와의 인연의 시작에 관심이 많습니다.&lt;/p&gt;</description>
      <category>Data&amp;amp;AI</category>
      <author>DarionKim</author>
      <guid isPermaLink="true">https://gsretail.tistory.com/95</guid>
      <comments>https://gsretail.tistory.com/95#entry95comment</comments>
      <pubDate>Sun, 12 Jul 2026 09:59:58 +0900</pubDate>
    </item>
    <item>
      <title>사내 지식 AI 만들기 ④&amp;middot;채널] 모바일 앱을 또 만들 뻔했다 &amp;mdash; 채널은 글로벌 업체를 못 이긴다, 그래서 Thin 플랫폼</title>
      <link>https://gsretail.tistory.com/94</link>
      <description>&lt;h2&gt;우리가 만든 앱, 그리고 폐기한 앱&lt;/h2&gt;
&lt;p&gt;솔직히 고백하면 — 우리는 모바일 앱을 만들었다. 포털도 만들었다. 그리고 &lt;strong&gt;폐기했다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;이유는 단순하고 아팠다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;사용자는 우리 앱에 안 들어왔다. 이미 &lt;strong&gt;Teams에 살고 있었다.&lt;/strong&gt;&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;좋은 지식 AI를 만드는 것과, 사용자가 그걸 쓰게 만드는 것은 완전히 다른 일이었다. 멋진 새 집(앱)을 지었는데, 사용자는 이사 올 생각이 없었다. 하루 종일 일하는 곳은 워크스페이스(Teams, Google Chat)였으니까.&lt;/p&gt;
&lt;h2&gt;채널은 글로벌 업체를 못 이긴다 — 그래서 Thin 플랫폼&lt;/h2&gt;
&lt;p&gt;방향을 틀면서 우리가 인정한 게 하나 있다. &lt;strong&gt;채널 그 자체(메신저 UX, 알림, 첨부, 카드 렌더링…)는 글로벌 업체가 수십 년 투자한 영역이고, 우리가 그 수준으로 만들 수 없다.&lt;/strong&gt; Teams를, Google Chat을 우리가 다시 만들 수는 없다.&lt;/p&gt;
&lt;p&gt;그리고 하나에 &lt;strong&gt;락인(lock-in)&lt;/strong&gt; 되는 것도 위험했다. 한 플랫폼에 올인하면 그 플랫폼 정책 하나에 서비스가 흔들린다.&lt;/p&gt;
&lt;p&gt;그래서 택한 게 &lt;strong&gt;Thin 플랫폼&lt;/strong&gt;이다 — 채널을 _소유_하지 않는다. 대신 각 채널에 얇게 연결만 하고, 무거운 지능(검색·권한·근거·rerank)은 우리 쪽 공통 substrate에 둔다. 채널은 갈아 끼울 수 있는 얇은 어댑터가 되고, 우리는 벤더와 경쟁하는 대신 그 위에 올라탄다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;        [디지털 동료]  (1~3탄: 저장 · 권한 · 대화)
             │  공통 substrate (검색/권한/rerank/근거)   ← 무겁게, 우리가 소유
   ┌─────────┼──────────┬───────────┐
 Teams봇   Google Chat   Outlook    A2A(에이전트 연동)    ← 얇게, 갈아끼움&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;882&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d3QtVn/dJMcahZnk81/Gpt3Jl0uBFj7tFr1L1L5w0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d3QtVn/dJMcahZnk81/Gpt3Jl0uBFj7tFr1L1L5w0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d3QtVn/dJMcahZnk81/Gpt3Jl0uBFj7tFr1L1L5w0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd3QtVn%2FdJMcahZnk81%2FGpt3Jl0uBFj7tFr1L1L5w0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;450&quot; height=&quot;435&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;882&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;디지털 동료 하나 → 채널 N개&lt;/h2&gt;
&lt;p&gt;Thin 플랫폼의 보상은 여기서 나온다. 신원 확인과 UX 포장을 채널별로 한 번씩만 풀어두면, 그 다음부터는 —&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;디지털 동료 하나를 추가하면&lt;/strong&gt; 이미 연결된 모든 채널에 동시에 나타난다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;채널 하나를 연결하면&lt;/strong&gt; 이미 있는 모든 동료가 그 채널에서 한 번에 쓸 수 있게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;동료 M명 × 채널 N개를 M×N번 따로 만드는 게 아니라, &lt;strong&gt;M + N번만 만들면 되는 구조&lt;/strong&gt;다. 이게 &amp;quot;직접 UI를 안 만든다&amp;quot;가 단순 비용 절감을 넘어 _구조적 레버리지_가 되는 지점이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1908&quot; data-origin-height=&quot;906&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Sfo7F/dJMcaf8iwfg/73yhF3Vyd9lPDQuZFyTZrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Sfo7F/dJMcaf8iwfg/73yhF3Vyd9lPDQuZFyTZrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Sfo7F/dJMcaf8iwfg/73yhF3Vyd9lPDQuZFyTZrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSfo7F%2FdJMcaf8iwfg%2F73yhF3Vyd9lPDQuZFyTZrk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1908&quot; height=&quot;906&quot; data-origin-width=&quot;1908&quot; data-origin-height=&quot;906&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;같은 답, 다른 얼굴&lt;/h2&gt;
&lt;p&gt;인증만 채널마다 다른 게 아니었다. 같은 질문에 같은 근거로 답해도, 그걸 _보여주는 방식_은 채널마다 달라야 했다. Teams에선 풍부한 카드(Adaptive Card)로, Google Chat에선 그 채널의 카드 포맷으로, 사람이 보지 않는 에이전트 연동 채널에선 애초에 &amp;quot;보여줄&amp;quot; 필요 없이 구조화된 데이터로 — 같은 답을 그 채널이 이해하는 언어로 다시 포장한다.&lt;/p&gt;
&lt;p&gt;여기서 데인 교훈 하나: &lt;strong&gt;pod에서 함수로 찍어 본 게 사용자 화면이 아니다.&lt;/strong&gt; 이건 그냥 넘어갈 얘기가 아니라 심화에서 따로 다룬다.&lt;/p&gt;
&lt;h2&gt;직접 UI를 안 만든다는 원칙&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;모바일·포털은 폐기. &lt;strong&gt;워크스페이스 플랫폼 + 채널 + 디지털 동료 연결&lt;/strong&gt;로 통합.&lt;/li&gt;
&lt;li&gt;새 기능 = 새 화면을 또 만드는 게 아니라, 기존 채널에 동료의 능력을 더하는 것.&lt;/li&gt;
&lt;li&gt;운영 작업(관리자)은 별도 UI 대신 CLI·슬래시 명령으로.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;우리는 _프론트엔드를 다시 만드는 일_을 줄이고, _동료의 능력_에 집중할 수 있게 됐다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2050&quot; data-origin-height=&quot;688&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnF7Ld/dJMcagGgKdR/Z8l8aK1kMenpqpukNFMKT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnF7Ld/dJMcagGgKdR/Z8l8aK1kMenpqpukNFMKT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnF7Ld/dJMcagGgKdR/Z8l8aK1kMenpqpukNFMKT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnF7Ld%2FdJMcagGgKdR%2FZ8l8aK1kMenpqpukNFMKT0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2050&quot; height=&quot;688&quot; data-origin-width=&quot;2050&quot; data-origin-height=&quot;688&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;심화 — 채널마다 다른 인증, 그리고 렌더링은 화면에서 검증한다&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;이 절은 깊다. 채널을 얇게 연결한다는 게 코드에서 뭘 뜻하는지 궁금한 분을 위한 detail이다. 바쁘면 맺음으로 건너뛰어도 좋다.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;① 같은 &amp;quot;누구인지&amp;quot; 확인인데, grant 타입이 다르다&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;채널을 하나 늘릴 때마다 가장 먼저 부딪힌 건 신원 확인 방식이 제각각이라는 점이었다. 두 개만 나란히 놓아 보자.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Google Chat — 서비스 신원(OIDC) 검증.&lt;/strong&gt; Google이 발급한 OIDC id_token을 우리 쪽 verifier가 검증한다(정해진 발신자 allowlist인 &lt;code&gt;service_account&lt;/code&gt; 모드, 또는 도메인 정책상 허용된 사용자 이메일 토큰). 핵심은 &lt;strong&gt;&amp;quot;이 요청이 신뢰된 발신자(서비스)에서 왔는가&amp;quot;&lt;/strong&gt; 를 토큰으로 확인하는, machine-to-machine에 가까운 모델이다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;에이전트 연동(A2A) — 위임 토큰 교환(OBO).&lt;/strong&gt; 여기선 사람이 채널에 로그인하는 게 아니라, &lt;strong&gt;에이전트가 사용자를 대신해(on-behalf-of)&lt;/strong&gt; 통신한다. 사용자 동의로 얻은 토큰을 downstream 토큰으로 &lt;strong&gt;교환(On-Behalf-Of)&lt;/strong&gt; 해서, 그 위임 신원으로 다음 시스템에 접근한다. authorization-code에서 파생된 &lt;strong&gt;위임(delegated)&lt;/strong&gt; 모델이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;같은 &amp;quot;이 사용자가 누구인지 확인한다&amp;quot;인데, 한쪽은 _서비스 신원을 검증_하고 다른 쪽은 _사용자 위임을 교환_한다 — grant 타입 자체가 다르다. 그래서 채널 하나 = 인증 어댑터 하나였다. (이 위임 교환은 실제로 한 번 크게 데였다 — &lt;code&gt;invalid_grant&lt;/code&gt;가 무더기로 나 별도 원인분석을 했다.) 각 채널의 인증을 2탄의 출입증(payload 권한)에 다시 맞물리는 게 Thin 플랫폼의 진짜 일이었다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;② 영리한 선택 — 채널을 소유하지 않는다&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;기각한 대안은 명확했다: 자체 채널·앱을 만들어 그 안에서 모든 걸 통제하기(모바일·포털이 그거였고, 폐기했다). Thin 플랫폼은 그 반대다 — 채널 UX는 벤더에게 맡기고, 우리는 그 위에 얇은 어댑터로만 붙는다. 잃는 것: 채널 화면을 100% 우리 맘대로 못 함. 얻는 것: 벤더와 경쟁 안 함 + 락인 회피 + M+N 레버리지.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;③ 숫자, 정직하게&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;여기엔 자랑할 하드 넘버가 없다. M+N의 이득은 &amp;quot;채널·동료를 늘려도 연결 작업이 곱이 아니라 합으로 는다&amp;quot;는 구조적 사실이지 측정된 %가 아니다. 없는 숫자는 안 만든다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;④ 우리가 처음엔 틀렸다 — pod에서 찍은 건 사용자 화면이 아니다&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;가장 아팠던 채널 사고는 렌더링이었다. Teams 카드가 &lt;strong&gt;단일 줄바꿈을 공백으로 뭉개&lt;/strong&gt; 잘 정리한 답이 &lt;strong&gt;한 덩어리 벽처럼&lt;/strong&gt; 나온 적이 있다. 또 한 번은 카드를 감싸던 내부 호환 마커(&lt;code&gt;__ADAPTIVE_CARD__&lt;/code&gt;)가 안 벗겨져 &lt;strong&gt;raw JSON이 그대로 사용자에게 노출&lt;/strong&gt;된 적도 있다. 둘 다 pod 안에서 함수를 호출해 찍어 보면 멀쩡했다 — &lt;strong&gt;&amp;quot;함수 출력이 맞다&amp;quot;와 &amp;quot;그 채널에서 실제로 그렇게 보인다&amp;quot;는 다른 일&lt;/strong&gt;이었으니까.&lt;/p&gt;
&lt;p&gt;그래서 렌더링을 화면 기준으로 강제하는 4겹을 깔았다: commit 훅(원시 마커 누출 차단) · CI(카드 골든 렌더 테스트) · 런타임(발신 직전 outbound guard) · Datadog 모니터(마커 누출·렌더 실패율). 채널을 얇게 연결한다는 건, 역설적으로 &lt;strong&gt;각 채널의 화면을 더 깐깐하게 검증한다&lt;/strong&gt;는 뜻이었다. (사실 문서를 한 도구에서 다른 도구로 옮길 때마다 겪는 일이다 — 원본에선 멀쩡한데 옮긴 화면에선 깨지는. 규모만 다를 뿐 같은 교훈이다.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2002&quot; data-origin-height=&quot;836&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHfJzw/dJMcab5XV22/ZWTEslmnkVEnr5dq75hZG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHfJzw/dJMcab5XV22/ZWTEslmnkVEnr5dq75hZG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHfJzw/dJMcab5XV22/ZWTEslmnkVEnr5dq75hZG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHfJzw%2FdJMcab5XV22%2FZWTEslmnkVEnr5dq75hZG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2002&quot; height=&quot;836&quot; data-origin-width=&quot;2002&quot; data-origin-height=&quot;836&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;맺음 — 그런데 좋은 지식이 없으면 다 소용없다&lt;/h2&gt;
&lt;p&gt;저장(1) → 권한(2) → 대화(3) → 채널(4). 이제 사용자는 자기 자리에서, 권한 안에서, 근거 있는 답을 받는다.&lt;/p&gt;
&lt;p&gt;그런데 이 모든 건 _좋은 지식이 들어와 있을 때_만 의미가 있다. 쓰레기가 들어가면 쓰레기가 나온다. 그 지식을 _어떻게 모으고, 들이기 전에 무엇을 검수했는지_는 — &lt;strong&gt;&lt;a href=&quot;https://gsretail.tistory.com/95&quot;&gt;번외편 — 좋은 답변의 90%는 검색 전에 결정된다&lt;/a&gt;&lt;/strong&gt;에서.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;시리즈&lt;/strong&gt;: &lt;a href=&quot;https://gsretail.tistory.com/89&quot;&gt;1탄 저장&lt;/a&gt; · &lt;a href=&quot;https://gsretail.tistory.com/90&quot;&gt;2탄 권한&lt;/a&gt; · &lt;a href=&quot;https://gsretail.tistory.com/92&quot;&gt;3탄-1부 대화&lt;/a&gt; · &lt;a href=&quot;https://gsretail.tistory.com/93&quot;&gt;3탄-2부 대화&lt;/a&gt; · &lt;strong&gt;4탄 채널 (이 글)&lt;/strong&gt; · &lt;a href=&quot;https://gsretail.tistory.com/95&quot;&gt;번외 수집&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock undefined&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;22787.jpg&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;960&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/02zUJ/btsMAMg3Wtb/7LuKJYntKKZdzNzAcaQAs0/tfile.dat&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/02zUJ/btsMAMg3Wtb/7LuKJYntKKZdzNzAcaQAs0/tfile.dat&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/02zUJ/btsMAMg3Wtb/7LuKJYntKKZdzNzAcaQAs0/tfile.dat&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F02zUJ%2FbtsMAMg3Wtb%2F7LuKJYntKKZdzNzAcaQAs0%2Ftfile.dat&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;80&quot; height=&quot;960&quot; data-filename=&quot;22787.jpg&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;960&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;김헌기 Darion&lt;/strong&gt; · AX본부 &amp;gt; AI데이터부문 &amp;gt; AI혁신지원팀&lt;/p&gt;
&lt;p&gt;AI 및 공통 Tech 기반의 기술 표준화 업무를 수행하고 있습니다. 동료들과 함께 기술 문화 만들기와 낯선 기술자와의 인연의 시작에 관심이 많습니다.&lt;/p&gt;</description>
      <category>Data&amp;amp;AI</category>
      <author>DarionKim</author>
      <guid isPermaLink="true">https://gsretail.tistory.com/94</guid>
      <comments>https://gsretail.tistory.com/94#entry94comment</comments>
      <pubDate>Sun, 12 Jul 2026 09:58:51 +0900</pubDate>
    </item>
    <item>
      <title>[사내 지식 AI 만들기 ③-2부&amp;middot;대화] RAG Score와 Answer Readiness는 다른 질문이다</title>
      <link>https://gsretail.tistory.com/93</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1598&quot; data-origin-height=&quot;764&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chBddT/dJMcadvO78E/eoK6MfxyNNh0X4UpgzHKz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chBddT/dJMcadvO78E/eoK6MfxyNNh0X4UpgzHKz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chBddT/dJMcadvO78E/eoK6MfxyNNh0X4UpgzHKz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchBddT%2FdJMcadvO78E%2FeoK6MfxyNNh0X4UpgzHKz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;575&quot; height=&quot;275&quot; data-origin-width=&quot;1598&quot; data-origin-height=&quot;764&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;정확도 1.0, 그런데 남은 질문&lt;/h2&gt;
&lt;p&gt;1부에서 정확도 1.0을 냈다. 에이전트가 KB를 정확히 고르고, 권한 안에서, 근거를 재정렬해서 답했다. 그런데도 사용자는 여전히 나쁜 경험을 겪었다. 이유는 하나였다 — &lt;strong&gt;&amp;quot;검색이 맞았는가&amp;quot;와 &amp;quot;이 사람에게 답이 됐는가&amp;quot;는 다른 질문&lt;/strong&gt;이기 때문이다.&lt;/p&gt;
&lt;p&gt;이 구분을 실감 나게 보여주는 비교 대상이 하나 있다.&lt;/p&gt;
&lt;h2&gt;좋은 비교 대상, 그러나 다른 질문 — NotebookLM&lt;/h2&gt;
&lt;p&gt;여기서 자주 듣는 말이 있다. &amp;quot;이건 NotebookLM에서는 잘 나오는데요?&amp;quot; 틀린 말은 아니다. NotebookLM은 문서 몇 개를 넣고 요약·질문·근거 정리를 시키는 데 실제로 뛰어나다. 범위가 좁고, 문맥이 유지되고, 목적이 분명해서 잘 나온다.&lt;/p&gt;
&lt;p&gt;문제는 비교 대상이 다르다는 데 있다. NotebookLM은 &lt;strong&gt;문서를 잘 읽는 도구&lt;/strong&gt;다. 기업의 지식 AI는 그 위에 몇 가지를 더 얹어야 하는 &lt;strong&gt;운영체계&lt;/strong&gt;다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;같은 질문도 &lt;strong&gt;누가 물었는지&lt;/strong&gt;에 따라 답이 달라진다 — 그 사람이 그 문서를 볼 권한이 있는지부터 확인해야 한다(2탄).&lt;/li&gt;
&lt;li&gt;최신 공지와 오래된 규정이 충돌하면, &lt;strong&gt;어느 쪽을 우선할지&lt;/strong&gt;도 판단해야 한다.&lt;/li&gt;
&lt;li&gt;답이 틀렸을 때, &lt;strong&gt;누가·어떤 근거로·어떤 경로로&lt;/strong&gt; 답했는지 나중에 재현할 수 있어야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이건 문서 QA가 아니라 운영이다. 그래서 NotebookLM은 &lt;strong&gt;경쟁 대상이 아니라 기준점&lt;/strong&gt;으로 쓰는 게 맞았다. 같은 문서를 넣었을 때 NotebookLM은 답하는데 우리 검색은 못한다면 — 그건 검색·청킹·리랭킹(1부)·근거검증·프롬프트 중 어딘가가 부족하다는 신호다. 반대로 NotebookLM이 잘한다고 그 경험을 그대로 기업 시스템에 옮길 수 있는 것도 아니다. 권한이 있어야 하고, 감사가 있어야 하고, 실패가 드러나야 하고, 업무로 이어져야 한다 — 문서를 잘 읽는 것과 회사 안에서 그 답을 운영 가능하게 만드는 것은 다른 일이다.&lt;/p&gt;
&lt;h2&gt;RAG Score vs Answer Readiness&lt;/h2&gt;
&lt;p&gt;이제 이름을 붙여보자.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;RAG Score        : 문서를 잘 읽었는가?         (검색·태깅·재정렬의 정확도)
Answer Readiness : 이 사람에게 답이 됐는가?     (맥락·권한·시점까지 반영한 실사용 준비도)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;RAG Score는 도구의 품질이고, Answer Readiness는 운영체계의 자격이다.&lt;/strong&gt; 1부는 전자의 이야기였다. 여기서부터는 후자다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1924&quot; data-origin-height=&quot;826&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkpg4N/dJMcacw1Nnp/sUbqIfWjdxUP9VFwzDLVG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkpg4N/dJMcacw1Nnp/sUbqIfWjdxUP9VFwzDLVG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkpg4N/dJMcacw1Nnp/sUbqIfWjdxUP9VFwzDLVG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbkpg4N%2FdJMcacw1Nnp%2FsUbqIfWjdxUP9VFwzDLVG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;668&quot; height=&quot;287&quot; data-origin-width=&quot;1924&quot; data-origin-height=&quot;826&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;Query Expansion — 사람은 완전한 문장으로 안 묻는다&lt;/h2&gt;
&lt;p&gt;&amp;quot;그거 다시 설명해줘.&amp;quot; &amp;quot;방금 그건 휴가에도 적용돼?&amp;quot; — 이런 말은 그 자체로는 검색할 수 없다. 이전에 뭘 물었는지, 뭘 가리키는지가 없으면 &amp;quot;그거&amp;quot;는 그냥 대명사다.&lt;/p&gt;
&lt;p&gt;그래서 검색으로 넘기기 전에 질문을 한 번 다듬는다. 세 갈래로:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;문맥 보존 명확화&lt;/strong&gt; — &amp;quot;그거&amp;quot;가 뭘 가리키는지 앞선 대화에서 찾아 완전한 문장으로 바꾼다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;핵심 키워드 추출&lt;/strong&gt; — 검색엔진이 더 잘 무는 형태로 다시 뽑는다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;의미 보존 변형&lt;/strong&gt; — 같은 뜻을 다르게 표현한 질문 몇 개를 더 만들어서, 하나로 안 걸리는 것도 다른 표현으론 걸리게 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;여기서도 익숙한 구조가 나온다. 사전에 등록된 동의어·줄임말은 &lt;strong&gt;규칙 기반으로 항상&lt;/strong&gt; 확장하고, 그걸로 부족하면 &lt;strong&gt;LLM 기반으로 의미를 더 풀어서&lt;/strong&gt; 확장한다. 값싼 걸 먼저, 비싼 건 필요할 때만 — 1부 rerank에서 봤던 것과 같은 이중 구조다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2020&quot; data-origin-height=&quot;500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bH7esA/dJMcadCy2RU/U8ucHphMd47LDVGuxGXxc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bH7esA/dJMcadCy2RU/U8ucHphMd47LDVGuxGXxc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bH7esA/dJMcadCy2RU/U8ucHphMd47LDVGuxGXxc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbH7esA%2FdJMcadCy2RU%2FU8ucHphMd47LDVGuxGXxc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;917&quot; height=&quot;227&quot; data-origin-width=&quot;2020&quot; data-origin-height=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3&gt;세 번 넘어졌던 이야기&lt;/h3&gt;
&lt;p&gt;이거 켜는 데 세 번 넘어졌다.&lt;/p&gt;
&lt;p&gt;첫 번째는 이름이었다. 코드는 한 이름의 환경변수만 봤는데, 운영자는 다른(그러나 더 흔히 쓰이던) 이름으로 설정을 넣었다. 둘 다 &amp;quot;쿼리 확장을 켜라&amp;quot;는 같은 뜻이었는데, 코드가 한쪽만 알아들어서 — dev에는 켜졌고 prod에는 조용히 안 켜져 있었다. 에러 한 번 없이, 그냥 확장이 안 됐을 뿐이었다.&lt;/p&gt;
&lt;p&gt;두 번째는 기본값이었다. 이름을 통일한 다음에도 기본값이 꺼짐으로 남아 있었다. 로그를 뒤져서 잡았다 — 같은 기간 dev 로그엔 &amp;quot;쿼리 확장됨&amp;quot; 흔적이 여러 건 있었는데, prod 로그엔 한 건도 없었다. 품질 지표(주제 적합도)도 유독 낮게 나오던 원인 중 하나가 이거였다. 기본값을 켬으로 뒤집었다.&lt;/p&gt;
&lt;p&gt;세 번째는 인터페이스였다. LLM 기반 확장을 붙이자 &amp;quot;지원하지 않는 클라이언트 타입&amp;quot;이라는 에러가 매 요청마다 조용히 찍히기 시작했다 — 확장을 시도했다가 실패하고 원래 쿼리로 되돌아가는 걸 반복하고 있었다. 새로 붙인 LLM 클라이언트가 기대하던 메서드 이름과 실제 메서드 이름이 달랐던 것 — 어댑터로 감싸서 맞췄다.&lt;/p&gt;
&lt;p&gt;세 번 다 겉으로는 &amp;quot;왜 확장이 안 켜지지&amp;quot;라는 같은 증상이었다. 원인은 매번 달랐다 — 이름 불일치, 기본값 반전, 인터페이스 불일치. 셋이 서로 아무 관계가 없다는 게 오히려 배운 점이었다. 같은 증상이 여러 다른 원인을 가릴 수 있다는 것.&lt;/p&gt;
&lt;h2&gt;개인화 스레드 회수 — 출입증이 이제 기억한다&lt;/h2&gt;
&lt;p&gt;2탄 끝에서 열어둔 질문이 있었다. &amp;quot;출입증은 못 들어가는 문만 막아줄 뿐, 이 사람이 평소 자주 드나드는 문이 어딘지는 알려주지 않는다.&amp;quot;&lt;/p&gt;
&lt;p&gt;이제 그 답을 할 수 있다. 매 턴마다, 이 사람이 &lt;strong&gt;누구이고&lt;/strong&gt;(조직·부서·직급) &lt;strong&gt;무엇을 기억하고 있는지&lt;/strong&gt;(장기 기억)를 한 번에 모아 하나의 맥락으로 만든다. 이 맥락이 두 곳에 쓰인다.&lt;/p&gt;
&lt;p&gt;하나는 &lt;strong&gt;대화 이어가기&lt;/strong&gt;다. &amp;quot;그거 다시 설명해줘&amp;quot; 같은 말은 그 자체로는 아무것도 아니다. 기억이 있어야 &amp;quot;그거&amp;quot;가 뭔지 안다. 장기 기억에서 방금 무슨 대화가 있었는지를 찾아, 그 말을 완전한 질문으로 다시 써서 검색에 넘긴다. (앞서 본 Query Expansion의 문맥 보존 명확화와 같은 문제를, 대화가 남긴 흔적 쪽에서 한 번 더 푸는 셈이다.)&lt;/p&gt;
&lt;p&gt;다른 하나는 &lt;strong&gt;조직에 맞춘 우선순위&lt;/strong&gt;다. 같은 질문도 이 사람이 어느 조직·부서에 있는지에 따라 무엇을 먼저 보여줄지가 달라진다. 접근 가능한 범위(2탄)는 그대로지만, 그 안에서 _이 사람에게 더 맞는 것_을 앞에 놓는다.&lt;/p&gt;
&lt;p&gt;두 가지 다 최근에 실제로 켜졌다. &amp;quot;이 사람이 평소 자주 드나드는 문&amp;quot;에 대한 답은 결국, 문을 열어주는 것과는 별개로 — &lt;strong&gt;그 사람을 기억하고, 그 기억을 대화와 라우팅 양쪽에 실제로 쓰는 것&lt;/strong&gt;이었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1732&quot; data-origin-height=&quot;794&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wd6Pl/dJMcagGfHG1/Kb7ogcSMtRuxvd1OZmLOD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wd6Pl/dJMcagGfHG1/Kb7ogcSMtRuxvd1OZmLOD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wd6Pl/dJMcagGfHG1/Kb7ogcSMtRuxvd1OZmLOD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fwd6Pl%2FdJMcagGfHG1%2FKb7ogcSMtRuxvd1OZmLOD1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1732&quot; height=&quot;794&quot; data-origin-width=&quot;1732&quot; data-origin-height=&quot;794&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;Before/After — 뭐가 달라졌나&lt;/h2&gt;
&lt;p&gt;숫자로 자랑할 단계는 아직 아니다. 그런데 체감은 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;같은 질문을 두 번 다른 말로 다시 물어야 했던 게, 한 번으로 줄었다 — 문맥 재작성과 쿼리 확장이 같이 자리를 잡은 덕분이다.&lt;/li&gt;
&lt;li&gt;&amp;quot;그거 다시&amp;quot; 같은 되묻기가 끊기지 않고 이어진다 — 장기 기억이 무엇을 가리키는지 찾아준다.&lt;/li&gt;
&lt;li&gt;같은 권한 범위 안에서도, 이 사람 조직에 더 맞는 답이 앞으로 온다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;여전히 남은 것도 있다. 그리고 그건 다음 이야기 몫이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1918&quot; data-origin-height=&quot;854&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwvSmD/dJMcagTJOkt/G8XCNkBKUdckxqbklA5Fd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwvSmD/dJMcagTJOkt/G8XCNkBKUdckxqbklA5Fd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwvSmD/dJMcagTJOkt/G8XCNkBKUdckxqbklA5Fd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwvSmD%2FdJMcagTJOkt%2FG8XCNkBKUdckxqbklA5Fd1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;671&quot; height=&quot;299&quot; data-origin-width=&quot;1918&quot; data-origin-height=&quot;854&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;심화 — &amp;quot;그거&amp;quot;를 자립형 질문으로 바꾸는 프롬프트, 그리고 &amp;quot;Pod&amp;quot; 사고&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;이 절은 깊다. 대화 재작성과 쿼리 확장이 실제 코드에서 어떻게 도는지 궁금한 분을 위한 detail이다. 바쁘면 맺음으로 건너뛰어도 좋다.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;① 코드 — &amp;quot;그거&amp;quot;를 푸는 실제 프롬프트 + 방어막&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;본문의 &amp;quot;문맥 보존 명확화&amp;quot;는 실제로 이런 프롬프트로 돈다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def _build_prompt(query, history):
    return (
        &amp;quot;사용자의 모호한 후속 질문을, 대화 기록에서 대명사·지시어(그거, 저분, 위, 아까)를 &amp;quot;
        &amp;quot;풀어 자립형 한국어 검색 질의로 다시 써라. 하나의 간결한 질의로. 답하지 말 것. &amp;quot;
        &amp;quot;이미 자립형이면 그대로 반환.\n\n&amp;quot;
        f&amp;quot;[대화 기록]\n{history}\n\n[현재 질문] {query}\n\n[자립형 질문]&amp;quot;
    )&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;중요한 건 프롬프트 자체가 아니라 그 주위의 &lt;strong&gt;방어막&lt;/strong&gt;이다. 재작성 결과는 (a) 비어있지 않고 (b) 원본 대비 터무니없이 길지 않고 (c) 프롬프트의 섹션 마커를 되돌려 뱉지 않을 때만 믿는다(&lt;code&gt;_is_plausible_rewrite&lt;/code&gt;). 하나라도 실패하면(타임아웃·예외·이상한 출력) &lt;strong&gt;조용히 옛 방식(직전 대화를 그냥 뒤에 이어 붙이기)으로 폴백&lt;/strong&gt;하고, Datadog에 &lt;code&gt;applied|timeout|error|rejected&lt;/code&gt; 태그를 남긴다. &amp;quot;LLM 한 스텝 + 하드 폴백 + 관측 트립와이어&amp;quot; — 이 기능 하나를 넘어 재사용되는 패턴이다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;② 우리가 처음엔 틀렸다 — &amp;quot;Pod&amp;quot;가 &amp;quot;Print On Demand&amp;quot;가 되다&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;쿼리 확장이 켜지자 새로운 실패가 나왔다. 쿠버네티스 &amp;quot;Pod&amp;quot;를 물은 사용자의 질의가, 같은 용어 사전에 있던 &lt;strong&gt;전혀 다른 도메인의 약어&lt;/strong&gt;로 조용히 확장됐다(리테일 쪽 &amp;quot;Pod = Print On Demand&amp;quot;). 사전에 IT 약어와 리테일 약어가 같이 살았고, 확장 로직은 사용자가 어느 도메인을 뜻했는지 몰랐던 것.&lt;/p&gt;
&lt;p&gt;여기서 배운 게 이 시리즈에서 드문 결이다 — &lt;strong&gt;확장은 &amp;quot;못 찾던 걸 찾게&amp;quot; 할 뿐 아니라, &amp;quot;맞던 걸 틀리게&amp;quot; 만들 수도 있다.&lt;/strong&gt; 본문의 세 번 넘어진 이야기(안 켜지는 문제)와는 정반대 방향의 실패다. 고친 방식: 질의에 이미 다른 IT·인프라 용어가 섞여 있으면, 알려진 교차-도메인 동음이의(pod, node, service, image, port, token, storage, disk)에 대해선 사전 확장을 &lt;strong&gt;건너뛴다&lt;/strong&gt; — 사전을 무조건 믿지 않고 문맥으로 가드.&lt;/p&gt;
&lt;p&gt;그리고 하나 더 — 이 확장이 답변 품질을 실제로 올리는지 A/B로 재려 했는데, 정작 골든 질문 세트에 &amp;quot;짧은 도메인 약어 질의&amp;quot;가 너무 적어 통계적으로 판정할 수 없었다. 그때 결과를 우겨서 내는 대신 &lt;strong&gt;INSUFFICIENT_DATA로 정직하게 기록&lt;/strong&gt;하고, 검정력이 낮다는 단서를 붙여 A/B 결론을 냈다. 기능의 버그가 아니라, &lt;strong&gt;기능을 재는 방식의 결함을 먼저 공개한&lt;/strong&gt; 사례다.&lt;/p&gt;
&lt;h2&gt;맺음 — 그리고 다음 질문&lt;/h2&gt;
&lt;p&gt;1부에서 라우팅을 풀었고, 2부에서 대화의 결을 채웠다. 태깅 정확도와 대화 능력, 둘 다 갖췄으니 이제 완성일까?&lt;/p&gt;
&lt;p&gt;아직 하나가 남는다. 이 좋은 답을 &lt;em&gt;어디서&lt;/em&gt; 보여줄 것인가. 우리는 하마터면 앱을 또 만들 뻔했다. 그 이야기는 &lt;strong&gt;4탄 — 모바일 앱을 또 만들 뻔했다&lt;/strong&gt;에서.&lt;/p&gt;
&lt;p&gt;(그리고 — 이 모든 걸 사람이 아니라 에이전트가 굴린다는 이야기, Claude나 Codex 같은 코딩 에이전트도 결국 같은 틀 안의 &amp;quot;에이전트&amp;quot;라는 이야기는 언젠가 따로.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1974&quot; data-origin-height=&quot;932&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YJtxq/dJMcacX5j8O/v7NsEoOkXQbnG3TRXqNaBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YJtxq/dJMcacX5j8O/v7NsEoOkXQbnG3TRXqNaBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YJtxq/dJMcacX5j8O/v7NsEoOkXQbnG3TRXqNaBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYJtxq%2FdJMcacX5j8O%2Fv7NsEoOkXQbnG3TRXqNaBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;578&quot; height=&quot;273&quot; data-origin-width=&quot;1974&quot; data-origin-height=&quot;932&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;시리즈&lt;/strong&gt;: &lt;a href=&quot;https://gsretail.tistory.com/89&quot;&gt;1탄 저장&lt;/a&gt; · &lt;a href=&quot;https://gsretail.tistory.com/90&quot;&gt;2탄 권한&lt;/a&gt; · &lt;a href=&quot;https://gsretail.tistory.com/92&quot;&gt;3탄-1부 대화&lt;/a&gt; · &lt;strong&gt;3탄-2부 대화 (이 글)&lt;/strong&gt; · 4탄 채널 · 번외 수집&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock undefined&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;22787.jpg&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;960&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/02zUJ/btsMAMg3Wtb/7LuKJYntKKZdzNzAcaQAs0/tfile.dat&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/02zUJ/btsMAMg3Wtb/7LuKJYntKKZdzNzAcaQAs0/tfile.dat&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/02zUJ/btsMAMg3Wtb/7LuKJYntKKZdzNzAcaQAs0/tfile.dat&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F02zUJ%2FbtsMAMg3Wtb%2F7LuKJYntKKZdzNzAcaQAs0%2Ftfile.dat&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;80&quot; height=&quot;960&quot; data-filename=&quot;22787.jpg&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;960&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;김헌기 Darion&lt;/strong&gt; · AX본부 &amp;gt; AI데이터부문 &amp;gt; AI혁신지원팀&lt;/p&gt;
&lt;p&gt;AI 및 공통 Tech 기반의 기술 표준화 업무를 수행하고 있습니다. 동료들과 함께 기술 문화 만들기와 낯선 기술자와의 인연의 시작에 관심이 많습니다.&lt;/p&gt;</description>
      <category>Data&amp;amp;AI</category>
      <author>DarionKim</author>
      <guid isPermaLink="true">https://gsretail.tistory.com/93</guid>
      <comments>https://gsretail.tistory.com/93#entry93comment</comments>
      <pubDate>Fri, 10 Jul 2026 14:12:11 +0900</pubDate>
    </item>
    <item>
      <title>[사내 지식 AI 만들기 ③-1부&amp;middot;대화] 사용자는 한 줄로 묻지 않았다 &amp;mdash; 그런데 정확도 1.0으로도 부족했다 (RAG &amp;rarr; AgenticRAG)</title>
      <link>https://gsretail.tistory.com/92</link>
      <description>&lt;h2&gt;사서가 필요했다&lt;/h2&gt;
&lt;p&gt;2탄까지 — 지식은 통합 컬렉션에 잘 저장되고, 권한대로 안전하게 조회된다. 그런데 한 가지가 끈질기게 남았다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;&amp;quot;이 질문은 어느 KB를 봐야 하지?&amp;quot;&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;per-KB 시절엔 사람이 골라줬다. &amp;quot;그건 인사 KB에 물어보세요.&amp;quot; 새 KB가 끝없이 추가되는 환경에서, 이 수동 선택은 곧 한계에 부딪혔다. 게다가 사용자는 한 줄로 묻지 않는다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;&amp;quot;지난번 그 정산 건, 점포 기준이랑 본사 기준 다르지? 그리고 그거 휴가에도 영향 있어?&amp;quot;&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;한 마디에 &lt;strong&gt;정산·점포운영·인사&lt;/strong&gt; 세 지식이 얽힌다. &lt;strong&gt;멀티턴, 멀티인텐트.&lt;/strong&gt; 사람이 KB를 골라주는 고전 RAG로는 이 대화를 감당할 수 없다. 잘못 고르면 — 문서는 있는데 답을 못 한다.&lt;/p&gt;
&lt;p&gt;이건 가정이 아니라 반복해서 겪은 패턴이었다. 같은 사용자가 부서 경계를 넘나드는 질문을 매번 &lt;strong&gt;다른 봇에 따로&lt;/strong&gt; 물어야 했고, &amp;quot;이걸 왜 매번 나눠서 물어야 하나&amp;quot;라는 불만이 쌓였다. 지식은 잘 저장돼 있는데(1탄), 그걸 하나의 대화로 잇지 못하면 사용자에게는 여전히 흩어진 지식일 뿐이었다.&lt;/p&gt;
&lt;h2&gt;RAG → AgenticRAG&lt;/h2&gt;
&lt;p&gt;전환점은 이거였다. &lt;strong&gt;&amp;quot;어느 지식을 볼지&amp;quot;를 사람이 하드코딩하는 대신, 에이전트가 대화 맥락 + 사용자 권한 + 의도로 동적으로 고르게&lt;/strong&gt; 했다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;  &lt;em&gt;여기서 &amp;quot;Agentic&amp;quot;의 범위&lt;/em&gt;: 에이전트가 &lt;strong&gt;무엇을 검색할지 스스로 정한다&lt;/strong&gt;는 뜻이다 — 의도를 분해하고, 접근 가능한 KB scope를 고르고, 멀티인텐트를 라우팅한다. (검색 결과를 스스로 평가·재시도하는 더 무거운 _적응형 루프_는 지연·비용 트레이드오프가 있어 별개의 프론티어로, 신중히 단계적으로 켠다. 과장하지 않는다.)&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;pre&gt;&lt;code&gt;멀티턴/멀티인텐트 질문
   → 의도 분해 (멀티 인텐트 감지)
   → 사용자 권한(2탄) 해석 → 접근 가능한 KB scope 자동 선택   ← 사람이 KB 안 고름
   → scope 내 통합 검색(1탄)
   → 필요하면 clarify (&amp;quot;어느 점포 기준이요?&amp;quot;)
   → rerank → 근거 기반 답변&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1950&quot; data-origin-height=&quot;850&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/st7pi/dJMcaa0fR82/sw6bljKr5A56040MaPyYg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/st7pi/dJMcaa0fR82/sw6bljKr5A56040MaPyYg0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/st7pi/dJMcaa0fR82/sw6bljKr5A56040MaPyYg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fst7pi%2FdJMcaa0fR82%2Fsw6bljKr5A56040MaPyYg0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;608&quot; height=&quot;265&quot; data-origin-width=&quot;1950&quot; data-origin-height=&quot;850&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;대화 스택:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;LLM 라우팅   : LiteLLM Proxy (작업별 모델 분리 — 분류는 가볍게, 답변은 무겁게)
의도 분해    : LLM 기반 intent classifier (멀티인텐트 감지)
에이전트 조율: Supervisor 패턴 (역할별 에이전트에게 위임)
비동기 실행  : Temporal 워크플로 (에이전트 작업 상태 추적)
권한 신호    : 사용자 조직 기준 KB 접근범위 결정&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;한 명의 사서가 아니라 &lt;strong&gt;역할이 나뉜 여러 에이전트&lt;/strong&gt;가 이 대화를 나눠 맡는다. 지식을 아는 에이전트, 그걸 조율하는 층, 실제로 화면을 조작하거나 알림을 보내는 에이전트 — 저마다 자기 몫을 하고, 서로에게 넘긴다. 그리고 &lt;em&gt;누가 물었는지&lt;/em&gt;(조직)가 그 라우팅에 함께 반영된다 — 다만 &amp;quot;이 사람이 평소 자주 찾는 지식까지&amp;quot; 반영하는 개인화는 아직 다른 이야기다. (2부에서 왜 그런지 다룬다.)&lt;/p&gt;
&lt;h2&gt;사서 비유 — 사서 한 명에서, 사서 팀으로&lt;/h2&gt;
&lt;p&gt;예전 도서관에선 사서가 &amp;quot;303호 서가로 가세요&amp;quot;라고 위치를 알려줬다 — 사용자가 서가 번호를 알아야 했다(수동 KB 선택). 처음엔 사서 한 명(에이전트 하나)이 질문을 듣고 알아서 서가를 도는 정도로 충분해 보였다.&lt;/p&gt;
&lt;p&gt;그런데 질문이 여러 전문 분야에 걸치자, 사서 한 명으로는 부족했다. 그래서 도서관을 &lt;strong&gt;사서 팀&lt;/strong&gt;으로 다시 그렸다 — 각 분야를 잘 아는 사서들이 있고(&lt;strong&gt;아는 역할&lt;/strong&gt;), 그 사서들 사이에서 &amp;quot;이 질문은 누구한테 먼저 물어야 하나&amp;quot;를 정리해주는 총괄 사서가 있고(&lt;strong&gt;조율하는 역할&lt;/strong&gt;), 그리고 자료를 찾아주는 데서 그치지 않고 실제로 뭔가를 갖다주거나 대신 처리해야 할 때 움직이는 사람도 있다(&lt;strong&gt;실행하는 역할&lt;/strong&gt;). &lt;strong&gt;사용자는 여전히 한 명의 사서에게 물을 뿐이지만, 그 뒤에서는 팀이 협업한다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1956&quot; data-origin-height=&quot;940&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8cIRu/dJMcaa65Z1M/Ka3AMpAJf117IZIhu5SUh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8cIRu/dJMcaa65Z1M/Ka3AMpAJf117IZIhu5SUh0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8cIRu/dJMcaa65Z1M/Ka3AMpAJf117IZIhu5SUh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8cIRu%2FdJMcaa65Z1M%2FKa3AMpAJf117IZIhu5SUh0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;627&quot; height=&quot;301&quot; data-origin-width=&quot;1956&quot; data-origin-height=&quot;940&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;핵심은 &amp;quot;검색을 똑똑하게&amp;quot;이기 &lt;em&gt;이전에&lt;/em&gt;, &lt;strong&gt;&amp;quot;무엇을 검색할지를 에이전트가 정한다&amp;quot;&lt;/strong&gt;였다. 끝없이 자라는 KB를 사람이 일일이 관리하던 구조에서, 에이전트가 권한과 의도로 길을 찾는 구조로.&lt;/p&gt;
&lt;h2&gt;rerank — 후보를 찾은 다음, 순서를 다시 세운다&lt;/h2&gt;
&lt;p&gt;&amp;quot;무엇을 검색할지&amp;quot;는 에이전트가 정했다. 그런데 검색(1탄, dense+sparse hybrid)은 &lt;em&gt;후보를 넓게&lt;/em&gt; 찾는 데 강할 뿐, 그 후보를 질문에 가장 잘 맞는 순서로 세우는 데는 약하다. 임베딩 검색(bi-encoder)은 질문과 문서를 각각 따로 벡터로 만들어 거리로 비교하기 때문에 빠르지만, 질문과 문서를 나란히 놓고 세밀하게 견주지는 못한다.&lt;/p&gt;
&lt;p&gt;그래서 상위 후보에만 한 번 더 손을 댄다. 질문과 문서를 함께 입력해 정밀하게 관련도를 매기는 &lt;strong&gt;cross-encoder 기반 reranker&lt;/strong&gt;를 상위 후보에만 돌린다 — 전체 후보에 돌리면 느리니까, 값싼 1차 검색으로 후보를 좁힌 다음 비싼 2차 정렬을 그 위에만 얹는 구조다. 상용 rerank API를 1순위로 쓰고, 막히면 자체 호스팅 cross-encoder로 넘어가는 이중화도 해뒀다.&lt;/p&gt;
&lt;p&gt;순서를 정할 때도 모델 점수 하나만 보지 않는다. &lt;strong&gt;모델 관련도 + 원래 검색 순위 + 출처 종류(공식 문서·웹·그래프·FAQ 별 가중치) + 필요하면 결과 다양성&lt;/strong&gt;을 가중합해서 최종 순서를 만든다. FAQ로 등록된 답이 있으면 살짝 밀어주고, 비슷한 문서만 줄줄이 나오지 않도록 다양성 점수도 얹는다. &amp;quot;무엇을 볼지&amp;quot;는 에이전트가 고르고, &amp;quot;어떤 순서로 보여줄지&amp;quot;는 이 재정렬이 고른다 — 둘이 같이 맞아야 사용자가 실제로 원하는 답에 먼저 닿는다.&lt;/p&gt;
&lt;p&gt;(이 &amp;quot;값싸고 넓게 + 비싸고 정밀하게&amp;quot; 이중 구조, 기억해 두면 2부에서 한 번 더 보게 된다 — 검색 말고 다른 layer에서.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1986&quot; data-origin-height=&quot;850&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4b8GY/dJMcab5WTkg/76I3Rszl2gnkF3yX1pyIKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4b8GY/dJMcab5WTkg/76I3Rszl2gnkF3yX1pyIKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4b8GY/dJMcab5WTkg/76I3Rszl2gnkF3yX1pyIKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4b8GY%2FdJMcab5WTkg%2F76I3Rszl2gnkF3yX1pyIKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;582&quot; height=&quot;249&quot; data-origin-width=&quot;1986&quot; data-origin-height=&quot;850&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;정확도 1.0인데, 왜 여전히 나쁜 경험이었나&lt;/h2&gt;
&lt;p&gt;여기서 또 한 번 배웠다. 어느 질문이 어느 지식 범위(KB)에 속하는지, API로 &lt;strong&gt;태그를 정확히 매기는 것 자체는 정확도 1.0&lt;/strong&gt;까지도 낼 수 있었다. 그런데 그것만으론 부족했다.&lt;/p&gt;
&lt;p&gt;사람은 한 번에 묻지 않는다. 되묻고, 앞서 한 말을 다시 끌어오고, 한 문장에 여러 의도를 섞는다. &lt;strong&gt;지식 범위를 완벽하게 골라내는 것과, 그 반복·다의도 대화를 자연스럽게 받아내는 것은 다른 능력&lt;/strong&gt;이었다. 태깅 정확도가 아무리 높아도, 대화 기능이 그 대화의 흐름을 못 따라가면 — 사용자에게 돌아오는 건 잘 만든 지식이 아니라, &lt;strong&gt;뚝뚝 끊기는 나쁜 경험&lt;/strong&gt;뿐이었다.&lt;/p&gt;
&lt;p&gt;즉 1탄의 저장, 2탄의 권한이 아무리 정교해도, &lt;strong&gt;이 위에서 사람과 자연스럽게 대화를 이어가는 능력이 없으면 그 지식은 사용자에게 닿지 않는다.&lt;/strong&gt; 지식 범위를 고르는 일(라우팅)과 대화를 이어가는 일(대화 관리)은 같이 완성돼야 하는 한 쌍이었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1636&quot; data-origin-height=&quot;816&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bq7Ksr/dJMcajiB1dj/bCmwMVTpExSE4KAopkglF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bq7Ksr/dJMcajiB1dj/bCmwMVTpExSE4KAopkglF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bq7Ksr/dJMcajiB1dj/bCmwMVTpExSE4KAopkglF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbq7Ksr%2FdJMcajiB1dj%2FbCmwMVTpExSE4KAopkglF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;598&quot; height=&quot;298&quot; data-origin-width=&quot;1636&quot; data-origin-height=&quot;816&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;심화 — reranker는 fallback 안에 fallback, 그리고 점수가 1.0에 붙어버린 사고&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;이 절은 깊다. 라우팅과 재정렬이 실제 코드에서 어떻게 방어되는지 궁금한 분을 위한 detail이다. 바쁘면 맺음으로 건너뛰어도 좋다.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;① 코드 — 리랭커는 fallback 안에 fallback&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;본문에서 &amp;quot;상용 rerank API 1순위, 막히면 자체 호스팅 cross-encoder&amp;quot;라 했다. 실제 코드는 한 겹 더 깊다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def _create_reranker():
    &amp;quot;&amp;quot;&amp;quot;우선순위: cohere(상용, LiteLLM 경유) &amp;gt; cross_encoder(자체) &amp;gt; 없음.&amp;quot;&amp;quot;&amp;quot;
    if reranker_type == &amp;quot;cohere&amp;quot; and os.getenv(&amp;quot;LITELLM_API_BASE&amp;quot;):
        return CohereReranker()                    # 1순위: 상용 API
    if os.getenv(&amp;quot;DISABLE_CROSS_ENCODER_RERANKER&amp;quot;) != &amp;quot;true&amp;quot;:
        adapter = CrossEncoderIRerankerAdapter()   # 2순위: 자체 호스팅
        loop.create_task(adapter.warmup())         # 모델 로드는 논블로킹
        return adapter
    logger.warning(&amp;quot;리랭커 없음 — 벡터 유사도 순서만. 관련도 ~20%% 저하 예상.&amp;quot;)
    return None                                    # 3순위: 없음(조용히 넘기지 않고 숫자 로깅)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;눈여겨볼 두 가지: (1) 자체 모델 warmup을 &lt;code&gt;loop.create_task&lt;/code&gt;로 &lt;strong&gt;논블로킹&lt;/strong&gt; 발사 — 콜드 모델 로딩이 그 요청을 붙잡지 않는다. (2) &amp;quot;리랭커가 아예 없는&amp;quot; 최후 분기가 조용히 넘어가지 않고 &lt;strong&gt;&amp;quot;~20% 관련도 저하&amp;quot;라는 숫자를 로그에 남긴다.&lt;/strong&gt; 그리고 자체 어댑터(&lt;code&gt;CrossEncoderIRerankerAdapter&lt;/code&gt;) 안에는 또 3단 fallback이 있다 — 원격 자체호스팅 HTTP → 인프로세스 로컬 모델 → 원순위 기반 선형감쇠. &lt;strong&gt;fallback 안의 fallback.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;② 영리한 선택 — 점수 정규화: 절대 clamp vs 배치 상대 stretch&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;싼 1차 점수(벡터 유사도)와 비싼 2차 점수(cross-encoder 관련도)를 가중합할 때, 두 점수의 스케일이 다르다(코사인은 대략 0&lt;del&gt;1, rerank logit은 -10&lt;/del&gt;10 같은 무한대역). 우리가 고른 방식은 &lt;strong&gt;각 점수를 절대 기준 0~1로 clamp&lt;/strong&gt;하는 것. 기각한 대안:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;정규화 없이 그냥 합산&lt;/strong&gt; — 스케일이 달라 무의미.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;배치 안에서 min-max로 늘리기(stretch)&lt;/strong&gt; — 이게 함정이었다(④ 참조).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;순위-위치 가중&lt;/strong&gt;(1등=1.0, 2등=0.95…) — 점수 크기를 버려서, 톱1이 &amp;quot;진짜 좋아서&amp;quot;인지 &amp;quot;그 배치에서 제일 덜 나빠서&amp;quot;인지 구분 못 함.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;③ 숫자, 정직하게 — 둘은 실측, 하나는 아직&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;점수 포화 fix&lt;/strong&gt;: golden-question 평가에서 리랭커 톱1 점수가 천장에 붙어 있었다 — 실제 관련도와 무관하게 &lt;strong&gt;톱1이 ≥0.94인 비율이 89.6%.&lt;/strong&gt; 배치 min-max 정규화가 그 배치의 최고점을 항상 1.0으로 만든 탓. 목표를 &amp;quot;톱1 ≥0.94 비율 &amp;lt;50%&amp;quot;로 잡고 고쳤다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;KB scope 확장 A/B&lt;/strong&gt;(프로덕션 데이터, 골든 26문항): 좁은 기본 scope vs 권한 내 넓힌 scope → 도메인 질문 근거율(&lt;a href=&quot;mailto:grounded@0.5&quot;&gt;grounded@0.5&lt;/a&gt;)이 &lt;strong&gt;3/22(13%)에서 10/22(45%)로&lt;/strong&gt;, 대조군 회귀 0.&lt;/li&gt;
&lt;li&gt;intent classifier 정확도: 하드 넘버 아직 없음(목표 ≥80% top-1, 8문항 PoC만) — 정직하게 &amp;quot;측정 인프라는 설계했으나 아직 대규모 미가동&amp;quot;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;④ 우리가 처음엔 틀렸다 — flag 켜니 &amp;quot;이 시스템 뭐야?&amp;quot;가 깨졌다&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;KB scope를 넓히는 건 명백히 좋아 보였다(③의 A/B가 증명). 그런데 프로덕션에서 flag를 켜자, 그동안 항상 맞히던 기본 질문 — &amp;quot;이 시스템 뭐야?&amp;quot; — 이 &lt;strong&gt;즉시 회귀&lt;/strong&gt;했다. 격리된 A/B 경로에선 멀쩡했는데, 라이브 end-to-end 경로에서만 깨졌다.&lt;/p&gt;
&lt;p&gt;원인은 ②의 점수 포화와 &lt;strong&gt;같은 버그 계열&lt;/strong&gt;이었다: 명시적 KB 리스트가 없을 때만 도는 내부 &amp;quot;KB 선택&amp;quot; 스텝이, min/max 기반 정규화로 &lt;strong&gt;아무 상관없는 대형 KB에 인공적 천장 점수&lt;/strong&gt;를 줘서 톱으로 올려버린 것. 좁혀진 후보 집합에서 &amp;quot;제일 top인 하나&amp;quot;가 실제 관련도와 무관하게 1.0을 받는, 바로 그 실패.&lt;/p&gt;
&lt;p&gt;고친 순서가 교훈이다: (1) 같은 날 flag를 한 줄로 되돌려 롤백 → (2) 다음날 격리로 원인 규명(명시적 KB 리스트로 넘기면 정상, &amp;quot;필터 없이 파이프라인이 알아서 고르게&amp;quot; 하면 회귀) → (3) 넓힌 scope를 &lt;strong&gt;항상 명시적 KB 리스트로&lt;/strong&gt; 넘겨 그 버그 경로를 고치는 대신 &lt;strong&gt;우회&lt;/strong&gt;해 재출시. 이 사고는 지금 라이브 코드의 docstring(&lt;code&gt;_resolve_accessible_default_kb_filter&lt;/code&gt;)에 그대로 적혀 있다 — &lt;strong&gt;코드가 자기 과거 회귀를 기억한다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;교훈: 격리된 실험에서 좋았다고 라이브에서도 좋은 게 아니다. &amp;quot;이 경로에서만 도는 스텝&amp;quot;이 실험 경로엔 없고 라이브 경로엔 있으면, 그 차이가 정확히 회귀가 숨는 자리다.&lt;/p&gt;
&lt;h2&gt;맺음 — 그리고 이 반전이 남긴 질문&lt;/h2&gt;
&lt;p&gt;이제 에이전트가 알아서 지식을 찾는다. 멀티턴으로 얽힌 질문도, 권한 안에서, 근거를 모아 답한다. 그런데 정확도 1.0짜리 라우팅으로도 사용자는 여전히 나쁜 경험을 겪었다 — 그 이유를 따라가면 질문이 하나 남는다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;quot;검색이 맞았는가&amp;quot;와 &amp;quot;이 사람에게 답이 됐는가&amp;quot;는 다른 질문이었다.&lt;/strong&gt; 그리고 2탄이 심어놓은 또 다른 숙제 — 이 사람이 _평소 자주 찾는 지식_은 여전히 못 알아본다는 것 — 도 그대로 남아있었다.&lt;/p&gt;
&lt;p&gt;이 두 질문에 어떻게 답을 하려 했는지는 &lt;strong&gt;&lt;a href=&quot;https://gsretail.tistory.com/93&quot;&gt;3탄-2부 — RAG Score와 Answer Readiness는 다른 질문이다&lt;/a&gt;&lt;/strong&gt;에서.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;시리즈&lt;/strong&gt;: &lt;a href=&quot;https://gsretail.tistory.com/89&quot;&gt;1탄 저장&lt;/a&gt; · &lt;a href=&quot;https://gsretail.tistory.com/90&quot;&gt;2탄 권한&lt;/a&gt; · &lt;strong&gt;3탄-1부 대화 (이 글)&lt;/strong&gt; · &lt;a href=&quot;https://gsretail.tistory.com/93&quot;&gt;3탄-2부 대화&lt;/a&gt; · 4탄 채널 · 번외 수집&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock undefined&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;22787.jpg&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;960&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/02zUJ/btsMAMg3Wtb/7LuKJYntKKZdzNzAcaQAs0/tfile.dat&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/02zUJ/btsMAMg3Wtb/7LuKJYntKKZdzNzAcaQAs0/tfile.dat&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/02zUJ/btsMAMg3Wtb/7LuKJYntKKZdzNzAcaQAs0/tfile.dat&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F02zUJ%2FbtsMAMg3Wtb%2F7LuKJYntKKZdzNzAcaQAs0%2Ftfile.dat&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;80&quot; height=&quot;960&quot; data-filename=&quot;22787.jpg&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;960&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;김헌기 Darion&lt;/strong&gt; · AX본부 &amp;gt; AI데이터부문 &amp;gt; AI혁신지원팀&lt;/p&gt;
&lt;p&gt;AI 및 공통 Tech 기반의 기술 표준화 업무를 수행하고 있습니다. 동료들과 함께 기술 문화 만들기와 낯선 기술자와의 인연의 시작에 관심이 많습니다.&lt;/p&gt;</description>
      <author>DarionKim</author>
      <guid isPermaLink="true">https://gsretail.tistory.com/92</guid>
      <comments>https://gsretail.tistory.com/92#entry92comment</comments>
      <pubDate>Fri, 10 Jul 2026 13:56:17 +0900</pubDate>
    </item>
    <item>
      <title>[사내 지식 AI 만들기 ②&amp;middot;권한] 지식을 한곳에 모았더니, 아무나 다 볼 수 있게 됐다 &amp;mdash; payload 필터로 RBAC를 다시 세운 이유</title>
      <link>https://gsretail.tistory.com/90</link>
      <description>&lt;h2&gt;통합의 청구서&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://gsretail.tistory.com/89&quot;&gt;1탄&lt;/a&gt;에서 우리는 KB마다 따로 있던 컬렉션을 하나로 합쳤다. 컬렉션 폭증은 사라졌고, 끝없이 늘어나는 지식에 드디어 대응이 됐다. 그런데 합쳐진 건 컬렉션만이 아니었다 — &lt;strong&gt;격리도 같이 합쳐졌다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;per-KB 컬렉션 시절엔 격리가 _공짜_였다. 인사 KB는 인사 컬렉션에만 있으니, 다른 컬렉션을 안 보면 그만이었다. 물리적인 벽. 그런데 모든 KB가 한 컬렉션에 들어오자 — 그 벽이 사라졌다. 아무 필터 없이 검색하면 &lt;strong&gt;모두가 모든 지식을&lt;/strong&gt; 본다. 인사 평가도, 다른 부문 기밀도.&lt;/p&gt;
&lt;p&gt;통합의 청구서가 날아온 것이다: &amp;quot;이제 누가, 무엇을, 볼 수 있게 할 것인가?&amp;quot;&lt;/p&gt;
&lt;p&gt;사실 이 질문은 우리가 먼저 던진 게 아니었다. &lt;strong&gt;엔터프라이즈 AI를 도입하려는 조직이 가장 먼저 묻는 질문&lt;/strong&gt;이 항상 이거였다. &amp;quot;우리 회사 전체 지식을 하나의 AI에 모으면, 신입사원이 임원 보고서를 검색해서 읽을 수 있는 거 아닌가?&amp;quot; — 보안·권한 관리는 옵션이 아니라 &lt;strong&gt;엔터프라이즈 AI가 팔리기 위한 전제조건&lt;/strong&gt;이었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2070&quot; data-origin-height=&quot;1118&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RLt7o/dJMcagMUHdF/zID4UIAkfaCArsFwnUcSN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RLt7o/dJMcagMUHdF/zID4UIAkfaCArsFwnUcSN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RLt7o/dJMcagMUHdF/zID4UIAkfaCArsFwnUcSN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRLt7o%2FdJMcagMUHdF%2FzID4UIAkfaCArsFwnUcSN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2070&quot; height=&quot;1118&quot; data-origin-width=&quot;2070&quot; data-origin-height=&quot;1118&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;물리 벽 대신, 출입증&lt;/h2&gt;
&lt;p&gt;선진사례(Qdrant multitenancy, Azure의 security trimming)의 답은 같았다. &lt;strong&gt;물리 분리 대신 payload 필터.&lt;/strong&gt; 모든 청크에 &amp;quot;출입증&amp;quot; 메타데이터를 박고, 질의 시 그 사용자가 통과할 수 있는 것만 본다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;청크 payload
{ tenant_id, kb_id, kb_tier, acl, ... }   + tenant_index (is_tenant=true)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;4-tier 권한 모델:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tier&lt;/th&gt;
&lt;th&gt;접근&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;GLOBAL&lt;/td&gt;
&lt;td&gt;전사 공통 (인프라·전사 지식)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BU&lt;/td&gt;
&lt;td&gt;조직(부문) 일치&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TEAM&lt;/td&gt;
&lt;td&gt;부서 일치 또는 명시적 공유&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PERSONAL&lt;/td&gt;
&lt;td&gt;개인 소유 — 본인만 접근, 본인이 직접 지식을 만들고 관리&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;기존 조직 위계(GLOBAL→BU→TEAM)만으로는 부족했다. &lt;strong&gt;개인도 자기 지식을 직접 관리&lt;/strong&gt;할 수 있어야 했다 — 회사 조직도에 없는, 그 사람만의 메모·노트·업무 자료. 그래서 tier 하나를 더 열었다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;질문 → 사용자 신원(tenant/부서/role/tier) 해석
     → payload 필터 자동 주입
     → 통합 컬렉션 검색 (접근 가능한 KB만 매칭)
     → 결과&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Qdrant는 이 4-tier 자체를 코드로 하드코딩하지 않는다. &lt;strong&gt;payload 스키마가 YAML 설정&lt;/strong&gt;이라, tier 종류를 늘리거나 조직의 RBAC 정책이 바뀌어도 컬렉션 구조를 새로 짜지 않고 설정만 반영하면 됐다 — 이게 개인 tier를 추가로 여는 결정이 부담 없었던 이유다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;권한 스택:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;신원 확인   : Azure AD(Teams 싱글사인온) / OIDC(로그인 표준 프로토콜)
조직 동기화 : HR 시스템 ↔ 조직 디렉토리 sync
정책 엔진   : Casbin (RBAC/ABAC 정책 평가)
격리 실행   : Qdrant payload 필터 + tenant index
위반 감지   : 무필터 검색 차단 + 관측 알림(Datadog)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;풀어 쓰면: 사용자가 Teams에 로그인한 세션(싱글사인온, SSO)을 그대로 넘겨받아 &amp;quot;이 사람이 누구인지&amp;quot;를 확인하고, 그 신원에 조직 위계에 따른 권한(역할 기반 접근제어, RBAC)과 민감도 등급에 따른 권한(속성 기반 접근제어, ABAC)을 함께 적용한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2082&quot; data-origin-height=&quot;716&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brrjv4/dJMcac4I7X6/7X4iCKDfxa7iss14OjEUH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brrjv4/dJMcac4I7X6/7X4iCKDfxa7iss14OjEUH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brrjv4/dJMcac4I7X6/7X4iCKDfxa7iss14OjEUH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbrrjv4%2FdJMcac4I7X6%2F7X4iCKDfxa7iss14OjEUH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2082&quot; height=&quot;716&quot; data-origin-width=&quot;2082&quot; data-origin-height=&quot;716&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;&amp;quot;kb_id는 장식이 아니다&amp;quot;&lt;/h2&gt;
&lt;p&gt;가장 중요한 깨달음 한 줄:&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;공유 컬렉션에서 &lt;strong&gt;kb_id는 cosmetic 메타필드가 아니라 _접근 경계_다.&lt;/strong&gt;&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;per-KB 시절 kb_id는 그냥 라벨이었다. 통합 컬렉션에선 그게 &lt;em&gt;벽&lt;/em&gt;이다. 그래서 우리는 이 계약을 &lt;strong&gt;검색 엔진이 소유&lt;/strong&gt;하게 했다 — 호출자가 매번 필터를 깜빡하지 않도록, 엔진이 항상 강제한다.&lt;/p&gt;
&lt;p&gt;그리고 &lt;strong&gt;fail-closed&lt;/strong&gt;: 혹시라도 필터 없이 공유 컬렉션을 검색하려는 코드가 있으면? &lt;strong&gt;거부하고 경보한다.&lt;/strong&gt; &amp;quot;권한을 깜빡한 검색&amp;quot;은 버그가 아니라 보안 사고다. 그래서 무필터 공유-컬렉션 검색은 차단이 기본값이다.&lt;/p&gt;
&lt;h2&gt;출입증은 한 번 발급으로 끝나지 않는다&lt;/h2&gt;
&lt;p&gt;출입증에는 또 다른 함정이 있다. &lt;strong&gt;발급하고 끝이 아니라는 것.&lt;/strong&gt; 사람은 입사하고, 부서를 옮기고, 퇴사한다. 출입증이 그때그때 갱신되지 않으면 — 옮긴 부서의 문은 못 열고, 떠난 부서의 문은 여전히 열리는 유령 출입증이 남는다.&lt;/p&gt;
&lt;p&gt;그래서 접근제어는 권한 로직 하나로 끝나는 일이 아니었다. &lt;strong&gt;인사 시스템의 조직 정보와 지속적으로 동기화&lt;/strong&gt;돼야 했다 — 누가 어느 조직에 속했는지가 바뀔 때마다, 그 사람의 출입증(payload 필터가 참조하는 신원)도 같이 갱신된다. 권한은 한 번 세우는 구조가 아니라, &lt;strong&gt;계속 맞춰 나가야 하는 흐름&lt;/strong&gt;이었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1892&quot; data-origin-height=&quot;762&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcXZ6m/dJMcadP3vnC/RGvhQoCxeCDrJ3g0jMZ22k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcXZ6m/dJMcadP3vnC/RGvhQoCxeCDrJ3g0jMZ22k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcXZ6m/dJMcadP3vnC/RGvhQoCxeCDrJ3g0jMZ22k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcXZ6m%2FdJMcadP3vnC%2FRGvhQoCxeCDrJ3g0jMZ22k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1892&quot; height=&quot;762&quot; data-origin-width=&quot;1892&quot; data-origin-height=&quot;762&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;한 단계 더 — tier ABAC&lt;/h2&gt;
&lt;p&gt;같은 KB 안에서도 민감도(tier)가 다른 청크가 있다. 그래서 사용자 tier에 맞는 것만 통과시키는 &lt;strong&gt;속성 기반 접근제어(ABAC)&lt;/strong&gt;를 공유 검색 경로에 얹었다. kb_id로 _어느 KB_를, tier로 _그 안의 어느 등급_까지를 거른다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1966&quot; data-origin-height=&quot;1060&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnG4M1/dJMcagTDgDV/nePnJKOzK4yWA7qvMDVdx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnG4M1/dJMcagTDgDV/nePnJKOzK4yWA7qvMDVdx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnG4M1/dJMcagTDgDV/nePnJKOzK4yWA7qvMDVdx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnG4M1%2FdJMcagTDgDV%2FnePnJKOzK4yWA7qvMDVdx1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1966&quot; height=&quot;1060&quot; data-origin-width=&quot;1966&quot; data-origin-height=&quot;1060&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;실전에서 — 4단계 권한이 3단계까지만 살아있었던 이야기&lt;/h2&gt;
&lt;p&gt;우리 시스템은 GLOBAL → BU → TEAM → PERSONAL, 4단계로 권한을 나눴다. 그런데 실제로 붙여보니 GLOBAL과 BU까지만 제대로 동작했다. TEAM과 PERSONAL은 설계는 있었지만, 코드는 &amp;quot;항상 빈 목록&amp;quot;을 돌려주는 껍데기였다 — 자기 팀 KB조차 누구도 볼 수 없는 상태로 방치돼 있었던 것.&lt;/p&gt;
&lt;p&gt;원인을 파고들자 진짜 문제가 나왔다. &lt;strong&gt;부서 매칭을 이름으로 하고 있었다.&lt;/strong&gt; &amp;quot;인사팀&amp;quot;이라는 문자열이 인사 시스템 쪽과 우리 쪽에서 한 글자라도 다르면 — 매칭 실패, 그 사람은 자기 부서 KB를 못 본다. 조직개편 한 번이면 전체가 깨질 수 있는 구조였다.&lt;/p&gt;
&lt;p&gt;고친 방법은 이름 대신 &lt;strong&gt;안정적인 코드&lt;/strong&gt;를 쓰는 것이었다. 인사 시스템이 주는 고유 조직 코드를 사람의 신원 토큰에 실어 나르고, 그 코드로만 매칭한다. 이름은 바뀌어도 코드는 안 바뀐다. 그리고 그 코드를 매 HR 동기화마다 다시 써준다 — &amp;quot;출입증은 한 번 발급으로 끝나지 않는다&amp;quot;는 원칙을 코드로 만든 것.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;666&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mHo4A/dJMcabkwF9e/FPonUHr2rpUQVIoAQIFK41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mHo4A/dJMcabkwF9e/FPonUHr2rpUQVIoAQIFK41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mHo4A/dJMcabkwF9e/FPonUHr2rpUQVIoAQIFK41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmHo4A%2FdJMcabkwF9e%2FFPonUHr2rpUQVIoAQIFK41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;666&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;666&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;심화 — 권한을 &amp;quot;검색 엔진이 소유&amp;quot;하게 만든 코드&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;이 절은 깊다. payload 필터가 실제로 어떻게 강제되는지 코드까지 궁금한 분을 위한 detail이다. 바쁘면 맺음으로 건너뛰어도 좋다.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;① fail-closed는 문장이 아니라 코드다&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;앞에서 &amp;quot;무필터 검색은 차단이 기본값&amp;quot;이라 했다. 그 문장의 실체는 이렇다 — 공유 컬렉션을 &lt;code&gt;kb_id&lt;/code&gt; 필터 없이 검색하려 하면, 검색 엔진이 &lt;strong&gt;거부하고 빈 결과를 돌려주며 경보를 쏜다.&lt;/strong&gt; 에러로 죽이지도, 조용히 전체를 훑지도 않는다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 공유 프로파일 컬렉션은 여러 KB의 청크를 kb_id로 나눠 담는다.
# kb_id 필터 없이 조회 = KB 경계를 넘는 스캔(교차-KB 유출) → 거부.
if self._is_shared_profile_collection(collection_name, cfg) \
        and not self._filter_has_kb_id(filter_conditions):
    logger.error(&amp;quot;공유 컬렉션 무필터 검색 거부 — kb_id 필터 없음: %s&amp;quot;, collection_name)
    emit_silent_fail(area=&amp;quot;kb_search&amp;quot;, signal=&amp;quot;profile_collection_unfiltered&amp;quot;,
                     reason=&amp;quot;no_kb_id_filter&amp;quot;, collection=collection_name)
    return []   # ← raise가 아니라 &amp;quot;빈 결과 + 카운터&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;이 계약을 &lt;strong&gt;검색 엔진이 소유&lt;/strong&gt;한다. 동반 함수의 docstring이 이 글 본문 문장을 거의 그대로 적고 있다 — &amp;quot;&lt;code&gt;kb_id&lt;/code&gt;는 cosmetic payload 필드가 아니라 접근 경계다. 검색 엔진이 이 계약을 소유하므로, 호출자가 매 진입점마다 같은 필터를 기억할 필요가 없다.&amp;quot; 본문의 &amp;quot;검색 엔진이 소유&amp;quot;는 마케팅 문구가 아니라 실제 코드 주석의 의역이다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;② 영리한 선택 — 엔진을 새로 들이지 않고, 있는 걸 확장&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;조직 위계(org-tree) + 상속 + 민감도(tier) 속성을 한 번에 평가하는 이 문제엔 업계 정석이 여럿 있다. 우리가 비교한 4가지 — SharePoint식 site→library 상속, Confluence식 space 격리, Google Drive OU+공유드라이브, 그리고 Casbin/OpenFGA식 ReBAC 튜플. 개념적으로 가장 잘 맞은 건 &lt;strong&gt;ReBAC 튜플 shape&lt;/strong&gt;(상속 있는 org-tree)였다.&lt;/p&gt;
&lt;p&gt;그런데 우리는 그걸 위해 &lt;strong&gt;새 엔진(OpenFGA)을 들이지 않고&lt;/strong&gt;, 이미 쓰던 &lt;strong&gt;Casbin 하나 안에서&lt;/strong&gt; 표현했다 — Casbin의 role 계층(&lt;code&gt;g&lt;/code&gt;)과 org-tree 그룹핑(&lt;code&gt;g2&lt;/code&gt;)이 같은 shape를 &lt;strong&gt;추가 인프라 0으로&lt;/strong&gt; 커버했기 때문. &amp;quot;새 문제 = 새 엔진&amp;quot;이 아니라 &amp;quot;있는 엔진의 표현력부터 확인&amp;quot;이 먼저였다. (&lt;code&gt;model.conf&lt;/code&gt;엔 정밀도 선택도 박혀 있다 — &lt;code&gt;keyMatch2&lt;/code&gt; 대신 &lt;code&gt;keyMatch&lt;/code&gt;: &lt;code&gt;keyMatch2&lt;/code&gt;는 &lt;code&gt;:&lt;/code&gt;를 경로 파라미터로 취급해 &lt;code&gt;mcp:adapter:tool&lt;/code&gt; 같은 식별자를 너무 넓게 매칭시키기 때문.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;③ 숫자, 정직하게 — 아직 없다&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;이 권한 엔진의 실측 성능 숫자(&lt;code&gt;enforce()&lt;/code&gt; p99 latency 등)는 아직 없다. 설계 목표로 &amp;quot;org-tree 깊이 ≤5 → 정책 평가 &amp;lt;5ms p99&amp;quot;를 잡아뒀지만 그건 target이지 measured가 아니다. 여기서도 시리즈 규율을 지킨다 — 없는 숫자를 지어내지 않는다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;④ 우리가 처음엔 틀렸다 — 같은 기능, 두 경로가 조용히 갈라지다&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;본문의 &amp;quot;이름 매칭 → 조직 코드 매칭&amp;quot;은 신원 데이터가 시간이 지나며 낡는 이야기였다. 결이 다른 두 번째 사고가 하나 더 있다.&lt;/p&gt;
&lt;p&gt;tier-ABAC(민감도 필터)가 &lt;strong&gt;같은 공유 컬렉션을 치는 두 경로 사이에서 비대칭&lt;/strong&gt;이었다. 주(主) 검색 경로는 tier 필터를 제대로 걸었는데, 나중에 붙은 &amp;quot;보조&amp;quot; 경로는 &lt;strong&gt;안 걸었다.&lt;/strong&gt; 요청이 어쩌다 보조 경로로 흐르면, 자기 tier보다 높은 청크가 조용히 보일 수 있었다 — 에러도 알림도 없이.&lt;/p&gt;
&lt;p&gt;이걸 잡은 건 사용자 신고가 아니라 &lt;strong&gt;일부러 &amp;quot;두 경로가 대칭인가&amp;quot;를 감사한 것&lt;/strong&gt;이었다(&amp;quot;당연히 같겠지&amp;quot; 하고 안 보던 경로였으니까). 고친 방식이 흥미롭다 — 한 방에 안 고치고 3단계로: (1) 우선 무필터 스캔을 막는 fail-closed 가드(①)를 안전망으로 즉시 투입 → (2) 빠진 tier 필터를 보조 경로에 추가하되 &lt;strong&gt;기본 off인 feature flag 뒤에&lt;/strong&gt; 둬서 격리 검증 → (3) 그다음에야 검색 실행기 전체를 tier-aware로 확장.&lt;/p&gt;
&lt;p&gt;재발을 눈에 보이게 하려고 카운터 3개를 심었다: &amp;quot;무필터로 공유 컬렉션 도달&amp;quot;(항상 0이어야) · &amp;quot;tier 필터 빌더가 실패해 no-tier로 fallback&amp;quot;(항상 0이어야) · &amp;quot;tier 필터가 실제 적용됨&amp;quot;(이게 0인데 flag는 켜져 있으면 = 코드가 새 경로를 안 타는 silent no-op cutover 감지).&lt;/p&gt;
&lt;p&gt;교훈: 신원 데이터가 낡는 것(본문)과, &lt;strong&gt;같은 기능을 구현한 두 코드 경로가 조용히 갈라지는 것&lt;/strong&gt;은 다른 종류의 사고다. 후자는 실패 신호를 기다리면 안 보이고, &amp;quot;대칭인지 일부러 확인&amp;quot;해야만 드러난다.&lt;/p&gt;
&lt;h2&gt;맺음 — 그리고 새로운 문제&lt;/h2&gt;
&lt;p&gt;출입증 구조(payload 필터 + fail-closed + tier ABAC)는 섰다. 통합 컬렉션의 효율을 가지면서도, 권한을 다시 세웠다.&lt;/p&gt;
&lt;p&gt;그런데 1탄에서 배운 게 하나 있다. &lt;strong&gt;구조가 섰다고 문제가 끝난 게 아니다.&lt;/strong&gt; &amp;quot;코드에 출입증 검사가 있다&amp;quot;와 &amp;quot;모든 경로가 실제로 그 검사를 통과하는가&amp;quot;는 다른 질문이다. 새 경로가 하나 늘 때마다, 그 경로도 출입증을 확인하는지 계속 확인해야 한다 — 이것도 결국 저장 구조와 똑같이, _운영하면서 증명해야 하는 일_이다.&lt;/p&gt;
&lt;p&gt;그리고 — 사용자는 여전히 한 줄로 묻지 않았다. &amp;quot;이 질문은 _어느 KB_를 봐야 하지?&amp;quot;가 남았다. 출입증은 &amp;quot;못 들어가는 문&amp;quot;만 막아줄 뿐, &amp;quot;이 사람이 평소 자주 드나드는 문이 어딘지&amp;quot;는 알려주지 않는다. 그걸 사람이 골라주던 시절의 한계, 그리고 그걸 에이전트에게 넘긴 이야기는 &lt;strong&gt;&lt;a href=&quot;https://gsretail.tistory.com/92&quot;&gt;3탄-1부 — 사용자는 한 줄로 묻지 않았다&lt;/a&gt;&lt;/strong&gt;에서.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;시리즈&lt;/strong&gt;: &lt;a href=&quot;https://gsretail.tistory.com/89&quot;&gt;1탄 저장&lt;/a&gt; · &lt;strong&gt;2탄 권한 (이 글)&lt;/strong&gt; · &lt;a href=&quot;https://gsretail.tistory.com/92&quot;&gt;3탄-1부 대화&lt;/a&gt; · &lt;a href=&quot;https://gsretail.tistory.com/93&quot;&gt;3탄-2부 대화&lt;/a&gt; · 4탄 채널 · 번외 수집&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock undefined&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;22787.jpg&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;960&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/02zUJ/btsMAMg3Wtb/7LuKJYntKKZdzNzAcaQAs0/tfile.dat&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/02zUJ/btsMAMg3Wtb/7LuKJYntKKZdzNzAcaQAs0/tfile.dat&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/02zUJ/btsMAMg3Wtb/7LuKJYntKKZdzNzAcaQAs0/tfile.dat&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F02zUJ%2FbtsMAMg3Wtb%2F7LuKJYntKKZdzNzAcaQAs0%2Ftfile.dat&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;80&quot; height=&quot;960&quot; data-filename=&quot;22787.jpg&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;960&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;김헌기 Darion&lt;/strong&gt; · AX본부 &amp;gt; AI데이터부문 &amp;gt; AI혁신지원팀&lt;/p&gt;
&lt;p&gt;AI 및 공통 Tech 기반의 기술 표준화 업무를 수행하고 있습니다. 동료들과 함께 기술 문화 만들기와 낯선 기술자와의 인연의 시작에 관심이 많습니다.&lt;/p&gt;</description>
      <category>Data&amp;amp;AI</category>
      <author>DarionKim</author>
      <guid isPermaLink="true">https://gsretail.tistory.com/90</guid>
      <comments>https://gsretail.tistory.com/90#entry90comment</comments>
      <pubDate>Thu, 2 Jul 2026 11:07:46 +0900</pubDate>
    </item>
    <item>
      <title>[사내 지식 AI 만들기 ①&amp;middot;저장] 컬렉션이 KB만큼 늘어나기 시작했다</title>
      <link>https://gsretail.tistory.com/89</link>
      <description>&lt;h2&gt;종합 공구 상자와, 내가 필요했던 전동 드릴&lt;/h2&gt;
&lt;p&gt;처음 사내에 RAG를 붙였을 때, 우리의 벡터 DB는 &lt;strong&gt;AWS OpenSearch&lt;/strong&gt;였다 — 처음 도입한 1세대 지식 솔루션이 고른 선택이었다.&lt;/p&gt;
&lt;p&gt;좋았다. 진심으로. 색인 만들고, 임베딩 넣고, k-NN 한 번 던지면 — 끝이었다. &amp;quot;이거면 되네?&amp;quot; 싶었다.&lt;/p&gt;
&lt;p&gt;OpenSearch도, 그 뿌리인 Elasticsearch도 &lt;strong&gt;이미 검증된 솔루션&lt;/strong&gt;이다. 누구도 쉽게 &amp;quot;나쁘다&amp;quot;고 말 못 한다. 로그도 보고, 전문 검색도 하고, 분석도 하고, 벡터도 한다. 뭐든 한다.&lt;/p&gt;
&lt;p&gt;그게 정확히 문제였다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;그건 &lt;strong&gt;종합 공구 상자&lt;/strong&gt;였다. 그런데 나는 벽에 구멍 하나 — &lt;strong&gt;RAG&lt;/strong&gt; — 를 뚫어야 했다. 망치도 줄자도 필요 없었다. 나는 &lt;strong&gt;RAG 하나를 제대로 파는 전동 드릴&lt;/strong&gt;이 필요했다.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;이 글은 그 드릴을 찾아 &lt;strong&gt;Qdrant&lt;/strong&gt;로 가고, 거기서 첫 번째 설계를 보기 좋게 말아먹고, 다시 설계한 이야기다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2044&quot; data-origin-height=&quot;712&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmzZzM/dJMcadbo3xw/v4Q0j0gniSKnHjiVDkQFn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmzZzM/dJMcadbo3xw/v4Q0j0gniSKnHjiVDkQFn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmzZzM/dJMcadbo3xw/v4Q0j0gniSKnHjiVDkQFn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcmzZzM%2FdJMcadbo3xw%2Fv4Q0j0gniSKnHjiVDkQFn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2044&quot; height=&quot;712&quot; data-origin-width=&quot;2044&quot; data-origin-height=&quot;712&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;1. 공구 상자의 한계 — 비용, 그리고 &amp;quot;RAG 특화&amp;quot;의 부재&lt;/h2&gt;
&lt;p&gt;작은 RAG에선 OpenSearch가 잘 돌았다. 그런데 &lt;em&gt;사내 지식 전체&lt;/em&gt;로 미션이 커지자 두 가지가 보였다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;① 비용.&lt;/strong&gt; 규모가 커질수록 운영 비용이 먼저 말을 걸어왔다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;② RAG 특화 기능의 부재.&lt;/strong&gt; 이게 더 컸다. 좋은 한국어 enterprise RAG에 필요한 것들 —&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;dense(의미) + sparse(정확어) &lt;strong&gt;하이브리드&lt;/strong&gt; 검색&lt;/li&gt;
&lt;li&gt;한 청크에 여러 임베딩 표현을 얹는 &lt;strong&gt;named vector&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;수십 KB·권한을 컬렉션 폭증 없이 다루는 &lt;strong&gt;payload 기반 멀티테넌시&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;토큰 단위 &lt;strong&gt;late-interaction rerank&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;— 공구 상자엔 &amp;quot;없거나, 직접 조립&amp;quot;이었다. 할 수는 있다. 다만 &lt;em&gt;드릴 한 자루로 끝날 일을, 공구 상자 전체를 뒤지며&lt;/em&gt; 해야 했다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[문서] → [임베딩] → OpenSearch k-NN → top-k → LLM → 답변
   ↑ 작을 땐 충분했다.  ↑ 사내 지식 &amp;quot;전체&amp;quot;엔 부족했다.&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;2. 미션, 그리고 전동 드릴(Qdrant)을 고르다&lt;/h2&gt;
&lt;p&gt;미션이 떨어졌다. &lt;strong&gt;&amp;quot;사내 지식 전체를 검색하게 만들어라.&amp;quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;지식 &lt;em&gt;플랫폼&lt;/em&gt;을 만들려면 검색 엔진 요구사항이 달라진다. 우리가 본 기준:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;요구&lt;/th&gt;
&lt;th&gt;왜 필요했나&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;named vectors (dense+sparse+late-interaction)&lt;/td&gt;
&lt;td&gt;의미 검색 + 정확어 검색을 한 포인트에&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;payload 기반 멀티테넌시&lt;/td&gt;
&lt;td&gt;끝없이 늘어날 KB·권한을 컬렉션 폭증 없이&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;hybrid + rerank 네이티브&lt;/td&gt;
&lt;td&gt;한국어 enterprise 검색 품질&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;self-host / 비용 통제&lt;/td&gt;
&lt;td&gt;사내 데이터 + 규모&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;→ &lt;strong&gt;Qdrant.&lt;/strong&gt; 종합 공구 상자가 아니라, RAG 하나를 제대로 파는 드릴.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;현재 기술 스택:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;임베딩(dense)  : OpenAI text-embedding-3-large
rerank         : Cohere rerank (LiteLLM 경유)
벡터 DB        : Qdrant (named vectors + payload multitenancy)
그래프 컨텍스트: Neo4j&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;3. 첫 번째 실수 — KB 하나에 컬렉션 하나&lt;/h2&gt;
&lt;p&gt;드릴을 손에 쥐고, 우리는 가장 자연스러운 첫 설계를 했다. &lt;strong&gt;KB 하나 = Qdrant 컬렉션 하나.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CVS-KB     → collection: kb_cvs
HR-KB      → collection: kb_hr
물류-KB    → collection: kb_logistics
...&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;단일 KB 검색은 단순하고, 격리도 물리적으로 깔끔하다. &lt;strong&gt;데모는 예뻤다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;그리고 — 우리는 이 구조의 실패를 &lt;em&gt;이미 한 번 맛본 적이 있었다.&lt;/em&gt; 알면서도, 처음엔 또 직관을 따랐다.&lt;/p&gt;
&lt;p&gt;문제는 KB가 늘 때 터진다:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;교차 KB 질문 1건
   └─▶ N개 컬렉션에 각각 질의  →  클라이언트에서 결과 합치기
       (N = KB 수.  KB가 늘수록 비용·복잡도·운영지옥이 선형으로 증가)&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;컬렉션 수 = KB 수 → 지식이 늘면 컬렉션 &lt;strong&gt;폭증&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;교차/멀티 KB 검색은 매번 &lt;strong&gt;fan-out&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;임베딩 버전·인덱스 설정 같은 공통 정책을 &lt;strong&gt;N곳에 반복&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;사내 지식은 고정돼 있지 않다. 새 부서, 새 제품, 새 규정 — KB가 &lt;em&gt;끝없이&lt;/em&gt; 추가된다. 컬렉션이 KB만큼 늘어나기 시작한 순간, 이 구조의 수명은 정해져 있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2332&quot; data-origin-height=&quot;902&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4xTHQ/dJMcagTBo07/uzaGPmlKdOLeX7Ce3Kl421/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4xTHQ/dJMcagTBo07/uzaGPmlKdOLeX7Ce3Kl421/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4xTHQ/dJMcagTBo07/uzaGPmlKdOLeX7Ce3Kl421/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4xTHQ%2FdJMcagTBo07%2FuzaGPmlKdOLeX7Ce3Kl421%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2332&quot; height=&quot;902&quot; data-origin-width=&quot;2332&quot; data-origin-height=&quot;902&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;4. 다시 설계 — 운영 경계로 나눈 통합 컬렉션&lt;/h2&gt;
&lt;p&gt;그래서 1:1을 버렸다. 업계 선진사례(Qdrant·Azure AI Search·Elastic)의 공통 원칙은 같았다:&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;컬렉션은 &lt;strong&gt;운영 경계(콘텐츠 종류·테넌트·라이프사이클·ACL)&lt;/strong&gt;로 나눈다. &lt;strong&gt;KB로 나누지 않는다.&lt;/strong&gt; 같은 청크의 다른 임베딩 표현은 &lt;strong&gt;named vector&lt;/strong&gt;로, 테넌트/KB 격리는 &lt;strong&gt;payload 필터 + 테넌트 인덱스&lt;/strong&gt;로.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;pre&gt;&lt;code&gt;        통합 텍스트 컬렉션 (모든 KB 공유)
        ├─ named vector: dense(의미)  [+ sparse(정확어) — 품질 반전은 아래 §5]
        └─ payload: { tenant, kb_id, tier, acl, ... }
                            ▲
        질의 시: payload 필터로 &amp;quot;이 사용자가 접근 가능한 KB&amp;quot;만 조회
        (시각 자산은 별도 통합 컬렉션 — 텍스트와 다른 point population이므로)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;효과는 즉각적이었다. &lt;strong&gt;KB가 100개 추가돼도 컬렉션은 그대로&lt;/strong&gt;다. 교차 KB 검색은 단일 질의 + 필터. 새 KB 온보딩은 &amp;quot;컬렉션 생성&amp;quot;이 아니라 &amp;quot;payload 태깅&amp;quot;. 끝없이 자라는 지식 범위에 드디어 대응이 된다.&lt;/p&gt;
&lt;h2&gt;심화 — 1:1 구조 vs 통합 구조, 코드 레벨로 뜯어보기&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;이 절은 깊다. &lt;em&gt;왜&lt;/em&gt; 1:1을 버렸는지 메커니즘까지 궁금한 분을 위한 detail이다. 바쁘면 §5로 건너뛰어도 좋다.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;한눈에:&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;차원&lt;/th&gt;
&lt;th&gt;1:1 (KB = 컬렉션)&lt;/th&gt;
&lt;th&gt;통합 (운영 경계)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;매핑&lt;/td&gt;
&lt;td&gt;KB N개 = 컬렉션 N개 (&lt;code&gt;kb_&amp;lt;id&amp;gt;&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;content type별 소수 (텍스트 / 시각자산)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;분리 기준&lt;/td&gt;
&lt;td&gt;KB&lt;/td&gt;
&lt;td&gt;point population (콘텐츠 종류)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;격리&lt;/td&gt;
&lt;td&gt;물리 (컬렉션 경계)&lt;/td&gt;
&lt;td&gt;논리 (payload 필터 + 인덱싱된 필드)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;벡터&lt;/td&gt;
&lt;td&gt;컬렉션마다 dense + sparse&lt;/td&gt;
&lt;td&gt;한 포인트에 named vector 다중&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;교차 KB 검색&lt;/td&gt;
&lt;td&gt;N개 fan-out + 클라이언트 병합&lt;/td&gt;
&lt;td&gt;단일 질의 + 필터 (서버사이드)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;융합(fusion)&lt;/td&gt;
&lt;td&gt;클라이언트가 점수 섞기&lt;/td&gt;
&lt;td&gt;서버사이드 RRF&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;재색인&lt;/td&gt;
&lt;td&gt;컬렉션별&lt;/td&gt;
&lt;td&gt;alias blue/green 무중단&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;비용&lt;/td&gt;
&lt;td&gt;컬렉션·HNSW 그래프 N배&lt;/td&gt;
&lt;td&gt;소수 고정&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;표만으론 &lt;em&gt;왜&lt;/em&gt; 그런지 안 보인다. 핵심 메커니즘 5개를 뜯어보자.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;① named vector — &amp;quot;컬렉션을 늘리지 말고, 포인트에 표현을 얹어라&amp;quot;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;흔한 오해: &amp;quot;dense랑 sparse는 다른 검색이니 컬렉션을 따로 만들자.&amp;quot; 틀렸다. Qdrant에선 &lt;strong&gt;한 포인트에 여러 벡터를 이름 붙여&lt;/strong&gt; 얹는다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;point {
  vectors: {
    dense   : [1536차원]      # 의미(dense)
    sparse  : {index: value}  # 정확어(sparse, 희소)
    colbert : 토큰별 multivector  # (설계) 재정렬 전용
  },
  payload: { tenant_id, kb_id, tier, acl, ... }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;같은 청크의 다른 표현이 &lt;em&gt;같은 포인트&lt;/em&gt;에 사니, 질의 때 dense·sparse를 함께 쓸 수 있다. 컬렉션을 새로 만드는 건 &amp;quot;벡터 종류&amp;quot;가 달라서가 아니라, &lt;strong&gt;&amp;quot;포인트 집단(콘텐츠 종류)&amp;quot;이 다를 때만&lt;/strong&gt;이다. 텍스트 청크와 이미지/표 자산은 다른 집단이라 컬렉션을 나눴고, dense·sparse·ColBERT는 같은 청크라 named vector로 얹었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1753&quot; data-origin-height=&quot;444&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AGqB0/dJMcabSeFMC/G6D0MMniD8Rl2FbHziZAqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AGqB0/dJMcabSeFMC/G6D0MMniD8Rl2FbHziZAqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AGqB0/dJMcabSeFMC/G6D0MMniD8Rl2FbHziZAqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAGqB0%2FdJMcabSeFMC%2FG6D0MMniD8Rl2FbHziZAqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1753&quot; height=&quot;444&quot; data-origin-width=&quot;1753&quot; data-origin-height=&quot;444&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;② payload 멀티테넌시 — 공유 컬렉션에서 &amp;quot;내 KB만&amp;quot; 좁히기&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;quot;다 합치면 느리지 않나?&amp;quot; 통합 컬렉션은 &lt;code&gt;tenant_id&lt;/code&gt; / &lt;code&gt;kb_id&lt;/code&gt;를 &lt;strong&gt;인덱싱된 payload 필드&lt;/strong&gt;로 두고, 질의 시 그 필드로 먼저 좁힌 다음 벡터를 본다. 물리 분리 없이도 &amp;quot;내가 접근 가능한 KB만&amp;quot; 검색 범위에서 걸러낸다. 1:1이 &amp;quot;물리 벽으로 격리&amp;quot;했다면, 통합은 &amp;quot;인덱스로 격리&amp;quot;한다.&lt;/p&gt;
&lt;p&gt;여기에 Qdrant는 한 단계 더 — 테넌트 수가 많을 때를 위한 &lt;strong&gt;tenant 전용 최적화 인덱스&lt;/strong&gt;(&lt;code&gt;is_tenant: true&lt;/code&gt;)를 제공한다. 정확히 이 용도다. 그런데 &lt;em&gt;정직하게&lt;/em&gt;: 우리 라이브 컬렉션 생성 코드는 아직 &lt;strong&gt;plain keyword index만&lt;/strong&gt; 부른다. tenant 최적화 인덱스는 &amp;quot;쓸 수 있는데 아직 안 켠&amp;quot; 상태다 — 이 얘기는 §심화 애프터노트에서 다시 한다(이 글이 자기 반전을 한 번 더 겪는 자리다).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;③ 서버사이드 hybrid — prefetch + RRF (클라이언트 fan-out과 다른 점)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1:1에서 교차 KB 검색은 — N개 컬렉션에 각각 질의하고, 클라이언트가 서로 다른 점수 체계를 &lt;em&gt;제멋대로&lt;/em&gt; 섞어 병합했다. 통합에선 Qdrant Query API가 서버 안에서 처리한다:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;prefetch(sparse, limit=100)  ─┐
prefetch(dense,  limit=100)  ─┤→  RRF(서버사이드 순위 융합)  →  [선택] ColBERT 재정렬  →  top_n
                              ┘&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;여기서 RRF(Reciprocal Rank Fusion)는 &lt;strong&gt;저장 구조가 아니라 &lt;em&gt;질의 융합 방법&lt;/em&gt;&lt;/strong&gt;이다. 흔한 오해: &amp;quot;RRF 컬렉션이나 RRF 벡터를 만들자&amp;quot; — 그런 건 없다. RRF는 여러 prefetch 순위 리스트를 질의 시점에 합칠 뿐이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;&lt;em&gt;정직하게&lt;/em&gt;: 현재 prod 서빙은 dense 1선 + 외부 rerank다. sparse·RRF·ColBERT는 &lt;strong&gt;구조가 &lt;em&gt;지원&lt;/em&gt;하지만&lt;/strong&gt; 아직 품질 로드맵(§5)이다. &lt;strong&gt;&amp;quot;구조가 지원한다&amp;quot;와 &amp;quot;서빙 경로가 그걸 쓴다&amp;quot;는 다른 일&lt;/strong&gt; — 이게 바로 이 글의 반전이다.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;④ 멱등 point_id — 재색인해도 중복이 안 생기는 이유&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1:1에서 흔한 사고: 재색인하면 같은 청크가 또 들어가 중복이 쌓인다. 통합에선 &lt;strong&gt;결정적(deterministic) ID&lt;/strong&gt;를 쓴다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;point_id = {tenant}:{kb}:{document}:{page}:{chunk}:{embedding_version}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;같은 청크는 항상 같은 ID → upsert가 덮어쓴다. 재색인이 안전해지고, 임베딩 버전을 ID에 넣으니 버전 교체도 깔끔하다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;⑤ HNSW 비용 + blue/green alias&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;컬렉션마다 HNSW 그래프가 &lt;em&gt;따로&lt;/em&gt; 선다. 컬렉션 N개 = 그래프 N개 = 메모리·관리 비용 N배. 통합은 2개로 끝. 그리고 ColBERT 같은 재정렬 전용 벡터는 &lt;code&gt;hnsw_config.m = 0&lt;/code&gt;으로 둔다 — &lt;strong&gt;그래프를 아예 안 만들고 선형 스캔&lt;/strong&gt;한다. 재정렬은 이미 추려진 후보만 보니 인덱스가 낭비이기 때문이다. 재색인이 필요하면 새 물리 컬렉션을 만들어 backfill한 뒤 &lt;strong&gt;alias만 바꿔(blue/green)&lt;/strong&gt; 무중단으로 전환하도록 &lt;strong&gt;설계했다&lt;/strong&gt; — 코드도 있고 테스트도 됐다. 다만 이건 feature flag로 켜고 끄는데, 지금 라이브에선 꺼져 있다(그래서 실제 alias는 아직 0개). &amp;quot;만들어 두고 아직 안 켠&amp;quot; 메커니즘이다. 이것도 §애프터노트에서 다시.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;mermaid-diagram-2026-06-30-094839.png&quot; data-origin-width=&quot;1184&quot; data-origin-height=&quot;444&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cie3e3/dJMcac4Hh7n/4pVKsXl7eiHkCeDRUfHliK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cie3e3/dJMcac4Hh7n/4pVKsXl7eiHkCeDRUfHliK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cie3e3/dJMcac4Hh7n/4pVKsXl7eiHkCeDRUfHliK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcie3e3%2FdJMcac4Hh7n%2F4pVKsXl7eiHkCeDRUfHliK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;551&quot; height=&quot;207&quot; data-filename=&quot;mermaid-diagram-2026-06-30-094839.png&quot; data-origin-width=&quot;1184&quot; data-origin-height=&quot;444&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;⑥ 결정을 문서가 아니라 코드로 못 박기 (architecture-as-code)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;quot;1:1을 버리고 통합으로 간다&amp;quot;는 건 설계 문서 한 줄로 끝날 수도 있었다. 문제는 — 문서는 읽지 않으면 그만이고, 6개월 뒤 누군가 &amp;quot;이 KB는 특별하니까 전용 컬렉션 하나 파자&amp;quot;라고 하면 조용히 원점이다. 그래서 우리는 이 결정을 &lt;strong&gt;런타임에서 강제&lt;/strong&gt;했다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;ADR012_PROFILE_COLLECTIONS = frozenset({ &amp;quot;&amp;lt;통합 텍스트 컬렉션&amp;gt;&amp;quot;, &amp;quot;&amp;lt;통합 시각자산 컬렉션&amp;gt;&amp;quot; })

def _assert_legacy_collection_creation_allowed(self, *, kb_id, collection_name):
    &amp;quot;&amp;quot;&amp;quot;ADR-012 컷오버 후, 실수로 per-KB 컬렉션을 만드는 걸 차단.&amp;quot;&amp;quot;&amp;quot;
    if self._provider.config.allow_nonstandard_collection_creation:
        return  # 명시적·시한부 레거시 마이그레이션 창구에서만
    raise NonStandardQdrantCollectionError(
        f&amp;quot;비-ADR-012 컬렉션 생성 거부: kb_id={kb_id!r}, collection={collection_name!r}. &amp;quot;
        &amp;quot;통합 프로파일 컬렉션을 쓰거나, 환경변수로 명시적 마이그레이션 창을 열어라.&amp;quot;
    )&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;레거시 per-KB 컬렉션 생성 경로로 들어오는 모든 호출은 sanctioned된 통합 컬렉션 이름 집합과 대조되고, 새 비표준 컬렉션은 &lt;strong&gt;명시적으로 이름 붙은 환경변수 escape hatch&lt;/strong&gt;를 켜지 않는 한 기본적으로 거부된다. 결정이 문서로만 남지 않고 &lt;strong&gt;구조적으로 회귀 불가능&lt;/strong&gt;해지는 것 — 앞 표의 &amp;quot;매핑: content type별 소수&amp;quot;가 지켜지는 진짜 이유다.&lt;/p&gt;
&lt;p&gt;이 여섯이 &amp;quot;1:1을 버린 이유&amp;quot;의 실체다. 앞 표의 각 줄 뒤엔 이 메커니즘이 있다.&lt;/p&gt;
&lt;h3&gt;심화 애프터노트 — 이 글을 쓰고, 코드를 다시 봤더니&lt;/h3&gt;
&lt;p&gt;솔직한 고백으로 이 심화를 닫자. 위 ②(tenant 최적화 인덱스)와 ⑤(alias 무중단 전환)를 &lt;strong&gt;처음 쓸 때 우리는 &amp;quot;이렇게 한다&amp;quot;고 적었다.&lt;/strong&gt; 발행하고 나서 코드를 다시 열었더니 — 서술이 코드보다 &lt;strong&gt;앞서 있었다.&lt;/strong&gt; tenant 전용 인덱스는 라이브가 아직 안 부르고 있었고, alias 전환은 flag가 꺼져 실제 alias가 0개였다. 둘 다 &amp;quot;구조는 지원, 서빙은 아직&amp;quot; — 이 글 §5가 말하려는 바로 그 gap을, &lt;strong&gt;이 글 자신이 저지르고 있었다.&lt;/strong&gt; 그래서 위 두 문단을 고쳐 썼고, 이 애프터노트를 남긴다. 완료를 다시 정의한 글이 자기 서술까지 receipt로 검증받지 않으면 그건 위선이니까.&lt;/p&gt;
&lt;p&gt;그리고 이왕 고백하는 김에 — ④(멱등 point_id)에도 뒷이야기가 있다. 결정적 ID는 재색인 시 중복을 막아준다. 그런데 그게 point-id의 &lt;em&gt;타입&lt;/em&gt; 일관성까지 보장하진 않았다.&lt;/p&gt;
&lt;p&gt;Qdrant의 point ID는 &lt;strong&gt;부호 없는 정수 아니면 UUID 문자열&lt;/strong&gt;이어야 한다 — 절대 &amp;quot;정수를 문자열로 담은 값&amp;quot;이면 안 된다. Qdrant가 문자열 ID는 UUID로 파싱하려 들기 때문이다. 그런데 서로 다른 시기에 서로 다른 ingest 소스로 들어온 탓에, 두 개의 KB만 정수 ID로 색인돼 있었고 나머지는 전부 UUID 문자열이었다. 후보를 추린 뒤 본문·late-interaction 벡터를 다시 당겨오는 hydration 경로가 &lt;strong&gt;모든 ID를 일괄 stringify&lt;/strong&gt;해서 Qdrant retrieve를 불렀고 — 정수-ID KB는 hydration이 100% &amp;quot;UUID 파싱 실패&amp;quot;로 떨어졌다. 그러면 재시도 루프가 돌면서 &lt;strong&gt;그 두 KB에서 나온 답변마다 약 24초가 얹혔다.&lt;/strong&gt; 조용히 느려지기만 하다가, 하필 채팅 채널 sync timeout이 터지면서 사용자 눈에 보였다.&lt;/p&gt;
&lt;p&gt;고친 건 작은 타입 강제 헬퍼 하나였다(전부 숫자면 int, 아니면 str 유지) + 다시 뒤집히지 않게 UUID 경로를 지키는 회귀 테스트. 교훈: &lt;strong&gt;결정성(④)은 idempotent upsert를 보장하지만, 여러 ingest 소스로 유기적으로 자란 corpus에서 point-id &amp;quot;타입&amp;quot;의 일관성은 그와 별개의 두 번째 invariant였다&lt;/strong&gt; — 우리가 한 번 데어보고 배운.&lt;/p&gt;
&lt;p&gt;이 세 자리(② ⑤ 정정 + point-id 사고)가 서로 다른 얼굴로 같은 말을 한다. &lt;strong&gt;저장 구조가 &amp;quot;완성&amp;quot;돼도, 그게 라이브에서 그대로 도는지는 계속 다시 확인해야 한다.&lt;/strong&gt; 그래서 ⑥처럼 결정을 코드에 못 박고, 이런 애프터노트를 남긴다.&lt;/p&gt;
&lt;h2&gt;벡터 옆에, 그래프 — &amp;quot;비슷한 것&amp;quot;과 &amp;quot;연결된 것&amp;quot;&lt;/h2&gt;
&lt;p&gt;지식을 잘 저장한다는 건 벡터만 잘 넣는 게 아니었다. 실제 업무 질문은 자주 &lt;em&gt;관계&lt;/em&gt;로 온다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;이 시스템과 연결된 담당 부서는?&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;이 장애가 어느 프로세스의 다음 단계랑 이어져?&amp;quot;&lt;/li&gt;
&lt;li&gt;&amp;quot;A 문서엔 없는데, B와 &lt;em&gt;연결&lt;/em&gt;하면 답이 나오는 질문&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;벡터 검색은 &amp;quot;비슷한 문장&amp;quot;엔 강하지만 이런 &lt;em&gt;연결 질문&lt;em&gt;엔 약하다. 그래서 우리는 지식을 두 가지로 저장한다 — *&lt;/em&gt;Qdrant(벡터, 비슷함) + Neo4j(그래프, 연결).** 그래프의 엣지는 *수집 시점에&lt;/em&gt; 같이 쌓인다.&lt;/p&gt;
&lt;p&gt;그런데 여기서 또 한 번 멈췄다. &lt;strong&gt;검증 안 된 그래프 검색을 일반 봇 답변 경로에 바로 섞으면, 잘 답하던 대화 품질이 흔들릴 수 있다.&lt;/strong&gt; 켜보고 측정했더니:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;항목&lt;/th&gt;
&lt;th&gt;상태&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;그래프 데이터(Neo4j)&lt;/td&gt;
&lt;td&gt;있음 — 연결 재료는 쌓여 있다&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;그래프 확장기&lt;/td&gt;
&lt;td&gt;동작 (chunk 1개 → 관련 후보 10개)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;교차-KB 탐색&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;timeout&lt;/strong&gt; — 답변 경로에 바로 넣기엔 불안정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;검색 개선&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0건 케이스 존재&lt;/strong&gt; — &lt;em&gt;항상&lt;/em&gt; 개선하진 않음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;답변 경로&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;원복&lt;/strong&gt; — 기존 봇 답변 품질 보호 우선&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;→ &amp;quot;그래프가 나쁘다&amp;quot;가 아니라 &lt;strong&gt;&amp;quot;지금 &lt;em&gt;전체 답변 경로에&lt;/em&gt; 켜는 방식이 맞지 않는다.&amp;quot;&lt;/strong&gt; 그래서 그래프는 &lt;em&gt;답변 경로&lt;/em&gt;가 아니라 &lt;strong&gt;검증 레이어&lt;/strong&gt;에 먼저 둔다:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;① 답변 경로 유지 (그래프 마스터 기본 off)
② 전용 eval 경로 (실사용 질문 X, 검증용 질문 세트로 그래프 vs 벡터 비교)
③ 성공 조건 (timeout 없음 · 벡터-only 대비 recall↑ · 근거↑ · latency OK · 회귀 0)
④ 그 다음 좁은 canary (특정 KB · 질문 유형 · 봇만)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;핵심은 &lt;strong&gt;GraphRAG의 가치는 &lt;em&gt;대체*가 아니라 관계형 질문 *보강&lt;/em&gt;&lt;/strong&gt;이라는 것, 그리고 &lt;strong&gt;증명되기 전엔 답변 품질을 지킨다&lt;/strong&gt;는 것이다.&lt;/p&gt;
&lt;h2&gt;5. 반전 — &amp;quot;구조 완성&amp;quot;이 &amp;quot;검색 품질 완성&amp;quot;은 아니었다&lt;/h2&gt;
&lt;p&gt;저장 구조를 닫고 나서, 우리는 값진 걸 배웠다. &lt;strong&gt;저장을 잘 설계한 것&lt;/strong&gt;과 &lt;strong&gt;검색이 좋아진 것&lt;/strong&gt;은 다른 일이었다.&lt;/p&gt;
&lt;p&gt;특히 짧은 한국어 현장어 — &amp;quot;침수&amp;quot;, &amp;quot;미송&amp;quot;, &amp;quot;담배권&amp;quot;, &amp;quot;재고감모&amp;quot; — 같은 질문. 의미(dense) 검색은 긴 문장엔 강하지만 이런 &lt;em&gt;정확어&lt;/em&gt;엔 약하다. 설계엔 dense+sparse 하이브리드가 분명히 있었다. 그런데 &lt;strong&gt;&amp;quot;구현돼 있다&amp;quot;와 &amp;quot;서빙 경로가 그걸 쓴다&amp;quot;는 다른 일&lt;/strong&gt;이었다. 실제로는 색인 파이프라인이 sparse named vector를 채워 넣긴 하는데, &lt;strong&gt;질의 서빙 프로세스가 sparse 인코더를 일부러 로드하지 않는다&lt;/strong&gt;(자원 트레이드오프 설정). 그래서 hybrid fusion 질의는 dense·sparse 두 다리에 똑같이 가중치를 주고 돌지만, sparse 다리는 매번 빈손으로 돌아온다.&lt;/p&gt;
&lt;p&gt;이걸 어떻게 살릴지도 하나의 선택이었다. 우리가 지금 검토 중인 안(내부 ADR, 아직 PROPOSAL)은 &lt;strong&gt;dense 모델은 그대로 두고, sparse 전용 로컬 인코더만 질의 pod에 얹는 것&lt;/strong&gt; — 이미 만들어 둔 RRF 융합의 sparse 다리에 드디어 질의 시점 벡터를 주는, 가장 가벼운 변경이다. 기각한 대안은 &lt;strong&gt;임베딩 모델 전면 교체&lt;/strong&gt;(dense+sparse+late-interaction을 한 모델이 함께 뽑도록): 이미 결론 난 임베딩 전략 ADR을 다시 열고, 전체 corpus를 blue/green으로 재색인해야 해서 무겁다. 근거로 인용한 숫자는 공개 논문 하나 — BGE-M3 논문(Table 2)이 &lt;strong&gt;한국어 검색에서 hybrid가 dense-only로 퇴화하면 약 -1.4 nDCG@10&lt;/strong&gt;을 추정한다. 다만 &lt;em&gt;같은 조건의 내부 paired 벤치는 아직 &amp;quot;미측정&amp;quot;&lt;/em&gt;이다. 외부 인용 + 구조적 gap 추적은 있고, 내부 하드 넘버는 없다 — 그것까지 정직하게 적는다. 벡터 하이브리드든, 위의 그래프든 — 결국 &lt;strong&gt;똑같이 &amp;quot;저장은 됐지만, 답변 품질로 증명돼야 완료&amp;quot;&lt;/strong&gt;다.&lt;/p&gt;
&lt;p&gt;그래서 우리는 &amp;quot;완료(Done)&amp;quot;를 다시 정의했다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;&lt;strong&gt;PR 머지 / dev에서 켜짐 / &amp;quot;코드에 있음&amp;quot; → 완료 아님&lt;/strong&gt;&lt;br&gt;&lt;strong&gt;실제 사용자가, 측정된 품질로, 운영 경로에서, 영속된 증거(receipt)와 함께&lt;/strong&gt; 더 나은 답을 받을 때 완료&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;이걸 팀의 &lt;strong&gt;엔지니어링 표준(4-layer Receipt)&lt;/strong&gt;으로 못 박았다 — 저장 구조의 완성이, 검색 &lt;em&gt;품질&lt;/em&gt;의 완료를 다시 정의하게 만든 자리에서.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;&lt;em&gt;(품질 coda)&lt;/em&gt;: 첫 파일럿은 OFC봇이었다. 실제 사용자 로그에서 나온 짧은 질문 20건을 dev 운영 경로로 다시 흘려보냈다. 개선 전에는 답변은 생성됐지만 근거 문서를 찾지 못한 케이스가 많았다. 개선 후 근거 문서 연결률은 35%에서 100%로 올랐다(+65%p). 평균 근거 문서 수는 0.9개에서 4.15개로 늘었고, 약한 케이스는 13건에서 0건으로 줄었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;495&quot; data-origin-height=&quot;1164&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFtGK4/dJMcabrdN4q/D7B57pn9imVyGszQz8nDX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFtGK4/dJMcabrdN4q/D7B57pn9imVyGszQz8nDX1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFtGK4/dJMcabrdN4q/D7B57pn9imVyGszQz8nDX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFtGK4%2FdJMcabrdN4q%2FD7B57pn9imVyGszQz8nDX1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;239&quot; height=&quot;562&quot; data-origin-width=&quot;495&quot; data-origin-height=&quot;1164&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;h2&gt;6. 맺음 — 그리고 새로운 문제&lt;/h2&gt;
&lt;p&gt;드릴은 손에 익었다. 전동 드릴(Qdrant)로 구멍 뚫는 법 — 통합 컬렉션 + named vector + payload — 도 배웠다. 끝없이 자라는 사내 지식을 &lt;em&gt;컬렉션 폭증 없이&lt;/em&gt; 저장하는 구조는 완성됐다.&lt;/p&gt;
&lt;p&gt;그런데 지식을 &lt;strong&gt;한곳에 모으자&lt;/strong&gt; 곧바로 새로운 질문이 생겼다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;&amp;quot;이제 누가, 무엇을, 볼 수 있지?&amp;quot;&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;h2&gt;물리적으로 분리돼 있던 격리가 사라졌으니, &lt;strong&gt;권한&lt;/strong&gt;을 다시 세워야 했다. 그 이야기는 &lt;strong&gt;&lt;a href=&quot;https://gsretail.tistory.com/90&quot;&gt;2탄 — 지식을 한곳에 모았더니, 아무나 다 볼 수 있게 됐다&lt;/a&gt;&lt;/strong&gt;에서.&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;시리즈&lt;/strong&gt;: &lt;strong&gt;1탄 저장 (이 글)&lt;/strong&gt; · &lt;a href=&quot;https://gsretail.tistory.com/90&quot;&gt;2탄 권한&lt;/a&gt; · &lt;a href=&quot;https://gsretail.tistory.com/92&quot;&gt;3탄-1부 대화&lt;/a&gt; · &lt;a href=&quot;https://gsretail.tistory.com/93&quot;&gt;3탄-2부 대화&lt;/a&gt; · 4탄 채널 · 번외 수집&lt;br&gt;&lt;figure class=&quot;imageblock undefined&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;22787.jpg&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;960&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/02zUJ/btsMAMg3Wtb/7LuKJYntKKZdzNzAcaQAs0/tfile.dat&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/02zUJ/btsMAMg3Wtb/7LuKJYntKKZdzNzAcaQAs0/tfile.dat&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/02zUJ/btsMAMg3Wtb/7LuKJYntKKZdzNzAcaQAs0/tfile.dat&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F02zUJ%2FbtsMAMg3Wtb%2F7LuKJYntKKZdzNzAcaQAs0%2Ftfile.dat&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;80&quot; height=&quot;960&quot; data-filename=&quot;22787.jpg&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;960&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;김헌기 Darion&lt;/strong&gt; · AX본부 &amp;gt; AI데이터부문 &amp;gt; AI혁신지원팀&lt;/p&gt;
&lt;p&gt;AI 및 공통 Tech 기반의 기술 표준화 업무를 수행하고 있습니다. 동료들과 함께 기술 문화 만들기와 낯선 기술자와의 인연의 시작에 관심이 많습니다.&lt;/p&gt;</description>
      <category>Data&amp;amp;AI</category>
      <author>DarionKim</author>
      <guid isPermaLink="true">https://gsretail.tistory.com/89</guid>
      <comments>https://gsretail.tistory.com/89#entry89comment</comments>
      <pubDate>Tue, 30 Jun 2026 09:25:26 +0900</pubDate>
    </item>
    <item>
      <title>쇼핑에 영상을 더하다: Part 3. 이해한 영상을 추천으로 연결하기</title>
      <link>https://gsretail.tistory.com/88</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;시리즈 목차&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://gsretail.tistory.com/79&quot;&gt;Part 1. 쇼핑에 영상을 더하다: GSSHOP 숏픽 추천 알고리즘 진화기&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gsretail.tistory.com/87&quot;&gt;Part 2. 쇼핑에 영상을 더하다: 영상을 '이해'하기 시작하다&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a&gt;Part 3. 쇼핑에 영상을 더하다: 이해한 영상을 추천으로 연결하기&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고객이 워킹화 숏폼을 클릭했을 때, 추천 시스템은 무엇을 기록했을까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아마 이렇게 남겼을 겁니다. &lt;b&gt;&quot;운동화 선호&quot;.&lt;/b&gt; 맞는 말이긴 한데, 뭔가 많이 잘려나간 느낌이 듭니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고객이 실제로 반응한 건 운동화라는 카테고리가 아니라, 영상이 전달한 &quot;편안하고 활동적인 일상&quot;이라는 맥락이었을지도 모릅니다. 그 차이를 시스템이 읽지 못하면, 추천은 늘 비슷한 운동화만 반복하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Part 1에서는 숏픽 추천이 어떻게 진화해 왔는지, Part 2에서는 왜 영상을 중요한 신호로 봐야 하는지를 다뤘습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글은 그 다음 이야기입니다. &lt;b&gt;영상에서 읽어낸 의미를 실제 추천 시스템에 어떻게 연결했는지&lt;/b&gt;, 그 과정을 정리해 보려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GS SHOP은 상품 데이터만 많은 커머스가 아니라, 방송 영상, 숏폼 콘텐츠, 고객 행동 데이터가 함께 축적되는 환경을 가지고 있습니다. 그렇기 때문에 이 문제는 단순히 &quot;영상을 분석해 보자&quot;는 실험이 아니라, &lt;b&gt;기존 커머스 추천 시스템이 활용하지 못했던 신호를 실제 서비스에 어떻게 편입할 것인가&lt;/b&gt;에 중점을 두었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;GS SHOP에서는 왜 이 문제가 중요했을까&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;홈쇼핑과 커머스 서비스에서 영상은 오래전부터 중요한 자산이었습니다. 상품명, 가격, 카테고리, 리뷰, 대표 이미지 같은 정형 정보만으로도 기본적인 추천은 충분히 가능합니다. 실제로 많은 추천 시스템이 이런 신호들 위에서 잘 동작해 왔습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 GS SHOP이 다루는 콘텐츠는 그보다 훨씬 풍부합니다. 라이브 방송에는 쇼핑호스트의 설명, 시연 장면, 사용 맥락, 비교 포인트가 담겨 있고, 숏픽 같은 숏폼에는 짧은 시간 안에 상품의 핵심 메시지와 사용 장면이 압축되어 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는 기존 추천 시스템이 이런 차이를 대부분 &lt;b&gt;상품 중심의 정형 신호&lt;/b&gt;로만 읽고 있었다는 점입니다. 예를 들어 같은 패션 상품이라도 영상에서는 &quot;체형 커버&quot;, &quot;출근룩&quot;, &quot;편안한 착용감&quot;처럼 전혀 다른 메시지가 강조될 수 있고, 같은 리빙 상품이라도 &quot;캠핑&quot;, &quot;전자레인지 사용 가능&quot;, &quot;정리 수납&quot;처럼 고객이 반응하는 포인트가 달라질 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, GS SHOP 입장에서는 이미 충분한 영상 자산을 가지고 있었지만, 추천 시스템이 그 안의 의미를 충분히 활용하지 못하고 있었습니다.&lt;br /&gt;이 간극을 메우는 것이 이번 작업의 출발점이었습니다.&lt;/p&gt;
&lt;figure data-ke-type=&quot;image&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; data-ke-style=&quot;alignCenter&quot;&gt;&lt;span class=&quot;bar_progress&quot;&gt;&lt;/span&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01_before_after.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sfPVA/dJMcagyh1Y4/Tn6eMWiL6NTDTb8NC7jRY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sfPVA/dJMcagyh1Y4/Tn6eMWiL6NTDTb8NC7jRY0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sfPVA/dJMcagyh1Y4/Tn6eMWiL6NTDTb8NC7jRY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsfPVA%2FdJMcagyh1Y4%2FTn6eMWiL6NTDTb8NC7jRY0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;1024&quot; data-filename=&quot;01_before_after.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;기존 추천의 한계&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;숏픽 추천은 꾸준히 발전해 왔지만, 한 가지 전제는 꽤 오랫동안 유지되고 있었습니다. 숏픽이 노출되더라도, 어떤 영상을 보여줄지는 결국 &lt;b&gt;상품 추천 결과&lt;/b&gt;에 따라 결정되는 구조였습니다. 즉, 추천의 중심은 여전히 상품이었고, 입력 신호 역시 상품 ID, 카테고리, 브랜드 같은 &lt;b&gt;정형 데이터&lt;/b&gt;가 대부분이었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구조는 상품 추천 관점에서는 충분히 합리적이었습니다. 하지만 영상 추천 관점에서는 분명한 한계가 있었습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;고객이 무엇을 클릭했는지는 볼 수 있었지만, 왜 반응했는지는 알기 어려웠습니다.&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 고객이 어떤 숏픽을 클릭했을 때, 시스템은 이를 &quot;이 상품을 좋아했다&quot; 정도로만 해석할 수 있었습니다. 하지만 실제 고객은 상품 자체보다 영상이 전달한 분위기, 사용 상황, 스타일링, 기능성 같은 요소에 더 크게 반응했을 수도 있습니다. 즉, 영상은 노출되고 있었지만, 영상 안에 담긴 맥락은 추천에 거의 쓰이지 못하고 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구조는 서비스 운영 관점에서는 이해할 수 있는 선택이기도 했습니다. 기존 추천 시스템은 상품 추천을 중심으로 발전해 왔고, 영상은 그 결과를 보조적으로 보여주는 방식이 더 단순하고 안정적이었기 때문입니다. 다만 숏폼과 영상 소비가 커질수록, 추천 시스템 입장에서는 조금 난감해졌습니다. 고객은 분명히 영상에 반응하고 있는데, 시스템이 읽을 수 있는 것은 여전히 상품 코드 중심이었기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;클릭을 다시 해석하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 저희는 숏픽 클릭을 조금 다르게 보기 시작했습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;영상 클릭은 단순한 상품 선호가 아니라, 고객 취향의 단서를 남긴다.&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 워킹화 숏폼을 클릭한 고객을 생각해보겠습니다. 기존 방식이라면 이를 &quot;운동화 선호&quot;로 해석하기 쉽습니다. 하지만 실제로는 편안함, 기능성, 활동적인 라이프스타일, 실용적인 코디에 반응했을 가능성이 더 클 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 차이는 생각보다 중요합니다. &quot;운동화&quot;라는 카테고리 하나로 해석하면 비슷한 상품만 반복 추천하게 되지만, &quot;편안하고 활동적인 스타일&quot;이라는 맥락으로 해석하면 다른 상품군까지도 더 자연스럽게 연결할 수 있기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 저희는 숏픽 클릭을 &lt;b&gt;상품 선호&lt;/b&gt;가 아니라 &lt;b&gt;맥락 선호&lt;/b&gt;, 혹은 &lt;b&gt;취향 신호&lt;/b&gt;로 해석해 보기로 했습니다.&lt;br /&gt;조금 과장해서 말하면, 고객은 꽤 풍부하게 반응하고 있었는데 시스템이 너무 단순하게 받아쓰고 있었던 셈입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;영상만이 줄 수 있는 신호, 소구 포인트&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는 여기서 끝나지 않았습니다. 영상에서 의미를 읽었다고 해도, 추천 시스템이 그대로 이해해 주는 것은 아니기 때문입니다. 추천 시스템은 결국 숫자와 점수로 움직입니다. 그래서 영상이 전달하는 설명을 추천에 활용할 수 있도록 구조화한 개념이 바로 &lt;b&gt;소구 포인트&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소구 포인트는 고객이 영상에서 실제로 반응했을 만한 핵심 메시지입니다. 예를 들면 &quot;전자레인지 OK&quot;, &quot;캠핑용&quot;, &quot;실용성&quot;, &quot;기능성&quot;, &quot;활용도 높은 스타일링&quot; 같은 표현들입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 중요한 점은, 카테고리나 브랜드는 이미 기존 추천 신호가 어느 정도 잘 설명하고 있었다는 점입니다. 그래서 영상에는 &lt;b&gt;영상만이 드러낼 수 있는 신호&lt;/b&gt;를 맡기기로 했습니다. 즉, 영상에서 소구 포인트를 추출하고, 이를 임베딩해 &lt;b&gt;비슷한 맥락의 영상&lt;/b&gt;을 찾을 수 있도록 설계했습니다. 이렇게 하면 고객이 최근 반응한 영상과 비슷한 결을 가진 다른 영상이나 상품을 추천 후보로 활용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;영상 임베딩, 무엇을 담아야 할까&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 영상 전체를 설명하는 긴 텍스트를 임베딩해 유사 영상을 찾는 방식도 시도했습니다. 결과는 꽤 그럴듯해 보였습니다. 그런데 자세히 들여다보니, 비슷하다고 묶이는 영상들이 대부분 같은 카테고리나 같은 브랜드 숏폼이었습니다. 영상을 열심히 읽었는데, 결국 상품 코드 근처를 맴도는 결과였습니다. 원점에 가까웠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 방향을 조금 바꿨습니다. 카테고리와 브랜드 선호는 기존 상품 추천이 맡고, 영상 쪽은 &lt;b&gt;소구 포인트 키워드 자체&lt;/b&gt;를 더 잘 표현하도록 역할을 분리했습니다. 결과적으로 Pegasus와 Claude를 통해 추출한 소구 포인트를 임베딩하고, 그 벡터를 기반으로 비슷한 맥락의 영상을 찾는 구조로 정리할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소구 포인트 임베딩은 처음에는 더 높은 차원으로 다뤘지만, 검색 속도와 저장 비용을 함께 고려해야 했습니다. 실서비스에서는 추천 품질뿐 아니라 인덱싱 비용, 조회 속도, 운영 복잡도도 함께 봐야 하기 때문입니다. 그래서 정보 보존율, 복원 오차, 유사도 유지율, 검색 속도 등을 비교하며 차원 축소를 진행했고, 운영 가능한 수준으로 최적화했습니다. 상품 임베딩과 같은 차원으로 맞춰 둔 덕분에 운영 측면에서도 훨씬 단순한 구조를 만들 수 있었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02_vector_matching_pipeline.png&quot; data-origin-width=&quot;956&quot; data-origin-height=&quot;639&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RyoHo/dJMcajobfkC/RkihloKGafCxu10kDBk8f1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RyoHo/dJMcajobfkC/RkihloKGafCxu10kDBk8f1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RyoHo/dJMcajobfkC/RkihloKGafCxu10kDBk8f1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRyoHo%2FdJMcajobfkC%2FRkihloKGafCxu10kDBk8f1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;956&quot; height=&quot;639&quot; data-filename=&quot;02_vector_matching_pipeline.png&quot; data-origin-width=&quot;956&quot; data-origin-height=&quot;639&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;기존 추천을 버리지 않고, 얹었습니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영상 신호를 도입한다고 해서 기존 추천 엔진을 처음부터 다시 만들지는 않았습니다. 오히려 저희가 택한 방식은 반대에 가까웠습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;기존 추천을 버린 것이 아니라, 영상 맥락 신호를 그 위에 얹었습니다.&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에는 상품 점수, 카테고리 선호, 인기나 평점 같은 신호들이 추천의 중심을 이루고 있었습니다. 여기에 &quot;이 고객이 최근 반응한 영상과 얼마나 비슷한 맥락인가&quot;라는 영상 신호를 추가해, 최종 추천 점수를 함께 계산하도록 설계했습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 선택은 기술적으로도 중요했습니다. 새로운 추천 시스템을 별도로 만들면 품질 검증, 운영, fallback, 기존 지표와의 비교가 모두 어려워집니다. 반면 기존 추천 로직 위에 영상 신호를 레이어처럼 얹는 방식은, 기존 시스템의 안정성을 유지하면서도 새로운 신호의 효과를 상대적으로 명확하게 검증할 수 있다는 장점이 있었습니다. 말 그대로 &quot;다 뜯어고치기&quot;보다 &quot;잘 쓰던 엔진에 새 감각을 붙이는&quot; 쪽에 가까웠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구조를 저희는 Hybrid라고 부릅니다. 기존 추천의 강점은 유지하되, 영상이 전달하는 의미를 새로운 레이어로 더한 방식입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;영상은 의미를 담고 있고, 행동은 의도를 담고 있습니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영상 기반 추천을 설계하면서 가장 중요하게 본 것은, 영상과 행동이 서로 다른 역할을 한다는 점이었습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;영상은 의미를 담고 있고, 행동은 의도를 담고 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영상 쪽에서는 소구 포인트를 임베딩한 뒤 OpenSearch에서 유사한 맥락을 찾도록 했습니다. 반면 행동 쪽에서는 고객이 최근 어떤 영상을 클릭하고 시청했는지, 어떤 맥락에 반응했는지를 Redis에 빠르게 조회할 수 있는 형태로 쌓았습니다. 그리고 추천 시점에는 API가 이 두 정보를 함께 조회해 최종 추천을 만듭니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;즉, &quot;이 영상이 어떤 메시지를 갖고 있는가&quot;와 &quot;이 고객이 최근 어떤 메시지에 반응했는가&quot;를 한 번에 보는 구조입니다. 조금 더 기술적으로 설명하면, 전체 구조는 크게 세 단계로 나눌 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;오프라인 처리 단계&lt;/b&gt;&lt;br /&gt;영상에서 소구 포인트를 추출하고 임베딩을 생성해 검색 가능한 형태로 적재합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;행동 집계 단계&lt;/b&gt;&lt;br /&gt;고객의 클릭&amp;middot;시청 로그를 바탕으로 최근 선호 맥락을 사용자 단위로 누적합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;온라인 추천 단계&lt;/b&gt;&lt;br /&gt;추천 요청 시 OpenSearch에서 의미 기반 후보를 찾고, Redis에서 사용자 행동 기반 선호를 조회한 뒤, 여러 점수를 합산해 최종 결과를 반환합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 역할을 나눈 이유는 명확합니다. 영상 의미를 계산하는 작업은 상대적으로 무겁고, 사용자 반응은 빠르게 갱신되어야 하며, 최종 추천 응답은 짧은 시간 안에 끝나야 하기 때문입니다. 한 시스템이 모든 걸 한 번에 다 잘해주기를 기대하기보다는, 각 단계가 잘하는 일을 나눠 맡기는 편이 훨씬 현실적이었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03_system_architecture.png&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;556&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4FPus/dJMb99MF5Az/4JNnsFeLLxGnNGKXnxmkE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4FPus/dJMb99MF5Az/4JNnsFeLLxGnNGKXnxmkE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4FPus/dJMb99MF5Az/4JNnsFeLLxGnNGKXnxmkE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4FPus%2FdJMb99MF5Az%2F4JNnsFeLLxGnNGKXnxmkE1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;841&quot; height=&quot;556&quot; data-filename=&quot;03_system_architecture.png&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;556&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;행동을 어떻게 선호도로 바꿨을까&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;행동 신호를 설계할 때는 단순 노출을 그대로 선호도로 보지 않았습니다. 대신 실제 시청과 클릭 행동을 중심으로, 의도 수준이 다른 행동을 구분해서 반영했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 상품 클릭, 상품 상세 진입, 이벤트 클릭처럼 구매나 전환에 더 가까운 행동에는 더 높은 가중치를 두고, 재생, 끝까지 시청, 썸네일 클릭처럼 관심을 보여주는 행동은 그보다 낮은 단계의 선호 신호로 반영했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정리하면 행동 신호는 크게 두 층으로 나눌 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;구매&amp;middot;전환에 가까운 행동&lt;/b&gt;: 상품 클릭, 상품 상세 진입, 이벤트 클릭&lt;/li&gt;
&lt;li&gt;&lt;b&gt;관심에 가까운 행동&lt;/b&gt;: 재생, 끝까지 시청, 썸네일 클릭, 추천 영역 진입&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요한 점은, 보였다는 사실 자체보다 &lt;b&gt;실제로 반응했는가&lt;/b&gt;를 더 강한 신호로 봤다는 것입니다. 숏폼 영역은 노출 위치나 UI 구조의 영향도 크기 때문에, 단순 impression까지 그대로 선호 신호로 쓰면 오히려 의도가 흐려질 수 있다고 판단했습니다. 또한 최근 행동일수록 더 큰 의미를 갖도록 반감기 개념을 적용해 시간에 따라 점수가 자연스럽게 감쇠되도록 설계했습니다. 이렇게 하면 오래전 행동보다 지금 고객이 실제로 관심을 보이는 맥락을 더 잘 반영할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;선호도 저장 역시 무한정 누적하지 않았습니다. 실시간 조회가 필요한 데이터인 만큼 사용자별 상위 선호 항목만 유지하는 방식으로 관리했고, 이를 통해 추천 시점의 조회 비용과 응답 시간을 함께 제어했습니다. 선호도 점수는 개념적으로 보면, 낮은 구간은 &quot;얼마나 오래 봤는가&quot;에 더 가깝고, 높은 구간은 실제 클릭이나 상세 진입 같은 행동이 붙으면서 올라가는 구조입니다. 즉, 단순 시청과 적극적인 반응을 같은 무게로 보지 않도록 설계했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;최종 추천 점수는 어떻게 만들었을까&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종 추천은 크게 다섯 단계를 거쳐 계산했습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;상품 점수&lt;/b&gt;&lt;br /&gt;최근 클릭한 상품을 기준으로 유사 상품을 찾고, 최근에 클릭한 상품일수록 더 높은 가중치를 둡니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;숏폼 점수&lt;/b&gt;&lt;br /&gt;최근 선호한 숏폼을 기준으로 유사 숏폼을 찾고, 해당 숏폼에 대한 사용자 선호 점수를 함께 반영합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;카테고리 점수&lt;/b&gt;&lt;br /&gt;사용자의 대/중 카테고리 선호를 반영해, 평소 관심을 보이던 축에 맞는 상품에 점수를 더합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;최종 점수 계산&lt;/b&gt;&lt;br /&gt;상품, 숏폼, 카테고리, 평점 등 여러 신호를 가중 합산해 1차 점수를 만듭니다. 이때 상품과 숏폼 신호를 중심에 두고, 카테고리와 평점은 보조 신호로 활용했습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;후처리&lt;/b&gt;&lt;br /&gt;마지막으로 MMR(Maximal Marginal Relevance)을 적용해 유사도뿐 아니라 다양성까지 함께 고려합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;이미지 (21).png&quot; data-origin-width=&quot;1136&quot; data-origin-height=&quot;542&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Bh1b0/dJMcagd2Eqk/y4oSZb8Nk4AAvUdrX3DQkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Bh1b0/dJMcagd2Eqk/y4oSZb8Nk4AAvUdrX3DQkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Bh1b0/dJMcagd2Eqk/y4oSZb8Nk4AAvUdrX3DQkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBh1b0%2FdJMcagd2Eqk%2Fy4oSZb8Nk4AAvUdrX3DQkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1136&quot; height=&quot;542&quot; data-filename=&quot;이미지 (21).png&quot; data-origin-width=&quot;1136&quot; data-origin-height=&quot;542&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정의 핵심은 단순히 비슷한 것을 찾는 데서 멈추지 않는다는 점입니다. 고객이 좋아할 가능성이 높은 후보를 모으고, 그 안에서 너무 비슷한 결과만 반복되지 않도록 다시 한 번 정리해 주는 구조입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 GS SHOP 같은 커머스 환경에서는 정확도만큼이나 &lt;b&gt;구성의 다양성&lt;/b&gt;도 중요합니다. 비슷한 맥락을 잘 맞추더라도 결과가 지나치게 한쪽 카테고리나 유사 상품군에 쏠리면 서비스 품질은 오히려 떨어질 수 있습니다. 그래서 MMR은 단순한 후처리가 아니라, 실제 사용자 경험을 보정하는 중요한 단계로 작동했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;구현하면서 함께 고민한 것들&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실서비스에 연결하는 과정에서는 추천 품질만큼이나 서빙 안정성도 중요했습니다. 그래서 Redis 조회와 상품/숏폼/카테고리 추천 계산은 가능한 한 병렬로 처리해 지연 시간을 줄였고, 여러 소스에서 같은 상품이 동시에 추천되면 하나로 묶어 점수를 통합했습니다. 이때 같은 상품이 여러 추천 소스에서 반복해서 등장하면 단순 중복 제거로 끝내지 않고, &quot;여러 관점에서 동시에 추천된 후보&quot;라는 의미로 보고 소량의 추가 점수를 주는 방식도 함께 사용했습니다. 완전히 새로운 규칙을 더한 것은 아니지만, 여러 신호에서 공통으로 살아남은 후보를 조금 더 위로 올려주는 데 도움이 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 추천 결과가 충분하지 않거나 예외 상황이 생길 때는 인기도 기반 결과로 자연스럽게 보완할 수 있도록 fallback도 마련했습니다. 기술적으로는 작은 디테일일 수 있지만, 실제 서비스에서는 이런 장치들이 사용자 경험을 안정적으로 유지하는 데 꽤 중요했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;온라인 서빙에서는 응답 시간이 매우 중요하기 때문에, Redis 조회와 추천 파이프라인 전반에 적절한 타임아웃을 두었습니다. 추천 품질이 좋아도 응답이 늦어지면 서비스 품질은 바로 흔들리기 때문에, 이 부분은 모델 성능과는 다른 의미의 중요한 운영 조건이었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 하나 중요했던 점은, 새 신호를 도입하더라도 기존 서비스 운영 체계를 크게 흔들지 않는 것이었습니다. 추천 품질 실험, 단계적 적용, 장애 대응, 비교 지표 검증까지 모두 고려해야 했기 때문에, 아키텍처와 로직 모두 &quot;좋은 아이디어&quot;보다 &quot;서비스에 안전하게 얹을 수 있는 구조&quot;를 우선해 설계했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;그래서 무엇이 달라졌을까요?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추천 품질을 이야기할 때 결과 화면만 보면 쉽게 와닿을 수 있지만, 그 전에 먼저 봐야 할 변화는 &lt;b&gt;추천에 들어가는 입력 자체가 달라졌다는 점&lt;/b&gt;입니다. 결과보다 먼저, 추천 시스템이 세상을 보는 방식이 달라졌다고 볼 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에는 클릭한 상품, 카테고리, 브랜드 같은 정형 신호가 중심이었습니다. 하지만 영상 기반 추천에서는 여기에 &lt;b&gt;영상이 전달한 맥락&lt;/b&gt;과 &lt;b&gt;고객 행동의 의도&lt;/b&gt;가 함께 들어가기 시작했습니다.&amp;nbsp;즉, 추천의 기준이 &quot;어떤 상품을 봤는가&quot;에서 &lt;b&gt;&quot;어떤 맥락에 반응했는가&quot;&lt;/b&gt;로 확장된 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 변화는 추천 결과에서도 드러났습니다. 기존에는 같은 카테고리 상품 위주로 영상이 붙어 나오는 경향이 강했다면, 이제는 카테고리가 다르더라도 실용성, 스타일링, 사용 상황처럼 &lt;b&gt;맥락이 비슷한&lt;/b&gt; 영상과 상품이 함께 추천될 수 있게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 워킹화에 반응한 고객에게 단순히 운동화만 더 보여주는 것이 아니라, &quot;편안하고 활동적인 일상&quot;이라는 맥락에 맞는 다른 숏픽을 연결해줄 수 있고, 와이드 청바지에 반응한 고객에게 단순히 청바지만 더 보여주는 것이 아니라, &quot;편안한 핏&quot;이라는 맥락에 맞는 슬랙스, 티셔츠 관련 숏픽까지 연결해 줄 수 있게 된 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1812&quot; data-origin-height=&quot;882&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXykLg/dJMcac3IevG/HluWFpGIklb88dk3L8Pry1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXykLg/dJMcac3IevG/HluWFpGIklb88dk3L8Pry1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXykLg/dJMcac3IevG/HluWFpGIklb88dk3L8Pry1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXykLg%2FdJMcac3IevG%2FHluWFpGIklb88dk3L8Pry1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1812&quot; height=&quot;882&quot; data-origin-width=&quot;1812&quot; data-origin-height=&quot;882&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실제로 어떤 변화가 있었을까&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동일 영역, 동일 기간 기준으로 A/B 테스트를 진행한 결과 입니다.&lt;/p&gt;
&lt;table style=&quot;height: 68px; width: 634px;&quot; width=&quot;546&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;th style=&quot;width: 220px; height: 20px;&quot;&gt;&amp;nbsp;&lt;/th&gt;
&lt;th style=&quot;width: 220px; height: 20px;&quot;&gt;클릭 UV&lt;/th&gt;
&lt;th style=&quot;width: 196px; height: 20px;&quot;&gt;총주문고객수&lt;/th&gt;
&lt;th style=&quot;width: 126px; height: 20px;&quot;&gt;CR&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 48px;&quot;&gt;
&lt;td style=&quot;width: 220px; text-align: left; height: 48px;&quot;&gt;&lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;기존 로직 대비 증감율&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 220px; text-align: center; height: 48px;&quot;&gt;&lt;span style=&quot;color: #e53e3e; font-weight: bold;&quot;&gt;+21.7%&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 196px; text-align: center; height: 48px;&quot;&gt;&lt;span style=&quot;color: #e53e3e; font-weight: bold;&quot;&gt;+57.5%&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 126px; text-align: center; height: 48px;&quot;&gt;&lt;span style=&quot;color: #e53e3e; font-weight: bold;&quot;&gt;+29.4%&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클릭 UV, 총주문고객수, 전환율(CR) 모두에서 개선이 관찰됐고, 일별 지표를 보더라도 전환율이 유의미하게 상승한 구간들을 확인할 수 있었습니다. 즉, 영상 이해 신호를 추천에 연결한 효과는 실제 서비스 지표에서도 확인할 수 있었고, 비즈니스 성과에 실질적으로 기여함을 입증할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;앞으로의 방향&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 작업을 통해 확인한 것은, GS SHOP이 이미 가지고 있는 영상 자산과 고객 반응 데이터를 더 잘 해석하면 추천 시스템이 훨씬 풍부해질 수 있다는 점이었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 저희는 여기서 한 단계 더 나아가고자 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지는 사람이 직접 숏폼 영상을 만들고, 저희가 그 영상에서 소구 포인트를 추출해 추천에 활용해 왔습니다. 그런데 추천 시스템은 무엇을 보여줄지 결정하는 역할에 그치지 않고, 고객이 &lt;b&gt;실제로 어떤 소구 포인트에 반응했는지&lt;/b&gt;를 계속 학습하는 구조이기도 합니다. 만약 실용성, 스타일링, 활용 상황 같은 요소가 클릭과 전환으로 이어졌다면, 이 정보는 추천 신호인 동시에 다음 콘텐츠를 만들 때 참고할 수 있는 제작 신호가 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 앞으로는 다음과 같은 선순환을 만들고 싶습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사람이 영상을 만들고&lt;/li&gt;
&lt;li&gt;AI가 그 핵심 메시지를 구조화하고&lt;/li&gt;
&lt;li&gt;추천이 어떤 포인트가 실제로 효과 있었는지 검증하고&lt;/li&gt;
&lt;li&gt;그 결과를 다시 다음 콘텐츠 제작에 반영하는 것&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, &lt;b&gt;콘텐츠 제작 &amp;rarr; 추천 &amp;rarr; 반응 학습 &amp;rarr; 다시 콘텐츠&lt;/b&gt;가 이어지는 구조입니다.&lt;br /&gt;추천을 넘어 검색과 탐색, 그리고 나아가 콘텐츠 제작까지 연결되는 방향으로 발전시켜 나가고자 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;이미지 (22).png&quot; data-origin-width=&quot;1141&quot; data-origin-height=&quot;748&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c90jPe/dJMcahYiHze/bCTJDsRVsJk6nj9W9Kejhk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c90jPe/dJMcahYiHze/bCTJDsRVsJk6nj9W9Kejhk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c90jPe/dJMcahYiHze/bCTJDsRVsJk6nj9W9Kejhk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc90jPe%2FdJMcahYiHze%2FbCTJDsRVsJk6nj9W9Kejhk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1141&quot; height=&quot;748&quot; data-filename=&quot;이미지 (22).png&quot; data-origin-width=&quot;1141&quot; data-origin-height=&quot;748&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리하며&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글을 통해 말씀드리고 싶었던 것은 세 가지입니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;영상은 상품 메타데이터만으로 담기지 않는 더 풍부한 신호를 제공합니다.&lt;/li&gt;
&lt;li&gt;추천에 필요한 신호만을 구조화해서 남기는 것이 중요했습니다.&lt;/li&gt;
&lt;li&gt;그리고 그 연결은 새로운 시스템을 처음부터 만드는 방식이 아니라, 기존 추천과 결합하며 인프라 위에 자연스럽게 확장하는 방식으로도 충분히 구현할 수 있습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Part 1이 숏픽 추천의 진화 과정이었다면, Part 2는 왜 영상을 중요한 신호로 봐야 하는지에 대한 이야기였고, 이번 Part 3는 그 신호를 실제 추천 시스템 언어로 바꿔 넣은 이야기였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글에서는 그 가능성을 &lt;b&gt;GS SHOP 서비스 안에서 어떻게 시스템으로 만들었는가&lt;/b&gt;를 조금 더 구체적으로 남기고 싶었습니다.&lt;br /&gt;결국 저희가 풀고자 했던 문제는 영상 모델을 쓰는 것 자체가 아니라, GS SHOP이 이미 가지고 있는 영상과 고객 반응을 &lt;b&gt;추천 가능한 데이터 구조&lt;/b&gt;로 다시 해석하는 일이었습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이제 GS SHOP은 영상을 노출하는 것을 넘어, 영상을 이해하며 추천하기 시작했습니다.&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;감사합니다 :)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock floatRight&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;97&quot; data-origin-height=&quot;130&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q2qkv/btsM8aG9wd8/D8TALcc5C0GoBWGGOPk9K1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q2qkv/btsM8aG9wd8/D8TALcc5C0GoBWGGOPk9K1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q2qkv/btsM8aG9wd8/D8TALcc5C0GoBWGGOPk9K1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq2qkv%2FbtsM8aG9wd8%2FD8TALcc5C0GoBWGGOPk9K1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;97&quot; height=&quot;130&quot; data-origin-width=&quot;97&quot; data-origin-height=&quot;130&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;이세윤 Erica&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;| AX본부 홈쇼핑AX부문 검색추천파트(H)&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size14&quot;&gt;추천 알고리즘 개발을 담당하고 있습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size14&quot;&gt;사용자에게 도움이 되는 서비스를 개발하고,&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size14&quot;&gt;합리적인 추론을 통해 변화를 만들어내는 일을 하고 싶습니다.&lt;/p&gt;
&lt;p style=&quot;position: absolute;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Data&amp;amp;AI</category>
      <author>세우초밥</author>
      <guid isPermaLink="true">https://gsretail.tistory.com/88</guid>
      <comments>https://gsretail.tistory.com/88#entry88comment</comments>
      <pubDate>Thu, 9 Apr 2026 18:01:49 +0900</pubDate>
    </item>
    <item>
      <title>쇼핑에 영상을 더하다: Part 2. 영상을 '이해'하기 시작하다</title>
      <link>https://gsretail.tistory.com/87</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;시리즈 목차&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;- &lt;a href=&quot;https://gsretail.tistory.com/79&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Part 1. 쇼핑에 영상을 더하다: GSSHOP 숏픽 추천 알고리즘 진화기&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;- &lt;a href=&quot;https://gsretail.tistory.com/87&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Part 2. 쇼핑에 영상을 더하다: 영상을 '이해'하기 시작하다&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gsretail.tistory.com/88&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;- Part 3.&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt; 쇼핑에 영상을 더하다: 이해한&amp;nbsp;영상을&amp;nbsp;추천으로&amp;nbsp;연결하기&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;숏픽 캡쳐.jpeg&quot; data-origin-width=&quot;1047&quot; data-origin-height=&quot;1239&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvbosD/dJMb99TmGJy/mWtZruSuooCS1WEYTOlUz1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvbosD/dJMb99TmGJy/mWtZruSuooCS1WEYTOlUz1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvbosD/dJMb99TmGJy/mWtZruSuooCS1WEYTOlUz1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvbosD%2FdJMb99TmGJy%2FmWtZruSuooCS1WEYTOlUz1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;318&quot; height=&quot;376&quot; data-filename=&quot;숏픽 캡쳐.jpeg&quot; data-origin-width=&quot;1047&quot; data-origin-height=&quot;1239&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;지난 포스팅 (Part 1) 에서 저희는 MAB 기반의 숏픽 추천 시스템을 소개했습니다. 카테고리, 브랜드, 상품명 같은 정형 메타데이터를 feature로 삼아 고객 취향을 학습하는 방식이었습니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그 글의 마지막 '앞으로의 방향' 에서 이런 문장을 남겼습니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;숏픽 추천은 아직 갈길이 멉니다. 기술적으로도, 콘텐츠 전략 측면에서도 진화의 여지가 많습니다. &lt;br /&gt;숏픽 추천의 Next는 영상 자체의 메타 정보를 활용한 콘텐츠 이해에 기반한 추천이라고 생각합니다.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;지금까지는 숏픽에 매핑된 상품 정보를 중심으로 추천을 구성해왔다면, &lt;br /&gt;앞으로는 &lt;b&gt;영상 내 포함된 텍스트, 음성, 이미지 등 콘텐츠 자체의 속성&lt;/b&gt;까지 분석해 추천에 반영하여 더 좋은 성능을 낼 수 있을 것입니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그렇다면&amp;nbsp;영상&amp;nbsp;안에&amp;nbsp;담긴&amp;nbsp;그&amp;nbsp;풍부한&amp;nbsp;정보를,&amp;nbsp;과연&amp;nbsp;&lt;b&gt;어떻게&amp;nbsp;꺼낼&amp;nbsp;수&amp;nbsp;있을까&lt;/b&gt;.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그&amp;nbsp;고민이&amp;nbsp;Part&amp;nbsp;2의&amp;nbsp;출발이었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;GS SHOP은 수많은 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;홈쇼핑 &lt;/span&gt;영상 데이터를 보유하고 있습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그런데 정작 그 영상들을 우리는 제대로 활용하고 있었을까요?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;들어가며&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;추천을 만든다는건, 일상 속 소통방식을 모방하는 일이라고 생각합니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;친한 친구에게 좋은 식당을 알려줄때 우리는 어떻게 하나요? &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;지도 링크를 직접 보내기도 하지만 가게 후기 영상 링크를 보냅니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;식당에 가서 꼭 먹어봐야할 음식과 그 장소만의 분위기를 전부 생생하게 전할 수 있기때문입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;하고 싶은 말이 많을수록, 영상이 더 효과적임을 우리는 경험을 통해 알고있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이번 포스팅에는 &lt;u&gt;&lt;b&gt;영상을 데이터로 이해하기까지의 여정&lt;/b&gt;&lt;/u&gt;을 담았습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;왜 지금이었을까 - 이 과제를 시작한 이유&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;영상 기반 추천은 오래된 숙제였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Part 1을 마무리하면서 To-Be로 적어놓긴 했지만 그게 당장 실현 가능한 일이라고는 생각하지 않았습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;영상을 이해한다는 건 영상에서 의미 있는 정보를 기계가 꺼낼 수 있어야 하는데, 그게 가능한지 자체가 불분명했기 때문입니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그런데 2024년을 지나면서 분위기가 달라졌습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ceD9f5/dJMb990aDlL/VFcOYK0RzrfyjfeSWq1qkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ceD9f5/dJMb990aDlL/VFcOYK0RzrfyjfeSWq1qkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ceD9f5/dJMb990aDlL/VFcOYK0RzrfyjfeSWq1qkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FceD9f5%2FdJMb990aDlL%2FVFcOYK0RzrfyjfeSWq1qkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;699&quot; height=&quot;390&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;LLM이 텍스트를 넘어 이미지를, 이미지를 넘어 영상을 이해하기 시작했습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;멀티모달 모델들이 빠르게 등장했고, 몇 가지 시도를 해보면서 &quot;이 수준이면 실제 서비스에 붙일 수 있겠다&quot;는 감이 왔습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt; 타이밍이 맞아 떨어졌습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;GS SHOP에는 영상이 있습니다. 매일 생방송이 쌓이고, 숏폼 콘텐츠가 쌓이고, &amp;nbsp;S3에 저장되는 영상들이 있었습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;어디서부터 시작해야 할까 고민이 들었습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;영상 추천이라는 최종 목표는 있었지만, 처음부터 추천 시스템을 뜯어고칠 수는 없었습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;먼저 &quot;&lt;b&gt;기계가 영상을 이해할 수 있는가&lt;/b&gt;&quot;를 확인해야 했습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그 검증을 위해 가장 먼저 한 일은, 사내에서 영상을 가장 많이 다루는 현업 담당자들과 이야기를 나누는 것이었습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;1. 과제의 출발점: PD의 고충&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이 여정의 시작은 추천 시스템이 아닌, &lt;u&gt;&lt;b&gt;영상 검색&lt;/b&gt;&lt;/u&gt;이었습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;GS SHOP에서는 매일 생방송 이후에 PD가 수십 개의 영상을 하나씩 재생하며 필요한 장면을 수동으로 찾아야 했습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&quot;이 영상에서 쇼핑호스트가 시식하는 장면이 어디였더라...&quot; 그 장면 하나를 찾는 데 몇 시간이 걸리기도 했습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이 고충에서 자연스럽게 질문이 떠올랐습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&quot;영상도&amp;nbsp;텍스트처럼&amp;nbsp;검색할&amp;nbsp;수&amp;nbsp;있지&amp;nbsp;않을까?&quot;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;2.&amp;nbsp;TwelveLabs와의&amp;nbsp;첫&amp;nbsp;만남:&amp;nbsp;영상을&amp;nbsp;검색하다&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;영상 이해 모델을 찾던 중 TwelveLabs를 알게 됐습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그 중 Marengo는 자연어로 영상 속 특정 장면을 찾아주는 모델이었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot;&gt;바로 접목해 영상 검색 대시보드를 만들었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;대시보드 화면.png&quot; data-origin-width=&quot;1833&quot; data-origin-height=&quot;915&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/br9jfr/dJMcadnTYu8/Ug35bXPHFd4hIIaQvw3aKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/br9jfr/dJMcadnTYu8/Ug35bXPHFd4hIIaQvw3aKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/br9jfr/dJMcadnTYu8/Ug35bXPHFd4hIIaQvw3aKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbr9jfr%2FdJMcadnTYu8%2FUg35bXPHFd4hIIaQvw3aKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1833&quot; height=&quot;915&quot; data-filename=&quot;대시보드 화면.png&quot; data-origin-width=&quot;1833&quot; data-origin-height=&quot;915&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;대시보드를 통해 몇 시간 걸리던 장면 검색을 몇 초 만에 해결할 수 있는 가능성을 보게 되었습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그런데 조사하는 과정에서 흥미로운 사실을 알게 되었는데, 바로 &lt;/span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot;&gt;TwelveLabs 는 두개의 모델을 지원한다는 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;color: #cccccc; text-align: start; border-collapse: collapse; width: 100%; height: 54px;&quot; border=&quot;1&quot; data-line=&quot;90&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style4&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 18px;&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;모델&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 18px;&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;역할&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 18px;&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;질문 방식&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot; data-line=&quot;92&quot;&gt;
&lt;td style=&quot;text-align: center; height: 18px;&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Marengo&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 18px;&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;영상 장면 검색&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 18px;&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&quot;이 장면이 몇 초에 있나?&quot;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot; data-line=&quot;93&quot;&gt;
&lt;td style=&quot;text-align: center; height: 18px;&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Pegasus&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 18px;&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;영상 전체 질의&amp;middot;응답&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 18px;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&quot;이 영상&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 무엇에관한 건가?&quot;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;PD 업무엔 Marengo가 맞았지만, Pegasus는 영상 속 검색 그 이상의 가능성을 갖고 있었습니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이미 영상을 이해하고 있었고,&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;여기서부터&amp;nbsp;다른&amp;nbsp;아이디어가&amp;nbsp;떠오르기&amp;nbsp;시작했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h2 id=&quot;3-%EB%B0%9C%EA%B2%AC-%EC%88%8F%ED%94%BD-%EC%B6%94%EC%B2%9C%EC%9D%80-%EC%82%AC%EC%8B%A4-%EC%98%81%EC%83%81-%EC%B6%94%EC%B2%9C%EC%9D%B4-%EC%95%84%EB%8B%88%EC%97%88%EB%8B%A4&quot; style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;101&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;3. 발견: 숏픽 추천은 &quot;영상&quot; 추천이 아니다&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;103&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이 시점에 숏픽 추천이 어떻게 작동하는지 다시 한번 되짚어봤습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;105&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;이미 알다시피 숏픽 추천은 &lt;u&gt;&lt;b&gt;영상&lt;/b&gt;&lt;/u&gt; 추천이 아니었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;105&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;과거숏폼추천.png&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1owMa/dJMb99MzQKk/60uv1UUEh7XDe2y96otVS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1owMa/dJMb99MzQKk/60uv1UUEh7XDe2y96otVS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1owMa/dJMb99MzQKk/60uv1UUEh7XDe2y96otVS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1owMa%2FdJMb99MzQKk%2F60uv1UUEh7XDe2y96otVS1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;808&quot; height=&quot;451&quot; data-filename=&quot;과거숏폼추천.png&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;121&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;121&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;현재의 추천 방식은 상품과 상품 사이의 추천이었고, 추천된 상품에 숏폼 영상이 있으면 그 영상이 노출되는 방식이었습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;121&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;영상의 내용은 전혀 반영되지 않았습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;121&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;121&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;영상 추천이 왜 이런 방식으로 운영이 되고 있었을까요? &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;121&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;123&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;저희는 이미 이유를 알고 있습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;123&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그리고 동시에, 오래된 질문이 하나 떠올랐습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;123&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h2 id=&quot;4-%EC%9A%B0%EB%A6%AC%EB%8A%94-%EC%A7%80%EA%B8%88%EA%B9%8C%EC%A7%80-%EC%98%81%EC%83%81%EC%9D%84-%EC%9D%B4%ED%95%B4%ED%95%98%EC%A7%80-%EB%AA%BB%ED%96%88%EC%8A%B5%EB%8B%88%EB%8B%A4&quot; style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;127&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;4. &quot;우리는 지금까지 영상을 이해하지 못했습니다&quot;&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;129&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;카테고리, 브랜드, 상품명, 이미지 &amp;mdash; 시스템이 다룰 수 있는 건 이런&amp;nbsp;&lt;b&gt;멈춰있는 데이터&lt;/b&gt;뿐이었습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;129&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;영상을 이해할 수단이 없었기 때문에 상품 정보에 기댈 수밖에 없었던 겁니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;129&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;131&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그렇다면 영상은 무엇일까요?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;131&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/z8zk4/dJMcaivYQDw/p98FF7kY5KNY86LXBrSas1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/z8zk4/dJMcaivYQDw/p98FF7kY5KNY86LXBrSas1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/z8zk4/dJMcaivYQDw/p98FF7kY5KNY86LXBrSas1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fz8zk4%2FdJMcaivYQDw%2Fp98FF7kY5KNY86LXBrSas1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;675&quot; height=&quot;377&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;140&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;140&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;140&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;영상은 상품 이미지에&amp;nbsp;&lt;b&gt;시간축이 더해진 형태&lt;/b&gt;입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;140&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000; text-align: start;&quot;&gt;정보의 밀도가 근본적으로 다릅니다.&lt;/span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;140&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;140&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000; text-align: start;&quot;&gt;우리가 지금까지 놓치고 있던 정보들이 어쩌면 시간의 흐름이었던 걸지도 모른다는 생각이 들었습니다&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/E14lg/dJMcacigH8u/pKGXk5COT9XetCKcWfumu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/E14lg/dJMcacigH8u/pKGXk5COT9XetCKcWfumu0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/E14lg/dJMcacigH8u/pKGXk5COT9XetCKcWfumu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FE14lg%2FdJMcacigH8u%2FpKGXk5COT9XetCKcWfumu0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1376&quot; height=&quot;768&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;156&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; text-align: start;&quot;&gt;그렇다면 &quot;&lt;/span&gt;&lt;u&gt;&lt;b&gt;이해한다&lt;/b&gt;&lt;/u&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; text-align: start;&quot;&gt;&quot;는 건 무슨 뜻일까요?&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;156&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이해한다는 것은 자신 있게 누군가에게 설명할 수 있다는 것. 그리고 이것이 추천의 본질이기도 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;156&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;156&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;추천이란 결국 &quot;이게 당신에게 맞을 것 같아&quot;라고 말하는 행위입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;156&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;156&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h2 id=&quot;5-%EB%A9%88%EC%B6%B0%EC%9E%88%EB%8D%98-%EB%8D%B0%EC%9D%B4%ED%84%B0%EC%97%90-%EC%8B%9C%EA%B0%84%EC%9D%B4-%EB%8D%94%ED%95%B4%EC%A7%80%EB%8B%A4&quot; style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;162&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;5. 멈춰있던 데이터에 시간이 더해지다&lt;/span&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;166&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;시스템이 다룰 수 있는 데이터는 항상&amp;nbsp;&lt;b&gt;멈춰있는 것들&lt;/b&gt;이었습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;166&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;166&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;카테고리 코드, 브랜드 ID, 상품명 텍스트, 대표 이미지. 이런 정형 데이터는 숫자나 텍스트로 표현되고, &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;166&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;추천 엔진이 이해할 수 있는 언어로 변환이 가능했습니다.&lt;/span&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;166&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;168&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그렇다면 영상은 어떤 정보를 담고 있을까요?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;168&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGmOwp/dJMcabwSeTP/p2pKVG1YHJhAfnD5lfcZtk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGmOwp/dJMcabwSeTP/p2pKVG1YHJhAfnD5lfcZtk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGmOwp/dJMcabwSeTP/p2pKVG1YHJhAfnD5lfcZtk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGmOwp%2FdJMcabwSeTP%2Fp2pKVG1YHJhAfnD5lfcZtk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;667&quot; height=&quot;372&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;179&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;앞서 말한것 처럼 영상은 상품 이미지에 &lt;b&gt;시간이 더해진 형태&lt;/b&gt;입니다. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;179&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;179&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;사람이 영상을 보면서 직관적으로 받아들이는 맥락 &amp;mdash; &quot;아 이 제품 실제로 효과가 있나 보다&quot;, &quot;저 MC가 이렇게 좋아하는 걸 보면 진짜인가 봐&quot; &amp;mdash; 이런 정보들은 기존 시스템이 전혀 건드리지 못하는 영역이었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;179&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;179&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;LLM과 멀티모달 모델이 이미지를 이해하기 시작했고, 똑똑해진 모델의 입력 시퀀스가 늘어나면서&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-ke-size=&quot;size16&quot; data-line=&quot;140&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;비로소 기계가 이 시간의 흐름을 이해할 수 있게 됐습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-ke-size=&quot;size16&quot; data-line=&quot;140&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-ke-size=&quot;size16&quot; data-line=&quot;140&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;시공간을 살아가는 저희에게 시간의 흐름을 이해하는 도구가 생겼습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-ke-size=&quot;size16&quot; data-line=&quot;140&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;드디어 저희가 바라보는 세상과 기계가 바라보는 세상의 &lt;b&gt;차원이 일치&lt;/b&gt;하게 된 것입니다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;183&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;183&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h2 id=&quot;6-%EC%B2%98%EC%9D%8C%EB%B6%80%ED%84%B0-%EC%84%A4%EA%B3%84%EB%90%9C-%EA%B2%83%EC%B2%98%EB%9F%BC--aws-bedrock-%ED%8C%8C%EC%9D%B4%ED%94%84%EB%9D%BC%EC%9D%B8&quot; style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;187&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;6. 처음부터 설계된 것처럼 &amp;mdash; AWS Bedrock 파이프라인&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;189&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Pegasus를 숏픽에 적용하려는 순간, 인프라 고민이 생각보다 크지 않았습니다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;189&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이미 모든 재료가 AWS 위에 있었습니다&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;193&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;193&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;GS SHOP의 영상 데이터는 S3에 저장되어 있었고, 상품&amp;middot;방송 정보는 Redshift에 있었습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;193&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;193&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그리고 Pegasus는 AWS Bedrock에 올라가 있었습니다.&lt;/span&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;193&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;퍼즐 조각들이 이미 같은 판 위에 놓여 있었던 셈입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;archi.png&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;667&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tLGUy/dJMcaardZ3Y/maPkCw1SMM4kkZXOQkS6jk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tLGUy/dJMcaardZ3Y/maPkCw1SMM4kkZXOQkS6jk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tLGUy/dJMcaardZ3Y/maPkCw1SMM4kkZXOQkS6jk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtLGUy%2FdJMcaardZ3Y%2FmaPkCw1SMM4kkZXOQkS6jk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;794&quot; height=&quot;385&quot; data-filename=&quot;archi.png&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;667&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;208&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;208&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;208&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;각 단계가 하는 일은 명확합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;208&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;210&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;Pegasus&lt;/b&gt;는 영상을 보고 한국어로 장면을 설명합니다. &quot;쇼핑호스트가 클렌징폼을 직접 얼굴에 올려 풍성한 거품을 만들며 피지 개선 효과를 강조하고 있다&quot; 같은 문장을 만들어냅니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;210&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;212&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;Claude&lt;/b&gt;는 그 설명에서 추천에 쓸 수 있는 핵심 키워드를 뽑아냅니다. &quot;체험형 시연&quot;, &quot;피지 개선&quot;, &quot;거품 풍부&quot;, &quot;셀럽 인증&quot; 같은 소구 포인트입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;212&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;214&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;Cohere&lt;/b&gt;는 이 텍스트를 벡터(숫자 배열)로 변환합니다. 비슷한 맥락의 영상은 벡터 공간에서 가깝게 위치하게 되어, &quot;이 영상과 비슷한 영상&quot;을 수학적으로 계산할 수 있게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;214&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;216&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;OpenSearch&lt;/b&gt;는 이 벡터들을 인덱싱해서 실시간 추천 서빙에 씁니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;216&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;218&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;영상이 S3에 올라가는 시점부터 추천 후보에 등록되기까지 &amp;mdash; 이 모든 과정이 AWS 안에서 닫힙니다. 별도 인프라를 구축할 필요가 없었고, 기존 서비스에 새로운 레이어를 자연스럽게 얹을 수 있었습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;218&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;218&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;처음부터 이렇게 설계된 것처럼 맞아 떨어졌습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;218&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h2 id=&quot;%EB%A7%88%EC%B9%98%EB%A9%B0&quot; style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;224&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;마치며&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;226&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이번 포스팅에서 다룬 내용을 정리하면 이렇습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;226&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #cccccc; text-align: start;&quot; data-line=&quot;228&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-line=&quot;228&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;출발점&lt;/b&gt;: PD의 영상 검색 고충에서 &quot;영상도 텍스트처럼 검색할 수 있지 않을까&quot;라는 질문이 시작됐습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-line=&quot;229&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;발견&lt;/b&gt;: Marengo로 영상 검색을 해결하면서, Pegasus라는 두 번째 모델이 가진 더 큰 가능성을 봤습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-line=&quot;230&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;문제 인식&lt;/b&gt;: 현재 숏픽 추천은 영상을 이해하지 않은 채 영상을 노출하고 있었습니다. 이유는 하나였습니다 &amp;mdash; 영상을 이해할 수단이 없었기 때문입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-line=&quot;231&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;개념 전환&lt;/b&gt;: 영상은 2D 이미지에 시간 차원이 더해진 데이터입니다. LLM과 멀티모달 모델 덕분에 비로소 이 차원을 다룰 수 있게 됐습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-line=&quot;232&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;파이프라인&lt;/b&gt;: Pegasus &amp;rarr; Claude &amp;rarr; Cohere &amp;rarr; OpenSearch. AWS 안에서 닫히는 구조였습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;234&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;234&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이제 영상을 이해할 수 있게 됐습니다. 다음 질문은 하나입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;234&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-line=&quot;234&quot; data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&quot;이해한 영상을, 어떻게 추천으로 연결할까?&quot;&lt;/b&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;234&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;234&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;238&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;그 이야기는 Part 3에서 이어집니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;238&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #cccccc; text-align: start;&quot; data-line=&quot;238&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;display: flex; align-items: center; justify-content: flex-end; gap: 20px; padding: 20px 0; border-top: 1px solid #333;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;text-align: right;&quot;&gt;
&lt;p style=&quot;margin: 0; font-size: 1.1em; font-weight: bold;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin: 0px; font-weight: bold;&quot; data-ke-size=&quot;size16&quot;&gt;조민규 Josh &lt;span style=&quot;font-weight: normal; color: #666;&quot;&gt;| AX본부 홈쇼핑AX부문 검색추천파트(H)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0px; font-weight: bold;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;margin: 5px 0 0; color: #333;&quot; data-ke-size=&quot;size16&quot;&gt;추천 시스템 개발을 담당하고 있습니다&lt;/p&gt;
&lt;p style=&quot;margin: 5px 0 0; color: #333;&quot; data-ke-size=&quot;size16&quot;&gt;기술을 통해 사람을 이해하고&lt;/p&gt;
&lt;p style=&quot;margin: 5px 0 0; color: #333;&quot; data-ke-size=&quot;size16&quot;&gt;현상을 설명하려 노력하고 있습니다&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;br /&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;증명사진.jpeg&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;1200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eeTubb/dJMcahRrE8l/MgdeqASvFKBNFkqvMI8BA1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eeTubb/dJMcahRrE8l/MgdeqASvFKBNFkqvMI8BA1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eeTubb/dJMcahRrE8l/MgdeqASvFKBNFkqvMI8BA1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeeTubb%2FdJMcahRrE8l%2FMgdeqASvFKBNFkqvMI8BA1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;100&quot; height=&quot;133&quot; data-filename=&quot;증명사진.jpeg&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;1200&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Data&amp;amp;AI</category>
      <author>otch80</author>
      <guid isPermaLink="true">https://gsretail.tistory.com/87</guid>
      <comments>https://gsretail.tistory.com/87#entry87comment</comments>
      <pubDate>Mon, 30 Mar 2026 17:51:57 +0900</pubDate>
    </item>
    <item>
      <title>비개발자 리서처가 AI로 인터뷰를 자동화하기까지: GS리테일 리서치봇 구축기</title>
      <link>https://gsretail.tistory.com/86</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;AI로 리서치 프로세스를 재설계한 GS리테일의 AX 사례&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1472&quot; data-origin-height=&quot;544&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c3KBL5/dJMcabW0njj/tzUJAra4KdEo3ORaeSGgxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c3KBL5/dJMcabW0njj/tzUJAra4KdEo3ORaeSGgxK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c3KBL5/dJMcabW0njj/tzUJAra4KdEo3ORaeSGgxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc3KBL5%2FdJMcabW0njj%2FtzUJAra4KdEo3ORaeSGgxK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1472&quot; height=&quot;544&quot; data-origin-width=&quot;1472&quot; data-origin-height=&quot;544&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;안녕하세요 AX본부에서 UX/고객 리서치를 담당하는 배선미 매니저입니다   &lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1455&quot; data-start=&quot;1344&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;오늘은 비개발자 리서처가 GEN AI를 활용해 &amp;lsquo;인터뷰 기반 정성 리서치&amp;rsquo;를 자동화한 과정을 소개해보려고 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;Intro:&amp;nbsp;&lt;/b&gt;&lt;b&gt;쉽게 접근할 수 없었던&amp;nbsp;&amp;lsquo;리서치&amp;rsquo;, AI로 풀 수 있을까?&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;저희 팀은 고객 경험을 분석하기 위해 다양한 리서치를 진행하는데요,&lt;br /&gt;그 중에서도&lt;b&gt; &amp;lsquo;인터뷰 기반 리서치&amp;rsquo;는 사실 많은 실무자들이 가장 부담을 느끼는 영역&lt;/b&gt;입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;인터뷰 설계 &amp;rarr; 일정 조율 &amp;rarr; 진행 &amp;rarr; 분석 &amp;rarr; 보고서&amp;hellip; 전부 다 챙기려면 정말 많은 시간과 전문성이 필요하죠.&amp;nbsp;&lt;br /&gt;그래서 &amp;ldquo;필요하긴 하지만 당장은 어렵다&amp;hellip;&amp;rdquo; 하고 포기하는 경우를 많이 봐왔어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;저 역시 리서처로서, 더 많은 실무자가 고객의 목소리를 &amp;lsquo;쉽고 빠르게&amp;rsquo; 들을 수 있다면 좋겠다는 생각을 늘 하고 있었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&amp;ldquo;AI를 활용해 인터뷰 각 단계의 부담을 덜 수 있다면, 누구나 빠르고 쉽게 리서치를 할 수 있지 않을까&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;?&amp;rdquo;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt; &lt;br /&gt;이 질문이, 바로 GS리테일 &amp;lsquo;AI 리서치봇&amp;rsquo; 개발의 출발점&lt;/b&gt;이었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;문제 정의: 인터뷰는 &amp;lsquo;특정 단계&amp;rsquo;가 아니라 &amp;lsquo;전 과정&amp;rsquo;이 어렵다&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;실무자들이 인터뷰를 어려워하는 이유는 아주 명확했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;1.&amp;nbsp;&amp;nbsp; &lt;b&gt;어떤 질문이 좋은 질문인지 모르겠다&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;2.&amp;nbsp;&amp;nbsp; &lt;b&gt;인터뷰를 직접 진행하고 준비할 시간이 없다&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;3.&amp;nbsp;&amp;nbsp; &lt;b&gt;기록하고 분석하는 데 너무 오래 걸린다&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;즉, 인터뷰는 준비부터 분석까지 &lt;b&gt;모든 단계가 부담이 큰 작업&lt;/b&gt;이었어요. &lt;br /&gt;그런데 이 구조는 오히려 AI가 가장 잘할 수 있는 영역이기도 했습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;999&quot; data-origin-height=&quot;398&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uj2K6/dJMb99LEEie/PVToH3daEtSdPmFqr6UWJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uj2K6/dJMb99LEEie/PVToH3daEtSdPmFqr6UWJ1/img.png&quot; data-alt=&quot;&amp;amp;lt;인터뷰 진행 시 어려움&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uj2K6/dJMb99LEEie/PVToH3daEtSdPmFqr6UWJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fuj2K6%2FdJMb99LEEie%2FPVToH3daEtSdPmFqr6UWJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;777&quot; height=&quot;310&quot; data-origin-width=&quot;999&quot; data-origin-height=&quot;398&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;인터뷰 진행 시 어려움&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;개발 방식: &amp;nbsp;비개발 리서처가 GEN AI로 직접 만들다&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;리서치봇 개발 과정에는 특별한 포인트가 있습니다.&lt;br /&gt;바로 &lt;b&gt;개발자가 아닌, 저 같은 &amp;lsquo;비개발자 리서처&amp;rsquo;가 직접 만들었다는 점&lt;/b&gt;입니다.&lt;br /&gt;&amp;ldquo;리서처가? 개발 지식 없이? 어떻게?&amp;rdquo;라고 놀라실 수도 있는데요  &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;GS리테일에는 &lt;b&gt;MISO라는 GEN AI기반의 워크플로우&amp;middot;AI 에이전트 생성 플랫폼&lt;/b&gt;이 있습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;올해 회사에서는 구성원들의 AI 실무 역량을 키우기 위해 MISO 교육을 운영했고,&amp;nbsp;&lt;br /&gt;저도 그 과정을 거치며 실제 업무에 적용할 기회를 얻었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;리서치봇은 바로 이 MISO를 기반으로 만들어졌습니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1028&quot; data-origin-height=&quot;405&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxZU5w/dJMcai9CtBY/kUxpwUHmkI39hS5CYL2QSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxZU5w/dJMcai9CtBY/kUxpwUHmkI39hS5CYL2QSK/img.png&quot; data-alt=&quot;&amp;amp;lt;AI리서치봇 개발 과정&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxZU5w/dJMcai9CtBY/kUxpwUHmkI39hS5CYL2QSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxZU5w%2FdJMcai9CtBY%2FkUxpwUHmkI39hS5CYL2QSK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;778&quot; height=&quot;307&quot; data-origin-width=&quot;1028&quot; data-origin-height=&quot;405&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;AI리서치봇 개발 과정&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;리서치봇을 만들기 위해 다음과 같은 과정을 거쳤습니다:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;리서치 프로세스를 단계별로 쪼개고&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;각 단계에서 &lt;b&gt;AI가 할 수 있는 일&lt;/b&gt;을 정리하고&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;프롬프트와 흐름을 설계하고&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;테스트 개선을 반복했습니다&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;이 과정을 빠르게 반복하면서, 몇주만에 인터뷰 설계부터 분석까지 자동화하는 베타버전을 완성할 수 있었어요.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1013&quot; data-origin-height=&quot;399&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQnq9g/dJMcaihw0rD/kk7mGNYv7MziTxaoVZaDWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQnq9g/dJMcaihw0rD/kk7mGNYv7MziTxaoVZaDWK/img.png&quot; data-alt=&quot;&amp;amp;lt;인터뷰 프로세스에서 AI기회요소 도출&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQnq9g/dJMcaihw0rD/kk7mGNYv7MziTxaoVZaDWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQnq9g%2FdJMcaihw0rD%2Fkk7mGNYv7MziTxaoVZaDWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;776&quot; height=&quot;306&quot; data-origin-width=&quot;1013&quot; data-origin-height=&quot;399&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;인터뷰 프로세스에서 AI기회요소 도출&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;이 과정에서 느낀점은 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;&amp;ldquo;업무 흐름을 가장 잘 아는 사람이 직접 도구를 만들 수 있는 환경&amp;rdquo;&lt;/b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;의 가치가 얼마나 큰지 다시 한 번 느꼈습니다. &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;880&quot; data-origin-height=&quot;399&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXNVft/dJMcajtVahQ/2w2Glot3BJmZ1snn4k2lj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXNVft/dJMcajtVahQ/2w2Glot3BJmZ1snn4k2lj0/img.png&quot; data-alt=&quot;&amp;amp;lt;팀 내부 테스트 및 피드백 수집&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXNVft/dJMcajtVahQ/2w2Glot3BJmZ1snn4k2lj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXNVft%2FdJMcajtVahQ%2F2w2Glot3BJmZ1snn4k2lj0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;641&quot; height=&quot;291&quot; data-origin-width=&quot;880&quot; data-origin-height=&quot;399&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;팀 내부 테스트 및 피드백 수집&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;리서치봇 기술 구조: Agent &amp;times; Workflow로 구현된 자동화&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;앞서 소개한 MISO의 두 가지 핵심 요소인 Agent(에이전트)와 Workflow(워크플로우)를 조합해 구현하였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;Agent = 대화하고 판단하는 역할(AI 챗봇)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;Workflow = 여러 작업을 순차적으로 자동 처리하는 역할(AI 자동화)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;이 두 기능을 활용하여 &amp;lsquo;설계 &amp;rarr; 진행 &amp;rarr; 분석&amp;rsquo;까지의 인터뷰 전체 흐름을 하나로 묶을 수 있었는데요,&amp;nbsp;&lt;b&gt;&lt;i&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;Agent가&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp;&amp;ldquo;&lt;/span&gt;대화와 생성&amp;rdquo;을 담당하고&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp;Workflow&lt;/span&gt;가&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp;&amp;ldquo;&lt;/span&gt;정제와 자동화&amp;rdquo;를 담당&lt;/b&gt;하면서&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;, &lt;br /&gt;&lt;/span&gt;인터뷰 전 과정이 유기적으로 연결되도록 설계한 것이 핵심입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;또한, &lt;b&gt;각 단계의 프롬프트에는 역할(Role)과 수행 규칙을 명확히 정의&lt;/b&gt;해 일관된 품질을 유지할 수 있도록 했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 99.5349%; height: 117px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 21px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;①설계봇&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;(Agent)&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;질문 생성 설계자&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 21px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;②진행봇&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;(Agent)&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;실제 인터뷰 진행자&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 21px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;③분석봇&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;(Workflow)&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;데이터 정제 및 인사이트 분석가&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 86px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 86px; text-align: left;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt; &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;조사 목적&amp;middot;대상자&amp;middot;알고 싶은 내용을 입력하면, 설계봇이&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;질문 생성 지침과 구조 프롬프트&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;를 기반으로 인터뷰 질문 리스트를 자동으로 만들어줍니다. 필요하면&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;재생성&amp;middot;수정&lt;/b&gt;&lt;/span&gt;도 바로 가능해요. &lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 86px; text-align: left;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;설계봇이 만든 질문 리스트가 전달되면&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;진행봇은&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;인터뷰 가이드 프롬프트&lt;/b&gt;&lt;/span&gt;에 따라 사람처럼 자연스럽게 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;인터뷰를 진행&lt;/b&gt;&lt;/span&gt;합니다. 탐색 질문(probing)도 상황에 맞춰 이어가요.&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 86px; text-align: left;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;인터뷰가 끝나면 분석봇이 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;로그 데이터를 자동으로 정제&lt;/b&gt;&lt;/span&gt;한 뒤, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;분석 프롬프트&lt;/b&gt;&lt;/span&gt;를 통해&amp;nbsp;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;핵심 문장 추출&amp;middot;주요 인사이트&amp;middot;요약&amp;middot;긍&amp;middot;부정 키워드&amp;middot;개선 제안&lt;/span&gt;&lt;/b&gt;을 생성해요. 최종적으로 자동으로 보고서가 작성됩니다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;AI &lt;/b&gt;&lt;b&gt;리서치봇의 가치 &amp;mdash; 인터뷰 설계, 진행, 분석의 과정을 자동화 &lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;리서치봇의 &lt;b&gt;핵심 목표는 &amp;ldquo;리서치를 해보지 않은 사람도 쉽게 인터뷰를 할 수 있게 하는 것&amp;rdquo;&lt;/b&gt;인데요,&lt;br /&gt;그래서 인터뷰의 세 가지 큰 허들(① &amp;nbsp;설계, ② &amp;nbsp;진행, ③ 분석)을 낮추는 데 집중했어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;① 인터뷰 질문 설계 자동화&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;조사 목적만 입력하면 리서치 경험이 없어도 &lt;b&gt;5분 안에 인터뷰 질문 설계가 완성&lt;/b&gt;할 수 있습니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;후속 질문&amp;middot;응답 시간 같은 부가 정보도 자동 구성돼요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;② 인터뷰 진행 자동화&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt; 기존의 대면 1:1 인터뷰 대신, AI가 &lt;b&gt;채팅 기반으로 자연스럽게 인터뷰를 진행&lt;/b&gt;합니다.&lt;br /&gt;필요한 경우 probing 질문도 스스로 이어가고요. &lt;br /&gt;여러 인터뷰를 동시에 진행할 수도 있어 예전엔 &lt;b&gt;며칠 걸리던 일이 수십 분으로 줄어&lt;/b&gt;듭니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;③ 결과 분석 자동화&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt; AI가 분석 초안&lt;/b&gt;을 먼저 만들어주고 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;b&gt;실무자는 그 결과를 빠르게 검토&amp;middot;보완하는 방식&lt;/b&gt;으로&amp;nbsp;&lt;/span&gt;기존 대비 분석 시간이 크게 줄었어요. &lt;br /&gt;&lt;b&gt;보고서 품질 편차도 줄고, 정성 분석의 부담이 크게 줄어드는 효과&lt;/b&gt;가 있었습니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;그 결과, 파일럿 기준&amp;nbsp;&lt;b&gt;리서치 전체 소요시간이 약 80% 감소&lt;/b&gt;하는 효과를 확인했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;궁금한 내용이 생겼을 때 바로 질문하고&amp;nbsp;&amp;rarr;&amp;nbsp;바로 데이터를 얻는&amp;nbsp;&amp;lsquo;즉시 리서치 환경&amp;rsquo;&amp;nbsp;이 가능해진거죠&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;이는 아이디어 검증&amp;ndash;수정&amp;ndash;재확인까지의 사이클을 크게 단축시키며, 업무 속도와 협업 효율을 크게 높여줄 것으로 기대됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;980&quot; data-origin-height=&quot;590&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biTZSc/dJMcafSD6JY/kqxJqh5KVpX0rYckT9BSp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biTZSc/dJMcafSD6JY/kqxJqh5KVpX0rYckT9BSp0/img.png&quot; data-alt=&quot;&amp;amp;lt; AI리서치봇 설계&amp;amp;ndash;진행&amp;amp;ndash;분석 화면: 사내 프로그램 인터뷰 사례&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biTZSc/dJMcafSD6JY/kqxJqh5KVpX0rYckT9BSp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiTZSc%2FdJMcafSD6JY%2FkqxJqh5KVpX0rYckT9BSp0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;815&quot; height=&quot;491&quot; data-origin-width=&quot;980&quot; data-origin-height=&quot;590&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt; AI리서치봇 설계&amp;ndash;진행&amp;ndash;분석 화면: 사내 프로그램 인터뷰 사례&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;활용 범위의 확장 : UX(User Experience) + EX(Employee Experience)로&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;리서치봇은 원래 &lt;b&gt;고객 인터뷰 자동화&lt;/b&gt;를 목표로 시작했습니다.&lt;br /&gt;하지만 MISO&amp;nbsp;보안상, 대고객 서비스 적용은 당장은 어려워 우선 &lt;b&gt;임직원 의견 수집&lt;/b&gt;에 활용하기로 방향을 바꿨습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;그런데 예상 밖의 기회가 열렸습니다. 임직원 인터뷰 중심으로 진행해 보니,&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;조직문화&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;교육&amp;middot;온보딩&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;사내 제도&amp;middot;프로세스&amp;middot;시스템 피드백&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;등 &lt;b&gt;임직원 경험(EX)&lt;/b&gt; 개선에도 활용 가치가 크다는 점을 발견할 수 있었어요.&lt;br /&gt;즉, UX뿐 아니라 &lt;b&gt;EX 영역&lt;/b&gt;까지 기대하지 않았던 확장성이 자연스럽게 열리게 되었어요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;현재 단계: 내부 테스트 완료, 베타테스트 준비 중, 그리고 앞으로의 확장&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;파일럿 테스트 과정에서 받은 리서치봇 피드백은 긍정적이었습니다. &lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666; font-family: 'Noto Sans Light';&quot;&gt;&amp;ldquo;&lt;i&gt;채팅형 인터뷰는 대면 인터뷰에서 얻기 힘든 '솔직한 의견', 특히 '단점'이나 '개선점'을 파악하는 데 매우 효과적일 것 같아요.&quot;&lt;/i&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666; font-family: 'Noto Sans Light';&quot;&gt;&lt;i&gt;&amp;ldquo;진짜 리서처와 인터뷰하는 느낌을 받았어요 집요하게 사례를 찾아내려고 하네요&amp;rdquo;&lt;/i&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #666666; font-family: 'Noto Sans Light';&quot;&gt;&lt;i&gt;&quot;AI 리서치봇이 다수로부터 정성적 데이터를 수집하고 이를 정량화할 수 있다는 점에 큰 기대가 돼요&quot;&lt;/i&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;이제 더 많은 임직원이 실제로 사용해보고 피드백을 남길 수 있도록 &lt;b&gt;베타테스트를 진행&lt;/b&gt;할 예정입니다.&lt;br /&gt;베타 기간 동안 인터뷰 품질&amp;middot;UI/UX&amp;middot;보고서 형태를 고도화해 장기적으로는 고객 대상 서비스로 확장하는 것도 목표입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;마치며: 이 프로젝트가 가능했던 이유&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;마지막으로, 이번 프로젝트는 제 개인의 역량만으로는 완성할 수 없었습니다. &lt;br /&gt;사내 MISO 교육 과정과 DX COE팀의 기술적 지원이 없었다면, 비개발자인 제가 혼자 구현하기 어려웠을 거에요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;또한 파일럿 테스트 단계에서 바쁜 와중에도 적극적으로 참여해 실제 사용 기반 피드백을 제공해주신 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;UX인사이트팀 팀장님과 팀원들 덕분에, 리서치봇은 훨씬 더 빠른 속도로 완성도를 높일 수 있었습니다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;업무 도메인을 가장 잘 아는 사람이 직접 도구를 만들 수 있도록 환경과 교육, 실험 기회를 제공해준 조직의 문화와 지원에 대해 이 자리를 빌려 감사의 마음을 전하고 싶습니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock floatRight&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;202&quot; data-origin-height=&quot;194&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vx8bM/btsJeAo8xZk/NXPFU802liPodFrOcA5RBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vx8bM/btsJeAo8xZk/NXPFU802liPodFrOcA5RBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vx8bM/btsJeAo8xZk/NXPFU802liPodFrOcA5RBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fvx8bM%2FbtsJeAo8xZk%2FNXPFU802liPodFrOcA5RBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;141&quot; height=&quot;135&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;202&quot; data-origin-height=&quot;194&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;배선미&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: right;&quot;&gt;&amp;nbsp;|&amp;nbsp;&lt;b&gt;AX본부 플랫폼AX부문 편의점AX팀&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #333333; text-align: right; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;GS리테일에서 고객경험 개선을 위한 UX리서치를 담당하고 있습니다&lt;br /&gt;새로운 것을 배우고 이것저것 시도해보는 것을 좋아합니다 :)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;p style=&quot;text-align: right;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Data&amp;amp;AI</category>
      <category>AI UX리서치</category>
      <category>AI 에이전트</category>
      <category>AI리서치봇</category>
      <category>AX사례</category>
      <category>GenAI혁신</category>
      <category>GS리테일 AX</category>
      <category>GS리테일테크</category>
      <category>리서치자동화</category>
      <author>sunmibae</author>
      <guid isPermaLink="true">https://gsretail.tistory.com/86</guid>
      <comments>https://gsretail.tistory.com/86#entry86comment</comments>
      <pubDate>Mon, 8 Dec 2025 12:18:55 +0900</pubDate>
    </item>
    <item>
      <title>[GS리테일] DX본부 플랫폼데이터분석팀/홈쇼핑데이터분석팀 데이터 사이언티스트 경력사원 채용(~10/24)</title>
      <link>https://gsretail.tistory.com/85</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슬라이드1.PNG&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;3213&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9m7xu/btsQ8vuke5B/p5UQ3uWSeQoKYgXdFhm9wk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9m7xu/btsQ8vuke5B/p5UQ3uWSeQoKYgXdFhm9wk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9m7xu/btsQ8vuke5B/p5UQ3uWSeQoKYgXdFhm9wk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9m7xu%2FbtsQ8vuke5B%2Fp5UQ3uWSeQoKYgXdFhm9wk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;756&quot; height=&quot;3213&quot; data-filename=&quot;슬라이드1.PNG&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;3213&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>채용공고</category>
      <category>GS25</category>
      <category>gs리테일 채용</category>
      <category>데이터 분석</category>
      <category>데이터 사이언스</category>
      <category>데이터 사이언티스트</category>
      <author>jayjay5</author>
      <guid isPermaLink="true">https://gsretail.tistory.com/85</guid>
      <comments>https://gsretail.tistory.com/85#entry85comment</comments>
      <pubDate>Tue, 14 Oct 2025 11:39:51 +0900</pubDate>
    </item>
  </channel>
</rss>