Harness 이전에 Attractor: 대규모 AI 개발을 위한 방법론
요약
대규모 AI 협업 시스템 구축 시 단순한 제약(Harness)보다 시스템이 지향해야 할 장기적 구조(Attractor)를 정의하는 것이 중요함을 강조합니다. 기존 엔지니어링이 상태(State) 평가에 집중했다면, AI 시대에는 궤적 수렴(Trajectory Convergence)을 모델링하는 방법론이 필요합니다.
핵심 포인트
- 단순 가드레일보다 시스템의 장기적 수렴 구조 정의가 우선되어야 함
- AI 협업은 기존의 상태 중심 평가를 넘어 궤적 수렴 문제를 다뤄야 함
- 전통적 방법론은 교정 메커니즘일 뿐, 궤적 자체를 모델링하지 못함
AI가 개발에 깊이 참여하는 시스템에서, 제1원칙(first-principles)에 기반한 질문은 "AI의 행동을 어떻게 제약할 것인가"가 아니라, "시스템이 어떤 장기적 구조로 수렴해야 하는가"입니다. 이러한 방향이 명확히 정의된 후에야 harness (하네스), guardrail (가드레일), verification (검증), audit (감사), closure (종결)와 같은 메커니즘이 진정한 의미를 가질 수 있습니다. 그렇지 않다면, 그것들은 단지 잘못된 베이스라인을 효율적으로 고착화할 뿐입니다. 이러한 주장은 불가피한데, 왜냐하면 AI 협업은 소프트웨어 엔지니어링 방법론에서 오랫동안 부가적인 요소로 취급되어 온 "trajectory convergence (궤적 수렴)" 문제를 명시적으로 모델링해야 하는 위치로 밀어올리기 때문입니다.
- AI 엔지니어링을 논할 때 사람들이 가장 먼저 떠올리는 것이 왜 Harness인가
AI 보조 개발에 관한 현재의 논의에서 가장 흔히 사용되는 용어들은 다음과 같습니다:
- guardrail (가드레일)
- verification (검증)
- review (리뷰)
- feedback loop (피드백 루프)
- agent harness (에이전트 하네스)
이러한 직관의 집합은 기본적으로 하나의 전제를 가정합니다: 시스템의 올바른 방향이 이미 알려져 있다는 것입니다. 그 전제가 주어지면, 문제들은 자연스럽게 다음과 같이 변합니다:
- 편차를 어떻게 제한할 것인가
- 실패를 어떻게 가능한 한 빨리 드러낼 것인가
- 리뷰를 어떻게 더 엄격하게 만들 것인가
- 에이전트가 통제를 벗어나는 것을 어떻게 방지할 것인가
이러한 언어는 작은 작업에는 충분합니다. 스크립트, CRUD 페이지, 또는 로컬 버그 수정의 경우, 당신은 보통 "올바른 결과가 무엇인지"를 이미 알고 있으며, 남은 작업은 주로 실행과 검증에 관한 것입니다. 하지만 대규모 시스템을 진정으로 어렵게 만드는 것은 종종 "선을 넘지 않게 하는 방법"이 아니라, "애초에 어떤 경로가 올바른 장기적 구조인가"입니다. 이 질문에 답하기 위해 우리는 한 가지를 먼저 인식해야 합니다: 모든 현재의 harness 유형 메커니즘은 암묵적인 전제에 기반하고 있습니다. 즉, 평가 단위가 주로 상태(state)이며, 궤적 수렴(trajectory convergence)은 개발자의 암묵적인 방향 감각에 의존하여 뒷받침된다는 것입니다. AI 협업은 바로 이 뒷받침(backstop)을 제거합니다.
제거된 뒷받침 (The Backstop That Has Been Removed)
TDD, DDD, Clean Architecture, Agile, Code Review 문화 등 어떤 주류 엔지니어링 방법론을 열어보더라도, 그들의 일급 평가 대상(first-class evaluation targets)은 거의 항상 상태(state)입니다. 즉, "지난 100개의 PR(Pull Request)의 누적된 방향이 옳은가"가 아니라 "이 PR이 올바른가"를 평가합니다. "진화 과정에서 아키텍처가 지속적으로 안정적인 형태를 향해 나아가고 있는가"가 아니라 "현재 아키텍처가 깨끗한가"를 평가합니다. "테스트 스위트 자체가 구현 세부 사항에 의해 부식되었는가"가 아니라 "테스트가 현재의 동작을 커버하는가"를 평가합니다.
전통적인 방법론들이 궤적 인식(trajectory awareness)이 전혀 없는 것은 아닙니다. 리팩터링(refactoring), 기술 부채(technical debt), 코드 스멜(code smells), 진화적 아키텍처(evolutionary architecture), 그리고 Lehman의 소프트웨어 진화 법칙(Lehman's laws of software evolution)은 모두 궤적을 다룹니다. 하지만 이러한 개념들은 방법론 내에서 근본적인 대상(fundamental objects)이 아니라, 교정 메커니즘(corrective mechanisms)이자 진단용 어휘(diagnostic vocabulary)로서 존재합니다. 어떤 이론이 궤적 문제를 사후적으로 인정하기 위해 "부채(debt)", "취약성(fragility)", "부식(corrosion)"과 같은 부정적인 개념을 지속적으로 도입해야만 한다면, 이는 그 이론의 기초 범주 집합(foundational category set)에 긍정적인 궤적 대상이 결여되어 있음을 드러내는 것입니다.
이 상태 중심의 패러다임이 오랫동안 작동할 수 있었던 이유는 인간 엔지니어 자신이 낮은 빈도와 안정적인 방향 감각을 가진 섭동원(perturbation source) 역할을 했기 때문입니다. 한 사람이 하루에 수백 줄의 코드를 작성하며, 각 섭동의 크기는 작고, 마음속에는 지속적인 방향 감각이 유지됩니다. 상태 수준의 품질 보증(quality assurance)이 프로그래머의 암묵적인 방향 감각과 결합되어 궤적이 표류하지 않도록 보장합니다.
AI 협업은 이 뒷받침(backstop)을 제거합니다. AI는 더 빠른 프로그래머가 아닙니다. AI는 구조적으로 다른 섭동원입니다:
-
높은 빈도 (High frequency): 단 한 번의 세션으로 몇 분 만에 여러 모듈에 걸친 수백 줄의 코드를 생성할 수 있습니다.
-
높은 크기 (High magnitude): 각 생성 단계가 경계를 넘나드는 구조적 변화를 도입할 수 있습니다.
-
지속적인 방향성 부재 (No persistent directional sense): 각 세션은 독립적이며, 세션 간에 암묵적인 아키텍처적 판단이 전달되지 않습니다.
-
국소적으로 매우 합리적임 (Highly reasonable locally): 인터페이스, 타입, 테스트 및 문서가 동시에 생성될 수 있으며, 각 요소는 개별적으로 검토될 때 검사를 통과합니다. 마지막 지점이 매우 중요합니다. AI 협업에서는 시스템 전체가 지속적으로 표류하는 동안 모든 상태 수준의 체크(state-level checks)를 통과할 수 있습니다. nop-chaos-flux의 Plan 76이 전형적인 사례입니다. array-editor / key-value에서 로컬 상태 미러(local state mirror)를 제거하려는 시도는 즉시 11개의 테스트 실패를 초래했습니다. 하지만 드러난 것은 특정 버그가 아니라 더 깊은 사실이었습니다. 테스트 자체가 이전 구현의 타이밍에 밀접하게 결합(tightly coupled)되어 버렸다는 점입니다. 상태(state) 관점에서는 모든 점진적 변화가 리뷰와 CI를 통과했지만
이를 대규모 AI 개발로 번역하면, 이 언어는 서로를 정의하는 네 가지 근본적인 객체에 대응합니다: 상태 공간 (State Space): 현재의 제약 조건 하에서 시스템이 진화할 수 있는 모든 가능한 구현 상태. 어트랙터 (Attractor): 장기적인 진화 과정 동안 시스템이 반복적으로 끌려 돌아가는 안정적인 구조. 궤적 (Trajectory): 생성, 검증, 수정의 각 라운드를 거친 후 남겨진 실제 진화 경로. 제어 (Control): 국소적 신호(local signals)를 통해 궤적에 지속적으로 영향을 미치는 다양한 메커니즘. 기존 제약 조건 하에서 리포지토리(repository)는 코드, 문서, 테스트가 진화할 수 있는 모든 가능한 조합의 집합을 가지고 있으며, 이것이 상태 공간을 구성합니다. 인간, AI, 리뷰, CI 및 문서 업데이트의 연속적인 행동은 진화 규칙을 구성합니다. 이 두 가지의 상호작용이 살아있는 리포지토리 이력(repo history)을 형성하며, 이것이 곧 궤적입니다. 어트랙터는 장기적인 반복(iteration) 과정 동안 시스템이 반복적으로 끌려 돌아가는 안정적인 구조입니다. 한 가지 분명히 짚고 넘어가야 할 점은, 이 언어가 단순히 "더 우아하게 말하는 방식"이 아니라 새로운 존재론(ontology)의 기초가 되는 언어라는 것입니다. 상태 공간, 어트랙터, 궤적, 제어라는 네 가지 개념은 서로를 정의합니다. 하나라도 누락되면 나머지 세 가지를 엄밀하게 표현할 수 없습니다. 이러한 개념들을 기존 존재론의 언어(아키텍처, 제약 조건, 목표, 프로세스)로 번역하려고 시도하면 필연적으로 정보 손실이 발생하며, 이것이 바로 "Attractor Guided Engineering은 결국 Harness 아닌가?"와 같은 오독의 근본 원인입니다. 네 가지 객체 사이의 관계는 다음과 같습니다: 상태 공간 (State Space) → 어트랙터 (Attractor) → 궤적 (Trajectory) → 제어 (Control). 이는 수사적인 순서가 아니라 논리적 의존성입니다. 상태 공간을 정의하지 않으면 어트랙터를 논할 수 없고, 어트랙터를 정의하지 않으면 궤적이 표류하고 있는지 판단할 수 없으며, 궤적에 대한 판단 없이는 제어가 목표를 가질 수 없습니다.
여기서 말하는 "이전"은 논리적 우선순위를 의미합니다. 실행 단계에서 어트랙터 (Attractor)와 하네스 (Harness)는 폐쇄 루프 (Closed loop) 내에서 함께 진화하지만, 어트랙터는 개념적으로 하네스와 독립적으로 정의될 수 있는 반면, 하네스는 개념적으로 어트랙터와 독립적으로 정의될 수 없습니다 (편차를 수정하려면, 무엇을 향해 수정해야 하는가?). 이러한 비대칭성은 동역학계 (Dynamical systems)에서의 목적인 (Final cause)과 작용인 (Efficient cause) 사이의 관계와 일치합니다. 함께 진화한다는 점을 인정한다고 해서 "이전"이라는 주장이 약화되지는 않습니다. 물리적 시스템에서도 목적인과 작용인은 함께 작용하지만, 목적인은 여전히 작용인을 위한 논리적 전제 조건으로 남습니다.
- 어트랙터 (Attractor)란 정확히 무엇인가
잘 알려진 로렌츠 어트랙터 (Lorenz attractor)를 예로 들어보겠습니다. 이는 미분 방정식 (Differential equations)에 의해 암묵적으로 정의됩니다. 이는 사전에 모든 올바른 궤적을 열거하는 체크리스트도 아니며, 단순한 경계도 아닙니다. 어트랙터 내부에서 국소적 궤적 (Local trajectories)은 매우 복잡하며 단기적으로는 거의 카오스 (Chaotic)처럼 보이지만, 전체는 무작위로 흩어지지 않고 항상 동일한 유형의 기하학적 형상으로 다시 끌려 들어옵니다.
로렌츠 어트랙터: 국소적 궤적은 매우 복잡하지만, 전체는 여전히 안정적인 구조에 의해 제약됩니다. 카오스 (Chaos)가 무작위성 (Randomness)과 동일한 것은 아닙니다. 국소적인 예측 불가능성이 전체가 통제 불능임을 의미하지는 않습니다. 엔지니어링 어트랙터도 동일한 방식으로 작동합니다. 이는 "하나씩 열거된 모든 허용된 지점의 목록"이라기보다는 "방정식으로 정의된 다양체 (Equation-defined manifold)"에 가깝습니다. 방정식은 다양체 위의 모든 점을 사전에 작성하지 않으며, 오직 어떤 관계가 성립해야 하는지만 규정합니다. 이러한 관계를 만족하는 점들은 자연스럽게 동일한 구조 내에 놓이게 됩니다.
전통적인 아키텍처 개념과의 핵심 차이점: DDD(Domain-Driven Design)와 Clean Architecture 또한 장기적인 구조를 강조하지만, 이들은 그 장기적 구조를 목표 상태(target state)로 취급합니다. 즉, 방법론의 역할은 "X에 도달하는 것"입니다. 반면 궤적 온톨로지(trajectory ontology)는 장기적 구조를 어트랙터(attractor, 끌개)로 취급합니다. 즉, 방법론의 역할은 "당신이 얼마나 멀리 밀려나더라도 X의 근방으로 돌아오는 것"입니다. 두 번째 관점은 섭동(perturbation, 교란) 하에서의 안정성을 다룹니다. 이것이 바로 AI 협업 시나리오에서의 핵심 문제이며, 전통적인 방법론들이 일급 개념 도구(first-class conceptual tools)를 갖추지 못한 바로 그 문제입니다. 개념적 표류(conceptual drift)를 방지하기 위해, 엔지니어링에서의 어트랙터는 엄격하게 세 가지 계층으로 나눌 수 있습니다:
- 구조 계층 (Structural layer, 어트랙터 자체): 책임이 어떻게 나뉘는지, 경계가 어떻게 설정되는지, 어떤 구조적 관계가 위반될 수 없는지 등과 같은 소수의 고차 불변량(high-order invariants).
- 캐리어 계층 (Carrier layer, 어트랙터의 엔지니어링 캐리어): 이러한 불변량들을 버전 관리가 가능하고 감사 가능한(auditable) 문서로 외재화하는 것.
- 구현 계층 (Implementation layer, 어트랙터의 순간적 투영): 이러한 불변량들을 실제로 구현하고 있는 현재 코드의 부분들.
어트랙터는 문서가 아닙니다. 문서는 어트랙터의 캐리어입니다. 어트랙터는 코드가 아닙니다. 코드는 어트랙터의 순간적인 투영입니다. 이러한 계층화는 흔히 발생하는 혼란, 즉 "아키텍처 문서와 코드가 충돌할 때, 우리는 무엇을 따라야 하는가?"라는 질문을 해결하기 때문에 중요합니다. 답변은 "어느 쪽이 더 권위 있는가"가 아니라, "당신은 어떤 질문을 던지고 있는가?"입니다. 만약 현재의 구현 동작에 대해 묻고 있다면, 코드가 권위가 있습니다. 만약 시스템이 어디로 수렴해야 하는지를 묻고 있다면, 문서가 권위가 있습니다. 만약 왜 특정 경로가 폐기되었는지를 묻고 있다면, 로그/버그/분석이 권위가 있습니다. 각 계층은 오직 그에 상응하는 질문에 대해서만 권위를 가집니다. 5.
저장소(Repository)가 시스템의 진실을 담아내기 시작하며, Harness 인프라가 필수적이 됨: AI가 깊게 참여하게 되면, 저장소는 더 이상 단순히 인간 인지(Human cognition)의 외부 투영체가 아닙니다. 저장소는 시스템의 진실을 운반하는 유일한 매개체가 되기 시작합니다. 그 누구도 시스템의 모든 설계 세부 사항을 완전히 파악할 수 없으며, 프로젝트 소스 코드(Source code)를 참조하지 않고서는 시스템 설계에 관한 질문에 답할 수 없습니다. 다음 세션에서 다시 읽을 수 있는 것은 저자의 마음속에 있는 완전한 의도가 아니라, 코드(Code), 차이점(Diffs), 로그(Logs), 테스트(Tests), 그리고 문서(Documentation)입니다. 이는 직접적인 엔지니어링 결과를 초래합니다: 생성(Generation)과 수용(Acceptance)은 반드시 진정으로 분리되어야 합니다. 생성 작업은 동일한 컨텍스트(Context) 내에서 AI에 의해 빠른 속도로 완료될 수 있지만, 수용은 더 이상 그 생성 컨텍스트 자체에 의존할 수 없습니다. 당신은 저장소의 외부 증거로 돌아가 다음을 재평가해야 합니다: 동작이 실제로 구현되었는지, 현재 베이스라인(Baseline)이 실제로 무엇인지, 어떤 자료가 권위가 있는지, 그리고 이 "완료"가 단지 완료되었다는 느낌일 뿐인지 말입니다. 저장소가 시스템의 진실을 담아내기 시작하기 때문에 생성과 평가가 분리되어야 하며, 생성과 평가가 분리되어 있기 때문에 Harness는 "더 안전한 엔지니어링 습관"에서 필수적인 인프라(Infrastructure)로 격상됩니다. 전통적인 협업에서 Harness는 선택적인 규율이었으나, AI 협업에서는
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기