Claude Code 같은 LLM으로 직접 스타일(Direct Style)로 작성된 Scala 3 애플리케이션을 생성할 때 필요한 가이드라인과 도구 설정, 개발 프로세스, 그리고 Tapir/Ox 활용 팁을 정리한다.
virtuslab.com에 오신 것을 환영합니다! 더 관련성 높은 경험을 제공하기 위해, 저희는 사이트 기능을 활성화하고 인기 콘텐츠를 추적하기 위해 쿠키를 사용합니다. 쿠키는 손쉬운 소셜 공유를 가능하게 하고, 사용자의 관심사 및 위치에 맞춘 기사, 채용 정보, 광고를 제공하는 데 도움이 됩니다. 개인정보 처리방침에 대해 더 알아보세요: Google privacy policy opens in new tab
세부 정보 표시 세부 정보 숨기기
필수
엄격히 필수적인 쿠키는 페이지 탐색 및 보안 영역 접근과 같은 기본 기능을 활성화하여 웹사이트를 탐색 가능하게 합니다. 이러한 쿠키 없이는 웹사이트가 정상적으로 작동할 수 없습니다.
서비스: Cookie Information
목적: 웹사이트의 기술적 기능을 지원합니다.
https://virtuslab.com/privacy-policy: Cookie Information - https://virtuslab.com/privacy-policy
만료: 1년
이름: CookieInformationConsent
공급업체: virtuslab.com
서비스: Cloudflare
목적: 대기 중
https://virtuslab.com/privacy-policy: Cloudflare - https://virtuslab.com/privacy-policy
만료: 세션
이름: _cfuvid
공급업체: .hsforms.com
서비스: Cloudflare
목적: 대기 중
https://virtuslab.com/privacy-policy: Cloudflare - https://virtuslab.com/privacy-policy
만료: 세션
이름: _cfuvid
공급업체: .hubspot.com
서비스: Piwik PRO
목적:
https://virtuslab.com/privacy-policy: Piwik PRO - https://virtuslab.com/privacy-policy
만료: 1년
이름: ppms_privacy_*
공급업체: .virtuslab.com
서비스: Cloudflare
목적: 대기 중
https://virtuslab.com/privacy-policy: Cloudflare - https://virtuslab.com/privacy-policy
만료: 세션
이름: _cfuvid
공급업체: .vimeo.com
서비스: Piwik PRO
목적:
https://virtuslab.com/privacy-policy: Piwik PRO - https://virtuslab.com/privacy-policy
만료: 30분
이름: _pk_idxxx
공급업체: virtuslab.com
서비스: Piwik PRO
목적:
https://virtuslab.com/privacy-policy: Piwik PRO - https://virtuslab.com/privacy-policy
만료: 30분
이름: _pk_sesxxx
공급업체: virtuslab.com
기능
기능 쿠키는 웹사이트의 표시 방식이나 동작 방식을 바꾸는 정보를 저장할 수 있게 해줍니다. 예를 들어 선호하는 언어 또는 지역 등이 이에 해당합니다.
서비스: Cloudflare
목적: 웹사이트의 기술적 기능을 지원합니다.
https://virtuslab.com/privacy-policy: Cloudflare - https://virtuslab.com/privacy-policy
만료: 30분
이름: __cf_bm
공급업체: .twitter.com
서비스:
목적: 대기 중
만료: 세션
이름: cookietest
공급업체: virtuslab.com
서비스: Cloudflare
목적: 웹사이트의 기술적 기능을 지원합니다.
https://virtuslab.com/privacy-policy: Cloudflare - https://virtuslab.com/privacy-policy
만료: 10분
이름: __cf_bm
공급업체: .apollo.io
서비스: Cloudflare
목적: 웹사이트의 기술적 기능을 지원합니다.
https://virtuslab.com/privacy-policy: Cloudflare - https://virtuslab.com/privacy-policy
만료: 몇 초
이름: __cf_bm
공급업체: .vimeo.com
서비스: Cloudflare
목적: 웹사이트의 기술적 기능을 지원합니다.
https://virtuslab.com/privacy-policy: Cloudflare - https://virtuslab.com/privacy-policy
만료: 16분
이름: __cf_bm
공급업체: .hubspot.com
서비스: Cloudflare
목적: 웹사이트의 기술적 기능을 지원합니다.
https://virtuslab.com/privacy-policy: Cloudflare - https://virtuslab.com/privacy-policy
만료: 30분
이름: __cf_bm
공급업체: .t.co
통계
통계 쿠키는 방문자가 웹사이트와 어떻게 상호작용하는지 이해할 수 있도록 정보를 수집하고 보고합니다.
서비스: Piwik PRO
목적:
https://virtuslab.com/privacy-policy: Piwik PRO - https://virtuslab.com/privacy-policy
만료: 1년
이름: _pk_idxxx
공급업체: virtuslab.com
서비스: Microsoft Clarity
목적: 분석 및 보고 목적을 위해 사용자의 활동과 관련된 익명 정보를 수집합니다.
https://virtuslab.com/privacy-policy: Microsoft Clarity - https://virtuslab.com/privacy-policy
만료: 1년
이름: _clck
공급업체: .virtuslab.com
서비스: Google Analytics
목적:
https://virtuslab.com/privacy-policy: Google Analytics - https://virtuslab.com/privacy-policy
만료: 1년
이름: _ga_xxx
공급업체: .virtuslab.com
서비스: Piwik PRO
목적:
https://virtuslab.com/privacy-policy: Piwik PRO - https://virtuslab.com/privacy-policy
만료: 30분
이름: _pk_sesxxx
공급업체: virtuslab.com
서비스: Google Analytics
목적: 분석 및 보고 목적을 위해 사용자의 활동과 관련된 익명 정보를 수집합니다.
https://virtuslab.com/privacy-policy: Google Analytics - https://virtuslab.com/privacy-policy
만료: 1년
이름: _ga
공급업체: .virtuslab.com
서비스: Microsoft Clarity
목적: 분석 및 보고 목적을 위해 사용자의 활동과 관련된 익명 정보를 수집합니다.
https://virtuslab.com/privacy-policy: Microsoft Clarity - https://virtuslab.com/privacy-policy
만료: 하루
이름: _clsk
공급업체: virtuslab.com
서비스: Google Analytics
목적:
https://virtuslab.com/privacy-policy: Google Analytics - https://virtuslab.com/privacy-policy
만료: 1년
이름: _ga_xxx
공급업체: virtuslab.com
서비스: Microsoft Clarity
목적: 분석 및 보고 목적을 위해 사용자의 활동과 관련된 익명 정보를 수집합니다.
https://virtuslab.com/privacy-policy: Microsoft Clarity - https://virtuslab.com/privacy-policy
만료: 하루
이름: _clsk
공급업체: .virtuslab.com
마케팅
마케팅 쿠키는 웹사이트 간 방문자를 추적하는 데 사용됩니다. 목적은 개별 사용자에게 관련성이 높고 흥미로운 광고를 표시하여, 게시자 및 제3자 광고주에게 더 높은 가치를 제공하는 것입니다.
서비스: Google Marketing Platform
목적: 사용자의 정보와 웹사이트 내 활동을 수집하여 온라인 마케팅에 사용합니다. 수집된 정보는 여러 채널과 기기에서 사용자에게 광고를 타겟팅하는 데 사용됩니다.
https://virtuslab.com/privacy-policy: Google Marketing Platform - https://virtuslab.com/privacy-policy
만료: 1년
이름: IDE
공급업체: .doubleclick.net
서비스: Twitter
목적: 파트너 및 기타 플랫폼을 통해 제품을 홍보하기 위해 사용자 정보를 수집함으로써 온라인 마케팅을 지원합니다.
https://virtuslab.com/privacy-policy: Twitter - https://virtuslab.com/privacy-policy
만료: 1년
이름: personalization_id
공급업체: .twitter.com
서비스: HubSpot
목적: 사용자와 웹사이트에서의 활동에 관한 정보를 수집합니다. 이 정보는 사용자 행동을 추적·분석하고 타겟 광고를 제공하는 데 사용됩니다.
https://virtuslab.com/privacy-policy: HubSpot - https://virtuslab.com/privacy-policy
만료: 세션
이름: __hssrc
공급업체: .virtuslab.com
서비스: Leadfeeder
목적: 사용자와 웹사이트에서의 활동에 관한 정보를 수집합니다. 이 정보는 사용자 행동을 추적·분석하고 타겟 광고를 제공하는 데 사용됩니다.
https://virtuslab.com/privacy-policy: Leadfeeder - https://virtuslab.com/privacy-policy
만료: 1년
이름: _lfa
공급업체: virtuslab.com
서비스: Twitter
목적: 파트너 및 기타 플랫폼을 통해 제품을 홍보하기 위해 사용자 정보를 수집함으로써 온라인 마케팅을 지원합니다.
https://virtuslab.com/privacy-policy: Twitter - https://virtuslab.com/privacy-policy
만료: 1년
이름: muc_ads
공급업체: .t.co
서비스: Twitter
목적: 사용자의 정보와 웹사이트 내 활동을 수집하여 온라인 마케팅에 사용합니다. 수집된 정보는 웹 전반에서 사용자에게 광고를 타겟팅하는 데 사용됩니다.
https://virtuslab.com/privacy-policy: Twitter - https://virtuslab.com/privacy-policy
만료: 1년
이름: guest_id_marketing
공급업체: .twitter.com
서비스: Youtube, Google
목적: 웹사이트에서 제3자 플랫폼의 통합을 지원합니다.
https://virtuslab.com/privacy-policy: Youtube, Google - https://virtuslab.com/privacy-policy
만료: 6개월
이름: __Secure-ROLLOUT_TOKEN
공급업체: .youtube.com
서비스: Leadfamly
목적: 웹사이트에서 제3자 플랫폼의 통합을 지원합니다.
https://virtuslab.com/privacy-policy: Leadfamly - https://virtuslab.com/privacy-policy
만료: 몇 초
이름: _lfa_test_cookie_stored
공급업체: .virtuslab.com
서비스: Youtube, Google
목적: 사용자와 웹사이트에서의 활동에 관한 정보를 수집합니다. 수집된 정보는 사용자 행동을 추적·분석하고, 개별 사용자 요구를 충족하며, 타겟 광고를 제공하는 데 사용됩니다.
https://virtuslab.com/privacy-policy: Youtube, Google - https://virtuslab.com/privacy-policy
만료: 6개월
이름: VISITOR_PRIVACY_METADATA
공급업체: .youtube.com
서비스: Leadfeeder
목적: 사용자와 웹사이트에서의 활동에 관한 정보를 수집합니다. 이 정보는 사용자 행동을 추적·분석하고 타겟 광고를 제공하는 데 사용됩니다.
https://virtuslab.com/privacy-policy: Leadfeeder - https://virtuslab.com/privacy-policy
만료: 1년
이름: _lfa
공급업체: .virtuslab.com
서비스: HubSpot
목적: 사용자와 웹사이트에서의 활동에 관한 정보를 수집합니다. 이 정보는 사용자 행동을 추적·분석하고 타겟 광고를 제공하는 데 사용됩니다.
https://virtuslab.com/privacy-policy: HubSpot - https://virtuslab.com/privacy-policy
만료: 30분
이름: __hssc
공급업체: virtuslab.com
서비스: Youtube, Google
목적: 사용자와 웹사이트에서의 활동에 관한 정보를 수집합니다. 수집된 정보는 사용자 행동을 추적·분석하고, 개별 사용자 요구를 충족하며, 타겟 광고를 제공하는 데 사용됩니다.
https://virtuslab.com/privacy-policy: Youtube, Google - https://virtuslab.com/privacy-policy
만료: 6개월
이름: __Secure-YNID
공급업체: .youtube.com
서비스: Youtube, Google
목적: 타겟 광고 제공을 목적으로, 임베디드 비디오 플레이어를 통해 웹사이트에서 사용자의 정보 및 활동을 수집합니다.
https://virtuslab.com/privacy-policy: Youtube, Google - https://virtuslab.com/privacy-policy
만료: 6개월
이름: VISITOR_INFO1_LIVE
공급업체: .youtube.com
서비스: LinkedIn
목적: 파트너 및 기타 플랫폼을 통해 제품을 홍보하기 위해 사용자 정보를 수집함으로써 온라인 마케팅을 지원합니다.
https://virtuslab.com/privacy-policy: LinkedIn - https://virtuslab.com/privacy-policy
만료: 1년
이름: bcookie
공급업체: .linkedin.com
서비스: LinkedIn
목적: 파트너 및 기타 플랫폼을 통해 제품을 홍보하기 위해 사용자 정보를 수집함으로써 온라인 마케팅을 지원합니다.
https://virtuslab.com/privacy-policy: LinkedIn - https://virtuslab.com/privacy-policy
만료: 하루
이름: lidc
공급업체: .linkedin.com
서비스: Twitter
목적: 사용자의 정보와 웹사이트 내 활동을 수집하여 온라인 마케팅에 사용합니다. 수집된 정보는 웹 전반에서 사용자에게 광고를 타겟팅하는 데 사용됩니다.
https://virtuslab.com/privacy-policy: Twitter - https://virtuslab.com/privacy-policy
만료: 1년
이름: guest_id_ads
공급업체: .twitter.com
서비스: Twitter
목적: 파트너 및 기타 플랫폼을 통해 제품을 홍보하기 위해 사용자 정보를 수집함으로써 온라인 마케팅을 지원합니다.
https://virtuslab.com/privacy-policy: Twitter - https://virtuslab.com/privacy-policy
만료: 1년
이름: guest_id
공급업체: .twitter.com
서비스: Leadfamly
목적: 웹사이트에서 제3자 플랫폼의 통합을 지원합니다.
https://virtuslab.com/privacy-policy: Leadfamly - https://virtuslab.com/privacy-policy
만료: 몇 초
이름: _lfa_test_cookie_stored
공급업체: virtuslab.com
서비스: Google Marketing Platform
목적: 사용자의 정보와 웹사이트 내 활동을 수집하여 온라인 마케팅에 사용합니다. 수집된 정보는 여러 채널과 기기에서 사용자에게 광고를 타겟팅하는 데 사용됩니다.
https://virtuslab.com/privacy-policy: Google Marketing Platform - https://virtuslab.com/privacy-policy
만료: 15분
이름: test_cookie
공급업체: .doubleclick.net
서비스: Youtube, Google
목적: 타겟 광고 제공을 목적으로, 임베디드 비디오 플레이어를 통해 웹사이트에서 사용자의 정보 및 활동을 수집합니다.
https://virtuslab.com/privacy-policy: Youtube, Google - https://virtuslab.com/privacy-policy
만료: 세션
이름: YSC
공급업체: .youtube.com
서비스: LinkedIn
목적: 파트너 및 기타 플랫폼을 통해 제품을 홍보하기 위해 사용자 정보를 수집함으로써 온라인 마케팅을 지원합니다.
https://virtuslab.com/privacy-policy: LinkedIn - https://virtuslab.com/privacy-policy
만료: 6개월
이름: li_gc
공급업체: .linkedin.com
서비스: Google
목적: 타겟 광고를 제공하기 위해 웹사이트에서 제3자 플랫폼의 통합을 지원합니다.
https://virtuslab.com/privacy-policy: Google - https://virtuslab.com/privacy-policy
만료: 3개월
이름: _gcl_au
공급업체: .virtuslab.com
서비스: Facebook
목적: 광고 및 사이트 분석 서비스를 제공하기 위한 목적으로 브라우저를 식별합니다.
https://virtuslab.com/privacy-policy: Facebook - https://virtuslab.com/privacy-policy
만료: 3개월
이름: _fbp
공급업체: .virtuslab.com
서비스: HubSpot
목적: 사용자와 웹사이트에서의 활동에 관한 정보를 수집합니다. 이 정보는 사용자 행동을 추적·분석하고 타겟 광고를 제공하는 데 사용됩니다.
https://virtuslab.com/privacy-policy: HubSpot - https://virtuslab.com/privacy-policy
만료: 6개월
이름: __hstc
공급업체: .virtuslab.com
서비스: HubSpot
목적: 사용자와 웹사이트에서의 활동에 관한 정보를 수집합니다. 이 정보는 사용자 행동을 추적·분석하고 타겟 광고를 제공하는 데 사용됩니다.
https://virtuslab.com/privacy-policy: HubSpot - https://virtuslab.com/privacy-policy
만료: 6개월
이름: hubspotutk
공급업체: .virtuslab.com
서비스: HubSpot
목적: 사용자와 웹사이트에서의 활동에 관한 정보를 수집합니다. 이 정보는 사용자 행동을 추적·분석하고 타겟 광고를 제공하는 데 사용됩니다.
https://virtuslab.com/privacy-policy: HubSpot - https://virtuslab.com/privacy-policy
만료: 30분
이름: __hssc
공급업체: .virtuslab.com
미분류
현재 미분류 쿠키를 각 쿠키 제공업체와 함께 분류하는 과정에 있습니다.
서비스:
목적:
만료: 3시간
이름: utm_params
공급업체: virtuslab.com
서비스:
목적:
만료: 3개월
이름: _rdt_uuid
공급업체: .virtuslab.com
서비스:
목적:
만료: 1년
이름: _twpid
공급업체: .virtuslab.com
서비스:
목적:
만료: 3개월
이름: _rdt_em
공급업체: .virtuslab.com
선택 쿠키 거부 설정 저장 모두 허용
필수
기능
통계
마케팅
제공: Cookie Information opens in new tab
귀하의 동의는 다음 도메인에 적용됩니다: virtuslab.com 쿠키 정책은 20.03.2026에 마지막으로 업데이트되었습니다
당사의 서비스를 이용하고 정보를 공유해 주실 때 여러분이 보여주시는 신뢰를 소중히 여깁니다. 그래서 저희는 최대한의 주의와 투명성을 바탕으로 여러분의 데이터를 처리하기 위해 최선을 다하고 있습니다.
이 개인정보 처리방침은 저희가 수집하는 정보의 유형, 수집 이유, 그리고 개인 정보를 효과적으로 관리하는 방법을 안내합니다. 목표는 여러분이 사이트를 이용하는 동안 개인정보 보호에 대해 충분히 이해하고 안심할 수 있도록 하는 것입니다.
저희는 이 책임의 중요성을 충분히 인지하고 있으며, 그에 따라 어떤 정보를 수집하는지, 왜 수집하는지, 그리고 데이터를 어떻게 업데이트하고 관리할 수 있는지 명확히 하기 위해 본 개인정보 처리방침을 마련했습니다.
개인정보의 처리자(데이터 컨트롤러)로서 Virtus Lab sp. z o.o.는, 개인 데이터 처리 및 해당 데이터의 자유로운 이동에 관한 유럽의회 및 이사회 규정(일반적으로 GDPR 및 ePrivacy 지침으로 알려짐)을 포함한 현행 법률을 특히 준수하여, 개인정보 처리가 항상 적법하게 이루어지도록 보장합니다.
사용자로서 귀하는 개인정보와 관련해 여러 권리를 가집니다. 언제든지 개인정보에 접근, 정정 또는 삭제를 요청할 수 있습니다. 또한 데이터 처리 제한, 데이터 이동, 그리고 동의 철회(철회 이전에 수행된 처리의 적법성에는 영향을 미치지 않음)를 요청할 권리가 있습니다.
또한 프로파일링을 포함하여 귀하의 개인정보 처리에 이의를 제기할 권리도 있습니다. 이러한 권리를 행사하고자 하거나 데이터 처리 방식에 대해 질문이 있으시면, dpo@virtuslab.com의 데이터 보호 책임자(DPO)에게 직접 연락하시거나 선호하시는 연락 방식으로 문의해 주세요. 저희는 여러분을 돕고, 귀하의 데이터가 최대한의 주의와 존중 속에서 처리되도록 보장하겠습니다.
당사 서비스 사용자에 대한 개인정보 처리자는 폴란드 크라쿠프(31-153) Szlak Street No 49에 소재한 Virtus Lab sp. z o.o.이며, 세금 식별 번호(Tax Identification Number)는 5170312965, 산업 식별 번호(Industry Identification Number)는 180526627입니다.
개인정보 처리의 주된 책임 주체로서 Virtus Lab sp. z o. o.는 Mariusz Zajkiewicz 씨를 데이터 보호 책임자(DPO)로 지정했습니다. Zajkiewicz 씨는 dpo@virtuslab.com 또는 위 주소로의 우편을 통해 연락할 수 있습니다.
Virtus Lab은 Virtus Lab Group 내에서 개인정보 처리를 총괄하는 선도 주체로 활동합니다.
개인정보 처리 목적 및 법적 근거
저희는 커뮤니케이션을 원활히 하고, 문의에 답변하며, 요청에 따라 상호작용하기 위해 개인정보를 처리합니다. 이러한 처리는 당사의 정당한 이익(GDPR 제6조 1항 f호)에 근거하며, 이는 당사에 연락한 개인과의 효과적인 의사소통을 포함합니다. 개인정보 제공은 자발적이지만, 답변을 기대하신다면 필요합니다. 서신 내용은 서비스 정보, 이벤트 조직, 계약 논의, 기술 자문, 금융 거래 등 다양한 주제를 포함할 수 있습니다.
저희는 커뮤니케이션을 원활히 하고, 문의에 답변하며, 요청에 따라 상호작용하기 위해 개인정보를 처리합니다. 이러한 처리는 당사의 정당한 이익(GDPR 제6조 1항 f호)에 근거하며, 이는 당사에 연락한 개인과의 효과적인 의사소통을 포함합니다. 개인정보 제공은 자발적이지만, 답변을 기대하신다면 필요합니다. 서신 내용은 이벤트 조직, 계약 논의, 기술 자문, 금융 거래 등 다양한 주제를 포함할 수 있습니다.
채용을 위해 귀하의 개인정보는 법적 요건을 충족하기 위한 목적(GDPR 제6조 1항 c호, 폴란드 노동법 제22[1]조)과, 귀하의 요청에 따른 계약 체결 전 조치 및 계약상 조치를 관리하기 위한 목적(GDPR 제6조 1항 b호)으로 처리됩니다. 또한 귀하가 동의하는 경우, 향후 채용 기회를 위해 데이터를 처리합니다(GDPR 제6조 1항 a호). 동의는 언제든지 철회할 수 있으며, 철회 이전의 적법한 처리에는 영향을 미치지 않습니다.
저희는 뉴스레터 발송을 위해 귀하의 동의(GDPR 제6조 1항 a호)에 근거하여 개인정보를 처리하며, 직접 마케팅 목적을 위해서는 직접 마케팅을 수행하려는 당사의 정당한 이익(GDPR 제6조 1항 f호)에 근거해 개인정보를 처리합니다. 동의는 언제든지 철회할 수 있으며, 철회 이전의 처리에는 영향을 미치지 않습니다.
저희는 독자가 홈페이지를 어떻게 사용하고 상호작용하는지 이해하기 위해 귀하의 동의(GDPR 제6조 1항 a호)에 근거하여 개인정보를 처리합니다. 목표는 사이트의 사용자 인터페이스를 개선하고, 판매 및 마케팅 관점에서 여러분께 제공하는 콘텐츠를 최적화하는 것입니다. 사이트와의 상호작용 방식을 이해함으로써, 더 나은 경험과 더 관련성 높은 정보를 제공하기 위한 의사결정을 내릴 수 있습니다. 이러한 목적을 위해 분석 도구를 통해 다음과 같은 데이터를 수집합니다: 브라우저 쿠키, virtuslab.com 및 하위 도메인에서의 브라우징 행동, 기기 정보, IP 주소.
저희는 귀하의 요청에 따라 계약을 준비하고 이행하기 위해 개인정보를 처리합니다(GDPR 제6조 1항 b호). 개인정보 제공은 모든 계약에 필수이며, 제공되지 않으면 계약을 진행할 수 없습니다.
저희는 직접 마케팅 수행, 법적 청구 관리, 사기 방지, ICT 환경의 보안 확보 등 다양한 활동을 위해 당사의 정당한 이익(GDPR 제6조 1항 f호)에 근거하여 개인정보를 처리합니다.
저희는 재무 및 세무 규정과 관련된 법적 의무를 이행하기 위해 개인정보를 처리합니다(GDPR 제6조 1항 c호). 데이터 제공은 법적 요구사항입니다.
각 처리 과정은 여러분의 개인정보 보호를 염두에 두고 설계되었으며, 당사 서비스의 소중한 사용자로서 귀하의 권리에 대한 투명성과 존중을 보장합니다.
목적을 더 잘 이해할 수 있도록, 목적을 두 가지 주요 범주로 나누고자 합니다:
마케팅 및 영업
채용
마케팅 및 영업
귀하의 개인정보는 컨설팅 서비스, 감사, 마케팅, IT 지원 등 다양한 기능에서 당사를 지원하는 서비스 제공업체와 공유되며, 이를 통해 가능한 최선의 서비스를 제공할 수 있습니다. 여기에는 Hubspot, Piwik PRO, Dealfront와 같은 서비스가 포함됩니다.
귀하의 개인정보는 재무 거래, 법률 및 컨설팅 서비스, 보관(아카이빙), 택배 및 우편 서비스 등 다양한 기능에서 당사를 지원하는 서비스 제공업체와 공유됩니다.
필요한 경우, Virtus Lab Group 내의 다른 법인이 귀하의 인지 하에 데이터를 처리할 수도 있습니다. 또한 귀하의 동의가 있는 경우, 후보자 데이터의 일부가 채용 목적을 위해 파트너 회사와 공유될 수 있습니다.
법률에 의해 요구되거나, 확정된 법원 판결 또는 관할 기관의 결정에 따른 경우를 제외하고는, 명시적 동의 없이 필요한 범위를 넘어 귀하의 데이터를 제3자와 공유하지 않습니다. 또한 당사 웹사이트의 외부 링크를 방문할 경우, 해당 사이트의 데이터 처리 활동에 대해서는 당사가 책임지지 않는다는 점에 유의해 주세요. 방문 시 해당 사이트의 개인정보 처리방침을 검토하시길 권장합니다.
저희는 채용 과정 등 엄격히 필요한 경우를 제외하고, 유럽경제지역(EEA) 밖이나 국제기구로 개인정보를 이전하지 않습니다. 이전이 발생하는 경우에도, 수신 주체가 GDPR 기준을 준수하는 경우에만 이루어집니다.
Virtus Lab sp. z o. o. (등록 사무소: Cracow (31-153), Szlak Street No 49, Tax Id. No. 5170312965, Industry Id. No.: 180526627.)
VirtusLab Ltd. (사무소: Level 18, 40 Bank Street HQ3 Canary Wharf. London, E14 5NR Registration No: 9793578, Registered in UK, VAT No: GB 223 5272 33.)
VirtusLab GmbH (사무소: Haus 2, 5. Etage Potsdamer Platz 10, 10785 Berlin HRB 209644 B, Tax Id. No. DE326092631.)
Sensinum sp. z o. o. (사무소: Krakow (31-153), Szlak Street no. 49, Tax Id. No. 6772376062, Industry Id. No.: 12289924000000.)
VL Group Services sp. z o. o. (사무소: 31-153 Kraków, Szlak Street No 49, TAX Id: 6762630978, Industry Id. No: 523784169,)
Luminis Research sp. z o. o. (사무소: Cracow (31-153), Szlak Street No 49, Tax Id. No. 5170308981, Industry Id. No.: 18050565400000.)
Softwaremill sp. z o. o. (등록 사무소: 02-791 Warszawa, Na Uboczu Street No. 8/87, Tax Id. No: 7010217058, REGON: 142195210.)
저희는 모든 관련 규정을 준수하면서도 여러분의 프라이버시와 권리를 존중하며, 투명하고 신중하게 개인정보를 처리할 것을 약속드립니다.
구현된 보안 조치: 무단 접근, 변경, 공개, 또는 파기로부터 귀하의 개인정보를 보호하기 위해, 저희는 포괄적인 보안 프로토콜을 적용합니다:
데이터 암호화: 모든 민감 데이터는 저장 및 전송 중 기밀성과 무결성을 보장하기 위해 암호화됩니다.
물리적 보안 조치: 시설에서 시스템에 대한 무단 접근을 방지하기 위해 엄격한 물리적 보안 조치를 시행합니다.
IT 시스템 검증: 보안 표준을 유지하기 위해 IT 시스템 내에서 정기적인 점검과 검증을 수행합니다.
백신 소프트웨어 및 방화벽: 악성코드 및 무단 접근 시도를 방지하기 위해 고급 백신 소프트웨어와 방화벽을 사용합니다.
접근 통제: 개인정보에 대한 접근은 비밀유지 계약에 의해 구속되는 인가된 인원으로 엄격히 제한됩니다. 또한 하도급업체(서브프로세서)는 유사한 데이터 보호 기준을 강제하는 재처리 계약에 서명해야 합니다.
개인정보는 공동 처리자 중 어느 곳과든 협력 관계가 유지되는 동안 처리됩니다.
이메일 서신: 이메일 상호작용과 관련된 데이터는 문의에 답변하는 데 필요한 기간 동안 또는 추가 처리를 반대할 때까지 처리됩니다. 논의가 이어질 가능성을 위해 데이터를 보관할 수 있으며, 관련성은 최소 연 1회 확인합니다.
채용 절차: 후보자 데이터는 채용 절차 기간 동안(최대 45일) 처리되며, 추가 고용 관련 보수 산정 목적을 위해 최대 24개월간 처리될 수 있습니다. 잠재적 청구를 위해 최대 36개월까지 보관될 수 있습니다. 향후 채용 절차를 위해서는 동의가 철회될 때까지(단, 36개월을 초과하지 않음) 보관됩니다.
뉴스레터 발송: 뉴스레터 사용자 데이터는 동의를 철회하거나 유효한 이의를 제기할 때까지 처리됩니다.
웹사이트 데이터: 웹사이트 상호작용과 관련된 데이터는 14개월 동안 처리된 후 삭제됩니다. 이 데이터의 단독 처리자는 Szlak Street No 49, Cracow (31-153)에 등록 사무소를 둔 Virtus Lab sp. z o. o.(Tax Id. No. 5170312965, Industry Id. No.: 180526627)입니다.
계약 관계: 계약 관계가 지속되는 동안 개인정보는 계약 기간 전반에 걸쳐 처리됩니다. 계약이 체결되지 않는 경우, 어느 한쪽이 계약을 진행하지 않기로 선택할 때까지 데이터가 보관됩니다.
재무 거래: 재무 거래 관련 데이터는 거래가 발생한 달력이 끝난 시점으로부터 5년간 보관됩니다.
처리 후 기간: 위 기간이 만료된 후에도, 잠재적 법적 청구를 해결하기 위해 필요하거나 관련 법률이 허용하는 경우 개인정보가 계속 처리될 수 있습니다. 더 이상 데이터가 필요 없고 다른 처리 근거가 존재하지 않는 경우, 개인정보는 영구 삭제 또는 익명화되어 프라이버시가 효과적으로 보호됩니다.
이러한 관행은 귀하의 권리와 당사의 법적 의무를 모두 존중하면서, 책임감 있고 안전하게 데이터를 처리하기 위해 마련되었습니다.
개인정보가 법적 규정을 위반하여 처리되었다고 판단하는 사용자는 개인정보 보호청(Personal Data Protection Office) 청장에게 불만을 제기할 권리가 있습니다. 이는 데이터 프라이버시 및 보호에 대한 최고 수준의 기준을 유지하려는 당사의 약속의 일부입니다.
본 정책(개정 포함)은 웹사이트에 게시되는 즉시 효력이 발생합니다. 사용자는 데이터 보호 및 이용 방식에 대한 정보를 최신 상태로 유지하기 위해 정기적으로 정책을 검토하시길 권장합니다.
쿠키 소개: 쿠키는 방문한 웹사이트가 귀하의 기기(컴퓨터, 스마트폰 등)로 전송하여 저장하는 작은 텍스트 파일입니다. 쿠키는 이후 방문 시마다 원래 웹사이트로 다시 전송되거나, 해당 쿠키를 인식하는 다른 웹사이트로 전송됩니다. 쿠키는 웹사이트가 사용자의 기기를 인식하고, 사용자 선호나 과거 행동에 대한 일부 정보를 저장할 수 있게 해주기 때문에 유용합니다.
세션 쿠키: 사이트를 떠날 때까지 브라우저의 쿠키 파일에 남아 있는 임시 쿠키입니다. 특정 사이트 기능에 필수적입니다.
영구 쿠키: 정해진 기간 동안 브라우저의 쿠키 파일에 남아 있습니다. 올바른 탐색 및 기능 보장, 그리고 사이트 레이아웃 개인화에 사용됩니다.
분석 쿠키: 사이트 사용에 관한 데이터를 수집합니다. 이 데이터는 웹사이트 기능 개선에 도움이 되며, 익명으로 수집됩니다. 분석은 데이터 친화적인 분석 제품군인 Piwik PRO 같은 서비스에 의해 제공됩니다.
광고 쿠키: 브라우징 습관을 추적하며, Facebook Pixel, Google Ads, LinkedIn Ads, Twitter Ads 같은 서비스가 사용자의 관심사와 관련된 타겟 광고를 제공하는 데 사용합니다.
기본 설정: 기본적으로 브라우저는 일반적으로 쿠키를 허용합니다. 그러나 브라우저 설정을 조정하여 쿠키를 차단하거나, 쿠키 저장 전에 알림을 받거나, 기타 선호 설정을 할 수 있습니다. 쿠키를 차단하면 사용자 경험에 영향을 줄 수 있으며, 사이트 일부가 올바르게 동작하지 않을 수 있습니다. 조정 방법: 쿠키 설정 관리에 관한 자세한 안내는 브라우저의 도움말 섹션 또는 고객 지원 채널에서 확인할 수 있습니다.
설정 모두 허용
제공: Cookie Information opens in new tab
산업 섹터
* [리테일](https://virtuslab.com/sectors/retail-industry/)
* [Industry 4.0](https://virtuslab.com/sectors/industry-4-0/)
* [Smart Factory](https://virtuslab.com/solutions/smart-factory-solutions/)
* [INSURANCE](https://virtuslab.com/sectors/insurance/)
* [물류](https://virtuslab.com/sectors/logistics-industry/)
* [AI 기반 공급망](https://virtuslab.com/solutions/ai-driven-supply-chain-automation/)
* [FinTech](https://softwaremill.com/services/fintech-software-development/)
주요 추천 글
* [ 데이터 기반 의사결정을 위한 분석 데이터 플랫폼의 힘을 열어보세요](https://virtuslab.com/blog/data/analytical-data-platforms-data-driven-decisions)
* [ developer experience(DX)란 무엇이며, 프로젝트가 좋은 DX를 제공하는지 어떻게 판단할까?](https://virtuslab.com/blog/backend/what-is-developer-experience)
리소스
* [기사](https://virtuslab.com/blog/)
* [비즈니스 인사이트](https://virtuslab.com/blog/business-insights/)
* [Scala](https://virtuslab.com/blog/scala/)
* [데이터 엔지니어링](https://virtuslab.com/blog/data/)
* [클라우드 엔지니어링](https://virtuslab.com/blog/cloud/)
* [백엔드 엔지니어링](https://virtuslab.com/blog/backend/)
* [프론트엔드 엔지니어링](https://virtuslab.com/blog/frontend/)
* [Agent Visualization](https://virtuslab.com/agent-visualization/)
* [성공 사례](https://virtuslab.com/success-stories/)
* [리테일](https://virtuslab.com/success-stories/industry/retail/)
* [Industry 4.0](https://virtuslab.com/success-stories/industry/industry-4-0/)
* [Insurance & fintech](https://virtuslab.com/success-stories/industry/insurance-fintech/)
* [물류](https://virtuslab.com/success-stories/industry/logistics/)
* [미디어](https://virtuslab.com/success-stories/industry/media-publishing/)
* [여행 및 호스피탈리티](https://virtuslab.com/success-stories/industry/hospitality/)
* [헬스케어](https://virtuslab.com/success-stories/industry/healthcare/)
주요 추천 글
* [ Azure의 Kubernetes로 레퍼런스 아키텍처를 만드는 방법: 광범위한 가이드](https://virtuslab.com/blog/cloud/reference-architecture-kubernetes-on-azure-guide)
* [ 회사 정보를 위한 LLM 챗봇을 만드는 방법](https://virtuslab.com/blog/ai/how-to-build-llm-chatbot)
This Is VirtusLab * 회사 소개: 우리의 미션은 소프트웨어 기술의 긍정적 진화를 지속적으로 이끄는 것입니다. * COMMUNITY: 커뮤니티는 우리의 효과성에 필수입니다. 우리는 기술 이벤트를 조직하고 후원합니다. * CAREERS: 커리어를 한 단계 더 발전시키세요. 우리 팀의 일원이 되어 유연성과 뛰어난 솔루션을 선택하세요. * Virtuslab Group: 혁신에 전념하며, 고객·파트너·팀 멤버와의 관계를 강화하고 가치를 더합니다. * COMPANY NEWS: 오픈소스 기여와 이벤트가 이 활기찬 커뮤니티를 더욱 풍성하게 만듭니다.

Adam Warski
SoftwareMill Chief R&D Officer
게시: 2026년 3월 19일 | 읽는 데 15분 15 minutes read

Scala는 현존하는 최고의 언어이지만, 비즈니스 애플리케이션 개발에서 (아직은?) 가장 보편적인 언어는 아닙니다. 하지만 우리는 그걸 바꾸려는 미션을 갖고 있습니다! 물론 시작은 모두가 지금 하고 있는 것부터죠. 바로 Claude Code나 다른 LLM을 활용해 애플리케이션을 생성하는 것입니다.
AI는 TypeScript, Java, Python 같은 가장 인기 있는 애플리케이션 스택을 강하게 이해하고 있습니다. 그렇다면 Scala 3 애플리케이션을 작성하라는 과제를 받았을 때 AI 에이전트는 얼마나 잘 해낼까요? 그리고 더 어렵게, Scala 내부에서도 널리 퍼진 접근은 아닌 direct style을 요청한다면 어떨까요?
LLM이 직접 스타일 Scala 3 애플리케이션을 작성하려면 어떤 가이드가 (필요하다면) 필요할까요? 함께 살펴보겠습니다!
Claude Code(제가 현재 선택한 LLM)가 직접 스타일 Scala 3 애플리케이션 작성 과제를 어떻게 다루는지 보기 위해, 다음을 수행하는 애플리케이션을 (여러 번) 생성해 보았습니다. HTTP API를 통해 SOAP 메시지를 받아, 들어오는 데이터를 Kafka에 저장하고, Kafka에서 S3로 데이터를 옮기는 백그라운드 프로세스를 실행하되, 데이터를 시간 단위 파일로 묶어서 업로드하는 애플리케이션입니다.
기술 스택은 다음과 같습니다:
수행해야 할 작업의 범위가 꽤 다양해서, LLM의 벤치마크로 좋다고 생각했습니다:
첫 시도에서는 Claude와 대화하면서 기능을 하나씩 진행하는 방식으로 인터랙티브하게 애플리케이션을 작성했습니다. 코드는 자동 및 수동으로 리뷰했고, “좋은 직접 스타일 Scala”(혹은 최소한 제가 생각하는 좋은 스타일)을 위해 무엇을 개선할 수 있는지도 짚었습니다.
이 세션 동안 CLAUDE.md는 비어 있었고, Claude가 어디에서 막히고 어떤 부분에서 가장 많은 수정이 필요했는지 메모했습니다. 전반적으로 Claude는 Scala 3이나 직접 스타일 Scala를 사용하는 데 큰 문제가 없었습니다. 대부분은 “그냥 동작”했습니다. 그래서 Scala를 어느 정도 알고 있고, 워크플로가 자율적이라기보다 인터랙티브한 편이라면, 여기서 멈춰도 충분합니다.
궁금하시다면, 제가 도움을 주며 Claude가 작성한 코드는 여기에 있습니다. 저는 구현 전에 기능을 조사하고 명세하기 위해 OpenSpec을 사용했습니다.
이 실험의 결과는 상당히 만족스러웠지만, Claude가 자율적으로도 잘 설계된 Scala 3 직접 스타일 애플리케이션을 생성할 수 있을까요? 그러려면 몇 가지 가이드가 필요합니다.
가장 먼저 눈에 띈 것은 Claude가 모든 것을 bash와 sbt로 하려 한다는 점입니다. 컴파일, 테스트 실행은 물론 의존성 확인까지(jar를 풀고 클래스를 디컴파일하는 식으로...) 말이죠.
sbt는 속도 챔피언이 아니므로, 첫 번째 조언은 항상 sbt --client를 사용하라는 것이었습니다. 이는 백그라운드 sbt 서버를 시작한 다음 거기에 연결하기 때문에, 이후 sbt 명령이 훨씬 빨라집니다. 다만 LLM이 애플리케이션을 실행하려고 하면 sbt를 직접 써야 하는데, 그렇지 않으면 애플리케이션이 오동작할 때 쉽게 중단하거나 종료할 수 없기 때문입니다. 이로부터 일반적인 Scala용 CLAUDE.md의 첫 부분이 나옵니다:
Copy
* use `sbt --client` instead of `sbt` to connect to a running sbt
server for faster execution
* to verify that the app starts use `sbt run`, WITHOUT
`--client`, as it prevents interrupting the process
* before committing, ALWAYS format all changed Scala files using
the sbt `scalafmt` plugin: `sbt --client scalafmtAll`
둘째로, 저는 VS Code + Metals로 작업하고 있는데, Metals MCP가 설치되어 사용 가능함에도 불구하고 위 일이 벌어졌습니다. 분명히 훨씬 더 잘할 수 있습니다!
Metals MCP는 Claude가 bash를 통해 sbt를 사용하던 케이스의 90%를 커버하는 도구를 제공합니다. 그런데 LLM 신들만이 아는 이유로, MCP가 활성화되어 있어도 보통은 사용되지 않습니다. 하지만 CLAUDE.md에 추가 지시사항을 넣으면 엄청나게 달라집니다:
Copy
* ALWAYS use tools to compile and run tests instead of relying on
bash commands
* after adding a dependency to `build.sbt`, ALWAYS run the
`import-build` tool
* to lookup a dependency or the latest version, use the
`find-dep` tool
* to lookup the API of a class, use the `inspect` tool

이 간단한 지시사항만으로도 Claude는 거의 항상 Metals MCP를 사용하게 되며, 보는 사람 입장에서도 즐겁습니다. 답이 거의 즉시 돌아오고, 심볼을 합리적인 방식으로 인스펙트하며, 사고 과정의 상당 부분이 test, compile, import-build, inspect 등의 도구와의 상호작용으로 구성됩니다.

전반적으로 Claude는 Scala 3를 꽤 잘 알고 있습니다. 새로운 타입, 새로운 문법 등을 문제 없이 사용합니다. 여기서 제가 추가로 준 조언은 중괄호 없는 문법을 사용하라는 것뿐이었습니다. 이는 Scala 3에서 강제되는 사항이라기보다 프로젝트별 선호에 가깝습니다:
Copy
* avoid using {} and use braceless syntax
Scala 프로젝트를 작성하라고 하면, Claude의 기본값은 cats-effect를 사용하는 것입니다. 하지만 제 목표는 직접 스타일이었고, 이는 기술 스택에 명확히 표시되어 있었습니다. 이 요구사항이 들어가면 Claude는 대체로 올바른 코드를 생성했지만, 반복해서 나타나는 문제들이 있었습니다.
대부분은 Claude가 Tapir와 Ox를 알고는 있지만 지식이 아주 깊지는 않고, 오래된 버전에 기반한 경우가 많다는 점에서 비롯됩니다. 그래서 최신의 직접 스타일에 맞춘 API를 알려줄 필요가 있습니다:
Copy
# Direct-style Scala
* in Tapir, use the `.handle...` methods instead of
`.serverLogic...` ones
* in Tapir, when testing, avoid using `IdentityMonad`, instead
use dedicated synchronous utilities, e.g.,
`BackendStub.synchronous`
* using `OxApp` to implement proper resource management on
shutdown
* only propagate concurrency scope (`using Ox`) when absolutely
needed. Prefer creating nested, local, structured concurrency
scopes instead.
* use Ox's `Channel`s to communicate between threads instead and
to avoid shared mutable state
전체 애플리케이션을 자율적으로 생성하려면, 기준선 실험에서 얻은 교훈만으로는 부족합니다.
저는 OpenSpec이 저장소에 작성해 둔(상당히 자세한) 명세를 모두 갖고 있었기 때문에, Claude에게 같은 애플리케이션을 처음부터 다시 생성하는 데 사용할 수 있는 프롬프트를 만들어 달라고 요청했습니다.
그리고 Claude가 처음에는 포함시켰던 모든 기술적 세부사항을 제거한 뒤(향후 에이전트들이 개발 중에 더 자유롭게 선택할 수 있도록 그렇게 요청했습니다), 결과는 이것이었습니다.
위에서 설명한 CLAUDE.md 파일과 프롬프트를 갖춘 상태에서, Claude를 완전히 자율적이면서도 위험하게(질문을 하지 않도록) 실행할 수 있도록 Sandcat 컨테이너를 띄웠습니다. 또한 개발 프로세스에 대한 간단한 설명도 추가했습니다(자세한 내용은 뒤에서). 결과는... 나쁘지 않았습니다.
애플리케이션은 동작했고 필요한 구성 요소도 모두 있었지만, 가장 큰 약점은 변경 가능한 자료구조, return, var 등의 사용이 광범위했다는 점입니다. 전반적으로 코드가 꽤 명령형이었습니다.
Claude를 더 “함수형” 프로그래머로 만들기 위해 몇 차례 실험을 했습니다. 100% 성공했다고 말할 수는 없지만, 아래 내용을 추가하면 초기보다 훨씬 좋아집니다. 참고로 이는 전체 앱을 자율적으로 생성하는 상황에서의 이야기입니다:
Copy
# Scala projects
* NEVER use non-local returns
* ALWAYS use functional programming: immutable data types,
pattern matching, immutable collections, higher-order
functions, algebraic data types
* instead of mutable state, ALWAYS prefer writing testable, pure
functions that accept and return a state data type. Use mutable
state only locally at the top-level
# Coding style
* take care of good naming; responsibilities in code should be
segregated between appropriately named entities
* when dealing with resources, properly track who owns which
resources, and ensure proper ordering on cleanup
* when possible, restrict visibility of classes and top-level
constructs to appropriate sub-packages. No need to restrict
visibility to the main package.
* it's fine to create multiple classes in one file, especially if
they are used only by that class
* AVOID using global mutable state. Instead, use an immutable
state that is passed & returned from functions. Local mutable
state, such as mutable variables, tightly scoped to a method,
is fine
* AVOID shared mutable state at any cost
* AVOID using mutable collections
* comment on any aspects that aren't obvious from the
implementation, but are important to know when reading the code
가변성을 피하는 것 외에도, 가시성 및 네이밍에 관한 가이드가 포함되어 있는데, 이런 부분도 종종 개선이 필요합니다.
그럼에도 Claude가 제 가이드를 받으며 반복적으로 개발한 기준선 버전이 “함수형” 측면에서는 여전히 훨씬 더 깔끔했습니다. 이는 특히 Kafka -> S3 뷰 생성기(데이터를 시간 단위 파일로 버킷팅하는 부분)에서 두드러졌습니다.
자율 실행 시 Claude는 일관되게 변경 가능한 Builder 류의 클래스를 만들며, 그 내부에서 변경 가능한 컬렉션이나 클래스의 var 필드를 사용합니다. 반면 협업 방식의 기준선에서는, 주요 비즈니스 로직이 전달받고 반환하는 불변 State 류 클래스를 만들었고, 메서드 로컬의 변경 가능한 변수에만 저장했습니다. 이런 설계는 오용하기가 더 어렵습니다. 가변성이 더 로컬에 머물고, 동시성 문제를 일으킬 방법 자체가 없기 때문입니다. 하지만 자율 생성에서 이런 설계를 재현하는 것은 쉽지 않았습니다.
프롬프트와 CLAUDE.md 모두에서 다양한 문구를 시도했지만, 아직 완전한 자율 성공에는 이르지 못했습니다. 이것은 개선 및 향후 연구의 여지가 있는 지점입니다.
프롬프트는 개발 프로세스에 대한 설명 없이는 완성되지 않습니다. 즉, 명세만 주어진 상태에서 작지만 결코 단순하지 않은 애플리케이션을 처음부터 어떻게 작성할 것인가에 대한 접근이 필요합니다. 여기의 지시사항은 먼저 plan.md 파일을 생성하고, 각 요구사항을 태스크로 쪼개는 것을 포함합니다. 그리고 각 태스크를 반복적으로 구현해 나가는 방식인데, 특별히 혁신적이거나 대단한 것은 아닙니다.
하지만 제가 코드 품질(그리고 종종 정확성)을 높이는 데 가장 도움이 된다고 느낀 한 가지는 코드 리뷰였습니다. 제가 하는 리뷰가 아니라, Claude 스스로 하는 리뷰였습니다. 저는 여러 리뷰 에이전트를 자주 사용하고 있는데(타깃 기능 커버리지 및 정확성, 성능, 코드 가독성, 테스트 최소주의, 추상화/DRY 등을 커버), 각 태스크 후에 Claude에게 그 에이전트들을 사용해 코드를 리뷰하게 하면 토큰이 조금 더 들긴 해도 많은 문제를 찾아 고칠 수 있었습니다.
다만, Claude가 매 태스크마다 자기 일을 리뷰하도록 강제하는 것은 어렵다는 것을 알게 됐습니다. ALWAYS나 MUST를 대문자로 쓰거나, 공손하게 말하거나, 덜 공손하게 말하거나, 리뷰 요구를 반복하는 등 여러 시도를 했지만, 에이전트는 첫 번째 또는 두 번째 태스크 이후에 “편리하게” 리뷰를 잊어버리곤 했습니다. 혹은 리뷰를 한 번만 수행하고 재리뷰 요구를 건너뛰기도 했습니다. 따라서 이것 또한 개선 여지가 있는 영역입니다.
결국 더 잘 동작한 것은, 단일 태스크가 아니라 태스크 그룹(즉, 전체 기능 단위)에 대해 리뷰를 요청하는 방식이었습니다. 전체적으로, 프롬프트에서 개발 프로세스를 설명하는 부분은 다음과 같습니다(완전성을 위해 포함하며, 이 부분은 직접 스타일 Scala 앱 작성과 엄밀히 관련된 것은 아닙니다):
Copy
# Development process
## Write a plan
First write a step-by-step implementation plan. Store the plan in
a `plan.md` file. Do not include any code in the plan.
* The plan should consist of multiple tasks
* Tasks should be designed to be implemented individually, one by
one
* Tasks should be grouped by feature / technical concern, so that
when all tasks from a group are implemented, the feature is
complete
* Each task should handle a single concern and gradually move the
system toward the goal
* Make sure there are no additional features planned
## Implement
Execute the implementation plan step by step
* Iterate on the implementation of consecutive tasks. The code
MUST compile without warnings, and the tests MUST pass
* Unit tests should be focused, non-overlapping, each covering a
single well-defined scenario
* After completig all tasks from a task group, ALWAYS perform a
code review, taking into account the coding guidelines. You
MUST run a code review before proceeding to the next task
group.
* ALWAYS apply code review remarks, and then repeat the review
process. If there were no remarks, proceed to the next task
group.
* All developed features should be integrated with the rest of
the system, so that there's no dead or unreachable code.
Anything that's developed must be somehow reachable from the
main entrypoint.
* Commit the result and proceed to the next task in the
implementation plan
* Mark the task as done in the plan file
Work on the implementation autonomously. Do not ask any
questions, resolve any issues on your own.
자율적으로 생성된 직접 스타일 Scala 앱은 좋았지만, Bootzooka 템플릿에 들어있는 것은 더 좋았습니다. 관측 가능성(observability)과 가상 스레드, 그리고 직접 스타일에 특화된 Scala 패턴이나 최신 Tapir/Ox API 주변에 약간의 요령들이 있는데, Claude는 이를 단순히 모르고 있었습니다. 어떻게 해결할 수 있을까요?
가능한 방법 중 하나는 Bootzooka 템플릿을 그대로 가져와 커스터마이즈하는 것입니다. 하지만 저는 다른 길을 택했습니다.
먼저, Tapir 문서와 Ox 문서의 목차를 링크 -> 챕터 설명 쌍 형태로 압축해 단일 파일로 만들었습니다. 하지만 이를 프롬프트에 추가해도 큰 차이는 없었습니다.
두 번째 시도는 달랐습니다. 저는 Claude에게 Bootzooka 코드베이스를 살펴보고, 유스케이스 기반의 "direct-style book"을 생성해 달라고 요청했습니다. 유스케이스는 제가 직접 골랐지만, 텍스트는 전적으로 AI가 생성했습니다. 초기에는 Claude가 너무 장황했고 몇 군데에서는 환각도 있었기 때문에 약간의 다듬기가 필요했습니다.
핵심 아이디어는 프롬프트의 일부로 LLM이 다음 내용을 받도록 하는 것입니다:
Copy
When implementing Scala 3 direct-style applications using Tapir,
Ox, or sttp, consult the guide at:
https://raw.githubusercontent.com/VirtusLab/direct-style-guide/refs/heads/master/index.md
The index lists self-contained chapters by use-case (error
handling, authentication, testing, observability, persistence,
configuration, etc.). Fetch the chapter relevant to your current
task for implementation patterns and code examples.
Base URL for chapters:
https://raw.githubusercontent.com/VirtusLab/direct-style-guide/refs/heads/master/
index.md에는 각 챕터에 대한 참조 목록과 함께, 각 챕터가 실제로 커버하는 유스케이스가 무엇인지에 대한 설명이 들어 있습니다. 이를 통해 LLM은 현재 문제에 해당하는 유스케이스를 선택하고, 해당 내용만 선택적으로 컨텍스트에 로드할 수 있습니다.
그리고 결과는 훨씬 좋아졌습니다! 생성된 애플리케이션은 JVM 메트릭, 가상 스레드 컨텍스트 전파, 로깅 통합을 포함해 OpenTelemetry 관측 가능성을 올바르게 통합합니다. Claude는 더 이상 TapirSyncStubInterpreter로 엔드포인트 테스트에 대한 광범위한 리서치를 수행하지 않고, sttp의 endpoint-as-request 인터프리터를 추가로 활용하는 템플릿 솔루션을 갖게 됩니다.
물론 direct-style-guide를 유지하는 것은 추가 작업입니다. Bootzooka, Tapir, Ox, sttp의 변경과 동기화되어야 하기 때문입니다. 하지만 에이전트를 사용해 자동화할 수 있을 것입니다. 물론, 다른 사람들도 이 아이디어가 유용하다고 느껴야겠죠(아직이라면, 저희 OSS 저장소에 ⭐도 부탁드립니다! :) ).
정리하자면: Claude는 기술 스택과 선택한 패러다임만으로도 올바른 직접 스타일 Scala 3 애플리케이션을 생성합니다. 하지만 몇몇 영역에서는 가이드가 유용합니다.
CLAUDE.md의 일부로, 다음 지시사항을 포함하세요:
그 다음 Claude는 다음을 포함하는 프롬프트가 주어지면, 우아한 직접 스타일 앱을 생성합니다:
마지막으로, 개발을 간소화하고(Claude가 리서치하는 시간을 절약) 직접 스타일 애플리케이션의 덜 명백한 측면들을 제대로 구현하려면, Bootzooka 템플릿에 이미 구현된 내용을 따르도록 Claude에게 요청하는 접근이 매우 유용합니다. 직접 따라 하게 하는 것이 아니라, 프롬프트에 AI를 위한 AI 생성 책 링크를 포함하는 방식으로 말이죠: direct-style-guide.
그렇다면 여러분은 Scala로 무엇을 생성하고 계신가요?
이 글의 목차
관련 글
글 태그
### Scala Long-Term Support retrospective
### Bringing Scala to Server-Side Wasm with WASI & Component Model
### The Most Common Scala Myths Debunked
©2026 VirtusLab