<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>team_vino.log</title>
        <link>https://velog.io/</link>
        <description>Vi.NO를 만드는 사람들</description>
        <lastBuildDate>Wed, 28 Feb 2024 11:39:34 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>team_vino.log</title>
            <url>https://velog.velcdn.com/images/team_vino/profile/ebd5a966-2567-4929-aca3-10d2970bc388/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. team_vino.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/team_vino" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[서버가 계속 죽어요… 간담을 서늘하게 했던 502 에러]]></title>
            <link>https://velog.io/@team_vino/8%EB%B2%88</link>
            <guid>https://velog.io/@team_vino/8%EB%B2%88</guid>
            <pubDate>Wed, 28 Feb 2024 11:39:34 GMT</pubDate>
            <description><![CDATA[<p>때는 <strong><a href="http://www.vi-no.site/">Vi.NO</a></strong> 런칭까지 1주일도 안남을때였습니다.. 필자는 휴대폰만 울리면 항상 두려운 맘을 가지고 알림을 확인했습니다.. 그럼 가장 무서운 메시지가 와있었습니다.</p>
<blockquote>
<p><strong>💬 프론트:</strong> 서버가 죽었어요..ㅠㅠㅠㅠ</p>
</blockquote>
<h1 id="원인">원인</h1>
<hr>
<p>바로 필자는 컴퓨터에 앉아서 로그를 뜯어보고 원인을 파악했습니다. 저희가 사용하는 서버는 aws의 Elastic beanstalk을 사용하고 였습니다. 팀원들과 원인을 찾아본 결과 다음과 같은 가설들이 나왔습니다.</p>
<blockquote>
<p>로직 상  부하를 주는 로직이 있다.</p>
</blockquote>
<ol>
<li>오토 스케일링이 자주 작동이 되어서 502가 나는거다</li>
<li>서버 용량이 부족하다</li>
<li>메모리가 부족하다.</li>
</ol>
<p>먼저 1번 가설에 따라 부하를 주는 기능들을 살펴 본 결과, GPT 요약 과 유튜브 스크립트 추출은 각각 GPT와 클로바 노트를 쓰기 때문에, 서버에 부하를 주지 않으며, 가장 유력한 가능성이 있는건, FFMPEG를 이용해 mp3를 생성하고, 네이버 스토리지에 올리는 기능이었습니다. 실제로 서버에 파일을 저장했다가 올리면서 삭제하기 때문이죠. 그렇게 되면서 2번 가설로 이어졌습니다.</p>
<p>2번 가설에 따라 서버에 부하가 되면서 그 순간, 스케일업이 진행되었고, 그 동안은 502를 응답으로 줬다고 판단했습니다. 그럼 서버가 왜 아파하는가 파악하기 위해 3번 가설과 2번 가설을 검증했습니다.</p>
<h3 id="q1-서버용량-부족">Q1) 서버용량 부족?</h3>
<hr>
<p>저희가 사용하는 elastic beanstalk의 인스턴스는 t3.micro로 가장 용량과 메모리가 적은 인스턴스입니다. 8GB의 스토리지와 1GB의 메모리를 가지고 있죠. 먼저 서버 캐시들이 쌓였기때문에 점차 무리를 주는것이 아닌가 싶어 서버의 스토리지를 8GB =&gt; 16GB로 업그레이드 했습니다.</p>
<p>하지만 업그레이드 한 뒤 10분도 안되서 서버가 터졌다는 메시지를 받음으로써, 서버 용량 부족은 아닌것 같다라는 판단이 들어서, 다음은 메모리를 조사했습니다.</p>
<h3 id="q2-메모리-부족">Q2) 메모리 부족?</h3>
<hr>
<p>메모리를 보기 위해서 SSH를 이용해 해당 인스턴스에 접속해서 로그를 뜯어봤습니다.
<img src="https://velog.velcdn.com/images/team_vino/post/3581e3ae-7293-40c1-b2a8-94c9fba1232d/image.png" alt=""></p>
<p>free 명령어를 통해 메모리를 보니, 스왑 메모리 설정을 제외하고, 가능한 메모리가 222mb밖에 되지 않았습니다. 사용을 하지 않을때가 222mb밖에 남지 않았으므로, <strong><em>FFMPEG를 사용하게 된다면 메모리 부족이 될 가능성이 크다.</em></strong> 가 확실해진 것 같았습니다.</p>
<h3 id="메모리-부족">메모리 부족!</h3>
<hr>
<p>그러다가 elastic beanstalk에서 제공하는 로그파일을 뜯어보던중 한 로그를 발견하게 됩니다.
<img src="https://velog.velcdn.com/images/team_vino/post/b1d1f6a5-4d3b-4161-b888-f7d0d0727832/image.png" alt=""></p>
<blockquote>
<p>&quot;System has too much memory&quot;</p>
</blockquote>
<p>역시나 메모리 부족 문제였습니다!
이제 원인을 알았으니 해결을 해봅시다.</p>
<h2 id="해결">해결</h2>
<hr>
<p>가장 첫번째 방법은 Swap Memory를 사용하는 것이었습니다. swap Memory를 활용해 메모리가 부족할 시, 배정된 보조메모리의 용량을 가져와 주 메모리에 할당해서 쓰는 방식이죠.</p>
<p>window의 가상 메모리 설정을 생각해주시면 됩니다. 하지만 큰 효과를 보지 못했습니다.
최후의 방법으로는 인스턴스를 업그레이드 하는 방법이었습니다.
<img src="https://velog.velcdn.com/images/team_vino/post/c948b080-eeaf-4185-a5bf-bb63c9915a9b/image.png" alt=""></p>
<p>단지 이 방법이 최후의 방법인 이유는 바로, 온디멘드 인스턴스를 한단계 업그레이드 할때 마다 , 시간당 요금이 2배가 된다는 점이었습니다. </p>
<p>그렇기에, 고민하면서 다른 방법들을 찾아보았지만 적합한 해결책이 없었기에 t3.micro에서t3.small로 업그레이드 했습니다. 따라서, 서버에 할당된 메모리는 2g로 늘어났고, 502 또한 발생하지 않게 되었습니다.</p>
<h2 id="결론">결론</h2>
<hr>
<p>서버를 최적화하는것은 굉장히 중요한 일입니다. 아무리 좋은 기능이 있어도, 서버가 터지면 아무 소용도 없기 때문이죠. 실제로 이번 경우는 인스턴스 메모리가 워낙 적었기 때문에 생긴 문제였지만, 실제 업무에서 메모리가 4gib, 8gib인데 메모리 부족이 뜬다면, 서버 로직상 문제가 있는 지 확인해보는 것이 좋을 것 같습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[처음 협업해보신다고요? 프론트엔드와 API 연동시 주의사항]]></title>
            <link>https://velog.io/@team_vino/7%EB%B2%88</link>
            <guid>https://velog.io/@team_vino/7%EB%B2%88</guid>
            <pubDate>Wed, 28 Feb 2024 11:39:11 GMT</pubDate>
            <description><![CDATA[<h1 id="개요">개요</h1>
<hr>
<p>개발자를 꿈꾸는 사람이라면 한번씩 들어보거나 고민하게되는 질문이 있습니다.</p>
<blockquote>
<p>&quot;넌 프론트 엔드로 가고 싶어 백엔드로 가고 싶어?&quot;</p>
</blockquote>
<p>물론 개발자는 이 둘만 있는게 아니라 다양하지만, 대체로 그 질문을 받게 됩니다. 둘 중 무엇을 선택하든 혼자서 다 하는 것이 아니라면 분업을 하게 될테고 그렇게 되면, 다른 한쪽에 대해 몰라서, 여러 실수가 나게 됩니다. 그래서 이번 게시물에서는 <strong><a href="http://www.vi-no.site/">Vi.NO</a></strong> 프로젝트를 진행하면서 생긴 사례를 통해 어떤 것을 주의하면 될지 말씀 드리겠습니다! 아마 당연한 것들이라 이런것을 실수한다고 생각하는 분들도 있겠고, <em>아, 이래야하구나</em> 생각하는 분들도 있을 것 같습니다.</p>
<h1 id="1-api-endpoint를-명확하게-짜자">1. API EndPoint를 명확하게 짜자</h1>
<hr>
<p>API를 설계하게 되면 백엔드 개발자의 입장에서 쉽지만 어려운.. 그 단계가 EndPoint 경로를 어떤식으로 설계할까입니다. 초반에 다 설계한다면, 어려움이 줄어들겠지만, 프로젝트 중간중간 새로운 API를 설계해야한다면, 아예 다른식으로 짜자니, 뭔가 애매하고, 기존것을 바꾸자니, 프론트 쪽에서 개발하는게 다 엉킬것같고, 많이 고민되기도 합니다.
필자는 이런 실수를 많이 했습니다.</p>
<blockquote>
<p>💬 <strong>프론트:</strong> &quot;이미 get,post등의 명칭이 있는데, 엔드포인트 뒤에 /get이나 post를 쓰시는건가요?&quot;</p>
</blockquote>
<p>맞습니다.. 엔드포인트를 설계할때, 뭔가 충돌 나는 부분도 있어서, 기존 것을 고치기 보다는, 뒤에 /get, /post등을 붙이면 되겠지! 라는 안일한 생각을 해 설계를 했지만 오히려 그것이, 프론트 쪽한테 혼란을 준것 같았습니다. 그래서 API 엔드포인트를 설계하는 좋은 방법들을 추가로 알려드리겠습니다.</p>
<h3 id="1-동사를-쓰지말자">1) 동사를 쓰지말자!</h3>
<hr>
<p>왜 동사를 쓰면 안되나면</p>
<blockquote>
<p>HTTP 메소드들이 이미 GET, PUT, PATCH, DELETE라는 동작을 동사의 형태로 나타내기 때문입니다.</p>
</blockquote>
<p>GET, POST, PUT, PATCH, DELETE는 가장 주로 쓰이는 HTTP 동사들이기 때문에 굳이 동사를 쓸필요가 없이 명사로 나타내는 것이 가장 좋습니다. 예를 들면</p>
<blockquote>
<p>/{userId}/getPosts 보다는
/{userId}/posts 로 작성하는 것이 좋습니다.</p>
</blockquote>
<p>어차피 get, post 등으로 동사인것을 표시해주기 때문이죠!!</p>
<h3 id="2-복수-명사로-쓰자">2) 복수 명사로 쓰자!</h3>
<hr>
<p>만약 /post/{postId}라는 엔드포인트가 있다고 해봅시다. get,delete,post 등으로 사용이 가능할것인데, 사용자는 저 postId만 보고는 저 id가 다른 id로도 되는지 햇갈릴 것입니다. 그래서</p>
<blockquote>
<p>/post/{postId}보다는 /posts/{postId}로 접근하는 것이 좋습니다</p>
</blockquote>
<h1 id="2-검색-api인-경우-에러보다는-빈-배열을-주자">2. 검색 api인 경우 에러보다는 빈 배열을 주자</h1>
<hr>
<p>사실 api를 설계하면서 값이 없는 경우 등은 오류로 취급하기도 합니다. id조회를 했는데, id가 없을경우 빈값보다는 에러를 보내줘, 해당 id가 없다는 것을 알리기도 하죠. 하지만 검색 같은 기능을 구현할떄는 오히려 그것 보다는 빈 배열을 주는 것이 프론트 엔드 개발자 입장에서는 더 편리할 수도 있습니다. 다음과 같은 과정이 있다 가정합시다.</p>
<blockquote>
<p>검색 API중 검색 결과가 없으면 error를 호출한다</p>
</blockquote>
<ol>
<li>프론트에서 error를 받으면 에러 코드를 확인한다.</li>
<li>값이 없다는 에러코드를 받으면 빈 값을 보여준다.</li>
</ol>
<p>물론 이 과정이 정석이기는 합니다. 하지만 에러 핸들링하는 과정이 복잡하기도 하고, 빈값을 주는 것이 오류라고 생각하기엔 애매하니까요. 그래서 보통 프론트엔드 개발자분들과 이야기하면서 조율하긴 하지만, 검색 API에서 결과가 없을 경우 빈값을 주는것이 좋습니다. 그 경우 다음 과정을 보입니다.</p>
<blockquote>
<p>1.검색 API 중 검색 결과가 없으면 빈 배열을 리턴한다.
2.프론트에서는 빈 배열을 받았지만, 오류는 아니므로 그대로 화면에 보여준다.</p>
</blockquote>
<p>조금 더 과정이 간결해지는 거죠. 물론 중요한건 소통입니다.</p>
<h1 id="3axios를-사용할때-주의점--get-메소드">3.Axios를 사용할때 주의점 -get 메소드</h1>
<hr>
<p>API를 설계하게 되면, 보통 PostMan 등으로 테스트를 해보게 됩니다. API 종류에 따라 파라미터를 주기도 하고, 바디를 API에다가 넘기기도 하죠. 그래서 흔히 발생하는 실수 일수도 있습니다. Axios를 사용할때 주의점! 바로 그건</p>
<blockquote>
<p>Axios의 get 메소드에서는 request body가 없습니다.</p>
</blockquote>
<p>Axios에서 제공되는 가이드라인을 보면</p>
<pre><code>axios.get(url[, config])            // GET
axios.post(url[, data[, config]])   // POST
axios.put(url[, data[, config]])    // PUT
axios.patch(url[, data[, config]])  // PATCH
axios.delete(url[, config])         // DELETE

axios.request(config)
axios.head(url[, config])
axios.options(url[, config])
</code></pre><p>post,put,patch는 &quot;data&quot; 를 포함하고 있지만, get은 포함하지 않습니다. 그렇기에 애초에 포함할수가 없다는 거죠.</p>
<p>사실 생각만 해보면, get 메소드를 호출할때는 간단한 정보만 포함되므로, 굳이 body안에 담을 필요는 없는 것을 알 수 있습니다.</p>
<h1 id="4-snake_casecamelcase-형식을-통일해야한다">4. snake_case,camelCase 형식을 통일해야한다.</h1>
<hr>
<p>당연한 소리입니다만 API 설계를 혼자 하는 것이 아닌 분업을 하다보면, 무심코 형식이 통일이 되지 않을때가 있습니다. 그렇기 위해서 개발을 시작하기전 규칙을 먼저 정하고 하지만, 코드를 작성하다보면 무심코, 잘못 짤 수 도 있죠. 저희 Vi.NO에서 정한 규칙은</p>
<blockquote>
<p>변수 명, 엔드포인트 등지에서는 camelCase를 쓴다.</p>
</blockquote>
<p>response 데이터, reqest body 데이터는 snake_case를 사용한다.</p>
<p>는 것입니다. 간단하게는 작성해놨지만, 생각보다 중요합니다. 매번 형식이 달라진다면 프론트 분들 입장에서는 저 API에서 주는 데이터가 어떤 변수 형식으로 되어있는지 햇갈리거든요. 그래서 꼭 지켜줘야 합니다.</p>
<h1 id="5-지속적인-테스트를-하자">5. 지속적인 테스트를 하자</h1>
<hr>
<p>이것 또한 당연한 소리로 들릴지 모르겠습니다. API를 테스트할때는 성공 인경우, 실패인 경우 등을 기본으로 테스트해야합니다. 그러기 위해서 테스트 케이스를 설계하는 것이 중요합니다. </p>
<p>예를 들면, 한 API에 존재하는 값을 엔드포인트로 보냈을때 원하는 값만 받아왔다고 배포를 해버리면, 나중에 버그가 발생했을때엔, 프론트 분들이 또 혼란에 빠질 수도 있거든요. 그렇기에 지속적인 테스트를 해서 안정적으로 배포해야 합니다.</p>
<h1 id="결론">결론</h1>
<hr>
<p>이번 포스트에서는 백엔드 개발자로써, 프론트 개발자와 협업해야할때 주의해야할점을 알려드렸습니다. 당연한 소리일 수도 있긴 하지만, 놓치기 쉬운 포인트 일수도 있습니다. 물론 이 내용을 통틀어서 제일 중요한 것은 바로 <strong>소통</strong>이지만요. 모두 도움이 되었으면 좋겠습니다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ Vi.NO 서비스의 핵심 ! GPT 이렇게 활용했어요.]]></title>
            <link>https://velog.io/@team_vino/6%EB%B2%88</link>
            <guid>https://velog.io/@team_vino/6%EB%B2%88</guid>
            <pubDate>Wed, 28 Feb 2024 11:38:35 GMT</pubDate>
            <description><![CDATA[<h1 id="개요">개요</h1>
<hr>
<p>Vi.NO는 Youtube 영상을 글로 보기 쉽게 AI를 이용해 요약해주는 서비스입니다. 본 포스트에서는 AI API 중 GPT API를 선정한 이유와 Vi.No서비스에서 어떤식으로 사용했는지 알려드리겠습니다!</p>
<h1 id="gpt-api">GPT API?</h1>
<hr>
<p><img src="https://velog.velcdn.com/images/team_vino/post/e5615e43-14c1-47d8-9f1b-d07725cf2210/image.png" alt=""></p>
<p>먼저 GPT는 Open Ai에서 2018년 선보인 대형 언어 모델(LLM)이며, GPT 모델들은 레이블링 되지 않는 대량의 텍스트 셋으로 미리 훈련되고, 인간과 같은 문자를 생성할 수 있는 변환기 아키텍처에 기반한 인공 신경망입니다. 쉽게 말해 데이터베이스에 저장된 내용을 기반으로 학습하여, 사람과 대화가 가능한 ai들을 LLM이라 하며, 가장 유명한 모델이 GPT이기 때문에 LLM을 GPT라고 부르기도 합니다. (<del>셀로판 테이프를 스카치테이프로 부르는 것처럼</del>)
Open ai에서는 순차적으로 번호가 매겨진 GPT기반 모델을 생성했으며, 현재 기준으로 가장 최신 모델은 2023년 3월 출시된 GPT-4입니다.</p>
<h2 id="gpt-api-종류">GPT API 종류</h2>
<hr>
<p>2024년 3월 기준 GPT API 종류는 다음과 같습니다.</p>
<h3 id="gpt-4-turbo-gpt-4-gpt--35-turbo">GPT-4 TURBO, GPT-4, GPT -3.5 TURBO</h3>
<hr>
<table>
<thead>
<tr>
<th>모델명</th>
<th>토큰</th>
<th>데이터 학습</th>
<th>입력(1K)</th>
<th>출력(1K)</th>
</tr>
</thead>
<tbody><tr>
<td>GPT-4-Turbo(gpt-4-1106-preview)</td>
<td>128,000</td>
<td>23년 4월</td>
<td>$0.01</td>
<td>$0.03</td>
</tr>
<tr>
<td>GPT-4-Turbo(gpt-4-1106-vision-preview)</td>
<td>128,000</td>
<td>23년 4월</td>
<td>$0.01</td>
<td>$0.03</td>
</tr>
<tr>
<td>GPT-4(gpt-4)</td>
<td>8,192</td>
<td>21년 9월</td>
<td>$0.03</td>
<td>$0.06</td>
</tr>
<tr>
<td>GPT-4(gpt-4-32k)</td>
<td>32,768</td>
<td>21년 9월</td>
<td>$0.06</td>
<td>$0.12</td>
</tr>
<tr>
<td>GPT-3.5 Turbo(gpt-3.5-turbo-1106)</td>
<td>16,385</td>
<td>21년 9월</td>
<td>$0.001</td>
<td>$0.0020</td>
</tr>
<tr>
<td>GPT-3.5 Turbo(gpt-3.5-turbo-instruct)</td>
<td>4,096</td>
<td>21년 9월</td>
<td>$0.0015</td>
<td>$0.0020</td>
</tr>
</tbody></table>
<p>가장 최근 모델은 GPT-4 Turbo 모델이며, 명령 수행 능력, JSON 모드, 일관된 답변 제공 능력, 병렬 함수 호출 등이 개선된 최신 GPT-4 모델입니다.
또 gpt-4-1106-vision-preview 모델은 이미지를 이해 하는 기능까지 있으며, 이때 비용은 이미지의 크기와 해상도에 따라 달라집니다. 때문에 OpenAi 홈페이지에서 예상 비용을 계산 할 수 있는 Vision Pricing calculatior가 제공됩니다.</p>
<h1 id="gpt-vino에서는-어떻게-사용했나요">GPT, VI.NO에서는 어떻게 사용했나요?</h1>
<hr>
<p>VI.NO에서는 gpt-3.5-turbo-16k 모델을 사용했습니다! 물론 성능은 GPT-4 Turbo 모델들이 더 좋고 토큰 수도 많긴 하지만, 거의 10배나 되는 가격차이로 인해, 눈물을 머금고 gpt-3.5-turbo-16k 모델을 선정했습니다.
<img src="https://velog.velcdn.com/images/team_vino/post/20ba8d52-21fc-488e-a6e9-3c6c146d14a4/image.png" alt=""></p>
<p>VI.NO 서비스에서 GPT를 사용하는 부분은 다음과 같습니다.</p>
<blockquote>
<ul>
<li>유튜브 영상 내용를 기반으로 한 제목 생성</li>
</ul>
</blockquote>
<ul>
<li>스크립트 원문에 대한 소주제들,</li>
<li>그 소주제에 맞게 스크립트를 나누기</li>
<li>해당 유튜브 영상의 한줄 요약 5개</li>
<li>해당 유튜브 영상의 태그 생성</li>
</ul>
<p>이 5개의 요소들을 GPT API를 통해 생성하고 사용자에게 전달합니다.</p>
<h2 id="문제점">문제점</h2>
<hr>
<p>API 모델링을 하면서, 하나의 난관에 봉착했습니다. 프롬프트 기반의 AI API라 발생한 문제였는데요. 바로</p>
<blockquote>
<p><strong>프롬프트 기반의 API는 매번 다른 형태의 값을 줄 수도 있다!</strong></p>
</blockquote>
<p>는 것이었습니다. 그렇기에 초반 모델링 개발에는 프롬프트를 수정해가며 원하는 형태의 값을 줄 수 있는, 프롬프트를 찾아내는 것이 핵심 과제였습니다. GPT한테서 매번 이상한 값을 받게 되면, 사용자나 그 데이터를 처리하는 입장에서도 골치가 아프기 때문이죠.</p>
<h2 id="해결책">해결책</h2>
<hr>
<p>그러기 위해서는 어떻게 하면 GPT에게서 원하는 대답을 끌어 낼 수 있는지 방법을 찾아야했습니다. 이때 구글링을 하던 도중 스탠퍼드대 겸임교수이신 엔드류 응 교수님이 말씀하신 &quot;AI에게 질문을 잘하는 방법&quot; 이라는 글을 보게 되었습니다.</p>
<p>이 글을 보고, 프롬프트를 기존 명령문이 아닌 구체적인 JSON 예시와 함께, 달라고 지시했으며, 표현되는 개수 또한 명확하게 표현함으로써 좀 더 나은 결과를 얻을 수 있었습니다.</p>
<h2 id="참고-프롬프트를-작성하는-좋은-방법">[참고] 프롬프트를 작성하는 좋은 방법</h2>
<hr>
<p>내용 가이드라인은 다음과 같습니다</p>
<h3 id="1-명확하고-구체적인-지시를-작성하라">1. 명확하고 구체적인 지시를 작성하라</h3>
<hr>
<p>글에 따르면 작업 관련 내용을 모르는 신입사원에게 지시하듯 명확하고 구체적으로 필요한 결과를 이야기 하라고 나와 있습니다. 예를 들면</p>
<blockquote>
<p>&quot;VI.NO에 대해 무언가 알려주세요&quot;</p>
</blockquote>
<p>보다는</p>
<blockquote>
<p>&quot;VI.NO 서비스에 대해 그 역사와 기능에 대해 알려주세요&quot;</p>
</blockquote>
<p>가 더 좋은 결과를 받을 수 있다고 합니다.</p>
<h3 id="2-구분-기호를-사용하여-입력-내용을-명확하게-표시-해야한다">2. 구분 기호를 사용하여 입력 내용을 명확하게 표시 해야한다</h3>
<hr>
<p>띄어쓰기, 쉼표, 마침표 등으로 입력내용을 명확하게 표시할 수 있어야 합니다.</p>
<h3 id="3-구조화된-출력-방식을-요청-해야한다">3. 구조화된 출력 방식을 요청 해야한다</h3>
<hr>
<p>값이 어떤 형식(표, JSON등) 으로 표현되길 원하는 지  구체적으로 알려줄 수 있어야 합니다.</p>
<h3 id="4-원하는-작업의-성공적인-실행-예시를-제공해라">4. 원하는 작업의 성공적인 실행 예시를 제공해라</h3>
<hr>
<p>원하는 답변에 대한 예시가 있다면 그 내용을 알려주고 일관된 스타일의 응답을 요청할 수 있습니다.</p>
<h3 id="5-ai가-생각할-시간을-줘야한다">5. AI가 생각할 시간을 줘야한다.</h3>
<hr>
<p>AI 모델에게 짧은 시간이나 적은 단어로 복잡한 작업을 주게 된다면, 잘못된 추측을 할 가능성이 높다고 합니다. 그렇기에 세부적으로 1단계.. 2단계.. 등으로 단계를 나눠서 요청해야합니다.</p>
<h2 id="gpt-fine-tunning">GPT Fine tunning</h2>
<hr>
<p>프롬프트 수정을 통해 나은 결과를 얻었다 해도, 10번중에 8번정도 원하는 결과를 얻는 상황이라 정확도를 위해 다른 방법을 찾아보던 중 GPT 모델 중 사용자의 서비스에 최적화된 맞춤형 모델을 만들 수 있는 Fine tunning을 발견했습니다. </p>
<p>Fine-tunning은 기존 프롬프트 기반의 GPT API와 다르게 우리가 새로운 데이터 셋을 넣음으로써, 데이터 기반으로 학습하여 데이터를 주기 때문에, 우리가 원하는 결과를 손쉽게 얻을 수 있을거라 판단했습니다. 종류와 가격은 다음과 같습니다.
<img src="https://velog.velcdn.com/images/team_vino/post/84c2b16a-bc1c-44b6-bb9e-e073baa95a63/image.png" alt=""></p>
<table>
<thead>
<tr>
<th>모델명</th>
<th>학습(1k)</th>
<th>입력(1K)</th>
<th>출력(1K)</th>
</tr>
</thead>
<tbody><tr>
<td>GPT-3.5-turbo</td>
<td>$0.008</td>
<td>$0.003</td>
<td>$0.006</td>
</tr>
<tr>
<td>Davinci-002</td>
<td>$0.0060</td>
<td>$0.003</td>
<td>$0.0120</td>
</tr>
<tr>
<td>Babbage-002</td>
<td>$0.0004</td>
<td>$0.0016</td>
<td>$0.0016</td>
</tr>
</tbody></table>
<p>사용법은 Open Ai 홈페이지 또는 터미널을 이용해 모델에 데이터셋을 학습시키고, 그 학습시킨 모델의 이름을 가져와 사용하는 방식입니다. 학습시킬 데이터셋은</p>
<pre><code>   {&quot;prompt&quot;:&quot;&quot;,&quot;completion&quot;:&quot;&quot;}
</code></pre><p>이런 jsonl 구문를 최소 10개부터 학습시키면 됩니다. 그렇기에</p>
<p><img src="https://velog.velcdn.com/images/team_vino/post/88453ed7-5f8b-4f52-879b-58997dda0c56/image.png" alt=""></p>
<p>이런 식으로 Jsonl 형식의 파일을 주어 학습시켰습니다.</p>
<h3 id="결과">결과</h3>
<hr>
<p>결과적으로는 학습시킨 데이터셋이 불안정하기때문에, 아직까진 Fine Tunning 보다는 일반 gpt api를 활용하여 원하는 값을 받아오는게 더 정확도가 높았습니다. </p>
<p>그렇지만, 학습시키는 데이터가 많아질 수록 정확도가 높아지기 때문에, 계속해서 데이터셋을 추가하고 훈련 중에 있습니다.</p>
<h1 id="결론">결론</h1>
<hr>
<p>이번 게시물에서는 저희 <strong><a href="http://www.vi-no.site/">Vi.NO</a></strong> 서비스의 핵심 기능 gpt api에 대해 소개했습니다. </p>
<p>어렸을 땐 어렵고 영화, 소설 속 이야기 같았던 AI가 지금은 손쉽게 우리 곁으로 다가오고 활용할 수 있다는 점이 너무 좋은 것 같습니다. 앞으로도 계속 발전할 Vi.NO! 기대해주시면 감사드리겠습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[사이드 프로젝트의 핵심 구세주였던 NAVER CLOVA SPEECH 사용법. A to Z ]]></title>
            <link>https://velog.io/@team_vino/5%EB%B2%88-z4ahym10</link>
            <guid>https://velog.io/@team_vino/5%EB%B2%88-z4ahym10</guid>
            <pubDate>Wed, 28 Feb 2024 11:38:18 GMT</pubDate>
            <description><![CDATA[<p>ViNo를 개발하면서 필요했던 Clova Speech를 어떻게 사용하는지 자세하게 알아보려고 한다.</p>
<hr>
<h1 id="1-로그인-및-이용신청">1. 로그인 및 이용신청</h1>
<blockquote>
<p>Clova Speech는 Naver Cloud에서 지원하는 AI Service로 네이버 계정을 통해 로그인을 진행할 수 있다.</p>
</blockquote>
<ul>
<li>로그인을 진행하고 Clova Speech 이용신청을 한다.</li>
</ul>
<blockquote>
<p><strong><a href="https://www.ncloud.com/product/aiService/clovaSpeech">Clova Speech 이용 신청 링크</a>
<img src="https://velog.velcdn.com/images/team_vino/post/76ae5b39-335a-4531-82ea-ef87b0586dae/image.png" alt=""></strong></p>
</blockquote>
<p>해당 링크를 클릭하면 위 사진과 같은 페이지가 나오고 우측 상단 로그인을 진행한 후 이용 신청하기를 눌러 <strong>Clova Speech</strong>를 콘솔에 등록할 수 있다.
<img src="https://velog.velcdn.com/images/team_vino/post/a61bcb73-144d-4c7d-893d-f7f95a1a8125/image.png" alt=""></p>
<ul>
<li><p>정상적으로 <strong>Clova Speech</strong>를 이용 신청 하였다면 콘솔 탭에 들어갔을 때 이와 같이 <strong>Clova Speech</strong>가 <strong>Recently Viewed</strong>에 등록되어 있어야 한다.
<img src="https://velog.velcdn.com/images/team_vino/post/1f25078a-b8de-4b04-881e-a1697a61d3ef/image.png" alt=""></p>
</li>
<li><p>Clova Speech는 장문 인식과 단문 인식 기능을 지원하는데 이 글에서는 장문 인식 도메인 생성 과정을 다루려고 한다.</p>
</li>
<li><p>위 사진과 같이 장문 인식 도메인 생성을 클릭하면 모든 항목이 필수 입력 항목으로 지정되어 있다</p>
</li>
</ul>
<p>Storage 설정에 인식 대상 저장 경로와 결과 파일 저장 경로의 항목이 있는데</p>
<p><strong>인식 대상 저장 경로</strong>는 Clova Speech에게 인식 시킬 음성파일을 저장하는 공간이다.
<strong>결과 파일 저장 경로</strong>는 Clova Speech가 인식한 음성파일의 스크립트를 저장할 공간이다.</p>
<p>이 공간은 컴퓨터의 로컬 저장소가 아니라 nCloud에서 지원하는 <strong>Object Storage</strong>에 버킷을 만들어야 한다.</p>
<hr>
<h1 id="2-object-storage-이용신청">2. Object Storage 이용신청</h1>
<p>Clova Speech를 사용하기 위해서는 Object Storage를 이용하여야 한다.</p>
<blockquote>
<p><strong><a href="https://www.ncloud.com/product/storage/objectStorage">ncloud Object Storage 이용 신청 링크</a></strong>
<img src="https://velog.velcdn.com/images/team_vino/post/6907ad11-64fd-47ef-b689-002cf40a443e/image.png" alt=""></p>
</blockquote>
<p>Clova Speech와 동일하게 이용 신청을 진행하고 콘솔탭에 가면 아래 사진과 같이 Object Storage 탭이 생성이 되었을 것이다.</p>
<p><img src="https://velog.velcdn.com/images/team_vino/post/28c07733-de8e-4847-ab5e-a13858c1e8c2/image.png" alt=""></p>
<p>필자는 이미 사용했기 때문에 두가지의 버킷이 존재하는것을 알 수 있다.</p>
<p>인식 대상 저장 경로와 결과 파일 저장 경로를 동일하게 설정할 수 있지만 효율적인 관리를 위해 두가지로 나누었고 버킷 생성하는 부분을 다뤄보겠다.</p>
<p><img src="https://velog.velcdn.com/images/team_vino/post/432ca70e-bba1-4dd3-80f2-a73011f49fa3/image.png" alt=""></p>
<h3 id="1-버킷-생성을-누르면-버킷을-만드는-창으로-이동하게-되는데-본인이-설정하고-싶은-이름을-적고-다음을-누른다-필자는-test-mp3로-이름을-정하겠다">1) 버킷 생성을 누르면 버킷을 만드는 창으로 이동하게 되는데 본인이 설정하고 싶은 이름을 적고 다음을 누른다. 필자는 &#39;Test-mp3&#39;로 이름을 정하겠다.</h3>
<p><img src="https://velog.velcdn.com/images/team_vino/post/7a7b3b57-e7e7-4c13-b1d0-2bccdd61e376/image.png" alt=""></p>
<h3 id="2-설정관리의-잠금-설정은-사진에-보이는-설명과-같이-별도의-고객센터-문의가-필요로-하다-따라서-암호화-관리---암호화-설정---ncp-관리형-키를-선택하고-다음으로-넘어가자">2) 설정관리의 잠금 설정은 사진에 보이는 설명과 같이 별도의 고객센터 문의가 필요로 하다. 따라서 암호화 관리 -&gt; 암호화 설정 -&gt; NCP 관리형 키를 선택하고 다음으로 넘어가자.</h3>
<p><img src="https://velog.velcdn.com/images/team_vino/post/dab8f78a-5c12-4f35-a402-82d680f65945/image.png" alt=""></p>
<h3 id="3-권한-관리-탭에서는-기본적으로-공개-안함으로-설정이-되어있어-다음으로-바로-넘어가도-된다">3) 권한 관리 탭에서는 기본적으로 공개 안함으로 설정이 되어있어 다음으로 바로 넘어가도 된다.</h3>
<p>만약 따로 공개하고 싶은 파일이 있으면 버킷 생성 후 버킷에 들어있는 파일의 개별 권한 설정을 해주면 된다.
<img src="https://velog.velcdn.com/images/team_vino/post/5c8920ea-29a1-4f9d-9390-697f4eaf3f1a/image.png" alt=""></p>
<h3 id="4-최종확인을-마친-후-버킷-생성을-진행한다">4) 최종확인을 마친 후 버킷 생성을 진행한다.</h3>
<hr>
<h1 id="3-clova-speech-사용하기">3. Clova Speech 사용하기</h1>
<p><img src="https://velog.velcdn.com/images/team_vino/post/32799229-97e1-4d56-a691-606e20181bcd/image.png" alt=""></p>
<p>ncloud 콘솔 탭에 Clova Speech를 클릭하고 Domain 생성을 누르게 되면 위 사진과 같이 나오게 되는데 몇가지 설명을 하려고 한다.</p>
<h3 id="1-서비스-플랜">1) 서비스 플랜</h3>
<p><img src="https://velog.velcdn.com/images/team_vino/post/468e7ccf-c638-499e-a0ca-85add9a9cd37/image.png" alt=""><img src="https://velog.velcdn.com/images/team_vino/post/6f8bfb48-1d71-41c6-af87-b8fb6c0a21d9/image.png" alt=""></p>
<ul>
<li>Free플랜 이용시 20분 이하의 음성파일 경우 무료로 사용이 가능하다.</li>
<li>Basic플랜 이용시 음성인식, 화자인식, 이벤트 탐지의 각각의 기능을 이용할 때마다 요금표와 같이 과금이 발생한다.</li>
</ul>
<p>필요성에 맞게 Clova Speech 도메인 생성을 할 때 고르면 될 것이다.</p>
<h3 id="2-음성인식-화자인식-이벤트-탐지">2) 음성인식, 화자인식, 이벤트 탐지</h3>
<p><img src="https://velog.velcdn.com/images/team_vino/post/4f8f066d-c61c-49a2-a034-31f01cf7ffce/image.png" alt=""></p>
<ul>
<li>사진 설명과 같이 음성인식은 Clova Speech를 이용했을 때 필수로 사용되는 기능이고, 화자인식은 선택이 가능하다.</li>
<li>화자인식의 예를 들어보면 음성파일에는 여러 사람의 음성이 존재하는데 그 음성을 기준으로 화자를 구분한 음성인식 스크립트를 제공해준다. 단방향성 인터뷰의 음성파일 혹은 강의 녹음 음성파일은 화자인식이 필요 없지만 면접 혹은 사회자와 인터뷰어가 같이 소통하는 음성파일일 경우에는 화자인식이 필요하다 할 수 있다.</li>
<li>이벤트 탐지는 음성에서 추출된 BGM이나 음악등을 텍스트로 표현해준다 예를들어 음성파일에 박수 소리가 들리면 (박수) 와 같이 스크립트 파일에 포함시켜준다.</li>
</ul>
<h3 id="3-빌더-실행">3) 빌더 실행</h3>
<p><img src="https://velog.velcdn.com/images/team_vino/post/02013117-cd44-497e-ae04-d056455d2a0f/image.png" alt=""></p>
<p>원하는 기능들을 선택하고 Clova Speech 도메인을 생성 하였으면 위 사진에서 빌더 실행을 눌러보자.
<img src="https://velog.velcdn.com/images/team_vino/post/98d648eb-f697-4b63-9d67-87289dbf81fa/image.png" alt=""></p>
<p>빌더 실행을 눌렀을 때의 페이지다 영상 인식 작업 요청을 하게 되면
<img src="https://velog.velcdn.com/images/team_vino/post/5ebb89aa-6a40-41ab-bc58-346e1ad0cb6f/image.png" alt=""> <img src="https://velog.velcdn.com/images/team_vino/post/14bb5a47-a51c-4b11-8b19-c2632fdeb305/image.png" alt=""></p>
<p>각각 원하는 방식(Object Storage에서 업로드, Local Storage에서 업로드)가 가능하다. Clova Speech는 아래 사진과 같은 파일만 업로드 및 빌드가 가능하기 때문에 참고 바란다.</p>
<p><img src="https://velog.velcdn.com/images/team_vino/post/b9451c17-9dcb-4e6e-9365-9042d20ef678/image.png" alt=""></p>
<p>음석인식을 진행하고 싶은 영상이나 음성파일이 준비가 되었다면 업로드 후 요청 시작을 눌러보자.
<img src="https://velog.velcdn.com/images/team_vino/post/e8e0dfb3-6836-40ac-993d-dc3745407fbe/image.png" alt=""></p>
<p>요청 시작을 누른 후 10~20초 정도 기다리면 인식 결과 편집 버튼이 활성화 되게 된다. 이 글에서 인식한 음성은 아래 유튜브 영상이다.</p>
<blockquote>
<p><strong><a href="https://www.youtube.com/watch?v=8eWMGsP_YzY">음성인식 요청 영상</a></strong></p>
</blockquote>
<p>영상 길이는 9분정도이며 영상 길이가 크게 늘지 않는 이상 30초 이내면 변환이 완료된다.
이제 인식 결과 편집을 눌러보자.
<img src="https://velog.velcdn.com/images/team_vino/post/6f8606e0-6615-4a2e-bb85-0ab8de900873/image.png" alt=""></p>
<p>영상일 경우에는 왼쪽에 영상이 표시가 되고 썸네일도 정상적으로 출력이 될 것이다. 하지만 MP3 음성 파일을 음성인식 시켰기 때문에 표시되지 않는 것이다.</p>
<p>이 음성인식 결과를 내보내기 할 수 있는데 우측 상단에 내보내기를 클릭하면 아래 사진 같이 나오게 된다.
<img src="https://velog.velcdn.com/images/team_vino/post/a3a75289-966c-4915-b43c-04697ba27f0c/image.png" alt=""></p>
<ul>
<li>내보내기 할 때에 여러 파일 형식을 선택할 수 있다. (Json, smi, srt, txt, csv, xsl)</li>
<li>내보낼 장소도 선택이 가능한데 Object Storage와 Local Storage에 다운로드도 가능하다.</li>
</ul>
<blockquote>
<p>간단하게 웹사이트에서 Clova Speech를 이용 신청하고 실행해보는 것 까지 진행 해봤다.
아래부터는 개발자가 이 Clova speech를 API 형태로 어떻게 호출하는지 Node.js를 사용하여 알아보도록 하겠다.</p>
</blockquote>
<hr>
<h1 id="4-nodejs에서-clova-speech-api-사용하기">4. Node.js에서 Clova Speech API 사용하기</h1>
<p>Clova Speech를 Node.js에서 사용하려면 Clova Speech에 사용할 음성 및 영상파일을 Object Storage에 업로드 후 호출할 수 있다. 따라서 Object Storage에서 파일을 업로드하고 업로드 된 파일을 Clova Speech를 호출해서 결과 값을 받아오는 것 까지 해볼 것이다.</p>
<h3 id="시작하기에-앞서-nodejs에서">시작하기에 앞서 node.js에서</h3>
<p>node.js에서 object storage API를 사용하려면 먼저 S3 sdk를 설치해줘야한다. 아래 코드를 npm을 통해 설치하자.</p>
<pre><code>npm install --save aws-sdk@2.348.0
</code></pre><p>또 API를 사용하기 위해서는 accessKeyId와 secretAccessKey가 필요한데 아래 사진을 보면 ncloud platform 사이트에 접속해서 마이페이지 -&gt; 계정관리 -&gt; 인증키 관리에서 볼 수 있다.
<img src="https://velog.velcdn.com/images/team_vino/post/1314759b-832f-4c96-81cb-58b1a6313f72/image.png" alt=""></p>
<h3 id="1-object-storage-파일-업로드">1) Object Storage 파일 업로드</h3>
<pre><code>import AWS from &#39;aws-sdk&#39;;
import fs from &#39;fs&#39;;
import path from &#39;path&#39;;

// Naver Cloud Object Storage 설정
const endpoint = new AWS.Endpoint(&#39;&lt;https://kr.object.ncloudstorage.com&gt;&#39;);
const region = &#39;kr-standard&#39;;
const bucketName = process.env.OBJECT_STORAGE_BUCKET_NAME;
const s3 = new AWS.S3({
    endpoint,
    region,
    credentials: {
        accessKeyId: process.env.OBJECT_STORAGE_ACCESS_KEY,
        secretAccessKey: process.env.OBJECT_STORAGE_SECRET_KEY
    }
});

// 로컬 파일을 S3에 업로드
export const uploadFileToStorage = async (filePath) =&gt; {
    const fileContent = fs.readFileSync(filePath);
    const fileName = path.basename(filePath);

    const params = {
        Bucket: process.env.OBJECT_STORAGE_BUCKET_NAME,
        Key: fileName,
        ACL: &#39;public-read&#39;,
        Body: fileContent
    };

    try {
        const { Location } = await s3.upload(params).promise();

        // 업로드 성공 후 로컬 파일 삭제
        fs.unlink(filePath, (err) =&gt; {
            if (err) console.error(&#39;Error deleting local file:&#39;, err);
            else console.log(&#39;Local file deleted successfully&#39;);
        });

        return Location; // S3에 업로드된 파일의 URL 반환
    } catch (error) {
        console.error(&#39;Error in uploading file to S3:&#39;, error);
        throw error;
    }
};
</code></pre><p>맨 위 코드를 살펴보면 기본적으로 Naver Cloud Object Storage를 먼저 기본설정해줘야한다.
Endpoint와 region 그리고 업로드 할 bucket Name을 꼭 지정해줘야한다.</p>
<blockquote>
<p>아래 링크는 Object Storage API 이용가이드 이다
<strong><a href="https://api.ncloud-docs.com/docs/common-objectstorageapi-objectstorageapi">Object Storage API 이용 가이드</a></strong></p>
</blockquote>
<hr>
<h3 id="2-clova-speech-api-호출">2) Clova Speech API 호출</h3>
<p>파일을 업로드 하고 나면 이제 clova speech를 호출 할 수 있게 되는데 object storage와 마찬가지로 API KEY가 필요하다
<img src="https://velog.velcdn.com/images/team_vino/post/5e35a3c8-de11-4f9a-8b73-4054b4938c3e/image.png" alt=""></p>
<p>ncloude 콘솔에 접속해서 Clova Speech를 빌드 실행하면 왼쪽에 설정탭이 있다.
필요한 정보는 Secret Key와 invoke URL이므로 잘 적어두도록 하자.</p>
<pre><code>import axios from &#39;axios&#39;;
import dotenv from &#39;dotenv&#39;;

dotenv.config();

const CLOVA_SPEECH_API_KEY = process.env.CLOVA_SPEECH_API_KEY;
const CLOVA_SPEECH_INVOKE_URL = process.env.CLOVA_SPEECH_INVOKE_URL;
//const CLOVA_SPEECH_CALLBACK_URL = 결과를 받을 Domain 주소;

export const recognizeFromObjectStorage = async (objectStorageDataKey, language = &#39;ko-KR&#39;) =&gt; {
    const requestBody = {
        dataKey: objectStorageDataKey, // 인식을 원하는 파일의 ObjectStorage 경로에 접근하기 위한 Key
        language,
        completion: &#39;async&#39;,
        resultToObs: true, // 결과를 Object Storage에 저장할지 여부
        noiseFiltering: true, // 노이즈 필터링 적용 여부
        wordAlignment: true, // 단어 정렬 정보 포함 여부
        fullText: true, // 전체 인식 결과 텍스트를 출력할지 여부
    };

    try {
        const response = await axios.post(`${CLOVA_SPEECH_INVOKE_URL}/recognizer/object-storage`, requestBody, {
            headers: {
                &#39;X-CLOVASPEECH-API-KEY&#39;: CLOVA_SPEECH_API_KEY,
                &#39;Content-Type&#39;: &#39;application/json&#39;
            }
        });
        console.log(&quot;스크립트화된 데이터&quot;,response.data);
        return response.data;
    } catch (error) {
        console.error(&#39;Error in recognizing from object storage:&#39;, error);
        throw error;
    }
};
</code></pre><p>해당코드를 사용하여 Clova Speech를 호출할 수 있는데 옵션에서 CallbackURL도 지정할 수 있다. CallbackURL을 지정하게 되면 API호출이 완료되고 결과값을 원하는 URL로 요청받을 수 있다.</p>
<blockquote>
<p>아래 링크는 Clova Speech 이용 가이드이다.
<strong><a href="https://api.ncloud-docs.com/docs/ai-application-service-clovaspeech-longsentence">Clova Speech API 이용 가이드</a></strong></p>
</blockquote>
<hr>
<h3 id="3-clova-speech-결과-값-가져오기">3) Clova Speech 결과 값 가져오기</h3>
<pre><code>//Clova Speech 결과 파일 읽기(Json)
export const readFileFromObjectStorage = async (bucketName, objectKey) =&gt; {

    const params = {
        Bucket: bucketName,
        Key: objectKey
    };

    try {
        const data = await s3.getObject(params).promise();
        return JSON.parse(data.Body.toString(&#39;utf-8&#39;));
    } catch (error) {
        console.error(&#39;Error in reading file from storage:&#39;, error);
        throw error;
    }
};
</code></pre><p>위에 코드를 사용했다면 Clova Speech를 호출한 결과가 JSON 형태로 Object Storage에 저장이 되었을 것이다. 따라서 Object Storage에 저장된 음성인식 결과 값을 가져와서 아래 코드와 같이 사용하면 된다.</p>
<pre><code>const jsonData = await readFileFromObjectStorage(process.env.OBJECT_STORAGE_BUCKET_SUMMARY_NAME, scriptFileName);
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[돌고돌아 클로바를 선택한 이유 + api별 비교]]></title>
            <link>https://velog.io/@team_vino/4%EB%B2%88</link>
            <guid>https://velog.io/@team_vino/4%EB%B2%88</guid>
            <pubDate>Wed, 28 Feb 2024 11:37:26 GMT</pubDate>
            <description><![CDATA[<p>Vi.NO 프로젝트는 유튜브 영상의 스크립트를 기반으로 영상 요약과 스크립트를 제공하는 서비스이기에 유튜브 영상의 스크립트를 추출하는 과정이 필요했다.</p>
<p>npm 모듈을 통해 스크립트를 추출하려고 했으나 정확도가 매우 떨어지는 것을 인지하고 정확도를 높이기 위해 고군분투하던 중 naver cloud에서 제공하는 clova speech를 알게 되어 성공적인 스크립트 추출 결과를 얻을 수 있었다.</p>
<p>그러므로 이번 포스트에서는 우리가 스크립트를 추출하기 위해 노력한 과정을 아래의 순서에 따라 설명해보도록 하겠다.</p>
<blockquote>
<p><strong>1. npm youtube 스크립트 모듈</strong>
=&gt; npm 모듈 사용 시에 발생한 정확도 문제
<strong>2. 음성 인식 api 비교</strong>
=&gt; 여러 음성 인식 api를 각 판단 기준에 따라 수치로 분류된 표를 참고하여 우리 서비스에 적합한 api를 찾는 과정
<strong>3. naver clova speech</strong>
=&gt; clova speech의 기능과 장점에 대해 설명
<strong>4. 스크립트 비교</strong>
=&gt; npm 모듈, clova speech로 추출한 스크립트를 비교하여 clova speech의 정확도 판단</p>
</blockquote>
<h2 id="😂-npm-youtube-스크립트-추출-모듈">😂 npm youtube 스크립트 추출 모듈</h2>
<p><img src="https://velog.velcdn.com/images/team_vino/post/e76f2487-4d50-4baf-8770-77bd43b785cd/image.png" alt=""></p>
<blockquote>
<p>** <a href="https://www.npmjs.com/package/youtube-caption-extractor">npm youtube 스크립트 추출 모듈</a>**</p>
</blockquote>
<p>유튜브 영상의 스크립트와 문장 마다의 타임 스탬프가 필요했고 node.js 를 활용해서 백엔드 개발을 진행하고 있었기에 먼저 Npm 에서 제공하는 유튜브 스크립트 추출 모듈을 사용하고자 했다.</p>
<p>유튜브 영상 더보기에서 볼 수 있는 스크립트를 가져오는 모듈로 처음엔, 매우 간단하게 진행되는 듯 했다.</p>
<pre><code>import { getSubtitles, getVideoDetails } from &#39;youtube-caption-extractor&#39;;

// Fetching Subtitles
const fetchSubtitles = async (videoID, lang = &#39;en&#39;) =&gt; {
  try {
    const subtitles = await getSubtitles({ videoID, lang });
    console.log(subtitles);
  } catch (error) {
    console.error(&#39;Error fetching subtitles:&#39;, error);
  }
};

// Fetching Video Details
const fetchVideoDetails = async (videoID, lang = &#39;en&#39;) =&gt; {
  try {
    const videoDetails = await getVideoDetails({ videoID, lang });
    console.log(videoDetails);
  } catch (error) {
    console.error(&#39;Error fetching video details:&#39;, error);
  }
};

const videoID = &#39;video_id_here&#39;;
const lang = &#39;en&#39;; // Optional, default is &#39;en&#39; (English)

fetchSubtitles(videoID, lang);
fetchVideoDetails(videoID, lang);
</code></pre><h3 id="하지만-만족스럽지-않았다">하지만, 만족스럽지 않았다.</h3>
<p>서비스 목표에 따라 스크립트의 정확도가 중요했기 때문에 정확도에 신경을 쓰지 않을 수가 없었다. 영어로 이루어진 영상은 나름 높은 정확도를 보였으나 한국어 영상의 경우에는 우리가 원하는 정도의 정확도가 나오지 않았다.</p>
<p><img src="https://velog.velcdn.com/images/team_vino/post/f0a3dc18-e94e-40e6-bb98-05540e780414/image.png" alt="">
ㄴ 위 이미지는 실제 스크립트 추출 결과다.. 참담..</p>
<p>글 마지막에 스크립트 비교를 통해 정확도 차이를 보여주도록 하겠다.</p>
<h2 id="💡-음성-인식-api-비교">💡 음성 인식 api 비교</h2>
<p>따라서 더 좋은 스크립트 추출을 위해.. 음성 인식 api를 비교해보기로 했다.
유튜브 영상의 mp3를 추출한 후 음성인식 api를 통해 스크립트를 추출하는 방식으로 정했다.</p>
<p>우리에게 필요한 요소는 다음과 같았다.</p>
<blockquote>
<ol>
<li>정확한 스크립트 추출</li>
<li>문장에 해당하는 타임 스탬프 추출</li>
</ol>
</blockquote>
<p>비교하고자 하는 google speech-to-text와 naver cloud 의 Clova speech 모두 타임 스탬프 기능은 지원하고 있었기에 <strong>스크립트의 정확도</strong>가 가장 중요한 선택 기준이 되었다.</p>
<p><img src="https://velog.velcdn.com/images/team_vino/post/8690d067-386d-4bad-b72d-9ae21e90d62e/image.png" alt=""></p>
<blockquote>
<p><strong><a href="https://github.com/rtzr/Awesome-Korean-Speech-Recognition?ref=blog.rtzr.ai">[참고] 음성인식 api 오인식률</a></strong></p>
</blockquote>
<h4 id="google-speech-to-text와-naver-cloud-의-clova-speech">google speech-to-text와 naver cloud 의 Clova speech</h4>
<p>이 두가지 api 중에 고민하고 있었는데 위의 자료를 참고하여 결정할 수 있었다.</p>
<p>CER(%)의 수치가 낮을 수록 인식률이 좋다고 보면 된다.
WER(Word Error Rate)과 CER(Character Error Rate)로 계산할 수 있는데 한국어의 언어 구조 특성 상 CER로 오류를 측정하는 것이 더 정확한 평가 방법으로 간주된다고 한다.</p>
<p>따라서 한국어 음성 인식률에서 clova speech의 오인식률이 더 낮게 측정됨에 따라 우리는 <strong>한국어 영상의 정확도</strong>가 높은것이 우선이기 때문에 clova speech api를 사용하기로 결정했다.</p>
<h2 id="naver-clova-speech-api">Naver Clova Speech api</h2>
<p>그렇게 최종적으로 naver cloud의 clova speech를 사용하기로 결정했다.</p>
<p>우리가 사용할 clova speech의 기능과 장점을 적어보고 추출된 스크립트의 비교를 통해 clova speech의 정확도를 알아봤다.</p>
<blockquote>
</blockquote>
<ul>
<li>문장 자동 분리 및 타임스탬프 지원</li>
<li>키워드 부스팅 및 인식 후 보정</li>
<li>인식 결과 수정 에디터 제공</li>
<li>실시간 음성 인식</li>
<li>API 기반 인식 제공</li>
</ul>
<p>문장 자동 분리 기능을 통해 우리 프로젝트의 기능인 영상 요약을 chat gpt에게 요청할 때 더욱 효과적일 수 있겠다고 판단했으며, 타임스탬프의 경우 테스트 결과, 시간에 맞게 잘 끊어주는 것을 확인할 수 있었다.</p>
<p>이를 활용하여 Vino의 기능을 더욱 효과적으로 구현할 수 있을 것이라고 판단했다.</p>
<p><img src="https://velog.velcdn.com/images/team_vino/post/ffe31264-514a-4ce4-b633-83f27fbac097/image.png" alt=""></p>
<p>또한 clova speech는 object storage 저장공간을 별도로 사용하기 때문에 <strong>유튜브 영상의 mp3를 저장</strong>할 수도 있고 <strong>추출된 스크립트도 저장</strong>할 수 있었다. 다른 데이터들이 담긴 메인 DB와 별도로 관리하여 <strong>스크립트만 따로 관리</strong>할 수 있다는 점도 장점으로 다가왔다.</p>
<h2 id="스크립트-비교">스크립트 비교</h2>
<p><a href="https://youtu.be/S6J8texGR0U?si=7DM2mQ0Lh97tFoX8">추출에 사용한 영상 보러가기
1강. Sales vs Marketing vs Branding - 현대카드 CEO 정태영 [OVER THE RECORD]</a></p>
<blockquote>
<p><strong>[YouTube Caption Extractor(npm 모듈 활용) ]</strong>
제 아이 씨 상처준 어때요 지금 몇 번 나왔어요 3분 대라 우리가 몇 번을 채워야 되는거예요 어 왜 가보자 [음악] 아 아 아 아 아 아 와 카메라 했으니까 나왔었네요 여러분 안녕하세요 현대카드 대표이사 맞붙는 상태입니다 저 사실 이런 동영산 굉장히 무서워 하고 불편해 하는 데 브랜딩에 권에서 꼭 한번 남기고 싶었던 얘기도 있고 길지 않게 한번 에센스를 정리하고 하는 것도 의미가 있겠다 싶고 오더 에코 엿 아름다운 섭외 하다 보니까 제가 안에서는 면목이 없어서 제가 나섰습니다 감사합니다 감사합니다 사정이고 에 일단 제 앞에 보시면 그 3 1스 그 마케팅 브랜딩 이라는 세 개의 단어가 있습니다</p>
</blockquote>
<blockquote>
<p><strong>[clova speech 활용]</strong>
제 아이 시선 처리는 어때요? 지금 몇 분 나왔어요? 한 3분 되나 우리가 몇 분을 채워야 되는 거예요? 오케이 가보자 와 카메라 앞에 서니까 낯서네요. 여러분 안녕하세요 현대카드 대표이사 맡고 있는 정태욱입니다. 저 사실 이런 동영상 굉장히 무서워하고 불편해하는데 브랜딩에 관해서 꼭 한 번 남기고 싶었던 이야기도 있고 길지 않게 한번 에센스를 정리하고 가는 것도 의미가 있겠 오버더레코에 다른 분을 섭외하다 보니까 제가 안에서는 면목이 없어서 제가 나섰습니다. 감사합니다. 감사합니다. 사족이구나. 일단 제 앞에 보시면 그 세일즈 마케팅 브랜딩이라는 세 개의 단어가 있습니다.</p>
</blockquote>
<p>clova speech api 를 활용해서 추출한 스크립트는 매우 높은 정확도를 보여주었고, 문장부호까지 clova speech에서 자동으로 인식하여 스크립트를 추출하는 것을 보고 감탄했다. 문장 마다의 타임스탬프 역시 정확도가 높아 우리 프로젝트에 사용하기 적합하다고 판단했다.</p>
<p><strong>clova speech의 구체적인 사용 예시와 관련 내용은 다음 포스트에 진행될 예정이다!</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[디자이너가 남기는, "이렇게 개발자와 협업했어요"
]]></title>
            <link>https://velog.io/@team_vino/3%EB%B2%88</link>
            <guid>https://velog.io/@team_vino/3%EB%B2%88</guid>
            <pubDate>Wed, 28 Feb 2024 11:37:08 GMT</pubDate>
            <description><![CDATA[<h2 id="더-가까워집시다-우리">더 가까워집시다 우리</h2>
<p>저는 지난 타 사이드 프로젝트에서 디자이너는 디자이너 개발자는 개발자 그 사이에 벽이 있는 것 같은 느낌을 받았었어요. 모두 열심히 임했지만 마치 각자의 영역에서 더는 궁금해하지 않은 채 각자 역할에만 최선을 다하는 느낌 🥲 </p>
<p>하지만 이건 디자이너 입장에서 결과적으로 많은 아쉬움을 남겼어요. 플러그인 사용으로 인한 디자인 임의 수정이나, 미세하게 달라진 디자인 시안의 수치 (ex. 요소들 간의 간격, 페이지 별 같은 버튼이지만 다른 수치)들로 디자이너는 매번 수정사항을 체크해서 전달하고, 프론트에서는 디자인 작업에 오래 시간을 쓰게 되고 서로를 지치게 만들었던 것 같아요. <em><del>(미세한 수치일지라도 달라진다면, 시각적으로 기능적으로 의도했던 바가 달라지기도 하거든요.ㅠ)</del></em></p>
<p>근본적인 원인을 찾고 싶었고, 결론적으로 이 문제점이 제가 <strong>의도했던 바를 제대로 전달하지 못했기 때문</strong>이라고 생각했어요. 그래서 이번엔 더 적극적인 소통을 위해 노력하고, 명확하고 규칙적인 지표를 전달드려야겠다! 다짐했죠. ✊🏻</p>
<h3 id="각자의-벽을-부셔보자">각자의 벽을 부셔보자!</h3>
<p>이번 Vi.NO 프로젝트는 pm과 디자이너 개발자 이 세 직군이 실제 협업 과정에서 효율적으로 소통하는 부분을 경험할 수 있는 기회였어요. </p>
<p>이번 글을 통해 지난번의 아쉬움을 보완했던 지극히 주관적인! 제 방법을 소개하려 합니다:)</p>
<p>우선, <strong>1) 디자인 단계에서 체계적인 틀</strong>을 만들어 제공하고, <strong>2) 각 역할 간의 소통을 용이</strong>하게 하여 프로젝트에 참여해야겠다는 것을 목표의 큰 틀로 잡았어요.</p>
<blockquote>
<p>이번 프로젝트의 목표는 다음과 같습니다!</p>
<ul>
<li>체계화된 디자인 시스템 전달</li>
<li>개발자와의 소통 방식 파악</li>
<li>빠른 피드백 수용</li>
<li>변수 상황에 대한 빠른 대처 및 제작</li>
</ul>
</blockquote>
<hr>
<h2 id="⚙️-명확한-가이드-전달하기--컴포넌트-제작">⚙️ 명확한 가이드 전달하기 : 컴포넌트 제작</h2>
<p>이번 프로젝트에서는 디자인 시스템에 대한 가이드를 체계적으로 설정해두고 싶었어요. </p>
<p>📍 <strong>효율성 측면에서</strong>
우선 컴포넌트 제작이 실제 프로젝트의 능률을 높일 수 있는지 확인해 보고 싶었어요. 추후 서비스 디벨롭 가능성이 열려있을 경우를 대비해 개발 후에도 새로운 화면이 추가되면 효율적으로 제작이 가능하기 때문이에요. </p>
<p>📍 <strong>개발 측면에서</strong>
개발자분들도 미리 컴포넌트 제작을 통해 페이지마다의 중복되는 코드를 최소화할 수 있고, 각 요소들이 규칙 된 상태를 제공하기 때문에 실제 적용할 때도 혼란을 줄일 수 있을 것이라고 생각했어요. </p>
<p>📍 <strong>디자인 측면에서</strong>
시각적으로는 통일된 디자인 베리에이션으로 안정감을 제공하고, 사용자들에게도 일관된 서비스를 경험을 제공할 수 있어요.</p>
<h4 id="결정적으로-명확한-가이드-제공은-곧-효율적인-소통으로-이어지니까-공을-들일-이유가-충분하다고-생각했습니다">결정적으로 명확한 가이드 제공은 곧 효율적인 소통으로 이어지니까 공을 들일 이유가 충분하다고 생각했습니다!</h4>
<h3 id="진행-과정">진행 과정</h3>
<p>우선 컴포넌트들을 제작하고 정리하는 과정에서 명칭 표시의 어려움을 느꼈는데요. 제작할 때마다 제각각의 이름을 붙여주는 건 오히려 스스로에게나 개발자분들에게나 혼란을 줄 수 있다고 생각했어요. 따라서 <strong>분류 체계가  명확해 보일 수 있도록 ‘/’를 사용해서 각 변주되는 요소들의 차이가 잘 나타나도록 작성하고자</strong> 했습니다. (ex. 상위 / 하위)</p>
<p><img src="https://velog.velcdn.com/images/team_vino/post/ef6584b5-dde1-4f27-9ddd-6b9f6bde1845/image.png" alt=""></p>
<p>크게 컴포넌트 별로 사용 목적 혹은 분류 기준에 따라 <strong>Type(타입)</strong>을 규정했고, 버튼과 같이 시각적인 부분에서 변형이 되는 경우 <strong>Style(스타일)</strong>로 유형을 구분해두었습니다. 각 타입별로 액션이 있는 경우에는 <strong>States(상태)</strong>를 제공했어요. </p>
<p>또한 필요에 따라, 구체적인 설명이 필요한 경우 </p>
<ul>
<li><strong>Placement(배치)</strong> : 고정된 위치가 있는 요소들 간의 간격 혹은 위치 값 제공 (ex. 카드 리스트 간의 간격은 세로 20px 가로 40px을 유지합니다.)</li>
<li><strong>Behavior(행동)</strong> : 고정된 특정 행위를 통해 진행되는 경우 또는 애니메이션 값 제공 (ex. [최근 읽은 영상]은 항상 폴더 상단에 고정되어 순서를 수정할 수 없습니다.)</li>
<li><strong>Element(내부 요소)</strong> : 구성요소의 제한 값 안내 또는 요소 별 글자 수 전달 또는 글자 수 초과 시 처리 방식 안내 등 (ex. 해시태그는 최대 2개까지 노출됩니다.)</li>
</ul>
<p>이와 같은 추가 설명으로 최대한 세세한 정보도 작성해두고자 했어요. </p>
<p>개발자분들은 주로 디자인 시안을 최종으로 확인하고 작업을 진행하기 때문에 PM 님이 전달해 주신 화면 정책집의 내용을 최종적으로 확인할 수 있는 창구라고 생각하며 꼼꼼하게 작업을 진행했어요. </p>
<blockquote>
<p>📂 진행 된 내용은 피그마를 통해 확인해주세요! :  <strong><a href="https://www.figma.com/file/rr7D2kNnJ6l3WltTZeS0q3/VI.NO-%EB%94%94%EC%9E%90%EC%9D%B8?type=design&amp;node-id=1%3A2&amp;mode=design&amp;t=F39fT3XO7LChxtUj-1">VI.NO 피그마</a></strong></p>
</blockquote>
<p>가이드 레퍼런스로는 주로 라인 디자인 시스템의 전달 방식을 참고하며 공부했습니다.
저는 라인 가이드가 분류측면이나, 설명방식에서 정말 친절하다고 느껴서요. 이미 유명하지만 링크 함께 첨부해둘게요! <strong><a href="https://designsystem.line.me/">[라인 디자인 시스템]</a></strong></p>
<p><img src="https://velog.velcdn.com/images/team_vino/post/ffbe824e-598e-447d-a222-984096afffff/image.png" alt=""></p>
<blockquote>
<p>그리고 피그마의 컴포넌트 지정 기능을 통해 제작된 원본은 다른 페이지에 두어 그곳에서 수정사항이 생기면 해당 공간에서 전체적으로 컨트롤이 가능하도록 했어요.</p>
<p>개발자분들이 보는 디자인 가이드에서는 복사본을 사용하여 컴포넌트들을 재정리하였는데, 이는 컴포넌트 기능에서 베리에이션 준 것과는 다르게 유형을 구분해서 전달하고 싶기 때문이었습니다.</p>
</blockquote>
<h3 id="효과">효과</h3>
<p>결론적으로 모든 상태가 반영되어 있는 페이지를 제작하지 않더라도, 각 요소들의 상태 변화를 파악할 수 있어 <strong>불필요한 시안의 페이지 수</strong>를 줄일 수 있었어요. 또한 개발 진행 중에 새로운 화면이나 컴포넌트가 필요해질 경우 <strong>빠른 제작과 추가가 가능</strong>했어요.</p>
<blockquote>
<ul>
<li>시각적인 정리를 통한 이해도 증가</li>
<li>효율적인 페이지 제작</li>
<li>추후 컴포넌트 추가에 용이</li>
<li>추가 페이지 제작 시 빠른 대처 가능</li>
</ul>
</blockquote>
<p>이전 프로젝트에서 컴포넌트는 그저 디자이너가 자신의 디자인을 통일성 있게 하고 기록하기 위한 요소로만 느껴져 아쉬움이 있었는데, 이번 경험은 개발자분들이 실제 활용하는 과정을 통해 컴포넌트 제작을 직접 체화하고 중요성을 느끼게 된 소중한 시간이었습니다! </p>
<p>+) 최대한 구체적으로 컴포넌트 가이드를 제작해 보고 싶은 욕심이 있었지만 시간상의 이유로 </p>
<ul>
<li>Anatomy (컴포넌트 내부 요소) : 컴포넌트 별 컴포넌트를 구성하는 기본적인 UI 요소 설명</li>
<li>Spec (제작 가이드) : 제작 시 권장 수치 제공</li>
<li>실제 모션이 적용되는 애니메이션을 시각적으로 전달</li>
</ul>
<p>등 과 같은 부분까지는 제작해 보지 못했는데요. 추후 해당 부분까지 보완된 구체화된 시스템을 구축해 보고 싶다는 목표가 생겼습니다.</p>
<hr>
<h2 id="📢-개발자와-소통하기--figma">📢 개발자와 소통하기 : Figma</h2>
<p>저희는 PM과 디자이너 개발자의 소통 창구로 노션, 슬랙, 디스코드를 이용하기도 했는데요, 아무래도 실질적으로 디자이너와 개발자로 소통했던 주 채널은 Figma였습니다.</p>
<h3 id="왜-figma">왜 Figma?</h3>
<p>Figma는 최종 디자인을 확인하는 공간이자 동시에 <strong>PM과 디자이너 그리고 개발자가 연결될 수 있는 공간</strong>이기도 했어요. 실시간으로 다수가 접근할 수 있고, 원하는 화면을 보며 상호작용할 수 있으며 변경 현황을 가장 빠르게 확인할 수 있는 곳이기도 했죠. <strong>최종적으로 확인하는 공간이다 보니, 피드백이 들어올 때마다 빠르게 수정하고 그 사실을 전달하는 과정이 중요</strong>하다고 느꼈어요.</p>
<h3 id="진행-과정-1">진행 과정</h3>
<p><img src="https://velog.velcdn.com/images/team_vino/post/096e0518-2dd1-44b3-994e-8243f0609fbf/image.png" alt=""></p>
<p>Figma에서의 소통은 코멘트 기능을 적극 사용했는데요. 개발자분들이 구현 과정에서 디자이너가 놓친 부분이 보이거나, 의문이 생길 경우 해당 시안 부분에 코멘트를 남겨두었습니다. 그럼 PM과 디자이너가 하단의 답글을 남길 수 있어요. 이는 공동 편집이 가능하기 때문이죠.</p>
<p>** 해당 방식을 사용하면서 느꼈던 장점은**</p>
<ul>
<li>원하는 페이지 부분에 유동적으로 코멘트를 남길 수 있어 피드백이 필요한 부분을 직관적으로 확인 가능</li>
<li>해당 코멘트는 모두 열람 가능하기 때문에 바로 확인 후 해당 답변을 공유할 수도 있어 그 공간에서 원격 논의 가능</li>
<li>상대의 답변도 확인할 수 있어 잘못된 답변을 바로잡기 가능</li>
<li>읽음을 체크해도 추후 히스토리에 남아 어떤 과정을 논의 했는지 기록 가능</li>
</ul>
<p><img src="https://velog.velcdn.com/images/team_vino/post/e93feae4-910c-4f80-8043-6922f4a91df9/image.png" alt=""></p>
<p>하지만 <strong>단점</strong>도 있었는데요,</p>
<ul>
<li>너무 많은 코멘트가 쌓이면 오히려 디자인 시안을 확인하는데 방해가 되기도 했고</li>
<li>알람 기능이 있지 않기 때문에, 수시로 피그마에 들어가지 않으면 신규 코멘트에 대한 확인이 늦어지는 경우도 빈번했습니다. 같은 맥락으로 코멘트 답변 확인도 늦어졌어요.
(ex. 4일이 지나서야 코멘트 확인하게 되는..)</li>
<li>또한, 디자인 수정을 진행해도 수정 여부가 한 번에 파악되지 않아 불편했어요.</li>
</ul>
<p>따라서, 급한 시안일 경우 따로 카톡을 통해 개인적으로 문의하게 되는 일이 빈번했습니다. PM과 상의해야 하는 경우 또 한 번의 확인 카톡이 오갔기 때문에 시간이 지연되는 불편함이 있었어요.</p>
<h3 id="해결-방법">해결 방법</h3>
<p>이를 개선하기 위해서, 해결된 코멘트들은 지우기 시작했습니다. 나름의 기준을 정했는데요. 최종적으로 수정 반영이 완료된 코멘트들을 우선적으로 지웠습니다. <del><em>한 번 지운 코멘트는 히스토리를 통해 확인할 수 있지만 그 과정이 꽤 번거롭거든요. 그래서 더 신중했습니다!</em></del>  하지만 남아있는 코멘트들 사이에서 시안을 수정하거나 답글을 달았을 때 변경 여부를 확인하기 어렵기 때문에 따로 근처에 빨간 선으로 표시를 해둔다거나, 멘트를 써 두어 정확하게 확인할 수 있도록 노력했어요.</p>
<p>하지만, 장기적으로는 소통 창구의 개편이 필요함을 느꼈어요. 피그마를 활용하되 상단에서 진행상황을 체크할 수 있는 요소를 제작하고자 하는데, 프로젝트가 지속된다면 적용시켜보고자 합니다! <em>(To be continued..?)</em></p>
<hr>
<h3 id="개발자-분들과-소통을-위해">개발자 분들과 소통을 위해</h3>
<p>제가 중요하게 생각했던 부분은 다음과 같아요.</p>
<p> <strong>✅ 진행 상황을 수시로 확인하고 있기</strong></p>
<p>우선 전체적인 페이지 제작으로 디자인 파트가 끝나도 진행 상황을 숙지하고 있는 것은 중요하다고 생각해요. 언제 어떤 오류로 프로세스가 바뀔지 모르고, 구현 중 놓친 부분들이 보이면 개발 중에도 계속해서 수정이 진행되게 되거든요. 따라서 저는 늘 귀를 열어두었습니다. 빠른 디자인 수정을 통해 스케줄링에 차질이 가지 않도록 노션과 회의록을 상시 체크하며 진행 상황을 확인하는 습관을 들였어요.</p>
<p> <strong>✅ 혼자 결정하지 않기</strong></p>
<p>디자이너에게 디자인에 대한 권한은 많지만, 새로운 기능을 더하거나 협업하는 과정에서 단독적으로 결정할 수는 없기에, 디자인 수정 시 사소한 수정을 제외하고는 항상 PM님과 개발자분들과 의논하는 과정을 거쳤습니다.</p>
<p>모든 시안에 대해서는 <strong>왜 이렇게 제작하고 싶은지 그 이유를 명확히 전달</strong>하고자 했습니다. 납득이 가야 구현의 이유도 생기니까요. 그리고 PM님과 함께 ‘혹시…가능할까요?’를 가장 많이 물어본 것 같아요(ㅎ) 그리고 마지막에 서로 해결할 수 있는 선에서 아이디어를 모아 새로운 방안을 내는 과정이 즐겁기도 했습니다. 서로의 입장에서 생각해 볼 수도 있고요!</p>
<p> <strong>✅ 수정 된 부분은 빠르게 확인할 수 있도록 돕기</strong></p>
<p>수정을 요청받고 디자인 수정본을 전달하는 과정에서, 해당 부분을 빠르게 찾을 수 있도록 피그마에 표시해 두었어요. 새로 수정 한 부분 근처에 빨간 테두리로 표시를 해두고, 멘트를 써 두어 정확하게 확인할 수 있도록요. </p>
<p>또, 카톡에서 어디가 수정되었는지 한 번 더 피그마 화면을 캡처해서 전달함으로써 소통의 오류를 최소화하기 위해 노력했어요. 사소한 변화나 미세한 차이의 경우 타인이 보면 빠르게 찾기 어려울 수 있으니까요.</p>
<p> <strong>✅ 이미지 혹은 GIF파일 전달 시 용량 확인하기</strong></p>
<p>비노의 로딩 페이지에 들어가는 로고 GIF 파일을 전달드리는 상황에서 최대한 고화질로 전달하고 싶은 생각에 앞서 냅다  21.8MB파일을 드린 적이 있어요. 기본 중에 기본이지만 이 사실을 간과했다는 게 좀 부끄러웠습니다. 파일이 너무 크면 서버의 속도를 느리게 만들기 때문에, 파일 크기를 체크하고 전달하는 과정은 꼭 필요하다는 것!</p>
<p>+) 추가적으로, 현재는 디자인 화면 페이지와 워딩으로만 개발자에게 서비스의 프로세스를 전달하는 형식으로 진행했어요. 하지만 이해의 한계가 있다고 판단하여 다음에는 프로토타입 제작을 통해 서비스 흐름에 대한 이해도 높일 수 있도록 하고 싶다는 생각을 했습니다!</p>
<hr>
<p>뒤돌아보니 아직 부족했던 점이 많고 개선하고 싶은 부분이 많네요! 하지만 고민이 많았던 만큼 배우는 것도 많고 또 다른 목표가 생기는 시간이였습니다 🌞 </p>
<p><em>함께 좋은 서비스를 만들기 위해 으쌰으쌰 마인드로 팀을 잘 이끌어주신 PM님 그리고 구현하면서 미처 놓쳤던 부분들을 찾아내주시고 함께 고민해 주신 프론트, 백엔드 개발자분들께 너무 감사하다고 말씀드리고 싶어요 :) 최고의 팀원들이 분명합니다 !!</em></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[비상! 사이드 프로젝트 망할 뻔한 이야기 (feat. 구세주 클로바 스피치)]]></title>
            <link>https://velog.io/@team_vino/2%EB%B2%88</link>
            <guid>https://velog.io/@team_vino/2%EB%B2%88</guid>
            <pubDate>Wed, 28 Feb 2024 11:36:42 GMT</pubDate>
            <description><![CDATA[<p>사이드 프로젝트를 진행해보신 분들이라면 모두 공감하시겠지만요. 아무 일 없이 순탄하게 개발이 이뤄지는 건 정말 드물거예요. 무조건 어려움에 직면할 수 밖에 없죠. </p>
<p>서비스 기획이 처음인 팀 비노에게 당황스러운 일들이 생기는 건 당연하고도 당연한 일이었습니다. 이번엔 팀 비노가 만난 당황스러운 사건들과 어떻게 헤쳐나갔는지, 그 고군분투기를 남겨보겠습니다.</p>
<h2 id="about-vino">ABOUT Vi.NO</h2>
<p>고군분투기를 설명하려면 저희의 Vi.NO가 어떤 서비스인지부터 말씀드려야 할 것 같아요. </p>
<blockquote>
<p><strong>Vi.NO는 AI를 활용하여 유튜브 영상을 단락화된 텍스트로 변환해주는 영상 정리 솔루션입니다.</strong></p>
</blockquote>
<p>유튜브에는 도움이 되는 정보성 콘텐츠들이 정말 많죠. 시간 없는 이 사회에 1시간, 2시간 넘어가는 영상들을 그냥 보고 있을 수도 없는데요.
<em>&quot;내가 원하는 부분만 확인하고 싶은데...&quot;</em> 하며 방향키로 &#39;15초 건너뛰기&#39;만 누르며, 곤란했던 적 한번쯤 있으실 거예요. </p>
<p>👀 한눈에 내용을 파악하기엔 텍스트가 제격이죠. 
그래서 <strong>Vi.NO는 유튜브 링크만 넣으면, 영상을 텍스트로 바꿔줍니다.</strong></p>
<p><img src="https://velog.velcdn.com/images/team_vino/post/6424129c-c09a-46ad-afee-8d45219a423a/image.png" alt=""></p>
<p>무엇보다 <strong><a href="www.vi-no.site">Vi.NO</a></strong>의 강점은 <strong>AI를 통해 스크립트를 읽기 쉽게 내용별로 단락을 나누어</strong> 준다는 것입니다. <strong>단락별로 소주제</strong>까지 제공하여  정말 읽기 쉽죠.  </p>
<p><img src="https://velog.velcdn.com/images/team_vino/post/e93d6b82-15d9-4986-b6c9-efba3238a95e/image.png" alt=""></p>
<h3 id="이럴-때-활용하기-좋아요">이럴 때 활용하기 좋아요!</h3>
<blockquote>
<p>1) (개인) 유튜브 영상이 너무 길어 다 보기 힘들어요!
2) (교육 플랫폼) 강의 영상 중 핵심만 제공하고 싶어요!
3) (청각장애인) 영상 내용을 텍스트로 직관적으로 확인하고 싶어요!</p>
</blockquote>
<h3 id="👇🏻-여기서-vino를-직접-만날-수-있어요">👇🏻 여기서 Vi.NO를 직접 만날 수 있어요</h3>
<blockquote>
<p>** <a href="www.vi-no.site">Vi.NO 사이트 바로가기</a>**
<a href="http://www.vi-no.site">www.vi-no.site</a></p>
</blockquote>
<p>Vi.NO가 어떻게 기획되고 디벨롭 되었는지 아래 노션 페이지에서도 자세히 확인해 보세요.
<strong>📂 <a href="https://www.notion.so/Vi-NO-l-AI-51430456110a4d7cae1fa820070389dc">Vi.NO 제작 자료 확인하기 (2023.12~)</a></strong></p>
<h2 id="vino가-꼭-해결해야-하는-문제들">Vi.NO가 꼭 해결해야 하는 문제들!</h2>
<p>각설하고, 모든 서비스들이 그렇듯 Vi.NO에게도 꼭 해결하고 싶은 문제들이 있었어요.</p>
<p>영상 대신 더 빠르게 원하는 부분을 텍스트로 파악할 수 있도록 하자는 비전을 바탕으로, 아래의 3개의 목표를 가졌죠.</p>
<h4 id="1-읽기-쉬운-스크립트를-제공할-것">1) 읽기 쉬운 스크립트를 제공할 것</h4>
<p>: 정말 유튜브에서 발화되는 그대로가 아닌, 텍스트로서 읽기에 부담없이 쉬운 스크립트가 필요했어요.</p>
<h4 id="2-스크립트에서-빠진-내용이-없을-것">2) 스크립트에서 빠진 내용이 없을 것</h4>
<p>: Vi.NO에서 스크립트를 제공하기로 한 이유는 우리가 유튭에서 &#39;15초 건너뛰기&#39;를 할 때 &quot;내가 중요한 내용을 건너뛰지는 않았을까?&quot; 하는 걱정을 해소시켜주기 위함이었어요. 그래서 빠진 내용이 없는 것이 정말 중요했죠.</p>
<h4 id="3-변환-시간이-너무-길지-않도록-하기">3) 변환 시간이 너무 길지 않도록 하기</h4>
<p>: 영상을 텍스트로 보려는 목적 중 하나는 시간적 효율성이기 때문에 변환 시간은 양보할 수 없는 부분이었죠.</p>
<h2 id="그런데-문제가-생겼어요">그런데, 문제가 생겼어요!</h2>
<h4 id="1-하나도-안읽히는-스크립트">1) 하나도 안읽히는 스크립트</h4>
<p><img src="https://velog.velcdn.com/images/team_vino/post/acf928b4-a67f-43ea-88d5-04b8dc065af7/image.png" alt=""></p>
<p>충격적이지만 위 사진은 1월 17일 추출했던 유튜브 스크립트입니다. 아래 api를 찾아 스크립트를 돌렸고, (<a href="https://www.npmjs.com/package/youtube-caption-extractor">https://www.npmjs.com/package/youtube-caption-extractor</a>) 충격에 제일 먼저 한 말은 &quot;이건 진짜 안돼요&quot; 였습니다. </p>
<h4 id="2-내용이-빠져버린-스크립트">2) 내용이 빠져버린 스크립트</h4>
<p>워낙 스크립트의 가독성이 좋지 않고, 내용 파악이 어려운 수준이다 보니, </p>
<blockquote>
<p><strong>스크립트 추출 -&gt; gpt 통한 텍스트 보정 -&gt; 텍스트 단락화</strong></p>
</blockquote>
<p>의 로직을 택했습니다. 그렇다보니 아래 이미지와 같이 내용이 빠져버린 텍스트만 남게 되었어요.</p>
<p>어떻게 보면 그럴듯해 보이지만, 스크립트 중간중간 비약이 생기는 지점들이 생겨, 유저가 영상과 스크립트를 함께 보기 힘들어졌죠.</p>
<h2 id="이렇게-해결했어요">이렇게 해결했어요!</h2>
<p>정말 서비스의 핵심 부분이 문제였던 비상인 상황, 위 두가지의 문제를 해결한 것은 바로 <strong>네이버 클라우드 api</strong> 덕분이었는데요. </p>
<p>그 배경엔 자주 사용하고 있었던 클로바 노트가 있었고, 눈여겨 보고 있던 hyperclovaX의 행보 덕이었습니다. 
<img src="https://velog.velcdn.com/images/team_vino/post/967ab9ac-539e-4f49-8542-55d39c78e6ba/image.png" alt=""></p>
<pre><code>ㄴ 2023년 10월, HyperClovaX 출시 후 셀프 스터디한 내용</code></pre><p>가장 먼저 주요하게 사용했던 것은 <strong>CLOVA SPEEACH api</strong> 였는데요. 
Vi.NO에서 작동하는 모습은 다음과 같습니다! 스크립트가 너무 잘 읽히지 않나요?</p>
<p><img src="https://velog.velcdn.com/images/team_vino/post/e927eda8-23f3-4110-9998-712c992c09f6/image.png" alt=""></p>
<p>게다가 구조화된 내용을 기반으로 단락까지 나누어 더욱 한 눈에 들어오도록 구성했습니다. </p>
<p>실제로 타 api가 아닌 <strong><a href="https://velog.io/@team_vino/4%EB%B2%88">clova speech api를 사용한 이유</a></strong>와 <strong><a href="https://velog.io/@team_vino/5%EB%B2%88-z4ahym10">본 api를 실제로 적용한 과정의 A to Z</a></strong> 를 다음 콘텐츠에서 더욱 자세히 소개하도록 하겠습니다.</p>
<h3 id="아직-해결하지-못한-문제-변환-시간">아직 해결하지 못한 문제, 변환 시간</h3>
<p>그럼에도 남은 문제는 바로 &#39;변환 시간&#39; 이었는데요. 사실 이 부분은 여전히 해소하지 못하였지만, 주요하게 해결해야 하는 문제로 남아있는데요. </p>
<p>대략 10-12분의 영상까지는 1분 정도의 스크립트 추출 + gpt를 통한 보정 시간이 소요됩니다. 이 이후의 영상들은 아직 변환하기 어려운 상태인데요. Vi.NO는 계속해서 개발 중이고, 더더욱 개선해나가겠습니다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로젝트 동아리가 처음인 PM에게 보내는 헌사 (feat. 전 이렇게 했어요)]]></title>
            <link>https://velog.io/@team_vino/TEAM.-ViNO%EA%B2%B0%EC%84%B1%EA%B8%B0</link>
            <guid>https://velog.io/@team_vino/TEAM.-ViNO%EA%B2%B0%EC%84%B1%EA%B8%B0</guid>
            <pubDate>Sun, 25 Feb 2024 12:45:52 GMT</pubDate>
            <description><![CDATA[<h1 id="축하합니다">축하합니다</h1>
<p>먼저 이 글을 만나신 것 축하합니다. 혹시 PM이 처음이신가요? 그렇다면 잘 오셨습니다.
이 글은 PM이 처음인 한 사람의 고군분투기입니다.</p>
<blockquote>
<h4 id="이-글을-다-읽고-나시면">이 글을 다 읽고 나시면</h4>
</blockquote>
<ul>
<li>서비스 기획안 짜는 법부터 화면 정책집 짜는 법</li>
<li>디자이너와 소통하는 법</li>
<li>개발자와 소통하는 법</li>
<li>일정관리와 기획자의 역할</li>
</ul>
<p>(에 대해 얘는 이런 생각을 했구나.. ㅋㅋ) 를 알게 되실 겁니다.  </p>
<p>저도 동아리에서 11명이라는 사람들을 이끌면서 2달간 서비스의 초반 기획부터 배포까지.. PM으로 총괄한 것이 처음인데요. 생각보다 사이드 프로젝트에서 PM이 어떻게 프로젝트를 이끌어갔는지 A to Z를 말하는 글들이 부족하더라구요. 저도 많이 헤맸는데요. </p>
<p>사이드 프로젝트 시작하시는 다른 분들도 이 글이 도움이 되었으면 하는 마음으로 글을 씁니다. 당연히 ‘이게 국룰이다. 이렇게 해라’는 글은 아니구요. PM으로서 사이드 프로젝트를 진행하며 느낀 회고이자 일기입니다.</p>
<h1 id="타임라인-서비스-기획부터-배포까지">[타임라인] 서비스 기획부터 배포까지</h1>
<p>각설하고, 사이드 프로젝트를 시작할 때 가장 고민인 부분은 일정짜기입니다. </p>
<p>제가 프로젝트를 진행했던 타임라인은 이렇습니다. 
<img src="https://velog.velcdn.com/images/team_vino/post/23aa99b0-d0df-48e8-b3a9-9fb60f360418/image.png" alt=""></p>
<blockquote>
<p>1) 기획 완료 
2) 함께할 크루 찾기 (설득) 
3) 디자이너와 디벨롭 + 시안 완성 
4) 개발자 이해시키고 플랜 합맞추기 
5) 개발과 디자인 그리고 미처 생각하지 못했던 디테일 기획의 무한굴레
6) QA + 오류잡기 </p>
</blockquote>
<p>하단의 메모는 다음 프로세스로 넘어가기 전에 필수적으로 완료되어야 할 일들을 적어둔 것입니다. </p>
<p>사실 프로젝트를 진행하는 방법론은 참 많죠. 애자일, 워터풀 등등이요. 저는 워터풀 방식을 택했는데요. 아무래도 프로젝트가 처음이다보니 애자일은 조금 한계가 있었던 것 같아요.</p>
<h2 id="프로젝트-기획하기-aka-사람들-꼬시기">&lt;프로젝트 기획하기 (a.k.a. 사람들 꼬시기)&gt;</h2>
<p>: 저는 프로젝트 기획이란, <strong><em>잘 꼬시기</em></strong> 라고 생각했어요. 나와 함께 이 서비스를 만들 사람들을 꼬시고, 이 서비스를 사용할 유저들을 꼬시고, 마지막으로 이 서비스을 짠 나 스스로에게 확신과 근거를 찾아가는 일이라고요.</p>
<p>이 방법은 바로 서비스 기획안이라는 이름으로 세상에 나오게 되죠.</p>
<h3 id="📍서비스-기획안-완성">📍서비스 기획안 완성</h3>
<p>서비스 기획안은 공감할 수 있는 문제 의식을 잘 드러내어 내 서비스가 꼭 필요한 서비스라고 설득하는 것이라고 생각합니다. 공감할 수 있는 문제 의식을 드러내는 데 가장 초점을 두었어요. 
<img src="https://velog.velcdn.com/images/team_vino/post/9007ff89-7787-479b-b46f-7bfb9c427ee2/image.png" alt=""></p>
<p>디테일한 기획안 말고, 러프한 버전의 아이데이션 차원으로 작성했던 기획안의 일부를 공유합니다. </p>
<blockquote>
<p><strong>🔎 필수로 들어가야 할 항목</strong></p>
</blockquote>
<p>1) 기획의도
2) 페르소나
3) 시장 분석 + 타겟분석
4) 서비스 차별성
5) MVP 핵심 기능 소개</p>
<p>저는 사실 서비스 기획안을 완성하기 이전, PM끼리 모여서 기획안에 대해서 돌아가면서 질문/피드백을 하는 시간을 가졌는데요. 이 시간이 정말 도움이 많이 되었습니다. 제 눈엔 꼭 필요하다고 생각했던 것들이 다른 사람에게는 전혀 아닐 수 있거든요. 주변에 다른 기획자가 있다면 많은 대화를 해보시는 것도 정말 추천합니다.</p>
<h4 id="1-기획의도">1) 기획의도</h4>
<p>: 기획 의도가 잘 설명되면, 서비스 자체에 대해서도 훨씬 이해도가 높아집니다. 더불어 내가 제시한 해법이 아니라, 다른 더 좋은 서비스 혹은 기능 아이디어를 바탕으로 디벨롭시킬 수도 있죠.  </p>
<p>더불어 공감할 수 있을만한 문제 의식을 가졌을 때 다른 사람들도 공감할 수 있고 재밌게 책임감을 갖고 서비스를 만들 수 있다고 생각해요. 시장에서 정말 필요한 서비스인지, 회고할 수 있었습니다.</p>
<h4 id="2-페르소나">2) 페르소나</h4>
<p>: 특히나 기존 시장에 있는 서비스가 아니라 타겟층이 새로워진 서비스인 경우엔 이 페르소나를 잘 설명하게는 게 중요하다고 생각해요. 페르소나를 설정하는 것이 추후 디자인/브랜딩 방향성을 정하는 데에도 아주 주요한 역할을 하죠. </p>
<h4 id="3-시장-분석--타겟-분석">3) 시장 분석 + 타겟 분석</h4>
<p>: 실제로 내가 이 서비스가 필요하고 시장도 원한다고 생각하지만, 사실은 그렇지 않을 수 있습니다. 내가 만들려고 한 서비스가 얼마나 시장성이 있는지 확인하는 것도 중요합니다. 기껏 만들어놨지만, 이 서비스는 나한테만 필요한 서비스라면..? 흠.. 생각해봐야겠죠?  </p>
<h4 id="4-서비스-차별성">4) 서비스 차별성</h4>
<p>: 사실 비슷한 서비스들이 정말 많은데, 내가 지정한 문제 의식을 이렇게 구현했을 때 가장 큰 해결법라는 확신을 찾아가는 단계라고 생각해요. 이 서비스는 다른 서비스들보다도 이런 점에서 강점을 가지고, 더 많은 유저가 효용을 느끼며 사용할 것이다 라는 확신이 들어야 한다고 생각해요. 저는 개인적으로 이 부분을 작성하면서 왜 이 서비스를 만들어야 하는지를 가장 확실히 할 수 있었습니다.   </p>
<h4 id="5-mvp-핵심-기능-소개">5) MVP 핵심 기능 소개</h4>
<p>직접적으로 내가 생각한 기획 의도에 맞게 설계한 기능이 바로 이것이다! 를 보여주는 섹션. 개발자분들은 이 부분을 집중해서 보셨던 것 같아요.   </p>
<blockquote>
<p>✍🏻 <strong>TIP</strong> 이라면, 이 핵심 기능을 <strong><em>어떤 api를 사용해서 어떤 로직으로 구현할지까지 미리 찾아보고 소개</em></strong>하는 것은 아주 좋습니다.   
사이드 프로젝트의 경우엔 개발자분들의 걱정 중 하나는 내가 이걸 실제로 구현할 수 있을까? 시간 내에 완성할 수 있을까? 도 있는데요.   
이때, 미리 찾아본 개발 정보나 개발 방법을 소개하면 개발자분들의 의욕을 더 불러일으킬 수 있습니다. 더불어 PM으로서도 일정 배분부터 개발 프로세스를 대략적으로 가늠할 수 있구요. </p>
</blockquote>
<h4 id="6-bm">6) BM</h4>
<p>사이드 프로젝트의 필수 항목엔 넣지 않았지만, 팀원들의 의욕 상승을 위해 필수적으로 필요하다고 생각하는 부분입니다. </p>
<pre><code>💬 Vi.NO의 서비스 기획안 작성법 편은 따로 작성하겠습니다.</code></pre><hr>
<h3 id="📍-팀원-모으기">📍 팀원 모으기</h3>
<p>이렇게 제 기획에 확신을 가지고, 다른 사람들도 <strong>꼬실 수 있는</strong> 서비스 기획안이 완성됐습니다. 이제 함께 만들 사람을 찾아 나서야겠죠. </p>
<pre><code>저는 함께할 팀원을 고르는 것이 정말 어려웠었는데요.  
어떤 기준으로 함께할 사람을 고르면 좋을지 누군가 알려줬으면, 하는 생각이 있었어요. 
누군가에겐 참고가 되었으면 하는 맘에 저의 기준을 남겨놓습니다. 
(물론, 가장 먼저 제가 함께하고 싶은 사람이 되는 게 가장 중요하겠죠?) </code></pre><blockquote>
<h4 id="q1-어떤-디자이너-개발자와-함께-해야-할까요">Q1. 어떤 디자이너, 개발자와 함께 해야 할까요?</h4>
<p><strong>A.</strong> 저는 이런 기준으로 함께할 분들을 찾았어요. <strong>1) 일정 약속 2) 꼼꼼함 3) 열정</strong> 을 가장 중요하게 생각합니다.  <strong><em>이렇게 하라</em></strong> 고 직접 말해줘야 사람 보다는, 공통의 목표가 정해져 있을 때 자신이 할 일이 무엇인지 아는 사람이랑 일하는 것이 가장 효율이 좋다는 저만의 기준이 있었습니다. </p>
</blockquote>
<p>🖌️ <strong>디자이너</strong>는 자신의 디자인에 이유가 있는 사람과 함께 일하고 싶었습니다. (실제로 저희 디자이너님은 정말 이 부분에 강한 것 같습니다!) 디자인이 그냥 취향의 산으로 빠져버리는 것은 위험하다고 생각했기에, 논리와 이유를 기반으로 이야기할 수 있는 분과 일하고 싶었어요.</p>
<p>🖥️ <strong>개발자</strong>는 경험과 열정, 정리 능력을 기반으로 함께할 분을 찾았습니다. 워낙 제가 개발 부분에 강점을 갖지 못하다보니 열정과 경험을 보여주신 분들을 뽑으려고 했던 것 같습니다.</p>
<blockquote>
<h4 id="q2----사이드-프로젝트의-시작-어떻게-팀원들에게-믿음직한-pm이-될-수-있을까요">Q2.    사이드 프로젝트의 시작, 어떻게 팀원들에게 믿음직한 pm이 될 수 있을까요?</h4>
</blockquote>
<p>제가 가장 고민한 부분이었습니다.</p>
<p>회사가 아니기에 원할한 프로젝트를 위해선 신뢰를 쌓는 것이 가장 중요하다고 생각했어요. 회사에선 검증된 pm이 있다고 생각하지만, 사이드 프로젝트에서 못미더운 pm이 있으면 중간에 애정을 잃기 쉬우니까요.</p>
<blockquote>
<h4 id="a----저는-팀원들에게-신뢰를-쌓기-위해-이-부분에-집중했습니다">A.    저는 팀원들에게 신뢰를 쌓기 위해 이 부분에 집중했습니다.</h4>
</blockquote>
<p>*<em>1)  존댓말을 썼어요. *</em>
상호존중의 시작은 아무래도 존댓말이더라구요. 반말은 친해질 수 있지만, 사적인 사이로 빠지기 쉬웠어요. </p>
<p>*<em>2) 정리를 습관화했어요. *</em>
우왕좌왕 정리가 안된 모습은 신뢰를 얻기 힘들어요. 회의 전, 회의 내용을 미리 공유하고, 회의 후에도 체계적으로 정리해서 공유해요. </p>
<p>*<em>3) 질문거리에 대한 답변은 미리 준비했어요. *</em>
질문이 나올법한 내용은 미리 고민하고 공부해 두어요. 언제든지 답변할 수 있도록이요. </p>
<p>*<em>4) 확실한 화법을 사용하려 했어요. *</em>
제게 어려운 부분이기도 했는데요. 최선을 다했던 부분이기도 합니다. 
애매모호하고 자신 없는 답은 다른 분들께 혼선을 줄 수 있다고 생각했습니다. <em>&quot;확실이 이렇게 할 거예요.&quot;</em> 라는 것이 개발자분들이 가장 선호한 화법이기도 했습니다. </p>
<p>그래서 답변하기 힘든 질문이 오면 잠시 시간을 달라고 말씀드렸어요. 전후 상황과 맥락 등을 모두 고려해서 ‘내가 확신이 드는‘ 최선의 답변을 찾아 확실하게 이야기하고는 했죠. </p>
<h2 id="디자이너와-디벨롭하기">&lt; 디자이너와 디벨롭하기 &gt;</h2>
<blockquote>
<p>🫧 <strong>사용 툴: 노션, 피그마</strong></p>
</blockquote>
<h3 id="step-1-서비스-레퍼런스-찾아서-합-맞추기">step 1. 서비스 레퍼런스 찾아서 합 맞추기 </h3>
<p>디자인 회의할 때 포인트는 항상 내가 좋아하는 예쁜 디자인이 아니라 “서비스가 전하고 싶은 메시지를 효과적으로 전달할 수 있는 디자인” 에 집중하려 했습니다</p>
<p>디자이너에게 이 서비스의 기획 의도부터 페르소나, 기대효과, 어떻게 유저들이 이 서비스를 사용했으면 좋겠는지까지 아주 아주 디테일하게 이야기했습니다. </p>
<p><img src="https://velog.velcdn.com/images/team_vino/post/fe59e3af-afe2-4b5d-a762-d34efc4dbe8e/image.png" alt=""></p>
<p>아무래도 <strong><a href="www.vi-no.site">Vi.NO</a></strong>는 정보성 영상 콘텐츠들을 텍스트로 전달하니, 가독성이 매우 중요했어요. </p>
<p>그래서 <strong>동일한 타겟층의 서비스들의 컬러링부터 라인의 사용, 텍스트 굵기나 크기까지</strong> 어떤 것이 가독성이 가장 좋을지 타 레퍼런스도 정말 참고를 많이하고 디자이너와 이야기했습니다. </p>
<p> <img src="https://velog.velcdn.com/images/team_vino/post/8a802eb9-c387-4568-8624-8193eda9e6d2/image.png" alt=""></p>
<p>이 뒤, 서비스 기획단계의 디자이너의 업무는 <strong><em><a href="https://velog.io/@team_vino/2%EB%B2%88">이 아티클</a></em></strong> 에서 더 디테일하게 확인할 수 있습니다. </p>
<p>초반 서비스 방향과 목표에 대한 공감대와 이해도가 잘 형성되어야 이후 디벨롭 과정이 더 의미있어진답니다. </p>
<h3 id="step-2-와이어프레임--기능-명세서-완성">step 2. 와이어프레임 + 기능 명세서 완성</h3>
<p>서비스의 디자인 방향성을 함께 잡았다면, 이제 화면을 진짜 그려야겠죠.
이 때 필요한 것은 <strong>와이어프레임과 기능명세서</strong>입니다. 내가 짠 기능하나 하나 이 버튼을 눌렀을 때 어떤 결과가 펼쳐지는지를 디테일하게 적는 것이 중요합니다.  </p>
<p><img src="https://velog.velcdn.com/images/team_vino/post/ca059beb-81c0-4452-84b1-b2470ece20b3/image.png" alt=""></p>
<p>이렇게 각 기능들에 번호 부여하여, </p>
<p>1) 숫자 순번으로는 &#39;각 기능들에 대해 설명&#39;을, 
2) 영어 순번으로는 &#39;어떤 액션을 했을 때&#39; + &#39;어떤 결과가 나오는지&#39;를 모두 적어주었습니다.</p>
<p><strong>기능명세서</strong>는 꼭 필요하다고 생각하는데요. </p>
<blockquote>
<p><strong>📍협업의 측면에서ㅣ</strong> 진전을 멈추게 하는 불필요한 핑퐁을 줄여줍니다, 하나하나 질문할 필요없이, 모든 설명들이 기능명세서에 응축되어 있으니까요
<strong>📍PM 스스로도ㅣ</strong> 기능명세서를 쓰면서 <em>‘이렇게까지 디테일하게 써야 할까’</em> 하는 생각이 많이 드는데요. 한 기능에서 파생되는 모든 결과치들을 생각하다보면 미처 생각하지 못했던 경우들에 대해 생각하게 될 뿐만 아니라 “이 기능이 꼭 필요할까? 추가로 어떤 기능이 필요하겠다”는 근본적인 고민들로 더 나은 서비스를 만들어나갈 수 있다고 생각해요. </p>
</blockquote>
<pre><code>➕ 더 나아가 디자이너와 UX의 측면에서도 더 나은 기능은 무엇일지, 어떻게 대체할 수 있는지 이야기했습니다. 
이 부분에 대한 디테일한 고민은 추후 콘텐츠에서 따로 소개할게요.</code></pre><h2 id="개발자와-합맞추기--커뮤니케이션-하기">&lt; 개발자와 합맞추기 + 커뮤니케이션 하기 &gt;</h2>
<p>저는 개발에 대한 지식이 별로 없습니다. 아는 문법이라곤 sql 정도..? 입니다. 22살 스타트업에서 인턴하던 시절, 아빠처럼 잘 챙겨주시던 개발자 팀장님께서 하시던 업무를 옆에서 보던 정도..? 요 정도 노베이스 상태의 pm이 어떻게 개발자와 커뮤니케이션 했는지 말씀드릴게요. </p>
<blockquote>
<h4 id="📍-사이드-프로젝트-시작-전-pm이-개발-관련-알아두면-좋은-것">📍 사이드 프로젝트 시작 전 pm이 개발 관련 알아두면 좋은 것.</h4>
<p><strong>1) 프로젝트 전 프론트엔드/백엔드가 담당하는 일과 업무들.</strong>
 저는 테크 블로그들도 전전하며 어떻게 개발하는지 최대한 많이 염탐했습니다. 대충 역할과 개발 흐름을 알겠더라구요. 이정도면 대략적으로 개발자분들과 대화가 가능해졌습니다. 
어떤 업무를 프론트에서 담당하고 어떤 업무를 백엔드에서 담당하는지 파악하고 정확하게 담당자와 커뮤니케이션하기 시작하면 효율적인 일정 관리가 가능해지더라구요.
2) <strong>오류 종류들</strong>
프로젝트가 끝나고 개발자분들께서 오류 종류들에 대해서는 미리 공부하는 것도 추천해주시더라구요. 현재 어떤 개발상의 문제점이 생겼는지를 파악하고 기획자로서 개발 일정을 애자일하게 확인하는 것이 중요하니까요!</p>
</blockquote>
<pre><code>*PM이 참고하기 좋은 IT 플랫폼: 1) 요즘IT 2) velog 3) 브런치 
</code></pre><h4 id="💬-tip1-개발짱을-선정하라">💬 TIP1. 개발짱을 선정하라.</h4>
<p>저처럼 노베이스인 pm께 드리는 자그마한 팁은, 가장 밀접하게 개발 상황을 커뮤니케이션할 수 있는 개발짱을 선정하라는 것입니다. 저는 프론트짱 1명, 백엔트짱 1명을 선정했는데요. </p>
<p>각 개발 부분에 대한 총체적인 뷰로 바라볼 수 있을 뿐만 아니라, 어떤 부분이 병목인지에 대한 디테일한 설명을 들을 수 있었습니다. 더 디테일하게 현재 빨리 개선되어야 하고 진행되어야 하는 부분들을 정확하게 지시하여 컨트롤 할 수 있었습니다. </p>
<h4 id="💬-tip2-솔직하게-모른다고-하고-공부하자">💬 TIP2. 솔직하게 모른다고 하고 공부하자.</h4>
<p>디테일한 부분들은 솔직하게 모른다고 이야기하고, 개발자 분들로부터 설명을 들었습니다. 설명 들은 내용을 바탕으로 더 아티클을 탐색해서 왜 이 부분이 어려운 지점인지 이해하려 했죠. 더 빠르게 일을 진행시킬 수 있었고, 서로가 이해가 되지 않는 지점을 쉽게 파악할 수 있어 훨씬 용이했죠.</p>
<hr>
<h3 id="📍개발자와-회의하기">📍개발자와 회의하기</h3>
<p><img src="https://velog.velcdn.com/images/team_vino/post/dc7a2358-8211-4eed-8019-7b690a4699ec/image.png" alt=""></p>
<blockquote>
<p><strong>회의</strong>는 
<strong>1️⃣ 서비스 전반 방향성 및 이슈 공유 -&gt; 2️⃣ 프론트짱/백엔드짱의 업무 진행상황 공유 -&gt; 3️⃣ 개별 진행상황 공유</strong> 의 순서로 스크럼을 진행하였는데요. </p>
</blockquote>
<hr>
<h3 id="📍개발자와-협업하기-feat-화면-정책집">📍개발자와 협업하기 (feat. 화면 정책집)</h3>
<blockquote>
<p><strong>🫧 활용툴: 피그마, 노션</strong></p>
</blockquote>
<p>개발자와 협업 시작 전, 무조건 완성되어야 하는 부분은 바로 화면 정책집입니다. 화면 정책집엔 기능명세서에서 담기지 않은, ‘조건’ 들을 담았습니다. &lt;어떤 조건에서 작동한다.&gt; 는 디테일한 부분입니다. </p>
<p><img src="https://velog.velcdn.com/images/team_vino/post/f06e31db-ee0e-4061-8f11-a336023381cb/image.png" alt=""></p>
<p>업무 소통의 경우에는 저는 피그마와 노션(화면 정책집)을 통해 진행했는데요. </p>
<p><img src="https://velog.velcdn.com/images/team_vino/post/7f9fc517-8311-42ec-9201-36fe15a512be/image.png" alt=""></p>
<p>스토리보드를 통해서 개괄적으로 화면을 보는 경우도 많지만, 저희의 경우엔 피그마에서 최대한 조건들을 많이 나누고, 사용 순서대로 화면을 배치해두어 이해가 쉽도록 했습니다. 추가로 설명이 필요한 경우엔 디테일하게 빨간 글씨로 화면 아래에 적어두었구요.</p>
<p><img src="https://velog.velcdn.com/images/team_vino/post/cb7679e2-0ce3-457c-9a99-dbeeec5bb048/image.png" alt=""></p>
<p>이렇게 와이어프레임 상단에는 정책집 링크를 넣어두어 언제든 조건들을 확인할 수 있게 해두었고,
와이어프레임 하단에는 추가적으로 필요한 정보들을 남겨두었습니다. </p>
<blockquote>
<p>피그마에서 와이어프레임을 어떻게 정리했는지 확인하고 싶다면,
이 곳을 확인해주세요 <strong><a href="https://www.figma.com/file/JUePmc6jcS5aeKeFB0XQbu/%EB%94%94%EC%9E%90%EC%9D%B8?type=design&amp;node-id=85%3A5674&amp;mode=design&amp;t=RWZ9LqVALsmtlWDW-1">(Vi.NO 피그마 바로가기)</a></strong></p>
</blockquote>
<hr>
<h3 id="📍개발자와-일정관리하기-feat-칸반보드">📍개발자와 일정관리하기 (feat. 칸반보드)</h3>
<p>일정관리의 경우에는 노션의 칸반보드를 통해서 개별적으로 스프린트 형식으로 진행상황을 파악했습니다. </p>
<p><img src="https://velog.velcdn.com/images/team_vino/post/9d787cc0-6255-4568-90d9-8d1f3558374e/image.png" alt=""></p>
<p>칸반보드의 형식은 개발 진행상황을 직관적으로 파악하고 관리하기 정말 용이했어요.</p>
<p><img src="https://velog.velcdn.com/images/team_vino/post/cdf15b79-ad8b-4141-89a1-379a8c9a1963/image.png" alt=""></p>
<p>서비스 기획부터 진행 방법까지 꿀팁을 모아모아봤는데요. 정말 이게 정답이라고 할 수 없지만, 여러분께 꼭 도움이 되는 내용이었으면 좋겠습니다. 다음엔 Vi.NO 서비스를 만드는 도중 만난 비상 상황들과 그 대처법에 대해 이야기해볼게요! </p>
]]></description>
        </item>
    </channel>
</rss>