ai-assisted-development

4 개의 포스트

datadog

AI 지원 리팩토링을 활용해 실시간 라우팅 시스템을 마이그레이션한 방법 (새 탭에서 열림)

Datadog은 Stream Router의 기존 FoundationDB 기반 KV 모델이 트랜잭션 크기와 데이터 증가에 따른 한계에 도달하자, 운영 중단 없이 PostgreSQL·DuckDB 기반의 관계형 구조로 전환했습니다. 이 과정에서 Claude와 Cursor를 활용했지만, AI가 자율적으로 코드를 작성한 것이 아니라 사람이 새 스키마와 기존 구현, 실패 테스트를 제공하고 테스트 결과로 검증하는 방식으로 사용했습니다. 핵심 결론은 AI가 대규모 마이그레이션을 크게 가속할 수 있지만, 데이터 모델 설계와 안전성 판단은 여전히 사람의 전문성이 필요하다는 것입니다. ## Stream Router의 역할과 기존 아키텍처 - Datadog은 하루 100조 개가 넘는 이벤트를 처리하며, 각 메트릭 데이터를 올바른 Kafka 클러스터·토픽·파티션으로 라우팅해야 합니다. - Stream Router는 Kafka 메시지를 직접 생산하거나 소비하지 않고, 다른 서비스가 사용할 라우팅 결정을 관리하는 제어 평면 서비스입니다. - 라우팅 정보는 다음과 같은 용도로 사용됩니다. - Producer가 데이터를 기록할 위치 결정 - Querier가 데이터를 읽을 위치 결정 - 시간에 따른 데이터 위치 이력 관리 - 기존 구조는 쓰기와 읽기를 분리한 Eventually Consistent 아키텍처였습니다. - 쓰기 경로: FoundationDB의 키-값 모델 사용 - 읽기 경로: 주기적으로 생성된 스냅샷을 RocksDB와 메모리 데이터베이스에 적재 - Producer와 Querier는 쓰기 경로에 직접 접근하지 않음 ## 설정 파일에서 중앙 제어 평면으로의 발전 - 2016년에는 몇 줄짜리 설정 파일을 모든 서비스에 배포해 라우팅을 관리했습니다. - 인프라와 고객 규모가 커지면서 설정 파일이 수천 줄로 증가했고, 수동 편집과 배포가 운영 부담이 되었습니다. - Stream Router 도입 후에는 다음과 같이 개선되었습니다. - 설정 파일 대신 gRPC API로 라우팅 변경 - 자동화된 오케스트레이션 - 점진적이고 자동화된 롤아웃 - 고가용성과 장애 내성을 고려한 읽기·쓰기 분리 ## KV 모델의 확장 한계 - 라우팅 데이터는 단순한 키-값 목록이 아니라 서로 연결된 관계형 데이터였습니다. - Route는 특정 Kafka Stream을 참조 - Route는 Sharding Strategy를 참조 - Rule은 Route를 참조하고 활성화 시점과 적용 방식을 결정 - 기존 KV 구조에서는 데이터베이스가 제공해야 할 관계 검증을 애플리케이션이 직접 수행해야 했습니다. - 수만 개의 레코드를 Pod 프로세스로 가져옴 - 애플리케이션 내부에서 관계형 데이터베이스처럼 조인과 일관성 검사를 수행 - 데이터와 변경 규모가 커지면서 FoundationDB 트랜잭션 크기 제한에 걸리는 작업이 발생했습니다. - FoundationDB를 PostgreSQL로 단순 교체하는 방안도 해결책이 되지 못했습니다. - 기존 KV 접근 패턴을 그대로 유지하면 수천 번의 순차적인 데이터베이스 왕복이 필요 - 일부 작업은 약 45분이 걸릴 것으로 예상 - 따라서 병목의 원인은 특정 데이터베이스가 아니라, KV에 맞춰진 데이터 모델과 애플리케이션 로직 자체였습니다. ## 관계형 스키마로 재설계 - 팀은 AI를 사용하기 전에 도메인 관계를 직접 분석하고 새 스키마를 설계했습니다. - 관계형 구조에서는 다음 관계를 외래 키로 명시합니다. - Streams와 Sharding Strategies → Routes - Routes → Rules - 기존 애플리케이션 코드가 수동으로 복원하던 관계를 데이터베이스가 직접 표현하고 검증할 수 있게 되었습니다. - 쓰기 경로에는 PostgreSQL을 선택했습니다. - 관계형 의미론 지원 - 트랜잭션 처리 - Datadog의 자체 관리형 PostgreSQL 플랫폼 활용 가능 - 읽기 경로에는 DuckDB를 선택했습니다. - 스냅샷 기반 읽기 계층에 적합한 임베디드 데이터베이스 - 배열 컬럼을 기본 지원 - PostgreSQL과 유사한 SQL 문법 - PostgreSQL과 DuckDB 사이에서 쿼리 로직을 공유할 수 있음 - SQLite도 검토했지만 배열 컬럼을 기본 지원하지 않아 적합하지 않았습니다. ## AI를 활용한 테스트 중심 리팩터링 - Claude와 Cursor는 코드를 독립적으로 생성하도록 맡기지 않았습니다. - 각 메서드마다 사람이 다음 정보를 제공했습니다. - 기존 구현 - 새 데이터베이스 스키마 - 현재 실패하는 테스트 - AI는 이를 바탕으로 첫 번째 구현을 만들었고, 테스트가 코드의 정확성을 검증했습니다. - 이 방식의 장점은 다음과 같습니다. - 전체 마이그레이션을 한 번에 생성하지 않고 메서드 단위로 분할 - 실패 테스트가 요구사항과 오류를 구체적으로 제시 - 생성 코드가 실제 동작과 데이터 관계를 만족하는지 즉시 확인 - 사람이 설계와 판단을 담당하고 AI는 반복적인 변환 작업을 가속 ## 안전한 마이그레이션을 가능하게 한 조건 - 마이그레이션이 성공할 수 있었던 기반은 AI보다 기존 시스템의 구조와 개발 프로세스였습니다. - 특히 저장소 계층이 `Controller`라는 내부 인터페이스 뒤에 모듈화되어 있었습니다. - 이러한 추상화 덕분에 저장 엔진과 구현을 교체하더라도 상위 계층의 변경 범위를 줄일 수 있었습니다. - 글의 제공된 부분은 안전성을 뒷받침한 요소를 설명하는 도중 끝나므로, 이후 테스트 전략이나 실제 전환 절차의 상세 내용은 포함되어 있지 않습니다. 결국 AI는 관계형 스키마를 설계하거나 운영 위험을 판단하는 도구라기보다, 명확한 설계와 테스트가 준비된 상태에서 반복적인 코드 변환을 빠르게 수행하는 도구로 활용하는 것이 적절합니다. 대규모 운영 시스템에서는 먼저 데이터 모델과 인터페이스를 사람이 설계하고, 작은 단위의 실패 테스트를 기준으로 AI 생성 코드를 검증하는 방식을 추천할 수 있습니다.

github

Git worktree란 무엇이며, 왜 사용해야 할까요? (새 탭에서 열림)

Git worktree는 하나의 저장소에서 여러 작업 디렉터리를 동시에 운영하게 해 주는 기능으로, 브랜치 전환과 `git stash` 없이 여러 작업을 병렬로 진행할 수 있게 한다. 특히 AI 에이전트와 개발 세션을 동시에 실행하는 환경에서 각 작업의 맥락을 보존하고 전환 비용을 줄여 주기 때문에 최근 주목받고 있다. 다만 의존성 저장 공간, 디렉터리 정리, 동일 브랜치 중복 체크아웃 등의 관리 부담은 남아 있다. ## 브랜치 전환과 `git stash`의 부담 - 기존 방식에서는 긴급한 버그를 처리하기 위해 현재 작업을 먼저 임시 저장해야 한다. ```bash git stash "wip feature login" ``` - 이후 `main` 브랜치로 이동하고 최신 변경 사항을 받은 뒤, 별도의 핫픽스 브랜치를 생성한다. ```bash git checkout main git pull origin main git checkout -b hotfix-bug ``` - 수정·커밋·푸시·병합이 끝나면 다시 원래 브랜치로 돌아가 `stash pop`을 실행한다. - 이 과정에서 다음과 같은 비용이 발생한다. - 작업 파일과 에디터 상태를 반복해서 다시 로드해야 함 - 변경된 의존성에 따라 `node_modules` 등을 재설치할 수 있음 - 복잡한 stash 충돌이 발생할 수 있음 - 현재 작업의 맥락을 잃기 쉬움 - 일부 개발자는 이를 피하기 위해 같은 저장소를 여러 번 clone하기도 하지만, 저장 공간과 관리 부담이 커진다. ## Worktree를 이용한 병렬 작업 - `git worktree add`를 사용하면 기존 작업 디렉터리를 그대로 둔 채 별도의 디렉터리에서 다른 브랜치를 체크아웃할 수 있다. ```bash git worktree add ../hotfix-workspace -b hotfix-bug main ``` - 이 명령은 다음 작업을 한 번에 수행한다. - 기존 프로젝트 옆에 `hotfix-workspace` 디렉터리 생성 - `main`을 기반으로 `hotfix-bug` 브랜치 생성 - 새 디렉터리에서 해당 브랜치 체크아웃 - 원래 에디터 창과 feature 브랜치의 파일 상태는 그대로 유지된다. - 새 디렉터리에서 독립적으로 수정하고 커밋·푸시할 수 있다. ```bash cd ../hotfix-workspace git add . git commit -m "fix broken submit button" git push origin hotfix-bug ``` - 작업이 끝나면 임시 worktree를 제거한다. ```bash cd ../main-project git worktree remove ../hotfix-workspace ``` - 따라서 stash 충돌 없이 여러 작업을 동시에 진행하고, 각 작업의 에디터와 파일 맥락을 보존할 수 있다. - VS Code 등 일부 개발 도구는 worktree를 직접 지원한다. ## Worktree가 최근 주목받는 이유 - Git worktree 자체는 2015년부터 존재했지만, 오랫동안 일반 개발자에게 널리 알려지지는 않았다. - 과거에는 대부분 다음과 같은 단순한 흐름을 사용했다. - feature 브랜치 생성 - 작업 - Pull Request 생성 - 병합 - 다음 작업 시작 - Git GUI가 worktree를 제대로 지원하지 않거나 부가 기능처럼 취급한 점도 확산을 막았다. - 최근에는 AI 도구와 에이전트가 여러 개발 세션을 동시에 실행하면서 병렬 작업이 크게 증가했다. - 코드 작성뿐 아니라 코드 리뷰와 자동화 작업도 병렬로 진행되면서, 세션마다 독립적인 작업 공간을 제공하는 worktree가 적합해졌다. - GitHub Copilot 앱을 비롯한 최신 개발 도구에서는 worktree가 기본 실행 방식으로 사용되기도 한다. ## Worktree 사용 시 주의점 - **의존성 저장 공간 증가** - 각 worktree가 프로젝트 의존성을 별도로 설치하면 `node_modules`나 Python 패키지가 반복 저장된다. - 여러 worktree를 동시에 사용하면 디스크 공간이 빠르게 줄어들 수 있다. - **디렉터리 정리 필요** - 작업이 끝난 worktree를 직접 삭제하지 않으면 부모 디렉터리에 임시 폴더가 계속 쌓인다. - 일부 앱은 이를 자동으로 처리하지만, 터미널 사용 시 직접 관리해야 한다. - **`.gitignore` 설정** - 저장소 내부에 worktree를 만들 경우 해당 폴더가 실수로 추적되지 않도록 `.gitignore`에 추가해야 한다. - 저장소 외부에 worktree를 생성하면 이 문제를 줄일 수 있다. - **동일 브랜치 중복 체크아웃 제한** - Git은 데이터 손상을 막기 위해 같은 브랜치를 여러 worktree에서 동시에 체크아웃하지 못하게 한다. ## GitHub Copilot 앱에서의 사용 - 새 세션을 만들 때 실행 위치를 선택할 수 있으며, 기본값으로 새 worktree를 사용할 수 있다. - 세션을 시작하면 앱에서 다음 정보를 확인할 수 있다. - 생성된 worktree 이름 - worktree의 경로 - 연결된 프로젝트 - 해당 worktree에서 발생한 변경 사항 - 사용자가 직접 Git 명령을 관리하지 않아도 병렬 세션을 쉽게 만들고 정리할 수 있다는 점이 장점이다. ## 상황에 따른 선택 - 작업을 자주 병렬로 진행하거나 AI 에이전트를 여러 개 실행한다면 worktree가 특히 유용하다. - 단일 작업을 순차적으로 처리하고 기존 브랜치·stash 방식이 익숙하다면 반드시 전환할 필요는 없다. - 두 방식을 함께 사용하면서 작업 유형에 따라 선택하는 것도 가능하다. - 병렬 작업이 많은 팀이나 개발자는 worktree를 도입하되, 의존성 공유와 임시 디렉터리 정리 전략을 함께 마련하는 것이 좋다.

gitlab

AI 보조 코딩 시대에 맞춰 파이프라인 경계를 강화하세요 (새 탭에서 열림)

AI 지원 개발로 사람·에이전트·외부 코드가 빠르게 결합하면서, 기존의 문서 중심 보안 정책만으로는 파이프라인을 보호하기 어려워졌다. 글은 GitLab Ultimate이 보안을 별도 포털이 아닌 개발 플랫폼의 통제 영역에 통합해, 모든 변경을 **보고(See)·강제하고(Enforce)·수정하는(Fix)** DevSecOps 제어면을 제공한다고 주장한다. 이 세 요소를 결합해야 AI가 생성하는 코드의 속도와 보안 요구를 함께 충족할 수 있다는 결론이다. ## 모든 프로젝트와 보안 활동을 가시화 - 그룹 보안 대시보드에서 다음 스캐너의 결과를 여러 저장소에 걸쳐 통합해서 확인한다. - SAST - SCA - 시크릿 탐지 - 컨테이너 스캔 - IaC 스캔 - DAST - 퍼징 테스트 - 프로젝트별 위험 추세, 사업부·노출 수준별 위험, 보안 인벤토리를 한 화면에서 확인할 수 있다. - 한 번도 스캔되지 않아 보안 등급이 없는 프로젝트도 식별해 보이지 않는 사각지대를 줄인다. - Credentials Inventory는 인스턴스 전체 토큰의 소유자, 권한 범위, 만료일을 보여준다. - 손상된 토큰이나 아직 활성화된 토큰을 필터링해 사고 중 즉시 폐기할 수 있다. - Token Lifetime Enforcement로 토큰이 관리자가 정한 최대 수명을 넘겨 사용되지 않도록 강제한다. - Audit Event Streaming은 토큰 생성, 권한 변경, MR 승인, 역할 변경 등의 이벤트를 구조화된 타임스탬프와 함께 SIEM으로 실시간 전송한다. - 그룹 단위 SBOM을 이용해 전체 프로젝트 포트폴리오에서 오픈소스 의존성 노출 여부를 검색한다. ## 정책을 파이프라인에서 자동으로 강제 - 문서로만 존재하는 정책은 개발자가 매번 기억하고 설정해야 하므로, 사람이 만든 변경뿐 아니라 AI 에이전트가 만든 변경에도 일관되게 적용하기 어렵다. - Scan Execution Policies는 운영 환경을 대상으로 하는 모든 파이프라인에 SAST, SCA, 시크릿 탐지 작업을 자동 삽입한다. - 프로젝트별 설정이 필요 없다. - 개발자가 보안 작업을 임의로 제거할 수 없다. - `[skip ci]`로 우회할 수 없다. - Pipeline Execution Policies(PEP)는 플랫폼이 관리하는 CI 템플릿을 강제한다. - 팀이 별도로 만든 이른바 섀도 파이프라인도 동일한 접근 권한과 신뢰 수준으로 실행되는 문제를 줄인다. - 프로젝트의 CI 설정에 보안 작업이 빠져 있어도 필수 검사를 실행한다. - MR Approval Policies로 보호 브랜치, 최소 승인자 수, 코드 소유자 승인 요건을 자동화한다. - Compliance Center는 정책을 SOC 2, ISO 27001, NIST, PCI DSS 등의 기준과 연결하고, 실시간 대시보드와 변경 이력 보고서를 제공한다. - Secret Push Protection은 pre-receive hook 단계에서 비밀정보가 Git 이력에 들어가기 전에 푸시를 차단한다. - 문제가 된 파일과 줄, 탐지된 시크릿 유형을 표시한다. - 우회 시도도 기록한다. ## 개발 흐름 안에서 취약점 수정 - MR 보안 위젯은 코드가 기본 브랜치에 병합되기 전에 diff 내부에 SAST, SCA, 컨테이너, IaC, 시크릿 탐지 결과를 표시한다. - 개발자는 별도 보안 포털로 이동하지 않고 현재 MR에서 다음 정보를 확인할 수 있다. - 새로 발생한 취약점 - 취약점이 존재하는 코드 위치 - 수정 방법 - Advanced SAST는 여러 함수와 파일을 가로지르는 데이터 흐름을 분석해, 공격자가 입력값을 추적하는 방식으로 오염된 입력이 최종 사용 지점까지 도달하는 경로를 보여준다. - GitLab Duo Agent Platform은 오탐 가능성을 평가하고 판단 근거를 설명해 불필요한 수동 분류 작업을 줄인다. - GitLab Duo Security Analyst Agent는 CVSS 점수만 보지 않고 악용 가능성, 외부 노출 정도, 비즈니스 맥락을 고려해 취약점의 우선순위를 정한다. - Agentic Vulnerability Resolution은 영향이 큰 SAST 취약점에 대해 수정 MR을 자동으로 생성한다. - 관련 코드 맥락이 함께 포함된다. - 개발자가 변경 내용을 검토하고 기존 승인 절차에 따라 병합한다. - 탐지부터 수정·배포까지 같은 워크플로 안에서 완료할 수 있다. ## AI 시대의 파이프라인 보안 전략 - AI 에이전트가 코드를 생성하고 MR을 열며 변경 사항을 배포하는 속도는 기존 보안 검토보다 빠르다. - 따라서 보안 검사를 개발자에게 맡기거나 별도 대시보드에 의존하기보다, 그룹·플랫폼 수준에서 자동 적용해야 한다. - 효과적인 통제면은 다음 세 요소를 함께 제공해야 한다. - **가시화:** 모든 프로젝트, 토큰, 의존성, 보안 이벤트 확인 - **강제:** 파이프라인과 MR마다 정책을 자동 적용 - **수정:** 코드 변경 지점에서 우선순위화와 자동 수정 수행 실무적으로는 먼저 그룹 단위 보안 대시보드와 SBOM으로 사각지대를 파악한 뒤, 필수 스캔·승인·시크릿 차단 정책을 플랫폼 수준에서 강제하는 접근이 권장된다. 이후 AI 기반 오탐 분류와 자동 수정 MR을 도입하면 개발 속도를 크게 떨어뜨리지 않으면서 보안 부채를 줄일 수 있다.

figma

더블 클릭: 코딩이 (새 탭에서 열림)

AI와 대화하며 코드를 생성·수정하는 ‘바이브 코딩’은 프로그래밍을 문법 작성보다 아이디어 표현과 반복 대화에 가깝게 만든다. 덕분에 코딩 경험이 없는 사람도 빠르게 프로토타입과 사이드 프로젝트를 만들 수 있지만, 프로젝트가 복잡해지면 일관성 없는 데이터 모델과 스파게티 코드라는 한계에 부딪힌다. 따라서 바이브 코딩은 완성도 높은 소프트웨어 개발 전체를 대체하기보다, 초기 탐색과 실험을 가속하는 방식으로 보는 것이 적절하다. ## 대화형 프로그래밍으로의 변화 - 바이브 코딩은 원하는 기능을 자연어로 설명하고, AI가 코드를 작성하면 실행 결과를 확인한 뒤 다시 대화로 수정하는 개발 방식이다. - 개발자는 코드를 한 줄씩 직접 작성하기보다 “보고, 말하고, 실행하고, 복사·붙여넣는” 흐름으로 결과를 만들어 간다. - Cursor Composer, Claude Sonnet, 음성 입력 도구인 SuperWhisper 같은 LLM 기반 도구의 성능 향상이 이러한 방식을 가능하게 했다. - 어셈블리에서 C, C에서 Python으로 추상화 수준이 높아졌던 것처럼, 바이브 코딩도 프로그래밍 추상화의 또 다른 단계로 볼 수 있다는 의견이 제시된다. ## 펀치카드에서 즉시 프로토타이핑까지 - 초기 컴퓨팅에서는 명령 하나를 펀치카드에 기록하고, 실행 결과를 보기까지 수 시간 또는 수일을 기다려야 했다. - 이후 직접 코드를 입력할 수 있게 되었지만, 아이디어를 실제 인터랙티브 결과물로 바꾸는 과정은 여전히 개발자에게 큰 장벽이었다. - 바이브 코딩은 이 간극을 줄여 아이디어를 빠르게 표현하고 반복적으로 실험하게 한다. - Figma의 디자이너 Nikolas Klein은 이를 “코딩 자체보다 인터랙티브 아이디어를 더 빠르고 쉽게 표현하는 방법”으로 본다. - Val Town의 Charmaine Lee는 문서에 낙서하거나 Google Sheet를 만드는 것처럼 코드를 가볍게 실험할 수 있다는 점을 강조한다. ## 코딩을 하지 않는 사용자도 소프트웨어를 만든다 - 바이브 코딩은 전문 개발자뿐 아니라 코드를 전혀 작성하지 않는 사람에게도 소프트웨어 제작 기회를 넓힌다. - Replit CEO Amjad Masad에 따르면 Replit 고객의 75%는 코드 한 줄도 직접 작성하지 않는다. - Figma 구성원들은 SwiftUI를 몰라도 러닝 코치 앱이나 TikTok 스타일의 Wikipedia 앱 로딩 애니메이션 같은 프로젝트를 만들 수 있었다. - 특히 사이드 프로젝트, 인터랙션 실험, 디자인 프로토타입처럼 빠른 시도가 중요한 작업에서 효과가 크다. ## 복잡해질수록 드러나는 한계 - 바이브 코딩은 프로젝트 초반에는 매우 빠르고 즐겁지만, 기능과 코드 규모가 커지면 AI의 대응 품질이 떨어진다. - 처음에는 원하는 결과의 약 80%까지 빠르게 도달할 수 있지만, 나머지 20%를 완성하는 과정에서 어려움이 커진다. - AI가 생성한 코드가 기능별로는 작동해도 전체적으로 일관된 내부 데이터 모델을 갖추지 못할 수 있다. - 결과적으로 구조를 이해하기 어렵고 유지보수하기 힘든 스파게티 코드가 쌓일 위험이 있다. - 따라서 복잡한 프로젝트에서는 아키텍처 설계, 데이터 모델 검토, 테스트와 리팩터링 등 전통적인 개발 역량이 여전히 필요하다. ## 실용적인 활용 방향 - 바이브 코딩은 아이디어 검증, 초기 프로토타입, 개인 프로젝트, UI·인터랙션 실험에 적극 활용할 만하다. - 운영 환경에 배포하거나 장기 유지보수할 코드는 생성 결과를 그대로 사용하지 말고, 개발자가 구조·보안·성능·테스트를 검토해야 한다. - 가장 현실적인 접근은 AI에게 구현을 맡기되, 사람이 요구사항과 설계 방향을 통제하고 결과물을 지속적으로 정리하는 방식이다.