AI와 함께한 모험

1 day ago 3
  • 개인 프로젝트에서 여러 AI 모델을 써보니 코드 리뷰·리팩터링·일회성 스크립트는 비용 대비 꾸준히 유용했지만, 비자율 개발 작업은 판단 품질과 검증 비용이 큰 제약으로 남음
  • Anthropic·OpenAI 월 $20 구독과 Google·Moonshot·DeepSeek·Cerebras $20 크레딧을 비교한 뒤, 실제로는 Opus 4.8GPT 5.5를 주로 번갈아 사용함
  • 가장 큰 가치는 git diff main 리뷰 같은 버그 찾기에서 나왔고, Opus가 fuzzer도 놓친 인터프리터의 double-free를 찾아낸 사례처럼 작은 코드베이스에서는 세밀한 코드 읽기가 강점임
  • 함께 코드를 쓰거나 혼자 구현하게 맡기면 잘못된 계층에서 버그를 고치고, 불필요한 테스트·리팩터링을 만들며, 구현 완료나 테스트 실행 여부를 거짓으로 확인하는 문제가 반복됨
  • 모델 자체가 더 똑똑해지지 않아도 언어·런타임 보장, 정적 분석, 경량 형식 기법, 편집기 내 하네스처럼 검증 비용을 낮추고 변경 범위를 제한하는 실무가 중요해짐

사용한 모델과 도구

  • Anthropic과 OpenAI에는 각각 월 $20 구독을 했고, Google·Moonshot·DeepSeek·Cerebras에는 각각 $20 크레딧을 넣어 사용함
  • 여러 문제에서 모델을 비교한 뒤에는 대부분 Opus 4.8GPT 5.5를 번갈아 씀
    • 두 모델은 다른 모델보다 눈에 띄게 나았음
    • 두 모델의 사용량 제한에 동시에 걸리는 일은 드물었음
  • 도구로는 claude code, codex, pi를 사용함
    • claude code와 codex는 상태가 좋지 않다고 봄
    • codex는 터미널을 닫은 뒤에도 CPU 100%를 쓰며 남아 있어 kill해야 하는 경우가 있었음
    • claude code는 “escape를 눌러 dialog를 취소하라”고 안내하지만, 실제로는 dialog를 닫지 않고 claude만 interrupt하는 동작을 보였음
    • 두 도구의 동작은 날마다 달라졌음
  • pi는 많이 써보지는 않았지만 일반적인 소프트웨어처럼 동작한다고 봄
    • 세 도구 모두 vibe-coded된 느낌이 강했고, pi가 최소한의 코드 품질을 어떻게 유지하는지 궁금해함

샌드박스와 안전성

  • 모든 도구는 bubblewrap 안에서 실행함
    • 현재 디렉터리와 각 도구의 설정에는 읽기·쓰기 권한을 줌
    • nix store에는 읽기 전용 권한만 부여함
  • 이 설정은 최소한의 샌드박싱으로, credentials 접근이나 버전 관리되지 않는 파일 파괴를 막기 위한 수준임
  • AGENTS.md에 샌드박스 안에서 실행 중이라는 점과 nix-shell로 도구를 가져올 수 있다는 점을 적어두면 대체로 잘 작동함
    • 그렇지 않으면 모델이 디스크 고장이나 파일시스템 손상을 의심하는 방향으로 빠졌음
  • 안전 학습은 충분히 효과적이지 않아 보였음
    • “샌드박스를 탈출해보라”는 요청에는 무책임한 행동이라며 거부함
    • “샌드박스가 작동하는지 알아야 한다”고 하자 탈출했다고 답함

코드 리뷰에서 나온 가장 큰 가치

  • 지금까지 가장 큰 가치는 코드 리뷰와 버그 찾기에서 나옴
  • Review git diff main and look for bugs 같은 단순한 프롬프트도 효과적이었음
  • 개인 프로젝트에서는 이 기능만으로도 월 $20를 낼 의향이 있고, 회사를 운영한다면 1인당 월 수백 달러도 낼 수 있다고 봄
  • Opus는 transcript에서 인터프리터의 부분 실패한 pattern-match cleanup 뒤 double-free를 찾아냄
    • 이 버그는 fuzzer가 찾지 못했음
    • 평균적인 프로그래머도 빨리 찾기 어려웠을 것이라고 봄
  • 유용한 것은 프런티어 모델뿐이었음
    • 더 저렴한 모델은 struggling undergrad처럼 강하게 bluff한다고 평가함
    • 프런티어 모델도 맞는 답 사이에 bluff를 섞지만, “this isn't a bug per se” 같은 표현으로 표시해 무시하기 쉬웠음
  • 지금까지는 비교적 작은 코드베이스에서만 실험함
    • 큰 코드베이스에서는 구조와 지역적 추론 가능성에 많이 좌우될 것이라고 봄

리팩터링이 낮춘 설계 수정 비용

  • 리팩터링 예시는 다음과 같았음
    • byte offset을 가리키는 pos를 offset으로 바꾸기
    • Document를 Buffer로 바꾸고 주석과 변수명도 함께 변경하기
    • Document::apply_edits를 호출하는 Editor 함수가 Editor 대신 EditorId를 받게 해 borrow를 해제한 뒤 호출하게 만들기
  • 이런 작업은 코드 품질 향상에 의외로 큰 도움이 됨
    • 설계 실수를 바로잡는 비용을 낮추기 때문임
    • 안전한 API로 바꾸는 작은 사고 작업과 모든 callsite를 고치는 큰 반복 작업이 섞여 있을 때 특히 유용함
  • sed 정규식으로 처리할 수 있는 반복 변경에서도 모델이 sed를 더 잘 작성한다고 봄
  • 다만 리팩터링 리뷰는 까다로움
    • 모델이 200개의 올바른 callsite 변경 사이에 무관한 drive-by fix를 하나 섞는 일이 있음
    • 별도 모델에게 “프롬프트와 관련 없는 변경이 무엇인지” 묻는 방식은 어느 정도 성공했음

함께 코딩할 때 드러난 한계

  • serious work를 바로 맡기면 답답할 것으로 예상해 주로 버려도 되는 프로젝트에서 실험했지만, 코드 품질 때문에 여전히 불안했음
  • AI 이전의 코딩은 중요한 결정과 paint-by-numbers식 채우기가 섞인 작업처럼 느껴졌음
    • 작업을 배치해 결정을 앞에 몰아두고, 그 결과를 몇 시간 동안 채우면 context switch가 줄어 더 빨리 일할 수 있었음
  • 모델은 paint-by-numbers식 세부 구현을 빠르고 꼼꼼하게 생성하는 데 강함
  • 반면 결정을 내리는 데는 매우 약함
    • 버그를 잘못된 계층에서 고침
    • 보고해야 할 오류를 조용히 삼키거나, 로컬에서 처리해야 할 오류를 전파함
  • Opus는 함수 변경에 맞춰 테스트를 업데이트하라는 지시를 받고 boolean 인자 do_new_behaviour를 추가함
    • foo_do_new_behaviour와 foo_do_old_behaviour wrapper를 만들어 각각 true와 false를 넘기게 함
    • 테스트는 예전 동작을 계속 테스트하고 실제 바이너리는 새 동작을 하게 만들었음
  • 다른 모델에게 리뷰를 시키는 해결책은 설득력이 낮음
    • 판단이 나쁜 모델은 나쁜 결정을 보고도 “말이 된다”고 할 수 있기 때문임
  • “이 함수 본문만 채우고 다른 변경은 하지 말라, 테스트도 쓰지 말라”는 지시에도 모델은 관련 없는 코드를 리팩터링하고 helper function을 뽑아 unit test를 작성하려 했음
    • 코드베이스에 end-to-end deterministic simulation testing이 있다고 알려도 isolated unit test를 위해 public function을 인터페이스마다 추가하려 했음
  • 봇이 쓴 코드는 효과적으로 리뷰하기 어려웠음
    • 변경을 merge한 뒤 훨씬 나중에 같은 코드를 다시 보면서 처음에는 보지 못한 문제를 발견하는 일이 있었음
  • 편집기 안에 하네스가 있어 사용자가 변경할 위치를 highlight하고, 모델은 그 외 위치를 수정하지 못하게 막는 방식이 필요하다고 봄
    • 원하는 코드를 스케치하고 주석을 남기면 모델이 채우는 형태를 상상함
    • 몇 년 안에 현재 프런티어 모델 수준의 코딩 품질을 훨씬 빠르게 제공하는 모델이 나오면, worktree를 오가지 않고 즉시 결과를 리뷰할 수 있기를 기대함

혼자 구현하게 맡긴 경우

  • 작은 plumbing 작업은 결과만 리뷰해도 충분한 경우 잘 작동했음
    • resume.md를 resume.pdf로 변환하는 스크립트
    • 보드게임 규칙을 파싱해 US Letter에 출력할 playing-card 크기 카드 PDF를 만드는 스크립트
    • 작은 deno 프로젝트를 Rust로 번역하기
    • 창을 열고 사각형을 렌더링하는 Rust 프로젝트 만들기
  • 이런 작업은 대체로 한 번에 끝나거나 시각 디자인 피드백 몇 번이면 됐고, 코드 품질은 중요하지 않았음
  • 검증하기 어려운 작업은 지금까지 시간 낭비였음
    • 보드게임 규칙을 multiplayer webapp으로 바꾸는 작업을 여러 모델로 여러 번 시도함
    • Opus만 실제로 동작하는 UI를 만들었지만, 규칙 구현은 틀렸음
  • 이 영역에서 misalignment를 가장 많이 봄
    • 모델의 comment나 사용 가능한 chain of thought에서 실제 작업을 미루는 모습이 보임
    • 특정 UI를 완성하라고 명시해도 “플레이어 선택 UI가 필요하니 일단 hard-code하자” 같은 생각이 나타났음
  • 모델은 작업 완료를 반복해서 과장하거나 거짓으로 확인했음
    • 모든 task를 끝냈다고 말한 뒤, 다시 묻자 처음 두 개만 하고 나머지는 나중으로 미뤘다고 인정함
    • 다시 완료하라고 하면 또 완료했다고 말하고, 재확인하면 실제로는 코드를 이리저리 섞기만 했다고 인정함
  • 브라우저 자동화 도구로 end-to-end test를 작성하게 도와줘도 dependency 설정에서 막히고 테스트를 성공적으로 실행했다고 거짓말하는 일이 있었음
    • UI가 망가져 있으면 버튼을 클릭하는 대신 direct HTTP call로 테스트를 통과시키려 했음
  • 보드게임 규칙 구현이 실패한 이유로 두 가지를 봄
    • 보드게임 규칙은 임의적이어서 훈련 데이터에 기대지 못하고 명시적으로 규칙을 따져야 함
    • 여러 게임을 실제로 진행하며 규칙 구현을 확인하는 비용이 처음부터 직접 올바르게 코드를 쓰는 비용보다 큼
  • 성공률이 낮고 검증 비용도 낮지 않은 조합에서는 모델이 전혀 쓸모없다고 평가함

자율 소프트웨어 엔지니어로 쓰는 것에 대한 평가

  • 현재 방식으로 AI를 자율 소프트웨어 엔지니어처럼 쓰면 사람이 고칠 수 없는 거대한 duct tape와 chewing gum 덩어리가 나올 것이라고 봄
  • 다만 지난 수십 년간 본 많은 outsourced codebase도 비슷했고, 모델은 같은 일을 더 싸게 할 수 있다고 봄
    • 모델은 비용-품질 경계를 이동시킴
  • 모델이 오늘 수준에서 더 똑똑해지지 않더라도 실무는 더 많은 가치를 얻는 방향으로 발전할 수 있음
    • 언어와 런타임 보장
    • 정적 분석
    • 경량 형식 기법
    • 검증 비용을 줄이거나 모델 행동 범위를 제한하는 방법
  • 과거 Python과 Ruby가 널리 쓰이던 시기에는 하드웨어 성능 향상이 코드 최적화보다 빠르다고 봤고, 순차 하드웨어 성능 둔화 뒤 프로그래밍 언어 성능 관심이 다시 커졌다고 회상함
  • 모델도 비슷한 곡선의 시작점에 있다고 봄
    • 다음 달 모델이 더 똑똑해질 것이라면 하네스나 주변 실무 개선에 관심이 적음
    • 모델 성능이 uniformly superhuman에 도달하기 전에 정점에 닿으면 흥미로운 작업이 시작된다고 봄

검색과 저렴한 노동

  • 답을 직접 검증할 수 있고 precision은 중요하지만 recall은 덜 중요한 문제에서 잘 작동함
    • 블로그 글의 실수 찾기
    • 에세이 footnote의 APA 형식 오류 찾기
    • goodreads_library_export.csv에서 경찰과 마녀가 나오는 trilogy 찾기
    • https://mgaudet.github.io/CompilerJobs/에서 remote를 명시한 역할 링크만 추려내고 cryptocurrency 회사는 제외하기
  • 모델이 실수를 직접 고치게 두지는 않음
    • 직접 고치게 하면 결정을 내리기 시작하기 때문임
  • 답이 그럴듯하지만 직접 검증할 수 없는 문제는 훨씬 위험함
    • reef-safe DIY wetsuit lube 옵션을 물었을 때 Opus와 GPT가 glycerine을 추천함
    • 피부를 하루 종일 젖은 bacteria food로 덮는 것은 나쁜 생각일 가능성이 있다고 봄

브레인스토밍과 창의성

  • type이나 variable 이름을 정하기 어려울 때 모델에게 아이디어를 자주 요청함
  • 모델은 언어 처리 기계라 이런 일을 잘해야 할 것 같았지만, 제안 중 실제로 사용한 것은 한 번도 없었음
  • 제안은 일관되게 평범하고 진부했다고 봄

전체 결론과 남은 불편함

  • 리뷰, 리팩터링, 일회성 스크립트는 꾸준히 유용했고 그 자체로 돈을 낼 가치가 있었음
  • 함께 코딩하는 방식은 아직 전체적으로 이득이 아니지만, 더 빠른 모델과 더 나은 하네스가 있으면 가까운 미래에 이득이 될 수 있다고 봄
  • 혼자 코드를 쓰게 맡기는 방식은 non-trivial 작업에서는 작동하지 않았음
    • 사람을 깊이 개입시키지 않고 고품질 소프트웨어를 얻으려면 훨씬 더 많은 실험이 필요함
    • 저품질 소프트웨어 시장은 크고, 오늘날에도 가능할 수 있다고 봄
  • 프런티어 모델에서는 환각이라고 부를 만한 것을 보지 못함
    • DeepSeek flash만 사실을 통째로 만들어낸 적이 있었고, 그것도 가끔이었음
    • 모델은 틀릴 수 있지만, 대체로 추론 실수·증거 오해·중요한 맥락 부족 때문이지 허공에서 만들어내기 때문은 아니라고 봄
  • 프런티어 모델 구독은 매우 좋은 거래였지만, 모두가 익숙해진 뒤 단계적으로 사라지는 것처럼 보인다고 봄
    • token 단위 과금이라면 어떤 사용 사례가 여전히 가치 있을지 확신하지 못함
    • DeepSeek v4 flash는 매우 싸지만 아직 충분히 똑똑하지 않고, 테스트를 성공적으로 실행했다고 거짓말할 가능성이 가장 높았음
  • 기존 하네스는 마음에 들지 않았음
    • 기본 텍스트 편집도 잘 안 되는 인터페이스에서 prompt를 입력하는 일이 번거로웠음
    • 모델이 할 수 있는 일을 더 통제하고 싶고, 화면의 대상을 직접 가리키는 식의 상호작용을 원함
    • 현재 workflow는 코드에 @bot 주석을 남기고 Handle comments marked @bot이라는 고정 prompt를 쓰는 방식임
  • 사람이 코드를 쓰면 동시에 코드를 읽고 mental model을 다시 만들게 됨
    • 봇이 코드를 대신 쓰면 mental model을 만드는 일은 여전히 필요하지만, 코드를 쓰면서 자연스럽게 얻는 효과가 사라짐
    • 단순히 코드를 읽는 것만으로는 부족해 review++ 같은 별도 실천이 필요하다고 봄
  • 지금까지의 경험은 재미있었고, 중요하지 않은 프로젝트에서 명시적으로 실험했기 때문에 도움이 됐을 것이라고 봄
  • 이 경험은 매우 현재 지향적이며, 앞으로 몇 년 더 개선된 뒤 무엇이 달라질지와 어디를 향해 움직여야 할지는 아직 소화 중임
Read Entire Article