<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>개인정보보호 &#8211; 솜삽 블로그</title>
	<atom:link href="https://somsap.somsap.com/tag/%EA%B0%9C%EC%9D%B8%EC%A0%95%EB%B3%B4%EB%B3%B4%ED%98%B8/feed/" rel="self" type="application/rss+xml" />
	<link>https://somsap.somsap.com</link>
	<description>개발, 업무, 피아노 등등</description>
	<lastBuildDate>Sun, 03 May 2026 12:54:12 +0000</lastBuildDate>
	<language>ko-KR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7.5</generator>

<image>
	<url>https://somsap.somsap.com/wp-content/uploads/sites/6/2025/02/cropped-이미지-1924-2-32x32.png</url>
	<title>개인정보보호 &#8211; 솜삽 블로그</title>
	<link>https://somsap.somsap.com</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">241690237</site>	<item>
		<title>쿠팡 탈퇴 회원 정보, 이렇게 관리해도 될까요? 개인정보 논란 재점화!</title>
		<link>https://somsap.somsap.com/2026/03/31/%ec%bf%a0%ed%8c%a1-%ed%83%88%ed%87%b4-%ed%9a%8c%ec%9b%90-%ec%a0%95%eb%b3%b4-%eb%85%bc%eb%9e%80/</link>
					<comments>https://somsap.somsap.com/2026/03/31/%ec%bf%a0%ed%8c%a1-%ed%83%88%ed%87%b4-%ed%9a%8c%ec%9b%90-%ec%a0%95%eb%b3%b4-%eb%85%bc%eb%9e%80/#respond</comments>
		
		<dc:creator><![CDATA[somsap]]></dc:creator>
		<pubDate>Tue, 31 Mar 2026 14:50:00 +0000</pubDate>
				<category><![CDATA[미분류]]></category>
		<category><![CDATA[개인정보보호]]></category>
		<category><![CDATA[온라인 서비스]]></category>
		<category><![CDATA[쿠팡 개인정보]]></category>
		<category><![CDATA[탈퇴 회원]]></category>
		<category><![CDATA[회원 정보 관리]]></category>
		<guid isPermaLink="false">https://somsap.somsap.com/2026/03/31/%ec%bf%a0%ed%8c%a1-%ed%83%88%ed%87%b4-%ed%9a%8c%ec%9b%90-%ec%a0%95%eb%b3%b4-%eb%85%bc%eb%9e%80/</guid>

					<description><![CDATA[<p>솔직히 말하면, 온라인 쇼핑 자주 하는 분들이라면 한 번쯤은 쿠팡 이용해보셨을 거예요. 저도 정말 자주 이용하거든요. 로켓배송의 편리함 때문에 끊을 수가 없죠. 급하게 필요한 게 있을 때 쿠팡만큼 빠른 곳이 없잖아요?근데 최근에 좀 걱정되는 소식을 접하게 됐어요. 바로 쿠팡 탈퇴 회원 정보 관리 문제로 개인정보 논란이 다시 불거졌다는 이야기였죠.아니, 회원 탈퇴를 했는데도 &#8220;미사용 구매이용권&#8221; 안내 [&#8230;]</p>
<p>게시물 <a rel="nofollow" href="https://somsap.somsap.com/2026/03/31/%ec%bf%a0%ed%8c%a1-%ed%83%88%ed%87%b4-%ed%9a%8c%ec%9b%90-%ec%a0%95%eb%b3%b4-%eb%85%bc%eb%9e%80/">쿠팡 탈퇴 회원 정보, 이렇게 관리해도 될까요? 개인정보 논란 재점화!</a>이 <a rel="nofollow" href="https://somsap.somsap.com">솜삽 블로그</a>에 처음 등장했습니다.</p>
]]></description>
										<content:encoded><![CDATA[<p>솔직히 말하면, 온라인 쇼핑 자주 하는 분들이라면 한 번쯤은 쿠팡 이용해보셨을 거예요. 저도 정말 자주 이용하거든요. 로켓배송의 편리함 때문에 끊을 수가 없죠. 급하게 필요한 게 있을 때 쿠팡만큼 빠른 곳이 없잖아요?<br />근데 최근에 좀 걱정되는 소식을 접하게 됐어요. 바로 <strong>쿠팡 탈퇴 회원 정보</strong> 관리 문제로 개인정보 논란이 다시 불거졌다는 이야기였죠.<br />아니, 회원 탈퇴를 했는데도 &#8220;미사용 구매이용권&#8221; 안내 문자가 온다니, 이게 무슨 일인가 싶더라고요. 개인적으로는 정말 깜짝 놀랐습니다. 소비자의 입장에서 이런 소식은 꽤나 민감할 수밖에 없잖아요. 제 정보가 어떻게 관리되고 있는지 궁금해질 수밖에 없었습니다. 혹시 내 정보도 아직 남아있는 건 아닐까 하는 불안감도 들었고요.</p>
<h2>탈퇴했는데 왜 문자가 오는 걸까요?</h2>
<figure class="wp-block-image size-full"><img decoding="async" src="https://somsap.somsap.com/wp-content/uploads/sites/6/2026/03/blog-image-1774968594050.png" alt="탈퇴했는데 왜 문자가 오는 걸까요? - 쿠팡 탈퇴 회원 정보" style="width:100%;height:auto" title="쿠팡 탈퇴 회원 정보, 이렇게 관리해도 될까요? 개인정보 논란 재점화! 4"></figure>
<p>요즘 온라인 서비스들, 정말 편리하잖아요? 클릭 몇 번이면 필요한 물건이 다음 날 문 앞에 도착하니 말이죠. 이런 편의성 때문에 많은 분들이 저처럼 쿠팡을 자주 이용하고 계실 거예요.<br />근데 그만큼 개인정보 관리가 중요해진 시대인데, 쿠팡에서 탈퇴한 회원들에게 &#8220;미사용 구매이용권&#8221; 안내 문자를 보냈다고 해요. 이게 사실이라면, 탈퇴했는데도 내 정보가 여전히 시스템 어딘가에 남아있었다는 거잖아요. 솔직히 좀 찜찜하고, 개인적으로는 기업에 대한 신뢰 문제가 아닌가 싶더라고요. 이런 일이 반복되면 소비자들이 불안감을 느낄 수밖에 없죠.<br />이런 상황은 보통 다음과 같은 경우에 발생할 수 있다고 하는데요.</p>
<ul>
<li>회원 탈퇴 처리 과정에서 시스템적인 오류가 발생했거나, 처리 지연이 있었을 때</li>
<li>개인정보 처리 방침에 따라 법적 의무 이행을 위해 일정 기간 정보가 보관될 수 있다고 명시되어 있었을 때</li>
<li>마케팅 수신 동의 철회와 회원 탈퇴가 별개로 처리되어, 탈퇴 후에도 마케팅 동의가 살아있어 잔여 정보가 활용된 경우</li>
</ul>
<p>제 생각엔, 어떤 이유든 탈퇴 의사를 명확히 밝혔다면 거기에 따라 정보도 깔끔하게 정리되어야 하는 게 맞지 않나 싶어요. 이런 문제 때문에 <a href="https://www.pipc.go.kr" target="_blank" rel="noopener">개인정보보호위원회</a>에서도 관련 내용을 검토 중이라고 하니, 결과가 어떻게 될지 지켜봐야 할 것 같아요. 소비자의 알 권리 차원에서도 명확한 설명과 개선 방안이 필요하다고 생각합니다.</p>
<h2>내 소중한 개인정보, 탈퇴 후에도 어디까지 남는 걸까?</h2>
<figure class="wp-block-image size-full"><img decoding="async" src="https://somsap.somsap.com/wp-content/uploads/sites/6/2026/03/blog-image-1774968594371.png" alt="내 소중한 개인정보, 탈퇴 후에도 어디까지 남는 걸까?" style="width:100%;height:auto" title="쿠팡 탈퇴 회원 정보, 이렇게 관리해도 될까요? 개인정보 논란 재점화! 5"></figure>
<p>사실, 온라인 서비스 탈퇴할 때마다 &#8220;내 정보가 다 지워질까?&#8221; 하는 걱정은 늘 있었거든요. 이번 쿠팡 사례를 보면서 그 걱정이 현실이 된 것 같아 더 불안해졌어요. 솔직히 말하면, 이건 단순히 문자를 한 번 더 보낸 문제가 아니잖아요.<br />개인정보는 정말 소중한 거잖아요. 특히, 내가 더 이상 이용하지 않겠다고 명확히 의사를 밝혔는데도 정보가 남아있고, 심지어 그걸로 마케팅 문자를 받았다면 이건 명백히 문제라고 생각해요. 단순히 귀찮음을 넘어선 프라이버시 침해 문제거든요. 내 의사와 상관없이 내 정보가 활용될 수 있다는 가능성 자체가 불편함을 주는 거죠.<br />개인적으로는 기업들이 이런 <strong>탈퇴 회원 정보</strong> 관리에 더 신경 써야 한다고 봐요. 법적 최소 보관 기간만 채우는 게 아니라, 고객의 신뢰를 얻기 위해서라도 더 투명하고 안전하게 정보를 다뤄야 하죠. 안 그러면 정말 많은 사람들이 서비스 이용을 망설이게 될 거예요. 우리 모두의 프라이버시가 달린 문제니까요. 이런 부분이 개선되지 않으면 소비자들이 결국 외면하게 될 수밖에 없지 않을까요? 기업들은 이런 점을 간과해서는 안 된다고 생각합니다. 고객의 신뢰를 잃는 건 한순간이니까요.</p>
<h2>기업의 개인정보 관리, 이제는 선택이 아닌 필수!</h2>
<figure class="wp-block-image size-full"><img decoding="async" src="https://somsap.somsap.com/wp-content/uploads/sites/6/2026/03/blog-image-1774968595360.png" alt="기업의 개인정보 관리, 이제는 선택이 아닌 필수!" style="width:100%;height:auto" title="쿠팡 탈퇴 회원 정보, 이렇게 관리해도 될까요? 개인정보 논란 재점화! 6"></figure>
<p>요즘 같은 시대에 기업이 개인정보를 어떻게 관리하느냐는 정말 중요하다고 생각해요. 단순히 서비스의 편리함을 넘어, 고객과의 신뢰를 쌓는 핵심 요소가 되니까요. 개인정보보호법도 점점 더 강화되고 있잖아요. 기업들이 이런 흐름에 발맞춰야 하는 건 당연한 이야기고요. 소비자들의 기대치도 높아지고 있고요. 예전처럼 대충 넘어가기 어려운 시대가 된 거죠.<br />기업들이 개인정보를 안전하게 관리하기 위해서는 몇 가지 중요한 원칙들이 있어요.</p>
<ul>
<li><a href="https://www.coupang.com/np/etc/privacyPolicy" target="_blank" rel="noopener">쿠팡 개인정보 처리 방침</a>처럼 개인정보 처리 방침을 명확하게 고지하고 고객이 쉽게 접근할 수 있도록 해야 해요. 복잡하고 어려운 용어보다는 이해하기 쉽게 설명하는 게 중요하죠.</li>
<li>회원 탈퇴 시, 어떤 정보가 언제까지, 어떤 목적으로 보관되는지 상세히 안내해야죠. 그리고 그 보관 기간이 지나면 확실히 파기한다는 약속도 지켜야 하고요.</li>
<li>마케팅 수신 동의와 개인정보 보관 동의를 명확히 분리해서 받아야 하고요. 동의 여부를 고객이 쉽게 확인하고 철회할 수 있도록 해야 합니다.</li>
<li>수집 목적이 달성되거나 탈퇴 등으로 불필요해진 회원 정보는 지체 없이 파기하는 것이 원칙이에요. 불필요한 정보는 더 이상 가지고 있지 않는 것이 가장 안전하니까요.</li>
</ul>
<p>이런 원칙들을 철저히 지키는 것이 결국 기업의 이미지를 좋게 만들고, 고객 충성도를 높이는 길이라고 믿어요. 그래야 소비자들이 안심하고 서비스를 이용할 수 있겠죠. 기업의 장기적인 성장에도 도움이 될 거고요. 결국은 기업과 소비자 모두에게 이득이 되는 일 아닐까요?<br />이번 쿠팡 개인정보 논란을 보면서 다시 한번 개인정보의 중요성을 깨닫게 됐어요. 우리 소비자들도 내 정보가 어떻게 관리되는지 좀 더 관심을 가지고 지켜봐야 할 것 같아요. 무심코 지나쳤던 약관들을 다시 한번 읽어보는 습관도 필요할 것 같고요.<br />기업들이 고객의 소중한 정보를 더 책임감 있게 다루는 계기가 되기를 바라봅니다. 안심하고 서비스를 이용할 수 있는 환경이 빨리 왔으면 좋겠어요! 모두가 만족할 수 있는 안전한 온라인 세상이 되기를 기대해봅니다. 우리 모두의 노력이 필요할 것 같아요.</p>
<p>게시물 <a rel="nofollow" href="https://somsap.somsap.com/2026/03/31/%ec%bf%a0%ed%8c%a1-%ed%83%88%ed%87%b4-%ed%9a%8c%ec%9b%90-%ec%a0%95%eb%b3%b4-%eb%85%bc%eb%9e%80/">쿠팡 탈퇴 회원 정보, 이렇게 관리해도 될까요? 개인정보 논란 재점화!</a>이 <a rel="nofollow" href="https://somsap.somsap.com">솜삽 블로그</a>에 처음 등장했습니다.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://somsap.somsap.com/2026/03/31/%ec%bf%a0%ed%8c%a1-%ed%83%88%ed%87%b4-%ed%9a%8c%ec%9b%90-%ec%a0%95%eb%b3%b4-%eb%85%bc%eb%9e%80/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3728</post-id>	</item>
		<item>
		<title>🎙️ 로컬 AI로 만드는 인터뷰 분석기 개발기 &#8211; 외부 API 없이 완전 오프라인 구현</title>
		<link>https://somsap.somsap.com/2026/03/30/%f0%9f%8e%99%ef%b8%8f-%eb%a1%9c%ec%bb%ac-ai%eb%a1%9c-%eb%a7%8c%eb%93%9c%eb%8a%94-%ec%9d%b8%ed%84%b0%eb%b7%b0-%eb%b6%84%ec%84%9d%ea%b8%b0-%ea%b0%9c%eb%b0%9c%ea%b8%b0-%ec%99%b8%eb%b6%80-api-%ec%97%86/</link>
					<comments>https://somsap.somsap.com/2026/03/30/%f0%9f%8e%99%ef%b8%8f-%eb%a1%9c%ec%bb%ac-ai%eb%a1%9c-%eb%a7%8c%eb%93%9c%eb%8a%94-%ec%9d%b8%ed%84%b0%eb%b7%b0-%eb%b6%84%ec%84%9d%ea%b8%b0-%ea%b0%9c%eb%b0%9c%ea%b8%b0-%ec%99%b8%eb%b6%80-api-%ec%97%86/#respond</comments>
		
		<dc:creator><![CDATA[somsap]]></dc:creator>
		<pubDate>Mon, 30 Mar 2026 12:02:29 +0000</pubDate>
				<category><![CDATA[개발/프로그래밍]]></category>
		<category><![CDATA[ChromaDB]]></category>
		<category><![CDATA[CUDA]]></category>
		<category><![CDATA[EXAONE]]></category>
		<category><![CDATA[FastAPI]]></category>
		<category><![CDATA[faster-whisper]]></category>
		<category><![CDATA[HuggingFace]]></category>
		<category><![CDATA[mlx-whisper]]></category>
		<category><![CDATA[Ollama]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[RAG]]></category>
		<category><![CDATA[Streamlit]]></category>
		<category><![CDATA[STT]]></category>
		<category><![CDATA[Whisper]]></category>
		<category><![CDATA[개인정보보호]]></category>
		<category><![CDATA[로컬AI]]></category>
		<category><![CDATA[벡터DB]]></category>
		<category><![CDATA[오프라인AI]]></category>
		<category><![CDATA[음성인식]]></category>
		<category><![CDATA[인터뷰분석기]]></category>
		<category><![CDATA[자연어처리]]></category>
		<guid isPermaLink="false">https://somsap.somsap.com/?p=3432</guid>

					<description><![CDATA[<p>외부 API 비용과 데이터 유출 걱정은 이제 그만! STT(Whisper), 벡터 DB, LLM(Ollama)을 결합하여 100% 로컬 환경에서 무료로 동작하는 'AI 인터뷰 분석기' 개발 과정을 아키텍처부터 하드웨어 최적화까지 상세히 공유합니다.</p>
<p>게시물 <a rel="nofollow" href="https://somsap.somsap.com/2026/03/30/%f0%9f%8e%99%ef%b8%8f-%eb%a1%9c%ec%bb%ac-ai%eb%a1%9c-%eb%a7%8c%eb%93%9c%eb%8a%94-%ec%9d%b8%ed%84%b0%eb%b7%b0-%eb%b6%84%ec%84%9d%ea%b8%b0-%ea%b0%9c%eb%b0%9c%ea%b8%b0-%ec%99%b8%eb%b6%80-api-%ec%97%86/">🎙️ 로컬 AI로 만드는 인터뷰 분석기 개발기 &#8211; 외부 API 없이 완전 오프라인 구현</a>이 <a rel="nofollow" href="https://somsap.somsap.com">솜삽 블로그</a>에 처음 등장했습니다.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading" id="프로젝트-개요">프로젝트 개요</h2>



<p>최근 AI 기술이 발전하면서 음성 인식과 자연어 처리를 활용한 다양한 서비스들이 등장하고 있습니다.&nbsp;하지만 대부분의 서비스들이 외부 API에 의존하고 있어 비용 부담과 데이터 보안 우려가 있었습니다.</p>



<p>이번에 개발한&nbsp;&#8216;인터뷰 분석기&#8217;는&nbsp;<strong>완전히 로컬 환경에서 동작</strong>하는 AI 서비스로,&nbsp;인터뷰 녹음 파일을 업로드하면 음성을 텍스트로 변환하고,&nbsp;변환된 내용을 바탕으로 자유롭게 질의응답할 수 있는 시스템입니다.</p>



<h3 class="wp-block-heading" id="주요-특징">주요 특징</h3>



<ul class="wp-block-list">
<li>🔒 <strong>완전 오프라인</strong>: 모든 데이터가 로컬에서만 처리</li>



<li>🎯 <strong>올인원 솔루션</strong>: STT, 임베딩, LLM까지 통합</li>



<li>💰 <strong>제로 비용</strong>: 외부 API 호출 없음</li>



<li>🚀 <strong>하드웨어 최적화</strong>: Windows/Mac 환경별 자동 최적화</li>
</ul>



<h2 class="wp-block-heading" id="기술-스택-선정">기술 스택 선정</h2>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="1024" height="572" src="https://somsap.somsap.com/wp-content/uploads/sites/6/2026/03/image-20.png" alt="image 20" class="wp-image-3440" title="🎙️ 로컬 AI로 만드는 인터뷰 분석기 개발기 - 외부 API 없이 완전 오프라인 구현 7" srcset="https://somsap.somsap.com/wp-content/uploads/sites/6/2026/03/image-20.png 1024w, https://somsap.somsap.com/wp-content/uploads/sites/6/2026/03/image-20-300x168.png 300w, https://somsap.somsap.com/wp-content/uploads/sites/6/2026/03/image-20-768x429.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading" id="핵심-기술-구성">핵심 기술 구성</h3>



<pre class="wp-block-code"><code><code>Frontend: Streamlit (빠른 프로토타이핑)
Backend: FastAPI (비동기 처리)
STT: faster-whisper / mlx-whisper (로컬 실행)
Vector DB: ChromaDB (임베딩 저장)
LLM: Ollama (로컬 추론)
Embedding: HuggingFace Transformers</code></code></pre>



<h3 class="wp-block-heading" id="왜-이-기술들을-선택했나">왜 이 기술들을 선택했나?</h3>



<p><strong>1. STT 엔진 선택</strong></p>



<ul class="wp-block-list">
<li>OpenAI Whisper API: 정확하지만 비용 발생</li>



<li><strong>faster-whisper</strong>: GPU 가속, 로컬 실행, 무료</li>



<li><strong>mlx-whisper</strong>: Mac M1/M2/M3 최적화</li>
</ul>



<p><strong>2. LLM 선택</strong></p>



<ul class="wp-block-list">
<li>ChatGPT API: 성능 좋지만 토큰당 과금</li>



<li><strong>Ollama</strong>: 로컬 실행, 다양한 모델 지원, 무료</li>
</ul>



<p><strong>3. 벡터 DB 선택</strong></p>



<ul class="wp-block-list">
<li>Pinecone: 클라우드 기반, 유료</li>



<li><strong>ChromaDB</strong>: 로컬 저장, 가벼움, 무료</li>
</ul>



<h2 class="wp-block-heading" id="개발-과정">개발 과정</h2>



<figure class="wp-block-image size-full"><img decoding="async" width="1024" height="572" src="https://somsap.somsap.com/wp-content/uploads/sites/6/2026/03/image-22.png" alt="image 22" class="wp-image-3442" title="🎙️ 로컬 AI로 만드는 인터뷰 분석기 개발기 - 외부 API 없이 완전 오프라인 구현 8" srcset="https://somsap.somsap.com/wp-content/uploads/sites/6/2026/03/image-22.png 1024w, https://somsap.somsap.com/wp-content/uploads/sites/6/2026/03/image-22-300x168.png 300w, https://somsap.somsap.com/wp-content/uploads/sites/6/2026/03/image-22-768x429.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading" id="1단계-기본-아키텍처-설계">1단계: 기본 아키텍처 설계</h3>



<div class="wp-block-merpress-mermaidjs diagram-source-mermaid"><pre class="mermaid">%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#0a4a4a', 'primaryTextColor': '#aaffee', 'primaryBorderColor': '#00e5cc', 'lineColor': '#00e5cc', 'secondaryColor': '#062e2e', 'tertiaryColor': '#041e1e', 'clusterBkg': '#062e2e', 'clusterBorder': '#00e5cc', 'titleColor': '#aaffee', 'edgeLabelBackground': '#062e2e', 'fontFamily': 'monospace'}}}%%
flowchart TD
    subgraph Client["🖥️ 클라이언트"]
        A["Streamlit UI&lt;br/&gt;(녹음/업로드/채팅 인터페이스)"]
    end

    subgraph Server["⚙️ 서버"]
        B["FastAPI&lt;br/&gt;(요청 수신 및 비동기 처리)"]
        C["STT&lt;br/&gt;(faster-whisper/CUDA&lt;br/&gt;음성 → 텍스트 변환)"]
        G["HuggingFace Embeddings&lt;br/&gt;(텍스트 → 벡터 변환)"]
        E[("ChromaDB&lt;br/&gt;(벡터 저장/검색)")]
        D["RAG Chain&lt;br/&gt;(문맥 검색 + LLM 답변 생성)"]
    end

    subgraph AI["🤖 AI 모델"]
        H["Ollama EXAONE 3.5&lt;br/&gt;(한국어 특화 LLM 추론)"]
    end

    A -- "① 오디오 업로드" --&gt; B
    B -- "② STT 변환" --&gt; C
    C -- "③ 텍스트" --&gt; G
    G -- "④ 벡터화 후 저장" --&gt; E

    A -- "⑤ 질문" --&gt; B
    B -- "⑥ RAG 실행" --&gt; D
    D -- "⑦ 벡터 검색" --&gt; E
    E -- "⑧ 관련 문맥 반환" --&gt; D
    D -- "⑨ 문맥 + 질문 전달" --&gt; H
    H -- "⑩ 답변 생성" --&gt; D
    D -- "⑪ 답변 반환" --&gt; B
    B -- "⑫ 답변 반환" --&gt; A

    style A fill:#0e6e4d,stroke:#34d399,color:#d1fae5
    style B fill:#0e4d6e,stroke:#38bdf8,color:#e0f9ff
    style C fill:#0e4d6e,stroke:#38bdf8,color:#e0f9ff
    style D fill:#0e4d6e,stroke:#38bdf8,color:#e0f9ff
    style E fill:#0e4d6e,stroke:#38bdf8,color:#e0f9ff
    style G fill:#0e4d6e,stroke:#38bdf8,color:#e0f9ff
    style H fill:#2d1b4e,stroke:#c084fc,color:#f0d6ff
    style Client fill:#062e1e,stroke:#34d399
    style Server fill:#041e2e,stroke:#38bdf8
    style AI fill:#110a1f,stroke:#c084fc</pre></div>



<p>처음에는 단순한 구조로 시작했지만,&nbsp;성능과 사용성을 고려하여 점진적으로 개선했습니다.</p>



<h3 class="wp-block-heading" id="2단계-하드웨어-최적화-로직-구현">2단계: 하드웨어 최적화 로직 구현</h3>



<p>가장 까다로웠던 부분은 다양한 하드웨어 환경에서 최적의 성능을 내는 것이었습니다.</p>



<div class="my-codeblock-wrap"><div class="my-codeblock-label">Python</div><pre><code class="language-python"><code>def get_optimal_hardware_config():
    """시스템 환경을 자동 감지하여 최적 설정 반환"""
    os_name = platform.system()
    machine_arch = platform.machine()
    cpu_cores = max(1, (os.cpu_count() or 4) - 1)

    if os_name == "Darwin" and machine_arch == "arm64":
        # Mac M1/M2/M3: Metal GPU 활용
        return {
            "engine": "mlx",
            "model_size": "medium"
        }
    elif os_name == "Windows":
        # Windows: NVIDIA CUDA 활용
        return {
            "engine": "faster-whisper",
            "model_size": "medium",
            "device": "cuda",
            "compute_type": "float16"
        }
    else:
        # 기타 환경: CPU 최적화
        return {
            "engine": "faster-whisper",
            "model_size": "medium",
            "device": "auto",
            "compute_type": "int8"
        }<span style="font-size: 0.8em"></span></code></code></pre></div>



<h3 class="wp-block-heading" id="3단계-cuda-환경-설정-문제-해결">3단계: CUDA 환경 설정 문제 해결</h3>



<p>Windows 환경에서 가장 큰 난관은 CUDA 라이브러리 인식 문제였습니다.</p>



<div class="my-codeblock-wrap"><div class="my-codeblock-label">Python</div><pre><code class="language-python"><code># 핵심 해결책: faster_whisper 임포트 전에 CUDA 경로 강제 등록
if platform.system() == "Windows":
    cuda_bin_path = r"D:\Program Files\NVIDIA\CUDA\v11.2\bin"
    if os.path.exists(cuda_bin_path):
        os.add_dll_directory(cuda_bin_path)
        os.environ&#091;"PATH"] = cuda_bin_path + os.pathsep + os.environ.get("PATH", "")

from faster_whisper import WhisperModel  # 이제 정상 작동<span style="font-size: 0.8em"></span></code></code></pre></div>



<h3 class="wp-block-heading" id="4단계-비동기-처리-및-성능-최적화">4단계: 비동기 처리 및 성능 최적화</h3>



<p>STT 변환은 시간이 오래 걸리는 작업이므로 비동기 처리가 필수였습니다.</p>



<div class="my-codeblock-wrap"><div class="my-codeblock-label">Python</div><pre><code class="language-python"><code>@app.post("/api/upload-audio")
async def upload_audio(file: UploadFile = File(...)):
    # 파일 저장을 비동기로 처리
    loop = asyncio.get_event_loop()
    await loop.run_in_executor(thread_pool, lambda: open(file_path, "wb").write(content))
    
    # STT 변환을 별도 스레드에서 실행
    transcribed_text = await loop.run_in_executor(
        thread_pool, lambda: _run_stt(file_path, file.filename, start_time)
    )
    
    # 벡터 DB 저장도 비동기 처리
    await loop.run_in_executor(thread_pool, lambda: save_to_vector_db(safe_text, file.filename))<span style="font-size: 0.8em"></span></code></code></pre></div>



<h3 class="wp-block-heading" id="5단계-rag-시스템-구현">5단계: RAG 시스템 구현</h3>



<p>단순한 STT를 넘어서 질의응답이 가능한 RAG(Retrieval-Augmented Generation)&nbsp;시스템을 구현했습니다.</p>



<div class="my-codeblock-wrap"><div class="my-codeblock-label">Python</div><pre><code class="language-python"><code># 텍스트를 청크 단위로 분할하여 벡터 DB에 저장
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,      # 청크 크기
    chunk_overlap=50     # 겹침 정도
)

# 한국어 특화 임베딩 모델 사용
embeddings = HuggingFaceEmbeddings(
    model_name="jhgan/ko-sroberta-multitask"
)

# ChromaDB에 벡터 저장
vector_db = Chroma.from_texts(
    texts=chunks,
    embedding=embeddings,
    metadatas=metadatas,
    persist_directory="chroma_db"
)<span style="font-size: 0.8em"></span></code></code></pre></div>



<h3 class="wp-block-heading" id="6단계-개인정보-보호-기능">6단계: 개인정보 보호 기능</h3>



<p>인터뷰 데이터의 민감성을 고려하여 자동 마스킹 기능을 추가했습니다.</p>



<div class="my-codeblock-wrap"><div class="my-codeblock-label">Python</div><pre><code class="language-python"><code>def mask_pii(text: str) -&gt; str:
    """개인정보 자동 마스킹"""
    # 주민등록번호 마스킹
    text = re.sub(r'(\d{6})&#091;-]\d{7}', r'\1-*******', text)
    # 전화번호 마스킹
    text = re.sub(r'(010)&#091;-]\d{4}&#091;-]\d{4}', r'\1-****-****', text)
    return text<span style="font-size: 0.8em"></span></code></code></pre></div>



<h2 class="wp-block-heading" id="개발-중-마주한-도전과-해결책">개발 중 마주한 도전과 해결책</h2>



<h3 class="wp-block-heading" id="도전-1-mac-m1-환경에서의-성능-이슈">도전 1: Mac M1 환경에서의 성능 이슈</h3>



<p><strong>문제</strong>:&nbsp;Mac M1에서 faster-whisper 성능이 현저히 떨어짐&nbsp;<strong>해결</strong>:&nbsp;mlx-whisper로 분기 처리하여 Metal GPU 활용</p>



<h3 class="wp-block-heading" id="도전-2-메모리-사용량-최적화">도전 2: 메모리 사용량 최적화</h3>



<p><strong>문제</strong>:&nbsp;큰 오디오 파일 처리 시 메모리 부족&nbsp;<strong>해결</strong>:&nbsp;스트리밍 처리 및 임시 파일 자동 삭제</p>



<h3 class="wp-block-heading" id="도전-3-인터뷰-대상자-구분">도전 3: 인터뷰 대상자 구분</h3>



<p><strong>문제</strong>:&nbsp;여러 명이 참여한 인터뷰에서 화자 구분 어려움&nbsp;<strong>해결</strong>:&nbsp;LLM을 활용한 이름 추출 및 메타데이터 관리</p>



<div class="my-codeblock-wrap"><div class="my-codeblock-label">Python</div><pre><code class="language-python"><code>def extract_interviewee_name(text: str) -&gt; str:
    """LLM으로 인터뷰 대상자 이름 추출, 실패 시 순번 반환"""
    global _interviewee_counter
    _interviewee_counter += 1

    try:
        llm = Ollama(model="exaone3.5:7.8b", temperature=0)
        answer = llm.invoke(
            f"""아래 인터뷰 텍스트에서 인터뷰 대상자(피면접자)의 이름만 추출하세요.
이름이 명확히 언급된 경우에만 이름을 반환하고, 불확실하면 반드시 'UNKNOWN'만 반환하세요.
다른 말은 절대 하지 마세요.

텍스트:\n{text&#091;:1000]}"""
        )
        name = answer.strip().replace("'", "").replace('"', "")
        if name and name != "UNKNOWN" and len(name) &lt;= 10:
            return name
    except Exception:
        pass

    return f"interviewee_{_interviewee_counter}"<span style="font-size: 0.8em"></span></code></code></pre></div>



<h2 class="wp-block-heading" id="성능-최적화-결과">사용자 경험 개선</h2>



<h3 class="wp-block-heading" id="실시간-진행률-표시">실시간 진행률 표시</h3>



<div class="my-codeblock-wrap"><div class="my-codeblock-label">Python</div><pre><code class="language-python"><code># STT 진행률을 실시간으로 표시
for segment in segments:
    progress_percent = (segment.end / total_duration) * 100
    elapsed_time = time.time() - start_time
    remaining_time = (total_duration - segment.end) * (elapsed_time / segment.end)
    
    print(f"진행률: {progress_percent:5.1f}% | "
          f"경과: {elapsed_time:4.1f}초 | "
          f"남은 시간: {remaining_time:4.1f}초")<span style="font-size: 0.8em"></span></code></code></pre></div>



<h3 class="wp-block-heading" id="직관적인-웹-인터페이스">직관적인 웹 인터페이스</h3>



<p>Streamlit을 활용하여 3개 탭으로 구성:</p>



<ol class="wp-block-list">
<li><strong>녹음 탭</strong>: 브라우저에서 직접 녹음</li>



<li><strong>파일 업로드 탭</strong>: mp3, wav, m4a, webm, ogg, flac 파일 드래그 앤 드롭</li>



<li><strong>AI 채팅 탭</strong>: 분석 결과 질의응답</li>
</ol>



<h2 class="wp-block-heading" id="배포-및-운영">배포 및 운영</h2>



<figure class="wp-block-image size-full"><img decoding="async" width="1024" height="572" src="https://somsap.somsap.com/wp-content/uploads/sites/6/2026/03/image-23.png" alt="image 23" class="wp-image-3443" title="🎙️ 로컬 AI로 만드는 인터뷰 분석기 개발기 - 외부 API 없이 완전 오프라인 구현 9" srcset="https://somsap.somsap.com/wp-content/uploads/sites/6/2026/03/image-23.png 1024w, https://somsap.somsap.com/wp-content/uploads/sites/6/2026/03/image-23-300x168.png 300w, https://somsap.somsap.com/wp-content/uploads/sites/6/2026/03/image-23-768x429.png 768w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading" id="원클릭-실행-스크립트">원클릭 실행 스크립트</h3>



<div class="my-codeblock-wrap"><div class="my-codeblock-label">Bash</div><pre><code class="language-bash"><code>@echo off
call .\venv\Scripts\activate
start "FastAPI Server" cmd /k "uvicorn main:app --reload"
start "ngrok" cmd /k "ngrok http 8000"
start "Streamlit Client" cmd /k "streamlit run client/app.py"
start "Cloudflared" cmd /k "cloudflared tunnel --url http://127.0.0.1:8501"<span style="font-size: 0.8em"></span></code></code></pre></div>



<h3 class="wp-block-heading" id="외부-접속-지원">외부 접속 지원</h3>



<ul class="wp-block-list">
<li><strong>ngrok</strong>: 서버 터널링</li>



<li><strong>cloudflared</strong>: 클라이언트 터널링</li>
</ul>



<h2 class="wp-block-heading" id="향후-개선-계획">향후 개선 계획</h2>



<h3 class="wp-block-heading" id="1-화자-분리-speaker-diarization">1. 화자 분리 (Speaker Diarization)</h3>



<p>현재는 이름 추출로만 구분하지만,&nbsp;실제 음성 패턴을 분석하여 화자를 자동 분리하는 기능 추가 예정</p>



<h3 class="wp-block-heading" id="2-다국어-지원">2. 다국어 지원</h3>



<p>현재 한국어 중심이지만,&nbsp;영어,&nbsp;일본어 등 다국어 STT 및 질의응답 지원</p>



<h3 class="wp-block-heading" id="3-실시간-스트리밍">3. 실시간 스트리밍</h3>



<p>파일 업로드가 아닌 실시간 음성 스트리밍 분석 기능</p>



<h3 class="wp-block-heading" id="4-고급-분석-기능">4. 고급 분석 기능</h3>



<ul class="wp-block-list">
<li>감정 분석</li>



<li>키워드 추출</li>



<li>요약 생성</li>



<li>인사이트 도출</li>
</ul>



<h2 class="wp-block-heading" id="마무리">마무리</h2>



<p>이 프로젝트를 통해 <strong>&#8220;외부 API 없이도 충분히 실용적인 AI 서비스를 만들 수 있다&#8221;</strong>는 것을 증명할 수 있었습니다.</p>



<p>특히 인상 깊었던 점들:</p>



<ol class="wp-block-list">
<li><strong>로컬 AI의 가능성</strong>: 생각보다 성능이 뛰어나고 실용적</li>



<li><strong>비용 효율성</strong>: 장시간 인터뷰도 추가 비용 없이 처리 가능</li>



<li><strong>보안성</strong>: 민감한 인터뷰 데이터가 외부로 전송되지 않음</li>



<li><strong>커스터마이징</strong>: 필요에 따라 모델이나 설정을 자유롭게 변경 가능</li>
</ol>



<p>앞으로도 로컬 AI 기술이 더욱 발전하여,&nbsp;개인이나 소규모 팀도 쉽게 AI 서비스를 구축할 수 있는 시대가 올 것이라 기대합니다.</p>



<hr class="wp-block-separator has-alpha-channel-opacity" />



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>이 글이 도움이 되셨다면&nbsp;❤️&nbsp;좋아요와 공유 부탁드립니다!</p>
</blockquote>
<p>게시물 <a rel="nofollow" href="https://somsap.somsap.com/2026/03/30/%f0%9f%8e%99%ef%b8%8f-%eb%a1%9c%ec%bb%ac-ai%eb%a1%9c-%eb%a7%8c%eb%93%9c%eb%8a%94-%ec%9d%b8%ed%84%b0%eb%b7%b0-%eb%b6%84%ec%84%9d%ea%b8%b0-%ea%b0%9c%eb%b0%9c%ea%b8%b0-%ec%99%b8%eb%b6%80-api-%ec%97%86/">🎙️ 로컬 AI로 만드는 인터뷰 분석기 개발기 &#8211; 외부 API 없이 완전 오프라인 구현</a>이 <a rel="nofollow" href="https://somsap.somsap.com">솜삽 블로그</a>에 처음 등장했습니다.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://somsap.somsap.com/2026/03/30/%f0%9f%8e%99%ef%b8%8f-%eb%a1%9c%ec%bb%ac-ai%eb%a1%9c-%eb%a7%8c%eb%93%9c%eb%8a%94-%ec%9d%b8%ed%84%b0%eb%b7%b0-%eb%b6%84%ec%84%9d%ea%b8%b0-%ea%b0%9c%eb%b0%9c%ea%b8%b0-%ec%99%b8%eb%b6%80-api-%ec%97%86/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">3432</post-id>	</item>
	</channel>
</rss>
