에이전트에게 프레임워크를 제공하는 것을 멈춘 이유
요약
글쓴이는 에이전트 코딩 도구의 한계점을 지적하며, 프레임워크에 대한 깊은 이해가 부족함을 강조합니다. 특히 런타임(runtime)에서만 발생하는 복잡한 버그나 프레임워크 스케줄러 관련 문제는 에이전트가 파일 단위로 추론하는 방식으로는 해결하기 어렵다고 설명합니다.
핵심 포인트
- 에이전트는 런타임 오류를 관찰할 수 없어 근본 원인 파악이 어려움.
- 프레임워크의 복잡한 스케줄링 및 라이프사이클 문제는 에이전트가 다루기 힘듦.
- 정적 검사(static checking)만으로는 발견하기 어려운 런타임 버그가 존재함.
- 명시적인 코드는 프레임워크 오버헤드와 관련된 버그를 피할 수 있음.
저는 Vue와 Angular에서 SPA(Single Page Application)를 배포해 왔습니다. 오늘날 제 프로젝트의 대부분 UI 코드는 코딩 에이전트에 의해 작성되며, 그 아래 라이브러리는 제가 직접 만든 것입니다: @relax.js/core. 이 라이브러리는 라우팅, 폼, 템플릿 및 DI를 갖춘 작은 Web Component 라이브러리이며 가상 DOM(virtual DOM)은 없습니다.
이것은 서류상으로는 이상한 선택입니다. 이 시리즈는 이것이 왜 작동하는지, 어디서 작동하지 않는지, 그리고 그것이 작동하도록 만들기 위해 제가 무엇을 구축해야 했는지에 관한 것입니다.
저에게 불리한 점
에이전트는 수백만 개의 Vue 컴포넌트와 Angular 모듈로 훈련되었습니다. Vue SFC의 첫 초안은 보통 맞습니다. 하지만 Relaxjs 컴포넌트의 첫 초안은 보통 틀립니다 :O 그것이 습관을 가지고 옵니다. connectedCallback을 async로 표시하고 브라우저가 기다리기를 기대합니다. 반응형 스토어(reactive store)를 찾습니다. 라이브러리가 이미 소유하고 있는 것 옆에 자체 submit 리스너를 추가합니다.
라이브러리와 함께 제공되는 핵심 기술은 이 문장으로 시작됩니다. 왜냐하면 그것이 실패 모드이기 때문입니다:
React에서 가져온 패턴들은 컴파일되고, 타입 검사되며, 아무것도 하지 않습니다.
저는 직접 React를 작성한 것은 아니지만, 에이전트가 프롬프트 없이 그것을 작성하는 것을 지켜봤고, 다른 사람이 시키지 않을 때 그들이 찾는 것이 바로 그것입니다.
저에게는 두 번째 불리한 점이 있습니다. Angular의 컴파일러는 템플릿에 대해 타입 검사를 합니다. vue-tsc도 Vue SFC에 대해 같은 작업을 수행합니다. 템플릿의 오타는 아무것도 실행되기 전에 빌드 오류가 됩니다. 하지만 템플릿이 문자열인 라이브러리에서는, {{user.naem}}은 페이지가 렌더링될 때까지 그냥 문자열일 뿐입니다. 이것에 대해서는 나중에 기사에서 다룰 것이며, 그것이 저를 충분히 괴롭혀서 수정하게 만들었습니다.
그래서: 더 안 좋은 사전 지식(priors), 그리고 최근까지 약한 정적 검사(static checking). 왜 애쓰해야 할까요?
에이전트가 실제로 갖는 것
에이전트는 브라우저를 열 수 없습니다. 그것은 파일을 읽고, 이름을 검색하고, 타입 검사를 실행하며, 테스트를 실행합니다. 이것이 전체 피드백 루프입니다. 런타임(runtime)에서만 관찰 가능한 것은 그것에게 보이지 않습니다.
이제 Vue와 Angular에서 제가 가장 많은 시간을 들여 해결했던 버그들, 리뷰를 통과한 버그들에 대해 생각해 보세요:
- 내가 생각했던 것보다 한 틱(tick) 늦게 발동되어 DOM에 이전 값이 표시되던
watch로직. - 의존성이 조건문 뒤에서 읽히기 때문에 재계산되지 않던 computed 속성.
- 업데이트가 zone 외부에서 발생하여 실행되지 않았던 변경 감지(Change detection) 메커니즘.
- 다음 사이클에 도착하는
@Input을 가정했던ngOnInit라이프사이클 훅.
이러한 문제들은 증상이 나타나는 파일 내에서는 보이지 않습니다. 원인은 프레임워크의 스케줄러(scheduler)에 있으며, 이를 찾으려면 DevTools를 열고 브레이크포인트를 설정하며 관찰해야 합니다. 에이전트는 이러한 작업을 수행할 수 없습니다. 에이전트는 자신이 연 파일을 근거로 추론하고, 그 파일이 올바르다고 결론 내린 후, 임의로 무언가를 수정하기 시작합니다. 이것이 에이전트가 하는 가장 비용이 많이 드는 작업입니다: 잘못된 위치에 그럴듯한(plausible) 수정을 생성하는 것입니다.
명시적인 코드는 이러한 종류의 버그를 가지고 있지 않습니다. user가 변경된 바로 그 위치에서 this.nameSpan.textContent = user.name와 같이 업데이트가 발생하면, 업데이트는 변화가 일어난 곳에 있습니다. 리뷰어는 읽음으로써 이를 검증할 수 있고, 에이전트도 할 수 있습니다. 무엇인가가 나중에 그것이 실행되었는지 결정하지 않습니다.
에이전트에게 도움이 되는 것들
소규모 라이브러리에 대한 일반적인 주장은
작고 명시적이라는 것만으로는 충분하지 않습니다. '에이전트가 원칙적으로 여기서 작동할 수 있다'는 것을 '에이전트가 실제로 여기서 작동한다'로 바꾼 세 가지 요소가 있습니다:
-
문서(docs)가 아닌 스킬(Skills). 이 라이브러리는 에이전트가 시작하기 전에 로드하는 짧은 파일 세트를 제공하며, 그 문장들 각각은 에이전트가 습관적으로 잘못 이해할 수 있는 내용입니다. 문서에서는 작동 방식을 설명하고, 스킬에서는 무엇을 잘못하게 될지 알려줍니다. 이 둘의 경계는 명시되어 있으며 읽어볼 가치가 있습니다.
-
침묵(Silence)이 오류로 바뀜. 경로를 해결하지 못하는 템플릿은 빈 문자열을 반환합니다. 이는 페이지 위의 사람에게는 공백일 뿐이지만, 에이전트에게는 녹색 테스트입니다. 이제 이러한 조용한 실패들은 모두 하나의 오류 채널을 통해 보고되며, 테스트 도우미(test helper)가 이 채널을 단언문(assertions)으로 만듭니다.
-
체커(Checker).
npx @relax.js/core check는 호출 지점의 TypeScript 타입과 비교하여 모든 템플릿 표현식을 해결하고tsc-스타일의 줄을 출력합니다. 이는 빌드 과정에서 컴파일러 없이 Angular의 템플릿 타입 검사와 대부분의 격차를 해소하며, 그렇게 합니다.
그리고 테스트 시퀀스: mount(), flush(), fakeServer(), mountRouting()입니다. 에이전트는 제가 클릭하도록 요청하는 것이 아니라 vitest를 실행하여 검증합니다.
여전히 프레임워크를 선택할 경우
만약 에이전트의 제로샷(zero-shot) 정확도가 전부인 게임이라면, 즉 아무도 diff를 검토하지 않고 스킬을 로드하지 않는다면, Vue나 Angular가 선험적 지식(priors)만으로 승리합니다. 앱이 깊게 상호 의존적인 상태를 가진 대규모라면, 반응형 엔진은 그 복잡성을 정당화하며, 저는 라이브러리의 README에서도 그렇게 말했습니다. SSR이 필요하다면, 여기에는 아무것도 없습니다.
에이전트가 작성한 내용을 사람이 읽는 소~중규모 SPA의 경우, 저는 명시적 모델(explicit model)이 매번 더 저렴하다고 느꼈으며, 이 시리즈의 나머지가 그 증거입니다.
다음: 스킬이란 무엇이며 왜 그것이 문서화된 내용이 아닌지에 대해 다룹니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기