스토리 홈

인터뷰

피드

뉴스

조회수 1465

[인공지능 in IT] 서로 다른 우리, 대화할 수 있을까?

설연휴 동안 그간 못 봤던 밀린 TV 프로그램들을 맘껏 즐기며 여유로운 시간을 보냈다. 그 중에서도 여러 분야의 전문가를 초빙해 특강을 해주는 tvN의 '어쩌다 어른'을 보기 시작했다. 몇 년 전 언어인문학을 주제로 한 조승연 작가님편을 보니 새삼 현재 대한민국이 처한 현실을 피부로 느끼게 되더라.< tvN>강연에서 가장 심도있게 다룬 부분은 대한민국 영어교육의 현실이다. 초등학교부터 영어 수업을 듣고, 심지어 말도 제대로 떼기 전인 유아기부터 영어를 주입시키는 것이 어느새 자연스러운 일이 되어버렸다. 하지만, 10년, 20년 이상 영어 교육을 받았는데도 막상 영어로 문서 작업을 하거나, 외국인이 길을 물어보면 식은땀을 흘리는 이유는 무엇일까? 어째서 한국에서는 영어를 제대로 하려는 노력보다, 영어를 아는 노력을 하고 있는 것일까?재미있는 사실은 우리만 영어를 배우려고 애먹는 것이 아니다. 미국인이 한국어를 배울 때에도 비슷한 현상을 겪는다. 강연 중 'FSI(The Foreign Service Institute)'에서 미국인들이 다른 나라 언어를 얼마나 공부해야 소통할 수 있는지에 대한 연구 자료를 공개했다. 언어별 Level 1부터 Level 5까지 다섯 가지 난이도로 구분 되어있고, 이에 따른 총 필요시간으로 구성되어 있는 연구에서, 한국어는 일본어, 중국어와 함께 소통하기 까지 총 2,200시간을 공부해야 하는 Level 5군에 속해 있었다.즉, 전세계 7,000여 개가 넘는 언어 중 한국어는 영어와 문장구조가 완전히 다르기 때문에, 24시간 내내 공부해도 90일 넘게 공부해야 한다는 것. 이렇듯 모국어가 아닌 다른 언어를 배우기 위해서는 어마어마한 시간과 노력이 필요하다. 만약, 단순히 언어를 알기 위해 배우는 것보다, 소통하기 위해 배운다면 흔히들 말하는 'ROI(Return on Investment)'를 더 높일 수 있자 않을까.출처: 동아일보소통을 위한 언어 학습은 비단 사람에게만 해당되는 것이 아니다. 기계와 사람의 소통 역시 요즘과 같은 인공지능 시대에서는 빼놓을 수 없는 부분이다. 몇 년 전부터 업계에서는 '챗봇(Chatbot)' 열풍이 불고있다. 챗봇은 대화(Chat)와 로봇(Robot) 두 단어를 합친 신조어로서, 각종 앱이나 웹을 기반으로 문자를 통해 사용자의 의도를 파악해 대화할 수 있는 인공지능 기계다. 여기에는 '자연어 처리(Natural Language Processing, NLP)', '자연어 이해(Natural Language Understanding, NLU)', '머신러닝(Machine Learning)' 등 수많은 기술이 접목되어 발전 중이다. 현재 챗봇은 나날이 진화하며, 텍스트를 텍스트로만 처리하는 것을 넘어, '음성으로 변환(Text-To-Speech, TTS)'시키거나, '음성을 텍스트로 변환(Speech-To-Text)'시키는 등 다양성에 있어 점점 넓은 범위에 적용되고 있는 추세다.< 출처: Understanding Natural Language Understanding, Bill MacCartney >글로벌 챗봇 시장은 매년 큰 폭으로 성장하고 있는 추세이며, 여러 사업 분야에 걸쳐 사용되고 있다. 북미의 시장조사기관 'Credence Research' 조사에 따르면, 글로벌 챗봇 시장은 2015년부터 2023년까지 연평균 35% 성장할 것으로 예상된다. IT솔루션 기업 'MindBowser'가 조사한 결과, 95%의 기업이 챗봇 활용성에 대해 긍정적인 반응을 보였으며, 고객응대(93%)부터, 마케팅(61%), 상품 주문(47%), 소셜 미디어(32%) 등 사업 분야에서 활용되는 용도 역시 다양한 것으로 밝혀졌다.챗봇은 어떠한 프로세스를 통해 실제로 작동하는지 살펴보기 위해서 사내 엔지니어의 도움을 받았다. 스켈터랩스에서 대화형 인공지능 프로젝트팀에 있는 정태형 엔지니어가 메신저를 통한 간단한 시범 사례를 스크린샷으로 찍어 보여주었다.< 인공지능 메신저 사례, 출처: 스켈터랩스 >여행지를 자동으로 추천해주는 엡에 적용할 수 있는 챗봇과의 대화다. 사용자가 "여행을 가고 싶다"고 말하자 자동으로 '카이트봇'이 반응하고, 여행 기간과 테마를 물어본다. 여기서 사용자가 "여행 기간"을 말하자 챗봇은 자동으로 '3월'과 '7일'을 인식, 이전 질문에서 대답하지 않은 테마에 대해 질문한다. 이렇게 사용자와 챗봇 사이에서 대화를 자연스럽게 주고 받을 수 있는 것은 대화의 구성 요소 중 '의도(Intent)', '개체(Entity)', '맥락(Context)'이 중요한 역할을 한다. 이를 간단히 살펴보도록 하자.의도(Intent)는 사용자가 어떠한 의도로 대화를 하는지를 의미한다. 위 스크린샷의 경우, 여행을 가는 것'이 의도라 할 수 있다. 예를 들어, "여행 가고 싶어"가 아닌 "여행 가볼까?"로 입력하더라도 - 미리 여행을 가는 것에 대한 자연어 기반 패턴이 'Intent Classifier'에 입력되어 있는 상태라면 - 이를 '사용자가 여행을 가고 싶구나'라는 의도로 이해할 수 있는 것이다.개체(Entity)는 사용자의 의도 중에서 실체가 될 수 있는 변수를 말한다. 개체는 사용자가 입력한 문장에서 특정한 변수가 달라질 때 사용된다. 위 스크린샷의 경우, '3월 3일', '해변', '일주일' 등과 같이 주로 명사 형태로 구성된 문장에 들어가는 구성 요소를 말한다.문맥(Context)은 이전 대화를 자연스럽게 이어갈 수 있도록 처리할 수 있는 기능이다. 예를 들어, 사용자가 챗봇에게 "가수 빅뱅의 프로필을 검색해달라"고 요청했다. 그리고 빅뱅의 노래를 듣기 위해 "거짓말 틀어 줘"라고 명령하면, 기존에 빅뱅이라는 가수에 대해 대화하고 있던 문맥을 인식해 God의 거짓말이 아닌 빅뱅의 거짓말을 재생하는 것이다.이 외에도 챗봇에는 '말뭉치(Utterance)', '시나리오(Scenario)', '슬롯채우기(Slot Filling)' 등 다양한 구성요소를 통해 대화를 이어나갈 수 있다. 물론, 아직 100% 인간과 대화하는 기술까지 이르지는 못했다. 하지만, 우문현답하지 않고 사용자 의도를 정확하게 파악하는 수준에 이르러 생활에 편의성을 제공하고 있다.한국어의 경우 언어의 난이도 때문에 국내 기업은 물론 많은 글로벌 IT 기업도 아직 완벽한 수준에 도달하지 못했다. '잘 한다'라는 말만 하더라도 '훌륭하게 하다', '만족할 만하다', '자주 하다' 등의 긍정적인 표현이 있는가 하면, '잘 하는 짓이다' 등의 부정적인 표현인 경우도 흔하기 때문이다. 결국 챗봇도 기계이기 때문에, 여러가지 문장과 상황을 학습시켜 한국어 성능을 향상시켜야만 한다.다시 '어쩌다 어른'으로 돌아가보자. 강연을 마무리할 즈음 조승연 작가는 이렇게 말한다."영어도 결국 언어의 한 종류, 영어를 쓰는 사람들도 우리와 같은 사람, 우리처럼 희로애락을 느끼는 인간입니다. 기계와 얘기하기 위해 법칙에 맞춰 말해야 하는 것이 아니라 그 사람과 감정을 통하게 해주는 어떤 도구입니다."여전히 우리는 챗봇이라는 기계와 소통한다기 보다, 일방적으로 질문을 던지고, 챗봇은 미리 입력되어 있는 규칙 안에서만 답한다. 학습을 통해 수많은 데이터가 축적된다 하더라도, 아직까지 언어를 통해 전달되는 인간의 감정을 완벽히 이해하기에는 부족한 것이 사실이다. 과연 기계가 '법칙'에 맞춰서 말해야 하는 것 이상을 넘어서는 순간이 올까? 우리는 그 순간을 찾아 지금도 노력하고 있는지 모른다.이호진, 스켈터랩스 마케팅 매니저조원규 전 구글코리아 R&D총괄 사장을 주축으로 구글, 삼성, 카이스트 AI 랩 출신들로 구성된 인공지능 기술 기업 스켈터랩스에서 마케팅을 담당하고 있다#스켈터랩스 #기업문화 #인사이트 #경험공유 #조직문화 #인공지능기업 #기술기업
조회수 2349

[MOIN] 05. MOIN 인턴 개발자를 떠나보내며...

어느덧 9월이 됐습니다. 정말 가을이 성큼 다가오는 것 같습니다.저희 MOIN에서도 큰 변화가 있었습니다. 두 달동안 안드로이드 개발에 여름방학을 불태워 준 오소연님이 학교로 돌아가게 됐습니다. 이번에는 7-8월 가장 뜨거웠던 여름을 함께한 오소연 안드로이드 개발자에 대해 소개해드리겠습니다.무뚝뚝한 매력이 철철 넘쳤던 오소연 안드로이드 개발자- Education -한양대학교 컴퓨터공학부 학사 (재학중)▶     업무에서 어떤 부분을 담당하고 계신가요?안드로이드 네이티브 어플리케이션 개발을 담당하고 있습니다. ▶     아직 학생이시죠? 왜 컴퓨터 공학을 전공하고 싶으셨나요? 어렸을 때부터 컴퓨터로 이것저것 해보는 걸 좋아했어요. 포토샵이나 나모웹에디터, html 같은 걸로 뭘 만들어 보는 게 재밌었거든요. 그 때는 코딩에 대해 전혀 아는 게 없었어요. 그러다가 중학교 때 어떤 선생님 한 분이 C언어를 가르쳐주셨는데 재밌더라구요. 나중에 이런 걸 해보면 좋겠다고 생각했어요. 대학교 전공을 선택할 때도 컴퓨터 코딩을 전문적으로 배운 적이 없으니까 해보자라는 마음으로 온거구요.  ▶     수많은 개발 영역 중에서 안드로이드를 선택한 이유도 있나요?학교 내 학술동아리 중 안드로이드를 다루는 동아리가 있었어요. 그게 재밌어 보이더라구요. 그래서 2학년 때 안드로이드 동아리에 들어갔어요. 안드로이드 앱은 직접 만든게 결과로 보이고 만든 결과물을 제가 직접 사용해볼 수도 있어서 뿌듯하기도 하고 만족스러웠어요. 웃는게 매력적인 오소연 안드로이드 개발자 ▶     모인에 합류하게 된 계기는 무엇이었나요?학교에 방학 때 하는 현장실습 프로그램이 있었어요. 저도 한 번 지원해보려고 기업리스트를 봤죠. 저는 컴퓨터 공학 전공이니까 그 전공을 필요로 하는 기업들 리스트를 살펴봤어요. 그 중에 모인이 있었어요. 모인 기업 설명을 보니까 호기심이 생기더라구요. 솔직히 학생으로서 핀테크, 해외송금 같은 분야는 쉽게 접해볼 수 있는 분야는 아닌 거 같거든요? 해보고 싶었어요. 그래서 지원했습니다.  ▶     그렇군요. 아직 학생이신 분에게 이런 질문을 하는 건 좀 그렇지만 개발 영역 중에 자신있는 부분이 있나요?아니면 재밌다고 생각하는 부분도 좋아요.오히려 배울수록 모르는 게 더 많아지는 거 같아서 자신 있는 파트는 잘 모르겠어요. 근데 앞으로 웹이나 앱 개발 하는 일을 더 전문적으로 공부하고 싶어요. 제가 생각했을 때 저는 제가 한 작업들이 결과물로 딱 보이는 걸 좋아해서요. 웹이나 앱은 제가 직접 써볼 수 있잖아요. 그래서 이 부분을 더 전문적으로 공부하고 싶습니다.  오소연 개발자에게 '함께 일하고 싶은 사람'이란?#매너 #겸손 #긍정(대책 없는 거 제외)▶     모인에서 두 달 정도 일해보니 어땠어요?진짜 재밌었어요. 여기 계신 분들은 제가 좀 무뚝뚝한데도 잘해주셨거든요. 학생이라고 무시하는 것도 없었고, 잘 챙겨주시고 진짜 좋았어요. 특히 디자이너와 하는 협업은 처음이었어요. 디자이너인 보람님은 초보인 제가 답답하셨을 거 같은데 매번 친절하게 대해주셨어요. 사소한 것 까지도 세세하게 잘 알려주시고, 덕분에 큰 어려움 없이 일할 수 있었어요.  그리고 대학생으로서 모인이 입주해있는 구글캠퍼스에서 일할 수 있었던 것도 정말 신기해요.▶     구글캠퍼스의 어떤 점이 신기했어요?구글캠퍼스 분위기가 진짜 멋졌어요. MOIN뿐만 아니라 여기 계신 분들이 다들 좋아하는 일을 자발적으로 하고 있다는 느낌을 받았어요. 각자 자기가 하시는 일이나 소속 스타트업에 대해 애정과 자부심이 있어 보였다고 해야 되나? 그냥 돈 벌려고 회사 나오는 느낌이 아니었어요. 저도 여기 오면서 “아, 나도 열심히 살아야겠다”고 반성 많이 했어요 (^^) 또 이곳에서 스타트업 세계를 새로 접했어요. 졸업하면 이름있는 기업에 들어가야겠다고만 생각했었는데 생각이 달라졌어요. 그녀는 라이언 노트북 파우치 함께 학교로 돌아갔다고 한다!!!!!!! (글쓴이는 절대 부럽지 않다)▶     오, 그러면 모인이라는 스타트업은 어떤 곳이라는 생각이 들던가요?처음 면접 때, 대표님이 저한테 “저희 회사는 출퇴근도 그렇고 유연한 곳이라서 너무 큰 부담은 안가져도 된다”고 하셨거든요. 솔직히 그때 ‘설마 그러겠어?’ 라고 생각했어요. 근데 진짜 그러더라구요. 뭔가 출퇴근이 자유로우면 풀어질 거 같은데, 여기 분들은 다들 자율적으로 알아서 하시더라구요. 다들 알아서 하면서도 체계가 생긴다는 게 신기했어요. 엄청 능력자로 보였어요.   ▶     너무 좋은 얘기만 해줬는데, 아쉬운 점은 없어요?진짜 별로 없는데… 그냥 스타트업에 대한 대중 인지도가 전반적으로 낮다는 거에 대한 아쉬움은 있어요. 제 주변 어른들도 그렇고 이름이 알려지지 않았다는 이유로 불신하는 분들도 많았고, 아예 관심도 안가지시는 분들이 많았거든요. 그게 조금 그랬어요. 그거 외에는 딱히…?▶     앞으로 어떤 개발자가 되고 싶으신가요?음. 제 머릿속에 있는 걸 그대로 구현 해낼 줄 아는 개발자가 되고 싶어요. 일단 앞에서도 말했지만 저는 제가 직접 만들어 낸 걸 눈으로 확인하고 싶고, 써보고 싶거든요. 근데 머릿속에 있는 대로 안되면 좀 그렇죠. 거기에 덤으로 세련되고 깔끔한 코딩을 할 줄 아는 개발자라면 훨씬 좋겠어요. - 오소연이 꼽은 인생 명언 -아직 안 일어난 일을 미리 걱정하지 좀 마라!by. 우리 엄마 (소연님 어머니)#모인 #MOIN #개발자 #개발 #개발팀 #인턴 #인턴소개 #팀원 #팀원소개 #팀원인터뷰 #인터뷰 #기업문화
조회수 1676

로봇 공학의 새로운 패러다임! 한화정밀기계의 협동 로봇을 만드는 로봇사업부 인터뷰!

한화정밀기계의 협동로봇 HCR-5 / 출처 - 한화정밀기계 이제 번거로운 작업은똑똑하고 안전한 협동 로봇에게 맡기세요! 제조 산업의 다양한 과정들이 점차 기계화되어가고 있습니다. 기계화의 과정에서도 사람이 개입되어야 하는 번거로운 과정들이 남아있기 마련인데요. 사람이 꼭 필요한 섬세하고 동적인 역할까지 수행하면서 기계의 편리성을 살릴 수 있는 ‘협동 로봇(코봇)’의 탄생으로 그 고민이 해결되었습니다.머지않은 미래에 협동 로봇의 춘추전국시대가 예상되는 가운데, 2017년 시장에 진입한 한화정밀기계의 HCR 시리즈 협동 로봇은 뒤늦게 시장에 합류했지만, 유려한 디자인과 다양한 기능, 안전성을 고려한 특색 있는 제품 생산으로 전 세계 고객들의 사랑을 받으며 점유율을 확대해가고 있습니다. 협동 로봇의 발전으로 개발과 연구를 전문으로 하는 직업도 탄생했는데요. 한화정밀기계에는 협동 로봇 전문가집단인 로봇사업부가 존재합니다. 이 부서의 수장인 장우석 로봇사업부장에게 자세한 이야기를 들어보겠습니다. Q. 안녕하세요. 우선 협동 로봇에 대해 간단히 설명 부탁드립니다!한화정밀기계 장우석 로봇사업부장 / 출처 - 한화정밀기계안녕하세요. 한화정밀기계 로봇사업부의 장우석입니다. 산업 현장에서 사람들을 돕기 위해 만들어진 로봇이 바로 협동 로봇입니다. 이들은 정확성과 일관성이 요구되는 반복적인 업무들을 처리하는데요. 기존의 반복적인 업무를 대신하고, 작업자는 주관적인 판단이나 유연성이 요구되는 일을 할 수 있도록 돕는 것이죠. 현재의 협동 로봇 이전에 주로 사용했던, 기존의 산업용 로봇은 굉장히 한정적인 업무만을 수행할 수 있었습니다. 가령 물건을 하나 옮긴다고 가정하면, 그에 맞는 고난도의 컴퓨터 프로그램을 입력해야 그 일을 할 수 있습니다. 만약 다른 장소로 물건을 옮기려고 한다면 조립공정을 멈추고 중장비를 사용해 옮겨야 합니다. 따라서 시간과 비용이 굉장히 많이 듭니다. 반면 협동 로봇은 이러한 번거로운 과정들을 한 번에 해결해줍니다. 특히, 한화정밀기계의 HCR 협동 로봇은 사용자 친화적인 인터페이스를 갖추고 있어서 작업자가 작동법을 익히는데 하루도 채 걸리지 않습니다. 또한, HCR 협동 로봇의 워크플로를 세팅하거나 변경할 때는 단순히 필요한 항목들만 클릭해 바꾸면 됩니다.싱가포르 합자법인 공장에서 HCR-5를 생산하고 동남아시아 시장에 공급할 예정인 한화정밀기계 / 출처 - 한화정밀기계 Q. 한화가 로봇 산업에 진출하게 된 계기는 무엇인가요?한화그룹은 4차 산업혁명의 일환으로 로봇 산업을 시작했습니다. 다양한 분야 중 저희는 협동 로봇에 초점을 맞췄고, 작년에 국내 최초의 협동 로봇인 HCR 시리즈를 출시했습니다.한화그룹은 항공엔진, 에너지, 산업 장비, CCTV 카메라와 같이 다양한 산업 분야에 관심을 두고 있습니다. 이러한 시장을 키우고 선두가 되기 위해, 한화는 정밀기계, 동작 조종 기술, 사물 인식 소프트웨어, 자동 내비게이션과 같은 분야에서 전문성을 높이고 있습니다. 이러한 모든 것의 중심이 바로 로봇 산업입니다.이렇게 다양한 산업 지식, 경험 그리고 기술을 바탕으로 로봇사업부를 키울 수 있었고, 지금의 HCR 시리즈 같은 제품을 시장에 내놓을 수 있게 된 것입니다. 특히 로봇 공학 분야와 소프트웨어 개발에 매우 높은 전문성을 가진 인력을 보유하여 협동 로봇 기술 개발(R&D)을 빠르게 진전시킬 수 있었습니다. 한화정밀기계와 싱가포르 정밀 엔지니어링 전문 업체인 PBA 그룹의 합자법인 "PBA-Hanwha Robotics"의 개소식 모습 / 출처 - 한화정밀기계  Q. 한화 협동 로봇의 제품 현황과 고객 반응은 어떤가요?한화정밀기계의 협동로봇 HCR-5 / 출처 - 한화정밀기계한화정밀기계는 현재 세 종류의 협동 로봇(HCR)을 출시하였으며, 각각 3kg, 5kg, 12kg의 무게를 들 수 있습니다. 이 세 종류의 협동 로봇은 크기가 작고, 옮기기 쉬우면서 방대한 범위의 업무를 진행할 수 있기 때문에 다양한 업무 지원이 필요한 중소 제조 기업에 이상적인 모델이라 할 수 있습니다. HCR 시리즈의 시장 내 고객 반응은 매우 호의적입니다. HCR 시리즈만이 가진 가장 큰 장점은 사용자가 단일 제어 장치에서 두 개의 HCR 협동 로봇을 실행할 수 있다는 점입니다. 그렇기 때문에 운영비가 최대 10%까지 절감되는 효과가 있죠. 거기에 HCR 시리즈 조작이 쉽다는 점까지 장점으로 작용하면서 시간을 절약하고 생산성을 더욱 높일 수 있습니다.  기능과 안정성을 모두 잡은 HCR 시리즈만의 디자인 또한, 고객들은 HCR 협동 로봇의 수려한 디자인을 가장 크게 평가합니다. 보통 산업용 기계는 튀어나온 부분들이 있어서 긁히거나 부딪힐 위험이 있는데 HCR은 부드러운 곡선 모양으로 제작되어 안전하고 디자인이 뛰어납니다. 산업 디자인은 보이는 게 전부가 아닙니다. 사람들이 협동 로봇과 같이 일할 때 실제로 안정감을 느낄 수 있어야 합니다. 그런 이유로 더 안전하고 부드럽게 보이도록 곡면을 살려 디자인했습니다. 디자인과 기능 면에서도 HCR 시리즈는 매우 안전한 제품입니다. HCR 협동 로봇은 작업자의 옆에서 업무를 보조하는데, 자동 충돌 감지 기능이 있어서 부딪히면 즉각적으로 작동을 멈춥니다. 2017 iF 디자인 어워드, 제품 디자인 부분에서 본상을 수상한 HCR 협동 로봇 / 출처 - 한화정밀기계 Q. 협동 로봇의 미래에 대한 예측과 향후 개발하고자 하는 협동 로봇은?미래에는 AI와 딥러닝, IoT 등 4차 산업혁명을 대표하는 기술들이 접목된 협동 로봇이 시장을 주도할 것이라 예측합니다. 특히 AI와 딥 러닝 기술로 인해 조만간 로봇 산업에는 큰 지각 변동이 있을 것이라 예상합니다. 원래는 5년이나 10년 주기로 일어날 것으로 생각했는데, 이제는 그것보다 더 앞당겨질 것 같네요. 예전에는 몇 년 더 걸릴 것으로 생각했던 기술들이 AI와 딥러닝 기술이 접목된 지 2년 반 만에 이미 구현되고 있으니까요!그래서 한화정밀기계에서는 앞으로 생산될 제품에 AI나 빅데이터, IoT를 어떻게 접목하고, 실제로 어떻게 적용될 수 있을지에 대해 연구하고 있습니다. AI가 접목된 협동 로봇은 어떠한 상황이나 조건에서도 최대한 쉽게 일을 수행할 수 있습니다. 특히 기술 접목 분야에서 한화그룹은 다양한 산업군과 계열사가 있다는 것이 매우 큰 장점인데요. 다양한 계열사에 자문하면서 실제로 협동 로봇이 어떻게 업무에 적용이 되고, 앞으로 어떻게 발전시킬지 논의하고 있습니다. 협동로봇 합자법인 공장 투어 모습 / 출처 - 한화정밀기계 한화정밀기계의 장우석 부장은 피처폰에서 스마트폰 시대로 바뀌었듯이, 로봇 시장도 향후 몇 년 이내로 큰 패러다임 전환이 일어나리라 전망했습니다. 단순히 몇 개의 일을 수행하는 로봇에서 거의 모든 일을 처리할 수 있는 로봇으로 변화하는 것입니다. 협동 로봇 시장은 아직 초기 단계에 있으며 시장 규모도 매우 작지만, 앞으로의 사업 성장 가능성이 매우 큰 분야입니다.한화정밀기계는 현재 유럽과 동남아시아 시장의 큰 성장 가능성을 두고 사업에 박차를 가하고 있는데요. 단기적인 목표는 시장점유율을 매년 두 배로 늘리는 것이며, 장기적인 목표는 협동 로봇 분야에서 세계적인 선도 기업이 되는 것이라고 합니다.4차 산업혁명에 힘입어 자동차와 스마트 팩토리를 중심으로 기술 트렌드를 이끄는 기업을 목표로, 글로벌 로봇 시장을 선도하는 기업이 되기 위해 끝없는 노력을 거듭하고 있습니다. 점차 확대되는 협동 로봇 시장을 선도하는 한화정밀기계의 미래를 함께 응원 부탁드립니다!#한화 #한화그룹 #한화정밀기계 #구성원인터뷰 #직무정보 #기업정보 #기업문화 #비전 #목표 #채용정보 #공채정보
조회수 1168

[인공지능 in IT] 인공지능과 저널리즘

얼마 전, 재미있는 기사를 읽었다. 일본의 한 SF 공모전에 응모한 작품 1,400편 중 인공지능이 작성한 소설 두 편이 예선 심사를 통과했다는 내용이었다. 이 중 소설 한편의 제목은 '컴퓨터가 소설을 쓴 날'이다. 소설을 작성하는 인공지능 기술을 개발한 연구팀은 육하원칙 등의 제시어를 준 뒤, 연관어에 따라 소설을 쓰는 알고리즘을 활용했다.미디어 혹은 인공지능 분야에 생소한 독자들에게 다소 신기할 수 있겠지만, 사실 인공지능을 활용한 저널리즘은 수 년 전부터 진행 중이다. 국내에서는 2014년 서울대학교 언론정보학과의 'hci+d Lab' 이준환 교수팀이 개발한 알고리즘을 시초라고 할 수 있다. '프로야구 뉴스 로봇'이라고 불리는 소프트웨어는 KBL의 모든 경기를 자동으로 요약해 정리한다. 연구팀이 처음부터 이 같은 기능을 염두에 둔 것은 아니었고, 데이터를 시각화하는 과정에서 시각화 방식을 텍스트로 바꿔본 것이 연구의 시작이라고 한다. 위 사례는 사람이 아닌 기계가 직접 '글'을 작성했다는 점에 있어 의미가 크다. 미디어 업계에서도 디지털화는 불가항력 같은 존재가 되고 있다.얼마 전, 옥스퍼드-로이터 저널리즘 연구소에서 미디어 업계를 대상으로 조사를 시행했다. "2018년 실행해야 할 가장 중요한 과제는 어떤 것이라고 생각하는지"에 대한 물음에 "데이터 수용량을 증가시키는 것"을 가장 많이 답변했다. 모바일 알림, 웹사이트나 애플리케이션에 사용자를 등록시키는 일 등 여러 과제들이 있었지만, IT 솔루션 업계도 아닌 미디어 업계가 데이터 수용량 증가를 최우선 과제로 생각하고 있다는 사실은 개인적으로 매우 충격적이었다. 또한, "현재 귀사에서는 기사 보도에 있어 어떠한 용도로 적극적인 인공지능 기술을 도입할 예정입니까?"라는 질문에 '컨텐츠 추천', '업무 자동화', '기삿거리 탐색' 등 다양한 분야에서 인공지능 기술 도입을 계획하고 있었다. 그만큼 이미 언론에서도 인공지능 기술은 먼 세상 이야기가 아닌, 당장 피부로 느껴질 정도로 가까워졌다.세계 최대 통신사 중 하나인 'Associated Press(AP)'는 2017년 'The Future of Augmented Journalism: A guide for newsrooms in the age of smart machines'이라는 인공지능 활용 기술 가이드를 발간했다. 해당 가이드에 따르면, 인공지능은 언론에서 크게 다섯가지 영역으로 활용된다. 이에 대한 예시를 하나씩 살펴보도록 하자.첫번째로 'Machine Learning', 즉 기계학습이다. 기계학습을 이용하면, 방대한 데이터로부터 결론을 도출하는 과정을 쉽게 처리할 수 있다. 그리고 기계학습 알고리즘을 통해 기자들은 이미지를 포함한 막대한 양의 자료를 한 번에 처리할 수도 있다. 미국의 매체 'Quartz' 소속 'Sarah Slobin' 기자가 트럼프 미국 대통령의 취임 연설에 대한 기사에 기계학습을 이용한 분석 자료를 쓴 일례가 있다. 트럼프의 얼굴 표정과 연설에서 표현된 감정을 판단하는 데에 기계학습 알고리즘을 사용한 것.< 출처: Quartz, 제공: 스켈터랩스 >두번째 활용 영역은 'Language'다. 인공지능 분야에서 언어에 대한 연구는 꾸준히 이어지고 있는데, 언어 처리 분야 중에서도 저널리즘과 관련 있는 기술은 '자연어 생성'과 '자연어 처리'다. 당연하겠지만, 자동으로 문장을 생성하는 것은 언론에서 매우 유용하게 사용할 수 있는 기술 중 하나다. 'LA Times'는 'LA Quakebot'이라는 서비스를 개발했다. 'LA Quakebot'은 자연어 생성 기술을 활용해 지역에서 지진이 일어난 순간, 이미 작성된 프레임에 맞춰 기사를 작성하며, 완성된 기사는 트위터를 통해 송출한다.< 출처: LA QuakeBot 트위터, 제공: 스켈터랩스 >세번째는 'Speech'로, 저널리즘에서 대화형 인터페이스가 뉴스 소비 및 유통에 어떠한 영향을 미칠 지 관심을 가지고 있다. 이미 'AP', 'Wall Street Journal', 'BBC', 'Economist' 등 여러 미디어가 오디오 인터페이스 기술을 시도하는 것으로 알려졌다. Speech 역시 크게 두 가지로 나뉘는데, 'TTS'라고 불리는 'Text-To-Speech'를 활용하면 뉴스룸에서 제공하는 문자 기사를 음성으로 변환시키고, 합성된 음성을 콘텐츠로 송출할 수 있다. 반대로 'STT', 즉 'Speech-To-Text'를 활용하면 음성으로부터 의미를 잡아내고, 모든 의도와 목적에 맞춰 음성을 문자로 변환시키며, 이를 통해 기자들이 인터뷰 내용을 녹취하는데 소요하는 시간을 줄일 수 있다.< 출처: BBC NEWS LABS, 제공: 스켈터랩스 >네번째, 듣는 것과 녹취하는 것을 넘어 눈으로 본 것을 기록할 수 있는 'Vision' 기술이다. 컴퓨터 비전을 활용하면 빠르고 쉽게 이미지 및 영상을 분류하고 정리할 수 있다. 용이한 검색을 통해 궁극적으로 편집 속도까지 높일 수 있는 셈이다. 'AP'는 인공위성으로 수집한 영상 데이터를 공급하는 'Digital Globe'라는 기업을 통해 동남아 선박의 고해상도 위성사진을 확보했다. 이를 통해 노예선에 관한 탐사보도에 필요한 결정적인 증거를 찾으며, 2016년 공공서비스 부문 퓰리처상을 수상했다.< 출처: AP, 제공: 스켈터랩스 >마지막으로 'Robotics'를 꼽을 수 있다. 로봇 센서를 활용해 사건 사고에 대한 사람들의 반응을 실시간으로 측정할 수 있으며, 앞서 언급한 'Quakebot'의 예처럼 자연재해가 발생하는 것에 대해 다룰 수 있다. 'AP'는 2016년 하계올림픽 당시, 로봇과 원격 카메라를 이용해 기자들이 물리적으로 직접 접근할 수 없는 지역에 카메라를 설치하고, 원격 조종해 촬영했다. 또한, 드론을 이용해 이라크 모술 남동쪽 다이바가 근처에 추방된 이라크인들을 촬영해 중독 지역 난민 위기에 대해서도 보도한 바 있다.< 출처: AP, 제공: 스켈터랩스 >이렇듯 인공지능이 미디어 업계 전체에 긍정적인 영향을 주고 있으며, 이를 활용한 사례는 앞으로도 더욱 늘어날 것으로 전망한다. 다만, 지속적으로 발전하는 인공지능을 무조건 도입하는 것만이 능사는 아니다. 인공지능 기술의 확산으로 보도 속도, 보도 규모 및 범위 등에 도움될지라도, 데이터의 질에 따라 좋지 않은 기사가 나올 수 있기 때문이다. 'AP'의 스마트머신 시대 뉴스룸을 위한 가이드에도 언급된 포인트로 마무리를 해보자.1. 인공지능은 저널리즘의 도구이지, 저널리즘을 대체하지 않을 것이다.2. 인공지능은 인간과 마찬가지로 편향적이고, 실수를 할 수도 있다. 이는 데이터가 모든 것을 결정하기 때문이다.3. 인공지능이 만병통치약은 아니다. 최근 자율주행 자동차 사고 이슈처럼 기술이 극복하지 못하는 문제는 여전히 존재한다.4. 인공지능에 대해 더 많이 알아야 인공지능 활용 가능성의 문이 크게 열린다.5. 저널리즘의 도구가 변한다고 해서 저널리즘의 법칙이 변하지 않는다. 언제나 윤리와 기준은 매우 중요하다.이호진, 스켈터랩스 마케팅 매니저조원규 전 구글코리아 R&D총괄 사장을 주축으로 구글, 삼성, 카이스트 AI 랩 출신들로 구성된 인공지능 기술 기업 스켈터랩스에서 마케팅을 담당하고 있다 #스켈터랩스 #기업문화 #인사이트 #경험공유 #조직문화 #인공지능기업 #기술기업
조회수 2207

CSS animation으로 프로토타이핑하기

들어가며Framer, Flinto, Origami, Invision. 많은 프로토타이핑 도구가 존재합니다. 디자인에 활력을 불어넣고 개발팀과의 커뮤니케이션을 위해 필수라고 하는 프로토타이핑. 어떻게 하기는 해야겠는 데 어려운 도구나 코드르 공부하기엔 시간이 없고, 막상 열심히 공부하면 새로운 버전이 나오고, 더 좋은 도구가 나오고. 이런 경험을 많이 하셨을 겁니다. 프로토타이핑 도구로 멋지고 완결된 시나리오를 가진 결과물을 만들 수도 있습니다. 하지만 우리에게 당장 필요한 것은 지금 당장 떠오르는 아이디어를 보여줄 수 있는 아이콘의 간단한 모션, 쓱 움직이는 화면 전환 같은 것이 아닐까요? 오늘 배워서 바로 쓸 수 있는 CSS animation으로 하는 간단한 프로토타이핑 방법을 소개합니다.https://codepen.io/yunkimoon/embed/preview/BZEYgY?default-tabs=css,result&embed-version=2&height=600&host=https://codepen.io&referrer=https://blog.stibee.com/media/c7c8adfdea76b3b98829ecce41fee7d7?postId=e5bb1630afb5&slug-hash=BZEYgY<iframe data-width="800" data-height="600" width="700" height="525" data-src="/media/c7c8adfdea76b3b98829ecce41fee7d7?postId=e5bb1630afb5" data-media-id="c7c8adfdea76b3b98829ecce41fee7d7" data-thumbnail="https://i.embed.ly/1/image?url=https://s3-us-west-2.amazonaws.com/i.cdpn.io/1370087.BZEYgY.small.f06b1cb1-09d2-4285-b8b5-eb8f5b9cea7a.png&key=a19fcc184b9711e1b4764040d3dc5c07" class="progressiveMedia-iframe js-progressiveMedia-iframe" allowfullscreen="" frameborder="0" src="https://blog.stibee.com/media/c7c8adfdea76b3b98829ecce41fee7d7?postId=e5bb1630afb5" style="display: block; position: absolute; margin: auto; max-width: 100%; box-sizing: border-box; transform: translateZ(0px); top: 0px; left: 0px; width: 700px; height: 525px;">어디서, playground코딩을 공부하려면 텍스트 에디터도 설치해야 하고, 각종 패키지도 설치해야 합니다. 또한, 결과물이 담길 파일도 생성해야 하고, 여러 파일이 연결되니까 폴더 구조도 고민해야 하죠. 이런 고민을 하다 보면 시작조차 하기 싫어집니다. 그래서 브라우저에서 바로 작성하고 확인하고 공유할 수 있는 온라인 코딩 플레이 그라운드가 있습니다. 대표적으로 jsbin과 codepen이 있습니다. 그냥 해당 서비스에서 가서 각 섹션(html 또는 css)에 맞게 코드를 입력하기만 하면 됩니다. 우리는 html과 css섹션만 사용할 예정입니다. js와 같은 다른 섹션은 최소화(minimize)해주세요.codepen.io어떻게 시작할까html에 내용을 담고, css에 디자인(스타일)을 담을 겁니다. 당장 직접 작성하기는 어려우니 예제(https://codepen.io/yunkimoon/pen/BZEYgY)의 html과 css코드를 그대로 복사합니다. 코드의 주석(회색글씨)을 확인해 봅니다. 요약하면 아래와 같습니다.가장 바깥의 파란 배경 상자이미지와 그걸 담고 있는 상자파란 배경 상자에 hover(마우스 오버 이벤트)를 하면,left 포지션을 2%에서 80%로 변경여기서 중요한 건 .box상자에 설정된 transition이라는 속성입니다. transition은 딱딱한 움직임을 부드럽게 해줍니다. 여기서는 position left를 2%에서 80%로 부드럽게 바꿔주었습니다. 위치뿐만 아니라 색상(color, background), 크기(width, height)도 자연스럽게 바꿔주는 속성입니다. “all 3s”라는 값을 가지고 있는데 “모든 변경사항에 대해 3초 동안 움직여라”라는 의미입니다.꼭 알아야할 3가지css 애니메이션의 맛을 잠깐 보았습니다. transition을 통해 부드러운 움직임을 줄 수 있습니다. 하지만 더 복잡하고 멋진 움직임을 위해서는 많은 속성들을 이해하고 응용할 수 있어야 합니다. 하지만 모든 속성을 다 알아볼 수는 없으므로 가장 중요한 3가지를 알아보도록 하겠습니다. 미리 살펴본 transition과 transform, keyframe(s) 입니다.1. transition위에서 살펴본 것처럼 대상의 위치, 크기, 색상 등에 부드러운 움직임을 줍니다.2. transform대상의 위치, 크기, 방향 등을 상대적으로 변경합니다. 예제를 통해 알아보겠습니다.<iframe data-width="800" data-height="600" width="700" height="525" data-src="/media/43617ca3eab01b6f86f50b25a362c5a1?postId=e5bb1630afb5" data-media-id="43617ca3eab01b6f86f50b25a362c5a1" data-thumbnail="https://i.embed.ly/1/image?url=https://s3-us-west-2.amazonaws.com/i.cdpn.io/1370087.BZErpP.small.5ebe332d-41b1-4a16-8253-6e2df7b347d0.png&key=a19fcc184b9711e1b4764040d3dc5c07" class="progressiveMedia-iframe js-progressiveMedia-iframe" allowfullscreen="" frameborder="0" src="https://blog.stibee.com/media/43617ca3eab01b6f86f50b25a362c5a1?postId=e5bb1630afb5" style="display: block; position: absolute; margin: auto; max-width: 100%; box-sizing: border-box; transform: translateZ(0px); top: 0px; left: 0px; width: 700px; height: 525px;">2.1. rotate대상에 각도 값을 설정합니다. 즉, 주어진 값만큼 회전합니다. 첫 번째 예제와 조금 다른 부분은 :hover { }에 작성된 내용입니다. transform:rotate(360deg)에서 rotate는 회전을 뜻하고, 360deg는 각도입니다. 즉, 360도(한 바퀴)만큼 회전하라는 의미입니다. 미리 transition이 걸려있었기 때문에 부드럽게 회전하는 모습을 볼 수 있습니다.2.2. translate대상의 이동 값을 설정합니다. 주어진 값만큼 이동합니다. 값은 좌푯값으로 x축, y축 값을 나눠서 줍니다. transform: translate(100px, 100px)에서 translate는 이동을 뜻하고, 이후에 나오는 값은 순서대로 x축의 이동값, y축의 이동 값입니다. 그런데 y축 이동 값이면 위로 올라가야 할 것 같은데, 그림은 아래로 이동합니다. 그 이유는 스크린에서 좌측 위가 기준점이기 때문입니다.2.3. scale대상의 크기를 설정합니다. 즉, 주어진 값만큼 늘어나거나 줄어듭니다. 값은 가로 값, 세로 값을 차례로 줍니다. transform:scale(1.5, 2)에서 scale은 크기를 뜻하고, 1.5와 2는 각각 가로값, 세로값을 뜻합니다. 가로는 1.5배가 늘어나고 세로는 2배가 늘어납니다. 그래서 그림은 세로로 긴 비율로 보입니다.이제 우리는 css만으로 대상의 위치, 크기, 회전 애니메이션을 줄 수 있습니다 :)3. keyframes마우스 오버 액션에 대한 애니메이션을 보아왔습니다. 이렇게 사용자의 특정 반응(마우스 오버)이 없어도 자동으로 움직이도록 할 수는 없을까요? 앞의 두 예제보다 조금 복잡하지만 keyframes를 사용하면 가능합니다. keyframes는 미리 움직임을 지정해두고, 대상에 해당 애니메이션의 속성을 부여하는 방식으로 작성됩니다. 예제를 확인해 보겠습니다.<iframe data-width="800" data-height="600" width="700" height="525" data-src="/media/fc6ef62f3a79def6442479e60dcba75d?postId=e5bb1630afb5" data-media-id="fc6ef62f3a79def6442479e60dcba75d" data-thumbnail="https://i.embed.ly/1/image?url=https://s3-us-west-2.amazonaws.com/i.cdpn.io/1370087.vZMRdd.small.22bea369-dda5-4454-9f16-f5ad68f9b292.png&key=a19fcc184b9711e1b4764040d3dc5c07" class="progressiveMedia-iframe js-progressiveMedia-iframe" allowfullscreen="" frameborder="0" src="https://blog.stibee.com/media/fc6ef62f3a79def6442479e60dcba75d?postId=e5bb1630afb5" style="display: block; position: absolute; margin: auto; max-width: 100%; box-sizing: border-box; transform: translateZ(0px); top: 0px; left: 0px; width: 700px; height: 525px;">3.1. spin앞서 살펴 본 transform의 rotate를 미리 애니메이션을 만들어 놓고 대상에 animation이라는 속성을 설정했습니다.@keyframes spin 처름 spin이라는 애니메이션을 설정합니다. 그 안에는 from과 to가 있는데 각각 시작과 끝을 뜻합니다. 즉, 시작할 때는 회전이 0(rotate(0deg))이고 끝날 때는 회전이 360도(rotate(360deg))입니다.대상과 keyframes를 연결할 때는 대상에 animation: spin 8s infinite linear;와같이 애니메이션 속성을 줍니다. spin은 keyframes의 이름, 8s는 8초 동안, infinite는 무한 반복을 뜻합니다. 여기서 linear는 easing을 나타내는데, 우선은 조금 딱딱한 애니메이션이라고 해둡시다.3.2. leftAndRighttransform의 translate를 활용해서 우측으로 이동했다 돌아오는 애니메이션을 반복시키는 예제입니다. from과 to대신 조금 상세한 타임라인을 가지고 있습니다. 0%, 50%, 100%는 타임라인을 구성하는 속성들로 전체 애니메이션 시간 동안 해당하는 타이밍에 맞게 속성이 변경됩니다. 역시 infinite 속성이 있어 계속 반복되고 있습니다. 그리고 마지막에 linear대신 ease라는 속성을 넣어서 조금 부드러운 움직임 표현했습니다.3.3. hideAndShow앞서 다루지 않은 opacity(투명도)를 활용했습니다. 1이 100%이고 0은 보이지 않는 상태입니다. 1 → 0 → 1을 반복하며 보였다 안 보였다 하는 애니메이션을 보여줍니다.이제 우리는 css만으로 대상의 위치, 크기, 회전 애니메이션 반복적으로 사용할 수 있게 되었습니다. 그리고 무한 반복 애니메이션도 만들 수 있습니다.마무리 예제<iframe data-width="800" data-height="600" width="700" height="525" data-src="/media/f95d4317209e7a3488242568bbdcd5a3?postId=e5bb1630afb5" data-media-id="f95d4317209e7a3488242568bbdcd5a3" data-thumbnail="https://i.embed.ly/1/image?url=https://s3-us-west-2.amazonaws.com/i.cdpn.io/1370087.OgeMEY.small.ab075079-b3bb-443e-a11e-d707c5a6a198.png&key=a19fcc184b9711e1b4764040d3dc5c07" class="progressiveMedia-iframe js-progressiveMedia-iframe" allowfullscreen="" frameborder="0" src="https://blog.stibee.com/media/f95d4317209e7a3488242568bbdcd5a3?postId=e5bb1630afb5" style="display: block; position: absolute; margin: auto; max-width: 100%; box-sizing: border-box; transform: translateZ(0px); top: 0px; left: 0px; width: 700px; height: 525px;">앞서 살펴본 예제들을 활용한 마무리 예제를 만들어 보았습니다. 앞서 공부한 내용을 바탕으로 소스를 분석해 보시기 바랍니다. 각 버튼에는 transiton으로 부드러운 hover 전환 효과를 주었고, 녹색의 메시지는 keyframes를 주어 상하로 계속 움직이도록 했습니다. frame에 마우스가 올라가면 메시지는 프레임 바깥으로 밀려나고 사용자 메뉴가 프레임 안으로 이동하도록 했습니다. 메뉴는 하위 메뉴가 펼쳐지는 인터렉션을 가지고 있습니다.마치며전문 프로토타이핑 도구보다 결과물이 투박하고, 지금 당장 만들 수 있는 장면도 제한적입니다. 자바스크립트 같은 동적 언어가 들어가 있지 않아 표현할 수 있는 화면도 많지 않습니다. 기본적으로 제공되는 템플릿이나 자원이 없으므로 하나하나 html로 코딩하거나 공개 소스를 넣어가면서 만들어야 하는 수고로움도 존재합니다.하지만 실행만 해도 막막한 도구들을 바라보며 “언제 한 번 해보나”하는 생각을 할 시간에 간단히 익혀 한 번이라도 써먹을 수 있다면 그 자체로 의미가 있지 않을까요? 물론 탄탄한 시나리오와 설계를 가지고, 제대로 만든다면 전문 프로토타이핑 도구보다 절대 뒤쳐지지 않을 것입니다. 그리고 우리가 만든 코드들은 커뮤니케이션을 위한 전달용이 아니고 실제로 쓰일 수도 있는 코드라는 점에서도 의미가 있습니다. 간단한 프로토타이핑이라도 지금 시작해 보면 어떨까요?참고https://www.w3schools.com/css/css3_animations.aspttps://www.w3schools.com/css/css3_transitions.asphttps://www.w3schools.com/css/css3_2dtransforms.asphttp://report.stibee.com/2017 by 조은지 디자이너#슬로워크 #스티비 #CSS #퍼블리셔 #개발 #디자인 #인사이트 #꿀팁 #조언
조회수 2664

[인공지능 in IT] 네가 내 마음을 알아?

지난 2018년 3월, 고용노동부는 10월부터 발효되는 '감정노동자 보호법 개정안'을 통과시켰다. 해당 개정안은 고객의 폭언이나 폭력으로부터 스트레스를 받는 감정노동자의 인권과 업무의 질을 개선시킬 사업주 조치를 의무화하는 내용을 담고 있다. 감정노동이란, 고객을 응대하며 자신의 본래 감정과는 상관없이, 업무상 정해진 감정 표현을 연기하는 것을 일상적으로 수행하는 노동을 말한다. 예로 콜센터, 백화점 안내, 텔레마케터 등이 있다.< 감정노동자 보호를 위한 5개 금융업법 개정안 주요 내용, 출처: 동아닷컴 >이제 정부는 감정노동자의 '적응 장애'와 '우울증' 등을 업무상 질병으로 인정한다. 세계보건기구(WHO)에서 정의한 건강은 '육체적, 정신적, 사회적, 영적으로 안녕한 상태'다. 즉, 감정노동자들은 육체뿐만 아니라 정신적, 사회적으로 고통받을 수 있다는 것이다. 그들은 자동으로 저장된 말을 내뱉는 음성 안내기가 아니고, 일반 사람들처럼 똑같이 울고 웃는 사람이다. 그렇지만, 아직까지 국내에서 심리상담에 대한 정서적인 장벽은 높고, 상담 받을 수 있는 인프라도 잘 갖춰지지 않다. 감정노동자들이 실질적인 상담 도움을 받기는 어렵다는 의미다.감정노동 소식 뒤, 국내 인공지능 기술 업체 중 한 곳이 심리상담 서비스를 출시했다는 기사를 접했다. 전문 심리 상담사들이 축적한 수많은 상담 시나리오 데이터를 수집하고 구축해, 개별적이고 정확한 서비스를 제공한다는 것이 취지다. 또한, 통화 목소리를 기반으로 이를 감정 데이터로 변환시켜 정신 건강에 대한 정보와 스트레스 관리 등을 위한 맞춤형 콘텐츠를 제공하는 것이 목적이다. 정확도는 알 수 없지만, 인공지능이 인간의 감정을 인지하고 생활에 도움을 줄 수 있다는 사실만으로도 큰 의미가 있다고 생각한다.사실 필자는 몇 년 전까지 매 순간 변하는 복잡한 인간의 감정은, 인간 고유의 것이라고 생각했다. 인간은 자신의 감정을 알지 못할 때도 있고, 긍정적인 감정과 부정적인 감정을 주체하지 못하기도 한다. 아직 우리 스스로 감정에 대해 확실하게 정의할 수 없고, 통제할 수 없다. 하지만, 그럼에도 불구하고, (앞서 언급한) 심리상담 서비스처럼 여러 분야에서 기계가 인간의 감정을 이해하고, 심지어 감정 표현을 돕는 연구는 거듭되고 있다.기계와 감정의 접목은 2000년대 이전부터 시작되었다. 1995년 MIT의 피카드(Rosalind Picard) 박사가 처음으로 감성컴퓨팅이라는 용어를 사용하며, 인간의 감성을 분석하고 해석하는 기술 개발을 시작했다. 감성 컴퓨팅은 인간이 느끼는 바를 인지, 해석, 처리할 수 있는 시스템을 설계하기 위한 인공지능 기술을 연구하고 개발하는 분야다. 감정 인식은 상상 이상으로 복잡하고, 아직까지 정확하게 구현하기 힘든 어려운 기술이지만, 조금씩 그 영역을 확장하며 다양한 분야에서 사용되고 있다.아무래도 사람의 감정을 드러내는 표면적인 수단 중 가장 눈에 띄는 것이 표정일 것이다. 얼굴에 드러나는 인간의 감정은 안면 근육의 움직임을 통해 여러 표정으로 나타나기 때문이다. 여기에 영상 처리 기술을 활용하면, 기계가 인간의 감정을 분류할 수 있다. 이를 기반으로 한 감정인식은 다음의 과정으로 이루어진다.먼저 영상이나 이미지 안에서 얼굴 영역을 찾는다. 일반적으로 스마트폰 카메라 앱에서 많이 볼 수 있듯, 네모 박스 형태로 얼굴을 인식한다. 그리고 해당 박스 안에서 눈, 코, 입 등 랜드마크라고 불리는 특징점들을 찾는다. 이어서 각 특징점을 바탕으로 각각의 위치나 배치를 파악하는 프로세스를 거친다. 마지막으로 학습을 거쳐 사람의 표정을 인식할 수 있다.일반적으로 감정 쪽을 연구하고 기술을 개발하는 업체 대다수는 이러한 딥러닝 방식을 적용한다. 그리고 미리 지정한 각각의 감정 메트릭에 사용자의 표정을 맵핑하는 식으로 결과값을 도출한다. 하나 주의해야 할 점은 표정과 비교하는 감정이라는 결과값을 '확률(%)'로 산출한다. 예를 들어, 눈썹을 찌푸리고 눈이 커지면서 입을 벌리고 있으면, 감정은 '화남 95%, 놀람 20%, 슬픔 5%...' 등으로 표현하는 방식이다.< EMOTION>이외에도 톤, 크기, 템포 등 감정 변화에 따라 변하는 목소리를 분석하는 음성 인식 기술이나 몸의 특정 움직임을 분석해 감정 상태를 인지하는 동작 인식 기술 등이 있다. 특히, 음성 인식은 CS(고객 응대) 영역에서 빛을 발할 수 있다. 실시간으로 고객의 감정을 분석해 소통방식을 바꾸거나, 그들의 구매 패턴을 예측하는 데 도움을 준다.최근에는 페퍼를 비롯한 가정용 휴머노이드 로봇이 여럿 출시되면서, 감정인식 기술의 적용사례를 쉽게 찾아볼 수 있다. 이들 로봇들은 인간과 대화할 때 억양이나 표정을 인식하며, 심지어 때로는 인간의 감정을 예측하고 묻기도 한다. 물론, 아직까지 우리의 머리 속에는 기계라는 생각 때문에 상호간 자연스러운 대화나 감정을 전달하기 어렵다. 하지만 문자, 음성, 시각 등 현재도 여러 영역에서 인공지능 기술은 발전을 거듭하고 있다.< 핸슨로보틱스(hansonrobotics)의 휴머노이드 로봇 소피아(Sopjia), 출처: 핸슨로보틱스 >인간의 감정이라는 것은 하나의 영적인 매개체가 아닌, 복합적인 것이다. 결국 각 영역별 인공지능 기술이 고도화될수록 감정 인식에 적용할 수 있는 기술 또한 정교해진다는 것을 의미한다. 언젠가는 기계가 인간의 말상대가 되어주고, 함께 어려운 문제에 대해 의논할 수 있는 단계까지 이르지 않을까? 감정 노동자의 마음을 어르고 달래는 로봇이 등장할지도 모를 일이다.이호진, 스켈터랩스 마케팅 매니저조원규 전 구글코리아 R&D총괄 사장을 주축으로 구글, 삼성, 카이스트 AI 랩 출신들로 구성된 인공지능 기술 기업 스켈터랩스에서 마케팅을 담당하고 있다#스켈터랩스 #기업문화 #인사이트 #경험공유 #조직문화 #인공지능기업 #기술기업
조회수 1687

Android 의 Sqlite Tip

Android 와 SqliteAndroid 에서 Sqlite 는 오랫동안 사용되어 왔습니다. 지금은 Realm 과 그외의 데이터베이스들이 그 위치를 넘보고 있지만 여전히 사용되고 있음은 틀림없습니다.현재 Jandi 는 서버의 대다수 정보를 앱의 Sqlite-Database 에 Cache 를 하고 있습니다. 따라서 Sqlite 를 얼마나 잘 분리하고 제어하느냐가 앱 자체의 라이프사이클에 큰 영향을 미칩니다.오늘은 Android 팀이 Sqlite 를 어떻게 사용하는지 공유해드리고자 합니다.1. ORM안드로이드만 하신 분들에게는 다소 생소한 개념일 수 있지만 다른 분야에서는 널리 사용되고 있습니다.Android 에서 Sqlite 는 Database 용 Access 객체를 통해서 column/row 단위로 정보를 가져와서 객체를 완성합니다. 하지만 Access 객체에 일일이 Query 를 작성하는 것은 실수가 많을 뿐더러 column/row 단위 정보 매핑 작업은 매우 불편하고 지루하며 잠재적 버그를 내포한 작업니다.그러기 때문에 Object-Query-Databse 를 각각에 맞게 매핑해주는 라이브러리들 통해 단순하고 반복적인 작업을 간단하게 회피할 수 있습니다.아래의 블로그들이 Sqlite-Orm 라이브러리를 사용하는 좋은 정보들이 될 것입니다. 현재 Jandi-Android 의 주요 Orm 라이브러리는 OrmLite 입니다.Sqlite-Orm : 네이버 기술블로그GreenDao BenchmarkRealm Database2. Database-Access유사 관심사 Domain 끼리 묶음수많은 데이터를 테이블로 관리하다보면 많은 Database-Access-Object(DAO) 가 필요합니다. 하지만 자세히 들여다보면 관계된 것끼리의 묶음이 생기게 되며 이를 묶어서 하나의 Access 객체를 만들 수 있습니다.Jandi 의 메시지는 크게 Text, File, Sticker 로 구분되어 있으며 이에 대한 상위로 Message 라는 개념이 있습니다. Text, File, Sticker 는 하위에 각각 2~3개의 Table 로 구성되어 있습니다. 이 전체를 각각 분리해서 관리하면 그에 따른 부수적인 제어 코드들이 불가피 하기 때문에 Jandi 에서는 최상위 Message 도메인에 맞춰서 하나의 묶음으로 관리하였습니다.코드는 다음과 같은 형태를 띄고 있습니다.public class MessageRepository { public List getMessages(/*args...*/) { /*코드 생략*/}; public Message save(/*args...*/) { /*코드 생략*/}; public Message update(/*args...*/) { /*코드 생략*/}; public Text getText(/*args...*/) { /*코드 생략*/}; /*이하 생략*/ } 이러한 형태로 독립성을 가질 수 있는 최상위 Domain 을 기준으로 Repository 클래스를 가지고 있습니다.3. Repository 요청 관리하기위의 모습처럼 관심사별로 Domain 을 분리한 이유 중 가장 큰 이유는 Domain 단위로 요청을 관리하기 위함입니다.Android-Sqlite 는 내부적으로 Read-Write lock 을 가지고 있지만 신뢰도가 높다 할 수 없으며 다양한 테이블에 동시 접근하는 경우 오류가 나지 않을 것이라 보장할 수 없습니다.따라서 보장이 안될바에 1번에 1개의 요청만 처리 할 수 있도록 Domain 단위로 요청을 제한해버리자는 결론을 냈습니다.그러기 위해 2가지 코드를 사용하였습니다.Lock 객체 사용요청을 래핑할 template interface 사용하기멀티 쓰레드로 요청을 처리할 때 Lock 객체를 통해 1번의 1개씩의 동작만 할 수 있도록 하였으며 이를 좀 더 쉽게 쓸 수 있도록 하기 위해 Template Interface 를 만들었습니다.public class LockTemplate { private Lock executorLock; LockTemplate() { executorLock = new ReentranceLock(); } protected T execute(Executable e) { executorLock.lock(); try { return e.execute(); } finally { executorLock.unlock(); } } interface Executable { T execute(); } } 위와 같은 클래스를 만들고 앞서 만든 Repository 클래스에 상속받도록 하였습니다.코드는 다음과 같습니다.public class MessageRepository extends LockTemplate { /*싱글톤으로 동작하도록 합니다. 코드 생략*/ public List getMessages(long roomId) { return execute(() -> { return dao.query(roomId); }); } public int save(List messages) { return execute(() -> { return dao.save(messages); }); } } 위와 같이 함으로써 최종적으로 같은 Repository 에 멀티쓰레드에서 요청을 하여도 1개의 처리만 할 수 있도록 원천적으로 작업하였습니다.정리Android 에서 Sqlite 는 Mysql 이나 PostSQL 과 유사한 RDBMS 를 제공하는 DB 툴입니다. 하지만 기본적인 사용이 매우 번거러울 뿐만 아니라 메모리릭과 오류에 매우 쉽게 노출됩니다. 그래서 다음과 같은 방법을 통해 최소한의 안전망을 구현했습니다.ORM 을 사용하라.반복적이고 DB 접근 과정에서 오류를 최소화 시켜줍니다.Lock 을 의도적으로 사용하라.멀티쓰레드 접근에 의한 오류를 최소화 합니다.synchroized 보다는 concurrent 패키지에서 제공해주는 Lock 을 사용해주세요.#토스랩 #잔디 #JANDI #개발 #앱개발 #인사이트
조회수 2322

JIRA하고 자빠졌네!?

Overview“JIRA하고, 자빠졌네!” 세종대왕은 확실히 개발자의 두뇌를 가지고 있었던 게 분명합니다. 먼 시대를 지나 오늘날 QA를 하는 저에게 응원을 해주시니 말입니다. 하지만 그는 틀렸습니다. 걱정과는 다르게 다행히 자빠지진 않았거든요. 지라(JIRA) 덕분입니다.갑자기 지라 이야기가 나와 당황하셨죠? 축하해주세요. 드디어 브랜디도 지라를 사용하게 되었답니다. (짝짝짝!) 지라 도입은 처음이라 세팅부터 쉽지 않았는데요. 이번 글은 눈물겨웠던 지라 세팅 과정과 브랜디의 이슈관리를 소개하겠습니다. 스크럼을 쓰면 좋은 점스크럼(Scrum)은 요구 사항 분석부터 하는 칸반(Kanban)보다 효율적입니다. 안드로이드와 iOS로도 나눠져 있고 업무를 짧게 반복하기 때문이죠. 스크럼에 적합한 워크플로우(Workflow)를 볼까요? 이것은 실제로 브랜디 R&D본부에서 사용하고 있기도 합니다. 스크럼에 적합한 워크플로우IN PROGRESS: 이슈나 개발 요건을 티켓으로 만들면 IN PROGRESS 상태가 됩니다. RESOLVED: 이슈나 개발 요건이 완료되면 RESOLVED 상태로 변경합니다.QA: QA가 필요한 개발 요건은 QA상태로 변경합니다.PASS: 이슈 또는 개발 요건이 수정되었거나 문제가 없다면 PASS 상태로 변경합니다.FAIL: 이슈 또는 개발 요건이 제대로 수정되지 않았거나 다른 이슈가 발생하면 FAIL 상태로 변경합니다.QA불필요: QA가 필요하지 않은 개발 요건은 QA불필요 상태로 변경합니다.DONE: 이슈를 해결했거나 개발을 완료하면 DONE 상태로 변경합니다CLOSE: 담당 팀장님이 이슈 확인 후 CLOSE 처리합니다. 예를 들어보겠습니다. 킥오프 서비스 회의를 하고, SB를 제작, 리뷰합니다. 이후에 디자인팀과 개발팀 일정을 공유하고 스크럼 마스터는 스프린트 주기를 책정하죠. 스프린트가 시작되면 개발자는 스토리 티켓을 작성하는데요. 개발이 끝나면 QA가 필요한 티켓은 테스트를 진행하고, QA가 종료되면 스프린트도 종료됩니다.Epic 티켓위의 이미지는 Epic 티켓입니다. Android, iOS, 이슈 등 모든 티켓은 Epic 안에서 관리합니다. 한 곳에서 한꺼번에 관리하기 때문에 히스토리 관리가 편하고, 진행 상황도 확인할 수 있습니다.티켓 생성개발팀의 티켓 생성입니다. 개발자는 SB를 보고 개발 티켓을 작성합니다. 개발 티켓 작성 후에 개발이 진행되며 QA 판단 여부를 체크해 QA 상태로 변경합니다. 변경된 티켓에 관한 QA가 진행되며 문제가 없으면 해당 티켓은 종료됩니다.이슈 생성다음은 이슈 생성입니다. 파악한 SB는 디자인 시안과 비교하며 개발이 된 Android, iOS 테스트 파일을 QA합니다. QA를 진행할 때 발생한 이슈는 지라 티켓으로 등록하여 이슈를 관리합니다. 모든 이슈 티켓 종료되면 해당 차수의 QA는 끝나고 마침내 상용에 배포합니다. 배포가 완료되면 필수 및 크리티컬 리그레이션 테스트가 진행됩니다. Conclusion실수는 항상 모든 것이 끝난 이후에 보이기 마련입니다. 수십 번 QA를 해도 보이지 않던 문제들이 상용에 올라간 이후부터 보이기 시작하죠. 스크럼은 이런 실수들을 가장 최소화할 수 있는 툴이 아닐까 생각합니다. 물론 아무리 좋은 툴을 써도 팀원들과 함께 뭉치는 것보다 중요한 것은 없겠죠. 다음 글은 자동화를 주제로 찾아뵙겠습니다. JIRA하고 자빠지지 않는 개발자가 됩시다!글김치영 대리 | R&D PM팀[email protected]브랜디, 오직 예쁜 옷만#브랜디 #개발자 #개발팀 #인사이트 #경험공유 #JIRA
조회수 3690

Node 서버로 Slack 메신저 자동화하기

Overview백엔드 업무를 하면 데이터 요청과 CS문의를 자주 받습니다. 날짜만 다를 뿐 같은 유형의 문의가 대부분이죠. 결국 반복적인 업무를 효율적으로 처리할 수 있는 방법을 고민했고, 사내 메신저로 사용하는 Slack의 몇 가지 API를 사용하기로 했습니다.1. 알림봇 만들기비즈니스 로직을 만들다 보면 정해진 시간에 맞춰 작업을 해야 하는 경우가 발생합니다. Slack 메신저에 로그온한 상태에서 스케줄러를 이용해 지정한 시간에 Slack 메세지를 전송해보겠습니다.1)Slack API 유저토큰 받기Slack API에 사용할 해당 계정의 토큰을 받아야 합니다. Slack 가입 절차 및 채널 생성은 생략하겠습니다.https://api.slack.com/custom-integrations/legacy-tokens 접속합니다.Legacy tokens 메뉴에서 아래로 스크롤을 내려 토큰 생성버튼을 누릅니다.계정 패스워드를 입력하여 확인하면 토큰을 생성할 수 있습니다.생성된 토큰을 복사하여 저장합니다.2)Node.js를 이용한 알림봇 구현2-1.Node.js 설치Node.js 다운로드 해당 사이트에서 운영체제 환경에 맞는 파일을 다운받아 설치2-2.프로젝트 생성해당 프로젝트 폴더로 이동 후 명령어 실행$ npm init --yes // package.json 파일 생성2-3.Slack 연동2-3-1. slack-node 모듈 설치$ npm install slack-node --save2-3-2. 유저토큰을 이용하여 해당채널에 메세지 전송const Slack = require('slack-node'); // 슬랙 모듈 사용 apiToken = "발급받은 유저토큰"; const slack = new Slack(apiToken); const send = async(message) => { slack.api('chat.postMessage', { username: 'dev-test', // 슬랙에 표시될 봇이름 text:message, channel:'#general' // 전송될 채널 및 유저 }, function(err, response){ console.log(response); }); } send('메세지 내용'); 지정한 채널에 메시지가 발송됩니다. 하지만 이와 같은 방법은 유저 토큰이 공개 코드에 노출되기 때문에 보안이 취약할 수 있습니다. 유저 토큰이 필요 없어도 해당 채널에 URL을 생성하는 WebHooks API를 이용하여 메시지를 전송해보겠습니다.3) Incoming WebHooks APIWebHooks는 유저 토큰 대신 Webhook URL을 생성해 HTTP 통신으로 Slack 메세지를 전송할 수 있습니다. 다양한 메시지 형식을 지원하고 게시할 사용자 이름 및 아이콘 등을 통합적으로 관리할 수 있는 장점을 가지고 있습니다.3-2. Webhook URL 생성하기Slack 해당채널에서 Add an app 클릭검색필터에 WebHooks 검색Incoming WebHooks 추가채널 선택 후 Incoming WebHooks 생성생성된 Webhook URL 복사하여 저장해당채널에 생성되었는지 확인봇이름 및 아이콘등 기본 설정 변경하여 저장curl 사용 예제$ curl -s -d "payload={'text':'메세지 내용'}" "Webhook URL"Webhook URL 사용 중인 모든 메시지는 통합적으로 기본 설정이 변경된 걸 확인할 수 있습니다.다양한 형식의 메세지를 전송해보겠습니다.const Slack = require('slack-node'); // 슬랙 모듈 사용 const webhookUri = "Webhook URL"; // Webhook URL const slack = new Slack(); slack.setWebhook(webhookUri); const send = async(message) => { slack.webhook({ text:"인터넷 검색 포털 사이트", attachments:[ { fallback:"링크주소: ", pretext:"링크주소: ", color:"#00FFFF", fields:[ { title:"알림", value:"해당링크를 클릭하여 검색해 보세요.", short:false } ] } ] }, function(err, response){ console.log(response); }); } 다양한 형태의 메시지를 전송할 수 있습니다.4) Schedule 연동이제 스케줄러를 이용하여 지정한 시간에 메세지를 전송해보겠습니다.4-1. node-schedule 모듈 설치node-schedule는 Node.js 작업 스케줄러 라이브러리입니다.$ npm install node-schedule --savenode-schedule 코드 작성const schedule = require('node-schedule'); // 스케줄러 모듈 사용 // rule-style 사용 var rule = new schedule.RecurrenceRule(); rule.dayOfWeek = new schedule.Range(3,4); rule.hour = 19; rule.minute = 50; schedule.scheduleJob(rule, function(){ console.log('rule 방식'); }); // cron-style 사용 schedule.scheduleJob('50 19 * * *', function(){ console.log('cron-style 방식'); }); 취향에 맞는 스타일로 사용하면 됩니다.5) 지정 시간에 메세지를 전송하는 알림봇을 작성해보겠습니다.const Slack = require('slack-node'); // 슬랙 모듈 사용 const schedule = require('node-schedule'); // 스케줄러 모듈 사용 const webhookUri = "Webhook URL"; // Webhook URL const slack = new Slack(); slack.setWebhook(webhookUri); const send = async(message) => { slack.webhook({ text:message, attachments:[ { fallback:"구글드라이브: ", pretext:"구글드라이브: ", color:"#00FFFF", fields:[ { title:"[알림]", value:"해당링크로 접속하여 작성해 주세요.", short:false } ] } ] }, function(err, response){ console.log(response); }); } schedule.scheduleJob('5 19 * * *', function(){ send('업무보고 보내셨나요?'); }); 업무보고 시간을 미리 알려주는 알림봇2. 대화봇 만들기업무 문서는 주로 구글 독스와 같은 온라인 문서로 관리하고 있습니다. 하지만 매번 구글 드라이브에서 문서를 찾는 건 정말 귀찮은 일입니다. 번거로운 건 딱 질색입니다. Slack API를 이용해 관련된 키워드를 입력하면 링크 주소를 바로 받을 수 있는 대화봇을 만들어 보겠습니다.1) Slack API Bots 토큰 받기Slack API에 사용될 Bots 토큰을 받아야 합니다.https://{App Name}.slack.com/apps 에 접속합니다.Bots 추가Bots Api 토큰을 복사해 저장합니다.설정한 봇이름으로 Apps 영역에 자동으로 추가됩니다.2) 구글독스 대화봇 코드 작성2-1. botkit 모듈 설치$ npm install botkit --save2-2. 코드 작성const botkit = require('botkit'); // 봇 모듈 사용 const Slack = require('slack-node'); // 슬랙 모듈 사용 const controller = botkit.slackbot({ debug: false, log: true }); const botScope = [ 'direct_message', 'direct_mention', 'mention' ]; controller.hears(['업무보고'], botScope, (bot, message) => { bot.reply(message, '업무보고 링크주소'); }); controller.hears(['가이드', 'guide', '튜토리얼'], botScope, (bot, message) => { bot.reply(message, '가이드 링크주소'); }); controller.hears(['api', '명세서'], botScope, (bot, message) => { bot.reply(message, 'api명세서 링크주소'); }); controller.hears(['일정', '일정관리'], botScope, (bot, message) => { bot.reply(message, '일정관리 링크주소'); }); controller.hears(['비품', '비품정리'], botScope, (bot, message) => { bot.reply(message, '비품관리 링크주소'); }); controller.spawn({ token: '발급받은 봇 토큰' }).startRTM(); 지정한 키워드를 입력하면 해당 링크가 수신 됩니다.3) 데이터문의 대화봇 코드 작성데이터 요청 시 결과 데이터를 보내주는 대화봇을 만들어 보겠습니다. 일단 먼저 데이터문의 전용 Bots을 생성합니다.3-1. Python 연동 요청한 데이터는 Mysql 데이터를 조회해서 전송합니다. 그러면 Mysql 을 연동해야겠죠? Node.js에서도 직접 mysql 연결할 수 있지만, 기존 프로젝트가 Python으로 구현되어 있어 Python을 실행해 필요한 데이터를 추출해보겠습니다.3-2. python-shell 모듈 설치Node.js에서 Python 실행가능하도록 모듈을 설치$ npm install python-shell --save3-3. Mysql Sample Table3-4. 회원테이블에 저장된 가입일시 기준으로 몇일전에 가입한 회원을 추출하여 전송하는 코드 작성해 보겠습니다.const botkit = require('botkit'); // 봇 모듈 사용 const Slack = require('slack-node'); // 슬랙 모듈 사용 const ps = require('python-shell'); // 파이썬 쉘 모듈 사용 // 몇일 전 날짜 구하기 function getDaysAgo(dayNo = 0) { let nowDate = new Date(); let tempDate = nowDate.getTime() - (dayNo * 24 * 60 * 60 * 1000); nowDate.setTime(tempDate); let getYear = nowDate.getFullYear(); let getMonth = nowDate.getMonth() + 1; let getDay = nowDate.getDate(); if (getMonth < 10 xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed> 3-5. Python 코드 작성 # -*- coding: utf-8 -*- import sys import pymysql // mysql 접속 db = pymysql.connect('hostname', user='', passwd='', db='', charset='utf8') cursor_db = db.cursor() exe_query = "SELECT MEMBER_NAME FROM MEMBER_INFO WHERE MEMBER_REGIST_DETE >= '{}' ORDER BY MEMBER_NO ASC ".format(sys.argv[1]) cursor_db.execute(exe_query) all_rows = cursor_db.fetchall() for idx, row in enumerate(all_rows): print(row[0])     지정한 며칠 전에 가입한 회원 이름이 전송됩니다.   로그도 정상적으로 출력됩니다. 3. Node.js 프로세스 관리를 위한 pm2 모듈 설치 Node.js 는 비동기 I/O를 지원하며 단일 스레드로 동작하는 서버입니다. 비동기식 방식이지만 처리하는 Event Loop는 단일 스레드로 이루어져 있어 처리 작업이 오래 걸리면 전체 서버에 영향을 줍니다. 그래서 pm2를 이용해 프로세스별로 상태를 관리해야 합니다. 1) pm2 모듈 설치$ npm install pm2 -g2) 자주사용하는 pm2 명령어 pm2 list -> 실행중인 프로세스 확인pm2 start {node 파일} -> 시작pm2 stop {id or App name} -> 중지pm2 delete {id or App name} -> 삭제pm2 show {id or App name} -> 상세정보pm2 restart {id or App name} -> 재시작pm2 kill -> pm2 종료pm2 logs {id} -> id 앱의 로그 확인 3) pm2 실행화면$ pm2 start bot.js   프로세스별로 앱 이름, 버전, 상태, cpu 및 memory 사용량이 표시됩니다.$ pm2 show 0   해당 프로세스의 상세 정보를 확인할 수 있습니다. Conclusion 지금까지 Node.js 로 유용한 Slack 메신져 API를 알아봤습니다. 반복적인 업무를 하나씩 줄이다 보면 분명 일의 능률을 높아집니다. 하지만 무분별한 자동화는 서버의 부하를 증가시키기 때문에 꼭 필요한지 확인하고 선택하길 바랍니다. 오늘은 여기까지 글곽정섭 과장 | R&D 개발1팀[email protected]브랜디, 오직 예쁜 옷만  
조회수 972

크로키닷컴을 소개합니다 #6

크로키닷컴 6번째 인터뷰!오늘은 지그재그 앱 개발을 담당해주시는 앱 개발자 연미님, 하경님과 함께 현재 채용 중인 [안드로이드/iOS 개발자] 포지션 및 지그재그 앱에 관해 소개해보도록 하겠습니다. :-)Chapter 1. 저를 소개합니다!Q. 연미님, 하경님 안녕하세요! 이번 인터뷰이로 선정되신 소감과 간단한 자기소개 부탁드립니다.하경 저는 입사하기 전에 저희 파트 형준님 인터뷰(3편)를 봤었는데 되게 인상 깊었거든요. 그래서 제가 면접을 볼 때도 그 얘기를 했던 게 엊그제 같은데.. 제가 어느새 인터뷰를 하고 있는 모습을 보니 신기하고 뿌듯하네요. (웃음)연미 저는 앱 개발뿐만 아니라 다른 포지션에 대해 도움이 되는 정보를 드릴 수 있게 돼서 감사하게 생각하고 있습니다. 초대해주셔서 감사해요!하경 저는 iOS 개발을 주로 하고 있는 김하경이라고 합니다. iOS를 하다가 최근에는 조그만 것들부터 안드로이드도 시도해보고 있어요. 이번에 저희 지그재그 결제 서비스인 Z결제 소속으로 들어가게 되었는데요, 커머스 앱의 가장 중요한 기능 중 하나인 리뷰 서비스 개발을 맡게 되었어요. 한동안 굉장히 바쁘게 일하지 않을까 생각합니다.연미 저도 하경님과 같이 앱 개발을 하고 있는 손연미입니다. 저는 지그재그 서비스의 초반부터 안드로이드/iOS 개발을 모두 해왔는데, 요즘은 안드로이드 쪽에 좀 더 집중해서 하고 있어요. 이번에 저는 지그재그 서비스를 폭풍 성장시킬 그로쓰팀의 일원으로 들어가게 되었는데요, 유저의 사용성뿐만 아니라 또 다른 시야에서 서비스의 성장을 같이 일궈낼 예정입니다. (앗, 그러면 하경님이 입사 8개월 만에 연미님의 품을 벗어나게 된 건가요?)하경 네 맞아요. 저희가 이번에 처음으로 떨어지게 되었는데 약간은 두렵네요.연미 혹시 괴롭히는 사람 있으면 말하세요. 제가 혼내줄게요!오늘도 평화로운 지그재그 팀Q. 하경님은 지그재그로 이직을 하고 싶으셨던 이유나 계기가 따로 있으셨나요?하경 저는 예전에 정말 소규모의 스타트업에서 처음 iOS 개발을 시작했었어요. 심지어 같이 일하는 동료도 iOS 개발이 처음이었다 보니 같이 배워가는 입장이라 어려운 점이 많았고, 항상 부족하다는 느낌을 받았어요. 계속 검색에 의존하여 개발을 하다 보니, '더 좋은 코드를 짤 순 없을까?' 하는 욕구가 있었는데 우연히 지그재그의 글을 보게 되었어요. 지그재그 기술 블로그나 브런치 글들을 보면 아시겠지만, 성장이라는 문구가 되게 많이 나오거든요! 그게 저에게 굉장히 매력적이었어요. 채용 공고에도 같이 성장하고 싶은 팀원을 구한다고 적혀있길래 망설임 없이 지원했습니다. 저는 그때도 그렇고 지금도 그렇고 항상 성장하고 싶어요.(실제로 입사하시고 나서 겪어본 지그재그는 어떤가요?)하경 전 직장과 비교했을 때 저에게는 지그재그가 큰 회사로 느껴졌어요. 그러다 보니 왠지 이미 굳어진 정책 안에서 정해져 있는 일만 해야 하지 않을까 하는 개인적인 생각이 있었는데, 실제로 겪어보니 전혀 아니었어요. 매우 빠르게 성장하며 끊임 없이 변하고 있고, 이것 저것 새로운 걸 많이 시도해보는 게 신기했어요. 코드 리뷰도 처음 입사했을 당시에는 모든 코드에 대해 서로 꼼꼼히 리뷰한 후에 배포가 가능해서 그 과정에서 정말 많이 배울 수 있어서 너무 좋았는데, 최근에는 작은 부분에 대해서는 코드 리뷰를 거치지 않고 담당자가 빠르게 배포할 수 있도록 자율성을 부여하고 있어요. 이렇게 자율적으로 맡게 되니, 코드에 대한 책임감이 더 커지고 공부도 더 열심히 하게 되는 것 같아요.Q. 연미님은 지그재그 서비스 초기에 합류해서 지금까지 함께하고 계신데요! 처음 합류하시게 된 계기가 궁금합니다.연미 이전 회사에서는 주로 파견을 나가서 근무한 적이 많았어요. 그러다보니 제가 애정을 담아 지속적으로 키워나갈 수 있는 서비스가 없는 점이 항상 아쉬웠어요. 그래서 그런 서비스를 만들어나가는 사람들을 만나 함께 발전시켜나가고 싶다는 생각을 늘 했었는데, 운이 좋게도 지그재그 팀을 만나게 되었네요.(합류를 결정하실 때, CTO 상민님과 함께 일을 해보고 싶었던 마음도 한 몫(?) 했다고 들었어요!)연미 제 주변에서 상민님은 천재 개발자라고 불렸어요. 그러다 보니 저도 상민님과 함께 일하면서 배우고 싶었고, 같이 파이팅해보고 싶다는 의지가 매우 강했어요. 그렇게 합류한 이후 지금까지 상민님과 함께 개발을 하면서 정말 많이 배웠어요. 그리고 상민님과 저의 커뮤니케이션 스타일이 비슷한 부분이 있는데, 그래서 더 편하게 좋은 팀워크를 유지해올 수 있었던 것 같아요. 둘 다 말수가 적은 편이라 업무에 필요한 말만 간단히 주고 받는 편인데, 그게 오히려 서로에게 편하게 느껴진다는 것? (웃음)천재 개발자 상민님의 기술 블로그 놀러 오세요! https://devblog.croquis.com(하경님께서 이전에 코드 리뷰에 대해 언급해주셨는데요, 연미님은 개발팀의 문화로 자리 잡은 코드 리뷰에 대해 어떻게 생각하시나요?)연미 개발자들에게 코드 리뷰는 책임감이고, 방향성이고, 하나의 커뮤니케이션 방식이라고 생각해요. '우리는 코드로 얘기한다.'고 생각하는 개발자들이 모여있기 때문에, 서로가 어떤 생각을 가지고 코드를 짰는지 공유하고, 미처 발견하지 못한 문제점이 있다면 같이 해결해보고 하는 거죠. 같이 sync를 맞추고 신뢰를 쌓아가는 과정이랄까요? 다른 인터뷰에서도 다른 분들이 말씀하시긴 했지만, 우리 지그재그 팀은 다들 서비스에 대한 애정을 바탕으로 더 나은 서비스를 만들고 싶어하는 사람들이라서 이런 문화를 매우 선호하고 환영합니다!Chapter 2. 업무와 일하는 방식Q. 오늘은 지그재그 팀이 목적 조직으로 대대적인 조직개편을 한 그 첫 날인데요, 이 변화에 대해 두 분이 기대하는 점 또는 걱정되는 점이 있다면요?연미 작년에 인원이 많이 늘었고 회사도 커지면서 각자의 R&R이 명확해지다 보니 '함께 한다'는 느낌이 조금 약하게 느껴졌었어요. 그런데 목적 조직은 모두 하나의 목적을 가지고 으쌰 으쌰 하기 때문에 그렇게 생각을 덜 하게 되지 않을까 싶어요. 다만 조직개편 후에 놓치지 않도록 신경써야 되겠다고 생각하는 부분은 각 프로젝트팀의 목적 범위 외의 부분인 것 같아요. 주요 프로젝트 목적에 너무 치중하다보면 다른 부분에서 소홀해질 수 있기 때문에, 그런 경우가 생기지 않도록 어떻게 대비할 것인지 생각해두면 좋을 것 같아요.하경 우선 업무에 보다 집중을 할 수 있는 환경이 된 것 같아 기대가 됩니다. 그리고 개발자는 개발팀, 디자이너는 디자인팀 이렇게 각자의 팀에서 협업을 진행했었는데, 이제는 같이 한 팀이 되어 하나의 목적을 달성해나가게 되었으니 커뮤니케이션이 훨씬 더 수월해진 것 같기도 하고요. 그리고 그럴 일은 절대 없게끔 할테지만, 각 팀의 목적이 훨씬 뚜렷해진 만큼 만에 하나라도 목적을 달성하지 못하게 된다면 제가 너무 우울해지지 않을까 하는 생각이 들기도 해요. 반드시 달성하고 싶어요!Q. 지그재그 앱의 역사를 함께 해오셨는데, 새로운 기술이 도입될 때마다 적용시키는 과정이 궁금해요. 연미 인원이 늘기 전까지는 새로운 기술들에 대해서 시도를 많이 못해봤던 것 같아요. 1년 전부터 팀원이 늘어나게 되면서는 레거시를 바꾸는 작업을 계속 진행하고 있어요. 서비스 초기에 적용된 기존의 기술들을 계속 사용하기보다는 새로 합류하는 팀원들의 의견을 많이 들어보고 적용하려고 하고요. 예전 버전에서 지속적으로 업그레이드를 하고 있다고 생각해주시면 될 것 같아요.하경 우리 지그재그 팀원분들은 기술 그 자체이신 분들이 굉장히 많거든요. 다른 팀원들이 새로운 기술을 접목해서 우리 서비스에 득이 된다면 새로운 기술은 언제든 배우고 싶어요. 물론 서비스의 안정성이 가장 중요하기 때문에, 접목해보기 전 새로운 기술에 대한 충분한 공부가 선행되어야 하는 건 필수라고 생각해요!(새로운 걸 배운다는 게 쉬운 일은 아닌데요..!)하경 어렵지 않아요. 되려 재밌어요! 새로운 걸 배운다는 게 제가 개발을 하는 데 있어서 활력을 불어넣어주는 거라고 생각하거든요. 기존에 하던 대로만 개발을 해오다 보면 지루해져서, 새로운 걸 시도해보곤 한답니다.연미 학습 속도가 정말 빨라요. 뚝딱 하고 만들어내시거든요.하경 아니에요..(부끄) 재밌어서 하다 보니 그렇게 되었네요.빛의 속도 하경님!Q. 서비스 초기부터 앱 파트를 이끌어오신 연미님! 성과를 이루기 위해 해왔던 업무 방식이나 프로세스가 있다면 어떤 것인가요?연미 저는 업무에 대한 흥미도가 성과 향상에 많은 영향을 미친다고 생각해요. 그래서 태스크의 담당자를 정할 때에는 그 태스크에 관심이 있고 하고 싶어하는 팀원이 있는지를 우선적으로 고려하는 편이에요. 만약 지원자가 없는 업무라면 그땐 팀원들과 이야기를 나누며 팀의 상황에 따라 분배를 하긴 하지만요. (웃음)그리고 2019년 초반에는 앱 파트 팀원이 총 3명이었는데요, 그땐 집중 프로젝트라는 것을 적용해봤어요. 각자 하나의 프로젝트를 맡아서 본인이 주도적으로 타 팀과 커뮤니케이션을 하면서 프로젝트를 완료할 수 있게끔 해본 거였는데, 결론적으로는 팀원 분들이 좋아하셨어요! 책임감도 키울 수 있었고, 비즈니스적인 측면에서도 성장할 수 있었다고 생각해요. 내 프로젝트다!라는 생각이 있다 보니까 아이디어도 내보고, 의견 전달도 많이 하면서 진행될 수 있어 좋았습니다 .하경 집중 프로젝트를 통해 미리 경험을 했어서 그런지 이번에 목적 조직에 들어간 게 어색하지 않은 것 같아요. 이미 그 방식에 적응되어 있는 것 같거든요.Q. 하경님은 작년 제1회 지그재그 배 해커톤에서 1등을 하셨어요! 그때 만드신 프로젝트 '휴가봇'이 회사에서 실제로 활용되고 있는데, 기분이 어떠세요?하경 작년 추석쯤에 해커톤을 했었는데요, 뭘 만들어볼까 하다가 회사 생활하면서 작은 부분이지만 불편하게 느껴졌던 부분을 개선해보고 싶어서 만들게 되었어요. 이름은 달비 휴가봇이고 같은 Dev.팀의 우식님과 만들었는데, 이게 이렇게 큰 영향을 끼치게 될 줄 몰랐어요! 사실 지금도 계속 사용 중이니 계속 기능 업데이트를 위해 공부를 하게 되고요. 그래서 신기하기도 하고 뿌듯하기도 하답니다. 원래 쓰던 기술이 아닌 새로운 기술을 배우면서 만들어봤던 프로젝트라서 더 재밌었고, 만약 개발에 지루함을 느끼신 분이라면 이런 프로젝트도 시도해보시면 좋을 것 같아요.연미 새로운 기술을 쓰다 보면 시야가 넓어지거든요. 정말 추천드리고 싶습니다. 하경 그리고 달비 휴가봇을 같이 만들어주신 우식님께도 감사인사를 전하고 싶습니다. 지금까지도 얼떨결에 같이 개발을 하고 계시거든요..(웃음)Chapter 3. 저희 공고를 소개합니다!Q. 현재 채용 중인 [안드로이드/iOS 개발자] 얘기를 해볼까 해요. 어떤 앱 개발자를 찾고 있는지 말씀해주시겠어요?연미 일단 현재는 경력이 3년 정도는 있으신 분을 찾고 있어요. 아무래도 계속 새로운 작업들이 진행되고 있기도 하고 새로운 기술을 계속 적용하며 함께 업데이트를 해나가실 분을 모시고 있기 때문에 어느 정도의 경력은 있으시면 좋을 것 같아요.그래서 Dev.팀이 이번에 인턴쉽을 진행했을 때에도 앱 개발 분야는 별도로 접수를 받지는 않았는데요, 나중에 기회가 된다면 저희도 인턴이나 신입 개발자분들도 모시고 싶어요!하경 개인적으로 바라는 부분이기도 하지만 서비스에 대한 애정이나 관심이 있으신 분이면 좋겠어요. 저랑 같이 텅장을 만드실 분이랄까요.. (웃음) 장난이고요, 애정과 그 서비스에 쏟는 열정은 비례하다고 생각하거든요.연미 사용자가 지그재그 앱을 어떻게 더 편하게 사용할 수 있을지 같이 고민해주실 분을 찾고 있어요. 그리고 채용 공고 내에 우대사항으로 적힌 부분은 정말 우대사항이기 때문에 해당 기술을 알고 계시면 더욱 좋겠지만 모르셔도 괜찮아요. 들어오셔서 같이 배워나가시는 분들도 많이 계시고, 또 필요하면 팀 내에서 개발 스터디를 직접 오픈하실 수도 있고 이미 활발하게 진행중인 스터디에 참여하실 수도 있으니까요.하경 아! 그리고 서로에게 동기부여가 될 수 있는 팀원분을 모시고 싶어요. 앞에서 말씀 드렸던 코드 리뷰 같은 경우에도 서로 코드를 공유 하면서 모르는 기술도 알 수 있게 되고, 몰랐던 문제점을 알아갈 수 있으니 각자의 발전에도 도움이 되거든요! 저희 팀에서 자체적으로 OOP스터디도 진행했었는데, 같이 배우고 공유하면서 회사와 개인의 발전에 목표를 가지실 분이었으면 좋겠어요!Q. 지그재그의 예비 지원자에게 전하는 메시지!연미 지그재그 팀은 사업적인 측면에서도 그렇고, 기술적인 측면에서도 성장 가능성이 무한해요. 아무래도 새로운 시도를 할 때 오픈 마인드이기 때문이지 않을까 싶은데요, 팀원의 성장을 위해서 적극적으로 지원을 해주기 때문에 회사와 함께 발전하고 싶으신 분들은 맘껏 지원해주셨으면 좋겠어요.하경 주저하지 마시고 지원해주셨으면 좋겠어요! 전 개인적으로 빠르게 성장하고 있는 회사에서 일하다 보니 제 자신이 능동적이고 주도적으로 변해가는 걸 느꼈는데요, 그게 되게 회사에서 재밌게 일할 수 있게 해주는 것 같아요.Chapter 4. 마무리Q. 2020년 두 분의 목표가 있으신가요?하경 2019년에는 개인적으로 이사를 하게 되면서 인테리어에도 관심을 갖게 되었고, 특히 제가 청소에 빠지게 됐어요. 부모님이 보시면 어이없어하시겠지만. (웃음) 다른 것에 좀 더 포커싱이 가있었다 보니 개발 공부를 많이 못했던 것 같아요. 그래서 올해엔 공부를 열심히 할 생각이고, 마인드도 바꿔보려고요! 더 긍정적인 마인드!연미 저도 비슷한데, 개발자로서의 역할을 더 강화하고 싶어요. 저의 테크니컬한 부분을 더 발전시켜보려고요. 개인적인 목표는.. 내 집 장만입니다.하경 그거.. 작년 목표 아니었나요..?(웃음) 저는 건강관리도! 점심마다 샐러드를 먹고 있는데요, 공개적으로 말해두면 더 열심히 지키지 않을까 싶어 추가로 말씀드려봅니다.Q. 다음으로 인터뷰를 진행했으면 하는 팀이 계신가요? 궁금한 팀이 있으면 말씀해주세요!하경 저는 Relations팀이요. 전반적인 채용을 담당해주셔서 그 과정도 궁금하고, 이번에 팀 인원도 두 분 더 합류하셨는데 어떤 변화들이 생겼는지 궁금해요.연미 저는 3PL분들이요! 각자 프로젝트마다 어떤 방식으로 업무를 진행해가실 예정인지, 주간 미팅 때 공유해주시긴 했지만 좀 더 구체적인 가이드라인과 비전이 궁금해요. 이 인터뷰가 성사되고 많은 분들께 읽혀진다면, 각 팀의 목표에 공감하시는 좋은 분들이 많이 합류해주시지 않을까요! (*3PL은 지그재그의 새로운 프로젝트팀 리더 세 분을 의미합니다!)지그재그에서는 안드로이드/iOS 개발자를 포함하여 활발하게 채용을 진행하고 있습니다. 지그재그 팀과 함께, 수면 아래 숨겨진 가치를 찾아내는 경험에 동참할 팀원을 꼭 모시고 싶습니다 :-) 궁금하신 점은 언제나 [email protected] 또는 http://facebook.com/zigzagcareer로 연락 주세요!지그재그 [안드로이드/iOS 개발자] 포지션을 소개합니다!이런 일을 합니다.안드로이드, iOS이런 분을 모십니다.안드로이드iOS이 중 하나라도 가능하시다면 더더욱 좋아요 :)공통안드로이드iOS지원 방법채용 절차혜택과 복지   더 많은 공고는 채용 사이트에서 확인 가능합니다! >>> 채용 사이트 바로가기
조회수 2026

Circle CI에서 rbenv를 이용해서 Ruby 2.2와 CocoaPods 0.39 버전 사용하기

최근 Circle CI에서 Ruby 버전을 2.3으로, CocoaPods 버전을 1.0으로 업그레이드함에 따라 발생하는 빌드 문제를 rbenv를 이용해서 해결한 경험을 공유합니다. 최종적으로 완성된 Gemfile과 circle.yml 파일은 마지막 섹션에서 확인하실 수 있습니다.1. CocoaPods 1.0지난 2015년 12월에 CocoaPods 1.0.0 베타 버전이 처음 공개되었습니다. CocoaPods이 1.0 버전으로 업그레이드되면서 굉장히 많은 변화가 있었는데요. 가장 큰 변화는 DSL입니다. 추상 타겟Abstract Target과 타겟 상속Target Inheritance이 새롭게 소개되면서, 0.39 버전까지 자주 사용되던 link_with 및 :exclusive => true와 같은 구문이 제거되었습니다.이에 따라 기존에 사용하던 Podfile이 CocoaPods 1.0 버전과는 호환되지 않는 문제가 발생했습니다. 이를 해결하기 위한 가장 좋은 방법은 새로운 DSL을 사용하여 Podfile을 다시 작성하는 것이지만, 꽤 많은 서드파티 라이브러리를 사용하는 StyleShare의 경우 새로운 DSL을 적용하여 빌드하면 각종 문제로 인해 빌드가 정상적으로 이루어지지 않았습니다. 4년동안 유지되고 있는 프로젝트이다보니, 레거시 Objective-C 코드와 라이브러리, 그리고 새로운 Swift 코드와 라이브러리가 혼용되어 사용되는 것도 원인 중 하나일 것입니다.따라서 StyleShare에서는 CocoaPods 0.39 버전을 사용하기로 결정을 했습니다. 하지만 최근 Circle CI에서 CocoaPods 버전을 공식적으로 1.0 버전으로 업그레이드하면서 빌드가 깨지기 시작했습니다. Circle CI 환경에서 CocoaPods 0.39 버전을 사용하려면 어떻게 해야 할까요?▲ ㅠㅠ2. Bundler를 이용해서 Gem 관리하기Bundler는 Ruby로 작성된 라이브러리들의 버전을 관리해주는 강력한 도구입니다. CocoaPods에서 Podfile에 의존성을 기재하듯, Bundler에서는 Gemfile에 의존성을 기재합니다.source 'https://rubygems.org' gem 'cocoapods', '~> 0.39' $ gem install bundler 명령어를 사용하면 Gemfile에 기재된 의존성 라이브러리들을 설치해줍니다. 이렇게 설치된 CocoaPods을 사용할 때에는 $ pod COMMAND 대신 $ bundle exec pod COMMAND 명령어를 사용해야 합니다.$ gem install bundler $ bundle install --path vendor/bundle $ bundle exec pod --version 0.39.0 3. Ruby 2.3과 CocoaPods 0.39Bundler를 사용해서 CocoaPods 0.39 버전을 사용하기만 하면 모든 문제가 해결될 줄 알았습니다. 하지만 더 큰 삽질이 남아있었는데요. 바로 Ruby 2.3 버전이 CocoaPods 0.39 버전과 호환되지 않는 것이었습니다.$ bundle exec pod install Updating local specs repositories Analyzing dependencies 신나게 $ bundle exec pod install 명령어를 실행하니, 의존성을 분석하는 듯 싶다가 갑자기 에러를 주르륵 뱉습니다. 에러 로그의 #### Error 항목을 보면 에러 메시지가 나와있습니다.NoMethodError - undefined method `to_ary’ for #이 에러 메시지로 CocoaPods GitHub 저장소의 이슈를 검색해보면 꽤나 많은 이슈가 올라와 있습니다. 이 이슈들을 보면, 모두 Ruby 버전이 2.3이라는 공통점이 있습니다. Ruby 버전을 2.2로 내렸더니 문제가 해결됐다는 댓글들도 굉장히 많고요. Circle CI의 Ruby 버전을 2.2로 낮추면 문제가 해결될 것 같습니다.Circle CI 문서 내용에 따라 circle.yml에 Ruby 버전을 기재해봅시다.machine: ruby: version: 2.2.5 그러나 Circle CI의 OS X 컨테이너에서는 Ruby 버전 변경을 지원하지 않는다고 합니다.▲ ㅠㅠ (2)4. rbenv를 이용해서 Ruby 2.2 사용하기그러다가 알게된 것이 바로 rbenv입니다. rbenv를 사용하면 여러개의 Ruby 버전을 깔끔하게 관리할 수 있게 됩니다. rbenv는 Homebrew를 사용해서 쉽게 설치할 수 있습니다.$ brew install rbenv rbenv는 ~/.rbenv 디렉토리에 안에 여러 Ruby 버전을 설치하고 관리합니다. rbenv를 설치한 뒤 가장 먼저 할 일은 환경변수 $PATH를 설정해주는 것입니다. $PATH에는 $HOME/.rbenv/shims와 $HOME/.rbenv/bin 경로가 포함되어있어야 합니다.4.1 환경변수 설정하기Circle CI에서는 환경변수를 설정하는 편리한 인터페이스를 제공합니다. 하지만, Circle CI에서 실행되는 각 명령어는 별도의 쉘에서 실행됩니다. 그말인 즉슨, 각 명령어가 실행되기 직전에 새로운 쉘이 실행되고, $PATH 환경변수를 덮어쓰는 .bash_profile이 실행된 후 명령어가 실행된다는 뜻인데요. 이렇게 될 경우 $PATH 환경변수의 가장 우선순위는 항상 /usr/local/bin이 가지게 됩니다. 그리고 같은 이유로 $ export FOO=bar와 같은 명령어도 사용할 수 없게 됩니다.1고민을 하다가 생각해낸 방법은 바로 .bash_profile의 내용을 변경(!)하는 것입니다. 그렇게 되면 우리가 원하는 $PATH를 항상 우선순위로 둘 수 있게 됩니다. 아래와 같이 환경변수를 설정하는 명령어를 .bash_profile의 가장 아랫줄에 삽입하도록 설정했습니다.machine: pre: - echo "export PATH=\$HOME/.rbenv/shims:\$HOME/.rbenv/bin:\$PATH" >> .bash_profile - echo "export RBENV_SHELL=bash" >> .bash_profile 4.2 rbenv에 Ruby 2.2 설치하기그 다음으로 할 일은 원하는 Ruby 2.2 버전을 설치하는 것입니다. $ rbenv install -l을 사용해서 설치 가능한 모든 Ruby 버전을 조회할 수 있고, $ rbenv install 2.2.5 명령어를 사용해서 2.2.5 버전을 설치할 수 있습니다.$ rbenv install -l Available versions: 1.8.5-p113 1.8.5-p114 1.8.5-p115 1.8.5-p231 ... $ rbenv install 2.2.5 이렇게 설치된 버전은 두 가지 방법으로 사용될 수 있습니다. 한 가지 방법은 시스템 전체에서 사용하는 것이고, 다른 한 가지 방법은 프로젝트 단위로 사용하는 방법입니다. 시스템 전체에서 사용하려면 $ rbenv global 2.2.5 명령어를, 프로젝트 단위로 사용하려면 $ rbenv local 2.2.5명령어를 사용합니다.global 명령어를 사용해서 Ruby 버전을 선택하면 ~/.rbenv/version 파일에 선택된 버전이 기록됩니다.$ rbenv global 2.2.5 $ cat ~/.rbenv/version 2.2.5 local 명령어를 사용하면 현재 디렉토리의 .ruby-version 파일에 선택된 버전이 기록됩니다.$ rbenv local 2.2.5 $ cat .ruby-version 2.2.5 local 명령어로 선택된 Ruby 버전은 global 명령어로 선택된 Ruby 버전보다 우선순위가 높습니다. $ rbenv version 명령어를 사용하면 현재 선택된 버전을 확인할 수 있습니다.$ rbenv version 2.2.5 (set by /project/path/.ruby-version) Circle CI에서는 편의를 위해 global 명령어를 사용해서 Ruby 버전을 선택하도록 했습니다.dependencies: pre: - brew update - brew install rbenv - rbenv install 2.2.5 - rbenv global 2.2.5 4.3 Bundler 다시 설치하기rbenv를 사용해서 새로운 Ruby 버전을 설치했기 때문에, Circle CI 시스템에서 제공하는 Gem도 다시 설치해야 합니다. 우리는 Bundler로 Gem 의존성을 관리하기로 했으므로, Bundler만 재설치합니다.$ gem install bundler --no-ri --no-rdoc $ rbenv rehash $ gem install 명령어를 실행한 후에는 $ rbenv rehash 명령어를 실행해서 executable 경로들을 재설정해주어야 합니다.4.4 ~/.rbenv 경로 캐싱하기rbenv를 사용해서 Ruby를 설치하는 과정이 굉장히 오래 걸립니다. 이 경우, Circle CI에서 제공하는 캐싱 기능을 사용해서 이 과정을 한 번만 하고 건너뛸수 있게 됩니다.dependencies: cache_directories: - ~/.rbenv 위와 같이 circle.yml를 설정해주면 컨테이너 실행시 ~/.rbenv 디렉토리가 캐시로부터 설정됩니다. 캐싱된 디렉토리를 사용하는 경우 Ruby 버전이 미리 설치되어있기 때문에 $ rbenv install시에 --skip-existing 옵션을 추가해주어서 캐싱된 버전을 재설치하지 않도록 합니다.5. 마치며최종적으로 완성된 Gemfile과 circle.yml 파일은 다음과 같습니다.Gemfilesource 'https://rubygems.org' gem 'cocoapods', '~> 0.39' circle.ymlmachine: pre: - echo "export PATH=\$HOME/.rbenv/shims:\$HOME/.rbenv/bin:\$PATH" >> .bash_profile - echo "export RBENV_SHELL=bash" >> .bash_profile xcode: version: 7.3 dependencies: cache_directories: - ~/.rbenv pre: - brew update - brew install rbenv - rbenv install 2.2.5 --skip-existing - rbenv global 2.2.5 - gem install bundler --no-ri --no-rdoc - rbenv rehash - bundle install --path vendor/bundle override: - bundle exec pod --version - bundle exec pod install https://circleci.com/docs/environment-variables/#custom ↩#스타일쉐어 #개발 #개발자 #개발팀 #후기 #일지 #인사이트
조회수 2520

AWS 서비스를 활용한 Kubernetes 클러스터 구축 - VCNC Engineering Blog

Kubernetes 클러스터를 상용 환경에서 운영하기 위해서는 몇 가지 추가 구성요소를 설치해야 합니다. 예를 들어 Ingress를 만들더라도 실제로 트래픽을 받아줄 Ingress Controller를 설치해두지 않았으면 소용이 없습니다. 그리고 모니터링을 위해 컨테이너의 로그나 CPU/메모리 사용량 등을 수집, 조회할 수 있는 서비스도 필요합니다.다행히 이러한 추가 구성요소 또한 Kubernetes 클러스터 위에서 일반 애플리케이션과 거의 같은 방식으로 작동하므로 설치하는 것이 어렵지는 않습니다. 다만 클러스터를 원하는 대로 구성할 수 있는 만큼 선택의 폭이 넓어서 여러 가지 해법을 놓고 고민하게 될 수 있습니다. 이 글에서는 타다 서비스를 위해 Kubernetes 클러스터를 구성할 때 어떤 선택을 했는지, 특히 AWS 환경에서는 어떤 서비스들을 활용할 수 있는지 공유합니다.서비스를 외부에 노출: NGINX Ingress Controller + NLBIngress Controller 고르기Kubernetes에서 클러스터 내부 서비스를 외부에 HTTP(S)로 노출할 때는 Ingress를 사용할 수 있습니다. TLS 암호화, 로드밸런싱, 호스트명/경로 기반 라우팅 등을 제공해서 상당히 편리한데, Ingress가 실제로 작동하기 위해서는 Ingress Controller가 필요합니다.시중에는 다양한 종류의 Ingress Controller 솔루션이 나와 있습니다. 그중 Kubernetes 프로젝트에서 공식 지원하는 NGINX Ingress Controller와 AWS ALB 로드밸런서를 이용하는 AWS ALB Ingress Controller를 두고 고민을 했습니다.타다에서는 클라이언트(모바일 앱)에 실시간 이벤트를 전달하기 위해 gRPC를 사용하고 있어서 gRPC를 지원하지 않는 ALB는 선택할 수 없었습니다. 그리고 AWS ALB Ingress Controller는 현재 Ingress 하나마다 ALB를 1개 생성하는 구조여서 앞으로 노출할 서비스 수가 늘어난다면 비용 효율이 떨어진다고 판단했습니다. 따라서 NGINX Ingress Controller를 선택하게 되었습니다.NGINX Ingress Controller는 NGINX 웹서버를 기반으로 하므로 gRPC 모듈을 비롯하여 다양한 NGINX 모듈을 통해 굉장히 세세한 부분까지 설정할 수 있습니다. NGINX Ingress Controller는 Ingress나 Ingress가 가리키는 서비스의 엔드포인트에 변화가 생길 때마다 동적으로 NGINX 설정을 업데이트하는 방식으로 동작합니다.NGINX Ingress Controller 로드밸런싱NGINX Ingress Controller를 사용해도 외부에서 오는 트래픽을 적절히 분배해 줄 외부 로드밸런서는 필요합니다. AWS의 로드밸런서는 Classic ELB, ALB, NLB가 있습니다. 앞서 설명했듯이 ALB는 gRPC를 지원하지 않아서 Classic ELB를 TCP 모드로 사용하거나 NLB를 사용해야 합니다. Classic ELB는 동시에 많은 연결을 처리하려면 웜 업이 필요한 단점이 있어 NLB를 사용하기로 하였습니다.최근 NLB가 TLS termination을 지원하기 시작했지만, HTTP/2와 gRPC를 사용하기 위해 필요한 ALPN 정보를 설정할 수 없어서 NGINX 수준에서 TLS 암호화를 처리하고 있습니다. NLB 수준에서 TLS 처리를 하면 무료로 자동 갱신되는 ACM 인증서를 사용할 수 있는 등 여러 가지 이점이 있어서 아쉽습니다.Kubernetes에서 LoadBalancer 타입의 서비스를 생성하면 알아서 AWS 로드밸런서를 만들어줍니다. 하지만 이렇게 해서 NLB를 생성하는 방식은 아직 알파 기능입니다. 따라서 먼저 NodePort 타입의 서비스를 생성하여 모든 노드의 특정 포트에 NGINX를 노출한 다음, 별도로 생성한 NLB에 노드들이 속한 오토스케일링 그룹을 연결해주는 방식으로 직접 설정하게 되었습니다.정리해보면 외부에서 오는 트래픽을 처리할 때는 다음과 같은 과정을 거칩니다.모든 서브도메인(*.tadatada.com)은 NLB를 가리킵니다.NLB의 443 포트로 암호화된 HTTP 또는 gRPC 요청이 들어옵니다. NLB는 적절한 Kubernetes 노드 중 하나의 특정 포트(예: 30000번)로 요청을 전달합니다.Kubernetes 노드에서는 포트 번호를 보고 NGINX 서비스로 향하는 요청임을 알 수 있고 NGINX 컨테이너 중 하나로 요청을 전달합니다.NGINX는 복호화를 한 다음 HTTP Host 헤더를 확인하여 요청을 전달할 Ingress를 알아냅니다. 그리고 해당 Ingress의 엔드포인트 중 하나로 복호화한 요청을 프록시합니다.애플리케이션 컨테이너가 요청을 처리합니다.트래픽 흐름: NLB → NodePort → NGINX Ingress Controller → 내부 서비스Pod에 IAM 역할 부여: kube2iamS3, SQS 등 IAM으로 인증하는 AWS 서비스에 접근하려면 인증 정보가 필요합니다. EC2에서는 액세스 키를 직접 넣는 대신 EC2 인스턴스 프로파일로 인스턴스에 IAM 역할을 부여할 수 있습니다. 하지만 하나의 Kubernetes 노드 (=EC2 인스턴스)에는 여러 Pod이 실행될 수 있기 때문에 Pod마다 다른 IAM 역할을 부여하기를 원한다면 인스턴스 프로파일을 활용할 수 없게 됩니다. (인스턴스 프로파일에는 하나의 IAM 역할만 부여 가능)kube2iam을 사용하면 다음과 같이 Pod 어노테이션으로 IAM 역할을 지정할 수 있습니다.apiVersion: v1 kind: Pod metadata: name: aws-cli labels: name: aws-cli annotations: iam.amazonaws.com/role: role-arn spec: ... 설치나 사용법은 문서를 참고하면 어렵지 않은데, 원리를 간단히 설명해 보겠습니다. EC2 인스턴스 안에서는 특정 IP 주소(169.254.169.254)로 접속하면 EC2 메타데이터 API에 접근할 수 있습니다. AWS SDK는 EC2 메타데이터 API를 통해서 인스턴스 프로파일에 붙은 IAM 역할과 IAM 역할에 해당되는 액세스 키 쌍을 받아오게 됩니다.kube2iam은 모든 노드에 실행되면서 Pod 내부에서 EC2 메타데이터 서버 주소로 나가는 모든 요청을 가로챕니다. 그리고 인스턴스 프로파일 정보와 액세스 키 발급 요청을 kube2iam 서버가 대신 처리합니다. 따라서 Pod 안에서는 인스턴스 프로파일이 부여된 EC2 인스턴스 내부에 있는 것처럼 느껴지게 됩니다.추후 AWS SDK에 EKS 지원이 추가되면 별도로 데몬을 설치하지 않고도 Pod에 IAM 역할을 줄 수 있게 될 것으로 보입니다.로그 수집: fluentd + CloudWatch LogsKubernetes의 컨테이너가 stdout/stderr로 출력하는 로그는 노드에만 쌓이고 컨테이너를 재시작하거나 삭제하면 함께 삭제됩니다. 또한 노드의 디스크가 꽉 차는 것을 방지하기 위해 일정 크기를 넘으면 오래된 로그는 없어집니다. 그러므로 로그가 사라지지 않도록 계속 어딘가에 모아두어야 합니다.AWS에서 활용할 수 있는 로그 저장 서비스에는 CloudWatch Logs가 있습니다. fluentd를 DaemonSet으로 노드마다 하나씩 실행해서 컨테이너 로그를 CloudWatch Logs로 전송할 수 있습니다.CloudWatch Logs에 저장한 로그는 최근 나온 CloudWatch Logs Insights로 검색, 분석할 수 있습니다. 아직 나온 지 얼마 되지 않아서 기능이 많지는 않지만, 간단히 조회하는 용도로는 충분합니다.CloudWatch Logs Insights 사용 예모니터링: PrometheusEC2 인스턴스 하나에 서비스 하나를 띄워서 사용할 때는 CloudWatch로 CPU 사용률 등의 지표를 측정할 수 있었습니다. 하지만 Kubernetes를 사용하면 여러 서비스가 하나의 인스턴스에서 동시에 실행될 것이므로 인스턴스 수준의 지표는 무의미합니다. 특히 최소 실행 단위인 컨테이너 수준의 CPU 사용률 같은 값을 측정해야 하는데, CloudWatch를 사용하기에는 과금 체계가 적합하지 않습니다.기본 제공되는 5분 간격의 EC2 지표는 무료지만 CloudWatch에 커스텀 지표를 올리게 되면 지표 당 비용을 지불해야 합니다. 이 때 '지표'는 지표 이름 + 고유한 차원(dimension)의 조합입니다. 예를 들어 CPUUtilization이라는 이름의 지표가 PodName=server-aaaaaaaa과 PodName=server-bbbbbbbb라는 다른 차원으로 올라온다면 각각을 다른 지표로 취급합니다. 따라서 지표 수가 너무 많아지지 않게 조정해야 하는데 그러면 상세하게 모니터링하기가 어렵습니다.비용 문제도 있고, Kubernetes의 여러 가지 정보를 CloudWatch로 내보내는 기존 도구가 없었기 때문에 다른 방법을 찾아보게 되었습니다. 그래서 Kubernetes 모니터링을 위해 많이 사용하는 Prometheus를 선택했습니다. Prometheus를 온전히 사용하기 위해서는 다양한 컴포넌트들이 필요한데, Prometheus Operator Helm 차트를 사용하면 비교적 쉽게 구축할 수 있습니다.Prometheus는 Kubernetes 클러스터 모니터링 외에 애플리케이션 모니터링에도 사용할 수 있습니다. 타다의 애플리케이션들은 Spring Boot로 작성되어 있는데 Spring Boot Actuator와 Micrometer의 Prometheus 지원을 사용해서 애플리케이션 수준의 지표도 Prometheus로 모니터링하고 있습니다. 특히 Prometheus Operator를 사용하면 모니터링 대상을 추가할 때 Prometheus 설정 파일을 수정하지 않아도 Kubernetes에 ServiceMonitor 리소스를 등록하기만 하면 되어서 편리합니다.Prometheus로 수집된 지표는 Grafana 대시보드로 시각화하고, 정해진 조건에서 Alertmanager를 통해 PagerDuty와 Slack에 알림을 보냅니다.Grafana 대시보드의 모습자동 처리량 확장: Cluster AutoscalerKubernetes에서 자동 처리량 확장은 크게 두 종류로 나눌 수 있습니다. 먼저 Horizontal Pod Autoscaler로 CPU, 메모리 사용량에 따라 Pod의 수를 자동으로 조정할 수 있습니다. HPA가 실제로 동작하기 위해서는 오토스케일링을 위한 지표를 제공하는 Metrics Server를 설치해야 합니다. 그런데 부하가 증가해서 HPA가 Pod 수를 늘리려고 할 때 워커 노드에 여유가 충분하지 않으면 새로운 Pod을 실행할 수 없어서 소용이 없습니다. 이 때 워커 노드의 수를 자동으로 조정해주는 것이 Cluster Autoscaler입니다. Cluster Autoscaler는 노드 수를 증가시키기만 하는 것이 아니라 여유가 생겼을 때 노드 수를 자동으로 줄여서 불필요한 비용이 발생하지 않도록 해줍니다.AWS 환경에서 Cluster Autoscaler는 EC2 API를 통해 EC2 오토스케일링 그룹의 Desired Capacity 값을 필요한 노드 수로 조정하는 방식으로 작동합니다. 따라서 Cluster Autoscaler에는 EC2 API를 호출할 수 있는 IAM 권한을 주어야 합니다. 이를 위해 위에서 소개한 kube2iam을 사용할 수 있습니다. 그리고 Cluster Autoscaler가 오토스케일링 그룹을 자동으로 발견할 수 있도록 미리 정해진 태그를 붙여야 합니다.한 가지 주의할 점은 노드의 오토스케일링 그룹이 여러 가용 영역(AZ)에 걸쳐있으면 안 된다는 것입니다. 오토스케일링 그룹이 여러 AZ에 속한 경우 AZ 간 인스턴스 수의 균형을 맞추려고 하는데 이 과정에서 인스턴스가 예기치 않게 종료될 수 있습니다. 이 때 해당 노드에 실행되어 있던 Pod이 안전하게 종료되지 않을 수 있기 때문에 AZ마다 오토스케일링 그룹을 따로 만들고 AZ 간 균형은 Cluster Autoscaler가 맞추도록 설정해야 합니다.도움이 되는 링크들위에서 소개한 컴포넌트들은 다음과 같은 Helm 차트를 통해 설치해서 사용하고 있습니다.stable/nginx-ingressstable/kube2iamincubator/fluentd-cloudwatchstable/prometheus-operatorstable/metrics-serverstable/cluster-autoscalerEKS Workshop: AWS 환경에서 Kubernetes 운영할 때 참고할 만한 정보가 많이 있습니다.Kubernetes Slack 채널: #eks 채널에는 AWS 직원들도 접속해 있어서 높은 확률로 답변을 받을 수 있습니다.

기업문화 엿볼 때, 더팀스

로그인

/