![logo](https://image.wanted.co.kr/optimize?src=https://static.codenary.co.kr/company-logo/375.png&w=100&q=90)
Kubernetes에서 NFS를 활용한 ReadWriteMany 스토리지 구성하기
Kubernetes 환경에서 여러 파드가 동시에 접근할 수 있는 공유 스토리지가 필요한 경우가 있다.이 글에서는 가장 간단하게 구성할 수 있는 NFS를 활용한 ReadWriteMany 스토리지 구성 방법을 알아본다.Kubernetes에서는 스토리지 접근 방식을 다음과 같이 구분한다:• None ReadWriteOnce (RWO): 단일 노드에서만 읽기/쓰기 가능• None ReadOnlyMany (ROX): 여러 노드에서 읽기만 가능• None ReadWriteMany (RWX): 여러 노드에서 읽기/쓰기 모두 가능• None Kubernetes SIG에서 개발한 Ganesha NFS를 사용하는 것이 가장 추천되는 방법이다. Helm을 통해 쉽게 설치할 수 있으며, 동적 프로비저닝을 지원한다.• None StatefulSet을 사용해 NFS 서버를 직접 구성할 수 있다:NFS 서버가 준비되면 다음과 같이 PV와 PVC를 구성한다:Ganesha NFS를 사용하는 경우 PVC만 생성하면 된다:아래는 앞에서 만든 pvc를 사용하는 3개의 pod를 생성하여 동시에 파일시스템을 활용하는 예시이다.• None NFS 클라이언트 패키지 설치가 필요• None 네트워크 성능이 스토리지 성능에 영향을 미침이렇게 구성된 NFS 스토리지는 여러 파드가 동시에 접근해야 하는 로그 수집, 공유 파일 시스템, 미디어 처리 등의 용도로 활용할 수 있다.
2/7/2025
![logo](https://image.wanted.co.kr/optimize?src=https://static.codenary.co.kr/company-logo/375.png&w=100&q=90)
Kubernetes에서 NFS를 활용한 ReadWriteMany 스토리지 구성하기
Kubernetes 환경에서 여러 파드가 동시에 접근할 수 있는 공유 스토리지가 필요한 경우가 있다.이 글에서는 가장 간단하게 구성할 수 있는 NFS를 활용한 ReadWriteMany 스토리지 구성 방법을 알아본다.Kubernetes에서는 스토리지 접근 방식을 다음과 같이 구분한다:• None ReadWriteOnce (RWO): 단일 노드에서만 읽기/쓰기 가능• None ReadOnlyMany (ROX): 여러 노드에서 읽기만 가능• None ReadWriteMany (RWX): 여러 노드에서 읽기/쓰기 모두 가능• None Kubernetes SIG에서 개발한 Ganesha NFS를 사용하는 것이 가장 추천되는 방법이다. Helm을 통해 쉽게 설치할 수 있으며, 동적 프로비저닝을 지원한다.• None StatefulSet을 사용해 NFS 서버를 직접 구성할 수 있다:NFS 서버가 준비되면 다음과 같이 PV와 PVC를 구성한다:Ganesha NFS를 사용하는 경우 PVC만 생성하면 된다:아래는 앞에서 만든 pvc를 사용하는 3개의 pod를 생성하여 동시에 파일시스템을 활용하는 예시이다.• None NFS 클라이언트 패키지 설치가 필요• None 네트워크 성능이 스토리지 성능에 영향을 미침이렇게 구성된 NFS 스토리지는 여러 파드가 동시에 접근해야 하는 로그 수집, 공유 파일 시스템, 미디어 처리 등의 용도로 활용할 수 있다.
2025.02.07
![emoji](https://cdn.jsdelivr.net/npm/emoji-datasource-twitter/img/twitter/64/1f603.png)
좋아요
![emoji](https://cdn.jsdelivr.net/npm/emoji-datasource-twitter/img/twitter/64/1f641.png)
별로에요
![logo](https://image.wanted.co.kr/optimize?src=https://static.codenary.co.kr/company-logo/100034.png&w=100&q=90)
현대차·기아에서 프론트엔드 개발에 다국어를 지원하며 협업하는 법 (feat. i18n)
들어가며안녕하세요, 인포테인먼트CCS개발팀에서 Frontend 업무를 수행하고 있는 이민재 연구원입니다.인포테인먼트CCS개발팀의 Frontend 개발자들는 CCS의 개발 및 운영, 이슈 파악등을 위한 팀 내의 백오피스 및 어드민 페이지들을 다양하게 구축하고 있습니다.커넥티드카 서비스는 글로벌하게 운영중입니다. 내수, 유럽, 북미, 아중동 등등 수 많은 지역에 전개되고 있습니다.커넥티드카 서비스를 글로벌하게 전개하고 운영하기 위해서는 현지의 연구소 분들, 협력사 및 개발자 분들과 개발/운영중인 시스템에 대해서 이슈가 발생할 때는 당팀에서 개발한 어드민을 통해서 소통을 하려고 했습니다만, 커넥티드카 서비스는 "글로벌"하지만, 기존에 Frontend 개발자들이 개발한 어드민들은 전부 한국어로 제작되어 있었습니다.이 부분에서 발생할 수 있는 문제점은현지 분들이 품질 게이트, 혹은 VOC가 들어온 이슈가 발생한 부분에 대해서 한국어만 봐야할 수 있음.개발된 페이지의 한국어에 대해서 다시 영어 혹은 현지 언어로 번역해야 함.등의 문제점들이 있을 수 있었습니다.이 문제를 해결하기 위해서 Frontend 개발자들은 i18n을 도입하여 어드민 및 백오피스를 개발하고 있습니다. 그렇다면 지금부터는 i18n을 당팀에서 어떻게 사용하고, 적용했는지 공유해드리려고 합니다.i18ni18n에 대해서 소개드리겠습니다. i18n은 "국제화"라는 의미입니다. "국제화"라는 단어를 직역하면 internationalization이라는 20개의 알파벳으로 이루어진 단어인데요, 여기서 맨 앞과 뒤의 철자만 빼면 18개가 됩니다. 그래서 이를 축약하여 i18n이라고 부르고 있습니다. 이는 mdn 공식문서에 잘 정리되어 있습니다. (출처: https://developer.mozilla.org/ko/docs/Glossary/Internationalization) 당팀에서 사용하는 i18n 라이브러리는 i18next입니다.i18next 라이브러리란?i18next는 다국어 지원을 위한 i18n 라이브러리이며 텍스트를 여러 언어로 번역하고, 관리할 수 있는 기능들을 제공합니다. i18next의 기능들로는 다국어 번역 관리, 언어 감지, 동적 번역 로딩, key에 대한 복수형 처리 기능, 내부적인 subscription을 통한 부분 번역 변경 등이 있습니다. 또한, 무엇보다도 커스터마이징과 여러 플러그인을 통한 개발이 가능하다는 장점을 가진 라이브러리입니다.설명에 앞서, Frontend에서 Next.js를 사용하는 두 가지 방식이 있습니다. 바로 SSR(Server-Side Rendering)과 CSR(Client-Side Rendering)인데요 저희 팀에서는 CSR을 위주로 사용했기 때문에 CSR에서 사용하는 방식을 설명해드리겠습니다.CSR? SSR?CSR (Client-Side Rendering):클라이언트(브라우저)에서 JavaScript를 사용하여 데이터를 렌더링합니다. 초기 로딩 시 HTML 구조만 다운로드되고, 이후에 JavaScript가 데이터와 함께 호출되어 페이지를 동적으로 생성합니다. 사용자 경험이 매끄럽고 빠르지만, SEO 최적화에 어려움이 있을 수 있습니다. SSR (Server-Side Rendering):서버에서 미리 렌더링된 HTML을 클라이언트에 전송합니다. 초기 로딩 시 완전한 HTML 페이지가 다운로드되므로, SEO에 유리하며 첫 페이지 로딩 속도가 빠릅니다. 그러나 서버에서 렌더링되기 때문에 서버의 부하가 증가할 수 있습니다.i18n을 사용하는 방법Directories1. Installation네 개의 dependency를 install합니다.2. i18n 설정installation 후에 i18n 관련 설정을 진행해주어야 합니다. 아래와 같이 i18n.ts 파일을 만들어 i18n에서 사용할 설정을 해줍니다.3. Provider 설정디렉토리 구조를 보면 아시겠지만, 위에서 생성한 i18n 인스턴스를 Provider에게 넘겨주어야 합니다. Provider 같은 경우에는 app 하위에 있는 layout.tsx에 주입하였습니다.4. locale 설정locale은 크게 아래의 두 가지 방법으로 설정할 수 있습니다.1. namespace로 나누어 namespace안에서 언어 별로 분리하는 법2. 언어별로 분리한 후에 namespace를 나누는 법당팀에서는 언어별로만 우선 분리를 하고, namespace는 따로 나누지 않는 전략을 선택했습니다. Frontend 개발자들끼리 내부적으로 잘 정의한 i18n locale Ground Rule을 정해, 이를 충실히 지킨다면 namespace를 따로 나눌 필요가 없다고 판단했습니다.Locale의 작성법은, 번역하고 싶은 string에 대해서 key를 먼저 선언하고, 번역은 value에 넣어줍니다. 아래의 json의 예시를 보시면 쉽게 이해가 되실겁니다.5. i18n 적용하기i18n은 쉽게 적용할 수 있습니다. 'react-i18next'에서 제공해주는 useTranslation hook을 사용하면 알아서 i18n 인스턴스를 통해 설정된 언어를 불러와서 화면에 render하게 됩니다.하지만 여전히 발생되는 에러이렇게 잘 설정을 한 것 같았지만, 브라우저와 console에서는 아래와 같은 에러가 뜨고 있었습니다.바로, hydration error입니다. 'use client'를 사용했음에도 불구하고, Next.js단에서 html을 미리 만들고 내려주는 text와 browser에서 초기에 render되는 text가 다른, 즉 React 트리가 아직 DOM과 동기화 되지 않은 상태로 Browser에 그려주려고 했기 때문에 발생하는 문제였습니다.이 문제는 간편하게 해결하는 방법은 react-i18next 라이브러리를 사용하지 않고, next-i18next를 사용하는 방법이었습니다.하지만, 저희는 조금 더 CSR스럽게 프로젝트를 진행하고 싶었기 때문에 dynamic을 통해 SSR로 render하는 것을 강제로 꺼버리도록 설정하는 방법을 사용했습니다. 아래의 코드처럼 dynamic을 적용해서 hydration error를 처리했습니다.6. 언어를 변경하는 방법언어를 바
reactjs
2/6/2025
![logo](https://image.wanted.co.kr/optimize?src=https://static.codenary.co.kr/company-logo/100034.png&w=100&q=90)
현대차·기아에서 프론트엔드 개발에 다국어를 지원하며 협업하는 법 (feat. i18n)
들어가며안녕하세요, 인포테인먼트CCS개발팀에서 Frontend 업무를 수행하고 있는 이민재 연구원입니다.인포테인먼트CCS개발팀의 Frontend 개발자들는 CCS의 개발 및 운영, 이슈 파악등을 위한 팀 내의 백오피스 및 어드민 페이지들을 다양하게 구축하고 있습니다.커넥티드카 서비스는 글로벌하게 운영중입니다. 내수, 유럽, 북미, 아중동 등등 수 많은 지역에 전개되고 있습니다.커넥티드카 서비스를 글로벌하게 전개하고 운영하기 위해서는 현지의 연구소 분들, 협력사 및 개발자 분들과 개발/운영중인 시스템에 대해서 이슈가 발생할 때는 당팀에서 개발한 어드민을 통해서 소통을 하려고 했습니다만, 커넥티드카 서비스는 "글로벌"하지만, 기존에 Frontend 개발자들이 개발한 어드민들은 전부 한국어로 제작되어 있었습니다.이 부분에서 발생할 수 있는 문제점은현지 분들이 품질 게이트, 혹은 VOC가 들어온 이슈가 발생한 부분에 대해서 한국어만 봐야할 수 있음.개발된 페이지의 한국어에 대해서 다시 영어 혹은 현지 언어로 번역해야 함.등의 문제점들이 있을 수 있었습니다.이 문제를 해결하기 위해서 Frontend 개발자들은 i18n을 도입하여 어드민 및 백오피스를 개발하고 있습니다. 그렇다면 지금부터는 i18n을 당팀에서 어떻게 사용하고, 적용했는지 공유해드리려고 합니다.i18ni18n에 대해서 소개드리겠습니다. i18n은 "국제화"라는 의미입니다. "국제화"라는 단어를 직역하면 internationalization이라는 20개의 알파벳으로 이루어진 단어인데요, 여기서 맨 앞과 뒤의 철자만 빼면 18개가 됩니다. 그래서 이를 축약하여 i18n이라고 부르고 있습니다. 이는 mdn 공식문서에 잘 정리되어 있습니다. (출처: https://developer.mozilla.org/ko/docs/Glossary/Internationalization) 당팀에서 사용하는 i18n 라이브러리는 i18next입니다.i18next 라이브러리란?i18next는 다국어 지원을 위한 i18n 라이브러리이며 텍스트를 여러 언어로 번역하고, 관리할 수 있는 기능들을 제공합니다. i18next의 기능들로는 다국어 번역 관리, 언어 감지, 동적 번역 로딩, key에 대한 복수형 처리 기능, 내부적인 subscription을 통한 부분 번역 변경 등이 있습니다. 또한, 무엇보다도 커스터마이징과 여러 플러그인을 통한 개발이 가능하다는 장점을 가진 라이브러리입니다.설명에 앞서, Frontend에서 Next.js를 사용하는 두 가지 방식이 있습니다. 바로 SSR(Server-Side Rendering)과 CSR(Client-Side Rendering)인데요 저희 팀에서는 CSR을 위주로 사용했기 때문에 CSR에서 사용하는 방식을 설명해드리겠습니다.CSR? SSR?CSR (Client-Side Rendering):클라이언트(브라우저)에서 JavaScript를 사용하여 데이터를 렌더링합니다. 초기 로딩 시 HTML 구조만 다운로드되고, 이후에 JavaScript가 데이터와 함께 호출되어 페이지를 동적으로 생성합니다. 사용자 경험이 매끄럽고 빠르지만, SEO 최적화에 어려움이 있을 수 있습니다. SSR (Server-Side Rendering):서버에서 미리 렌더링된 HTML을 클라이언트에 전송합니다. 초기 로딩 시 완전한 HTML 페이지가 다운로드되므로, SEO에 유리하며 첫 페이지 로딩 속도가 빠릅니다. 그러나 서버에서 렌더링되기 때문에 서버의 부하가 증가할 수 있습니다.i18n을 사용하는 방법Directories1. Installation네 개의 dependency를 install합니다.2. i18n 설정installation 후에 i18n 관련 설정을 진행해주어야 합니다. 아래와 같이 i18n.ts 파일을 만들어 i18n에서 사용할 설정을 해줍니다.3. Provider 설정디렉토리 구조를 보면 아시겠지만, 위에서 생성한 i18n 인스턴스를 Provider에게 넘겨주어야 합니다. Provider 같은 경우에는 app 하위에 있는 layout.tsx에 주입하였습니다.4. locale 설정locale은 크게 아래의 두 가지 방법으로 설정할 수 있습니다.1. namespace로 나누어 namespace안에서 언어 별로 분리하는 법2. 언어별로 분리한 후에 namespace를 나누는 법당팀에서는 언어별로만 우선 분리를 하고, namespace는 따로 나누지 않는 전략을 선택했습니다. Frontend 개발자들끼리 내부적으로 잘 정의한 i18n locale Ground Rule을 정해, 이를 충실히 지킨다면 namespace를 따로 나눌 필요가 없다고 판단했습니다.Locale의 작성법은, 번역하고 싶은 string에 대해서 key를 먼저 선언하고, 번역은 value에 넣어줍니다. 아래의 json의 예시를 보시면 쉽게 이해가 되실겁니다.5. i18n 적용하기i18n은 쉽게 적용할 수 있습니다. 'react-i18next'에서 제공해주는 useTranslation hook을 사용하면 알아서 i18n 인스턴스를 통해 설정된 언어를 불러와서 화면에 render하게 됩니다.하지만 여전히 발생되는 에러이렇게 잘 설정을 한 것 같았지만, 브라우저와 console에서는 아래와 같은 에러가 뜨고 있었습니다.바로, hydration error입니다. 'use client'를 사용했음에도 불구하고, Next.js단에서 html을 미리 만들고 내려주는 text와 browser에서 초기에 render되는 text가 다른, 즉 React 트리가 아직 DOM과 동기화 되지 않은 상태로 Browser에 그려주려고 했기 때문에 발생하는 문제였습니다.이 문제는 간편하게 해결하는 방법은 react-i18next 라이브러리를 사용하지 않고, next-i18next를 사용하는 방법이었습니다.하지만, 저희는 조금 더 CSR스럽게 프로젝트를 진행하고 싶었기 때문에 dynamic을 통해 SSR로 render하는 것을 강제로 꺼버리도록 설정하는 방법을 사용했습니다. 아래의 코드처럼 dynamic을 적용해서 hydration error를 처리했습니다.6. 언어를 변경하는 방법언어를 바
2025.02.06
reactjs
![emoji](https://cdn.jsdelivr.net/npm/emoji-datasource-twitter/img/twitter/64/1f603.png)
좋아요
![emoji](https://cdn.jsdelivr.net/npm/emoji-datasource-twitter/img/twitter/64/1f641.png)
별로에요
![logo](https://image.wanted.co.kr/optimize?src=https://static.codenary.co.kr/company-logo/324.png&w=100&q=90)
모두를 위한 LLM 애플리케이션 개발 환경 구축 사례
안녕하세요. Game Platform Dev의 류동훈, Zhang Youlu(Michael), Takenaka, 이형중입니다. 저희 조직은 게임 퍼블리싱에 필요한 다양한 기능을 개발하고 운영하는 역할을 맡고 있습니다.저희는 최근 조직 내 업무 효율을 높이기 위해 다양한 LLM(large language model) 애플리케이션을 개발하고, 이와 연계해 LLMOps 시스템 구축 프로젝트를 진행했습니다. 프로젝트의 주요 목표 중 하나는 진입 장벽이 높은 LLM 애플리케이션 개발을 직군에 상관없이 누구나 쉽게 제작할 수 있는 환경을 구축하는 것이었는데요. 이를 위해 여러 가지를 고민하며 시도하는 과정을 거쳤고, 그 결과 누구나 손쉽게 접근할 수 있는 개발 및 배포 환경을 마련할 수 있었습니다.이번 글에서는 LLM 애플리케이션의 일반적인 개발 방식과 개발 과정에서 마주하는 어려움을 살펴보고, 이런 문제를 해결할 수 있는 환경을 구성하기 위해 저희가 어떤 고민을 하고 노력을 했는지 공유하고자 합니다. 이 글을 통해 LLM 애플리케이션 개발 과정의 병목 지점을 개선하고 고도화해 접근성을 높일 수 있는 인사이트를 얻으시길 바라며 시작하겠습니다.LLM 애플리케이션의 개발 과정최근 OpenAI의 GPT와 Anthropic의 Claude 같은 고성능 LLM을 쉽게 활용할 수 있게 되면서, LLM 애플리케이션 개발의 초점이 이러한 모델을 효과적으로 활용해 서비스를 제공하는 방향으로 전환되고 있습니다. 모델을 직접 학습시키거나 파인튜닝(fine-tuning)하지 않고, 비용 효율을 고려해 상용 모델을 그대로 사용하면서 모델의 입력인 프롬프트를 구조화해 모델이 이를 잘 이해하도록 만드는 데 집중하고 있는 것입니다.프롬프트는 모델이 수행해야 할 작업의 맥락과 방향을 제시하므로 프롬프트를 잘 구조화하면 LLM의 성능을 한층 더 높일 수 있습니다. 또한 프롬프트는 수정하기 쉽기 때문에 비싼 비용을 지불해 모델을 직접 수정하는 것보다 훨씬 저렴하다는 장점도 있습니다. 이런 장점을 이용해 개발자들은 보다 빠르고 경제적으로 모델의 성능을 최적화할 수 있습니다.하지만 LLM 애플리케이션이 새로운 데이터에 대해 적절히 답변하도록 만드는 문제는 프롬프트 최적화만으로는 해결할 수 없습니다. 그럼 이 문제를 모델을 추가 학습하지 않고 어떻게 해결할 수 있을까요?일반적으로 이런 문제는 LLM의 몇 가지 기능을 활용해 해결합니다. LLM은 사전 학습된 데이터 외에 프롬프트에 제시된 추가 정보를 통해 즉석에서 정보를 생성할 수 있습니다. 이런 기능을 인 컨텍스트(in-context) 러닝이라고 합니다. 인 컨텍스트 러닝 중 특히 몇 가지 예시 답변을 통해 모델이 패턴을 익히고 더욱 잘 답변하게 만드는 것을 퓨 샷(few-shot) 러닝이라고 하는데요. 이를 이용해 프롬프트에 정보를 주입하면 LLM이 새로운 데이터에 대해 적절히 답변할 수 있게 만들 수 있습니다.이제 LLM이 새로운 데이터에 대해 답변할 수 있게 됐지만 인 컨텍스트 러닝과 퓨 샷 러닝, 두 가지 기법만으로는 새로운 데이
python
2/6/2025
![logo](https://image.wanted.co.kr/optimize?src=https://static.codenary.co.kr/company-logo/324.png&w=100&q=90)
모두를 위한 LLM 애플리케이션 개발 환경 구축 사례
안녕하세요. Game Platform Dev의 류동훈, Zhang Youlu(Michael), Takenaka, 이형중입니다. 저희 조직은 게임 퍼블리싱에 필요한 다양한 기능을 개발하고 운영하는 역할을 맡고 있습니다.저희는 최근 조직 내 업무 효율을 높이기 위해 다양한 LLM(large language model) 애플리케이션을 개발하고, 이와 연계해 LLMOps 시스템 구축 프로젝트를 진행했습니다. 프로젝트의 주요 목표 중 하나는 진입 장벽이 높은 LLM 애플리케이션 개발을 직군에 상관없이 누구나 쉽게 제작할 수 있는 환경을 구축하는 것이었는데요. 이를 위해 여러 가지를 고민하며 시도하는 과정을 거쳤고, 그 결과 누구나 손쉽게 접근할 수 있는 개발 및 배포 환경을 마련할 수 있었습니다.이번 글에서는 LLM 애플리케이션의 일반적인 개발 방식과 개발 과정에서 마주하는 어려움을 살펴보고, 이런 문제를 해결할 수 있는 환경을 구성하기 위해 저희가 어떤 고민을 하고 노력을 했는지 공유하고자 합니다. 이 글을 통해 LLM 애플리케이션 개발 과정의 병목 지점을 개선하고 고도화해 접근성을 높일 수 있는 인사이트를 얻으시길 바라며 시작하겠습니다.LLM 애플리케이션의 개발 과정최근 OpenAI의 GPT와 Anthropic의 Claude 같은 고성능 LLM을 쉽게 활용할 수 있게 되면서, LLM 애플리케이션 개발의 초점이 이러한 모델을 효과적으로 활용해 서비스를 제공하는 방향으로 전환되고 있습니다. 모델을 직접 학습시키거나 파인튜닝(fine-tuning)하지 않고, 비용 효율을 고려해 상용 모델을 그대로 사용하면서 모델의 입력인 프롬프트를 구조화해 모델이 이를 잘 이해하도록 만드는 데 집중하고 있는 것입니다.프롬프트는 모델이 수행해야 할 작업의 맥락과 방향을 제시하므로 프롬프트를 잘 구조화하면 LLM의 성능을 한층 더 높일 수 있습니다. 또한 프롬프트는 수정하기 쉽기 때문에 비싼 비용을 지불해 모델을 직접 수정하는 것보다 훨씬 저렴하다는 장점도 있습니다. 이런 장점을 이용해 개발자들은 보다 빠르고 경제적으로 모델의 성능을 최적화할 수 있습니다.하지만 LLM 애플리케이션이 새로운 데이터에 대해 적절히 답변하도록 만드는 문제는 프롬프트 최적화만으로는 해결할 수 없습니다. 그럼 이 문제를 모델을 추가 학습하지 않고 어떻게 해결할 수 있을까요?일반적으로 이런 문제는 LLM의 몇 가지 기능을 활용해 해결합니다. LLM은 사전 학습된 데이터 외에 프롬프트에 제시된 추가 정보를 통해 즉석에서 정보를 생성할 수 있습니다. 이런 기능을 인 컨텍스트(in-context) 러닝이라고 합니다. 인 컨텍스트 러닝 중 특히 몇 가지 예시 답변을 통해 모델이 패턴을 익히고 더욱 잘 답변하게 만드는 것을 퓨 샷(few-shot) 러닝이라고 하는데요. 이를 이용해 프롬프트에 정보를 주입하면 LLM이 새로운 데이터에 대해 적절히 답변할 수 있게 만들 수 있습니다.이제 LLM이 새로운 데이터에 대해 답변할 수 있게 됐지만 인 컨텍스트 러닝과 퓨 샷 러닝, 두 가지 기법만으로는 새로운 데이
2025.02.06
python
![emoji](https://cdn.jsdelivr.net/npm/emoji-datasource-twitter/img/twitter/64/1f603.png)
좋아요
![emoji](https://cdn.jsdelivr.net/npm/emoji-datasource-twitter/img/twitter/64/1f641.png)
별로에요
![logo](https://image.wanted.co.kr/optimize?src=https://static.codenary.co.kr/company-logo/1376.png&w=100&q=90)
오픈채팅 Lite FE 성능 개선의 모든 것
안녕하세요, 오픈채팅 Lite의 stella, roddy, holly입니다.오픈채팅 Lite는 부담 없이 수많은 사람들과 대화할 수 있도록 하는 것을 목표로 개발된 서비스로, 지금 이 순간에도 다양한 주제로 많은 이야기가 만들어지고 있습니다.하나의 주제로 많은 사람이 제한 없이 참여할 수 있다는 서비스 특성상, 유저들의 화력에 따라 짧은 시간 안에 한 화면에 적게는 수십 개, 많게는 수백, 수천 개의 메시지가 몰릴 수 있습니다. 그만큼 오픈채팅 Lite에서는 화면 렌더링 성능에 큰 관심을 기울이고 있습니다. 약간의 개선 혹은 개악으로도 유저들의 체감 성능이 극적으로 바뀔 수 있기 때문이에요.이번 포스트에서는 오픈채팅 Lite FE에서 진행했던 여러 렌더링 성능 개선 시도, 그리고 그 결과를 공유합니다. 간단한 컴포넌트 개선부터 라이브러리 사용 컨벤션, 코어 로직의 변경까지 여러 방면에 걸쳐 개선을 진행하였으니 많은 관심을 가지고 지켜봐 주세요!이 게시글에서 발생하는 여러 가지 문제 상황들은 단숨에 발생한 것이 아니라, 23년 5월 오픈채팅 Lite 런칭 이후 꾸준한 기능 개발 및 구조 개선을 거쳐오며 수정된 것입니다. 전후 비교 영상 혹은 그래프는 개선 양상을 보여드리기 위해 테스트 환경을 구성하여 촬영된 것으로, 오픈채팅 Lite의 현재 성능 및 동작과는 다를 수 있습니다.먼저, 오픈채팅 Lite를 개발하면서 직면했던 여러 가지 성능 문제를 소개하겠습니다.잠깐 텍스트를 보내고 나가는 사용성에서는 크게 문제가 되지 않았지만, 한 주제에서 여러 채팅방을 이동하며 대화하거나, 오랜 시간 채팅방에 머물며 여러 개의 메시지를 받을 경우 유저가 체감할 수 있을 정도로 점점 동작이 느려지는 현상이 발생했습니다.메시지를 주고받는 동안에도 문제가 발생했어요. 누군가 보낸 메시지가 화면에 그려지는 동안, 유저가 누른 버튼이 동작하지 않다가 뒤늦게 동작하는 현상이 발생했습니다. 평소에도 종종 발생하지만, 시즈널 이벤트를 기념하는 채팅방에서는 수많은 사람이 메시지를 작성하기 때문에 이 문제점이 더 극명하게 드러났습니다. 이 현상은 안드로이드보다는 iOS에서 더 잘 재현되었어요.화면이 깜빡이는 현상마지막으로, 유저의 참여율이 높은 주제에서 채팅방에 너무 빠른 속도로 메시지가 쌓일 때 발생하는 문제입니다. 우리가 기대한 동작은 메시지가 빠르게 주르룩 올라가는 그림이었는데, 메시지가 전역 스토어에 쌓이는 속도 대비 메시지가 그려지는 속도가 충분하지 못해서 화면이 하얗게 보이는 현상이었어요. iOS보다는 안드로이드에서 더 잘 발생했습니다.여러 가지 방법으로 두 현상을 개선할 수 있겠지만, 여기서는 컴포넌트를 좀 더 빨리 그리는 방법에 집중해 보겠습니다.먼저 첫 번째, 앱이 점점 느려지는 이유 중 하나는 DOM에 그려진 컴포넌트가 시간이 지날수록 점점 늘어나기 때문입니다. 말풍선 하나를 그릴 때마다 a만큼의 메모리를 사용한다고 하면, n개의 말풍선을 그리기 위해서는 총 a*n만큼의 메모리가 필요하죠. a와 n을 줄일 수 있다면 위의 두 가지 문제를 해결할 수 있을
reactjs
2/6/2025
![logo](https://image.wanted.co.kr/optimize?src=https://static.codenary.co.kr/company-logo/1376.png&w=100&q=90)
오픈채팅 Lite FE 성능 개선의 모든 것
안녕하세요, 오픈채팅 Lite의 stella, roddy, holly입니다.오픈채팅 Lite는 부담 없이 수많은 사람들과 대화할 수 있도록 하는 것을 목표로 개발된 서비스로, 지금 이 순간에도 다양한 주제로 많은 이야기가 만들어지고 있습니다.하나의 주제로 많은 사람이 제한 없이 참여할 수 있다는 서비스 특성상, 유저들의 화력에 따라 짧은 시간 안에 한 화면에 적게는 수십 개, 많게는 수백, 수천 개의 메시지가 몰릴 수 있습니다. 그만큼 오픈채팅 Lite에서는 화면 렌더링 성능에 큰 관심을 기울이고 있습니다. 약간의 개선 혹은 개악으로도 유저들의 체감 성능이 극적으로 바뀔 수 있기 때문이에요.이번 포스트에서는 오픈채팅 Lite FE에서 진행했던 여러 렌더링 성능 개선 시도, 그리고 그 결과를 공유합니다. 간단한 컴포넌트 개선부터 라이브러리 사용 컨벤션, 코어 로직의 변경까지 여러 방면에 걸쳐 개선을 진행하였으니 많은 관심을 가지고 지켜봐 주세요!이 게시글에서 발생하는 여러 가지 문제 상황들은 단숨에 발생한 것이 아니라, 23년 5월 오픈채팅 Lite 런칭 이후 꾸준한 기능 개발 및 구조 개선을 거쳐오며 수정된 것입니다. 전후 비교 영상 혹은 그래프는 개선 양상을 보여드리기 위해 테스트 환경을 구성하여 촬영된 것으로, 오픈채팅 Lite의 현재 성능 및 동작과는 다를 수 있습니다.먼저, 오픈채팅 Lite를 개발하면서 직면했던 여러 가지 성능 문제를 소개하겠습니다.잠깐 텍스트를 보내고 나가는 사용성에서는 크게 문제가 되지 않았지만, 한 주제에서 여러 채팅방을 이동하며 대화하거나, 오랜 시간 채팅방에 머물며 여러 개의 메시지를 받을 경우 유저가 체감할 수 있을 정도로 점점 동작이 느려지는 현상이 발생했습니다.메시지를 주고받는 동안에도 문제가 발생했어요. 누군가 보낸 메시지가 화면에 그려지는 동안, 유저가 누른 버튼이 동작하지 않다가 뒤늦게 동작하는 현상이 발생했습니다. 평소에도 종종 발생하지만, 시즈널 이벤트를 기념하는 채팅방에서는 수많은 사람이 메시지를 작성하기 때문에 이 문제점이 더 극명하게 드러났습니다. 이 현상은 안드로이드보다는 iOS에서 더 잘 재현되었어요.화면이 깜빡이는 현상마지막으로, 유저의 참여율이 높은 주제에서 채팅방에 너무 빠른 속도로 메시지가 쌓일 때 발생하는 문제입니다. 우리가 기대한 동작은 메시지가 빠르게 주르룩 올라가는 그림이었는데, 메시지가 전역 스토어에 쌓이는 속도 대비 메시지가 그려지는 속도가 충분하지 못해서 화면이 하얗게 보이는 현상이었어요. iOS보다는 안드로이드에서 더 잘 발생했습니다.여러 가지 방법으로 두 현상을 개선할 수 있겠지만, 여기서는 컴포넌트를 좀 더 빨리 그리는 방법에 집중해 보겠습니다.먼저 첫 번째, 앱이 점점 느려지는 이유 중 하나는 DOM에 그려진 컴포넌트가 시간이 지날수록 점점 늘어나기 때문입니다. 말풍선 하나를 그릴 때마다 a만큼의 메모리를 사용한다고 하면, n개의 말풍선을 그리기 위해서는 총 a*n만큼의 메모리가 필요하죠. a와 n을 줄일 수 있다면 위의 두 가지 문제를 해결할 수 있을
2025.02.06
reactjs
![emoji](https://cdn.jsdelivr.net/npm/emoji-datasource-twitter/img/twitter/64/1f603.png)
좋아요
![emoji](https://cdn.jsdelivr.net/npm/emoji-datasource-twitter/img/twitter/64/1f641.png)
별로에요
![logo](https://image.wanted.co.kr/optimize?src=https://static.codenary.co.kr/company-logo/375.png&w=100&q=90)
FastAPI에 모듈화된 구조 적용을 통한 빠른 프로토타이핑
오늘은 FastAPI와 SQLite를 사용하여 간단한 사용자 정보 관리 기능을 구축하고, 프로젝트를 모범 사례에 맞게 그리고, Fast라는 말에 걸맞게 신속하게 모듈화하는 과정을 공유해보려 합니다.이 글에서는 FastAPI의 주요 기능들을 활용해 어떻게 프로젝트 구조를 만들 수 있는지에 관한 간단한 예시를 소개합니다.이 프로젝트 구조는 API 엔드포인트(api/)와 데이터베이스 연동(db/, crud/)을 모듈화하여 관리합니다.• None 모델 정의는 models/에,• None 데이터 검증용 스키마는 schemas/에 분리하여 코드의 가독성과 유지 보수성을 높였습니다.• None 최상위 main.py는 FastAPI 애플리케이션을 초기화하고 라우터를 등록하는 역할을 합니다.이제, 각 모듈이 어떤 역할을 하는지 자세히 살펴보겠습니다.SQLite 데이터베이스를 설정하기 위해 파일을 작성했습니다.여기서는 함수를 통해 **의존성 주입(Dependency Injection)**을 사용하여 데이터베이스 세션을 주입합니다.2) 데이터베이스 모델 정의 (models/user.py)사용자 테이블을 정의하기 위해 파일을 작성했습니다.입력과 출력을 검증하기 위해 Pydantic 모델을 사용했습니다.데이터베이스와 상호작용하는 CRUD 함수들을 에 정의했습니다.에서는 사용자 관련 API를 정의했습니다.파일에서 FastAPI 애플리케이션을 생성하고 라우터를 등록합니다.서버 기동에 필요한 패키지를 배포합니다.이제 모든 준비가 끝났습니다! FastAPI 서버를 실행해서 API의 동작을 확인해 볼 수 있습니다.• None 모듈화된 프로젝트 구조의 중요성 🚀• None , , , , 로 기능을 분리하여 코드 가독성과 유지 보수성을 크게 향상할 수 있습니다. 모듈화를 통해 재사용성과 확장성이 극대화되었으며, 추후 기능 추가나 데이터베이스 변경이 용이한 구조를 갖추었습니다.• None• None 의존성 주입(Dependency Injection)을 사용해 데이터베이스 세션을 안전하게 관리하고, Pydantic을 활용해 입력 데이터 검증을 강화할 수 있습니다.• None SQLite와 SQLAlchemy를 통한 빠른 프로토타이핑 💡• None SQLite를 사용해 빠르게 데이터베이스 설정을 완료하고, SQLAlchemy로 ORM 방식을 적용해 데이터베이스 관련 처리를 직관적이고 효율적으로 구성할 수 있습니다.• None API 설계와 예외 처리의 중요성 🛡️• None RESTful API 원칙을 준수하며, FastAPI의 HTTPException을 활용해 에러 처리를 구조화했습니다. 이를 통해 명확한 에러 메시지 제공으로 사용자 경험을 개선할 수 있습니다.• None• None FastAPI의 자동 Swagger 문서 생성을 통해 API 테스트를 효율적으로 진행할 수 있었고, 을 사용해 빠르게 서버를 실행해 개발 속도를 높일 수 있습니다.
fastapi
2/6/2025
![logo](https://image.wanted.co.kr/optimize?src=https://static.codenary.co.kr/company-logo/375.png&w=100&q=90)
FastAPI에 모듈화된 구조 적용을 통한 빠른 프로토타이핑
오늘은 FastAPI와 SQLite를 사용하여 간단한 사용자 정보 관리 기능을 구축하고, 프로젝트를 모범 사례에 맞게 그리고, Fast라는 말에 걸맞게 신속하게 모듈화하는 과정을 공유해보려 합니다.이 글에서는 FastAPI의 주요 기능들을 활용해 어떻게 프로젝트 구조를 만들 수 있는지에 관한 간단한 예시를 소개합니다.이 프로젝트 구조는 API 엔드포인트(api/)와 데이터베이스 연동(db/, crud/)을 모듈화하여 관리합니다.• None 모델 정의는 models/에,• None 데이터 검증용 스키마는 schemas/에 분리하여 코드의 가독성과 유지 보수성을 높였습니다.• None 최상위 main.py는 FastAPI 애플리케이션을 초기화하고 라우터를 등록하는 역할을 합니다.이제, 각 모듈이 어떤 역할을 하는지 자세히 살펴보겠습니다.SQLite 데이터베이스를 설정하기 위해 파일을 작성했습니다.여기서는 함수를 통해 **의존성 주입(Dependency Injection)**을 사용하여 데이터베이스 세션을 주입합니다.2) 데이터베이스 모델 정의 (models/user.py)사용자 테이블을 정의하기 위해 파일을 작성했습니다.입력과 출력을 검증하기 위해 Pydantic 모델을 사용했습니다.데이터베이스와 상호작용하는 CRUD 함수들을 에 정의했습니다.에서는 사용자 관련 API를 정의했습니다.파일에서 FastAPI 애플리케이션을 생성하고 라우터를 등록합니다.서버 기동에 필요한 패키지를 배포합니다.이제 모든 준비가 끝났습니다! FastAPI 서버를 실행해서 API의 동작을 확인해 볼 수 있습니다.• None 모듈화된 프로젝트 구조의 중요성 🚀• None , , , , 로 기능을 분리하여 코드 가독성과 유지 보수성을 크게 향상할 수 있습니다. 모듈화를 통해 재사용성과 확장성이 극대화되었으며, 추후 기능 추가나 데이터베이스 변경이 용이한 구조를 갖추었습니다.• None• None 의존성 주입(Dependency Injection)을 사용해 데이터베이스 세션을 안전하게 관리하고, Pydantic을 활용해 입력 데이터 검증을 강화할 수 있습니다.• None SQLite와 SQLAlchemy를 통한 빠른 프로토타이핑 💡• None SQLite를 사용해 빠르게 데이터베이스 설정을 완료하고, SQLAlchemy로 ORM 방식을 적용해 데이터베이스 관련 처리를 직관적이고 효율적으로 구성할 수 있습니다.• None API 설계와 예외 처리의 중요성 🛡️• None RESTful API 원칙을 준수하며, FastAPI의 HTTPException을 활용해 에러 처리를 구조화했습니다. 이를 통해 명확한 에러 메시지 제공으로 사용자 경험을 개선할 수 있습니다.• None• None FastAPI의 자동 Swagger 문서 생성을 통해 API 테스트를 효율적으로 진행할 수 있었고, 을 사용해 빠르게 서버를 실행해 개발 속도를 높일 수 있습니다.
2025.02.06
fastapi
![emoji](https://cdn.jsdelivr.net/npm/emoji-datasource-twitter/img/twitter/64/1f603.png)
좋아요
![emoji](https://cdn.jsdelivr.net/npm/emoji-datasource-twitter/img/twitter/64/1f641.png)
별로에요
![logo](https://image.wanted.co.kr/optimize?src=https://static.codenary.co.kr/company-logo/4962.png&w=100&q=90)
기존 서비스 국제화(i18n) 작업 쉽게 덜어내기: t 함수 자동 래핑 스크립트 만들기
안녕하세요. 인프랩의 랠릿 셀 프론트엔드 개발자 고슈, 도니, 루시입니다.2024년 초, 연간 플래닝에서 CTO인 향로에게서 예상치 못한 발표를 듣게 됩니다.이렇게 랠릿을 포함한 인프랩 개발파트는 레거시 코드 정리부터 국제화 작업까지, 인프런의 글로벌 서비스 출시를 위한 새로운 도전을 시작하게 되었습니다.i18n을 서비스에 적용하는 전체 과정보다는, 기존 서비스를 다국어 서비스로 전환하는 과정에서 i18n 을 효율적으로 적용하는 방법에 대해 공유하고자 합니다. 이후 적용 과정에 대한 상세한 내용은 후속 글에서 다루도록 하겠습니다.들어가기 앞서, Next.js 기반의 프로젝트에서 다국어 지원을 위해 일반적으로 사용되는 라이브러리에 대해 먼저 살펴보겠습니다.간단한 사용 예시를 보면 다음과 같습니다.이제 이 라이브러리를 활용하여 어떻게 효율적으로 기존 서비스에 국제화를 적용했는지 살펴보도록 하겠습니다.기존 인프런 담당 셀에서 레거시 코드의 React 마이그레이션이 진행을 진행중에 있어서 랠릿 셀은 이미 React로 전환된 코드들에 대한 i18n 적용을 가장 먼저 담당하게 되었습니다. 따라서 다른 셀과 함께 작업 하면서 사용할 효율적인 컨벤션을 먼저 결정할 필요가 있었습니다. 이 과정에서 가장 중요한 초기 결정 사항 중 하나는 다음과 같았습니다.이 문제에 대한 해답을 찾기 위해 다양한 개발자들과의 네트워킹을 하며 인사이트를 얻었습니다. 그 중 기억에 남는 의견이 있었습니다.이 의견에 많은 개발자들이 동의했고, 그 이유를 물어보니 다음과 같은 공통된 피드백을 얻을 수 있었습니다.• 영문 키를 사용할 경우 대응되는 번역 키를 찾는 과정이 번거로움이러한 인사이트를 바탕으로, 랠릿셀은 함께 언어 자원의 키 정의에 대한 세 가지 컨벤션을 수립하고, 각각의 장단점을 분석하여 PM과 PD에게 제안하게 되었습니다.서비스의 국제화를 위한 언어 자원 키 정의 방식을 세 가지로 분류하여 분석했습니다.한국어 텍스트를 그대로 키로 사용하는 방식입니다.• 키 정의 과정 생략 가능• 원본 텍스트 변경 시 키도 함께 수정 필요• 비개발 직군의 낮은 직관성 (URL 구조 이해 필요)최종적으로 을 채택했습니다. 주요 결정 요인은 다음과 같습니다.• 프로젝트의 시간 제약 상황 고려이러한 결정은 빠른 구현과 팀 전체의 효율성을 우선시한 결과였습니다.배경과 아이디어i18next-parser나 i18next-scanner는 i18n이 적용된 코드에서 번역 키를 추출하여 JSON 파일을 생성해주는 기능을 제공합니다.컨벤션도 정해졌으니, 이제 기존에 있던 한글들을 모두 t로 감싸주면 됩니다.이 한숨 앞에서 괜찮은 생각이 스쳐 지나갔습니다.결국 우리는 반복 작업을 줄이려고 개발을 시작한 사람들이니까요.그렇다면… 기나긴 전체 서비스 소스에서 번역 대상이 될 한글 텍스트를 어떻게 찾아내고, 수정할 수 있을까요?백엔드 개발자인 우드가 던진 이 한마디가 스크립트의 출발점이 되었습니다.저희는 Babel에서 제공하는 라이브러리를 이용해 AST 기반으로 소스 코드를 파싱하고, 탐색하고, 수정하기로 했
nodejs
reactjs
2/6/2025
![logo](https://image.wanted.co.kr/optimize?src=https://static.codenary.co.kr/company-logo/4962.png&w=100&q=90)
기존 서비스 국제화(i18n) 작업 쉽게 덜어내기: t 함수 자동 래핑 스크립트 만들기
안녕하세요. 인프랩의 랠릿 셀 프론트엔드 개발자 고슈, 도니, 루시입니다.2024년 초, 연간 플래닝에서 CTO인 향로에게서 예상치 못한 발표를 듣게 됩니다.이렇게 랠릿을 포함한 인프랩 개발파트는 레거시 코드 정리부터 국제화 작업까지, 인프런의 글로벌 서비스 출시를 위한 새로운 도전을 시작하게 되었습니다.i18n을 서비스에 적용하는 전체 과정보다는, 기존 서비스를 다국어 서비스로 전환하는 과정에서 i18n 을 효율적으로 적용하는 방법에 대해 공유하고자 합니다. 이후 적용 과정에 대한 상세한 내용은 후속 글에서 다루도록 하겠습니다.들어가기 앞서, Next.js 기반의 프로젝트에서 다국어 지원을 위해 일반적으로 사용되는 라이브러리에 대해 먼저 살펴보겠습니다.간단한 사용 예시를 보면 다음과 같습니다.이제 이 라이브러리를 활용하여 어떻게 효율적으로 기존 서비스에 국제화를 적용했는지 살펴보도록 하겠습니다.기존 인프런 담당 셀에서 레거시 코드의 React 마이그레이션이 진행을 진행중에 있어서 랠릿 셀은 이미 React로 전환된 코드들에 대한 i18n 적용을 가장 먼저 담당하게 되었습니다. 따라서 다른 셀과 함께 작업 하면서 사용할 효율적인 컨벤션을 먼저 결정할 필요가 있었습니다. 이 과정에서 가장 중요한 초기 결정 사항 중 하나는 다음과 같았습니다.이 문제에 대한 해답을 찾기 위해 다양한 개발자들과의 네트워킹을 하며 인사이트를 얻었습니다. 그 중 기억에 남는 의견이 있었습니다.이 의견에 많은 개발자들이 동의했고, 그 이유를 물어보니 다음과 같은 공통된 피드백을 얻을 수 있었습니다.• 영문 키를 사용할 경우 대응되는 번역 키를 찾는 과정이 번거로움이러한 인사이트를 바탕으로, 랠릿셀은 함께 언어 자원의 키 정의에 대한 세 가지 컨벤션을 수립하고, 각각의 장단점을 분석하여 PM과 PD에게 제안하게 되었습니다.서비스의 국제화를 위한 언어 자원 키 정의 방식을 세 가지로 분류하여 분석했습니다.한국어 텍스트를 그대로 키로 사용하는 방식입니다.• 키 정의 과정 생략 가능• 원본 텍스트 변경 시 키도 함께 수정 필요• 비개발 직군의 낮은 직관성 (URL 구조 이해 필요)최종적으로 을 채택했습니다. 주요 결정 요인은 다음과 같습니다.• 프로젝트의 시간 제약 상황 고려이러한 결정은 빠른 구현과 팀 전체의 효율성을 우선시한 결과였습니다.배경과 아이디어i18next-parser나 i18next-scanner는 i18n이 적용된 코드에서 번역 키를 추출하여 JSON 파일을 생성해주는 기능을 제공합니다.컨벤션도 정해졌으니, 이제 기존에 있던 한글들을 모두 t로 감싸주면 됩니다.이 한숨 앞에서 괜찮은 생각이 스쳐 지나갔습니다.결국 우리는 반복 작업을 줄이려고 개발을 시작한 사람들이니까요.그렇다면… 기나긴 전체 서비스 소스에서 번역 대상이 될 한글 텍스트를 어떻게 찾아내고, 수정할 수 있을까요?백엔드 개발자인 우드가 던진 이 한마디가 스크립트의 출발점이 되었습니다.저희는 Babel에서 제공하는 라이브러리를 이용해 AST 기반으로 소스 코드를 파싱하고, 탐색하고, 수정하기로 했
2025.02.06
nodejs
reactjs
![emoji](https://cdn.jsdelivr.net/npm/emoji-datasource-twitter/img/twitter/64/1f603.png)
좋아요
![emoji](https://cdn.jsdelivr.net/npm/emoji-datasource-twitter/img/twitter/64/1f641.png)
별로에요
![logo](https://image.wanted.co.kr/optimize?src=https://static.codenary.co.kr/company-logo/2826.png&w=100&q=90)
RAG를 활용한 검색 서비스 만들기
안녕하세요! 당근 검색품질팀 ML 엔지니어 해리예요. 👋이 글에서는 RAG를 활용한 검색 서비스인 “동네생활 기반 동네업체 추천” 기능 구현에 사용된 기술에 대해 이야기해보려고 해요.혹시 활동하고 있는 커뮤니티가 있으신가요?커뮤니티는 고향을 떠나 먼 곳으로 대학을 진학한 제게 절대 없어서는 안 될 정보의 창구였어요. 대학 새내기 시절을 돌아보면, 낯선 학교 근처의 맛집이나 듣기 좋은 꿀강의들을 찾기 위해 교내 커뮤니티 게시판을 열심히 뒤지던 기억이 새록새록 떠올라요. 대학원 진학을 준비할 때는 대학원생 커뮤니티에서 각 랩실의 정보를 얻기도 했죠.이처럼 커뮤니티는 우리 생활과 밀접한, 신뢰도 높은 정보들로 가득해요. 하지만 이런 정보들이 여러 게시글에 흩어져 있다 보니, 사용자는 정보를 모으기 위해 다양한 키워드로 검색하고 많은 게시글을 일일이 확인해야 하는 불편함이 있어요.이러한 정보 검색의 불편함은 당근의 동네 커뮤니티인 동네생활에서도 마찬가지였어요. 동네생활에는 “과잉 진료 없는 치과”, “탈색 잘하는 미용실”, “마카롱이 맛있는 카페” 등 동네 이웃들만이 알 수 있는 신뢰도 높은 업체 정보들이 가득하죠. 하지만 이런 정보들이 여러 게시글과 댓글에 흩어져 있어서, 사용자는 1) 적절한 검색어를 입력하고, 2) 게시글과 댓글 내용을 모두 확인하고, 3) 얻은 정보를 취합하는 과정을 거쳐야 해요.이 글에서는 이런 불편을 해결하고자 RAG를 활용해 “동네생활 기반 업체 추천” 서비스를 만들었던 과정을 자세히 소개해보고자 해요.당근 동네생활의 검색은 어떻게 개선될 수 있을까요?이 질문에 답하기 위해 먼저 유저들의 동네생활 검색 패턴을 분석했어요. 분석 결과, 유저들은 동네생활에서 주변 업체 정보를 활발하게 찾아보고 있었어요. 특히 “용달”, “24시 동물병원”과 같은 동네 업체 관련 검색어가 실제 상위 검색어들 중 큰 비중을 차지했죠.하지만 기존 검색 시스템으로는 이런 정보를 효율적으로 찾기가 어려웠어요. 기존에는 당근에 업체 관련 검색어를 입력하면, 그와 관련된 당근 등록 업체들을 최상단에 보여줬어요. 예를 들어, “치과”라는 검색어가 입력되면 사용자의 동네에 등록된 치과들을 검색 결과로 보여준 거죠.물론 “치과”라는 검색어에 치과를 보여주는 것이 틀린 검색 결과라고 볼 수는 없지만, 이 방식으로는 유저의 니즈를 제대로 충족하기 어려워요. 유저들은 “우리 동네 주민들이 추천한 알짜배기 업체”들을 발견하기를 원하는데, 현재 검색은 단순히 “관련 업체 프로필”들을 최상위로 노출하는 데 그치고 있거든요. “유저가 정말 원하는 동네업체 정보는 동네생활에 있다”는 점을 고려하면, 현재 검색에는 동네생활과 동네업체 간의 정보들을 서로 연결해 주는 도구가 없는 셈이에요.이런 문제를 해결하기 위해 우리는 동네생활 검색 시스템을 개선하기로 했어요. 유저들이 원하는 업체 관련 정보를 동네생활에서 더 쉽고 빠르게 찾을 수 있도록 돕는 것이 핵심이었죠. 그래서 RAG(Retrieval Augmented Generation) 기술을 활용해 동네생활의 정보와 업체
2/5/2025
![logo](https://image.wanted.co.kr/optimize?src=https://static.codenary.co.kr/company-logo/2826.png&w=100&q=90)
RAG를 활용한 검색 서비스 만들기
안녕하세요! 당근 검색품질팀 ML 엔지니어 해리예요. 👋이 글에서는 RAG를 활용한 검색 서비스인 “동네생활 기반 동네업체 추천” 기능 구현에 사용된 기술에 대해 이야기해보려고 해요.혹시 활동하고 있는 커뮤니티가 있으신가요?커뮤니티는 고향을 떠나 먼 곳으로 대학을 진학한 제게 절대 없어서는 안 될 정보의 창구였어요. 대학 새내기 시절을 돌아보면, 낯선 학교 근처의 맛집이나 듣기 좋은 꿀강의들을 찾기 위해 교내 커뮤니티 게시판을 열심히 뒤지던 기억이 새록새록 떠올라요. 대학원 진학을 준비할 때는 대학원생 커뮤니티에서 각 랩실의 정보를 얻기도 했죠.이처럼 커뮤니티는 우리 생활과 밀접한, 신뢰도 높은 정보들로 가득해요. 하지만 이런 정보들이 여러 게시글에 흩어져 있다 보니, 사용자는 정보를 모으기 위해 다양한 키워드로 검색하고 많은 게시글을 일일이 확인해야 하는 불편함이 있어요.이러한 정보 검색의 불편함은 당근의 동네 커뮤니티인 동네생활에서도 마찬가지였어요. 동네생활에는 “과잉 진료 없는 치과”, “탈색 잘하는 미용실”, “마카롱이 맛있는 카페” 등 동네 이웃들만이 알 수 있는 신뢰도 높은 업체 정보들이 가득하죠. 하지만 이런 정보들이 여러 게시글과 댓글에 흩어져 있어서, 사용자는 1) 적절한 검색어를 입력하고, 2) 게시글과 댓글 내용을 모두 확인하고, 3) 얻은 정보를 취합하는 과정을 거쳐야 해요.이 글에서는 이런 불편을 해결하고자 RAG를 활용해 “동네생활 기반 업체 추천” 서비스를 만들었던 과정을 자세히 소개해보고자 해요.당근 동네생활의 검색은 어떻게 개선될 수 있을까요?이 질문에 답하기 위해 먼저 유저들의 동네생활 검색 패턴을 분석했어요. 분석 결과, 유저들은 동네생활에서 주변 업체 정보를 활발하게 찾아보고 있었어요. 특히 “용달”, “24시 동물병원”과 같은 동네 업체 관련 검색어가 실제 상위 검색어들 중 큰 비중을 차지했죠.하지만 기존 검색 시스템으로는 이런 정보를 효율적으로 찾기가 어려웠어요. 기존에는 당근에 업체 관련 검색어를 입력하면, 그와 관련된 당근 등록 업체들을 최상단에 보여줬어요. 예를 들어, “치과”라는 검색어가 입력되면 사용자의 동네에 등록된 치과들을 검색 결과로 보여준 거죠.물론 “치과”라는 검색어에 치과를 보여주는 것이 틀린 검색 결과라고 볼 수는 없지만, 이 방식으로는 유저의 니즈를 제대로 충족하기 어려워요. 유저들은 “우리 동네 주민들이 추천한 알짜배기 업체”들을 발견하기를 원하는데, 현재 검색은 단순히 “관련 업체 프로필”들을 최상위로 노출하는 데 그치고 있거든요. “유저가 정말 원하는 동네업체 정보는 동네생활에 있다”는 점을 고려하면, 현재 검색에는 동네생활과 동네업체 간의 정보들을 서로 연결해 주는 도구가 없는 셈이에요.이런 문제를 해결하기 위해 우리는 동네생활 검색 시스템을 개선하기로 했어요. 유저들이 원하는 업체 관련 정보를 동네생활에서 더 쉽고 빠르게 찾을 수 있도록 돕는 것이 핵심이었죠. 그래서 RAG(Retrieval Augmented Generation) 기술을 활용해 동네생활의 정보와 업체
2025.02.05
![emoji](https://cdn.jsdelivr.net/npm/emoji-datasource-twitter/img/twitter/64/1f603.png)
좋아요
![emoji](https://cdn.jsdelivr.net/npm/emoji-datasource-twitter/img/twitter/64/1f641.png)
별로에요
![logo](https://image.wanted.co.kr/optimize?src=https://static.codenary.co.kr/company-logo/1529.png&w=100&q=90)
Spring 기반 멀티모듈 프로젝트 환경변수 설정 방법
roy.ce 카카오페이 서버 개발자가 알려주는 Spring 멀티모듈 환경변수 설정 노하우! 멀티모듈 프로젝트의 복잡성을 줄이고 효율적인 환경 설정을 원한다면 꼭 읽어보세요!zeta.wan 멀티모듈을 잘 활용하면 불필요한 설정을 최소화할 수 있다는 것을 느꼈습니다. 글을 읽는 여러분도 더 나은 방식이 무엇일지 고민하는 시간이 되면 좋겠습니다.안녕하세요. 파트너플랫폼파티에서 서버 개발을 하고 있는 그루(Geuru)입니다. 카카오페이에서는 Spring 기반 멀티모듈 프로젝트로 서비스를 개발하고 있습니다. 그 이유는 요구사항이 여러 가지 추가되면서 특정 목적을 위한 애플리케이션이 필요하거나, 도메인의 확장에 따라 모듈을 추가하기 때문입니다. 모듈을 추가함에 따라 각 모듈별로 필요한 환경변수 설정을 위해 yml 또는 properties 파일을 작성하고 있습니다.입사하고 파트너 도메인에 익숙해지기 위해 여러 프로젝트를 리뷰하면서 알게 된 사실이 있습니다. 팀 내 프로젝트마다 환경변수 설정하는 방법이 미묘하게 다르다는 사실입니다. 더 크게는 팀마다 환경변수 설정하는 방법이 다르고, 취향 차이도 있다는 것입니다.이번 글에서는 제가 사내 여러 프로젝트를 경험해 보면서 알게 된 환경변수 설정방법은 어떤 것들이 있는지 소개해보려고 합니다. 먼저 멀티모듈에서의 환경변수 설정 고민을 말씀드리고, 그 고민을 해결할 수 있는 환경변수 설정 방법 4가지를 알려드리려고 합니다. 그래서 최종적으로 저희는 그 4가지 방법 중 어떤 방법을 선택했으며, 그 이유는 무엇인지 말씀드리려고 합니다.이 글을 읽으시는 독자분께서는 각자의 프로젝트의 환경변수 설정 방법과 본 글에서 소개하는 설정방법을 비교해 보면서, 본인은 어떤 방식을 적용하고 있는지 알아보고 싶은 분들께 이 글을 추천합니다. 또, 이것 외에 다른 방법이 있으면 코멘트도 남겨주세요 😀멀티모듈의 정의와 장점멀티모듈 프로젝트는 여러 개의 모듈로 구성된 프로젝트로, 각 모듈은 독립적으로 빌드되고 배포될 수 있습니다. 멀티모듈로 프로젝트를 구성하는 이유는 코드의 재사용성을 높이고, 모듈 간의 의존성을 명확히 하여 유지보수성을 향상하기 위함입니다.예를 들어, 위와 같이 머니 송금 API를 사용하는 internal-api(사내용 API 모듈), external-api(서비스용 API 모듈)가 있다고 가정하겠습니다. 만약 internal-api, external-api가 각각 단일 모듈로 프로젝트를 구성한다면, 각 프로젝트마다 머니송금용 RestTemplate과 HttpClient 코드와 같은 구현체를 두 번이나 작성하게 될 것입니다.같은 코드 작성 두 번 정도야 할 수 있습니다. 유지보수하거나 신규 서비스 개발 시에는 어떨까요? 만약 머니 송금 API를 사용하는 admin-api(운영자용 API 모듈) 같은 애플리케이션이 늘어난다면, 한 번 더 구현체를 작성해야겠죠? 또, API 버전이 V1에서 V2로 변경되는 스펙 변경이 발생한다면 각 프로젝트마다 해당 내용을 반영해야 합니다.아까 말씀드린 상황을 해결하기 위해 멀티모듈로 구성
spring
2/5/2025
![logo](https://image.wanted.co.kr/optimize?src=https://static.codenary.co.kr/company-logo/1529.png&w=100&q=90)
Spring 기반 멀티모듈 프로젝트 환경변수 설정 방법
roy.ce 카카오페이 서버 개발자가 알려주는 Spring 멀티모듈 환경변수 설정 노하우! 멀티모듈 프로젝트의 복잡성을 줄이고 효율적인 환경 설정을 원한다면 꼭 읽어보세요!zeta.wan 멀티모듈을 잘 활용하면 불필요한 설정을 최소화할 수 있다는 것을 느꼈습니다. 글을 읽는 여러분도 더 나은 방식이 무엇일지 고민하는 시간이 되면 좋겠습니다.안녕하세요. 파트너플랫폼파티에서 서버 개발을 하고 있는 그루(Geuru)입니다. 카카오페이에서는 Spring 기반 멀티모듈 프로젝트로 서비스를 개발하고 있습니다. 그 이유는 요구사항이 여러 가지 추가되면서 특정 목적을 위한 애플리케이션이 필요하거나, 도메인의 확장에 따라 모듈을 추가하기 때문입니다. 모듈을 추가함에 따라 각 모듈별로 필요한 환경변수 설정을 위해 yml 또는 properties 파일을 작성하고 있습니다.입사하고 파트너 도메인에 익숙해지기 위해 여러 프로젝트를 리뷰하면서 알게 된 사실이 있습니다. 팀 내 프로젝트마다 환경변수 설정하는 방법이 미묘하게 다르다는 사실입니다. 더 크게는 팀마다 환경변수 설정하는 방법이 다르고, 취향 차이도 있다는 것입니다.이번 글에서는 제가 사내 여러 프로젝트를 경험해 보면서 알게 된 환경변수 설정방법은 어떤 것들이 있는지 소개해보려고 합니다. 먼저 멀티모듈에서의 환경변수 설정 고민을 말씀드리고, 그 고민을 해결할 수 있는 환경변수 설정 방법 4가지를 알려드리려고 합니다. 그래서 최종적으로 저희는 그 4가지 방법 중 어떤 방법을 선택했으며, 그 이유는 무엇인지 말씀드리려고 합니다.이 글을 읽으시는 독자분께서는 각자의 프로젝트의 환경변수 설정 방법과 본 글에서 소개하는 설정방법을 비교해 보면서, 본인은 어떤 방식을 적용하고 있는지 알아보고 싶은 분들께 이 글을 추천합니다. 또, 이것 외에 다른 방법이 있으면 코멘트도 남겨주세요 😀멀티모듈의 정의와 장점멀티모듈 프로젝트는 여러 개의 모듈로 구성된 프로젝트로, 각 모듈은 독립적으로 빌드되고 배포될 수 있습니다. 멀티모듈로 프로젝트를 구성하는 이유는 코드의 재사용성을 높이고, 모듈 간의 의존성을 명확히 하여 유지보수성을 향상하기 위함입니다.예를 들어, 위와 같이 머니 송금 API를 사용하는 internal-api(사내용 API 모듈), external-api(서비스용 API 모듈)가 있다고 가정하겠습니다. 만약 internal-api, external-api가 각각 단일 모듈로 프로젝트를 구성한다면, 각 프로젝트마다 머니송금용 RestTemplate과 HttpClient 코드와 같은 구현체를 두 번이나 작성하게 될 것입니다.같은 코드 작성 두 번 정도야 할 수 있습니다. 유지보수하거나 신규 서비스 개발 시에는 어떨까요? 만약 머니 송금 API를 사용하는 admin-api(운영자용 API 모듈) 같은 애플리케이션이 늘어난다면, 한 번 더 구현체를 작성해야겠죠? 또, API 버전이 V1에서 V2로 변경되는 스펙 변경이 발생한다면 각 프로젝트마다 해당 내용을 반영해야 합니다.아까 말씀드린 상황을 해결하기 위해 멀티모듈로 구성
2025.02.05
spring
![emoji](https://cdn.jsdelivr.net/npm/emoji-datasource-twitter/img/twitter/64/1f603.png)
좋아요
![emoji](https://cdn.jsdelivr.net/npm/emoji-datasource-twitter/img/twitter/64/1f641.png)
별로에요
![logo](https://image.wanted.co.kr/optimize?src=https://static.codenary.co.kr/company-logo/375.png&w=100&q=90)
AI 학습을 위한 LLM 스터디 - 배치 전략 및 어텐션 개선 방안
LLM에 대해 아무것도 모른채로 공부하고 싶은 마음에 LLM 스터디 (딥그라운드)에서 좋은 기회로 이렇게 제가 공부한 부분에 대해 정리 하게 되었습니다.사실 AI라는 분야가 워낙 방대해서 처음에는 어디서부터 시작해야 할지 막막했어요.하지만 조금씩 공부하다 보니 재미있는 부분들이 많이 보이더라구요.부족한 점이 많겠지만, 저와 비슷한 초보자 분들에게 조금이나마 도움이 되었으면 좋겠어요.• None 입력 데이터 추론 시, 한번에 많은 데이터를 받으면 좋겠지만, 한번의 하나씩 토큰을 생성하고 입력에 따라 몇의 토큰을 추가할 지 예상하기 어려워 데이터 처리에 전략이 필요하다.• None 일반배치, 또는 정적배치는 전통적인 배치 처리 방식입니다. 이 방법은 고정된 크기의 입력 배치를 한 번에 처리합니다 하지만 이 방식에는 몇 가지 단점이 있습니다:• None 배치 내 각 요청이 서로 다른 수의 완료 토큰을 생성할 수 있어 실행 시간이 달라집니다.• None 모든 요청은 가장 긴 요청이 완료될 때까지 기다려야 합니다.• None 생성 길이의 큰 차이로 인해 성능이 저하될 수 있습니다.• None 동적배치는 정적배치의 단점을 보완하기 위한 방법입니다. 이 방식은 입력의 길이와 복잡성에 따라 배치 크기를 동적으로 조정합니다. 이를 통해:• None 다양한 길이의 입력을 효율적으로 처리할 수 있습니다.• None 연속배치, 또는 인-플라이트 배칭은 정적배치의 문제를 해결하기 위한 또 다른 접근 방식입니다. 이 방법의 특징은:• None 요청이 도착하는 대로 처리를 시작합니다.• None 진행 중인 요청과 새로운 요청을 동적으로 결합합니다.• None 각 요청의 완료 시간을 개별적으로 관리합니다. 이 방식을 통해 대기 시간을 줄이고 전체적인 처리량을 향상시킬 수 있습니다.플래시 어텐션(FlashAttention)은 트랜스포머 모델의 핵심 요소인 어텐션 메커니즘을 크게 개선한 혁신적인 알고리즘입니다.이 기술은 대규모 언어 모델(LLM)과 긴 컨텍스트를 다루는 애플리케이션에서 성능 병목 현상을 해결하는 데 중요한 역할을 합니다.• None 입력 준비: 입력 시퀀스를 세 개의 벡터로 변환합니다 - 쿼리(Q), 키(K), 값(V).• None 유사도 계산: 쿼리와 키 사이의 유사도를 계산합니다. 이는 두 벡터의 내적(dot product)으로 이루어집니다.• None 스케일링: 유사도 점수를 키의 차원의 제곱근으로 나눕니다. 이는 값이 너무 커지는 것을 방지합니다.플래시 어텐션은 다음과 같은 핵심 원리를 바탕으로 작동합니다:• None 메모리 최적화: 어텐션 연산을 재배치하고 타일링 기법을 사용하여 메모리 사용량을 시퀀스 길이에 따라 제곱에서 선형으로 줄입니다.• None 타일링 기법: GPU의 주 메모리(HBM)에서 빠른 캐시(SRAM)로 입력 데이터 블록을 로드하여 처리합니다. 중간 결과 최소화: 큰 중간 어텐션 행렬을 HBM에 저장하지 않아 메모리 읽기/쓰기를 줄입니다.• None 재계산 활용: 필요한 경우 중간 결과를 재계산하여 메모리 사용을 줄입니다.•
2/5/2025
![logo](https://image.wanted.co.kr/optimize?src=https://static.codenary.co.kr/company-logo/375.png&w=100&q=90)
AI 학습을 위한 LLM 스터디 - 배치 전략 및 어텐션 개선 방안
LLM에 대해 아무것도 모른채로 공부하고 싶은 마음에 LLM 스터디 (딥그라운드)에서 좋은 기회로 이렇게 제가 공부한 부분에 대해 정리 하게 되었습니다.사실 AI라는 분야가 워낙 방대해서 처음에는 어디서부터 시작해야 할지 막막했어요.하지만 조금씩 공부하다 보니 재미있는 부분들이 많이 보이더라구요.부족한 점이 많겠지만, 저와 비슷한 초보자 분들에게 조금이나마 도움이 되었으면 좋겠어요.• None 입력 데이터 추론 시, 한번에 많은 데이터를 받으면 좋겠지만, 한번의 하나씩 토큰을 생성하고 입력에 따라 몇의 토큰을 추가할 지 예상하기 어려워 데이터 처리에 전략이 필요하다.• None 일반배치, 또는 정적배치는 전통적인 배치 처리 방식입니다. 이 방법은 고정된 크기의 입력 배치를 한 번에 처리합니다 하지만 이 방식에는 몇 가지 단점이 있습니다:• None 배치 내 각 요청이 서로 다른 수의 완료 토큰을 생성할 수 있어 실행 시간이 달라집니다.• None 모든 요청은 가장 긴 요청이 완료될 때까지 기다려야 합니다.• None 생성 길이의 큰 차이로 인해 성능이 저하될 수 있습니다.• None 동적배치는 정적배치의 단점을 보완하기 위한 방법입니다. 이 방식은 입력의 길이와 복잡성에 따라 배치 크기를 동적으로 조정합니다. 이를 통해:• None 다양한 길이의 입력을 효율적으로 처리할 수 있습니다.• None 연속배치, 또는 인-플라이트 배칭은 정적배치의 문제를 해결하기 위한 또 다른 접근 방식입니다. 이 방법의 특징은:• None 요청이 도착하는 대로 처리를 시작합니다.• None 진행 중인 요청과 새로운 요청을 동적으로 결합합니다.• None 각 요청의 완료 시간을 개별적으로 관리합니다. 이 방식을 통해 대기 시간을 줄이고 전체적인 처리량을 향상시킬 수 있습니다.플래시 어텐션(FlashAttention)은 트랜스포머 모델의 핵심 요소인 어텐션 메커니즘을 크게 개선한 혁신적인 알고리즘입니다.이 기술은 대규모 언어 모델(LLM)과 긴 컨텍스트를 다루는 애플리케이션에서 성능 병목 현상을 해결하는 데 중요한 역할을 합니다.• None 입력 준비: 입력 시퀀스를 세 개의 벡터로 변환합니다 - 쿼리(Q), 키(K), 값(V).• None 유사도 계산: 쿼리와 키 사이의 유사도를 계산합니다. 이는 두 벡터의 내적(dot product)으로 이루어집니다.• None 스케일링: 유사도 점수를 키의 차원의 제곱근으로 나눕니다. 이는 값이 너무 커지는 것을 방지합니다.플래시 어텐션은 다음과 같은 핵심 원리를 바탕으로 작동합니다:• None 메모리 최적화: 어텐션 연산을 재배치하고 타일링 기법을 사용하여 메모리 사용량을 시퀀스 길이에 따라 제곱에서 선형으로 줄입니다.• None 타일링 기법: GPU의 주 메모리(HBM)에서 빠른 캐시(SRAM)로 입력 데이터 블록을 로드하여 처리합니다. 중간 결과 최소화: 큰 중간 어텐션 행렬을 HBM에 저장하지 않아 메모리 읽기/쓰기를 줄입니다.• None 재계산 활용: 필요한 경우 중간 결과를 재계산하여 메모리 사용을 줄입니다.•
2025.02.05
![emoji](https://cdn.jsdelivr.net/npm/emoji-datasource-twitter/img/twitter/64/1f603.png)
좋아요
![emoji](https://cdn.jsdelivr.net/npm/emoji-datasource-twitter/img/twitter/64/1f641.png)
별로에요
![logo](https://image.wanted.co.kr/optimize?src=https://static.codenary.co.kr/company-logo/1246.png&w=100&q=90)
FE News 25년 2월 소식을 전해드립니다!
주요내용25년 2월 소식에서는 다음과 같은 유용한 정보들을 만나보실 수 있습니다.Cascading Spy Sheets: Exploiting the Complexity of Modern CSS for Email and Browser FingerprintingJavascript와 Cookie 없이 CSS만으로 브라우저 지문 채취의 가능함이 증명되었습니다The Ai-Assisted Developer Workflow: Build Faster and Smarter TodayAI를 활용한 다양한 개발 도구가 어떻게 개발 방식을 변화시킬 수 있는지 알아봅니다.Toss Frontend Fundamentals토스의 프런트엔드 개발자들이 공개한 변경하기 쉬운 프론트엔드 코드를 위한 지침서Do JavaScript frameworks still need portals?Dialog, popover, CSS anchor positioning 등의 기능으로 Portal(React), Teleport(Vue) 를 대체하는 방법을 소개합니다.>> FE News 25년 2월 소식 보러가기 ◎ FE News란? 네이버 FE 엔지니어들이 엄선한 양질의 FE 및 주요한 기술 소식들을 큐레이션해 공유하는 것을 목표로 하며, 이를 통해 국내 개발자들에게 지식 공유에 대한 가치 인식과 성장에 도움을 주고자 하는 기술소식 공유 프로젝트 입니다.매월 첫째 주 수요일, 월 1회 발행 되고 있으니 많은 관심 부탁드립니다.▷ 구독하기
2/4/2025
![logo](https://image.wanted.co.kr/optimize?src=https://static.codenary.co.kr/company-logo/1246.png&w=100&q=90)
FE News 25년 2월 소식을 전해드립니다!
주요내용25년 2월 소식에서는 다음과 같은 유용한 정보들을 만나보실 수 있습니다.Cascading Spy Sheets: Exploiting the Complexity of Modern CSS for Email and Browser FingerprintingJavascript와 Cookie 없이 CSS만으로 브라우저 지문 채취의 가능함이 증명되었습니다The Ai-Assisted Developer Workflow: Build Faster and Smarter TodayAI를 활용한 다양한 개발 도구가 어떻게 개발 방식을 변화시킬 수 있는지 알아봅니다.Toss Frontend Fundamentals토스의 프런트엔드 개발자들이 공개한 변경하기 쉬운 프론트엔드 코드를 위한 지침서Do JavaScript frameworks still need portals?Dialog, popover, CSS anchor positioning 등의 기능으로 Portal(React), Teleport(Vue) 를 대체하는 방법을 소개합니다.>> FE News 25년 2월 소식 보러가기 ◎ FE News란? 네이버 FE 엔지니어들이 엄선한 양질의 FE 및 주요한 기술 소식들을 큐레이션해 공유하는 것을 목표로 하며, 이를 통해 국내 개발자들에게 지식 공유에 대한 가치 인식과 성장에 도움을 주고자 하는 기술소식 공유 프로젝트 입니다.매월 첫째 주 수요일, 월 1회 발행 되고 있으니 많은 관심 부탁드립니다.▷ 구독하기
2025.02.04
![emoji](https://cdn.jsdelivr.net/npm/emoji-datasource-twitter/img/twitter/64/1f603.png)
좋아요
![emoji](https://cdn.jsdelivr.net/npm/emoji-datasource-twitter/img/twitter/64/1f641.png)
별로에요