클로드 소넷으로 코드 이사하기 : 파이썬에서 러스트까지
컨텐츠 정보
- 조회 466
본문
AI 기반 코드 개발 툴에 대한 보편적인 경험을 하나만 꼽으라면 툴이 마법처럼 느껴지다가, 어느 순간 엇나가면서 그 환상이 깨진다는 점이다.
AI 에이전트는 코드베이스를 샅샅이 훑어보고 아키텍처와 설계 선택에 대해 놀라울 정도로 날카롭게 분석하는 모습을 보여준다. 그러다가 갑자기 스크롤 백 버퍼가 가득 차고 토큰이 바닥날 때까지 콘솔에 “CoreCoreCoreCore” 같은 이상한 문자열을 쏟아낸다.
AI 기반 코딩 및 개발 툴이 발전하면서 사람들은 이러한 툴이 잘 하는 일과 못하는 일, 그리고 경우에 따라서는 하면 안 되는 일에 대해 더 확실한 감을 갖게 됐다. 이론적으로 AI 기반 툴은 단조롭거나 부담이 큰 작업, 예를 들어 테스트 생성, 리팩터링, 문서용 예제 작성 같은 작업을 수행함으로써 개발자의 역량을 더 강화해준다. 실무에서 이와 같은 “역량 강화”에는 대가가 따르는 경우가 많다. AI가 작업 초반에 쉽게 만들어준 일이 나중에 상황을 더 어렵게 한다.
필자가 구상한 시나리오는 AI 툴을 사용해 코드를 한 언어에서 다른 언어로 이식하는 것이다. 파이썬 프로젝트를 시작했다가 나중에 러스트로 마이그레이션하기로 결정한 경우를 생각해 보자. AI 에이전트가 이 과정을 더 빠르게 해주는 든든한 동반자가 될 수 있을까?
이와 같은 질문에는 어느정도 위험을 감수하고 실험을 통해 답을 찾아볼 가치가 있다. 클로드 코드를 사용해 파이썬 프로젝트를 러스트로 이식하는 과정이 어떻게 진행됐는지 살펴보자.
프로젝트 설정과 러스트 선택 이유
이식하기로 결심한 대상은 필자가 전에 작성한 파이썬 기반 블로깅 시스템으로, 정적 HTML을 생성하고 워드프레스와 비슷한 인터페이스를 제공하는 서버 측 앱이다. 이 프로젝트를 선택한 이유 중 하나는 기능이 비교적 적다는 점이다. 블로그별 템플릿 시스템, 범주와 태그, 그리고 리치 텍스트 편집기나 일반 텍스트 마크다운을 통해 HTML로 글을 작성할 수 있는 인터페이스로 구성된다.
필자는 템플릿 시스템, ORM, 웹 프레임워크를 포함한 모든 기능에 대해 러스트 생태계에도 하나 이상의 동등한 대응 요소가 있는지 확인했다. 프로젝트에는 일부 자바스크립트 프론트엔드 코드도 포함돼 있어서, 이를 사용해 혼합된 코드베이스를 툴이 얼마나 잘 처리하는지도 테스트할 수 있었다.
러스트를 이식 대상으로 선택한 주된 이유는 러스트의 정확성과 안전성 보장이 런타임이 아니라 컴파일 시점에 이뤄진다는 데 있다. 필자는 이 과정에서 컴파일러가 제공하는 유용한 피드백이 AI에 도움이 되고, 이것이 이식 프로세스를 더 생산적으로 만들어 줄 것이라고 생각했다.
AI의 경우 처음에는 클로드 소넷 4.5를 선택했지만 이전 버전의 갑작스러운 단종에 따라 클로드 소넷 4.6으로 업그레이드해야 했다. 또한 전에 리뷰한 적이 있는 구글의 자체 안티그래비티 IDE도 함께 사용했다.
첫 번째 지시
파이썬 코드베이스 디렉터리를 복사해 그곳에서 안티그래비티를 열고 다음과 같은 간단한 지시를 내렸다.
This directory contains a Python project, a blogging system. Examine the code and devise a plan for how to migrate this project to Rust, using native Rust libraries but preserving the same functionality.
클로드는 코드를 검토한 다음 “현대적인 고성능 러스트 스택으로 전환”하기 위한 계획의 일부로 다음과 같은 구성요소를 추천했다.
- 액섬(Axum) : 웹 레이어
- SeaORM : 데이터베이스 상호작용
- 테라(Tera) : 템플릿
- 도쿄(Tokio) : 비동기 작업 처리(파이썬의 멀티프로세싱 대체)
클로드는 파이썬 라이브러리의 적절한 대체제를 찾거나 동작을 다른 언어로 매핑하는 부분은 특별한 어려움 없이 처리했다(예를 들어 파이썬 멀티프로세싱을 대체하기 위한 비동기 작업에 tokio 를 사용). 원본 프로그램이 동적 가져오기와 같은 까다로운 파이썬 기능에 의존하지 않도록 설계됐다는 점도 이 부분이 비교적 쉽게 처리된 데 일부 기여한 것으로 보인다. 또한 클로드가 개별 인터페이스나 함수가 아니라 프로그램의 행동을 분석하고 이를 다시 구현하는 방식을 사용했다는 점도 도움이 됐다. (이 접근 방식에는 몇 가지 한계도 있었는데, 이에 대해서는 아래에서 설명한다.)
생성된 계획을 검토해 보니 새로 초기화된 데이터베이스를 위한 플레이스홀더 데이터, 가령 샘플 사용자, 샘플 게시물이 포함된 블로그 등이 생성되지 않은 상태였다. 클로드가 이를 추가한 후 필자는 프로그램을 다시 시작해서 생성된 데이터베이스를 통해 이 부분이 작동하는지 확인했다. 여기까지는 그럭저럭 괜찮았다.
몇 가지 빠진 조각
다음 단계에 들어서자 클로드가 해야 할 일을 상당히 빼먹었음을 알 수 있었다. 클로드는 앱의 핵심 페이지 렌더링 로직을 찾아서 구현했지만 사용자와 접하는 인프라, 즉 로그인하고 게시물을 편집 및 관리하기 위한 관리자 패널 등은 전혀 만들지 않았다. 물론 필자가 애초에 지시할 때 인터페이스에 대해 언급하지 않은 것도 사실이다. 꼼꼼하게 챙기지 않은 클로드의 잘못일까, 명시적으로 지시하지 않은 필자의 잘못일까? 어쨌든 필자는 이 부분이 누락됐음을 지적했고 클로드는 빠진 부분을 보완한 계획을 다시 생성했다.
I'm now addressing the missing Admin UI by analyzing the original Bottle templates and planning their migration to Tera, including the login screen and main dashboard.
참 고: 보틀(Bottle)은 개인적으로 파이썬 프로젝트에서 사용한 웹 프레임워크다. 비교적 덜 유명한 라이브러리에서 마이그레이션하는 상황을 클로드가 얼마나 잘 처리할 수 있을지에 대한 테스트가 됐다. 보틀 자체는 별다른 문제가 되지 않았지만 다른 곳에 훨씬 더 큰 여러 문제가 잠재해 있었다.
클로드와의 본격적인 주고받기는 이 부분에서 시작됐다. 이미 AI 툴을 사용하는 개발자라면 프롬프트—>생성—>테스트—>재프롬프트로 이어지는 이 사이클에 익숙할 것이다. 기본적으로 필자는 클로드에 누락된 기능을 구현하도록 하고(여기서는 관리자 UI의 각 요소) 프로그램을 실행해 직접 테스트하면서 다양한 오류 또는 누락을 발견하고 클로드에 수정을 요청했다.
관리자 UI에서 처음 발견한 문제는 웹 템플릿에서 발생한 포착되지 않은 런타임 오류로, 러스트의 컴파일 타임 검사에서 잡히지 않는 문제였다. 그 다음에는 관리자 패널의 로그인 페이지가 비어 있었다. 로그인 페이지가 정상 작동하게 되자 이번에는 “Login logic not yet implemented”라는 문구가 표시되는 플레이스홀더 페이지로 이동했다. 그 다음에는 사용자 이름과 비밀번호를 받는 로직에 문제가 있음이 드러났다. 이런 식으로 원래 애플리케이션의 각 구성요소 전반에서 줄줄이 문제가 발생했다.
크고 작은 오작동
클로드를 사용해 코드를 마이그레이션하는 경험은 어떤 면에서는 과거 AI 툴 없이 프로그램을 다시 작성하거나 마이그레이션했던 경험과 별 차이가 없었다. 모든 부분이 가다 서다를 반복했고 간단해 보였던 일이 예상을 뛰어넘는 어려운 문제로 이어졌다. 가끔은 반대의 경우도 있었다. 어렵다고 생각했던 일이 금방 해결되면서 뜻밖의 기쁨을 주기도 했다.
큰 차이점 중 하나는 AI 코딩 툴 경험이 있는 사람이라면 익숙할텐데, 클로드가 간혹 엉뚱하게 움직여서 다시 정상 궤도로 돌려놓기 위해서는 상당한 개입이 필요하다는 것이다. 한 시점에서 필자는 클로드에게 각 블로그에 대한 관리자 페이지 구현 작업을 계속하라고 지시했는데, 클로드는 엉뚱하게도 콘솔에 CoreCoreCoreCoreCore…를 출력하기 시작했다. 이 문자열만 수백 라인이 출력됐으며 이런저런 응답의 끝부분에도 Core라는 문자열이 무작위로 나타나기 시작했다.
Implementing Blog Detail and Post ListCoreCoreI've implemented the blog detail and post management features, fixed type mismatches, and updated the project artifacts. I'm now performing a deep dive into the remaining compilation error by capturing the complete cargo check output to ensure the system is production-ready.CoreCoreCoreCore
그 다음에는 모델의 생성 결과가 최대 출력 토큰 제한을 초과했다는 경고가 뜨기 시작했다. 이 문제는 다음 날 세션을 다시 시작하자 사라졌지만 그 이후부터는 비슷한 이상 현상이 있는지 모든 출력 결과를 일일이 눈으로 확인했다.
또 한 가지 눈에 띈 부분은 클로드가 자신의 실행 환경에 대해 테스트되지 않은 전제를 하고 시작한 다음 문제가 발생하면 뒤늦게 수정하며, 그나마도 지속적이지 않다는 점이다. 예를 들어 클로드는 bash 구문으로 셸 명령을 실행했다가 오류가 발생하면 그제서야 자신이 PowerShell을 사용 중임을 인식하고 적절한 명령을 실행하는 경우가 많았다.
이것은 AI 코드 툴에서 경험한 전형적인 패턴이다. AI 코드 툴은 대체로 사용자가 지시한 만큼만 계획을 수립하고 짚고 넘어가야 하는 디테일을 놓치는 경향이 있다. 모델을 위해 더 지속적으로 이것저것 정의할수록 결과도 더 일관적이다. (참고로 더 일관적이라는 말이지, 항상 또는 완벽하게 일관적이라는 뜻은 아니다.)
마지막으로, 생성된 코드를 직접 검토한 결과 많은 측면에서 클로드가 원본 코드의 의도를 무시했음이 드러났다. 예를 들어 필자의 원본 파이썬 프로그램에서는 웹 UI의 모든 경로에 로그인 검증 데코레이터가 있어 로그인한 상태가 아닌 경우 로그인 페이지로 리디렉션된다. 그러나 클로드는 이 패턴을 거의 반영하지 않은 채 코드를 생성했다. 즉, 관리자 UI의 거의 모든 경로(파괴적인 작업을 수행한 경로까지 포함)가 무단 사용으로부터 전혀 보호되지 않았다.
또한 경로에 검증이 포함된 경우라 해도 함수 호출이나 데코레이터, 매크로와 같은 모듈화된 방식이 아니라 경로 함수의 맨 위에 상용구 코드를 넣는 방식을 사용했다. 클로드가 원본 파이썬의 데코레이터 패턴을 인식하지 못했는지, 아니면 그 부분을 러스트로 효과적으로 이식할 아이디어를 구상하지 못했는지는 필자로서는 알 수 없다. 어느 쪽이든 클로드는 이 누락에 대해 언급조차 하지 않았기 때문에 필자가 직접 시행착오를 거쳐 발견해야 했다.
3가지 교훈을 얻다
클로드와 며칠 동안 밀고 당기기를 반복하면서 원본 앱의 기능 중 많은 부분을 러스트로 마이그레이션했는데, 이쯤에서 잠시 멈추고 상황을 살펴보기로 했다. 필자가 정리한 세 가지 교훈은 다음과 같다.
1. 원본과 대상에 대한 이해
언어 간 마이그레이션에 클로드 같은 툴을 사용한다고 해서 원본 언어와 대상 언어에 대해 몰라도 되는 것은 아니다. 마이그레이션 원본이나 대상 언어 중 하나에 능숙하지 않다면 에이전트에 설명을 요청해 도움을 받을 수는 있다. 그러나 생성된 코드에 문제가 있을 때 이를 인식할 수 있는 능력은 대체할 수 없다. 자신이 무엇을 모르는지조차 모른다면 클로드는 별 도움이 되지 않는다.
필자는 러스트보다 파이썬에 더 능숙하기는 하지만 러스트에 대해서도 a) 러스트 코드가 잘 컴파일된다고 해서 문제가 없다는 뜻은 아니라는 점을 알고 b) 코드에 누락된 로직(예를 들어 API 경로상의 보안 검사 부재)을 식별할 만큼의 경험은 있었다. 필자가 얻은 교훈은 언어 간 이식에서 발생하는 문제의 상당수는 눈에 띄는 큰 문제가 아니라 포착하기 어려운 미묘한 문제이며, 이에 대처하려면 두 영역 모두에 대한 이해가 필요하다는 점이다. 자동화는 경험을 보완할 수 있지만 대체할 수는 없다.
2. 반복될 것을 예상해야
앞서 언급했듯이 지시가 명확하고 지속적일수록 의도한 바에 근접한 결과를 얻을 가능성이 높아진다. 물론 첫 번째, 두 번째, 세 번째, 심지어 네 번째 시도에서도 정확히 원하는 결과를 얻을 가능성은 높지 않다. 프로그램 전체는 말할 필요도 없고 프로그램의 개별 요소 어느 하나에 대해서도 마찬가지다. 다행이라고 말해야 할지, 개발자의 마음을 읽는 능력, 그것도 정확하게 읽는 능력까지는 아직 갈 길이 멀다.
특히 프로젝트를 다른 언어로 다시 구현하는 경우라면 원하는 결과를 얻기까지 어느 정도의 시행착오는 불가피해 보인다. 장점은 진행 과정에서 각각의 변경 사항을 직접 마주하면서 제대로 작동하는지 확인할 수밖에 없다는 점이고, 단점은 이 과정이 매우 힘들 수 있으며, 그 방식도 혼자서 반복적 변경 작업을 하는 것과는 다르다는 것이다. 개발자 혼자서 변경 작업을 할 때는 자신과 컴퓨터, 둘 사이에만 일이 오간다. 그러나 에이전트가 대신 변경을 수행하게 되면 개발자와 에이전트, 컴퓨터의 3자 구도가 된다. 컴퓨터 자체의 결정성이 에이전트의 비결정성으로 대체된다.
3. 결과에 대한 책임은 전적으로 개발자가 진다
마지막 교훈은 프로젝트에서 생성된 모든 코드를 책임질 준비를 해야 한다는 것이다. 그저 코드가 잘 실행된다고 해서 괜찮다고 판단하면 안 된다. 필자의 경우 클로드가 에이전트로서 코드를 생성했지만, 매 단계에서 코드를 승인하고 최종 결정한 사람은 필자였다. 개발자로서의 책임은 여전하다. 또한 그 책임은 단순히 모든 부분이 작동하는지 확인하는 데서 끝나지 않는다. 결과물이 대상 언어의 메타포, 생태계, 관용구를 얼마나 잘 활용하는지도 중요하다.
여기에는 전문성을 갖춘 개발만이 제공할 수 있는 부분이 존재한다. 사용하는 기술에 충분히 익숙하지 않다면 클로드 프롬프트를 시작하기 전에 환경에 대해 배우는 것이 좋다.
dl-itworldkorea@foundryco.com
관련자료
-
링크
-
이전
-
다음





