포스트

OpenAI 하네스 엔지니어링 정리

OpenAI 하네스 엔지니어링 정리

출처: https://openai.com/ko-KR/index/harness-engineering/

아래는 요약 + 추가설명 위주 원본 글의 목차를 그대로 이용해서 정리했다.

OpenAI의 시도

에이전트가 스스로 문제 없이 작동하게끔 설계를 하고자 함. 수동으로 코드 라인을 전혀 작성하지 않고 소프트웨어 제품의 내부 베타를 구축하고 출시하는 실험을 진행

엔지니어링 팀 업무의 방향성

환경을 설계하고, 의도를 명시하며, Codex 에이전트가 안정적인 작업을 수행할 수 있도록 피드백 루프를 구축하는 것

빈 git 리포지터리로 시작함

스캐폴드(리포지터리 구조, CI 구성, 서식 지정 규칙, 패키지 관리자 설정, 애플리케이션 프레임워크)는 codex가 직접 설정

엔지니어의 역할 재정의하기

엔지니어는 거의 대부분 프롬프트를 통해 시스템과 상호작용한다. PR을 codex가 열고, 다양한 에이전트 검토자의 통과를 얻을 때까지 반복 검증한다. 나중에 거의 모든 검토 작업은 에이전트 간에 처리되도록 전환했다.

애플리케이션의 가독성 향상

인적 자원은 제한적이기에 애플리케이션 UI, 로그, 앱 메트릭 등을 Codex가 직접 읽고 이해할 수 있도록 하여 에이전트에 더 많은 기능을 추가하기 위해 노력했다.

예를 들어, git worktree별로 앱을 부팅할 수 있게 하여 Codex가 변경사항마다 하나의 인스턴스를 실행하고 제어할 수 있도록 했습니다. 또한 Chrome DevTools Protocol을 에이전트 런타임에 연결하고 DOM 스냅샷, 스크린샷, 탐색 작업을 위한 스킬을 만들었습니다. 이를 통해 Codex는 버그를 재현하고, 수정사항을 검증하며, UI 동작에 대해 직접 추론할 수 있었습니다.

리포지터리 지식을 기록 시스템으로 만듦

교훈

Codex에 1,000페이지의 설명서가 아닌 맵을 제공해야 한다는 것

“하나의 큰 AGENTS.md⁠(새 창에서 열기)” 접근 방식을 시도해 보았지만 다음과 같이 예측 가능한 방식으로 실패했습니다.

컨텍스트는 희소 리소스. 거대한 지침 파일로 인해 작업, 코드 및 관련 문서가 복잡해져서 에이전트가 주요 제약 조건을 놓치거나 잘못된 제약 조건에 맞게 최적화를 시작하게 됩니다. 지침이 너무 많으면 지침이 되지 않음. 모든 것이 “중요”하다면 중요한 것은 아무것도 없습니다. 에이전트는 의도적으로 탐색하는 대신 로컬에서 패턴 매칭을 수행하게 됩니다. 순식간에 망가짐. 획일적인 거대 매뉴얼은 낡은 규칙들의 무덤으로 변합니다. 에이전트는 무엇이 여전히 사실인지 알 수 없고, 사람들은 더 이상 이를 유지관리하지 않으며, 파일은 조용히 매력적인 골칫거리로 변합니다. 확인하기 어려움. 단일 블롭은 기계적 점검(커버리지, 신선도, 소유권, 교차 연결)에 적합하지 않으므로 드리프트는 불가피합니다.

여러가지 markdown파일을 배치하는 예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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

AGENTS.md를 백과사전으로 취급하는 대신 목차로 취급한다.

목표는 에이전트가 리포지터리 자체에서 직접 전체 비즈니스 도메인에 대해 추론할 수 있도록 하는 것

즉 AGENTS.md는 “이 주제를 알고 싶으면 이 문서를 보라”고 안내만 해주고, 실제 깊이 있는 정보는 각 전용 문서에 있는 구조이다.


계획(plan)도 코드나 문서처럼 정식으로 관리되는 산출물로 취급한다.

  • 복잡한 작업은 진행 상황과 왜 그런 결정을 내렸는지를 기록한 실행 계획 문서로 만들어 리포지터리에 버전 관리하며 저장

이 지식 베이스를 사람이 성실하게 유지보수해주길 기대하지 않고, 기계적으로 강제한다

  • 전용 린터와 CI 작업이 문서가 최신 상태인지, 서로 링크가 잘 연결되어 있는지, 형식이 올바른지를 자동으로 검사한다. 그리고 “doc-gardening”이라는 반복 실행되는 에이전트가 실제 코드 동작과 어긋나는 낡은 문서를 찾아내 스스로 수정 PR을 올린다.

에이전트의 가독성이 목표

인간 엔지니어의 목표는 에이전트가 리포지터리 자체에서 직접 전체 비즈니스 도메인에 대해 추론할 수 있도록 하는 것이다.

에이전트의 관점에서 보면 실행 중에 컨텍스트 내에서 액세스할 수 없는 것은 사실상 존재하지 않는 것이다.

Codex에 더 많은 컨텍스트를 제공한다는 것은 임시 지침으로 너무 많은 부담을 주는 것이 아니라 올바른 정보를 정리하고 노출하여 에이전트가 추론할 수 있도록 한다는 의미한다.

기술 선택에도 영향

개발팀은 에이전트가 완전히 이해하고 다룰 수 있는 단순하고 안정적인 기술을 선호했다.

필요한 기능만 직접 작게 구현하는 편이 나은 경우도 있다. 외부 라이브러리는 내부 동작이 불투명해서 에이전트가 추론하기 어렵기 때문이다.

시스템을 에이전트가 직접 들여다보고 검증하고 고칠 수 있는 형태로 만들수록 에이전트의 작업 효율이 크게 올라간다.

아키텍쳐 및 취향 강제 적용

문제점: 문서만 잘 정리해둔다고 해서 에이전트가 만든 코드베이스가 저절로 일관성을 유지하지는 않는다.

-> 팀은 세세한 구현 방식까지 일일이 간섭하지는 않으면서도, 절대 어겨서는 안 되는 규칙(불변 조건)만큼은 강제로 지키게 만드는 방식을 택했다.

비즈니스 영역은 정해진 층(타입 → 설정 → 저장소 → 서비스 → 실행 → UI 같은 순서)을 통해서만 데이터가 흐르도록 만들고, 인증이나 로깅처럼 여러 영역에 걸치는 기능은 반드시 하나의 정해진 통로(Providers)를 거치게 했다.

로깅 형식, 이름 짓는 규칙, 파일 크기 제한 같은 것들을 맞춤형 린트로 강제하고, 이 린트가 오류를 낼 때는 단순히 “틀렸다”고만 하는 게 아니라 어떻게 고쳐야 하는지 안내까지 함께 주입해서 에이전트가 스스로 수정할 수 있게 한다.

병합 철학을 변화시키는 처리량

‘병합 전에 꼼꼼히 막아서 확인하는’ 방식의 개발 규범이 오히려 발목을 잡기 시작했다.

pull request는 오래 열려있지 않고 빠르게 처리되며, 테스트가 가끔 불안정하게 실패하더라도 그걸 붙잡고 무기한 막기보다는 일단 넘어가고 다음 실행에서 다시 확인하는 식으로 처리한다.

코드 생산 속도를 사람이 검증하는 속도로 따라갈 수 없기 때문에 “일단 빠르게 진행하고, 문제가 생기면 그때 고친다”는 쪽으로 병합 철학 자체를 바꾼 것이다.

다만 위의 방식이 항상 올바른 것은 아니며 유기적으로 변화할 필요가 있다.

“에이전트 생성”의 실제 의미

“제품 코드를 AI가 짰다”는 좁은 의미가 아니라, 리포지터리에 존재하는 사실상 모든 것을 에이전트가 만들었다는 훨씬 넓은 의미이다.

에이전트가 뭔가를 잘 못 해내면 그걸 탓하기보다 “도구나 가이드, 문서 중에 뭐가 빠졌길래 이런 일이 생겼나”를 파악하는 신호로 받아들이고, 그 보완책 역시 사람이 직접 만드는 게 아니라 Codex를 시켜서 리포지터리에 반영한다.

자율성 수준의 증가

리포지토리 안에서 많은 설계가 들어가 있기에 완성도 있는 아웃풋이 나오는 것이지 아무 리포지토리나 완성도 있게 아웃풋이 나오는 것은 아니다.

즉, 많은 투자를 해야 원하는 아웃풋을 생산할 수 있다.

엔트로피 및 가비지 컬렉션

Codex는 리포지터리 안에 이미 존재하는 패턴을 그대로 따라 하는 경향이 있는데, 그 패턴이 설령 고르지 못하거나 최적이 아니더라도 그대로 복제해버린다. 즉, 안좋은 것들이 누적되기 시작한다.

대안은 “황금 원칙”을 아예 리포지터리 자체에 규칙으로 박아 넣고, 정기적인 자동 정리 프로세스를 만드는 것이었다.

예를 들어 매번 즉석에서 만든 헬퍼 함수 대신 공유 유틸리티 패키지를 쓰게 하거나, 경계를 제대로 검증하지 않고 추측만으로 데이터를 다루는 “묻지마식” 코딩을 못 하게 막는 식이다.

그리고 Codex의 백그라운드 작업이 주기적으로 돌면서 규칙에서 벗어난 부분을 찾아내고, 품질 점수를 갱신하고, 필요하면 리팩터링용 pull request를 스스로 만들어낸다.

기술 부채를 매일 조금씩 갚아나가는 편이 훨씬 낫다.

우리가 여전히 배우고 있는 점

코드베이스의 일관성을 지켜주는 툴링과 추상화, 피드백 루프를 잘 설계하는 일이 점점 더 중요해지고 있다.

에이전트가 복잡하고 안정적인 소프트웨어를 대규모로 만들고 유지할 수 있도록 도와주는 환경, 피드백 루프, 통제 체계를 잘 설계하는 일이 중요하다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.