하네스 엔지니어링: 에이전트 퍼스트 세계에서 Codex 활용하기
게시일: 2026년 2월 26일 | 원문 작성일: 2026년 2월 11일 | 저자: Ryan Lopopolo (OpenAI) | 원문 보기
핵심 요약
OpenAI 엔지니어링팀이 5개월간 수동으로 작성한 코드 한 줄 없이 실제 내부 제품을 구축했어요. 엔지니어 3명이 Codex를 이용해 100만 줄 규모의 코드베이스를 만든 과정에서 배운 에이전트 퍼스트 개발 원칙들을 공유해요.
- 인간은 방향, 에이전트는 실행 — 엔지니어의 역할이 직접 코드를 쓰는 것에서 에이전트가 잘 동작할 수 있는 환경과 피드백 루프를 설계하는 것으로 바뀌었어요.
- 레포지토리가 지식의 중심 — Slack 대화, Google Docs, 구두 결정 등 Codex가 접근할 수 없는 정보는 사실상 존재하지 않는 거나 마찬가지예요. 모든 중요한 컨텍스트는 레포에 마크다운으로 남겨야 해요.
- 아키텍처는 초기부터 엄격하게 — 보통 수백 명 규모 팀이 되어서야 도입하는 엄격한 레이어 아키텍처가, 에이전트 환경에서는 처음부터 필수 조건이에요. 제약이 있어야 속도와 일관성을 동시에 잡을 수 있어요.
- 처리량이 달라지면 머지 철학도 달라져요 — 에이전트의 throughput이 인간의 리뷰 속도를 훨씬 앞서는 환경에서는 “기다리는 것”이 비용이에요. 수정은 저렴하고 대기는 비싸요.
- 가비지 컬렉션처럼 지속적으로 정리 — Codex는 레포에 있는 패턴을 그대로 복제해요. 나쁜 패턴이 퍼지기 전에 자동화된 정리 프로세스로 매일 잡아내는 게 핵심이에요.
• • •
지난 5개월간 우리 팀은 한 가지 실험을 진행했어요. 수동으로 작성한 코드 0줄로 소프트웨어 제품의 내부 베타를 구축하고 실제로 출시한 거예요.
이 제품은 내부 일간 사용자도 있고 외부 알파 테스터도 있어요. 배포되고, 고장 나고, 고쳐져요. 달라진 건 애플리케이션 로직, 테스트, CI 설정, 문서, 옵저버빌리티, 내부 툴링에 이르기까지 모든 코드 한 줄 한 줄을 Codex가 작성했다는 거예요. 직접 손으로 코드를 썼을 때보다 약 1/10의 시간에 이걸 만들었어요.
인간은 방향을 잡고, 에이전트가 실행한다.
우리는 의도적으로 이 제약을 선택했어요. 엔지니어링 속도를 몇 자릿수 수준으로 높이려면 무엇이 필요한지 직접 알아내기 위해서요. 몇 주 안에 결국 100만 줄짜리 코드가 될 것들을 출시해야 했어요. 그러려면 소프트웨어 엔지니어링 팀의 주된 역할이 더 이상 코드를 쓰는 것이 아닐 때—환경을 설계하고, 의도를 구체화하고, Codex 에이전트가 믿을 만한 작업을 할 수 있도록 피드백 루프를 구축하는 것이 역할이 될 때—무엇이 달라지는지 이해해야 했어요.
이 글은 에이전트 팀으로 완전히 새로운 제품을 만들면서 배운 것들에 관한 이야기예요. 무엇이 잘못됐는지, 무엇이 복리로 쌓여갔는지, 그리고 우리의 유일하게 희소한 자원인 인간의 시간과 주의를 어떻게 최대로 활용하는지에 대해서요.
빈 git 레포지토리에서 시작했어요
빈 레포지토리에 첫 번째 커밋이 들어온 건 2025년 8월 말이었어요.
초기 스캐폴드—레포 구조, CI 설정, 포맷 규칙, 패키지 매니저 설정, 애플리케이션 프레임워크—는 기존 템플릿 몇 개를 가이드로 삼아 Codex CLI가 GPT-5로 생성했어요. 에이전트가 레포에서 어떻게 작업해야 하는지를 지시하는 초기 AGENTS.md1 파일조차 Codex가 직접 썼어요.
시스템을 잡아줄 기존 사람 손으로 쓴 코드 같은 건 없었어요. 처음부터 레포지토리는 에이전트가 만들어갔어요.
5개월 후: 100만 줄 규모의 코드베이스 — 엔지니어 3명이 ~1,500개의 PR 머지 — 1인당 하루 평균 3.5개 PR — 팀이 7명으로 늘어난 후 처리량 증가
중요한 건 숫자를 위한 숫자가 아니었다는 거예요. 이 제품은 내부적으로 수백 명의 사용자가 실제로 사용했고, 매일 쓰는 파워 유저들도 있었어요.
개발 과정 전반에 걸쳐 인간은 코드에 직접 기여한 적이 없어요. 이건 팀의 핵심 철학이 됐어요: 수동으로 코드를 쓰지 않는다.
• • •
엔지니어의 역할을 새롭게 정의하기
직접 손으로 코딩하지 않는다는 제약은 시스템, 스캐폴딩, 레버리지에 집중하는 다른 종류의 엔지니어링 작업을 만들어냈어요.
초기 진행 속도는 예상보다 느렸어요. Codex가 못해서가 아니라 환경이 제대로 명세되지 않았기 때문이에요. 에이전트에게 고수준 목표를 향해 나아가는 데 필요한 툴, 추상화, 내부 구조가 없었거든요. 우리 엔지니어링 팀의 주된 역할은 에이전트가 유용한 작업을 할 수 있도록 환경을 갖추는 일이 됐어요.
실제로 이건 깊이 우선(depth-first)으로 작업하는 것을 의미했어요. 큰 목표를 더 작은 빌딩 블록(설계, 코드, 리뷰, 테스트 등)으로 분해하고, 에이전트에게 그 블록들을 만들도록 프롬프팅하고, 그것들을 활용해 더 복잡한 작업을 풀어나가는 거예요. 뭔가 실패했을 때 답이 “더 열심히 해봐”인 경우는 거의 없었어요. 유일하게 진전을 만드는 방법이 Codex가 일을 하게 만드는 것이었기 때문에, 인간 엔지니어는 항상 그 작업 안으로 들어가 이렇게 물었어요: “어떤 기능이 빠진 건지, 어떻게 하면 에이전트가 이해하고 강제할 수 있는 형태로 만들 수 있지?”
인간이 시스템과 상호작용하는 방식은 거의 대부분 프롬프트를 통해서예요. 엔지니어가 작업을 설명하고, 에이전트를 실행하고, PR을 열도록 놔두는 거예요. PR을 완성까지 이끌기 위해 우리는 Codex에게 로컬에서 자신의 변경 사항을 직접 리뷰하고, 로컬과 클라우드 양쪽에서 추가 에이전트 리뷰를 요청하고, 인간 또는 에이전트가 준 피드백에 응답하고, 모든 에이전트 리뷰어가 만족할 때까지 루프를 반복하도록 지시해요(사실상 이건 랄프 위검 루프2예요). Codex는 우리의 표준 개발 툴(gh, 로컬 스크립트, 레포에 내장된 스킬)을 직접 사용해서 컨텍스트를 수집해요. 사람이 직접 CLI에 복사-붙여넣기를 할 필요가 없어요.
인간이 PR을 리뷰할 수도 있지만 필수는 아니에요. 시간이 지나면서 거의 모든 리뷰 작업을 에이전트 간 처리로 넘겼어요.
애플리케이션 가독성 높이기
코드 처리량이 늘어나자 병목은 인간의 QA 역량이 됐어요. 고정된 제약이 인간의 시간과 주의력이었기 때문에, 우리는 애플리케이션 UI, 로그, 앱 메트릭 같은 것들이 Codex에게 직접 읽힐 수 있도록 만들어서 에이전트 역량을 더 키우려고 했어요.
예를 들어, Codex가 변경 사항 하나당 앱 인스턴스 하나씩 띄울 수 있도록 앱을 git worktree 단위로 부팅 가능하게 만들었어요. 또 Chrome DevTools Protocol3을 에이전트 런타임에 연결하고 DOM 스냅샷, 스크린샷, 네비게이션 작업을 위한 스킬을 만들었어요. 이를 통해 Codex가 버그를 재현하고, 수정 사항을 검증하고, UI 동작을 직접 추론할 수 있게 됐어요.
옵저버빌리티 툴링도 똑같은 방식으로 접근했어요. worktree마다 임시 로컬 옵저버빌리티 스택이 생겨요. Codex는 완전히 격리된 앱—로그와 메트릭까지 포함해서—을 대상으로 작업하고, 작업이 끝나면 그 환경 전체가 사라져요. Codex는 LogQL4로 로그를 쿼리하고 PromQL로 메트릭을 쿼리할 수 있어요. 이 컨텍스트가 갖춰지면 “서비스 시작을 800ms 안에 완료시켜” 또는 “이 네 가지 핵심 사용자 여정에서 어떤 트레이싱 스팬도 2초를 넘지 않게 해”같은 프롬프트가 실제로 다룰 수 있는 목표가 돼요.
단일 Codex 실행이 하나의 작업을 6시간 이상 이어가는 경우도 정기적으로 봐요(인간이 자는 동안에도요).
레포지토리 지식을 진실의 원천으로
컨텍스트 관리는 에이전트를 크고 복잡한 작업에서 효과적으로 만드는 가장 큰 도전 중 하나예요. 가장 일찍 배운 교훈 중 하나는 단순했어요: Codex에게 지도를 줘요, 1,000페이지짜리 매뉴얼 말고.
우리는 “하나의 큰 AGENTS.md” 방식을 시도해봤어요. 예상 가능한 방식으로 실패했어요:
- 컨텍스트는 희소 자원이에요. 거대한 지침 파일은 작업, 코드, 관련 문서를 밀어내요. 그러면 에이전트가 핵심 제약을 놓치거나 잘못된 것에 최적화하기 시작해요.
- 지침이 너무 많으면 지침이 아니게 돼요. 모든 게 “중요하면” 아무것도 중요하지 않은 거예요. 에이전트들이 의도적으로 탐색하는 대신 로컬 패턴 매칭을 하기 시작해요.
- 금방 낡아요. 단일체로 된 매뉴얼은 죽은 규칙들의 무덤이 돼요. 에이전트는 뭐가 아직 사실인지 구분 못하고, 인간은 유지 보수를 멈추고, 파일은 조용히 “attractive nuisance”5가 돼요.
- 검증하기 어려워요. 하나의 덩어리는 기계적 검사(커버리지, 최신성, 소유권, 크로스링크)에 적합하지 않아서 드리프트가 불가피해요.
그래서 AGENTS.md를 백과사전이 아니라 목차로 취급하게 됐어요.
레포지토리의 지식 베이스는 진실의 원천으로 취급되는 구조화된 docs/ 디렉터리에 살아요. 짧은 AGENTS.md(약 100줄)가 컨텍스트에 주입되고, 주로 지도 역할을 하면서 다른 곳에 있는 더 깊은 진실의 원천을 가리켜요.
설계 문서는 검증 상태와 에이전트 퍼스트 운영 원칙을 정의하는 핵심 신념 세트를 포함해 카탈로그화되고 색인화돼요. 아키텍처 문서는 도메인과 패키지 레이어링의 최상위 지도를 제공해요. 품질 문서는 각 제품 도메인과 아키텍처 레이어를 등급화하고 시간에 따른 격차를 추적해요.
플랜은 일급 아티팩트로 취급돼요. 작은 변경에는 임시 경량 플랜을 사용하고, 복잡한 작업은 진행 상황과 결정 로그가 담긴 실행 플랜으로 레포에 체크인돼요. 활성 플랜, 완료된 플랜, 알려진 기술 부채가 모두 버전 관리되고 함께 위치해서, 에이전트가 외부 컨텍스트에 의존하지 않고 동작할 수 있어요.
이를 통해 점진적 공개6가 가능해요. 에이전트가 처음부터 압도당하는 대신 작고 안정적인 진입점에서 시작해 다음에 어디를 볼지 배워가요.
우리는 이걸 기계적으로 강제해요. 전용 린터와 CI 작업이 지식 베이스가 최신 상태인지, 크로스링크가 있는지, 올바르게 구조화됐는지 검증해요. 정기적인 “doc-gardening” 에이전트가 실제 코드 동작을 반영하지 않는 낡거나 쓸모없는 문서를 스캔하고 수정 PR을 열어요.
에이전트 가독성이 목표예요
코드베이스가 발전하면서 Codex의 설계 결정 기준도 함께 발전해야 했어요.
이 레포지토리는 처음부터 끝까지 에이전트가 만들었기 때문에, 최적화 대상이 독특해요. 바로 Codex가 직접 읽고 이해할 수 있는 코드베이스를 만드는 거예요. 마치 팀이 신입 엔지니어를 위해 코드 탐색성을 높이듯, 우리 인간 엔지니어들의 목표는 에이전트가 외부 도움 없이 레포지토리만 보고 전체 비즈니스 도메인을 파악할 수 있게 만드는 거였어요.
에이전트 입장에서는 실행 중에 직접 접근할 수 없는 정보는 없는 것과 같아요. Google Docs에 적힌 결정, Slack 채팅 스레드, 동료들 머릿속에 있는 지식—에이전트에게 이건 전부 보이지 않아요. 레포에 버전 관리된 아티팩트(코드, 마크다운, 스키마, 실행 가능한 플랜)만이 에이전트가 실제로 볼 수 있는 전부예요.
시간이 지나면서 점점 더 많은 컨텍스트를 레포에 넣어야 한다는 걸 배웠어요. 팀이 아키텍처 패턴에 대해 정렬한 그 Slack 토론? 에이전트가 발견할 수 없다면, 3개월 후에 합류한 신입 사원이 모르는 것처럼 에이전트에게도 알 수 없는 거예요.
Codex에게 더 많은 컨텍스트를 주는 건 즉흥적인 지침으로 압도하는 게 아니라, 에이전트가 추론할 수 있도록 올바른 정보를 정리하고 노출하는 거예요. 새 팀원에게 제품 원칙, 엔지니어링 규범, 팀 문화(이모지 취향까지)를 온보딩하는 것처럼, 에이전트에게 이 정보를 주면 더 잘 맞는 결과물이 나와요.
”에이전트가 레포에서 직접 추론할 수 있어야 한다”는 이 관점이 많은 트레이드오프를 명확하게 해줬어요. 우리는 레포 내에서 완전히 파악하고 추론할 수 있는 의존성과 추상화를 선호했어요. 흔히 “지루하다”고 불리는 검증된 기술들은 조합 가능성, API 안정성, 그리고 모델 훈련 데이터 내 노출 빈도 덕분에 에이전트가 이해하기 더 쉬운 경향이 있어요. 어떤 경우에는 외부 공개 라이브러리의 불투명한 동작을 우회하는 것보다 에이전트가 필요한 기능만 직접 재구현하는 게 더 빠르고 안전했어요. 예를 들어, 범용 p-limit7 스타일 패키지를 가져오는 대신 자체 map-with-concurrency 헬퍼를 만들었어요. OpenTelemetry8 계측과 긴밀하게 통합되고, 100% 테스트 커버리지가 있으며, 런타임의 기대 방식 그대로 동작해요.
시스템의 더 많은 부분을 에이전트가 직접 검사하고, 검증하고, 수정할 수 있는 형태로 만드는 것은 레버리지를 높여줘요. Codex뿐만 아니라 코드베이스에서 작업하는 다른 에이전트들에게도요.
아키텍처와 취향 강제하기
문서만으로는 완전히 에이전트가 생성한 코드베이스의 일관성을 유지할 수 없어요. 구현을 세세하게 관리하는 대신 불변 조건을 강제해서, 에이전트들이 기반을 무너뜨리지 않고 빠르게 출시할 수 있게 만들었어요. 예를 들어, Codex에게 경계에서 데이터 형태를 파싱9하도록 요구하지만, 어떻게 할지는 명시하지 않아요(모델은 Zod를 좋아하는 것 같지만 특정 라이브러리를 지정하진 않았어요).
에이전트는 엄격한 경계와 예측 가능한 구조가 있는 환경에서 가장 효과적이에요. 그래서 우리는 애플리케이션을 엄격한 아키텍처 모델을 중심으로 구축했어요. 각 비즈니스 도메인은 고정된 레이어 세트로 나뉘고, 의존성 방향이 엄격하게 검증되며, 허용되는 엣지 세트도 제한돼요. 이 제약들은 커스텀 린터(물론 Codex가 생성한!)와 구조 테스트로 기계적으로 강제돼요.
아래 다이어그램은 규칙을 보여줘요. 각 비즈니스 도메인(예: 앱 설정) 내에서 코드는 고정된 레이어 세트를 따라 “앞으로”만 의존할 수 있어요(Types → Config → Repo → Service → Runtime → UI). 횡단 관심사(인증, 커넥터, 텔레메트리, 기능 플래그)는 단일 명시적 인터페이스인 Providers를 통해 들어와요. 그 외의 것은 허용되지 않고 기계적으로 강제돼요.
이건 보통 수백 명의 엔지니어가 생기고 나서야 미루다 도입하는 아키텍처예요. 코딩 에이전트를 쓸 때는 초기 전제 조건이에요. 제약이 있어야 부패나 아키텍처 드리프트 없이 속도를 낼 수 있어요.
실제로는 커스텀 린터와 구조 테스트, 그리고 소수의 “취향 불변 조건”으로 이 규칙들을 강제해요. 예를 들어 구조화된 로깅, 스키마 및 타입 명명 규칙, 파일 크기 제한, 플랫폼별 안정성 요구 사항을 커스텀 린트로 정적으로 강제해요. 린트가 커스텀이기 때문에, 에이전트 컨텍스트에 직접 주입될 수정 지침을 에러 메시지 안에 담아요.
인간 중심 워크플로에서 이런 규칙들은 까다롭거나 제약처럼 느껴질 수 있어요. 에이전트와 함께하면 승수가 돼요. 한 번 인코딩되면 모든 곳에 동시에 적용돼요.
동시에, 제약이 중요한 곳과 그렇지 않은 곳을 명확히 구분해요. 이건 수백 명 규모의 엔지니어링 플랫폼 조직을 이끄는 방식과 비슷해요: 경계는 중앙에서 강제하고, 그 안에서는 자율성을 허용하는 거예요. 경계, 정확성, 재현 가능성에는 엄격하게 신경 쓰지만, 그 경계 안에서 팀—또는 에이전트—이 솔루션을 어떻게 표현할지는 많은 자유를 줘요.
결과로 나오는 코드가 항상 인간의 스타일 선호와 일치하지는 않는데, 그건 괜찮아요. 결과물이 정확하고, 유지 보수 가능하고, 미래의 에이전트 실행에서 읽을 수 있는 한 기준을 충족한 거예요.
인간의 취향은 시스템에 지속적으로 피드백돼요. 리뷰 코멘트, 리팩터링 PR, 사용자 직면 버그들은 문서 업데이트로 캡처되거나 툴링에 직접 인코딩돼요. 문서가 부족할 때는 규칙을 코드로 격상시켜요.
처리량이 달라지면 머지 철학도 달라져요
Codex의 처리량이 늘어나면서 많은 기존 엔지니어링 규범이 역효과를 냈어요.
레포지토리는 최소한의 블로킹 머지 게이트로 운영돼요. PR은 단명해요. 테스트가 간헐적으로 실패해도 진행을 무기한 막지 않고, 후속 실행에서 처리하는 경우가 많아요. 에이전트 처리량이 인간의 주의력을 훨씬 앞서는 시스템에서는 수정이 저렴하고, 기다리는 것이 비싸요.
이건 처리량이 낮은 환경에서는 무책임한 일이에요. 여기서는 종종 올바른 트레이드오프예요.
”에이전트 생성”이 실제로 의미하는 것
Codex 에이전트가 코드베이스를 생성한다고 할 때, 코드베이스의 모든 것을 의미해요.
에이전트가 생성하는 것들:
- 제품 코드와 테스트
- CI 설정과 릴리스 툴링
- 내부 개발자 툴
- 문서와 설계 히스토리
- 평가 하네스10
- 리뷰 코멘트와 응답
- 레포지토리 자체를 관리하는 스크립트
- 프로덕션 대시보드 정의 파일
인간은 항상 루프에 있지만, 이전과는 다른 추상화 레이어에서 작업해요. 우리는 작업의 우선순위를 정하고, 사용자 피드백을 수용 기준으로 변환하고, 결과를 검증해요. 에이전트가 어려움을 겪을 때는 신호로 받아들여요: 무엇이 빠진 건지—툴, 가드레일, 문서—를 파악하고 레포에 피드백하되, 항상 Codex 자체가 수정을 쓰게 해요.
에이전트들은 우리의 표준 개발 툴을 직접 사용해요. 리뷰 피드백을 가져오고, 인라인으로 응답하고, 업데이트를 푸시하고, 자신의 PR을 스쿼시 머지하는 경우도 많아요.
점점 높아지는 자율성 수준
테스트, 검증, 리뷰, 피드백 처리, 복구 같은 개발 루프의 핵심 단계들이 시스템에 직접 인코딩되면서, 이 레포지토리는 최근 중요한 임계점을 넘어섰어요. Codex가 새 기능 하나를 엔드투엔드로 혼자 완성할 수 있게 된 거예요.
단일 프롬프트가 주어지면 에이전트는 이제 다음을 할 수 있어요:
- 코드베이스의 현재 상태 검증
- 보고된 버그 재현
- 실패를 보여주는 비디오 녹화
- 수정 구현
- 앱을 구동해서 수정 검증
- 해결을 보여주는 두 번째 비디오 녹화
- PR 열기
- 에이전트 및 인간 피드백에 응답
- 빌드 실패 감지 및 수정
- 판단이 필요할 때만 인간에게 에스컬레이션
- 변경 사항 머지
이 동작은 이 레포지토리의 구체적인 구조와 툴링에 크게 의존하며, 비슷한 투자 없이 일반화된다고 가정하면 안 돼요—적어도 아직은요.
엔트로피와 가비지 컬렉션
완전한 에이전트 자율성은 새로운 문제도 만들어요. Codex는 레포지토리에 이미 존재하는 패턴을 복제해요—고르지 않거나 최선이 아닌 것들도요. 시간이 지나면서 이건 필연적으로 드리프트로 이어져요.
처음에는 인간이 이걸 수동으로 처리했어요. 우리 팀은 매주 금요일(주의 20%)을 “AI slop” 정리에 쓰곤 했어요. 당연히 그건 확장이 안 됐어요.
대신 우리가 “골든 원칙”이라고 부르는 것들을 레포지토리에 직접 인코딩하고 정기적인 정리 프로세스를 만들었어요. 이 원칙들은 미래 에이전트 실행을 위해 코드베이스를 읽기 좋고 일관되게 유지하는, 의견이 담긴 기계적 규칙이에요. 예를 들어: (1) 불변 조건을 한 곳에 모으기 위해 직접 만든 헬퍼보다 공유 유틸리티 패키지를 선호하고, (2) 데이터를 “YOLO 스타일”로 탐색하지 않아요—에이전트가 형태를 임의로 추측해서 그 위에 코드를 쌓는 일이 없도록, 경계에서 타입을 검증하거나 타입이 있는 SDK에 의존해요. 정기적으로 백그라운드 Codex 작업이 이탈을 스캔하고, 품질 등급을 업데이트하고, 타겟 리팩터링 PR을 열어요. 대부분 1분 이내에 리뷰하고 자동 머지할 수 있어요.
이건 가비지 컬렉션처럼 동작해요. 기술 부채는 고이자 대출과 같아요. 복리로 불어나도록 놔뒀다가 고통스럽게 한 번에 해결하는 것보다, 지속적으로 작은 단위로 갚는 게 거의 항상 나아요. 인간의 취향을 한 번 캡처하면 모든 코드 라인에 지속적으로 강제돼요. 이를 통해 나쁜 패턴이 코드베이스에 며칠이나 몇 주 동안 퍼지도록 놔두는 대신 매일 잡아내고 해결할 수 있어요.
• • •
우리가 아직 배우는 중인 것들
이 전략은 OpenAI 내부 런칭과 도입까지 지금까지 잘 작동했어요. 실제 사용자를 위한 실제 제품을 구축하는 것이 우리의 투자를 현실에 붙들어 두고 장기적 유지 보수성을 향해 방향을 잡아줬어요.
아직 모르는 건 이거예요: 완전히 에이전트가 만들어가는 시스템에서 아키텍처적 일관성이 수년에 걸쳐 어떻게 유지될까요? 인간 판단이 가장 큰 레버리지를 만드는 지점은 어디이고, 그 판단을 어떻게 코드에 녹여서 복리로 쌓이게 할 수 있을까요? 모델이 계속 강력해지면 이 모든 게 어떻게 달라질까요? 이 질문들의 답은 아직 없어요.
분명해진 것은: 소프트웨어 구축에는 여전히 규율이 필요하지만, 그 규율은 코드보다 스캐폴딩에서 더 많이 나타나요. 코드베이스를 일관되게 유지하는 툴링, 추상화, 피드백 루프가 점점 더 중요해지고 있어요.
이제 우리의 가장 어려운 도전은 환경, 피드백 루프, 제어 시스템을 설계하는 것에 집중돼 있어요. 에이전트가 우리 목표를 달성하도록 돕기 위해서요: 복잡하고 믿을 만한 소프트웨어를 규모 있게 구축하고 유지하는 것이요.
Codex 같은 에이전트들이 소프트웨어 라이프사이클의 더 많은 부분을 맡아가면서, 이런 질문들은 훨씬 더 중요해질 거예요. 초기 교훈 몇 가지를 공유함으로써 여러분이 어디에 노력을 투자할지 판단하는 데 도움이 되길 바라고—그리고 그냥 뭔가를 만들어나가길 바라요.
감사의 말: 이 글에 기여해준 Victor Zhu와 Zach Brock, 그리고 이 새 제품을 구축한 전체 팀에게 특별히 감사해요.
역자 주
- AGENTS.md: AI 에이전트가 레포지토리에서 작업할 때 따라야 할 규칙과 컨텍스트를 담아두는 마크다운 파일이에요. Cursor의
.cursorrules, Claude Code의CLAUDE.md와 비슷한 개념이에요. 에이전트가 작업을 시작할 때 이 파일을 읽어 “이 프로젝트에서 어떻게 일해야 하는지”를 파악해요. agents.md에서 커뮤니티 표준을 확인할 수 있어요. ↩ - 랄프 위검 루프(Ralph Wiggum Loop): 미국 애니메이션 <심슨 가족>의 캐릭터 랄프 위검에서 따온 이름이에요. 랄프는 사랑스럽지만 단순하고 예측 가능한 실수를 반복하는 캐릭터예요. 여기서 “랄프 위검 루프”는 에이전트가 모든 리뷰어가 만족할 때까지 반복해서 수정-검토-피드백 사이클을 도는 패턴을 가리켜요. 에이전트가 완고하게 같은 실수를 반복한다는 뉘앙스가 아니라, 충분히 오래 루프를 돌리면 결국 통과한다는 실용적인 접근법이에요. 원문 링크 ↩
- Chrome DevTools Protocol (CDP): Chrome 브라우저를 외부 프로그램이 직접 제어할 수 있도록 Google이 공개한 프로토콜이에요. Puppeteer, Playwright 같은 브라우저 자동화 라이브러리들이 내부적으로 CDP를 사용해요. 여기서는 Codex가 CDP를 통해 앱의 브라우저 인스턴스를 직접 조작하고 UI 상태를 읽을 수 있게 했다는 의미예요. ↩
- LogQL: Grafana의 로그 집계 시스템 Loki에서 사용하는 쿼리 언어예요. Prometheus의 PromQL과 문법이 유사하게 설계되어 있어요.
{app=“myservice”} |= “error”같은 형식으로 로그 스트림을 필터링하고 분석해요. PromQL은 메트릭 쿼리, LogQL은 로그 쿼리라고 기억하면 돼요. ↩ - Attractive nuisance: 미국 불법행위법(tort law)에서 나온 개념이에요. 어린이를 끌어당기면서도 위험한 시설(빈 수영장, 공사 현장 등)에 대한 소유자의 법적 책임을 다루는 원칙에서 비롯됐어요. 기술 맥락에서는 “겉으로는 유용해 보이지만 실제로는 해를 끼치는 것”을 가리켜요. 여기서는 낡고 잘못된 내용을 담고 있는 커다란 지침 파일이 에이전트를 그릇된 방향으로 이끄는 함정이 된다는 뜻이에요. ↩
- 점진적 공개(Progressive disclosure): UI/UX와 정보 설계에서 쓰이는 원칙으로, 사용자(또는 에이전트)에게 처음부터 모든 정보를 한꺼번에 보여주는 대신 작은 진입점에서 시작해 필요할 때 더 깊은 정보로 안내하는 방식이에요. 여기서는 짧은 AGENTS.md가 지도 역할을 하고 상세 문서는 필요에 따라 탐색하는 구조를 가리켜요. 에이전트가 컨텍스트 한도를 효율적으로 쓸 수 있도록 정보를 계층적으로 설계하는 핵심 원칙이에요. ↩
- p-limit: Node.js 생태계에서 비동기 작업의 동시 실행 수를 제한하는 데 쓰이는 npm 패키지예요. 예를 들어 API 요청을 동시에 100개 날리는 대신, 최대 5개만 동시에 처리되도록 조절해줘요. 이 글에서는 이런 범용 패키지에 의존하는 대신 팀이 자체 헬퍼를 만들었다는 선택을 설명하기 위해 언급돼요. ↩
- OpenTelemetry: 분산 시스템의 트레이스(trace), 메트릭, 로그를 수집하고 내보내는 오픈소스 표준이에요. CNCF(Cloud Native Computing Foundation)가 관리하며, Jaeger, Prometheus, Grafana 등 다양한 백엔드와 연동돼요. 벤더에 종속되지 않는 계측 표준을 제공한다는 점에서 현대 클라우드 네이티브 환경의 사실상 표준으로 자리잡았어요. 이 글에서는 자체 map-with-concurrency 헬퍼가 OpenTelemetry 계측과 긴밀하게 통합돼 있다는 점을 강점으로 꼽고 있어요. ↩
- 경계에서 파싱(Parse, don’t validate): 소프트웨어 엔지니어 Alexis King(Lexi Lambda)이 제안한 설계 원칙이에요. 핵심은 “데이터가 시스템에 들어오는 경계 지점에서 즉시 타입을 검증하고 변환하라”는 거예요. 그 이후부터는 이미 검증된 타입만 다루게 되므로 코드 내부에 흩어진 null 체크나 타입 가드가 필요 없어져요. 에이전트 생성 코드베이스에서는 이 원칙을 강제하는 게 특히 중요해요—에이전트가 데이터 형태를 임의로 추측해서 쌓아올리는 실수를 방지하거든요. 원문 글 ↩
- 평가 하네스(Evaluation harness): AI/ML 시스템의 성능과 동작을 체계적으로 측정하는 테스트 인프라예요. 일반 소프트웨어의 유닛 테스트와 달리, 모델이나 에이전트의 출력 품질을 자동으로 채점하고 회귀를 감지하는 파이프라인을 포함해요. OpenAI처럼 AI 제품을 만드는 팀에서는 에이전트 동작을 평가하는 harness 자체도 코드베이스의 중요한 구성 요소예요. ↩
저자 소개: Ryan Lopopolo, OpenAI Member of the Technical Staff
참고: OpenAI 엔지니어링 블로그에 게시된 아티클을 번역한 것이에요.
원문: Harness engineering: leveraging Codex in an agent-first world — Ryan Lopopolo, OpenAI Engineering Blog (2026년 2월 11일)
생성: Claude (Anthropic)