병목 현상은 생성(Generation)의 문제가 아니었다
요약
AI 에이전트가 초래하는 '에이전트적 기술 부채' 문제를 진단하고, 이를 해결하기 위한 구조적 제약 방안을 제시합니다. 단순 코드 생성을 넘어 컨텍스트 조사와 독립적 검증 단계를 포함한 멀티패스(Multi-pass) 접근법의 중요성을 강조합니다.
핵심 포인트
- 자율 에이전트는 리뷰 속도보다 빠르게 아키텍처 부채를 축적함
- 단순 프롬프팅 대신 컨텍스트 조사(Context Interrogation) 단계가 필수적임
- 빌더와 검증자 에이전트를 분리하는 멀티패스 워크플로우 권장
- 시스템 프롬프트보다 구조적이고 결정론적인 제약 메커니즘이 필요함
AI 에이전트(AI agents)는 믿을 수 없을 정도로 빠르게 코드를 작성합니다. 그리고 소프트웨어 아키텍처(software architecture)를 그보다 훨씬 더 빠르게 파괴합니다.
이것은 더 이상 비밀이 아닙니다. 이제는 '에이전트적 기술 부채 (agentic technical debt)'라는 이름이 붙었으며, 이를 뒷받침하는 일련의 연구들과 대략적인 합의가 존재합니다. 즉, 자율 에이전트(autonomous agents)는 그 어떤 리뷰 프로세스(review process)가 흡수할 수 있는 속도보다 더 빠르게 아키텍처 부채(architectural debt)를 축적한다는 것입니다.
표준적인 AI 코딩 에이전트를 복잡하고 레거시가 통합된 기업 환경에 투입하면 속도를 얻을 수 있습니다. 하지만 그 대가를 치러야 합니다. 의존성 주입 (dependency-injection) 경계를 조용히 깨뜨리고, 독립적으로 유지되도록 설계된 모듈들을 결합하며, 다음 주요 릴리스(major release) 전까지는 드러나지 않을 아키텍처 드리프트 (architectural drift)를 심어놓게 됩니다.
이제 이러한 진단은 어디에서나 볼 수 있습니다. 해결책 또한 빠르게 등장하고 있습니다. 질문해야 할 가치가 있는 문제는 에이전트가 드리프트(drift)를 일으키느냐가 아닙니다. 그것은 이미 결론이 난 문제입니다. 대신, 규제 대상 코드베이스(regulated codebase)를 에이전트에게 맡기기 전에 어떤 메커니즘이 무엇을 보장해야 하는지를 물어야 합니다.
저는 결함이 그것을 배포한 스프린트(sprint)보다 더 오래 지속되는 C++, .NET Framework, 네이티브 모듈 (native modules) 등이 혼재된 규제 도메인의 소프트웨어를 다룹니다. 그런 환경에서는 '생성된 코드 라인 수 (lines of code generated)'를 최적화하는 것이 잘못된 방향입니다. 올바른 질문은 더 좁고 더 어렵습니다:
에이전트를 얼마나 결정론적(deterministically)으로 제약할 수 있는가 — 그리고 그 제약이 유지되었음을 어떻게 증명할 것인가?
아래의 모든 내용은 그 질문에 대한 답변입니다.
원샷 프롬프팅(one-shot prompting)이 아닌 멀티패스(Multi-pass)
대부분의 팀은 에이전트에게 사용자 스토리(user story)를 건네주고 풀 리퀘스트(pull request)를 요청합니다. 이는 환각 (hallucination)을 유발하는 레시피입니다. AI는 모호한 사양을 잡아내는 대신 오히려 증폭시킵니다.
해결책은 의무적인 컨텍스트 조사 (Context Interrogation) 패스입니다. 에이전트가 단 한 줄의 코드를 쓰기 전에, 티켓을 읽고, 저장소 컨텍스트 (repository context)를 스크래핑하며, 이해하지 못하는 부분에 대해 구조적인 질문을 생성해야 합니다.
그런 다음 에이전트는 멈춥니다. 엔지니어가 답변할 때까지 기다립니다. 모호함이 해결되었을 때에만 구현 단계로 넘어갑니다. 에이전트는 제약 사항에 따라 행동하기 전에, 자신이 그 제약 사항을 이해하고 있음을 증명해야 합니다.
그리고 구현(implementation) 그 자체는 결코 단일 에이전트의 말 한마디에 의존하지 않습니다. 빌더 패스(builder pass)가 변경 사항을 생성하면, 초안에 이해관계가 없는 별도의 에이전트인 독립적인 검증자 패스(verifier pass)가 사람이 디프(diff)를 확인하기도 전에 명세(spec) 및 리스크 티어(risk tier)를 기준으로 이를 감사(audit)합니다. 빌더는 제안하고, 검증자는 기소하며, 인간은 판결합니다.
선의보다는 엄격한 경계가 낫다
"DI 컨테이너를 깨뜨리지 마세요"라고 말하는 시스템 프롬프트(system prompt)만으로는 복잡한 C++ 모놀리스(monolith)를 보호할 수 없습니다. 모델은 결국 이를 무시할 것입니다.
경계는 구조적이어야 합니다. 에이전트는 저장소(repo)에 대한 개방형 접근 권한이 아니라, 빌드 파이프라인(build pipeline)에 고정된 특정하고 제약된 CLI 명령을 통해 실행되어야 합니다. 지침은 아키텍처 문서와 분리된 상태를 유지합니다. 즉, 에이전트는 인간 엔지니어와 정확히 동일한 ARCHITECTURE.md를 읽고, 이를 바탕으로 변경을 제안하며, 그 후 시스템은 인간의 중단 게이트(stop gate)를 위해 멈춥니다.
대부분의 팀이 모호하게 처리하는 또 다른 차이점이 있습니다. 문서에만 존재하는 규칙은 관례(convention)일 뿐, 통제(control)가 아닙니다. 파이프라인이 이를 기계적으로 확인하지 않는다면, 여러분은 다시 선의에 의존하는 상태로 돌아가는 것입니다. 단지 형식이 더 잘 갖춰졌을 뿐입니다. 규칙이 거버넌스(governance)라고 불리기 위해서는 마크다운(markdown)에서 머지 체크(merge check) 단계로 격상되어야 합니다.
프롬프트는 제안입니다. 게이트는 벽입니다.
리스크에는 두 개의 축이 있다
이 지점이 대부분의 거버넌스 프레임워크가 조용히 실패하는 곳입니다. 이들은 "리스크"를 단일 다이얼로 축소해 버린 뒤, 사소한 작업에는 과도한 게이트를 설정하는 반면 위험한 작업은 그대로 통과시켜 버립니다.
여기에는 두 가지 독립적인 질문이 있으며, 각각 별도의 분류 체계(taxonomy)가 필요합니다.
행동 리스크(Action risk)는 작업(operation)에 관한 것입니다. 파일을 읽는 것은 브랜치(branch)를 삭제하는 것이 아니며, 브랜치 삭제는 빌드 파이프라인을 다시 쓰는 것이 아닙니다. 행동 리스크는 에이전트가 스스로 무엇을 할 수 있는지에 대해 규정합니다.
변경 리스크(Change risk)는 결과(consequence)에 관한 것입니다. 로그 메시지를 편집하는 것은 규제 대상 시스템의 계산 코어(calculation core)를 건드리는 것과 다릅니다. 변경 리스크는 변경 사항이 배포되기 전까지 얼마나 많은 게이트를 통과해야 하는지를 규정합니다.
두 가지 모두가 필요한 이유는 불일치하는 셀(mismatched cells) 때문입니다. 에이전트가 파이프라인을 수정하고 싶어 할 수도 있습니다. 운영 측면에서는 두려운 일이지만, 변경 사항 자체는 단 한 줄의 린트(lint) 단계일 뿐입니다. 해당 동작을 게이트(Gate)로 통제한 다음 통과시키면 됩니다. 반대의 경우가 위험한 상황입니다. 가장 지루한 작업인 단일 파일 편집이 우연히 계산 코어(calculation core)에 위치하게 되는 경우입니다. 단일 축 모델(single-axis model)은 작업이 작아 보인다는 이유로 이를 통과시킵니다. 하지만 이중 축 모델(two-axis model)은 키 입력이 아무리 사소했더라도 그 결과가 엄청나기 때문에 이를 차단합니다. 축을 분리하면 마침내 마찰(friction)이 실제 위험이 존재하는 곳에 위치하게 됩니다.
지저분한 초안(dirty draft)의 종말
업계는 AI가 "지저분한 초안(dirty draft)"을 생성하면 인간이 이를 다듬는다는 점을 대체로 수용해 왔습니다. 하지만 규제가 있는 환경에서는 지저분한 초안을 다듬는 작업이 처음부터 새로 쓰는 것보다 더 오래 걸리는 경우가 많습니다. AI가 전제한 모든 숨겨진 가정을 검증해야 하기 때문입니다.
인간의 게이트가 열려 지저분한 초안이 사라지기 전에, 단순히 코드가 실행되었는지가 아니라 동작이 명세(spec)가 의도한 방식대로 변경되었음을 증명하는 요구 사항 테스트(Demand tests)가 필요합니다. 그러면 당신은 추측을 검토하는 일을 멈추게 됩니다. 대신 검증 가능하고 프로덕션 준비가 된(production-ready) 제안을 검토하기 시작할 것입니다.
코드를 테스트한다면, 에이전트는 누가 테스트하는가?
에이전트 도구(agentic tooling)에 관한 논의에서 거의 아무도 던지지 않는 질문이 있습니다. 에이전트의 출력물은 테스트되지만, 에이전트 자체는 누가 테스트하는가 하는 점입니다.
이 시스템에서 모든 에이전트 기능은 이름이 지정된 기술(skill)이며, 기술은 단순히 배포되는 것이 아니라 '졸업'합니다.
기술은 실험적인 단계로 시작됩니다. 더 넓은 자율성을 얻으려면 평가 게이트(evaluation gate)를 통과해야 합니다. 이는 실제 작업 항목에서 추출한 골든 케이스(golden cases) 세트이며, 두 가지 방식으로 동시에 점수가 매겨집니다. 결정론적 단언(Deterministic assertions)은 기계가 확인할 수 있는 구조적 실패를 잡아냅니다. 예를 들어, 판결 필드(verdict field)가 존재하는지, 리스크 등급(risk tier)이 나타났는지, 에이전트가 수정 권한이 없는 코드를 수정했다고 주장했는지 등을 확인합니다. LLM 판사(LLM judge)는 정규 표현식(regex)이 결코 할 수 없는 것을 평가합니다. 즉, 등급 분류가 실제로 정확했는지, 추론이 타당했는지, 시니어 엔지니어가 이 논거를 수용할 것인지 등을 점수화합니다.
두 부분 모두 검증기 (validators)에 의해 강제되며, 검증기 그 자체 또한 검증됩니다 — 고정 장치 계약 (fixture contracts), 샘플 보고서, 기술 레지스트리 항목에 기록된 증거 등이 이에 해당합니다. 기술 (skill)이 업데이트될 때, 골든 케이스 (golden cases)는 해당 기술의 회귀 테스트 망 (regression net)이 됩니다. 기술의 판단력을 조용히 저하시키는 프롬프트 수정은 실제 티켓 (ticket)에 닿기도 전에 게이트 (gate)에서 차단됩니다.
이것이 바로 변화의 핵심입니다: 에이전트 (agent)에 대한 신뢰는 더 이상 막연한 느낌이 아니라, 증거를 바탕으로 한 성숙도 상태 (maturity state)가 됩니다. 단위 테스트 (Unit tests)가 변경으로부터 코드베이스를 보호한다면, 평가 (Evals)는 코드베이스를 에이전트로부터 보호합니다.
기억하는 게이트
결정론적 경계 (Deterministic boundaries)와 리스크 축 (risk axes)이 경계면을 확보합니다. 하지만 이것만으로는 확장이 불가능합니다.
모든 스톱 게이트 (stop gate)의 결과물은 정보이며, 대부분의 팀은 이를 버려버립니다. 사람이 변경 사항을 차단하고, 이유를 입력하고, 수정된 버전을 병합하면 — 다음에 에이전트가 호출될 때, 에이전트는 다시 제로(zero)에서 시작합니다.
그러면 안 됩니다. 이 시스템은 에이전트에게 하나의 통합된 메모리 (memory)를 제공합니다: 정확히 두 가지 작업인 캡처 (Capture)와 회상 (Recall)만을 수행하는 단일 관리형 기록 저장소입니다. 사람이 통과를 차단하면, 그 판결은 하나의 기록으로 캡처됩니다. 에이전트가 다음 티켓을 집어 들 때, 단순히 ARCHITECTURE.md를 읽는 것에 그치지 않고 — 자신의 지난 세 번의 통과 시도가 왜 중단되었는지에 대한 로그를 회상합니다.
하지만 — 그리고 이 부분이 메모리와 부채 (liability)를 구분 짓는 지점입니다 — 메모리 그 자체도 게이트를 거칩니다. 모든 기록은 그 출처 (provenance)를 지닙니다: 어떤 종류의 학습인지, 소스의 강도가 어떠했는지, 그리고 어떤 게이트가 이를 승인했는지 말입니다. 명시적인 인간의 승인은 기존의 표준 문서 (canonical document)로부터 도출된 추론과 같지 않으며, 스키마 (schema)는 이 둘이 모호해지는 것을 허용하지 않습니다. 자신의 메모리에 자유롭게 쓸 수 있는 에이전트는 결국 자신의 실수를 정책 (policy)으로 세탁하게 될 것입니다. 반면 메모리 쓰기가 코드와 동일한 게이트 규율을 통과하는 에이전트는 그럴 수 없습니다.
이것이 매일 아침 당신의 아키텍처를 다시 설명해야 하는 도구와, 스스로를 발명하도록 허용되지 않으면서도 당신의 판단을 내재화하는 시스템 사이의 차이입니다. 복리로 쌓이는 제약 (Constraint that compounds).
통제되는 것처럼 보이는 것은 통제되는 것이 아니다
마지막 함정 하나를 더 언급하겠습니다. 왜냐하면 이것은 위에서 언급한 모든 것들의 끝에 기다리고 있는 함정이기 때문입니다.
이 글에서 언급된 모든 메커니즘 — 게이트 (gates), 축 (axes), 평가 (evals), 메모리 (memory) — 을 구축할 수는 있겠지만, 여전히 믿음에 의존하여 운영될 수도 있습니다. 문서로만 존재하는 거버넌스 프레임워크 (governance framework)는 주장일 뿐, 사실이 아니기 때문입니다. 성숙한 팀의 실패 모드 (failure mode)는 법이 없는 에이전트가 아닙니다. 그것은 아름답게 문서화되어 있지만, 아무도 실제로 작동했음을 증명할 수 없는 통제 장치들입니다.
따라서 모든 스킬 실행 (skill run)은 텔레메트리 (telemetry) 기록을 생성해야 합니다: 무엇이 실행되었는지, 어떤 작업 항목 (work item)에 대해 실행되었는지, 어떤 위험 계층 (risk tier)과 조치 수준 (action level)이었는지, 검증기 (verifier)가 어떤 증거를 카운트했는지, 변이 (mutation)가 제안되었는지 그리고 인간이 이를 승인했는지, 게이트 (gate)가 무엇을 결정했고 그 이유는 무엇인지에 대한 기록입니다. 이는 무언가 고장 났을 때 grep으로 검색하기 위한 로그가 아니라, 시스템이 스스로를 거버넌스하는 과정을 담은 구조화된, 추가만 가능한 (append-only) 기록입니다.
그 기록이야말로 "우리는 거버넌스가 적용된 프로세스를 가지고 있다"라는 주장을 감사 추적 (audit trail)으로 바꾸어 주는 것입니다. 그것은 품질 팀이 검사할 수 있고, 규제 기관이 추적할 수 있으며 — 솔직히 말해서 — 첫 번째 예산 검토를 통과하여 도입 명령을 유지할 수 있게 해주는 것입니다. 속도가 파일럿 (pilot) 프로젝트를 승리로 이끈다면, 증명이 프로그램 전체를 승리로 이끕니다.
진짜 병목 현상
에이전트 기반 도입 (agentic adoption)을 확장하는 것은 더 똑똑한 모델을 찾는 문제가 아닙니다. 그것은 더 엄격한 공장을 건설하는 문제입니다. 즉, 자신의 기계를 테스트하고, 자신의 판결을 기억하며, 영수증(증거)을 보관하는 공장 말입니다.
거버넌스 (Governance)는 관료주의적 형식주의 (red tape)가 아닙니다. 그것은 당신이 빠르게 달릴 수 있게 해주는 가드레일 (guardrail)입니다. 이 전환기에서 승리하는 팀은 가장 많은 자율성을 가진 팀이 아닐 것입니다. 그들은 오케스트레이션 계층 (orchestration layer)이 인간의 모든 "아니오"를 에이전트의 다음 제약 조건 (constraint)으로 전환하고, 실행할 때마다 그 제약 조건이 유지되었음을 증명할 수 있는 팀이 될 것입니다.
병목 현상은 결코 생성 (generation)의 문제가 아니었습니다. 그것은 게이트 (gate)로부터 배우는 시스템을 구축하는 문제였습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기