이름은 나중에 왔다 — Jira 티켓에서 PR까지, AI 개발 루프를 만든 이야기

2025년 초 Claude Code가 출시되고 지금까지, 개발자로서 제가 일하는 방식은 꾸준히 바뀌고 개선되고 있습니다.
그러다가 2026년 올해 초에 내가 일하는 방식에 무언가 반복되는 패턴이 있다는 것을 깨닫게 되었고 이 반복 패턴 자체를 시스템으로 만들어보면 어떨까 하는 생각이 들었습니다. 그래서 저는 지난 3월부터 저만의 AI Agent system을 조금씩 만들기 시작했습니다. 그로부터 4개월이 지난 지금 어느 정도 유의미한 결과를 내고 있습니다.
이 글은 2025년 초부터 시작된 AI Agent 개발 경험이 올해 초에 어떻게 다른 방향으로 분화되기 시작했는지, 그리고 그 결과를 두고 느낀 제 개인적인 감상과 평가를 담고 있습니다. 최근의 AI Agent의 발전 방향성이 제 생각과 얼마나 유사한 방향으로 가고 있는지도 다룹니다.
1. Claude Code와 함께한 1년
Claude Code가 베타 버전으로 출시된 것이 2025년 2월입니다. 저는 3월부터 claude code를 유료로 사용하기 시작했습니다.
처음 claude code를 설치하고 몇 번의 턴을 거쳐 대화를 진행하며 아주 간단한 코드 수정을 했던 것이 기억에 납니다. 저는 자연어로 지시만 하고 직접적인 코드 수정은 claude code가 하는 방식. 그리고 그 간편함과 강력함에 적지 않은 충격을 받았던 것도 아직까지 제 기억에 남아 있습니다.
그 후로 저는 이 방식을 적극적으로 차용했습니다. 처음엔 버그 수정과 간단한 기능 추가만 AI에게 맡기고 약간 복잡한 로직 작성은 제가 담당했습니다. 그러다가 Claude 모델의 성능이 비약적으로 향상되면서 점차 사람과 AI가 작성하는 코드의 비율이 역전되기 시작하더니 현재(2026년 7월 기준)는 AI가 작성하는 코드의 비율이 거의 99%에 달하는 상태입니다.
1년 정도 이 방식으로 일해오면서 일정한 패턴의 반복을 느끼게 되었습니다. 모든 작업의 시작은 너무 당연하게도 사람인 저의 프롬프트 입력에서부터 시작합니다. claude code 신규 세션에 해결할 문제를 차분하게 입력하기 시작합니다. 어쩔 때는 모든 내용을 제가 직접 텍스트로 입력하기도 하고 또 어떤 경우는 Jira ticket 번호만 주고 Atlassian MCP로 구체적인 내용을 읽도록 지시하기도 합니다.
그리고 엔터를 치면 Claude Code는 내부적으로 본인만의 Loop를 돌면서 문제 해결을 시도합니다. 수십 또는 수백 번의 내부 turn을 거치면서 코드를 수정하거나 새로 만들고 막히는 경우 사람에게 역으로 질문(Ask)하기도 합니다. 문제를 최종적으로 해결하기까지 사람과 AI의 대화는 적게는 한 번, 많게는 수십 번까지 반복됩니다.
사람의 입력 → AI의 action → 사람의 검증 → 다시 사람의 입력 (반복)
마치 턴제 게임과 같이 사람 한 번, AI 한 번 turn을 소모하면서 작업이 진행됩니다. 그리고 마지막에 가서는 사람이 문제가 해결되었다고 판단하게 되는 순간 Loop가 종료됩니다. (물론 문제가 해결되지 않고 종료되는 경우도 더러 있긴 합니다)
Claude 모델의 성능이 갈수록 좋아지면서 이 방식의 작업물 결과가 계속 좋아졌던 것은 맞습니다. 그러나 이상하게도 일의 본연 그 자체는 AI가 하고 사람인 저는 일의 땔감을 나르는 역할만 수행한다는 느낌을 지울 수 없었습니다. 티켓이 바뀌어도 순서는 늘 같았습니다. Jira를 열어 티켓을 읽고, 어느 저장소의 어느 모듈을 고칠지 판단하고, 맥락을 조립해 전달하고, 결과를 확인해 커밋과 PR을 만드는 것. 물론 AI의 결과물을 리뷰하는, 가장 중요한 일은 여전히 사람의 몫이었습니다. 하지만 정작 제 시간은 리뷰보다 땔감을 나르는 데 더 많이 쓰이고 있었습니다.
저는 이 반복되는 일에 제 시간을 쏟고 싶지 않았습니다. 사람이기에 실수할 수도 있고, 무엇보다 이런 반복 작업은 너무 지루했기 때문입니다.
2. Symphony — 문제에 구조가 생긴 순간
2026년 3월, GitHub에서 낯선 저장소 하나를 발견했습니다. OpenAI의 Symphony였습니다.
Symphony는 OpenAI가 공개한 Codex 오케스트레이션 스펙입니다. 처음에는 스펙 문서만 공개되어 있어서 Codex나 Claude Code로 직접 구현해 볼 수 있도록 스펙만 제시하는 간단한 프로젝트였습니다.
동작 방식은 단순합니다. Linear 보드를 지켜보다가 열린 티켓을 발견하면 티켓마다 에이전트를 붙이고, 그 에이전트는 작업이 끝날 때까지 계속 돌아갑니다. 사람이 에이전트 세션을 열고 일을 넣어주는 것이 아니라, 보드가 일을 공급하고 시스템이 세션을 여는 구조입니다.
소개 문서와 SPEC.md를 읽어 내려가면서 "이거다"라는 생각이 들었습니다. 새로운 문제를 발견한 것이 아니었습니다. 1년 내내 겪었지만 명확하게 표현하지 못했던 문제 — 제가 매일 나르던 그 땔감 — 에 구조가 생기는 순간이었습니다.
제가 Symphony에서 가져온 것은 세 가지 관점입니다.
첫째, 작업의 기본 단위는 코딩 세션이 아니라 티켓이라는 것. 그동안 저는 세션 단위로 일했습니다. 세션을 열고, 티켓 내용을 옮겨 담고, 결과를 확인하고, 세션을 닫는 식이었죠. Symphony는 이것을 뒤집습니다. 티켓이 곧 실행 단위이고, 세션은 티켓을 처리하기 위한 일회용 도구일 뿐입니다.
둘째, 프로젝트 관리 보드가 코딩 에이전트의 control plane이 될 수 있다는 것. 보드는 이미 회사의 모든 일이 모이는 곳입니다. 우선순위, 상태, 담당자, 요구사항이 전부 거기에 있습니다. 그렇다면 에이전트에게 일을 시키는 인터페이스를 새로 만들 필요 없이, 보드 그 자체를 쓰면 됩니다. 사람의 역할은 에이전트 세션을 관리하는 것에서, 보드에 좋은 티켓을 쓰고 결과물을 검토하는 것으로 옮겨갑니다.
셋째, 작업의 시작을 사람이 하지 않아도 된다는 것. 작업 티켓은 사람이 공들여서 작성하는 경우도 있지만 다른 시스템이 자동으로 만들 수도 있습니다. 곧 사람뿐 아니라 시스템도 스스로 작업을 시작시킬 수 있다는 뜻입니다.
다만 Symphony를 그대로 가져다 쓸 수는 없었습니다. Symphony는 Linear와 Codex 사용을 전제로 한 프로젝트로서, OpenAI 스스로도 제품으로 유지보수할 계획이 없는 레퍼런스라고 밝혔습니다. 반면 우리 회사의 일은 Jira에 있고, 저장소 구조도 빌드 방식도 전혀 다릅니다. 그래서 저는 코드가 아니라 위의 관점들을 가져와, 회사 환경에 맞는 시스템을 처음부터 직접 만들기로 했습니다.
3. 한 달 만에 만든 루프의 뼈대
새로 만드는 시스템의 이름은 jira-autopilot으로 정했습니다. 회사는 Linear가 아닌 Atlassian Jira를 사용 중이기 때문에 Jira를 이슈 트래커로 삼았고 구현 언어는 제가 익숙하게 다룰 수 있는 TypeScript로 정했습니다. 또한 Codex가 아니라 Claude Code가 AI Agent를 담당하도록 했습니다. 회사에서는 Claude Code만 구독하고 있었기 때문입니다.
jira-autopilot을 만들기 시작하면서 저는 딱 하나의 기준을 세웠습니다.
최대한 작게 시작해서 조금씩 살을 붙여나가보자.
처음부터 병렬 처리나 토큰 사용량 관리 같은 것은 신경쓰지 않기로 했습니다. 완벽한 설계를 먼저 해놓고 구현을 시작하기 보다는 Hello world! 버전을 먼저 만드는 데 집중했습니다.
사실 만들어야 할 것이 무엇인지는 이미 알고 있었습니다. 1년 동안 제가 매일 반복하던 그 순서 — Jira를 열어 티켓을 읽고, 고칠 모듈을 판단하고, 맥락을 조립해 전달하고, 결과를 확인해 커밋과 PR을 만드는 것 — 가 그대로 시스템의 명세였기 때문입니다. 저는 저 자신을 관찰하며 코드를 썼습니다.
한 달 뒤 완성된 뼈대는 이렇게 움직입니다.
티켓 발견 → 맥락 수집 → 모듈 판단 → 코드 수정 → 빌드 검증 → 커밋 → PR 생성 → 결과 기록 → 다음 티켓 (반복)

상시 실행되는 Orchestrator가 30초 간격으로 Jira를 폴링합니다. 조건에 맞는 티켓이 발견되면 티켓 하나당 일회용 Docker 컨테이너를 하나 띄우고, 그 안에서 Claude Code가 헤드리스(비대화형) 모드로 실행됩니다. 에이전트는 티켓 본문을 읽고 어느 저장소의 어느 모듈을 고쳐야 할지 스스로 판단한 뒤, 코드를 수정하고, 빌드로 검증하고, 커밋과 PR을 만들고, 결과를 Jira 코멘트로 남기고 사라집니다.
각 구성요소는 제가 하던 반복을 하나씩 대신합니다. 폴링은 수시로 Jira를 열어 보던 저를, 모듈 판단은 "이건 어느 저장소 일이지?"를 고민하던 저를, 프롬프트 조립은 티켓 내용을 복사해 붙여넣던 저를, 빌드 검증과 PR 생성은 결과를 확인하고 마무리하던 저를 대신합니다. 1장에서 나르던 땔감의 목록이 그대로 시스템의 기능 목록이 된 셈입니다.
인프라는 최대한 새로 만들지 않았습니다. 별도의 작업 큐도, 상태 관리 시스템도 없습니다. Jira 티켓에 라벨을 붙이는 것으로 큐와 상태 머신과 잠금을 모두 해결했습니다. 처리 중인 티켓에는 처리 중 라벨이 붙어 다른 워커가 집지 않고, 완료·실패 라벨이 결과를 표시합니다. 보드가 곧 control plane이라는 둘째 관점을 그대로 구현한 것입니다.
격리 원칙도 하나로 정했습니다. 1 티켓 = 1 컨테이너 = 1 브랜치 = 1 PR. 티켓 하나의 실행은 다른 티켓과 완전히 분리되어, 하나가 실패해도 서로 오염되지 않습니다. 컨테이너는 작업이 끝나면 통째로 사라지므로 잔여물도 남지 않습니다. 그리고 에이전트는 일회용 컨테이너 안에 가두고 나가는 네트워크 트래픽까지 통제했는데, 어떻게 가뒀는지는 이 시리즈의 2편에서 자세히 다루겠습니다.
이렇게 해서 루프 안에 있던 사람은 루프 밖으로 나왔습니다. 매 턴마다 프롬프트를 입력하고 결과를 확인하던 사람의 자리는 루프의 양 끝으로 이동합니다. 사람이 하는 일은 두 가지로 압축됩니다. 티켓을 명확히 쓰는 것, 그리고 PR을 리뷰하는 것. 자동 머지는 없습니다. PR 생성은 작업의 완료가 아니라, 사람이 검토할 수 있는 결과물을 준비해 두는 단계입니다.
4월 초, jira-autopilot이 처음으로 혼자 PR을 만들었습니다. 제가 엔터를 치지 않았는데 만들어진 첫 PR이었습니다.
그리고 4월 27일, OpenAI가 Symphony를 공식 블로그로 발표했습니다.
코딩 에이전트를 감독하는 대신, 일을 관리하라. (manage work instead of supervising coding agents)
Symphony 저장소에 달린 소개 문구입니다. 이 발표를 봤을 때, jira-autopilot은 이미 몇 주째 회사 Jira 위에서 돌고 있었습니다.
4. 석 달의 확장 — 세 방향
처음부터 무거운 일을 맡긴 것은 아닙니다. 가동 초기에 넘긴 티켓은 간단한 버그 수정, 사소한 동작 개선, 설정 변경처럼 완료 조건과 검증 방법이 명확한 일들이었습니다. 처음부터 완전 자동화를 노린 것도 아니었습니다. 작은 일을 맡겨 보고, 실패하는 지점을 관찰하고, 검증 장치를 보강하면서 조금씩 맡기는 범위를 넓혔습니다.
돌이켜보면 이 확장은 세 방향으로 일어났습니다. 맡기는 일의 종류가 넓어졌고, 맡기는 일이 무거워졌고, 그리고 이 모든 것을 허가하는 안전장치가 함께 자랐습니다.
4.1. 맡기는 일의 종류가 넓어지다
시작은 코드였습니다. "이 필드의 기본값을 바꿔 달라", "이 화면의 안내 문구를 수정해 달라" 같은, 티켓만 명확하면 검증까지 한 번에 끝나는 일들이었습니다. 이런 티켓은 autopilot이 안정적으로 처리했고, 커밋과 PR 생성까지 문제 없이 수행했습니다.
코드 수정이 안정적으로 돌기 시작하자 분명해진 것이 하나 있습니다. 이 루프가 하는 일의 본질은 코드를 고치는 것이 아니라, 티켓을 읽고, 필요한 맥락을 모으고, 판단하고, 결과를 남기는 것이라는 점입니다. 결과가 꼭 PR일 필요는 없었습니다.
그래서 다음으로 맡긴 것은 CS(고객 문의) 티켓 분석이었습니다. CS 티켓의 처리는 대부분 조사 작업입니다. 과거의 유사 티켓을 찾아보고, DB 스키마를 확인하고, 실제 코드를 열어 원인을 좁히는 일이죠. 이 조사를 에이전트에게 맡겼습니다. 새 CS 티켓이 들어오면 에이전트가 과거 티켓 아카이브와 스키마와 코드를 뒤져 원인 분석 코멘트를 티켓에 달아 둡니다. 이 워크플로우는 코드를 한 줄도 수정하지 않습니다. 산출물은 PR이 아니라 코멘트이고, 사람은 그 분석을 검증하고 후속 조치를 결정하면 됩니다.
한 걸음 더 나아가, CS 티켓의 담당자 배정도 맡겼습니다. 새 티켓의 내용을 읽고 누구에게 가야 할 일인지 판단해 배정하고, 판단의 근거를 코멘트로 남깁니다. 단, 여기에는 원칙을 하나 박아 두었습니다. 확신이 없으면 배정하지 않는다. 잘못된 배정은 배정하지 않는 것보다 비싸기 때문입니다. 에이전트는 애매한 티켓 앞에서 "모르겠다"고 말하고 물러날 수 있어야 합니다.
autopilot에게 맡긴 일은 세 가지입니다.
| 맡긴 일 | 산출물 | 지켜야 할 경계 | 사람의 몫 |
|---|---|---|---|
| 코드 수정 | 커밋과 PR | 자동 머지 X | PR 리뷰 |
| CS 티켓 분석 | 원인 분석 코멘트 | 코드 수정 X | 분석 검증과 후속 조치 |
| CS 담당자 배정 | 배정 + 근거 코멘트 | No 확신 → No 배정 | 애매한 티켓의 판단 |
이렇게 해서 코드를 짜는 루프는 일을 처리하는 루프가 되었습니다. 루프에 넣을 수 있는 일의 조건은 "코드로 해결되는 일"이 아니라 "티켓으로 정의할 수 있고, 결과를 검증할 수 있는 일"이라는 것을 이때 배웠습니다.
4.2. 맡기는 일이 무거워지다
간단한 티켓이 안정적으로 처리되기 시작하자 자연스럽게 다음 질문이 생겼습니다. 어디까지 맡길 수 있을까?
무거운 티켓(여러 모듈에 걸쳐 있고 요구사항이 열 줄을 넘어가는 기능 개발)을 넣어 보면 결과물이 나오기는 했습니다. 그러나 한 번의 실행으로 스펙을 전부 만족시키는 경우는 드물었습니다. 빠뜨린 요구사항이 있거나, 동작은 하지만 품질이 아쉬운 부분이 남았습니다.
돌이켜보면 Claude Code와 대화를 주고받으며 일할 때의 가장 큰 장점 중 하나가 바로 이 지점에 있었습니다. AI의 작업물을 사람이 리뷰해서 피드백을 주면, AI가 그 피드백을 이어받아 다시 작업하는 것. 이 리뷰와 재작업의 사이클이 결과물의 완성도를 끌어올렸습니다. 저는 이 사이클도 시스템에 녹여내고 싶었습니다.
그래서 리뷰어 워크플로우를 만들었습니다. 코드 변경이 성공하면 이번에는 리뷰 전용 에이전트가 별도의 컨테이너에서 자동으로 실행됩니다. 이 리뷰어에게는 독립성 원칙이 있습니다. 코드를 작성한 워커의 로그나 의도에는 접근할 수 없고, 원본 티켓과 PR의 diff만 보고 처음 보는 것처럼 리뷰합니다. 리뷰의 기준은 단 하나, 티켓의 스펙 대비 코드의 품질입니다.
리뷰어가 발견한 문제(finding)는 원본 티켓의 subtask로 등록됩니다. 물론 전부는 아닙니다. 사소한 지적은 걸러져 코멘트로만 남고, 처리할 가치가 있는 것만 subtask가 됩니다. 그러면 subtask 워크플로우가 이를 감지해서, 부모 티켓의 브랜치 위에 하나씩 수정 PR을 만듭니다. 실행 루프 뒤에 검증 루프가 붙고, 그 검증이 다시 실행을 낳는 구조 — 루프가 합성되기 시작한 것입니다.

이 구조가 실제로 어떻게 움직였는지, 4월 말의 사례 하나를 보겠습니다. 백엔드와 프런트엔드에 걸친 데이터 일괄 업로드 기능 티켓이었습니다. 저녁에 티켓을 등록했습니다. autopilot이 백엔드와 프런트엔드에 PR을 하나씩 만들었고, 리뷰어가 그 두 PR에서 스펙 대비 finding 15개를 찾아냈습니다. 그중 11개가 subtask로 등록되었고(나머지 4개는 사소해서 코멘트로만 남았습니다), subtask 11개가 밤사이 각각의 수정 PR로 처리되었습니다. 다음 날 아침 저를 기다리고 있던 것은 PR 13개였습니다. 들어간 비용은 전부 합쳐 약 $26이었습니다.
finding의 수준도 인상적이었습니다. 예를 들어 "검증 실패 에러 메시지가 다국어 메시지 키를 쓰지 않고 영어로 하드코딩되어 있다 — 스펙의 수용 기준 위반" 같은 것들이었는데, 스타일 지적이 아니라 티켓에 적힌 수용 기준과 코드를 대조한 결과였습니다.
물론 PR 13개가 곧 완료 13건은 아닙니다. 하나하나 사람의 리뷰를 거쳐야 하고, 그 리뷰에서 반려되는 것도 있습니다. autopilot이 바꾼 것은 완료의 기준이 아니라, 사람이 리뷰를 시작하는 시점에 이미 구현과 검증과 후속 수정까지 준비되어 있다는 점입니다.
여기서 눈여겨볼 것이 있습니다. 무거운 기능을 맡길 수 있게 된 그 시점에 모델이 갑자기 더 똑똑해진 것이 아닙니다. 달라진 것은 루프의 구조였습니다. 원래 품질을 지키기 위해 만든 검증 루프가, 큰 일을 작은 일로 쪼개 다시 루프에 넣는 분해 장치가 된 것입니다. 능력의 확장은 모델에서 오지 않았습니다. 루프의 구조에서 왔습니다.
4.3. 그 모든 것을 허가한 것
세 번째 방향이 남았습니다. 맡기는 일이 이렇게 넓어지고 무거워지는 동안, 마음 한 켠에 불안감이 남아 있었습니다.
너무 과도하게 AI Agent에게 권한을 준 것은 아닐까? 이러다가 보안 사고가 나면 어떡하지?
jira-autopilot의 에이전트는 승인 게이트 없이 실행됩니다. 대화형 세션이라면 위험한 명령 실행 전에 사람의 승인을 기다리겠지만, 컨테이너 안의 헤드리스 실행에는 승인해 줄 사람이 없습니다. 에이전트에게 최대한의 자유를 준 셈입니다. 그래서 저는 처음부터 원칙을 하나 세웠습니다. 최대한의 자유를 주되, 최대한의 구속을 함께 준다. 4.1의 표에 적어 둔 "지켜야 할 경계"가 일의 규칙이라면, 그 아래에는 더 물리적인 구속의 층이 있습니다. 일회용 컨테이너, 읽기 전용 마운트, 나가는 네트워크 트래픽의 통제. 그리고 각 워커는 자기 일에 필요한 최소한의 권한만 가진 채 태어납니다. 코드를 고치는 워커에는 Jira 토큰이 없고, CS 티켓을 분석하는 워커에는 GitHub 토큰이 없습니다.
핵심은 이 구속들이 프롬프트에 적어 둔 부탁이 아니라 물리적인 경계라는 점입니다. "하지 마세요"라고 말하는 것과 애초에 할 수 없게 만드는 것은 다른 차원의 문제입니다. 에이전트의 선의는 방어선이 아니니까요. 맡기는 일의 자유가 늘어날 수 있었던 것은 이 경계들이 먼저 자랐기 때문입니다. 무엇을 어떻게 가뒀는지는 그 자체로 글 한 편이 될 분량이라, 이 시리즈의 2편에서 자세히 다루겠습니다.
5. 숫자로 보는 석 달
석 달 동안 이 루프가 실제로 얼마나 돌았는지, 운영 데이터베이스의 기록을 그대로 옮깁니다.
| 지표 | 값 |
|---|---|
| 운영 기간 | 약 3개월 (2026년 4월 ~ 7월 초) |
| 총 실행 | 약 470건 |
| 생성된 PR | 313개 |
| 코드 변경 성공률 | 90.7% (성공 351 / 실패 36, 취소 제외) |
| 건당 비용 | 중간값 **5.85) |
| 건당 소요 시간 | 중간값 4.1분 (p90 12.8분) |
거칠게 말하면 PR 하나가 1~2달러에, 5분 안팎에 나옵니다. 다만 이 숫자를 읽을 때 주의할 점이 있습니다. 분모는 "autopilot에 맡길 만하다"고 사람이 판단한 티켓입니다. 선택 편향이 있는 숫자라는 뜻이고, 동시에 그것이 이 도구의 올바른 사용법이기도 합니다. 아무 티켓이나 넣는 도구가 아니라, 잘 정의된 티켓을 넣는 도구입니다.
성공률의 이면도 있는 그대로 적어 둡니다.
먼저, 석 달 동안 19건은 에이전트가 어느 저장소의 어느 모듈을 고쳐야 할지 판단하지 못해 PR 0개로 끝났습니다. 티켓이 가리키는 곳이 모호하면 루프는 첫 단계에서 멈춥니다.
자동 리뷰의 승인율은 55%입니다. 바꿔 말하면, 첫 실행의 결과물 중 절반 가까이는 리뷰어가 수정을 요구했다는 뜻입니다. 4.2에서 본 것처럼 그 간극은 subtask 루프가 메꿔주지만, "한 번에 완벽한 결과"라는 환상은 데이터가 허락하지 않습니다.
그리고 가장 일관된 패턴이 하나 있습니다. 모호한 티켓은 모호한 PR이 됩니다. 요구사항이 명확한 티켓은 안정적으로 처리되지만, 해석의 여지가 있는 티켓은 그 여지만큼 이상한 결과물이 나옵니다. 석 달을 운영하며 내린 결론은, 이 시스템의 품질을 결정하는 것은 모델의 성능만큼이나 티켓의 품질이라는 것입니다. 좋은 티켓을 쓰는 일은 자동화되지 않았습니다. 그것은 여전히, 어쩌면 전보다 더, 사람의 일입니다.
6. 6월, 이름이 도착했다
jira-autopilot이 석 달째 돌아가던 2026년 6월, 개발자 커뮤니티에서 낯선 표현 하나가 눈에 들어오기 시작했습니다. Loop engineering.
에이전트가 멈춤 조건에 도달할 때까지 작업 사이클을 반복하는 것을 루프라고 부르고, 그 루프를 설계하고 운영하고 개선하는 일을 Loop engineering이라고 부르자는 것입니다. 여기저기서 산발적으로 쓰이던 이 표현은 6월 말 Claude Code 팀의 글로 정리되었습니다. 이 글은 루프를 네 가지로 분류합니다.
| 유형 | 무엇이 루프를 시작시키나 | 사람은 어디에 있나 |
|---|---|---|
| Turn-based loop | 사람의 프롬프트 | 매 턴의 결과를 확인하고 다음 지시를 입력 |
| Goal-based loop | 사람이 정의한 목표 | 성공 기준을 정의하고, 도달까지는 루프에 맡김 |
| Time-based loop | 정해진 주기 | 주기와 할 일을 정의 |
| Proactive loop | 사건 또는 일정 — 실시간 개입 없음 | 루프를 설계하고, 결과를 검토 |
첫 번째 항목을 읽는 순간 1장에서 이야기한 그 방식이 떠올랐습니다. 사람 한 번, AI 한 번. 턴제 게임처럼 주고받던 그 리듬에도 이름이 있었던 것입니다. Turn-based loop. 제가 1년 동안 일해온 방식입니다.

그리고 표의 마지막 항목, Proactive loop. 사람이 실시간으로 개입하지 않은 채, 사건이나 일정에 따라 스스로 작업을 시작해 완료까지 도달하는 루프. 저는 이 정의에서 jira-autopilot을 읽었습니다. 30초마다 Jira를 확인한다는 동작만 보면 Time-based처럼 보이지만, 루프를 실제로 시작시키는 것은 시간이 아니라 "실행할 수 있는 티켓이 존재한다"는 사건입니다. 2장에서 Symphony로부터 가져온 셋째 관점(작업의 시작을 사람이 하지 않아도 된다는 것)이 Proactive loop라는 이름을 얻는 순간이었습니다.
분명히 해 두자면, 저는 이 글을 읽고 jira-autopilot을 만들기 시작한 것이 아닙니다. 이 글이 나왔을 때 시스템은 이미 석 달째 회사 Jira 위에서 돌고 있었고, 300개 가까운 PR을 만든 뒤였습니다. 개념을 보고 시스템을 만든 것이 아니라, 만들어 둔 시스템에 이름이 나중에 도착한 것입니다.
처음에는 묘한 기분이었습니다. 그런데 곧 다른 생각이 들었습니다. 이 용어가 이렇게 빠르게 퍼진다는 것은 나만 이 생각을 한 것이 아니라는 뜻입니다. 전 세계의 개발자들이 저마다 같은 반복에 지쳐서, 비슷한 구조에 도달하고 있었던 것입니다. 수렴은 방향이 맞다는 신호입니다. 저에게 Loop engineering이라는 용어의 등장은 유행의 시작이 아니라, 가고 있던 방향에 대한 확인이었습니다.
7. 맺음 — 루프를 설계하는 사람
마지막으로, 요즘 이 시스템에서 제가 가장 아끼는 워크플로우 하나를 소개하며 글을 맺겠습니다. autopilot이 autopilot을 고치는 워크플로우입니다.
autopilot이 티켓을 잘못 처리하는 일은 여전히 일어납니다. 그런 실패를 발견하면 저는 그것을 파이프라인 자신의 개선 티켓으로 만듭니다. 그러면 autopilot이 그 티켓을 집어 들고 — 다른 티켓을 처리할 때와 똑같은 루프로 — 자기 자신의 저장소 코드를 수정해 PR을 만듭니다. 실제로 이렇게 만들어진 PR 두 건이 사람의 리뷰를 거쳐 머지되었습니다. 자신의 검증 로직과 프롬프트를 고치는 변경이었습니다.
물론 여기에도 사람의 게이트는 두 곳 존재합니다. 개선 티켓을 실행 대상으로 승인하는 것도 사람이고, 최종 PR을 리뷰해서 머지하는 것도 사람입니다. 무한 자기수정 루프가 아니라, 통제된 개선 루프입니다.
제가 이 워크플로우를 아끼는 이유는 상징성 때문입니다. 처음에 루프는 제가 하던 반복을 대신했습니다. 다음에는 루프가 루프의 결과물을 검증했습니다. 그리고 이제는 루프가 루프를 고칩니다. 그사이 저의 자리는 계속 이동했습니다. 개별 작업을 직접 수행하는 사람에서, 좋은 작업이 계속 수행될 수 있는 루프를 설계하고 관찰하고 개선하는 사람으로. 그리고 그 개선마저 일부는 이제 루프가 거들고 있습니다.
이 글의 초반부에서 저는 일의 땔감을 나르는 역할이 지겹다고 했습니다. 석 달을 돌려 보고 확실해진 것이 있습니다. jira-autopilot이 없앤 것은 개발자의 일이 아니라, 땔감을 나르는 일이었습니다. 티켓을 명확하게 쓰는 일과 결과물을 리뷰하는 일 — 판단이 필요한 자리는 전부 그대로, 어쩌면 전보다 더 중요해진 채로 남아 있습니다.
이 글에서 미뤄 둔 이야기가 두 가지 있습니다. 승인 게이트 없이 실행되는 에이전트를 어떻게 가뒀는지, 그리고 "프롬프트는 강제 수단이 아니다"라는 원칙 아래 LLM의 자유와 결정론적 통제를 어떻게 함께 설계했는지. 각각 이 시리즈의 2편과 3편에서 다루겠습니다.
