3줄 요약
- 이 글은 OpenAI의 Ryan Lopopolo가 2026년 2월 11일에 쓴 엔지니어링 회고로, 한 팀이 다섯 달 동안 사람이 직접 쓴 코드 0줄로 사내 제품을 만들어 출시한 실험의 기록이다. 모든 코드 — 애플리케이션 로직·테스트·CI·문서·관측·내부 도구 — 를 Codex가 썼고, 손으로 짰을 때보다 약 1/10의 시간이 들었다.
- 사람이 코드를 쓰지 않게 되자 엔지니어의 일 자체가 바뀌었다. “사람은 방향을 잡고, 에이전트가 실행한다(Humans steer. Agents execute).” 실패할 때 답은 “더 열심히"가 아니라 “무슨 능력이 빠졌고, 그걸 어떻게 에이전트가 읽을 수 있고 강제될 수 있게 만들 것인가"였다. 일의 무게중심이 코드에서 발판(scaffolding) 으로 옮겨 갔다.
- 핵심은 레거빌리티(legibility) — 에이전트가 인-컨텍스트로 접근하지 못하는 것은 사실상 존재하지 않는다. 그래서 UI·로그·메트릭·아키텍처·취향까지 전부 리포지토리 안의 버전 관리되는 산물로 옮겨, 에이전트가 읽고 검증할 수 있게 만들었다. 그리고 드리프트는 사람이 금요일마다 청소하는 대신 “골든 원칙"으로 규칙화해 가비지 컬렉션처럼 상시 수거한다.
이 글은 “루프 엔지니어링” 연재의 네 번째 편이다. 1편(Addy Osmani)·2편(Firecrawl)·3편(Oracle)이 “에이전트를 프롬프트하지 말고 루프를 설계하라”, 그리고 “그 루프란 무엇인가"를 다뤘다면, 이번 OpenAI 글은 한 칸 더 위로 올라가 루프를 감싸는 틀 전체 를 본다. 앞선 세 편이 말한 검증·정지·반복의 루프는, 이 글에서 하네스(harness) 라 부르는 더 넓은 환경 — 도구·문서·아키텍처·관측·강제 규칙 — 안에 들어앉는다. 루프가 엔진이라면, 하네스는 그 엔진을 매단 차체다. 이 글은 그 차체를 어떻게 짜는가에 관한 OpenAI의 1차 사료다.
빈 git 저장소에서 시작했다
첫 커밋은 2025년 8월 말, 텅 빈 저장소에 떨어졌다.
최초의 발판 — 저장소 구조, CI 설정, 포매팅 규칙, 패키지 매니저, 애플리케이션 프레임워크 — 은 GPT‑5를 쓰는 Codex CLI가 소수의 기존 템플릿을 길잡이 삼아 생성했다. 에이전트에게 이 저장소에서 어떻게 일하라고 지시하는 AGENTS.md 파일조차 Codex가 직접 썼다. 시스템을 붙들어 줄 사람이 쓴 코드가 처음부터 하나도 없었다. 저장소는 시작부터 에이전트가 빚었다.
다섯 달 뒤 저장소는 백만 줄 규모로 자랐다. 그동안 약 1,500개의 풀 리퀘스트가 열리고 머지됐다. 그것도 Codex를 모는 엔지니어 단 세 명 으로. 엔지니어 한 명당 하루 평균 3.5개의 PR이고, 놀랍게도 팀이 일곱 명으로 늘자 처리량은 오히려 올라갔다. 출력을 위한 출력이 아니었다 — 이 제품은 사내에서 수백 명이, 매일 쓰는 파워 유저까지 포함해 실제로 사용했다.
개발 내내 사람은 코드를 직접 단 한 줄도 보태지 않았다. 이것이 팀의 핵심 철학이 됐다 — 손으로 쓴 코드 없음(no manually-written code).
엔지니어의 역할을 다시 정의하다
사람이 손으로 코딩하지 않게 되자, 시스템·발판·레버리지에 집중하는 다른 종류의 엔지니어링 일 이 생겨났다.
초기 진척은 예상보다 느렸다. Codex가 무능해서가 아니라 환경이 덜 정의돼 있었기 때문이다. 에이전트에게는 높은 수준의 목표로 나아가는 데 필요한 도구·추상·내부 구조가 없었다. 그래서 엔지니어링 팀의 주된 일은 에이전트가 쓸모 있는 일을 할 수 있게 만드는 것 이 됐다.
실무에서 이것은 깊이 우선(depth-first)으로 일하는 것을 뜻했다. 큰 목표를 작은 빌딩 블록(설계·코드·리뷰·테스트 등)으로 쪼개고, 에이전트에게 그 블록을 만들게 하고, 그것들로 더 복잡한 작업을 풀어 가는 식이다. 무언가 실패하면 답은 거의 한 번도 “더 열심히 해 봐"가 아니었다. 진척을 내는 유일한 길은 Codex가 그 일을 하게 만드는 것이었으므로, 사람 엔지니어는 늘 한 발 들어와 물었다 — “무슨 능력이 빠졌고, 그걸 어떻게 에이전트가 읽을 수 있고(legible) 강제될 수 있게(enforceable) 만들 것인가?”
사람은 거의 전적으로 프롬프트를 통해 시스템과 상호작용한다. 엔지니어가 작업을 기술하고, 에이전트를 돌리고, PR을 열게 둔다. PR을 완료까지 끌고 가기 위해 Codex에게 자기 변경을 로컬에서 스스로 리뷰하게 하고, 로컬과 클라우드 양쪽에서 별도의 에이전트 리뷰를 요청하게 하고, 사람이든 에이전트든 피드백에 응답하게 하고, 모든 에이전트 리뷰어가 만족할 때까지 루프를 돈다(사실상 랠프 위검 루프(Ralph Wiggum Loop)다). Codex는 사람이 CLI에 복사·붙여넣기 하지 않고도 표준 개발 도구(gh, 로컬 스크립트, 저장소에 심긴 스킬)를 직접 써서 맥락을 모은다.
사람이 PR을 리뷰할 수는 있지만, 그래야만 하는 것은 아니다. 시간이 지나며 거의 모든 리뷰 노력을 에이전트 대 에이전트 로 넘겨 왔다.
애플리케이션 레거빌리티를 높이다
코드 처리량이 늘자 병목은 사람의 QA 능력 이 됐다. 고정된 제약이 사람의 시간과 주의였으므로, 팀은 애플리케이션의 UI·로그·앱 메트릭 같은 것들 자체를 Codex가 직접 읽을 수 있게 만들어 에이전트의 능력을 키웠다.
예를 들어 앱을 git worktree마다 부팅할 수 있게 만들어, Codex가 변경 하나당 인스턴스 하나를 띄워 직접 몰 수 있게 했다. Chrome DevTools Protocol을 에이전트 런타임에 연결하고 DOM 스냅숏·스크린숏·내비게이션을 다루는 스킬을 만들었다. 덕분에 Codex는 버그를 재현하고, 수정을 검증하고, UI 동작을 직접 추론할 수 있게 됐다.

관측 도구도 똑같이 했다. 로그·메트릭·트레이스를 worktree마다 임시로 뜨는 로컬 관측 스택을 통해 Codex에 노출한다. Codex는 로그와 메트릭까지 포함해 완전히 격리된 버전의 앱 위에서 일하고, 작업이 끝나면 그 스택은 헐린다. 에이전트는 로그를 LogQL로, 메트릭을 PromQL로 질의할 수 있다. 이 맥락이 주어지면 “서비스 시작이 800ms 안에 끝나게 하라"거나 “이 네 개의 핵심 사용자 여정에서 어떤 스팬도 2초를 넘기지 않게 하라” 같은 프롬프트가 다룰 수 있는 일이 된다.

단일 Codex 실행이 하나의 작업을 두고 여섯 시간 넘게 (종종 사람이 자는 동안) 일하는 모습을 정기적으로 본다.
저장소 지식을 시스템 오브 레코드로 삼다
맥락 관리는 에이전트를 크고 복잡한 작업에서 효과적으로 만드는 데 가장 큰 도전 중 하나다. 가장 일찍 배운 교훈은 단순했다 — Codex에게 1,000쪽짜리 설명서가 아니라 지도를 줘라.
팀은 “하나의 거대한 AGENTS.md” 방식을 시도했다. 그것은 예측 가능한 방식으로 실패했다.
- 맥락은 희소 자원이다. 거대한 지시 파일은 작업·코드·관련 문서를 밀어내, 에이전트가 핵심 제약을 놓치거나 엉뚱한 것을 최적화하기 시작한다.
- 지나친 안내는 안내가 아니게 된다. 모든 것이 “중요"하면 아무것도 중요하지 않다. 에이전트는 의도적으로 항해하는 대신 국소적으로 패턴 매칭을 한다.
- 즉시 썩는다. 모놀리식 설명서는 낡은 규칙의 무덤이 된다. 에이전트는 무엇이 아직 참인지 알 수 없고, 사람은 유지를 멈추며, 파일은 조용히 “매력적인 골칫거리"가 된다.
- 검증하기 어렵다. 하나의 덩어리는 기계적 점검(커버리지·신선도·소유권·상호 링크)에 맞지 않아, 드리프트가 불가피하다.
그래서 AGENTS.md를 백과사전이 아니라 목차(table of contents) 로 다룬다.
저장소의 지식 베이스는 시스템 오브 레코드로 취급되는 구조화된 docs/ 디렉토리에 산다. 짧은 AGENTS.md(대략 100줄)가 컨텍스트에 주입되어, 다른 곳의 더 깊은 진실의 원천을 가리키는 지도 역할을 한다.
AGENTS.md
ARCHITECTURE.md
docs/
├── design-docs/
│ ├── index.md
│ ├── core-beliefs.md
│ └── ...
├── exec-plans/
│ ├── active/
│ ├── completed/
│ └── tech-debt-tracker.md
├── generated/
│ └── db-schema.md
├── product-specs/
│ ├── index.md
│ ├── new-user-onboarding.md
│ └── ...
├── references/
│ ├── design-system-reference-llms.txt
│ ├── nixpacks-llms.txt
│ ├── uv-llms.txt
│ └── ...
├── DESIGN.md
├── FRONTEND.md
├── PLANS.md
├── PRODUCT_SENSE.md
├── QUALITY_SCORE.md
├── RELIABILITY.md
└── SECURITY.md
설계 문서는 검증 상태와 에이전트 우선 운영 원칙을 정의하는 “핵심 믿음(core beliefs)“을 포함해 목록화·색인된다. 아키텍처 문서는 도메인과 패키지 계층의 최상위 지도를 준다. 품질 문서는 각 제품 도메인과 아키텍처 계층에 등급을 매겨 시간에 따른 격차를 추적한다. 계획은 일급 산물로 다뤄진다. 작은 변경에는 가벼운 임시 계획을, 복잡한 작업에는 진행·결정 로그가 달린 실행 계획(execution plans)을 저장소에 체크인한다. 활성 계획·완료 계획·알려진 기술 부채가 모두 버전 관리되며 한곳에 모여, 에이전트가 외부 맥락에 기대지 않고 일할 수 있다.
이것이 점진적 공개(progressive disclosure) 를 가능하게 한다. 에이전트는 작고 안정적인 진입점에서 출발해, 처음부터 모든 것에 압도되는 대신 다음에 어디를 봐야 할지 배운다.
팀은 이것을 기계적으로 강제한다. 전용 린터와 CI 작업이 지식 베이스가 최신이고, 상호 링크돼 있고, 올바르게 구조화돼 있는지 검증한다. 주기적으로 도는 “문서 정원사(doc-gardening)” 에이전트가 실제 코드 동작을 반영하지 않는 낡거나 쓸모없어진 문서를 훑어 수정 PR을 연다.
에이전트 레거빌리티가 목표다
코드베이스가 진화하면서 Codex의 설계 결정 틀도 함께 진화해야 했다.
저장소가 전적으로 에이전트가 생성한 것이므로, 무엇보다 Codex의 레거빌리티 에 맞춰 최적화된다. 새 엔지니어 신입을 위해 코드의 항해성을 높이듯, 사람 엔지니어의 목표는 에이전트가 저장소 그 자체로부터 전체 비즈니스 도메인을 추론할 수 있게 만드는 것이었다.
에이전트의 관점에서, 돌아가는 동안 인-컨텍스트로 접근할 수 없는 것은 사실상 존재하지 않는다. Google Docs나 채팅 스레드, 사람의 머릿속에 사는 지식은 시스템에 접근 가능하지 않다. 저장소에 로컬로, 버전 관리되는 산물(코드·마크다운·스키마·실행 가능한 계획)만이 에이전트가 볼 수 있는 전부다.

아키텍처와 취향을 강제하다
문서만으로는 전적으로 에이전트가 생성한 코드베이스를 일관되게 유지하지 못한다. 구현을 미주알고주알 관리하는 대신 불변식(invariants)을 강제함으로써, 에이전트가 토대를 무너뜨리지 않으면서 빠르게 출시하게 한다. 예를 들어 Codex에게 경계에서 데이터 형태를 파싱하라고 요구하지만, 어떻게 그렇게 할지는 지시하지 않는다(모델은 Zod를 좋아하는 듯하나 그 라이브러리를 특정하지 않았다).
에이전트는 엄격한 경계와 예측 가능한 구조를 갖춘 환경에서 가장 효과적이므로, 애플리케이션을 단단한 아키텍처 모델 위에 지었다. 각 비즈니스 도메인은 고정된 계층 집합으로 나뉘고, 엄격히 검증되는 의존 방향과 허용되는 간선의 제한된 집합을 가진다. 이 제약은 (물론 Codex가 생성한) 커스텀 린터와 구조 테스트로 기계적으로 강제된다.

도식의 규칙은 이렇다. 각 비즈니스 도메인(예: App Settings) 안에서 코드는 고정된 계층(Types → Config → Repo → Service → Runtime → UI)을 따라 “앞으로만” 의존할 수 있다. 횡단 관심사(인증·커넥터·텔레메트리·피처 플래그)는 단 하나의 명시적 인터페이스인 Providers를 통해서만 들어온다. 그 밖의 모든 것은 금지되고 기계적으로 강제된다.
이것은 보통 엔지니어가 수백 명이 될 때까지 미뤄 두는 종류의 아키텍처다. 코딩 에이전트와 함께라면 이것은 이른 전제 조건 이다 — 제약이야말로 부패나 아키텍처 드리프트 없이 속도를 내게 하는 것이다. 실무에서는 커스텀 린터와 구조 테스트, 그리고 소수의 “취향 불변식(taste invariants)“으로 규칙을 강제한다. 예를 들어 구조화된 로깅, 스키마·타입 명명 규칙, 파일 크기 제한, 플랫폼별 신뢰성 요건을 커스텀 린트로 정적으로 강제한다. 린트가 커스텀이므로, 에러 메시지에 교정 지시 를 적어 에이전트 컨텍스트에 주입한다.
사람 우선 워크플로에서 이런 규칙은 현학적이거나 옥죄는 것으로 느껴질 수 있다. 에이전트와 함께라면 그것은 승수 가 된다 — 한 번 인코딩되면 모든 곳에 한꺼번에 적용된다. 동시에 제약이 중요한 곳과 중요하지 않은 곳을 분명히 한다. 이것은 큰 엔지니어링 플랫폼 조직을 이끄는 일과 닮았다 — 경계는 중앙에서 강제하고, 자율은 국소적으로 허용한다. 결과 코드가 늘 사람의 문체 취향과 맞지는 않지만, 그래도 괜찮다. 출력이 정확하고, 유지보수 가능하고, 미래의 에이전트 실행에 읽힌다면 기준을 충족한 것이다. 사람의 취향은 시스템에 상시 되먹여진다. 리뷰 코멘트·리팩토링 PR·사용자가 마주친 버그는 문서 갱신으로 담기거나 도구에 직접 인코딩된다. 문서로 부족할 때는 규칙을 코드로 승격시킨다.
처리량이 머지 철학을 바꾼다
Codex의 처리량이 늘자, 관습적인 엔지니어링 규범 다수가 역효과를 냈다.
저장소는 머지를 막는 게이트를 최소한으로 두고 돌아간다. PR은 수명이 짧다. 테스트 플레이크는 진척을 무한정 막는 대신 후속 실행으로 처리되는 일이 잦다. 에이전트 처리량이 사람의 주의를 한참 웃도는 시스템에서는, 교정이 싸고 기다림이 비싸다.
이것은 처리량이 낮은 환경이라면 무책임한 처사일 것이다. 여기서는 종종 옳은 절충이다.
“에이전트가 생성했다"가 실제로 뜻하는 것
코드베이스가 Codex 에이전트에 의해 생성됐다고 말할 때, 그것은 코드베이스의 모든 것 을 뜻한다. 에이전트는 다음을 만든다.
- 제품 코드와 테스트
- CI 설정과 릴리스 도구
- 내부 개발자 도구
- 문서와 설계 역사
- 평가 하네스(evaluation harnesses)
- 리뷰 코멘트와 응답
- 저장소 자체를 관리하는 스크립트
- 프로덕션 대시보드 정의 파일
사람은 늘 루프 안에 남지만, 예전과는 다른 추상 계층에서 일한다. 우리는 일의 우선순위를 정하고, 사용자 피드백을 인수 조건으로 번역하고, 결과를 검증한다. 에이전트가 헤맬 때는 그것을 신호 로 삼는다 — 무엇이 빠졌는지(도구·가드레일·문서) 짚어내 저장소에 되먹이되, 언제나 Codex 자신이 그 수정을 쓰게 한다. 에이전트는 표준 개발 도구를 직접 쓴다. 리뷰 피드백을 끌어오고, 인라인으로 응답하고, 업데이트를 푸시하고, 종종 자기 PR을 스쿼시 머지한다.
자율 수준을 높여 가다
테스트·검증·리뷰·피드백 처리·복구까지 개발 루프의 더 많은 부분이 시스템에 직접 인코딩되면서, 저장소는 최근 의미 있는 문턱을 넘었다 — Codex가 새 기능을 엔드투엔드로 몰 수 있게 된 것이다. 단 하나의 프롬프트가 주어지면, 에이전트는 이제 다음을 할 수 있다.
- 코드베이스의 현재 상태를 검증한다
- 보고된 버그를 재현한다
- 실패를 보여 주는 영상을 녹화한다
- 수정을 구현한다
- 애플리케이션을 직접 몰며 수정을 검증한다
- 해결을 보여 주는 두 번째 영상을 녹화한다
- 풀 리퀘스트를 연다
- 에이전트와 사람의 피드백에 응답한다
- 빌드 실패를 감지하고 교정한다
- 판단이 필요할 때만 사람에게 에스컬레이션한다
- 변경을 머지한다
이 동작은 이 저장소의 특정 구조와 도구에 크게 의존하므로, 비슷한 투자 없이 일반화된다고 가정해서는 안 된다 — 적어도 아직은.
엔트로피와 가비지 컬렉션
완전한 에이전트 자율은 새로운 문제도 들여온다. Codex는 저장소에 이미 있는 패턴을 — 고르지 못하거나 차선인 것까지 — 복제한다. 시간이 지나면 이것은 필연적으로 드리프트로 이어진다.
처음에는 사람이 손으로 해결했다. 팀은 매주 금요일(주의 20%)을 “AI 슬롭(AI slop)“을 청소하는 데 썼다. 당연하게도 그것은 확장되지 않았다.
대신 팀은 “골든 원칙(golden principles)“이라 부르는 것을 저장소에 직접 인코딩하고, 주기적으로 도는 정리 프로세스를 만들었다. 이 원칙들은 코드베이스를 미래의 에이전트 실행에 읽히고 일관되게 유지하는, 의견이 분명하고 기계적인 규칙이다. 예를 들어 (1) 불변식을 한곳에 모으기 위해 손수 만든 헬퍼보다 공유 유틸리티 패키지를 선호하고, (2) 데이터를 “YOLO 방식"으로 더듬지 않는다 — 경계를 검증하거나 타입 있는 SDK에 기대, 에이전트가 추측한 형태 위에 실수로 무언가를 짓지 못하게 한다. 정해진 주기로, 배경에서 도는 Codex 작업 묶음이 일탈을 훑고, 품질 등급을 갱신하고, 표적 리팩토링 PR을 연다. 이들 대부분은 1분 안에 리뷰돼 자동 머지된다.
이것은 가비지 컬렉션처럼 작동한다. 기술 부채는 고금리 대출과 같다 — 복리로 불어나게 두었다가 고통스러운 폭발로 갚느니, 작은 단위로 끊임없이 갚아 나가는 편이 거의 늘 낫다. 사람의 취향은 한 번 포착되어, 그다음부터는 모든 코드 줄에 상시 강제된다. 덕분에 나쁜 패턴을 며칠·몇 주씩 코드베이스에 퍼지게 두는 대신 매일 잡아 해결한다.
아직 배우는 중인 것
이 전략은 지금까지 사내 출시와 채택에 이르기까지 잘 작동했다. 실제 사용자를 위한 진짜 제품을 만든 것이 투자를 현실에 닻 내리게 했고, 장기적 유지보수성으로 안내했다.
아직 모르는 것은, 전적으로 에이전트가 생성한 시스템에서 아키텍처의 정합성이 수년에 걸쳐 어떻게 진화하는가 다. 사람의 판단이 어디서 가장 큰 레버리지를 더하는지, 그 판단을 어떻게 인코딩해야 복리로 쌓이는지 여전히 배우는 중이다. 모델이 계속 더 유능해질 때 이 시스템이 어떻게 진화할지도 모른다.
분명해진 것은 이렇다. 소프트웨어를 짓는 일은 여전히 규율을 요구하지만, 그 규율이 코드보다 발판에서 더 많이 드러난다. 코드베이스를 정합하게 유지하는 도구·추상·피드백 루프가 점점 더 중요해진다.
우리의 가장 어려운 도전은 이제 에이전트가 목표를 이루도록 돕는 환경·피드백 루프·제어 시스템을 설계하는 일 에 모인다 — 복잡하고 신뢰할 수 있는 소프트웨어를 규모 있게 짓고 유지하는 것.
가장 눈여겨본 대목
내가 가장 오래 머문 곳은 “에이전트가 볼 수 없는 것은 존재하지 않는다"는 한 줄이다. 이 연재의 앞 세 편이 루프 를 이야기했다면 — 검증을 누가 책임지는가(1편), 언제 멈추는가(2편), 무엇으로 이루어졌는가(3편) — 이 글은 그 루프가 무엇을 먹고 도는가 를 말한다. 답은 컨텍스트다. 그리고 컨텍스트는 공짜로 주어지지 않는다. 사람의 머릿속·구글 독스·슬랙 스레드에 흩어진 지식은, 에이전트에게는 없는 것이나 마찬가지다. 그래서 OpenAI 팀은 UI·로그·메트릭·아키텍처·취향까지 전부 저장소 안의 버전 관리되는 마크다운과 코드로 끌어내렸다. 루프를 잘 돌리려면 루프 바깥을 먼저 읽히게 만들어야 한다는 것 — 이것이 “하네스 엔지니어링"이라는 이름이 가리키는 전부다.
또 하나 곱씹은 것은 금요일 청소의 실패 다. 사람이 매주 20%를 들여 AI 슬롭을 치우던 방식은 확장되지 않았고, 팀은 그 일을 “골든 원칙"으로 규칙화해 가비지 컬렉터에게 넘겼다. 검증을 사람의 주의에 맡기지 말고 루프에 내재화하라는 앞 편들의 결론이, 여기서는 코드 위생 의 차원으로 한 번 더 반복된다. 사람의 취향은 한 번 포착되어 모든 줄에 상시 강제된다 — 판단을 자동화하라는 명제의 가장 선명한 사례다.
출처
OpenAI, “Harness engineering: leveraging Codex in an agent-first world” — Ryan Lopopolo (Member of the Technical Staff), 2026년 2월 11일. Victor Zhu·Zach Brock 기여. 원문: https://openai.com/index/harness-engineering/
