LLM으로 소프트웨어 개발하는 나만의 워크플로우
How I write software with LLMs
TL;DR Highlight
수만 줄 규모의 실제 프로젝트를 LLM으로 유지보수 가능하게 개발해온 개발자가 구체적인 워크플로우(Architect→Developer→Reviewer 파이프라인)와 실제 세션을 공개한 글. LLM 코딩에서 결함률을 낮추고 시스템 이해도를 유지하는 방법을 다룬다.
Who Should Read
LLM을 활용해 실제 프로젝트를 개발하고 있거나 시작하려는 개발자, 특히 LLM이 생성한 코드가 며칠 뒤 엉망이 되는 경험을 해본 사람.
Core Mechanics
- 저자는 '프로그래밍을 좋아했던 게 아니라 무언가를 만드는 것을 좋아했던 것'이라 깨달았고, LLM이 코딩을 잘하게 된 이후 오히려 더 많이 만들게 됐다고 말한다. 핵심은 코드 작성 능력보다 시스템 아키텍처 설계 능력이 더 중요해졌다는 점이다.
- 초기 LLM 시절엔 코드 한 줄 한 줄을 검토해야 했고, 그 다음 세대엔 함수 단위 검토가 필요했는데, 지금은 '전체 아키텍처' 수준으로만 검토하면 되는 수준까지 왔다. 저자는 내년쯤엔 그것도 필요 없어질 수 있다고 본다.
- 저자의 핵심 워크플로우는 Architect → Developer → Reviewer 3단계 파이프라인이다. 먼저 아키텍트 역할의 LLM과 최대 30분씩 대화하며 목표, 제약, 트레이드오프를 명확히 하고, 구현 계획을 plan 파일로 저장소에 남긴다.
- 개발자 역할 LLM에게 plan 파일을 넘겨 코드를 생성하게 하고, 이후 여러 개의 리뷰어 LLM이 보안, 성능, 코드 품질 등 각기 다른 관점에서 검토한다. 리뷰어를 단일 모델이 아닌 복수로 운영하는 점이 특징이다.
- 기술을 잘 아는 도메인(백엔드 앱 등)에서는 수만 SLoC(실제 코드 줄 수)까지 늘어나도 코드가 엉망이 되지 않았지만, 잘 모르는 기술(모바일 앱 등)에서는 여전히 빠르게 나빠졌다. 즉, LLM 코딩에서도 도메인 지식은 여전히 필수다.
- 저자가 이 방식으로 만든 프로젝트 중 가장 큰 것은 'Stavrobot'으로, 보안에 초점을 맞춘 LLM 개인 비서다. OpenClaw의 대안으로 만들었으며, 캘린더 관리 등을 처리하고 매일 실제로 사용 중이다.
- 모델 선택에서도 역할별로 다른 모델을 쓴다. Codex 5.2와 Opus 4.6 등을 언급하며, 각 단계(설계/구현/리뷰)에 적합한 모델이 다를 수 있다고 본다. GitHub Copilot Pro를 통해 여러 모델에 저렴하게 접근하는 방법도 언급한다.
- 코드 품질을 높이는 핵심은 코드를 작성하기 전에 설계에 충분한 시간을 투자하는 것이다. 프롬프트가 모호할수록 LLM이 생성하는 결과물의 분포가 넓어지고(원치 않는 구현이 나올 확률 증가), 설계 단계에서 맥락을 충분히 제공할수록 원하는 결과에 가까워진다.
Evidence
- Architect→Developer→Reviewer 파이프라인의 실제 효과에 의문을 제기하는 댓글이 있었다. Opus를 프로덕션 에이전트로 매일 사용하는 개발자는 '좋은 컨텍스트와 명확한 방향을 주면 단일 모델 단일 세션으로도 충분히 좋은 결과가 나온다. 역할을 나누는 게 제어감을 주는 것 같지만 단일 모델이 놓쳤을 에러를 실제로 더 잘 잡는다는 증거가 없다'고 지적했다.
- 반대로 '코드를 작성하기 전 설계에 충분한 시간을 쓰는 것이 가장 큰 차이를 만든다'는 의견도 있었다. 모델은 가능한 모든 구현에 대한 확률 분포를 갖고 있는데, 프롬프트가 모호하면 분포가 넓고 결과가 일반적이 된다. 설계 단계에서 맥락을 계속 추가할수록 분포가 좁아져 원하는 구현에 수렴하게 된다는 설명이다.
- 'LLM과 대화하면서 시스템 이해도를 유지한다'는 주장에 의구심을 표하는 댓글도 있었다. LLM에게 코드를 만들고 다른 LLM이 리뷰해도 개발자 본인이 아키텍처를 이해하는 건 아니라는 지적이다. '코드를 한 번도 읽지 않으면서 아키텍처를 잘 안다'는 건 모순이라는 비판이다.
- 비슷한 워크플로우를 Notion 기반으로 구현한 사례가 공유됐다. 'Thinker' 에이전트가 질문하고 탐색해 Notion에 feature 페이지와 kanban 태스크를 만들면, 'Executor' 에이전트가 구현하고, QA 에이전트가 검토 후 사람 리뷰 컬럼으로 넘기는 방식이다. 모든 문서가 Notion에 있어 비즈니스 요구사항과 쉽게 연결된다고 한다.
- LLM 코딩의 코드 리뷰 문제를 지적하는 댓글이 있었다. 에이전트가 코드를 대량 생성하면 리뷰해야 할 코드량이 늘어나는데, 작성자와 리뷰어가 사실상 둘 다 LLM인 셈이라 실질적인 사람 검토가 줄어드는 역설이 생긴다는 우려다. 에이전트가 테스트를 자율적으로 실행할 수 있으면 결국 머신에 대한 전체 읽기/쓰기 권한을 주는 것과 다름없는데, 이를 샌드박스 없이 YOLO로 돌리는 건지 묻는 댓글도 있었다.
How to Apply
- 새 기능을 추가하거나 버그를 수정할 때, 바로 코드 생성을 요청하지 말고 먼저 아키텍트 역할로 LLM과 목표/제약/트레이드오프를 충분히 논의(최대 30분)하고 합의된 계획을 plan.md 파일로 저장소에 저장한다. 이후 별도 세션에서 해당 파일을 컨텍스트로 넣어 코드를 생성하면, LLM이 일관된 방향으로 코드를 작성할 가능성이 높아진다.
- 코드 생성 후 단일 리뷰 대신 보안, 성능, 코드 품질 등 관점별로 각각 다른 LLM 세션에서 리뷰를 요청해본다. 각 리뷰어에게 역할을 명확히 지정(예: '너는 보안 전문가로서 이 코드를 리뷰해라')하면 단일 리뷰보다 더 다양한 문제를 잡아낼 수 있다.
- LLM 코딩을 적용할 프로젝트를 고를 때, 자신이 기술 스택을 잘 아는 도메인부터 시작한다. 저자 경험상 모르는 기술(모바일 등)에서는 LLM이 만든 코드가 빠르게 나빠지지만, 잘 아는 기술(백엔드 등)에서는 수만 줄까지도 품질이 유지됐다. 도메인 지식이 LLM 코딩의 품질 보장 역할을 한다.
- 비용이 걱정된다면 GitHub Copilot Pro 플랜을 통해 Sonnet 4.6, Opus 등 여러 모델에 접근하는 방법을 검토한다. copilot-api 해킹이나 opencode 도구를 사용하면 Claude 클라이언트에서 Copilot 모델을 쓸 수 있고, 긴 세션에서 토큰 한도 문제가 생길 때 Claude와 opencode를 번갈아 쓰는 전략도 유효하다.
Terminology
SLoCSource Lines of Code의 약자. 주석이나 빈 줄을 제외한 실제 코드 줄 수를 세는 단위. 프로젝트 크기를 가늠하는 데 쓴다.
agentic codingLLM이 단순히 코드 조각을 제안하는 게 아니라, 파일을 읽고 수정하고 테스트를 실행하는 등 일련의 작업을 자율적으로 수행하는 방식의 코딩.
YOLO mode에이전트가 파일 수정, 코드 실행 등을 사람의 확인 없이 자동으로 수행하도록 허용하는 설정. 빠르지만 의도치 않은 시스템 변경 위험이 있다.
plan fileLLM과 설계 논의를 마친 뒤 구현 계획, 목표, 제약, 트레이드오프를 정리해 저장소에 저장하는 텍스트 파일. 다음 세션에서 컨텍스트로 활용한다.
probability distribution over implementationsLLM이 프롬프트를 받았을 때 가능한 코드 구현 방식들에 대해 갖는 확률 분포. 프롬프트가 구체적일수록 분포가 좁아져 원하는 결과가 나올 확률이 높아진다.
opencodeGitHub Copilot 등 여러 모델 제공자의 API를 지원하는 오픈소스 AI 코딩 도구. 긴 세션에서 Claude보다 스크롤 성능이 낫다는 평가가 있다.