반응형
SMALL

2026/06 31

AI 에이전트가 빌드까지 하는 시대, 6년차의 하루 워크플로를 다시 짰습니다

어제 새벽 3시, 클로드 코드(Claude Code)가 lint와 테스트까지 마친 PR 일곱 개를 머지하고 있었어요. 저는 자고 있었고요. 아침에 출근해서 그 PR들을 훑어보다 손이 잠깐 멈췄습니다. "이걸 내가 짠 게 맞나"가 아니라, "앞으로 내가 뭘 해야 돈을 받지"가 떠올랐거든요. 6년차의 익숙한 루틴이 그때부터 흔들리기 시작했어요. 클로드 코드·데빈이 PR까지 만드는 현장상반기에 데빈(Devin)이 인프라 배포 단계까지 자율로 처리하는 걸 옆에서 보고, 그 다음 주에 클로드 코드를 야간 큐(Claude Code Routines)에 붙여본 게 결정타였어요. 계획부터 구현, 테스트, 디버그, PR 생성까지 사람 개입을 최소화한 채로 굴러가더군요. 수치만 보면 한동안 과장이라고 생각했습니다. 개발자의..

KMP 새 기본 프로젝트 구조로 옮겨보니 모듈 책임이 또렷해졌습니다

얼마 전에 사이드 프로젝트를 AGP 9.0으로 올렸다가 빌드가 통째로 깨졌습니다. 원인을 파봤더니 composeApp 한 모듈에 앱 플러그인이랑 KMP 플러그인이 같이 박혀 있던 게 문제였더라고요. AGP 9.0에서 composeApp 단일 모듈이 깨지는 이유기존 코틀린 멀티플랫폼(Kotlin Multiplatform, KMP) 마법사가 만들어주는 composeApp 모듈은 사실 처음 봤을 때부터 좀 이상했어요. 한 모듈 안에 com.android.application 플러그인이 박혀 있는데, 동시에 kotlin("multiplatform") 도 적용돼서 iOS·데스크톱 타깃이 같이 굴러갑니다. "이게 앱이야 라이브러리야?" 가 처음 입문자 입장에서 헷갈리는 자리였습니다. AGP 9.0 부터는 KMP 플..

Compose Composition tracing으로 Layout Inspector가 놓친 스크롤 잰크 잡기

Recomposition Count가 0이라고 잰크가 없는 게 아닙니다. 오히려 Layout Inspector가 0을 찍는 그 순간, 진짜 비용은 measure 와 layout 단계로 옮겨가 있는 경우가 많거든요. 지난 4월에 사이드 프로젝트 상품 리스트 화면을 손보다가 정확히 이 함정에 빠졌습니다. 스크롤할 때 한 박자가 묘하게 끊기는데, Android Studio Layout Inspector 의 Recomposition Count 는 거의 0이었어요. "그럼 도대체 뭐가 문제지" 하면서 한참 헤맸는데, 결국 범인을 찾아준 건 Composition tracing 이었습니다. 그 과정을 정리해뒀어요. Layout Inspector Recomposition Count 가 0이어도 잰크가 생기는 이유Lay..

Kotlin 2.4 field 키워드로 ViewModel _state/state 보일러플레이트 한 줄로 줄이기

얼마 전에 후배가 _state 가 왜 붙어있냐고 묻길래 한참 설명했거든요. 끝나고 코틀린(Kotlin) 2.4 릴리스 노트를 보니, 그 설명이 통째로 필요 없어지는 문법이 들어와 있었습니다. 기존 _state / state 패턴, 두 줄이 거슬렸던 이유ViewModel 한 번 까보면 이런 두 줄이 화면 절반을 채우는 경우가 많아요. private val _state = MutableStateFlow(UiState.Idle)val state: StateFlow = _state.asStateFlow() 프로퍼티가 하나면 모르겠는데, query·result·loading·error 같이 네다섯 개 깔리면 ViewModel 윗단이 선언부로만 20줄 가까이 됩니다. 정작 비즈니스 로직은 그 밑에서 시작하지요. _..

@PreviewWrapper 하나로 디자인 시스템 프리뷰 일관성 잡기

프리뷰에서는 멀쩡한데, 앱 빌드해서 띄우면 색이랑 폰트가 다르게 보인 적 있으신가요? 매번 MyTheme { Surface { ... } } 감싸다가 하나 빠뜨려서 그런 거거든요. 저도 작년에 디자인 시스템 모듈 정리하면서 안드로이드 스튜디오(Android Studio) 프리뷰 패널만 100개 가까이 깔아두고 작업했었는데요. 그중 한 다섯 개 정도는 꼭 테마 래퍼를 빼먹고 머터리얼 기본값으로 찍힌 상태로 PR 올라가곤 했어요. 4월에 Compose 1.11.0 에 들어온 @PreviewWrapper 가 정확히 이 지점에 들어맞아서, 지난 한 달 굴려본 정리를 옮겨둡니다. Compose 프리뷰가 디자인 시스템이랑 다르게 렌더링되는 이유원인은 크게 세 갈래입니다. 첫 번째는 CompositionLocal 의..

클로드 코드 서브에이전트로 안드 멀티모듈 리팩터링 반나절 컷 낸 후기

멀티에이전트의 핵심은 '병렬 처리'가 아니었습니다. 정작 시간을 줄여준 건 '컨텍스트 격리'였거든요. 빌드는 어차피 직렬로 쌓이니까요. 지난달에 회사 안드로이드 프로젝트의 Convention Plugin 마이그레이션을 하루 안에 끝내야 하는 상황이 생겼어요. 모듈이 30개 정도 있는데 compileSdk, Hilt(힐트), Detekt(디텍트) 설정이 모듈마다 따로 박혀 있어서, build-logic 으로 한 번에 묶어야 했습니다. 평소라면 사흘은 잡았을 작업인데, 이번엔 클로드 코드(Claude Code) 서브에이전트를 처음으로 본격 투입해봤네요. 단일 클로드 코드 세션으로 30개 모듈 굴리면 한계가 옵니다이전까지는 그냥 단일 클로드 코드 세션으로 모듈을 하나씩 돌려가며 작업했어요. 근데 6년차로 굴려..

공유 UI 말고 공유 코어부터, KMP 도입 한 주 일지

공유 UI는 안 만들었습니다. 그런데도 KMP 도입은 남는 장사였어요. 코어만 떼어내도 테스트 속도가 7배 빨라지는 일이 벌어지거든요. iOS 앱은 아직 계획도 없어요. 그런데도 안드로이드 사이드 프로젝트 하나에 코틀린 멀티플랫폼(Kotlin Multiplatform)을 한 주 동안 발라봤습니다. 네트워킹과 도메인 모델만 commonMain 으로 떼어내는, 딱 거기까지요. 넷플릭스가 KMP 도입으로 기능 개발 시간을 40% 줄였다거나, 에어비앤비가 95% 코드 공유까지 갔다는 얘기가 자주 인용됩니다. 그게 전부 공유 UI 까지 간 사례는 아니라고 해요. 비즈니스 로직만 공유해도 충분히 의미가 있다는 입장이 업계에서 더 흔하게 보이는 편입니다. 2026년 KMP 시작, 공유 코어부터가 정석인 이유2026년..

LazyColumn 41번 재구성, Quail Layout Inspector로 진범 잡은 일주일

지난주 화요일 새벽 두 시, LazyColumn 한 칸이 41번 재구성된 화면을 보면서 멍하니 앉아있었습니다. Skip 카운트는 0이었어요. Compose 1.7부터 Strong Skipping Mode가 기본으로 켜져있다는 얘기를 워낙 많이 들어서, 재구성은 거의 없을 거라고 무방비 상태였습니다. 막상 Layout Inspector를 띄워보니 카드 하나가 스크롤 한 번에 41번씩 그려지고 있더라고요. Janky frame 비율은 14%, 평균 프레임 타임은 28ms. 스크롤이 끊기는 게 손끝에 느껴질 정도였습니다. 스크롤 60fps가 깨진 자리에서 처음 의심한 세 가지문제 화면은 홈 피드의 진행률 카드 리스트였습니다. 스크롤하면서 빠르게 위아래로 흔들면 프레임 타임이 38~52ms로 튀어 올랐어요. 6..

Compose UI 테스트 느린 자리, runWithoutImplicitWait로 5초 잡은 일지

같은 테스트 코드인데 6.2초가 0.4초로 줄어들었습니다. 화면 50개 중 8개에서만 새던 5초 지연을, 최근 androidx.compose.ui-test 라인에 새로 들어온 API 하나로 막은 일지예요. 지난주에 사내 슬랙으로 CI 알림이 또 빨갛게 떠서 로그를 까봤는데, 평소 8분 안에 끝나던 UI 테스트 묶음이 14분을 찍었습니다. 새로 추가된 테스트는 4개뿐이었는데 말이지요. 범인을 잡으려 시간 프로파일링을 돌려보니 특정 화면 8개에서만 어셔션 한 번에 5초씩 새고 있더라고요. runWithoutImplicitWait, 상태 검사용으로 새로 깔린 APIandroidx.compose.ui-test 의 ComposeTestRule 과 ComposeUiTest 에 새로 깔린 람다 블록입니다. 릴리즈 노..

Kotlin 2.4 UUID 안정화로 안드 데이터 클래스에서 라이브러리 두 개 지운 후기

어제 저녁 build.gradle.kts 열어두고 의존성 두 줄을 지웠습니다. com.benasher44:uuid, 그리고 정렬용으로 붙여놨던 ulid-kotlin. RC2 시절부터 만져보던 코틀린(Kotlin) 2.4를 지난주 풀린 2.4.0 정식판으로 올렸을 뿐인데 모듈이 가벼워지더라고요. KMP 공통 모듈에서 ID 타입을 고민하시던 분이라면 이번 릴리즈가 꽤 반가울 거예요. @OptIn(ExperimentalUuidApi::class) 어노테이션을 클래스마다 박아두던 자리가 그대로 사라지고, 외부 정렬 ID 라이브러리도 표준 함수 한 줄로 옮겨갈 수 있게 됐습니다. Kotlin 2.4 stable UUID로 사라진 com.benasher44:uuid kotlin.uuid.Uuid 클래스 자체가 St..

반응형
LIST