logo
emoji
검색하기
어제 가장 많이 검색된 기술
emoji
가장 많이 읽은 글
logo
멀티턴에서 답변을 잘하는 Agent 만들기 - 쿼리 재작성(Query Rewriting)
이번 블로그는 사내 Agent를 개선하면서 고민 했던 사례와 제가 적용해 보았던 Query Rewriting 사례를 공유하고자 합니다.엔터프라이즈 환경에서 LLM을 활용해본 분들이라면 RAG(Retrieval-Augmented Generation, 검색 증강 생성) 라는 용어가 매우 익숙하실 겁니다.기업의 모든 절차는 외부 검색이나 LLM 자체의 지식이 아닌, 내부 문서, 사규, 공동 작업 문서를 기반으로 답변해야 하기 때문에 RAG는 선택이 아닌 필수 기술로 자리 잡았죠.RAG를 처음 구성하고 단일 질문을 던져보면, 놀라울 정도로 정확하고 신뢰도 높은 답변을 제공합니다.하지만 사용자와 AI의 대화가 여러 차례 이어지는 멀티턴(Multi-turn) 상황에 들어서면 이야기는 완전히 달라집니다.RAG 챗봇을 개발해본 사람이라면 누구나 겪어봤을 답답한 순간입니다.사용자는 분명 '육아 휴직' 에 대해 묻고 있는데, AI는 엉뚱하게 '의료 지원'이나 '교육 지원'에 대한 답을 내놓습니다.왜 이런 문제가 발생할까요?문제의 핵심은 RAG 파이프라인의 문서 검색 단계에 있습니다.AI는 "아이는 몇 명까지 지원돼?" 라는 질문 그 자체만 보고, 대화의 맥락('육아 휴직')을 놓친 채 '아이 수'와 관련된 모든 문서를 찾아내기 때문입니다.이러한 한계를 극복하고 똑똑한 대화형 AI를 만들기 위한 핵심 열쇠가 바로 쿼리 재작성(Query Rewriting) 입니다.💡 해결책: 검색 전에 질문부터 다듬어라! 쿼리 재작성(Query Rewriting)쿼리 재작성은 사용자의 질문을 검색 시스템이 가장 잘 이해할 수 있는 형태로 변환하는 과정입니다.이전 대화 기록과 현재 질문을 함께 고려하여, 맥락이 누락된 질문을 완전한 형태의 질문으로 다시 만들어주는 것이죠.단순히 이전 대화를 기억하지 못하는 문제를 넘어, 대화형 RAG 시스템은 다음과 같은 복합적인 과제를 안고 있습니다.• None 문맥적 모호성 (Contextual Ambiguity): 사용자는 "그건?", "다른 옵션은?"처럼 핵심 정보를 생략하는 경우가 많습니다. 시스템은 이런 문맥 의존적인 질문을 그 자체로 완전한 의미를 갖는 독립적인 형태로 변환해야 합니다.• None 의도의 진화 (Intent Evolution): '노트북 가격'을 묻던 사용자가 다음엔 '성능 비교', 그다음엔 '사용자 후기'를 물어보는 것처럼, 대화가 진행됨에 따라 변화하는 사용자의 의도를 실시간으로 추적해야 합니다.• None 정보 손실 및 최신 편향 (Information Loss & Recency Bias): LLM은 긴 대화의 초기 내용을 잊고, 가장 최근 질문에만 집중하는 경향이 있습니다. 이로 인해 전체 흐름을 무시한 단편적인 답변을 내놓을 수 있습니다.이러한 문제들을 해결하기 위해, 현대적인 RAG 아키텍처는 검색 단계 이전에 쿼리 재작성(Query Rewriter) 모듈을 도입합니다.이 모듈은 사용자의 질문과 대화 기록을 받아, Vector DB 같은 정보 검색 시스템에 가장 효과적인, 명확하고 구체적인 검색 쿼리를 생성하는 역할을 담당합니다.그렇다면 쿼리를 '잘' 재작성하는 데에는 어떤 기법들이 있을까요? 대표적인 세 가지 방법을 소개합니다.복잡한 질문에 바로 답하는 대신, 의도적으로 한 걸음 물러나(step back) 더 근본적이고 추상적인 상위 개념의 질문을 먼저 생성하는 기법입니다.예를 들어, "특정 물리학 문제를 푸는 방법"을 묻는 대신, "이 문제에 적용되는 물리 법칙은 무엇인가?" 라는 근본적인 질문을 먼저 생성하고 검색하는 식이죠.이렇게 얻은 배경 지식은 LLM이 더 깊이 있는 추론을 통해 정확한 답변을 도출하는 데 결정적인 단서가 됩니다.• None 👍 장점: 복잡한 추론이 필요한 전문 분야(과학, 법률 등)에서 답변의 깊이와 정확성을 높여줍니다.• None 👎 단점: 효과적인 상위 질문을 만들기 위한 프롬프트 설계가 까다롭고, 추가 LLM 호출로 인해 응답 시간과 비용이 증가합니다.정보 검색의 패러다임을 '질문-문서 유사도'에서 '답변-문서 유사도' 로 전환하는 혁신적인 접근법입니다.사용자의 질문을 받으면, LLM이 먼저 그 질문에 대한 **이상적인 '가상의 답변'**을 생성합니다. 그리고 이 가상 답변과 가장 유사한 실제 문서를 찾아내는 것이죠.질문(의문문)과 문서(평서문) 사이의 표현 차이를 극복하고, 의미의 핵심이 유사한 문서를 더 효과적으로 찾아낼 수 있습니다.• None 👍 장점: 사용자의 질문이 모호하거나 키워드가 부족할 때, 의미적 의도를 파악하여 예상치 못한 관련 문서를 발굴하는 데 강력합니다.• None 👎 단점: LLM이 전혀 모르는 최신 정보나 전문 용어에는 엉뚱한 가상 답변을 생성하여 오히려 검색 성능을 저하시킬 수 있습니다.3. Multi-Query & RAG-Fusion: 질문을 쪼개고 결과를 합치기"최근 레드삭스와 패트리어츠 중 어느 팀이 더 최근에 우승했나요?"와 같은 복잡한 질문은 사실 여러 개의 하위 질문("레드삭스의 마지막 우승 연도는?", "패트리어츠의 마지막 우승 연도는?")을 내포하고 있습니다.Multi-Query는 이처럼 복합적인 질문을 여러 개의 단일 관점 쿼리로 분해하는 전략입니다.RAG-Fusion은 여기서 한 단계 더 나아가, 각 쿼리에 대해 독립적으로 검색을 수행한 후,그 결과들을 지능적인 알고리즘(Reciprocal Rank Fusion)으로 융합(Fusion)하여 최종적으로 가장 관련성 높은 문서 순위를 결정합니다.• None 👍 장점: 여러 정보를 동시에 묻거나 비교가 필요한 질문에 대해, 놓치는 정보 없이 포괄적인 검색을 수행하여 신뢰성을 높입니다.• None 👎 단점: 여러 번의 쿼리 생성 및 검색으로 인해 응답 시간과 비용이 가장 크게 증가할 수 있습니다.지금까지 소개된 기법을 모든 쿼리에 일괄적으로 적용하는 것은 비효율적일 수 있습니다.때로는 사용자의 원본 질문 자체가 가장 좋은 검색어일 수도 있으니까요.최근 RAG 연구는 쿼리의 특성에 따라 최적의 처리 방식을 동적으로 결정하는 '적응형(Adaptive)' 아키텍처로 나아가고 있습니다.파이프라인 가장 앞단에 '라우터(R
9/5/2025
logo
멀티턴에서 답변을 잘하는 Agent 만들기 - 쿼리 재작성(Query Rewriting)
이번 블로그는 사내 Agent를 개선하면서 고민 했던 사례와 제가 적용해 보았던 Query Rewriting 사례를 공유하고자 합니다.엔터프라이즈 환경에서 LLM을 활용해본 분들이라면 RAG(Retrieval-Augmented Generation, 검색 증강 생성) 라는 용어가 매우 익숙하실 겁니다.기업의 모든 절차는 외부 검색이나 LLM 자체의 지식이 아닌, 내부 문서, 사규, 공동 작업 문서를 기반으로 답변해야 하기 때문에 RAG는 선택이 아닌 필수 기술로 자리 잡았죠.RAG를 처음 구성하고 단일 질문을 던져보면, 놀라울 정도로 정확하고 신뢰도 높은 답변을 제공합니다.하지만 사용자와 AI의 대화가 여러 차례 이어지는 멀티턴(Multi-turn) 상황에 들어서면 이야기는 완전히 달라집니다.RAG 챗봇을 개발해본 사람이라면 누구나 겪어봤을 답답한 순간입니다.사용자는 분명 '육아 휴직' 에 대해 묻고 있는데, AI는 엉뚱하게 '의료 지원'이나 '교육 지원'에 대한 답을 내놓습니다.왜 이런 문제가 발생할까요?문제의 핵심은 RAG 파이프라인의 문서 검색 단계에 있습니다.AI는 "아이는 몇 명까지 지원돼?" 라는 질문 그 자체만 보고, 대화의 맥락('육아 휴직')을 놓친 채 '아이 수'와 관련된 모든 문서를 찾아내기 때문입니다.이러한 한계를 극복하고 똑똑한 대화형 AI를 만들기 위한 핵심 열쇠가 바로 쿼리 재작성(Query Rewriting) 입니다.💡 해결책: 검색 전에 질문부터 다듬어라! 쿼리 재작성(Query Rewriting)쿼리 재작성은 사용자의 질문을 검색 시스템이 가장 잘 이해할 수 있는 형태로 변환하는 과정입니다.이전 대화 기록과 현재 질문을 함께 고려하여, 맥락이 누락된 질문을 완전한 형태의 질문으로 다시 만들어주는 것이죠.단순히 이전 대화를 기억하지 못하는 문제를 넘어, 대화형 RAG 시스템은 다음과 같은 복합적인 과제를 안고 있습니다.• None 문맥적 모호성 (Contextual Ambiguity): 사용자는 "그건?", "다른 옵션은?"처럼 핵심 정보를 생략하는 경우가 많습니다. 시스템은 이런 문맥 의존적인 질문을 그 자체로 완전한 의미를 갖는 독립적인 형태로 변환해야 합니다.• None 의도의 진화 (Intent Evolution): '노트북 가격'을 묻던 사용자가 다음엔 '성능 비교', 그다음엔 '사용자 후기'를 물어보는 것처럼, 대화가 진행됨에 따라 변화하는 사용자의 의도를 실시간으로 추적해야 합니다.• None 정보 손실 및 최신 편향 (Information Loss & Recency Bias): LLM은 긴 대화의 초기 내용을 잊고, 가장 최근 질문에만 집중하는 경향이 있습니다. 이로 인해 전체 흐름을 무시한 단편적인 답변을 내놓을 수 있습니다.이러한 문제들을 해결하기 위해, 현대적인 RAG 아키텍처는 검색 단계 이전에 쿼리 재작성(Query Rewriter) 모듈을 도입합니다.이 모듈은 사용자의 질문과 대화 기록을 받아, Vector DB 같은 정보 검색 시스템에 가장 효과적인, 명확하고 구체적인 검색 쿼리를 생성하는 역할을 담당합니다.그렇다면 쿼리를 '잘' 재작성하는 데에는 어떤 기법들이 있을까요? 대표적인 세 가지 방법을 소개합니다.복잡한 질문에 바로 답하는 대신, 의도적으로 한 걸음 물러나(step back) 더 근본적이고 추상적인 상위 개념의 질문을 먼저 생성하는 기법입니다.예를 들어, "특정 물리학 문제를 푸는 방법"을 묻는 대신, "이 문제에 적용되는 물리 법칙은 무엇인가?" 라는 근본적인 질문을 먼저 생성하고 검색하는 식이죠.이렇게 얻은 배경 지식은 LLM이 더 깊이 있는 추론을 통해 정확한 답변을 도출하는 데 결정적인 단서가 됩니다.• None 👍 장점: 복잡한 추론이 필요한 전문 분야(과학, 법률 등)에서 답변의 깊이와 정확성을 높여줍니다.• None 👎 단점: 효과적인 상위 질문을 만들기 위한 프롬프트 설계가 까다롭고, 추가 LLM 호출로 인해 응답 시간과 비용이 증가합니다.정보 검색의 패러다임을 '질문-문서 유사도'에서 '답변-문서 유사도' 로 전환하는 혁신적인 접근법입니다.사용자의 질문을 받으면, LLM이 먼저 그 질문에 대한 **이상적인 '가상의 답변'**을 생성합니다. 그리고 이 가상 답변과 가장 유사한 실제 문서를 찾아내는 것이죠.질문(의문문)과 문서(평서문) 사이의 표현 차이를 극복하고, 의미의 핵심이 유사한 문서를 더 효과적으로 찾아낼 수 있습니다.• None 👍 장점: 사용자의 질문이 모호하거나 키워드가 부족할 때, 의미적 의도를 파악하여 예상치 못한 관련 문서를 발굴하는 데 강력합니다.• None 👎 단점: LLM이 전혀 모르는 최신 정보나 전문 용어에는 엉뚱한 가상 답변을 생성하여 오히려 검색 성능을 저하시킬 수 있습니다.3. Multi-Query & RAG-Fusion: 질문을 쪼개고 결과를 합치기"최근 레드삭스와 패트리어츠 중 어느 팀이 더 최근에 우승했나요?"와 같은 복잡한 질문은 사실 여러 개의 하위 질문("레드삭스의 마지막 우승 연도는?", "패트리어츠의 마지막 우승 연도는?")을 내포하고 있습니다.Multi-Query는 이처럼 복합적인 질문을 여러 개의 단일 관점 쿼리로 분해하는 전략입니다.RAG-Fusion은 여기서 한 단계 더 나아가, 각 쿼리에 대해 독립적으로 검색을 수행한 후,그 결과들을 지능적인 알고리즘(Reciprocal Rank Fusion)으로 융합(Fusion)하여 최종적으로 가장 관련성 높은 문서 순위를 결정합니다.• None 👍 장점: 여러 정보를 동시에 묻거나 비교가 필요한 질문에 대해, 놓치는 정보 없이 포괄적인 검색을 수행하여 신뢰성을 높입니다.• None 👎 단점: 여러 번의 쿼리 생성 및 검색으로 인해 응답 시간과 비용이 가장 크게 증가할 수 있습니다.지금까지 소개된 기법을 모든 쿼리에 일괄적으로 적용하는 것은 비효율적일 수 있습니다.때로는 사용자의 원본 질문 자체가 가장 좋은 검색어일 수도 있으니까요.최근 RAG 연구는 쿼리의 특성에 따라 최적의 처리 방식을 동적으로 결정하는 '적응형(Adaptive)' 아키텍처로 나아가고 있습니다.파이프라인 가장 앞단에 '라우터(R
2025.09.05
emoji
좋아요
emoji
별로에요
logo
고등학생도 이해하는 Transformer (Deep Learning) #6 - Deep Learning이란
고등학생도 이해하는 Transformer (Deep Learning) #1고등학생도 이해하는 Transformer (Deep Learning) #2고등학생도 이해하는 Transformer (Deep Learning) #3고등학생도 이해하는 Transformer (Deep Learning) #4고등학생도 이해하는 Transformer (Deep Learning) #5이전 5편에서는 Linear Layer를 이용한 손글씨 분류기를 만들어 보았습니다.사실 아직 Deep Learning이 아니라 Machine Learning으로만 이야기 하고 있습니다.그럼 AI(Artificial Intelligence), ML(Machine Learning)과 DL(Deep Learning)이 무슨 차이일 까요?아래 그림과 같이 AI 부류 안에 ML(기계학습)과 DL(심층학습)이 속해 있어요이전 강의의 손글씨 분류기는 왜 ML이지 DL이 아닐까요?ML은 어떤 Model에 데이터를 입력해서 결과가 나오는 구조이고, DL은 이 모델이 Deep 하게 심층 구조로 되어 있는게 특징입니다.Deep 이 뭔지 다시 이야기 해보겠습니다. Deep Learning은 그림과 같이 모델안에 Layer가 여러개 있어서 Deep 한 구조인데요,5편에서는 Linear Layer를 사용한 모델이 Deep Learning이 아니라고 했습니다.5편의 손글씨 분류기는 Linear Layer 1개만 사용했는데요, Deep게 한번 Linear Layer를 여러개 추가 하면 DL이 될까요?Linear Layer를 a(x)=Ax+B 라고 정의하고, a(x), b(x), c(x) 의 Layer를 3개 추가 한다고 하면, y = a(b(c(x))) 로 구성 할 수 있습니다.a(b(c(x))) 를 풀어서 합성해보면 a(b(c(x))) = d(x) 로 풀어볼 수 있습니다.이를 설명하면 선형함수들의 합성은 선형함수가 됩니다. 이 뜻은 아무리 Linear Layer를 여러 층으로 쌓아보아도 하나의 Linear Layer로 합성되기 때문입니다. 이를 이용한것이 LLM Fine Tuning방법중에 하나인 LoRA(Low-Rank Adaptation) 입니다. (이야기가 또 다른데로 샐뻔 했네요. LoRA는 나중에 다시 설명드릴께요)따라서 Linear Layer를 여러 개층으로 쌓아도 결국 하나의 Layer 통과한 것과 동일합니다. 이러한 문제를 막고, 여러 레이어를 통과할 수 있도록 하는 방법이 각 레이어 사이에 Non-Linear 함수를 추가해서 함성함수가 안되도록 하는 방법입니다.대표적인 Non-Linear 함수는 ReLU(Rectified Linear Unit) 함수 입니다. 아래 수식 및 그림과 같이 생겼습니다. 각 Linear Layer 사이에 이 Non-Linear 함수를 추가하여 Deep 하게 계층을 쌓으면, 수식을 전개 하거나 함성 함수로 간략화 할 수가 없게 됩니다. 이러한 Layer 사이에 추가 되는 Non-Linear Layer를 Activation Function 이라고 부릅니다.ReLU 함수를 r(x) 라고 하면 a(r(b(r(c))) = y 로 모델을 구성하면 수식을 전개해서 함성 함수를 생성 할 수 없이 구성 할 수 있게 됩니다. 이러한 구조를 생물학적 신경 구조를 본따서 만들어서 신경망(Neural Network)으로 불리기도 합니다. 'Dendrite(덴드라이트)'는 '나뭇가지 모양으로 부터 여러 입력을 받아 세포체(Nucleus)에서 입력을 더해서 시냅스를 통해 전달 됩니다. 이러한 Neuron이 모여서 뇌신경망을 구성하게 되는데요 여러 입력 을 받아 출력값을 다음으로 전달하여 사고 및 판단하는 구조에서 본따서 인공 신경망도 여러 입력을 받아, 곱하고 더해서 출력하게 되는 구조로 설계 되었습니다. 여러 입력을 받아서 연산을 수행하고 다시 다음 레이어로 전달하는 구조가 아주 유사합니다.이러한 Linear Layer와 Non-Linear Layer를 중첩하여 Deep 한 네트워크를 구성 하여 뇌의 사고와 같은 복잡한 사고를 구성 할 수 있게 되었습니다.• None Deep Learning은 Linear Layer와 Non-Linear Layer를 중첩하여 Deep 한 구조로 되어 있다.• None 이러한 Deep 한 구조는 뇌신경망을 참고하였다.• None Linear Layer로만 Deep 하게(여러 레이어로) 구성하면, 하나의 Linear Layer로 합성 될 수 있으며, 이를 방지하는 것이 Activation Function이다. Activation Function(Non-Linear Layer)로 복수의 Linear Layer들이 하나의 Layer로 합성되는 것을 방지하여 Deep 한, 깊은 구조의 Model 을 구성할 수 있다.
9/5/2025
logo
고등학생도 이해하는 Transformer (Deep Learning) #6 - Deep Learning이란
고등학생도 이해하는 Transformer (Deep Learning) #1고등학생도 이해하는 Transformer (Deep Learning) #2고등학생도 이해하는 Transformer (Deep Learning) #3고등학생도 이해하는 Transformer (Deep Learning) #4고등학생도 이해하는 Transformer (Deep Learning) #5이전 5편에서는 Linear Layer를 이용한 손글씨 분류기를 만들어 보았습니다.사실 아직 Deep Learning이 아니라 Machine Learning으로만 이야기 하고 있습니다.그럼 AI(Artificial Intelligence), ML(Machine Learning)과 DL(Deep Learning)이 무슨 차이일 까요?아래 그림과 같이 AI 부류 안에 ML(기계학습)과 DL(심층학습)이 속해 있어요이전 강의의 손글씨 분류기는 왜 ML이지 DL이 아닐까요?ML은 어떤 Model에 데이터를 입력해서 결과가 나오는 구조이고, DL은 이 모델이 Deep 하게 심층 구조로 되어 있는게 특징입니다.Deep 이 뭔지 다시 이야기 해보겠습니다. Deep Learning은 그림과 같이 모델안에 Layer가 여러개 있어서 Deep 한 구조인데요,5편에서는 Linear Layer를 사용한 모델이 Deep Learning이 아니라고 했습니다.5편의 손글씨 분류기는 Linear Layer 1개만 사용했는데요, Deep게 한번 Linear Layer를 여러개 추가 하면 DL이 될까요?Linear Layer를 a(x)=Ax+B 라고 정의하고, a(x), b(x), c(x) 의 Layer를 3개 추가 한다고 하면, y = a(b(c(x))) 로 구성 할 수 있습니다.a(b(c(x))) 를 풀어서 합성해보면 a(b(c(x))) = d(x) 로 풀어볼 수 있습니다.이를 설명하면 선형함수들의 합성은 선형함수가 됩니다. 이 뜻은 아무리 Linear Layer를 여러 층으로 쌓아보아도 하나의 Linear Layer로 합성되기 때문입니다. 이를 이용한것이 LLM Fine Tuning방법중에 하나인 LoRA(Low-Rank Adaptation) 입니다. (이야기가 또 다른데로 샐뻔 했네요. LoRA는 나중에 다시 설명드릴께요)따라서 Linear Layer를 여러 개층으로 쌓아도 결국 하나의 Layer 통과한 것과 동일합니다. 이러한 문제를 막고, 여러 레이어를 통과할 수 있도록 하는 방법이 각 레이어 사이에 Non-Linear 함수를 추가해서 함성함수가 안되도록 하는 방법입니다.대표적인 Non-Linear 함수는 ReLU(Rectified Linear Unit) 함수 입니다. 아래 수식 및 그림과 같이 생겼습니다. 각 Linear Layer 사이에 이 Non-Linear 함수를 추가하여 Deep 하게 계층을 쌓으면, 수식을 전개 하거나 함성 함수로 간략화 할 수가 없게 됩니다. 이러한 Layer 사이에 추가 되는 Non-Linear Layer를 Activation Function 이라고 부릅니다.ReLU 함수를 r(x) 라고 하면 a(r(b(r(c))) = y 로 모델을 구성하면 수식을 전개해서 함성 함수를 생성 할 수 없이 구성 할 수 있게 됩니다. 이러한 구조를 생물학적 신경 구조를 본따서 만들어서 신경망(Neural Network)으로 불리기도 합니다. 'Dendrite(덴드라이트)'는 '나뭇가지 모양으로 부터 여러 입력을 받아 세포체(Nucleus)에서 입력을 더해서 시냅스를 통해 전달 됩니다. 이러한 Neuron이 모여서 뇌신경망을 구성하게 되는데요 여러 입력 을 받아 출력값을 다음으로 전달하여 사고 및 판단하는 구조에서 본따서 인공 신경망도 여러 입력을 받아, 곱하고 더해서 출력하게 되는 구조로 설계 되었습니다. 여러 입력을 받아서 연산을 수행하고 다시 다음 레이어로 전달하는 구조가 아주 유사합니다.이러한 Linear Layer와 Non-Linear Layer를 중첩하여 Deep 한 네트워크를 구성 하여 뇌의 사고와 같은 복잡한 사고를 구성 할 수 있게 되었습니다.• None Deep Learning은 Linear Layer와 Non-Linear Layer를 중첩하여 Deep 한 구조로 되어 있다.• None 이러한 Deep 한 구조는 뇌신경망을 참고하였다.• None Linear Layer로만 Deep 하게(여러 레이어로) 구성하면, 하나의 Linear Layer로 합성 될 수 있으며, 이를 방지하는 것이 Activation Function이다. Activation Function(Non-Linear Layer)로 복수의 Linear Layer들이 하나의 Layer로 합성되는 것을 방지하여 Deep 한, 깊은 구조의 Model 을 구성할 수 있다.
2025.09.05
emoji
좋아요
emoji
별로에요
logo
AI 시대를 살아갈 개발자들에게
우리는 어디에 서 있는가?지금 우리는 거대한 변혁의 한복판에 서 있습니다. 어떤 사람들은 지금을 ‘제2의 산업혁명’이라 부르고, 또 어떤 사람들은 ‘지능 혁명’이라고도 칭합니다. AI라는 거대한 변혁의 파도가 우리의 일과 삶, 그리고 생각하는 방식까지 모든 것을 바꾸고 있다는 사실만은 분명한 듯 합니다.18세기에는 증기기관이 인간의 근육을 대신해 물리적 한계를 무너뜨렸다면, 21세기는 AI가 인간의 두뇌를 확장시키고 지적 능력의 경계를 허물고 있습니다. AI가 가져오고 있는 변화는 단순한 기술의 발전이 아니라, 인류 문명의 OS를 통째로 업그레이드하는 것과 같은 근본적인 변화로 보입니다.이 변화는 두려움과 설렘이 뒤섞인 복잡한 감정을 불러 일으킵니다. 특히 변화의 물결을 가장 먼저, 그리고 가장 온몸으로 맞고 있는 소프트웨어 엔지니어들에게 ‘AI 네이티브’라는 화두는, 오늘의 생존과 성장에 관한 절박한 질문일 것입니다.여기에서는 AI의 전면적인 등장 앞에서 개인과 조직이 어떻게 방향을 찾고, 어떻게 대응해야 하며, 궁극적으로 어떻게 AI 네이티브화되어야 하는지에 대해 이야기하고자 합니다. 카카오테크가 AI 네이티브 전환 과정에서 얻은 교훈을 공유하면서 이 시대를 살아가는 우리 모두의 미래에 대한 제 생각을 함께 나누고 싶습니다.AI는 위협인가, 기회인가?골리앗들의 전쟁과 우리의 위치2023년과 2024년은 그야말로 AI 광풍의 시대였습니다. OpenAI의 압도적인 질주와 이를 추격하는 글로벌 빅테크들의 천문학적인 자본 경쟁은, 1990년대에서 2000년대 초반으로 이어진 월드 와이드 웹(WWW)의 등장을 방불케 하며 새로운 AI 시대의 재림과 거대한 변화의 흐름을 온 몸으로 느낄 수밖에 없는 시기였습니다. AI가 가져올 변화에 대한 기대감과 함께, “이 게임에 우리가 낄 자리가 있기는 한 걸까?” 하는 깊은 초조함도 함께 느꼈습니다.LLM의 발전 속도는 상상을 초월했습니다. 오늘 최신 버전을 가정하고 만든 서비스가, 내일 새벽에 발표된 다음 업데이트와 함께 구식이 되어버리는 일이 비일비재했습니다. “OpenAI가 키노트를 할 때마다 스타트업들이 사라진다”는 말이 더 이상 농담처럼 들리지 않았던 시절입니다. 이 거대한 흐름 앞에서 근본적인 질문과 마주하게 됩니다.“우리가 참여할 수 있는 경쟁인가?”결론부터 말하자면, LLM 자체를 처음부터 개발하는 ‘모델 경쟁’은 이미 다른 차원의 이야기가 되었습니다. 이는 단순히 돈의 문제를 넘어, 국가 단위의 인프라와 자원이 동원되는 총력전의 양상을 띠고 있기 때문입니다.• 전력: 메타와 테슬라가 건설 중인 데이터센터는 ‘기가와트’ 단위의 전력을 소모합니다. 이는 원자력 발전소 몇 기가 생산하는 전력량과 맞먹는 수준으로, 하나의 거대 도시가 쓰는 에너지를 단 몇 개의 기업이 AI를 위해 사용하고 있다는 의미입니다. 카카오가 수천억을 들여 지은 최신 데이터센터의 총 전력 용량이 수십메가와트 수준임을 감안하면, 현재의 인프라로는 상상조차 하기 힘든 규모입니다. 중국이 서부 해안에 수십 기의 원자력 발전소를 동시에 건설하며 AI 시대의 에너지 패권을 노리는 것은 결코 우연이 아닙니다.• 컴퓨팅: 19세기의 골드러시 시기에 부를 거머쥔 사람들은 금을 찾아 헤매던 광부가 아니라 광부들에게 채굴 도구와 의식주를 제공했던 상인들이었습니다. AI 시대의 GPU는 바로 이 ‘채굴 도구’와 같습니다. AI라는 새로운 금맥을 캐기 위한 경쟁이 치열해질수록 채굴 도구의 가치는 천정부지로 치솟고 있습니다. 따라서 이 자원을 안정적으로, 그리고 대규모로 확보하고 운영하는 능력 자체가 곧 국가와 기업의 경쟁력을 결정짓는 핵심이 되었습니다.• 인재: 경쟁력 있는 LLM을 만드는 과정은 정해진 공식에 따라 기계를 조립하는 것과는 다릅니다. 수많은 변수를 조정하고 데이터의 미묘한 특성을 파악해 최적의 결과물을 만들어내는, 마치 ‘연금술’에 가까운 경험적 튜닝에 크게 의존합니다. 이 때문에 전 세계 최고의 AI 연구자는 100명 내외라는 말이 나올 정도로 극소수이며, 이들의 몸값은 천정부지로 치솟고 있습니다. 수백억 원의 연구 인프라와 최고의 인재가 확보되어야만 비로소 경쟁의 출발선에라도 설 수 있는 것이 현실입니다.AI를 OS로 바라보기이처럼 거대한 장벽 앞에서 우리는 좌절해야만 할까요? 저는 그렇지 않다고 생각합니다. 관점을 바꾸면 새로운 길이 보입니다. 바로 AI, 특히 LLM을 OS 레이어로 인식하는 것입니다.우리는 윈도우나 iOS, 안드로이드를 직접 만들지 않습니다. 이미 세상에 존재하는 강력하고 안정적인 OS 위에서 우리만의 독창적인 애플리케이션과 서비스를 만들어 새로운 가치를 창출합니다. 카카오톡이 안드로이드와 iOS 위에서 국민 메신저가 되었고, 수많은 스타트업이 AWS나 GCP 위에서 세상을 바꾸는 서비스를 만들어내고 있듯이 말입니다.마찬가지로, LLM 자체를 처음부터 개발하는 경쟁에 매몰되기보다, 이미 존재하는 강력한 LLM들을 마치 OS처럼 활용하고, 그 위에 우리만의 비즈니스와 서비스, 데이터에 맞게 ‘튜닝’하고 ‘커스텀’할 수 있는 역량에 집중하는 것이 더 현명한 전략 일 수 있습니다. 범용 리눅스 커널을 가져와 셋톱박스나 가전제품에 맞게 최적화된 임베디드 OS를 만드는 것과 같이 말입니다. 물론, 이 역량을 갖추기조차 쉽지 않지만, 이것이 바로 미국과 중국을 제외한 대부분의 국가와 기업이 집중해야 할 소버린 AI, 즉 ‘AI 기술 주권’의 핵심이라고 생각합니다.현재의 AI 시장은 2000년대 초반의 인터넷 시장과 놀라울 정도로 유사합니다. 당시에는 모두가 네트워크 망을 깔고 데이터센터를 짓는 인프라 경쟁에 열을 올렸습니다. 하지만 결국 시장의 진정한 승자는 그 인프라 위에서 콘텐츠와 서비스를 만들어낸 구글, 아마존, 페이스북과 같은 기업들이었습니다.지금도 LLM이라는 거대한 인프라를 구축하는 경쟁은 극소수 플레이어들의 승리로 귀결될 가능성이 높습니다. 하지만 진짜 부가가치와 혁신은 그 인프라 위에서 피어날 것입니다. AI라는 OS를 활용해 이전에는 불가능했던 새로운 사용자 경험을 만들고, 특정 산업의 고질적인 문제를 해결하는 애플리케이션과 서
9/5/2025
logo
AI 시대를 살아갈 개발자들에게
우리는 어디에 서 있는가?지금 우리는 거대한 변혁의 한복판에 서 있습니다. 어떤 사람들은 지금을 ‘제2의 산업혁명’이라 부르고, 또 어떤 사람들은 ‘지능 혁명’이라고도 칭합니다. AI라는 거대한 변혁의 파도가 우리의 일과 삶, 그리고 생각하는 방식까지 모든 것을 바꾸고 있다는 사실만은 분명한 듯 합니다.18세기에는 증기기관이 인간의 근육을 대신해 물리적 한계를 무너뜨렸다면, 21세기는 AI가 인간의 두뇌를 확장시키고 지적 능력의 경계를 허물고 있습니다. AI가 가져오고 있는 변화는 단순한 기술의 발전이 아니라, 인류 문명의 OS를 통째로 업그레이드하는 것과 같은 근본적인 변화로 보입니다.이 변화는 두려움과 설렘이 뒤섞인 복잡한 감정을 불러 일으킵니다. 특히 변화의 물결을 가장 먼저, 그리고 가장 온몸으로 맞고 있는 소프트웨어 엔지니어들에게 ‘AI 네이티브’라는 화두는, 오늘의 생존과 성장에 관한 절박한 질문일 것입니다.여기에서는 AI의 전면적인 등장 앞에서 개인과 조직이 어떻게 방향을 찾고, 어떻게 대응해야 하며, 궁극적으로 어떻게 AI 네이티브화되어야 하는지에 대해 이야기하고자 합니다. 카카오테크가 AI 네이티브 전환 과정에서 얻은 교훈을 공유하면서 이 시대를 살아가는 우리 모두의 미래에 대한 제 생각을 함께 나누고 싶습니다.AI는 위협인가, 기회인가?골리앗들의 전쟁과 우리의 위치2023년과 2024년은 그야말로 AI 광풍의 시대였습니다. OpenAI의 압도적인 질주와 이를 추격하는 글로벌 빅테크들의 천문학적인 자본 경쟁은, 1990년대에서 2000년대 초반으로 이어진 월드 와이드 웹(WWW)의 등장을 방불케 하며 새로운 AI 시대의 재림과 거대한 변화의 흐름을 온 몸으로 느낄 수밖에 없는 시기였습니다. AI가 가져올 변화에 대한 기대감과 함께, “이 게임에 우리가 낄 자리가 있기는 한 걸까?” 하는 깊은 초조함도 함께 느꼈습니다.LLM의 발전 속도는 상상을 초월했습니다. 오늘 최신 버전을 가정하고 만든 서비스가, 내일 새벽에 발표된 다음 업데이트와 함께 구식이 되어버리는 일이 비일비재했습니다. “OpenAI가 키노트를 할 때마다 스타트업들이 사라진다”는 말이 더 이상 농담처럼 들리지 않았던 시절입니다. 이 거대한 흐름 앞에서 근본적인 질문과 마주하게 됩니다.“우리가 참여할 수 있는 경쟁인가?”결론부터 말하자면, LLM 자체를 처음부터 개발하는 ‘모델 경쟁’은 이미 다른 차원의 이야기가 되었습니다. 이는 단순히 돈의 문제를 넘어, 국가 단위의 인프라와 자원이 동원되는 총력전의 양상을 띠고 있기 때문입니다.• 전력: 메타와 테슬라가 건설 중인 데이터센터는 ‘기가와트’ 단위의 전력을 소모합니다. 이는 원자력 발전소 몇 기가 생산하는 전력량과 맞먹는 수준으로, 하나의 거대 도시가 쓰는 에너지를 단 몇 개의 기업이 AI를 위해 사용하고 있다는 의미입니다. 카카오가 수천억을 들여 지은 최신 데이터센터의 총 전력 용량이 수십메가와트 수준임을 감안하면, 현재의 인프라로는 상상조차 하기 힘든 규모입니다. 중국이 서부 해안에 수십 기의 원자력 발전소를 동시에 건설하며 AI 시대의 에너지 패권을 노리는 것은 결코 우연이 아닙니다.• 컴퓨팅: 19세기의 골드러시 시기에 부를 거머쥔 사람들은 금을 찾아 헤매던 광부가 아니라 광부들에게 채굴 도구와 의식주를 제공했던 상인들이었습니다. AI 시대의 GPU는 바로 이 ‘채굴 도구’와 같습니다. AI라는 새로운 금맥을 캐기 위한 경쟁이 치열해질수록 채굴 도구의 가치는 천정부지로 치솟고 있습니다. 따라서 이 자원을 안정적으로, 그리고 대규모로 확보하고 운영하는 능력 자체가 곧 국가와 기업의 경쟁력을 결정짓는 핵심이 되었습니다.• 인재: 경쟁력 있는 LLM을 만드는 과정은 정해진 공식에 따라 기계를 조립하는 것과는 다릅니다. 수많은 변수를 조정하고 데이터의 미묘한 특성을 파악해 최적의 결과물을 만들어내는, 마치 ‘연금술’에 가까운 경험적 튜닝에 크게 의존합니다. 이 때문에 전 세계 최고의 AI 연구자는 100명 내외라는 말이 나올 정도로 극소수이며, 이들의 몸값은 천정부지로 치솟고 있습니다. 수백억 원의 연구 인프라와 최고의 인재가 확보되어야만 비로소 경쟁의 출발선에라도 설 수 있는 것이 현실입니다.AI를 OS로 바라보기이처럼 거대한 장벽 앞에서 우리는 좌절해야만 할까요? 저는 그렇지 않다고 생각합니다. 관점을 바꾸면 새로운 길이 보입니다. 바로 AI, 특히 LLM을 OS 레이어로 인식하는 것입니다.우리는 윈도우나 iOS, 안드로이드를 직접 만들지 않습니다. 이미 세상에 존재하는 강력하고 안정적인 OS 위에서 우리만의 독창적인 애플리케이션과 서비스를 만들어 새로운 가치를 창출합니다. 카카오톡이 안드로이드와 iOS 위에서 국민 메신저가 되었고, 수많은 스타트업이 AWS나 GCP 위에서 세상을 바꾸는 서비스를 만들어내고 있듯이 말입니다.마찬가지로, LLM 자체를 처음부터 개발하는 경쟁에 매몰되기보다, 이미 존재하는 강력한 LLM들을 마치 OS처럼 활용하고, 그 위에 우리만의 비즈니스와 서비스, 데이터에 맞게 ‘튜닝’하고 ‘커스텀’할 수 있는 역량에 집중하는 것이 더 현명한 전략 일 수 있습니다. 범용 리눅스 커널을 가져와 셋톱박스나 가전제품에 맞게 최적화된 임베디드 OS를 만드는 것과 같이 말입니다. 물론, 이 역량을 갖추기조차 쉽지 않지만, 이것이 바로 미국과 중국을 제외한 대부분의 국가와 기업이 집중해야 할 소버린 AI, 즉 ‘AI 기술 주권’의 핵심이라고 생각합니다.현재의 AI 시장은 2000년대 초반의 인터넷 시장과 놀라울 정도로 유사합니다. 당시에는 모두가 네트워크 망을 깔고 데이터센터를 짓는 인프라 경쟁에 열을 올렸습니다. 하지만 결국 시장의 진정한 승자는 그 인프라 위에서 콘텐츠와 서비스를 만들어낸 구글, 아마존, 페이스북과 같은 기업들이었습니다.지금도 LLM이라는 거대한 인프라를 구축하는 경쟁은 극소수 플레이어들의 승리로 귀결될 가능성이 높습니다. 하지만 진짜 부가가치와 혁신은 그 인프라 위에서 피어날 것입니다. AI라는 OS를 활용해 이전에는 불가능했던 새로운 사용자 경험을 만들고, 특정 산업의 고질적인 문제를 해결하는 애플리케이션과 서
2025.09.05
emoji
좋아요
emoji
별로에요
logo
프론트엔드 개발자를 위한 FEConf 2025 간단 후기
안녕하세요. 에이닷에서 프론트엔드 개발 업무를 하고 있는 스카이입니다.지난 9월 23일 토요일 FEConf 2025가 열렸습니다.코로나 팬데믹 이후 오프라인 콘퍼런스는 오랜만이었는데 생각보다 사람들이 많아서 놀랐습니다. 다녀온 후기를 간단하게 정리해 보았습니다.FEConf는 매해 열리는 Front-End 콘퍼런스로 FE 기술을 공유하는 콘퍼런스입니다. 이번 콘퍼런스는 세종대학교에서 진행되었습니다.30분 단위로 세션이 있었고10분 단위의 Lightning talk 세션이 따로 있었습니다.세션 중에 가장 기억이 남는 세션들 위주로 정리해 보았습니다.이 세션에서 놀라웠던 건 스벨트의 파인 그레인드(fine-grained) 업데이트 방식이었습니다.리액트처럼 전체 컴포넌트가 재렌더링되는 게 아니라, 바뀐 부분만 딱 업데이트하는 방식을 말하는데 빠른 성능을 내는 큰 장점이 있어 보였습니다.또한 ref callback에 대해서도 설명했는데 Vue에서도 적용해 볼 수 있을 것 같습니다.간단하게 ref callback에 대해 설명하면, ref에 ref로 선언한 값만 할당할 수 있다고 생각했는데요.함수를 할당하는 방식을 말합니다. 다음은 예시 코드입니다.이 방식을 통해 페이지가 in/out될 때 애니메이션을 구현하는 예시를 보여주었는데 생각하지 못했던 접근법이라 신선했습니다.♿ 중요하지만 긴급하지 않은 일, 그럼에도 계획해야 하는 웹 접근성업무에 바빠 아무래도 우선순위가 낮을 수밖에 없는 웹 접근성에 대해 다시 생각해 보게 된 세션이었습니다.ARIA(Accessible Rich Internet Applications) 속성 하나하나가 누군가에겐 정말 중요한 의미라는 생각을 하게 되었습니다.ARIA 역할의 정의와 기본 원칙은 이렇습니다.• None ARIA는 HTML의 의미를 확장하거나 보완하는 역할로서, UI 요소에 적절한 역할을 명시해 보조기술에 정보를 제공함• None 이미 HTML에 정의된 역할은 우선적으로 사용하고, 없는 UI 패턴에 대해 ARIA 역할을 정의하여 표현함ARIA 속성을 정리해 보면 다음과 같습니다.• None aria-expanded : 메뉴나 리스트가 확장되었는지 여부를 나타냅니다.• None aria-selected : 선택된 항목을 표현한다고 합니다.• None aria-controls : 버튼 등 UI 요소가 제어하는 대상 요소의 ID를 연결해 상호작용 관계를 명확히 합니다.• None aria-labelledby, aria-describedby : 레이블과 설명을 연결해 시멘틱 정보를 보완합니다.🎨 최신 CSS? 10년 뒤에 쓰면 되나요?CSS 새로운 기능이 실제 적용되기까지 예전에는 5~8년 정도의 시간이 걸렸으나 요즘은 빠르게 진행되고 적용된다고 합니다.이 세션에서 그 예로 다음 두 가지를 알려주었습니다.Customizable Select, select box 디자인을 변경하려면 select 태그 자체로만 구현이 어려워 div, span 태그를 활용해야 했습니다.하지만 요즘에는 select에 CSS를 적용해서 가능하다고 합니다. 자세한 코드는 링크에서 확인하실 수 있습니다.또한 Popover API에 대해서도 언급해 주었는데요.이것 역시 실무에 사용해 볼 수 있는 기능으로 보입니다.🤖 UI 코드 생성 자동화를 프로덕션까지 (Figma MCP + Cursor)'오늘의 집' 회사에서 발표한 내용으로 Figma MCP + Cursor 조합으로 UI 개발은 Cursor에게 위임했다는 이야기였습니다.디자인팀과 1px로 싸울 일이 없다는 마지막 말은 너무나 감동적이었습니다.9명 팀에서 AI를 실제 프로덕션까지 도입한 사례로 국내에서는 거의 최초라고 하더군요.특히 디자인 시스템과 AI를 연결하는 부분에서 많은 노하우를 알려주셨습니다.유튜브에서 찾아보니 이것 관련 영상이 꽤 많이 나오더라고요. 참고해서 도입해 보면 좋을 것 같습니다.강남언니, 오늘의집, AWS, MOYO 부스가 있었습니다. 링크드인에 각 회사를 구독하면 상품을 주는 행사도 진행 중이었습니다.
9/4/2025
logo
프론트엔드 개발자를 위한 FEConf 2025 간단 후기
안녕하세요. 에이닷에서 프론트엔드 개발 업무를 하고 있는 스카이입니다.지난 9월 23일 토요일 FEConf 2025가 열렸습니다.코로나 팬데믹 이후 오프라인 콘퍼런스는 오랜만이었는데 생각보다 사람들이 많아서 놀랐습니다. 다녀온 후기를 간단하게 정리해 보았습니다.FEConf는 매해 열리는 Front-End 콘퍼런스로 FE 기술을 공유하는 콘퍼런스입니다. 이번 콘퍼런스는 세종대학교에서 진행되었습니다.30분 단위로 세션이 있었고10분 단위의 Lightning talk 세션이 따로 있었습니다.세션 중에 가장 기억이 남는 세션들 위주로 정리해 보았습니다.이 세션에서 놀라웠던 건 스벨트의 파인 그레인드(fine-grained) 업데이트 방식이었습니다.리액트처럼 전체 컴포넌트가 재렌더링되는 게 아니라, 바뀐 부분만 딱 업데이트하는 방식을 말하는데 빠른 성능을 내는 큰 장점이 있어 보였습니다.또한 ref callback에 대해서도 설명했는데 Vue에서도 적용해 볼 수 있을 것 같습니다.간단하게 ref callback에 대해 설명하면, ref에 ref로 선언한 값만 할당할 수 있다고 생각했는데요.함수를 할당하는 방식을 말합니다. 다음은 예시 코드입니다.이 방식을 통해 페이지가 in/out될 때 애니메이션을 구현하는 예시를 보여주었는데 생각하지 못했던 접근법이라 신선했습니다.♿ 중요하지만 긴급하지 않은 일, 그럼에도 계획해야 하는 웹 접근성업무에 바빠 아무래도 우선순위가 낮을 수밖에 없는 웹 접근성에 대해 다시 생각해 보게 된 세션이었습니다.ARIA(Accessible Rich Internet Applications) 속성 하나하나가 누군가에겐 정말 중요한 의미라는 생각을 하게 되었습니다.ARIA 역할의 정의와 기본 원칙은 이렇습니다.• None ARIA는 HTML의 의미를 확장하거나 보완하는 역할로서, UI 요소에 적절한 역할을 명시해 보조기술에 정보를 제공함• None 이미 HTML에 정의된 역할은 우선적으로 사용하고, 없는 UI 패턴에 대해 ARIA 역할을 정의하여 표현함ARIA 속성을 정리해 보면 다음과 같습니다.• None aria-expanded : 메뉴나 리스트가 확장되었는지 여부를 나타냅니다.• None aria-selected : 선택된 항목을 표현한다고 합니다.• None aria-controls : 버튼 등 UI 요소가 제어하는 대상 요소의 ID를 연결해 상호작용 관계를 명확히 합니다.• None aria-labelledby, aria-describedby : 레이블과 설명을 연결해 시멘틱 정보를 보완합니다.🎨 최신 CSS? 10년 뒤에 쓰면 되나요?CSS 새로운 기능이 실제 적용되기까지 예전에는 5~8년 정도의 시간이 걸렸으나 요즘은 빠르게 진행되고 적용된다고 합니다.이 세션에서 그 예로 다음 두 가지를 알려주었습니다.Customizable Select, select box 디자인을 변경하려면 select 태그 자체로만 구현이 어려워 div, span 태그를 활용해야 했습니다.하지만 요즘에는 select에 CSS를 적용해서 가능하다고 합니다. 자세한 코드는 링크에서 확인하실 수 있습니다.또한 Popover API에 대해서도 언급해 주었는데요.이것 역시 실무에 사용해 볼 수 있는 기능으로 보입니다.🤖 UI 코드 생성 자동화를 프로덕션까지 (Figma MCP + Cursor)'오늘의 집' 회사에서 발표한 내용으로 Figma MCP + Cursor 조합으로 UI 개발은 Cursor에게 위임했다는 이야기였습니다.디자인팀과 1px로 싸울 일이 없다는 마지막 말은 너무나 감동적이었습니다.9명 팀에서 AI를 실제 프로덕션까지 도입한 사례로 국내에서는 거의 최초라고 하더군요.특히 디자인 시스템과 AI를 연결하는 부분에서 많은 노하우를 알려주셨습니다.유튜브에서 찾아보니 이것 관련 영상이 꽤 많이 나오더라고요. 참고해서 도입해 보면 좋을 것 같습니다.강남언니, 오늘의집, AWS, MOYO 부스가 있었습니다. 링크드인에 각 회사를 구독하면 상품을 주는 행사도 진행 중이었습니다.
2025.09.04
emoji
좋아요
emoji
별로에요
logo
A2A 서비스 사용사례 및 고찰
오늘은 A2A 실무 사례에 대해서 소개드리고자 합니다.최근 엄청 핫한 A2A를 실무에 적용해야 하는 서비스가 있어서 제가 리서치한 내용과 실무에 적용하면서 고민이 필요했던 내용을 공유드리고자 합니다.구글이 2025년 4월에 A2A(Agent-to-Agent) 프로토콜은 AI 에이전트 모델끼리 서로 연결되고 협력하는 방식을 지칭합니다.하나의 AI 에이전트 모델이 사용자의 쿼리를 처리하는 것 뿐만 아니라, 여러 AI 에이전트 모델이 서로 소통하며 문제 해결을 확장하는 구조라고 볼 수 있습니다.AI 에이전트 모델이 발전하면서 단순한 쿼리 요청이 아닌 다양한 context와 복잡한 요청을 처리해야 하는 경우가 늘어나고 있습니다. 예시를 들어보겠습니다.예시: "최근 일주일 사이에 시장의 변동성을 고려해서 주식 차트에 추세선을 그려줘" 라는 사용자 쿼리는 생각보다 단일 AI 에이전트가 처리하기엔 복잡할 수 있습니다.이러한 상황에서 하나의 에이저트가 모든 것을 담당하는 것 보다, 여러 도메인과 테스크를 다루는 에이전트들이 서로 협력하는 방식이 필요하게 되었습니다.A2A 아키텍쳐는 간단합니다. host agent가 remote agent를 호출하고 remote agent는 A2A 표준을 통해 A2A server에서 수행한 결과를 다시 host agent에게 전달하는 방식입니다.A2A 프로토콜은 AI 에이전트간의 표준화 규칙입니다.공식 문서에 따르면 다양한 플랫폼과 프레임워크에서 만들어진 AI 에이전트들이 서로 통신을 주고받을 수 있는 개방형 표준입니다.A2A 프로토콜은 이미 잘 알려져있는 웹 표준을 따르고 있습니다.이 세가지 표준을 활용하여 통신을 수행합니다. (JSON RPC는 이미 **well-known **데이터 통신 방식이라 한번 보시면 좋을 듯 합니다!)A2A 프로토콜의 작동방식은 다음과 같습니다각 AI 에이전트는 고유의 정보를 담고 있는 에이전트 카드를 가져야 합니다.이 카드에는 해당 에이전트가 무엇을 할 수 있는지, 어떤 스킬을 가지고 있는지 정보를 담고 있습니다. (언급하진 않았지만 A2A는 push notification도 할 수 있습니다..!)A2A에서 에이전트 스킬은 각각의 에이전트가 수행할 수 있는 구체적인 기술을 의미합니다.예를 들어, 여행 에이전트라면 '항공권 검색', '호텔 예약' 등의 스킬을 가질 수 있습니다.이러한 skill 정보들이 에이전트 카드에 명시되어, 다른 에이전트들이 어떤 작업을 요청할 수 있는지 파악할 수 있습니다.여기서 skill 정보들을 자세히 나열하고 태그들을 명확하게 기입해야 나중에 host agent가 다수의 remote agent를 매끄럽게 call 할 수 있습니다.에이전트간 모든 소통은 작업(Task) 중심으로 이루어집니다.한 에이전트가 다른 에이전트에게 특정 작업을 요청하면, 해당 작업에 고유 ID가 부여되며 그 작업을 트래킹할 수 있습니다. (ID는 UUID로 관리합니다.)위에서 설명한 A2A 프로토콜을 기반으로 에이전트들이 호스트 에이전트(client agent)와 리모트 에이전트(server agent)의 관계로 서로 커뮤니케이션을 수행합니다.사진에서는 host agent, remote agent가 모두 MCP server를 가지고 있지만 없어도 됩니다.단 잘 보시면 host agent와 remote agent간의 데이터를 주고받는 방식을 /.well-known/agent.json 이라는 JSON 파일로 주고받습니다.해당 JSON 파일엔 remote agent의 name, description, tag, skill, example 정보들을 담고 있습니다.리모트 에이전트는 실제로 작업을 수행하는 전문화 에이전트입니다.호스트 에이전트에서 받은 작업 요청을 받아 결과를 만들어서 다시 호스트에게 전달합니다.리모트 에이전트는 호스트 에이전트가 호출할 수 있도록 자세한 description과 example을 기술하는 것이 좋습니다.호스트 에이전트는 작업을 시작하고 관리하는 에이전트입니다.사용자의 쿼리를 받아 어떤 작업이 필요한지 파악하고, 적절한 리모트 에이전트를 찾아서 작업을 요청합니다.호스트 에이전트가 사실상 A2A의 머리 역할을 담당하는데요, host agent의 성능이 곧 A2A 서비스 성공의 척도이며 올바른 서비스를 구동할 수 있습니다.사실 실제 서비스에서는 더 복잡한 context와 host agent가 remote agent calling 을 더 잘해야하는 경우들이 많은데요,대외비라 자세한 설명을 드리지 못하는 점이 있습니다. 최대한 비슷하게 Public 환경에서의 사용 예시를 설명드리겠습니다.위에서 언급한 여행 계획을 세우는 상황을 고려해보겠습니다.• None 사용자 요청: "뉴욕 3박 4일 여행 계획을 작성해줘"• None 호스트 에이전트 동작: 여행 계획 에이전트가 요청을 받고, 필요한 리모트 에이전트들의 에이전트 카드를 확인하여 리모트 에이전트를 식별• None 작업 분배: 항공편 에이전트, 호텔 예약 에이전트, 가이드 에이전트등 각각의 에이전트들에게 고유의 작업 ID를 부여하여 작업을 요청• None 리모트 에이전트 실행: ID를 발급받은 에이전트가 결과를 도출하고 호스트 에이전트에게 결과를 전달• None 결과 종합: 호스트 에이전트가 모든 리모트 에이전트들의 결과물을 종합하여 완성된 결과물로 만들어 사용자에게 전달이렇게 host agent와 remote agent를 사용한 A2A 서비스 사용 사례를 기술해보았습니다.생각보다 고려해야 하는 점이 현저히 많고 google a2a-sdk도 지속적인 버전 업이 되고 있어 있었던 기능이 사라지거나 새로 생기는 기능들이 무수히 많은 것 같습니다.그럼에도 불구하고 미래의 각각의 개인별 agent, 기업 agent들을 바탕으로 서로 소통하는 a2a 서비스를 위해선 지금부터 기초를 다지는 건 매우 좋은 것 같습니다!
9/4/2025
logo
A2A 서비스 사용사례 및 고찰
오늘은 A2A 실무 사례에 대해서 소개드리고자 합니다.최근 엄청 핫한 A2A를 실무에 적용해야 하는 서비스가 있어서 제가 리서치한 내용과 실무에 적용하면서 고민이 필요했던 내용을 공유드리고자 합니다.구글이 2025년 4월에 A2A(Agent-to-Agent) 프로토콜은 AI 에이전트 모델끼리 서로 연결되고 협력하는 방식을 지칭합니다.하나의 AI 에이전트 모델이 사용자의 쿼리를 처리하는 것 뿐만 아니라, 여러 AI 에이전트 모델이 서로 소통하며 문제 해결을 확장하는 구조라고 볼 수 있습니다.AI 에이전트 모델이 발전하면서 단순한 쿼리 요청이 아닌 다양한 context와 복잡한 요청을 처리해야 하는 경우가 늘어나고 있습니다. 예시를 들어보겠습니다.예시: "최근 일주일 사이에 시장의 변동성을 고려해서 주식 차트에 추세선을 그려줘" 라는 사용자 쿼리는 생각보다 단일 AI 에이전트가 처리하기엔 복잡할 수 있습니다.이러한 상황에서 하나의 에이저트가 모든 것을 담당하는 것 보다, 여러 도메인과 테스크를 다루는 에이전트들이 서로 협력하는 방식이 필요하게 되었습니다.A2A 아키텍쳐는 간단합니다. host agent가 remote agent를 호출하고 remote agent는 A2A 표준을 통해 A2A server에서 수행한 결과를 다시 host agent에게 전달하는 방식입니다.A2A 프로토콜은 AI 에이전트간의 표준화 규칙입니다.공식 문서에 따르면 다양한 플랫폼과 프레임워크에서 만들어진 AI 에이전트들이 서로 통신을 주고받을 수 있는 개방형 표준입니다.A2A 프로토콜은 이미 잘 알려져있는 웹 표준을 따르고 있습니다.이 세가지 표준을 활용하여 통신을 수행합니다. (JSON RPC는 이미 **well-known **데이터 통신 방식이라 한번 보시면 좋을 듯 합니다!)A2A 프로토콜의 작동방식은 다음과 같습니다각 AI 에이전트는 고유의 정보를 담고 있는 에이전트 카드를 가져야 합니다.이 카드에는 해당 에이전트가 무엇을 할 수 있는지, 어떤 스킬을 가지고 있는지 정보를 담고 있습니다. (언급하진 않았지만 A2A는 push notification도 할 수 있습니다..!)A2A에서 에이전트 스킬은 각각의 에이전트가 수행할 수 있는 구체적인 기술을 의미합니다.예를 들어, 여행 에이전트라면 '항공권 검색', '호텔 예약' 등의 스킬을 가질 수 있습니다.이러한 skill 정보들이 에이전트 카드에 명시되어, 다른 에이전트들이 어떤 작업을 요청할 수 있는지 파악할 수 있습니다.여기서 skill 정보들을 자세히 나열하고 태그들을 명확하게 기입해야 나중에 host agent가 다수의 remote agent를 매끄럽게 call 할 수 있습니다.에이전트간 모든 소통은 작업(Task) 중심으로 이루어집니다.한 에이전트가 다른 에이전트에게 특정 작업을 요청하면, 해당 작업에 고유 ID가 부여되며 그 작업을 트래킹할 수 있습니다. (ID는 UUID로 관리합니다.)위에서 설명한 A2A 프로토콜을 기반으로 에이전트들이 호스트 에이전트(client agent)와 리모트 에이전트(server agent)의 관계로 서로 커뮤니케이션을 수행합니다.사진에서는 host agent, remote agent가 모두 MCP server를 가지고 있지만 없어도 됩니다.단 잘 보시면 host agent와 remote agent간의 데이터를 주고받는 방식을 /.well-known/agent.json 이라는 JSON 파일로 주고받습니다.해당 JSON 파일엔 remote agent의 name, description, tag, skill, example 정보들을 담고 있습니다.리모트 에이전트는 실제로 작업을 수행하는 전문화 에이전트입니다.호스트 에이전트에서 받은 작업 요청을 받아 결과를 만들어서 다시 호스트에게 전달합니다.리모트 에이전트는 호스트 에이전트가 호출할 수 있도록 자세한 description과 example을 기술하는 것이 좋습니다.호스트 에이전트는 작업을 시작하고 관리하는 에이전트입니다.사용자의 쿼리를 받아 어떤 작업이 필요한지 파악하고, 적절한 리모트 에이전트를 찾아서 작업을 요청합니다.호스트 에이전트가 사실상 A2A의 머리 역할을 담당하는데요, host agent의 성능이 곧 A2A 서비스 성공의 척도이며 올바른 서비스를 구동할 수 있습니다.사실 실제 서비스에서는 더 복잡한 context와 host agent가 remote agent calling 을 더 잘해야하는 경우들이 많은데요,대외비라 자세한 설명을 드리지 못하는 점이 있습니다. 최대한 비슷하게 Public 환경에서의 사용 예시를 설명드리겠습니다.위에서 언급한 여행 계획을 세우는 상황을 고려해보겠습니다.• None 사용자 요청: "뉴욕 3박 4일 여행 계획을 작성해줘"• None 호스트 에이전트 동작: 여행 계획 에이전트가 요청을 받고, 필요한 리모트 에이전트들의 에이전트 카드를 확인하여 리모트 에이전트를 식별• None 작업 분배: 항공편 에이전트, 호텔 예약 에이전트, 가이드 에이전트등 각각의 에이전트들에게 고유의 작업 ID를 부여하여 작업을 요청• None 리모트 에이전트 실행: ID를 발급받은 에이전트가 결과를 도출하고 호스트 에이전트에게 결과를 전달• None 결과 종합: 호스트 에이전트가 모든 리모트 에이전트들의 결과물을 종합하여 완성된 결과물로 만들어 사용자에게 전달이렇게 host agent와 remote agent를 사용한 A2A 서비스 사용 사례를 기술해보았습니다.생각보다 고려해야 하는 점이 현저히 많고 google a2a-sdk도 지속적인 버전 업이 되고 있어 있었던 기능이 사라지거나 새로 생기는 기능들이 무수히 많은 것 같습니다.그럼에도 불구하고 미래의 각각의 개인별 agent, 기업 agent들을 바탕으로 서로 소통하는 a2a 서비스를 위해선 지금부터 기초를 다지는 건 매우 좋은 것 같습니다!
2025.09.04
emoji
좋아요
emoji
별로에요
logo
FE News 25년 9월 소식을 전해드립니다!
주요소식다음과 같은 유용한 정보들을 만나보실 수 있습니다.Augmented vs Vibe Coding:Kent Beck은 BPlusTree3 라이브러리를 통해, Vibe Coding보다 코드 품질과 복잡성을 중시하는 Augmented Coding의 중요성을 설명했습니다. Rust, Python, C 등 다양한 언어로도 구현했습니다.Code w/ Claude Developer Conference:Anthropic의 첫 개발자 컨퍼런스에서는 Claude 4 모델, API 및 CLI 활용 사례, 다양한 플랫폼 통합 등을 소개했습니다.VS Code에서의 Prompt Injection 방지:VS Code Copilot Chat에서 발생할 수 있는 보안 문제들과 이를 방지하기 위한 개선 사항을 설명합니다.프로그램의 미래와 Vibe Coding:AI 도구의 활용으로 프로그래밍 접근법이 변화하고 있으며, 시니어 개발자는 AI 활용 시 더 빠른 개발 속도를 경험한다고 보고합니다.CSS 2025 현황:CSS가 Web apps 개발에 주로 사용되며, 새로운 기능들이 도입됐습니다. 개발자는 Mixins와 Masonry Layout을 가장 요구하고 있습니다.Agent Client Protocol (ACP):AI 코딩 에이전트와 코드 에디터 간의 표준 프로토콜로, 상호 운용성을 보장합니다.DeepWiki:GitHub 저장소에 대해 대화형 AI 문서를 제공하여 개발자들이 특정 코드베이스를 쉽게 이해할 수 있도록 돕습니다.인지 부하의 중요성:개발자가 이해하기 쉬운 코드를 작성하는 것이 중요하며, 과도한 코드는 인지 부하를 증가시킵니다.AI 코드 배포 경향:시니어 개발자는 주니어보다 AI 생성 코드를 더 많이 배포하며, 대체로 AI 도구가 코딩을 더 즐겁게 만든다고 답변합니다.>> FE News 25년 9월 소식 보러가기 FE News란? 네이버 FE 엔지니어들이 엄선한 양질의 FE 및 주요한 기술 소식들을 큐레이션해 공유하는 것을 목표로 하며, 이를 통해 국내 개발자들에게 지식 공유에 대한 가치 인식과 성장에 도움을 주고자 하는 기술소식 공유 프로젝트 입니다. 매월 첫째 주 수요일, 월 1회 발행 되고 있으니 많은 관심 부탁드립니다. 구독하기
9/4/2025
logo
FE News 25년 9월 소식을 전해드립니다!
주요소식다음과 같은 유용한 정보들을 만나보실 수 있습니다.Augmented vs Vibe Coding:Kent Beck은 BPlusTree3 라이브러리를 통해, Vibe Coding보다 코드 품질과 복잡성을 중시하는 Augmented Coding의 중요성을 설명했습니다. Rust, Python, C 등 다양한 언어로도 구현했습니다.Code w/ Claude Developer Conference:Anthropic의 첫 개발자 컨퍼런스에서는 Claude 4 모델, API 및 CLI 활용 사례, 다양한 플랫폼 통합 등을 소개했습니다.VS Code에서의 Prompt Injection 방지:VS Code Copilot Chat에서 발생할 수 있는 보안 문제들과 이를 방지하기 위한 개선 사항을 설명합니다.프로그램의 미래와 Vibe Coding:AI 도구의 활용으로 프로그래밍 접근법이 변화하고 있으며, 시니어 개발자는 AI 활용 시 더 빠른 개발 속도를 경험한다고 보고합니다.CSS 2025 현황:CSS가 Web apps 개발에 주로 사용되며, 새로운 기능들이 도입됐습니다. 개발자는 Mixins와 Masonry Layout을 가장 요구하고 있습니다.Agent Client Protocol (ACP):AI 코딩 에이전트와 코드 에디터 간의 표준 프로토콜로, 상호 운용성을 보장합니다.DeepWiki:GitHub 저장소에 대해 대화형 AI 문서를 제공하여 개발자들이 특정 코드베이스를 쉽게 이해할 수 있도록 돕습니다.인지 부하의 중요성:개발자가 이해하기 쉬운 코드를 작성하는 것이 중요하며, 과도한 코드는 인지 부하를 증가시킵니다.AI 코드 배포 경향:시니어 개발자는 주니어보다 AI 생성 코드를 더 많이 배포하며, 대체로 AI 도구가 코딩을 더 즐겁게 만든다고 답변합니다.>> FE News 25년 9월 소식 보러가기 FE News란? 네이버 FE 엔지니어들이 엄선한 양질의 FE 및 주요한 기술 소식들을 큐레이션해 공유하는 것을 목표로 하며, 이를 통해 국내 개발자들에게 지식 공유에 대한 가치 인식과 성장에 도움을 주고자 하는 기술소식 공유 프로젝트 입니다. 매월 첫째 주 수요일, 월 1회 발행 되고 있으니 많은 관심 부탁드립니다. 구독하기
2025.09.04
emoji
좋아요
emoji
별로에요
logo
에이닷 웹서비스팀의 E2E 테스트 도입기
에이닷 웹서비스팀의 E2E 테스트 도입기에이닷은 SK텔레콤이 2022년 5월에 공개한 AI 에이전트 서비스입니다.에이닷 웹서비스개발팀은 adot.ai 웹사이트의 검색·노트 기능을 제공하고, 앱 내 웹뷰 개발까지 담당하며 다양한 웹 기술로 사용자 경험을 강화하고 있습니다.2025년, 저희 팀의 목표 중 하나는 테스트 코드 작성 및 운영 체계화였습니다.특히 QA 자동화를 위해 E2E(End-to-End) 테스트를 본격적으로 도입해본 경험을 공유해보려 합니다.테스트 코드는 크게 세 가지로 나눌 수 있습니다.• None 이 세 가지는 실행 환경, 시점, 복잡성 등에서 차이가 있으며, E2E 테스트는 특히 실제 사용자의 서비스 흐름 전체를 자동화해 검증한다는 점에서 가장 큰 차이점을 지니고 있습니다.• None “로그인 → 페이지 이동 → 버튼 클릭 → 결과 확인”처럼 실제 사용자 시나리오 전체를 확인 가능합니다• None Playwright, Cypress, Selenium으로 DOM 클릭·입력 등 실제 사용과 유사하게 동작을 검증할 수 있습니다• None 프론트엔드·백엔드 연결 상태와 주요 기능의 안정성 테스트 할 수 있습니다• None 실행 속도가 느리고, 작성·유지보수 비용이 높습니다• None 도입 시 초기 설정과 러닝커브 필요합니다테스트 도구 선정 전, 대표적인 세 가지 도구를 비교했습니다.• 사용자 친화적인 인터페이스로 프론트엔드 테스팅에 탁월• cypress studio로 코드 자동 생성 가능하나 아직 실험적 기능 Playwright도 강력한 디버깅 기능 제공. Cypress 수준의 상호작용성을 달성하려면 추가 설정 필요• None 포괄적인 크로스 브라우저 테스팅을 지원하고, 복잡하고 대규모 프로젝트를 위한 고급 병렬 처리가 가능하며 CI/CD 연동 용이성을 고려하여 Playwright를 선택하였습니다.설치와 실행 그리고 report를 보는 방법은 아래의 간단한 명령어로 가능합니다• None Playwright의 codegen 기능은 테스트 코드를 자동으로 초안화해주는 강력한 도구입니다• None local서버를 구동시켜두고 이를 타겟으로 codegen 실행하는 방법은 아래와 같습니다• None Codegen을 통해 테스트 초안을 작성하는 과정에서 DOM selector 탐지할 수 있습니다• None input 입력하는 코드를 자동화할 수 있습니다selector는 data-testid로 관리하는것이 합리적• None Codegen이 작성해준 E2E테스트 초안은 처음엔 무척 간편하다는 느낌을 안겨주었습니다. 하지만 서비스는 빠르게 변화하고 그에 따라 코드의 변경점이 늘어날 수록 Selector에 대한 고민이 늘어났는데요.• None 결과적으로 class, id, DOM 구조는 언제든 변경될 수 있다는 점에서 점차 data-testid 기반 selector를 사용하는 방식으로 정착하게 되었습니다.• None 초기에는 개발 Repo와 테스트 Repo를 분리해서 관리하는 것으로 시작하였습니다.• None 하지만 실제 경험상 하나의 Repo에서 개발 코드와 테스트 코드를 함께 관리하는 것이 훨씬 효율적이라는 결론을 얻었습니다. 이유는 다음과 같습니다:• None product 코드 변경시 → 테스트 코드도 즉시 반영 필요합니다.• None 같은 속성은 product 코드에 직접 추가해야 하는 점에서도 역시 하나의 Repo에서 관리가 필요했습니다.• None playwright는 UI모드로 테스트를 실행할 수 있습니다.• None UI모드에서는 테스트 전체 과정이 스크린녹화되어 기록되고 원하는 시점에 mouse hover하여 테스트 과정을 step by step으로 확인 가능합니다.• None 특정 테스트 watch mode 실행을 하면 코드를 수정하고 저장 시 테스트가 자동 재실행이 되어 유용합니다.• None 스크린 녹화와 watch mode는 특정 테스트를 디버깅하고 빠른 피드백을 받기에 큰 도움이 되었습니다.• None 로그인 플로우를 테스트 코드로 구현했을 때, 단순히 만 사용하면 너무 빠른 입력에 의해 로봇 탐지에 걸려 로그인에 실패합니다.• None 이를 해결하기 위해 랜덤 wait를 삽입하여 실제 사용자 입력과 유사하게 만들어 안정적으로 로그인을 시킬 수 있었습니다.• None QA팀에서 에이닷 노트라는 서비스를 타겟으로 작성하고 공유해주신 테스트 코드는 무려 248개나 되는 방대한 분량이었습니다.• None 모든 코드를 수작업으로 작성하기엔 비효율적이었고, Cursor를 활용하기 시작하였습니다.• None 방법은 간단했는데요 먼저 Cursor에 아래와 같이 QA팀에서 제공해주신 TC 를 스크린샷해서 첨부합니다.• None “이 스크린샷 기반으로 테스트 코드를 작성해줘. 티켓 넘버를 주석으로 달아줘.”라고 입력하면 자동으로 테스트 코드 생성됩니다'• None 여러 테스트를 추가하다보면 테스트가 실패하기도 하는데요 이때 “실패하는 테스트는 예외 처리 추가해줘.” 라고 입력하면 즉시 수정을 진행합니다• None Cursor를 도입하면서 자동 코드 생성과 즉시 수정을 반복하며 코드 작성 속도를 획기적으로 단축할 수 있었습니다.E2E Test는 어떤 목표를 잡고 진행하는게 좋을까?• None Unit Test의 경우 전체 Code coverage의 60% 이상 작성하기 같은 목표를 수립하곤 합니다. E2E 테스트는 어떨까요?• None E2E테스트는 테스트의 목적과 사용자의 사용성을 테스트 하는 것이기에 Code Coverage를 목표로 설정하는 것의 의미가 크지 않습니다.• None 팀에서 선정한 중요도 높은 TC들에 대해 테스트를 작성하는 것으로 목표를 수립하였고 QA팀이 제공해주신 TC의 50% 이상의 TC를 작성하는 것으로 목표를 수립하고 진행하고 있습니다.E2E 테스트는 빠른 실행·간단한 유지보수와는 거리가 멀지만, 서비스 전체 품질을 보장하는 핵심 역할을 합니다.에이닷 웹서비스팀은 Playwright와 Cursor를 도입해 방대한 QA 시나리오를 효율적으로 자동화하고, 이를 통해 개발자와 QA 모두의 생산성을 높일 수 있었습니다.앞으로도 저희는 사용자 경험
playwright
9/3/2025
logo
에이닷 웹서비스팀의 E2E 테스트 도입기
에이닷 웹서비스팀의 E2E 테스트 도입기에이닷은 SK텔레콤이 2022년 5월에 공개한 AI 에이전트 서비스입니다.에이닷 웹서비스개발팀은 adot.ai 웹사이트의 검색·노트 기능을 제공하고, 앱 내 웹뷰 개발까지 담당하며 다양한 웹 기술로 사용자 경험을 강화하고 있습니다.2025년, 저희 팀의 목표 중 하나는 테스트 코드 작성 및 운영 체계화였습니다.특히 QA 자동화를 위해 E2E(End-to-End) 테스트를 본격적으로 도입해본 경험을 공유해보려 합니다.테스트 코드는 크게 세 가지로 나눌 수 있습니다.• None 이 세 가지는 실행 환경, 시점, 복잡성 등에서 차이가 있으며, E2E 테스트는 특히 실제 사용자의 서비스 흐름 전체를 자동화해 검증한다는 점에서 가장 큰 차이점을 지니고 있습니다.• None “로그인 → 페이지 이동 → 버튼 클릭 → 결과 확인”처럼 실제 사용자 시나리오 전체를 확인 가능합니다• None Playwright, Cypress, Selenium으로 DOM 클릭·입력 등 실제 사용과 유사하게 동작을 검증할 수 있습니다• None 프론트엔드·백엔드 연결 상태와 주요 기능의 안정성 테스트 할 수 있습니다• None 실행 속도가 느리고, 작성·유지보수 비용이 높습니다• None 도입 시 초기 설정과 러닝커브 필요합니다테스트 도구 선정 전, 대표적인 세 가지 도구를 비교했습니다.• 사용자 친화적인 인터페이스로 프론트엔드 테스팅에 탁월• cypress studio로 코드 자동 생성 가능하나 아직 실험적 기능 Playwright도 강력한 디버깅 기능 제공. Cypress 수준의 상호작용성을 달성하려면 추가 설정 필요• None 포괄적인 크로스 브라우저 테스팅을 지원하고, 복잡하고 대규모 프로젝트를 위한 고급 병렬 처리가 가능하며 CI/CD 연동 용이성을 고려하여 Playwright를 선택하였습니다.설치와 실행 그리고 report를 보는 방법은 아래의 간단한 명령어로 가능합니다• None Playwright의 codegen 기능은 테스트 코드를 자동으로 초안화해주는 강력한 도구입니다• None local서버를 구동시켜두고 이를 타겟으로 codegen 실행하는 방법은 아래와 같습니다• None Codegen을 통해 테스트 초안을 작성하는 과정에서 DOM selector 탐지할 수 있습니다• None input 입력하는 코드를 자동화할 수 있습니다selector는 data-testid로 관리하는것이 합리적• None Codegen이 작성해준 E2E테스트 초안은 처음엔 무척 간편하다는 느낌을 안겨주었습니다. 하지만 서비스는 빠르게 변화하고 그에 따라 코드의 변경점이 늘어날 수록 Selector에 대한 고민이 늘어났는데요.• None 결과적으로 class, id, DOM 구조는 언제든 변경될 수 있다는 점에서 점차 data-testid 기반 selector를 사용하는 방식으로 정착하게 되었습니다.• None 초기에는 개발 Repo와 테스트 Repo를 분리해서 관리하는 것으로 시작하였습니다.• None 하지만 실제 경험상 하나의 Repo에서 개발 코드와 테스트 코드를 함께 관리하는 것이 훨씬 효율적이라는 결론을 얻었습니다. 이유는 다음과 같습니다:• None product 코드 변경시 → 테스트 코드도 즉시 반영 필요합니다.• None 같은 속성은 product 코드에 직접 추가해야 하는 점에서도 역시 하나의 Repo에서 관리가 필요했습니다.• None playwright는 UI모드로 테스트를 실행할 수 있습니다.• None UI모드에서는 테스트 전체 과정이 스크린녹화되어 기록되고 원하는 시점에 mouse hover하여 테스트 과정을 step by step으로 확인 가능합니다.• None 특정 테스트 watch mode 실행을 하면 코드를 수정하고 저장 시 테스트가 자동 재실행이 되어 유용합니다.• None 스크린 녹화와 watch mode는 특정 테스트를 디버깅하고 빠른 피드백을 받기에 큰 도움이 되었습니다.• None 로그인 플로우를 테스트 코드로 구현했을 때, 단순히 만 사용하면 너무 빠른 입력에 의해 로봇 탐지에 걸려 로그인에 실패합니다.• None 이를 해결하기 위해 랜덤 wait를 삽입하여 실제 사용자 입력과 유사하게 만들어 안정적으로 로그인을 시킬 수 있었습니다.• None QA팀에서 에이닷 노트라는 서비스를 타겟으로 작성하고 공유해주신 테스트 코드는 무려 248개나 되는 방대한 분량이었습니다.• None 모든 코드를 수작업으로 작성하기엔 비효율적이었고, Cursor를 활용하기 시작하였습니다.• None 방법은 간단했는데요 먼저 Cursor에 아래와 같이 QA팀에서 제공해주신 TC 를 스크린샷해서 첨부합니다.• None “이 스크린샷 기반으로 테스트 코드를 작성해줘. 티켓 넘버를 주석으로 달아줘.”라고 입력하면 자동으로 테스트 코드 생성됩니다'• None 여러 테스트를 추가하다보면 테스트가 실패하기도 하는데요 이때 “실패하는 테스트는 예외 처리 추가해줘.” 라고 입력하면 즉시 수정을 진행합니다• None Cursor를 도입하면서 자동 코드 생성과 즉시 수정을 반복하며 코드 작성 속도를 획기적으로 단축할 수 있었습니다.E2E Test는 어떤 목표를 잡고 진행하는게 좋을까?• None Unit Test의 경우 전체 Code coverage의 60% 이상 작성하기 같은 목표를 수립하곤 합니다. E2E 테스트는 어떨까요?• None E2E테스트는 테스트의 목적과 사용자의 사용성을 테스트 하는 것이기에 Code Coverage를 목표로 설정하는 것의 의미가 크지 않습니다.• None 팀에서 선정한 중요도 높은 TC들에 대해 테스트를 작성하는 것으로 목표를 수립하였고 QA팀이 제공해주신 TC의 50% 이상의 TC를 작성하는 것으로 목표를 수립하고 진행하고 있습니다.E2E 테스트는 빠른 실행·간단한 유지보수와는 거리가 멀지만, 서비스 전체 품질을 보장하는 핵심 역할을 합니다.에이닷 웹서비스팀은 Playwright와 Cursor를 도입해 방대한 QA 시나리오를 효율적으로 자동화하고, 이를 통해 개발자와 QA 모두의 생산성을 높일 수 있었습니다.앞으로도 저희는 사용자 경험
2025.09.03
playwright
emoji
좋아요
emoji
별로에요
logo
Playwright로 하는 Component Test와 E2E Test Coverage
안녕하세요. 서비스웹개발팀의 프론트엔드 개발자 헨비입니다.이번 고객센터 채팅 상담 프로젝트는 Web과 Mobile Web, 그리고 “여기어때” 앱 내의 WebView(Android/iOS) 환경에서 동시에 작동하는 서비스입니다.실시간 상호작용과 멀티 디바이스 환경에서 안정성을 보장하기 위해 단위 테스트와 E2E 테스트를 도입했습니다.특히 핵심 사용자 여정(접속→연결→메시지/파일→종료)은 수동 테스트만으로는 리스크를 충분히 검증하기 어렵다고 판단했습니다.이러한 이유로 테스트 코드의 필요성을 절실히 느꼈고, 그 과정과 선택을 이번 글에서 공유하고자 합니다.1. 왜 Playwright를 선택했는가GUI E2E Test Tool 중의 양대산맥인 Cypress와 Playwright 가 있습니다.각자의 장점과 단점을 알아보고 왜 Playwright를 선택하게 되었는지 같이 체크 해보겠습니다.Cypress 장점GUI 기반 Test Runner와 Time‑Travel 덕분에 개발자 경험(DX)이 뛰어납니다.방대한 생태계와 네트워크 스텁 기능, 그리고 친절한 문서가 초보자 진입 장벽을 낮춰줍니다.설정과 사용 흐름이 단순해서 빠르게 시작할 수 있습니다.결론적으로 테스트코드의 이해와 작성이 쉽고 UI가 이쁩니다.Cypress 단점브라우저 엔진과 탭, 도메인 제어에 제약이 있어, 복잡한 시나리오 테스트에는 부적합할 수 있습니다.Safari(WebKit)를 지원하지 않아 iOS Safari 호환성을 보장하기 어렵습니다.Playwright 장점Chromium, Firefox, WebKit까지 모두 공식 지원해 크로스 브라우징 커버리지가 넓습니다.멀티 탭, 권한 설정, 네트워크 제어, 디바이스 및 GPS 시뮬레이션 등 고급 브라우저 제어 기능이 훨씬 풍성합니다.자동 대기, 병렬 실행, Trace/비디오/스크린샷 캡처 같은 견고한 테스트 인프라가 기본 포함되어 있습니다.Playwright 단점Cypress의 UI Runner처럼 한눈에 보여지는 인터페이스와 같은 개발자 통합 경험은 아니어서, 일부에겐 다소 불편할 수 있습니다.선택 기준과 결론본 서비스는 고객센터 “실시간 채팅” 앱으로 iOS Safari(WebKit) 호환성과 모바일 뷰 재현성이 매우 중요합니다. 또한 파일 업로드/미디어 재생, 웹소켓 기반 메시징 등 브라우저 레벨 제어가 필요했습니다.멀티 브라우저(WebKit 포함)와 모바일 디바이스 프로필과 후에 포커싱/권한/다운로드까지 포괄하는 제어가 필요했기에 Playwright를 선택했습니다. 더군다나 Web과 Webview 모두에서 사용되는 앱이므로 많은 멀티 브라우저와 다양한 모바일 디바이스 프로필이 있다는 점이 매력적 이였습니다.Component Test, E2E가 모두 필요한 이유실시간 채팅은 “UI 상호작용의 촘촘함”과 “End-To-End 시나리오의 연속성”이 모두 중요합니다.컴포넌트 테스트(CT)로는 채팅에 접속해서 바로 만나는 다양한 컴포넌트들의 핵심 UI의 상태 전이(비활성/활성, 파일 선택, 미디어 렌더와 닫기)를 빠르고 결정적으로 검증했
cypress
playwright
9/3/2025
logo
Playwright로 하는 Component Test와 E2E Test Coverage
안녕하세요. 서비스웹개발팀의 프론트엔드 개발자 헨비입니다.이번 고객센터 채팅 상담 프로젝트는 Web과 Mobile Web, 그리고 “여기어때” 앱 내의 WebView(Android/iOS) 환경에서 동시에 작동하는 서비스입니다.실시간 상호작용과 멀티 디바이스 환경에서 안정성을 보장하기 위해 단위 테스트와 E2E 테스트를 도입했습니다.특히 핵심 사용자 여정(접속→연결→메시지/파일→종료)은 수동 테스트만으로는 리스크를 충분히 검증하기 어렵다고 판단했습니다.이러한 이유로 테스트 코드의 필요성을 절실히 느꼈고, 그 과정과 선택을 이번 글에서 공유하고자 합니다.1. 왜 Playwright를 선택했는가GUI E2E Test Tool 중의 양대산맥인 Cypress와 Playwright 가 있습니다.각자의 장점과 단점을 알아보고 왜 Playwright를 선택하게 되었는지 같이 체크 해보겠습니다.Cypress 장점GUI 기반 Test Runner와 Time‑Travel 덕분에 개발자 경험(DX)이 뛰어납니다.방대한 생태계와 네트워크 스텁 기능, 그리고 친절한 문서가 초보자 진입 장벽을 낮춰줍니다.설정과 사용 흐름이 단순해서 빠르게 시작할 수 있습니다.결론적으로 테스트코드의 이해와 작성이 쉽고 UI가 이쁩니다.Cypress 단점브라우저 엔진과 탭, 도메인 제어에 제약이 있어, 복잡한 시나리오 테스트에는 부적합할 수 있습니다.Safari(WebKit)를 지원하지 않아 iOS Safari 호환성을 보장하기 어렵습니다.Playwright 장점Chromium, Firefox, WebKit까지 모두 공식 지원해 크로스 브라우징 커버리지가 넓습니다.멀티 탭, 권한 설정, 네트워크 제어, 디바이스 및 GPS 시뮬레이션 등 고급 브라우저 제어 기능이 훨씬 풍성합니다.자동 대기, 병렬 실행, Trace/비디오/스크린샷 캡처 같은 견고한 테스트 인프라가 기본 포함되어 있습니다.Playwright 단점Cypress의 UI Runner처럼 한눈에 보여지는 인터페이스와 같은 개발자 통합 경험은 아니어서, 일부에겐 다소 불편할 수 있습니다.선택 기준과 결론본 서비스는 고객센터 “실시간 채팅” 앱으로 iOS Safari(WebKit) 호환성과 모바일 뷰 재현성이 매우 중요합니다. 또한 파일 업로드/미디어 재생, 웹소켓 기반 메시징 등 브라우저 레벨 제어가 필요했습니다.멀티 브라우저(WebKit 포함)와 모바일 디바이스 프로필과 후에 포커싱/권한/다운로드까지 포괄하는 제어가 필요했기에 Playwright를 선택했습니다. 더군다나 Web과 Webview 모두에서 사용되는 앱이므로 많은 멀티 브라우저와 다양한 모바일 디바이스 프로필이 있다는 점이 매력적 이였습니다.Component Test, E2E가 모두 필요한 이유실시간 채팅은 “UI 상호작용의 촘촘함”과 “End-To-End 시나리오의 연속성”이 모두 중요합니다.컴포넌트 테스트(CT)로는 채팅에 접속해서 바로 만나는 다양한 컴포넌트들의 핵심 UI의 상태 전이(비활성/활성, 파일 선택, 미디어 렌더와 닫기)를 빠르고 결정적으로 검증했
2025.09.03
cypress
playwright
emoji
좋아요
emoji
별로에요
logo
AWS MediaConvert 를 활용한 동영상 스트리밍 서비스 구축기 - 3편
3편에서는 lambda 설정에 대해서 알아보겠습니다.아직 갈 길이 멉니다!!전체 아키텍쳐는 1편을 참고해 주시길 바랍니다.• None S3에 동영상이 업로드 완료• None 해당 lambda에서 업로드 파일 트리거• None 업로드된 동영상 확인 및 media convert에 작업 의뢰기본 실행 역할 변경 → 기존 역할 사용 → 1편 IAM에서 만들었던 "{환경}-ifland-Role-LambdaVod" 선택아래 2개의 파일을 zip 파일로 압축.코드 → 에서 업로드 클릭 → .zip 파일 선택 후 위에서 압축한 zip 파일 업로드MediaConvertRole : 1편 IAM 에서 만들었던 {환경}-ifland-Role-MediaConvert 의 ARN버킷 : 2편 S3 에서 만든 버킷 선택• None event bridge에서 작업 완료 내용 트리거 및 lambda로 내용 전달• None lambda에서 작업 내역 확인 및 데이터 워싱• None CMS 시스템으로 결과 callback 이프랜드에서는 구축한 동영상 시스템을 Content Media Service(CMS) 라고 지칭함.기본 실행 역할 변경 → 기존 역할 사용 → 1편 IAM 에서 만들었던 "{환경}-ifland-Role-LambdaVod" 선택프로젝트 폴더 생성후 convert.py 와 requirements.txt 를 배치.필요 라이브러리 다운로드프로젝트 폴더 안에서 모든 파일을 zip 으로 압축• None 코드 → 에서 업로드 클릭 → .zip 파일 선택 후 위에서 압축한 zip 파일 업로드구성 → 환경 변수에 결과를 알려줄 API 입력CallbackUrl : 동영상 변환 결과를 받을수 있는 API URL 입력• None 결과를 받을수 있는 API 개발이 별도 필요한데요. 소스 포함해서 이 부분은 추후 블로그 작성시 공유 드릴 예정입니다.complete.py 의 내용은 eventbridge에서 받은 mediaconvert 결과값을 그대로 api 에 전달하지 않고, lambda에서 데이터를 가공해서 api 로 전달 한다.데이터 가공전(mediaconvert 결과값 원본)데이터 가공후(개발될 callback API 에서 받을 데이터)4편에서는 VPC 설정과 lambda에서 이 VPC를 연결하는 작업을 진행하도록 하겠습니다.유저 입장에서는 단순히 동영상 하나 보는것 뿐인데 실제 구축시에는 이렇게나 많이 설정이....아무튼 4편으로 다시 돌아오겠습니다!
9/3/2025
logo
AWS MediaConvert 를 활용한 동영상 스트리밍 서비스 구축기 - 3편
3편에서는 lambda 설정에 대해서 알아보겠습니다.아직 갈 길이 멉니다!!전체 아키텍쳐는 1편을 참고해 주시길 바랍니다.• None S3에 동영상이 업로드 완료• None 해당 lambda에서 업로드 파일 트리거• None 업로드된 동영상 확인 및 media convert에 작업 의뢰기본 실행 역할 변경 → 기존 역할 사용 → 1편 IAM에서 만들었던 "{환경}-ifland-Role-LambdaVod" 선택아래 2개의 파일을 zip 파일로 압축.코드 → 에서 업로드 클릭 → .zip 파일 선택 후 위에서 압축한 zip 파일 업로드MediaConvertRole : 1편 IAM 에서 만들었던 {환경}-ifland-Role-MediaConvert 의 ARN버킷 : 2편 S3 에서 만든 버킷 선택• None event bridge에서 작업 완료 내용 트리거 및 lambda로 내용 전달• None lambda에서 작업 내역 확인 및 데이터 워싱• None CMS 시스템으로 결과 callback 이프랜드에서는 구축한 동영상 시스템을 Content Media Service(CMS) 라고 지칭함.기본 실행 역할 변경 → 기존 역할 사용 → 1편 IAM 에서 만들었던 "{환경}-ifland-Role-LambdaVod" 선택프로젝트 폴더 생성후 convert.py 와 requirements.txt 를 배치.필요 라이브러리 다운로드프로젝트 폴더 안에서 모든 파일을 zip 으로 압축• None 코드 → 에서 업로드 클릭 → .zip 파일 선택 후 위에서 압축한 zip 파일 업로드구성 → 환경 변수에 결과를 알려줄 API 입력CallbackUrl : 동영상 변환 결과를 받을수 있는 API URL 입력• None 결과를 받을수 있는 API 개발이 별도 필요한데요. 소스 포함해서 이 부분은 추후 블로그 작성시 공유 드릴 예정입니다.complete.py 의 내용은 eventbridge에서 받은 mediaconvert 결과값을 그대로 api 에 전달하지 않고, lambda에서 데이터를 가공해서 api 로 전달 한다.데이터 가공전(mediaconvert 결과값 원본)데이터 가공후(개발될 callback API 에서 받을 데이터)4편에서는 VPC 설정과 lambda에서 이 VPC를 연결하는 작업을 진행하도록 하겠습니다.유저 입장에서는 단순히 동영상 하나 보는것 뿐인데 실제 구축시에는 이렇게나 많이 설정이....아무튼 4편으로 다시 돌아오겠습니다!
2025.09.03
emoji
좋아요
emoji
별로에요
logo
코드 품질 개선 기법 19편: 차일드 록
LY Corporation은 높은 개발 생산성을 유지하기 위해 코드 품질 및 개발 문화 개선에 힘쓰고 있습니다. 이를 위해 다양한 노력을 하고 있는데요. 그중 하나가 Review Committee 활동입니다.Review Committee에서는 머지된 코드를 다시 리뷰해 리뷰어와 작성자에게 피드백을 주고, 리뷰하면서 얻은 지식과 인사이트를 Weekly Report라는 이름으로 매주 공유하고 있습니다. 이 Weekly Report 중 일반적으로 널리 적용할 수 있는 주제를 골라 블로그에 코드 품질 개선 기법 시리즈를 연재하고 있습니다.이번에 블로그로 공유할 Weekly Report의 제목은 '차일드 록(child lock)'입니다.메시지의 데이터 모델로 라는 추상 클래스가 있다고 가정해 봅시다. 메시지에는 여러 유형이 있으며, 각 유형은 의 자식 클래스를 정의하는 방식으로 표현합니다.여기서 의 자식 클래스 의 목록 를 화면에 표시하기 위해 다음과 같이 추상 클래스 를 정의했다고 가정하겠습니다. 단, 메시지 표시 로직은 메시지 유형에 따라 달라지므로 에는 목록 표시 로직을 구현하지 않았습니다. 부모 클래스의 에서는 헤더와 푸터(footer)만 표시하고, 목록 표시는 자식 클래스에서 오버라이딩해서 구현할 것으로 기대한 코드입니다(Kotlin에서 은 오버라이딩이 가능하다는 의미의 수정자입니다).다음 는 를 구현한 예시입니다. 를 타입 파라미터로 지정하고, 해당 클래스 고유의 목록 표시 로직을 에 정의했습니다.이 코드에 문제가 있을까요?자식 클래스가 장난을 못 치도록 하기를 명시적으로 호출해야 한다는 것은 대부분 오버라이딩 가능한 함수의 범위가 너무 넓다는 것을 의미합니다(예외에 대해서는 뒤에서 설명하겠습니다). 위 코드는 오버라이딩할 수 있는 함수의 범위가 너무 넓기 때문에 다음과 같은 구현 실수가 발생하기 쉽습니다.• 호출 누락: 모든 자식 클래스는 헤더와 푸터를 업데이트하려면 를 호출해야 합니다. 만약 호출을 누락한 경우 헤더와 푸터가 업데이트되지 않는 버그가 발생하며, 이때 특별히 에러 가 발생하지 않기 때문에 버그를 간과하기 쉽습니다.• 오버라이딩 누락: 상속 시 오버라이딩이 필요하다는 제약 조건이 인라인 주석으로만 설명돼 있습니다. 따라서 오버라이딩해야 할 다른 함수가 있는 상황에서는 오버라이딩을 누락하는 버그가 발생하기 쉽습니다. 오버라이딩을 강제하기 위해 수정자를 사용하려고 해도 헤더나 푸터 업데이트 로직이 섞여 있다면 쉽지 않습니다.• 기대하지 않은 구현: 인라인 주석에 적혀 있는 대로 오버라이딩된 에서는 메시지 목록 표시만 구현되기를 기대하겠지만, 실제로 를 호출하면 헤더와 푸터도 표시됩니다. 즉, 오버라이딩의 책임 범위와 함수의 책임 범위가 일치하지 않습니다. 이로 인해 오버라이딩의 책임 범위를 오해하기 쉬우며, 결과적으로 책임 범위를 벗어난 코드가 자식 클래스에 구현될 수 있습니다.이 문제를 해결하기 위해서는 함수를 으로 만들지 말고 목록을 업데이트하는 함수인 를 분리해 추상 메서드(또는 순수 가상 함수)로 만드는 것이 좋습니다.자식 클래스는 다음과 같습니다.이렇게 하면 '헤더 및 푸터와 메시지 목록을 업데이트한다'는 의 흐름은 변경할 수 없게 만들면서 자식 클래스마다 메시지 목록을 다르게 구현할 수 있습니다. 이처럼 자식 클래스가 변경할 수 있는 범위를 제한하면 코드를 더욱 견고하게 만들 수 있습니다.비슷한 문제를 피하려면 다음과 같은 상황을 피하는 것이 좋습니다.• 오버라이딩된 부모 클래스의 함수를 호출하는 경우(명시적으로 를 사용하는 경우)• 다만 라이프사이클과 관련된 함수(생성자, 소멸자 등)와 플랫폼이나 라이브러리의 제약 조건 때문에 필요한 경우(Android의 등)는 예외.• 자식 클래스에서 공통으로 사용되는 함수의 흐름을 각 자식 클래스에서 구현하는 경우이와 같은 상황에 해당한다면 오버라이딩 가능한 범위를 제한하는 것이 좋습니다.C++에서는 함수를 정의할 수 있습니다. 이 함수는 부모 클래스에서만 호출할 수 있지만, 호출은 동적으로 디스패치됩니다. 함수를 사용하면 전체 흐름( )을 변경하지 않고 각 자식 클래스의 로직( )을 변경할 수 있습니다.
9/3/2025
logo
코드 품질 개선 기법 19편: 차일드 록
LY Corporation은 높은 개발 생산성을 유지하기 위해 코드 품질 및 개발 문화 개선에 힘쓰고 있습니다. 이를 위해 다양한 노력을 하고 있는데요. 그중 하나가 Review Committee 활동입니다.Review Committee에서는 머지된 코드를 다시 리뷰해 리뷰어와 작성자에게 피드백을 주고, 리뷰하면서 얻은 지식과 인사이트를 Weekly Report라는 이름으로 매주 공유하고 있습니다. 이 Weekly Report 중 일반적으로 널리 적용할 수 있는 주제를 골라 블로그에 코드 품질 개선 기법 시리즈를 연재하고 있습니다.이번에 블로그로 공유할 Weekly Report의 제목은 '차일드 록(child lock)'입니다.메시지의 데이터 모델로 라는 추상 클래스가 있다고 가정해 봅시다. 메시지에는 여러 유형이 있으며, 각 유형은 의 자식 클래스를 정의하는 방식으로 표현합니다.여기서 의 자식 클래스 의 목록 를 화면에 표시하기 위해 다음과 같이 추상 클래스 를 정의했다고 가정하겠습니다. 단, 메시지 표시 로직은 메시지 유형에 따라 달라지므로 에는 목록 표시 로직을 구현하지 않았습니다. 부모 클래스의 에서는 헤더와 푸터(footer)만 표시하고, 목록 표시는 자식 클래스에서 오버라이딩해서 구현할 것으로 기대한 코드입니다(Kotlin에서 은 오버라이딩이 가능하다는 의미의 수정자입니다).다음 는 를 구현한 예시입니다. 를 타입 파라미터로 지정하고, 해당 클래스 고유의 목록 표시 로직을 에 정의했습니다.이 코드에 문제가 있을까요?자식 클래스가 장난을 못 치도록 하기를 명시적으로 호출해야 한다는 것은 대부분 오버라이딩 가능한 함수의 범위가 너무 넓다는 것을 의미합니다(예외에 대해서는 뒤에서 설명하겠습니다). 위 코드는 오버라이딩할 수 있는 함수의 범위가 너무 넓기 때문에 다음과 같은 구현 실수가 발생하기 쉽습니다.• 호출 누락: 모든 자식 클래스는 헤더와 푸터를 업데이트하려면 를 호출해야 합니다. 만약 호출을 누락한 경우 헤더와 푸터가 업데이트되지 않는 버그가 발생하며, 이때 특별히 에러 가 발생하지 않기 때문에 버그를 간과하기 쉽습니다.• 오버라이딩 누락: 상속 시 오버라이딩이 필요하다는 제약 조건이 인라인 주석으로만 설명돼 있습니다. 따라서 오버라이딩해야 할 다른 함수가 있는 상황에서는 오버라이딩을 누락하는 버그가 발생하기 쉽습니다. 오버라이딩을 강제하기 위해 수정자를 사용하려고 해도 헤더나 푸터 업데이트 로직이 섞여 있다면 쉽지 않습니다.• 기대하지 않은 구현: 인라인 주석에 적혀 있는 대로 오버라이딩된 에서는 메시지 목록 표시만 구현되기를 기대하겠지만, 실제로 를 호출하면 헤더와 푸터도 표시됩니다. 즉, 오버라이딩의 책임 범위와 함수의 책임 범위가 일치하지 않습니다. 이로 인해 오버라이딩의 책임 범위를 오해하기 쉬우며, 결과적으로 책임 범위를 벗어난 코드가 자식 클래스에 구현될 수 있습니다.이 문제를 해결하기 위해서는 함수를 으로 만들지 말고 목록을 업데이트하는 함수인 를 분리해 추상 메서드(또는 순수 가상 함수)로 만드는 것이 좋습니다.자식 클래스는 다음과 같습니다.이렇게 하면 '헤더 및 푸터와 메시지 목록을 업데이트한다'는 의 흐름은 변경할 수 없게 만들면서 자식 클래스마다 메시지 목록을 다르게 구현할 수 있습니다. 이처럼 자식 클래스가 변경할 수 있는 범위를 제한하면 코드를 더욱 견고하게 만들 수 있습니다.비슷한 문제를 피하려면 다음과 같은 상황을 피하는 것이 좋습니다.• 오버라이딩된 부모 클래스의 함수를 호출하는 경우(명시적으로 를 사용하는 경우)• 다만 라이프사이클과 관련된 함수(생성자, 소멸자 등)와 플랫폼이나 라이브러리의 제약 조건 때문에 필요한 경우(Android의 등)는 예외.• 자식 클래스에서 공통으로 사용되는 함수의 흐름을 각 자식 클래스에서 구현하는 경우이와 같은 상황에 해당한다면 오버라이딩 가능한 범위를 제한하는 것이 좋습니다.C++에서는 함수를 정의할 수 있습니다. 이 함수는 부모 클래스에서만 호출할 수 있지만, 호출은 동적으로 디스패치됩니다. 함수를 사용하면 전체 흐름( )을 변경하지 않고 각 자식 클래스의 로직( )을 변경할 수 있습니다.
2025.09.03
emoji
좋아요
emoji
별로에요
Copyright © 2025. Codenary All Rights Reserved.