Refactoring English: Month 14

Michael Lynch

Refactoring English: 14개월 차

한 줄 요약

AI 샌드박스의 힘을 발견하다

처음 방문하셨나요?

안녕하세요, 저는 Michael입니다. 소프트웨어 개발자이자 작은 인디 테크 비즈니스를 운영하는 창업자입니다. 현재 Refactoring English: Effective Writing for Software Developers라는 책을 집필하고 있습니다.

매달 이렇게 회고를 발행해 책 작업이 어떻게 진행되고 있는지, 그리고 전반적인 근황을 공유하고 있습니다.

하이라이트

  • 책 독자를 찾기 위한 새로운 전략이 긍정적인 성과를 내고 있습니다.
  • AI 에이전트를 제한 없이 실행해 보며 돌파구를 경험했습니다.
  • 후회했던 기술 스택 선택을 AI로 바로잡고 있습니다.

목표 달성 평가

매달 초에 이루고 싶은 목표를 정합니다. 이번 달 목표 달성 결과는 다음과 같습니다.

Refactoring English 챕터 3개 발행하기

  • 결과: 신규 챕터 2개 발행
  • 등급: B-

지난달과 마찬가지로 AI 실험에 너무 몰두한 나머지 집필 시간을 잠식당하는 문제가 여전합니다.

2025년 연간 회고(8년 차) 발행하기

완료했습니다! 결과물에 만족합니다. 관성이나 시의성 때문에 특정 시점까지 발행해야 한다는 압박을 느꼈던 연재 글을 이제 모두 마무리했습니다.

Refactoring English 지표

지표2025년 12월2026년 1월변화
순 방문자 수2,26638,511+36,245 (+1600%)
사전 주문 수익$492.55$1,132.75+$640.20 (+130%)
스폰서 수익$48.25$0.00-$48.25 (-100%)

1월 초에 “The Most Popular Blogs of Hacker News in 2025”를 발행했는데, 기대를 훨씬 뛰어넘는 성과를 거두었습니다. 덕분에 1월은 지난해 킥스타터 이후 가장 높은 방문자 수와 수익을 기록했습니다.

다른 수익은 감소했습니다. 편집 의뢰가 없었고, TinyPilot의 현 소유주가 2025년을 끝으로 책 후원을 종료했기 때문입니다. 기업들의 관심이 크지 않고 독자에게 집중하는 편이 더 효율적이라, 앞으로 기업 스폰서는 더 이상 적극적으로 찾을 계획이 없습니다.

다른 작가에 대해 쓰며 얻은 성공

“The Most Popular Blogs of Hacker News in 2025”는 제가 약 6개월간 시도해 온 전략의 연장선에 있습니다. 한마디로 요약하면, 다른 소프트웨어 작가들을 조명하는 것입니다.

작년 여름 파티에서 자비 출판을 하는 로맨스 소설가를 만났습니다. 다루는 주제는 전혀 달랐지만 비슷한 고민을 하고 있어 이야기가 흥미로웠습니다.

어떻게 독자를 찾느냐고 물었더니, 그녀는 “그게 바로 핵심 질문이죠!”라고 답했습니다.

그녀는 주로 인디 작가들의 로맨스 소설을 리뷰하는 뉴스레터를 시작해 큰 성과를 얻었다고 했습니다. 이를 통해 선순환이 만들어졌습니다.

  1. 독자가 뉴스레터를 읽고 그녀의 책을 발견해 구매합니다.
  2. 다른 인디 작가들이 자신의 작품 리뷰를 반기며 자신의 독자를 그녀의 뉴스레터로 안내하고, 이는 (1)을 더욱 키웁니다.
  3. 구독자는 뉴스레터를 통해 다른 흥미로운 소설을 발견합니다.

모두에게 인센티브가 일치하는 전략을 좋아해서, 이를 제 책에 적용할 방법을 고민하기 시작했습니다. 제가 좋아하는 다른 블로거와 저자에 대해 글을 써서 블로그에 올리기 시작했고, 반응이 좋았습니다.

순 독자 수Hacker News 점수Lobsters 점수
The Most Popular Blogs of Hacker News in 202533.8k692-
The Software Essays that Shaped Me25.6k30885
What Makes the Intro to Crafting Interpreters so Good?3.5k-137

AI 샌드박스의 힘을 발견하다

1년 전 처음으로 AI 에이전트를 사용했을 때 큰 깨달음을 얻었습니다. 당시에는 파일을 수정하는 모습을 옆에서 지켜보는 정도였는데도 LLM에 이 정도 권한을 주는 것이 무서울 정도라고 생각했습니다.

지난 1년간은 주로 VS Code의 AI 에이전트 확장인 Cline으로 코딩했습니다. 작업 속도가 많이 빨라지긴 했지만, 개발 머신에서 임의의 작업을 수행하도록 신뢰할 수 없어 세세하게 통제했습니다.

몇 주 전 친구 okay가 OpenAI의 터미널 기반 AI 에이전트인 Codex를 활용한 자신의 AI 워크플로를 보여주었습니다. okay는 Codex가 직접적인 감독 없이 파일을 수정하고 명령어를 실행하도록 둡니다. 이를 보고 제가 AI 에이전트를 일일이 돌보며 Cline의 멈춤 현상을 처리하느라 얼마나 많은 시간을 낭비했는지 깨달았습니다.

okay는 가끔 Codex를 한 시간 이상 방치해 둔다고 했는데, 믿기 어려웠습니다. Cline에 10분 이상 걸리는 작업을 맡기면 UI가 멈추거나 엉뚱한 방향으로 가거나 비용이 폭증하곤 했기 때문입니다. 하지만 Codex는 토큰당 과금이 아니라 정액제라 비용을 신경 쓰지 않아도 됩니다.

여전히 어떤 AI 에이전트도 실제 컴퓨터에서 마음대로 돌아다니도록 신뢰하지는 않기에, 머신에서 AI 에이전트를 실행하기 위한 커스텀 샌드박스를 만들었습니다. 프로젝트 디렉터리로 이동해 커스텀 명령어인 sb를 실행합니다. 그러면 로컬 네트워크에 접근할 수 없고 현재 작업 디렉터리만 볼 수 있는 rootless Podman 컨테이너가 생성됩니다. 컨테이너에는 Codex와 Claude Code가 미리 설치되어 있고 제 계정으로 인증되어 있습니다.

AI가 샌드박스 안에 있으니 파일 수정, 애플리케이션 설치 등 모든 권한을 주어도 안심이 되었습니다.

정말 놀라운 차이였습니다!

AI 에이전트가 전체 권한으로 동작하는 모습을 보는 것은 또 하나의 전환점이었습니다. 이전에는 “지난 8년간의 수입을 막대그래프로 그려줘”라고 하면 30% 정도는 뭔가 어긋나게 구현했습니다. 제가 직접 결과를 확인하고 “아니, 막대가 어긋났어. 고쳐줘”라고 말해야 했습니다. 하지만 AI 에이전트가 샌드박스 안에서 root 권한을 가지면 테스트 서버를 띄우고 브라우저에서 페이지를 확인하며 작업을 완료할 때까지 스스로 반복할 수 있습니다.

그러다 Ralph Loops라는 것을 알게 되었습니다. 아직 명확한 설명을 찾지 못해 제가 하는 방식이 “공식” Ralph Loop가 맞는지 확신할 수 없지만, 제 방식은 이렇습니다. ralph-loop라는 bash 스크립트를 실행하는데, 내용은 이처럼 단순합니다.

#!/usr/bin/env bash

rm ALL-DONE.txt || true

while true; do
  cat AGENT-WORKFLOW.md | codex exec

  if [[ -f "ALL-DONE.txt" ]]; then
    echo "ALL-DONE.txt detected. Exiting."
    exit 0
  fi
done

그리고 AGENT-WORKFLOW.md는 이렇게 생겼습니다.

1. Pick the top task in TODO.md and begin work on it
   - If no actions remain, write a file called ALL-DONE.txt to the current
     directory, and exit.
1. Complete the task and delete the entry from TODO.md.
   - If the task is unachievable, explain why in the commit message.
1. Commit the changes with a detailed commit message explaining what you
   changed, why you changed it, and what impact it had.

그런 다음 TODO.md 파일을 만들어 할 일 목록을 적어 둡니다. 일부 작업에는 후속 작업을 생성하는 내용이 포함되어 있어, 에이전트가 진행됨에 따라 목록이 늘어나기도 하고 줄어들기도 합니다.

Ralph Loop 덕분에 AI 에이전트를 10시간 이상 무인으로 자율 실행할 수 있게 되었습니다. 아침에 컴퓨터로 돌아와 제가 자는 동안 에이전트가 맡긴 일을 모두 끝내 놓은 것을 보면 비현실적인 기분마저 듭니다.

AI는 코드 포팅에 탁월하다

지난 몇 달간 AI를 실험하며 가장 효과가 큰 경우는 다음과 같다는 것을 알게 되었습니다.

  1. 성공 기준을 객관적으로 정의할 수 있을 때.
    • 예컨대 “이 크래시의 원인을 찾아라”는 객관적이고 명확하지만, “이 랜딩 페이지를 더 좋게 만들어라”는 그렇지 않습니다.
  2. AI 에이전트가 성공 여부를 스스로 검증할 수 있을 때.
    • 예컨대 “브라우저에서 페이지를 열고 버튼을 눌렀을 때 배경이 파란색으로 바뀌는지 확인하라”와 같습니다.
  3. 주니어 수준의 소프트웨어 지식을 가진 사람이라도 검색과 실험, 인내심으로 해결할 수 있는 문제일 때.

이러한 기준을 충족하는 소프트웨어 작업 유형은 다음과 같습니다.

  • 자동화된 테스트가 있는 코드 리팩터링
  • 동작을 유지한 채 한 언어/기술에서 다른 언어/기술로 코드 포팅하기
  • 소스에서 프로젝트를 빌드하고 필요한 의존성 설치하기
  • 테스트를 통과하도록 코드 수정하기

최근에는 AI로 코드 포팅을 하고 있습니다. 기술 스택을 다르게 선택했으면 좋았을 코드베이스가 몇 개 있는데, 전부 다시 작성하자니 늘 시간이 너무 많이 들었습니다. 하지만 AI를 이용하면 스택의 일부를 교체하는 작업이 저렴하고 빨라집니다.

여러 프로젝트에서 코드 포팅에 성공했습니다.

  • Zestful 웹사이트를 Vue/Nuxt2에서 Hugo 기반 바닐라 HTML로 변환했습니다.
    • 들어본 적도 없는 전이(transitive) Node.js 라이브러리를 통한 어이없는 취약점이 있다는 GitHub 알림을 받았습니다. “다시는 이런 알림을 보고 싶지 않다”는 생각이 들어 AI에 사이트를 Hugo와 일반 HTML/JS/CSS로 다시 작성하도록 했습니다.
  • PicoShare의 CSS 프레임워크를 Bulma에서 Bootstrap으로 포팅했습니다.
    • PicoShare를 만들 당시 Bulma를 한번 써보고 싶었습니다. 나쁘지 않았지만 저는 Bootstrap을 더 선호해서 다른 곳에서는 계속 Bootstrap을 썼고, PicoShare를 작업할 때마다 감을 다시 잡아야 했습니다.
  • LogPaste의 e2e 테스트를 Cypress에서 Playwright로 변환했습니다.
    • Playwright를 알기 전에 e2e 테스트를 작성했는데, 이제는 Playwright에 너무 익숙해져 Cypress로 돌아가기가 어렵습니다.
  • fusion RSS 리더를 Svelte에서 바닐라 HTML + Go 템플릿으로 변환했습니다.
    • fusion은 제 프로젝트가 아니라 단순한 개념 검증이지만, 제가 선호하는 기술 스택으로 포크해 보고 싶었습니다. AI가 모든 Svelte 코드를 바닐라 HTML과 Go 템플릿으로 잘 변환해 주었지만, 실제로 포팅하려면 테스트 인프라를 더 갖춰야 할 것 같습니다.
  • MeshCore 웹 앱을 Vue.js에서 Flutter로 변환했습니다.
    • 이 작업은 “AI가 결과를 검증할 수 있다”는 단계가 빠져 있어 실제로는 잘 되지 않았습니다. Flutter가 웹 앱 출력으로 시맨틱 HTML을 생성할 줄 알았는데, 실제로는 엉뚱한 Flutter 중심의 HTML 방언을 생성했습니다. 게다가 MeshCore 앱은 외부 하드웨어 장치(LoRa 무전기)에 크게 의존해서 제가 계속 개입해야 했습니다.

사이드 프로젝트

StreamPreserve

휴대폰으로 꼭 기록하고 싶은 장면을 목격했는데, 누군가 휴대폰을 빼앗아 영상을 삭제하거나 휴대폰 자체를 파손할 가능성이 있는 상황을 상상해 보았습니다.

그래서 중요한 영상을 신속하게 원격의 안전한 서버로 옮기는 웹 앱인 StreamPreserve를 만들었습니다.

StreamPreserve는 중요한 영상을 캡처해 가능한 한 빨리 원격 서버로 옮깁니다.

동작 방식은 다음과 같습니다.

  1. StreamPreserve 앱을 열고 녹화를 시작합니다.
  2. 앱은 가용 대역폭에 맞춰 스트림 품질을 조정하며 저해상도 영상을 백엔드 서버로 스트리밍합니다.
  3. 앱은 고해상도 영상을 개별 청크 단위로 브라우저 저장소에 기록합니다.
  4. 남는 대역폭으로는 스트리밍을 계속하면서 고해상도 영상 청크를 서버에 업로드합니다.
  5. 녹화가 중지되면 앱은 고해상도 영상을 로컬 기기에 다운로드 파일로 저장합니다.
  6. 앱이 열려 있고 녹화 중이 아닐 때는 기기에 있는 모든 고해상도 영상을 서버로 동기화합니다.

즉, 무언가를 녹화하다 누군가 제 휴대폰을 부숴도 StreamPreserve 서버에는 저해상도 사본이 남아 있게 됩니다. 누군가 녹화를 막기 위해 휴대폰을 빼앗더라도 웹 앱이 백그라운드에서 고해상도 영상을 계속 업로드합니다.

몇 가지 단점을 깨닫고 나서는 아이디어에 대한 열정이 식었습니다.

  • 수 시간 분량의 영상을 녹화하기에는 부적합합니다.
  • 웹 앱으로 구현하면 복잡성이 커지고 영상을 잃을 가능성이 생깁니다. 네이티브 모바일 앱으로 만들어야 하는데, 저는 모바일 개발을 좋아하지 않습니다.
  • 브라우저 카메라 API에 의존하는데, AI 샌드박스에서 이를 가짜로 구현하기가 까다로워 AI가 맡기에 좋은 작업이 아닙니다.

마무리

완료한 일

배운 점

  • 다른 소프트웨어 작가들을 조명하면 새로운 독자를 찾는 데 도움이 됩니다.
  • AI 에이전트는 root 권한으로 애플리케이션을 설치하고 웹을 검색할 수 있는 환경에서 훨씬 더 유용해집니다.
  • 성공 기준을 객관적으로 정의할 수 있고 에이전트가 성공 여부를 검증하며 반복을 통해 스스로 교정할 수 있을 때 AI는 문제 해결에 뛰어납니다.
  • AI는 한 기술에서 다른 기술로 코드를 포팅하는 데 탁월합니다.

다음 달 목표

  • Refactoring English 챕터 2개 발행하기.
  • Refactoring English 독자를 위한 라이브 이벤트 일정 잡기.

원문은 Michael Lynch님이 에 게재했습니다.

이 글은 muse-spark-1.2-contributor 모델을 사용해 번역했습니다.