AI 에이전트를 워크플로우에 붙이는 순간, 개발자가 가장 먼저 마주치는 감각은 '빠르다'가 아니라 '뭔가 이상하다'다. 두 에이전트가 동시에 실행되는데 한쪽이 다른 쪽의 작업을 취소하거나, 프롬프트를 보낸 것도 없는데 모델이 엉뚱한 곳을 클릭하거나, 재시도가 오히려 상황을 악화시킨다. 이 혼란의 원인은 대부분 에이전트 자체의 문제가 아니다. 에이전트를 실제 환경에 붙이기 전에 설계해야 할 것들을 설계하지 않은 결과다.
최근 dev.to에 올라온 두 편의 글이 이 문제를 서로 다른 각도에서 짚는다. 하나는 데스크톱 자동화 제어 플레인 CliGate를 만들면서 겪은 에이전트 병렬 처리의 리소스 충돌 경험이고, 다른 하나는 MCP(Model Context Protocol)를 활용해 Claude가 GitHub와 DEV.to를 직접 다루게 만든 자동화 사례다. 두 글 모두 'AI 에이전트를 실제 환경에 붙였을 때 어떤 설계 문제가 생기는가'를 다루고 있어, 단순한 도구 소개를 넘어 실무 설계 관점의 통찰을 건진다.
1. 리소스 소유권을 명시적으로 설계하라
CliGate 사례에서 핵심 교훈은 단순하다. 병렬 실행 자체는 문제가 아니었다. 문제는 모든 에이전트가 모든 리소스를 동시에 쓸 수 있다고 가정한 설계였다. 코드 실행, API 호출, 백그라운드 요약은 얼마든지 병렬로 돌릴 수 있다. 하지만 마우스와 키보드, 화면이라는 물리 리소스는 다르다. 이건 동시에 소유할 수 없는 리소스다.
해결책은 '더 스마트한 오케스트레이션'이 아니었다. 오히려 반대였다. 데스크톱 입력을 리스를 임대하는 방식처럼 다루는 것—태스크가 마우스와 키보드를 사용하기 시작하면 해당 태스크가 현재 데스크톱 홀더가 되고, 다른 태스크는 그 위를 클릭할 수 없다. 기다린다. 규칙은 간단하다: 데스크톱이 필요 없으면 병렬로 실행하고, 필요하면 큐에 넣고, 취소는 사용자가 명시적으로 요청할 때만 한다. 이 '덜 스마트한' 설계가 오히려 사용자에게 예측 가능한 동작을 돌려줬다.
프론트엔드 관점으로 번역하면, 에이전트가 공유하는 리소스—파일 시스템, 브라우저 탭, DOM 조작 API—를 목록으로 만들고, 각 리소스에 명시적인 소유권 모델을 붙이는 일이 먼저다. '두 에이전트가 같은 파일을 동시에 수정할 수 있는가'라는 질문에 답하지 않고 에이전트를 켜면, 충돌은 예정된 버그가 된다.
2. 도구 경계를 컨텍스트로 설계하라
MCP 서버 사례는 다른 차원의 설계 문제를 보여준다. Claude가 GitHub와 DEV.to를 다루게 하기 위해 100줄 미만의 Python으로 MCP 서버를 구성했고, 7개의 도구를 정의해 모델이 대화 중에 직접 API를 호출하게 만들었다. '내 가장 별 많은 레포는?'이라고 물으면 Claude가 실제로 GitHub API를 쿼리해 답한다.
이 사례에서 주목할 지점은 기술 스택의 단순함이 아니다. 도구의 경계를 어떻게 설계했는가다. 각 도구는 명확한 책임 범위를 가진다. get_github_profile은 프로필 통계만, create_article은 아티클 생성만. 도구 간 의존성을 최소화하고, 각 도구가 독립적으로 호출 가능하게 설계된 구조다. 이게 MCP의 핵심 가치이기도 하다—모델이 무엇을 할 수 있는지를 명확하게 선언하고, 그 경계 안에서만 행동하게 만든다.
에이전트에게 '무엇이든 해도 된다'는 권한을 주는 것과, '이 일곱 가지를 할 수 있다'고 경계를 설계하는 것은 전혀 다른 결과를 낳는다. 전자는 테스트하기 어렵고, 디버깅하기 어렵고, 신뢰하기도 어렵다. 에이전트 도구 설계는 API 설계와 같은 원칙이 적용된다. 인터페이스가 명확할수록 시스템은 예측 가능해진다.
3. 신뢰성 레이어를 프로덕션 전에 설계하라
세 번째 설계 문제는 가장 눈에 덜 띄지만 가장 비싸게 돌아온다. dev.to의 또 다른 글은 하루 1만 건의 채용공고를 처리하는 LLM 파이프라인을 프로덕션에 올린 후 API 비용이 폭발한 경험을 다룬다. 스테이징에서는 완벽히 동작했다. 프로덕션에서는 중복 호출, 불필요한 재임베딩, 과다한 모델 사용이 비용을 키웠다.
해결책은 세 가지였다. 배치 API로 비실시간 작업을 묶어 비용을 낮추고, 지수 백오프와 지터를 적용한 재시도 로직으로 API 장애를 흡수하고, 함수 호출에 엄격한 JSON 스키마를 붙여 모델 출력을 제약했다. 그리고 모든 LLM 호출에 구조화된 로그를 남겼다—어떤 모델을, 어떤 프롬프트로, 얼마의 토큰을 써서, 어떤 결과를 냈는지.
에이전트 자동화를 워크플로우에 붙이는 순간부터 이 신뢰성 레이어는 선택이 아니다. 재시도가 없으면 장애가 조용히 퍼지고, 비용 추적이 없으면 청구서가 먼저 이상징후를 알려주고, 출력 검증이 없으면 파이프라인 하류에 쓰레기 데이터가 쌓인다. 특히 프론트엔드에서 에이전트 결과를 렌더링한다면—에러 상태, 로딩 지연, 예상 밖의 출력 형식—이 모두 UI 설계의 변수가 된다.
설계 순서가 도구 선택보다 중요하다
세 가지 설계 문제는 각각 다른 층위에 있지만 하나의 공통 패턴을 공유한다. 에이전트는 '켜면 알아서 동작하는 것'이 아니라 '경계를 설계해야 제대로 동작하는 것'이라는 사실이다. 리소스 소유권을 명시하지 않으면 충돌이 생기고, 도구 경계를 설계하지 않으면 테스트할 수 없는 블랙박스가 되고, 신뢰성 레이어 없이 프로덕션에 올리면 비용과 품질이 동시에 무너진다.
MCP의 확산과 Claude Code 같은 에이전트 도구의 성숙은, AI를 워크플로우에 붙이는 일이 점점 쉬워지고 있다는 신호다. 하지만 쉽게 붙일 수 있다고 해서 설계를 생략해도 된다는 의미는 아니다. 오히려 진입 장벽이 낮아질수록, 설계 없이 에이전트를 붙이는 팀과 설계부터 하는 팀의 격차는 더 빨리 벌어진다. 빠른 프로토타이핑은 좋다. 그 전에 소유권, 경계, 신뢰성—이 세 가지를 화이트보드에 먼저 그리는 것이 더 좋다.