MCP는 합성 가능성이 낮고 컨텍스트 비용이 과도하다는 이유로, 대규모 자동화에는 코드 생성 중심 접근이 더 낫다는 주장. LLM을 직접 추론에 쓰기보다 코드를 생성·검증·반복하는 파이프라인이 신뢰성과 확장성에서 유리하며, 향후에는 생성 코드 실행 후 LLM으로 결과를 판정하는 하이브리드 추상화가 필요하다고 제안한다.
작성일: 2025년 7월 3일
트위터에서 나를 지켜봐 온 분들은 알겠지만, 나는 지금의 MCP(Model Context Protocol)에 큰 팬이 아니다. 아이디어가 싫다는 건 아니다. 다만 광고된 대로 잘 작동하는 사례를 내가 못 봤을 뿐이다. 내 생각에 MCP에는 두 가지 큰 결함이 있다:
간단한 실험이 이를 보여 준다. GitHub MCP로 GitHub 작업을 끝내 본 뒤, gh CLI 도구로 같은 일을 다시 해 보라. 거의 확실히 후자가 컨텍스트를 훨씬 효율적으로 쓰고 원하는 결과에 더 빨리 도달할 것이다.
이에 대한 내 입장에 관해 받은 피드백도 이야기하고 싶다. 나는 MCP를 에이전틱 코딩 맥락에서 광범위하게 평가했는데, 거기서 한계가 가장 잘 드러났다. 피드백 중 하나는 일반적인 코드 생성에는 MCP가 큰 의미가 없을 수 있다는 것이다. 모델이 이미 코드를 꽤 잘 생성하므로, 오히려 금융회사 같은 곳의 도메인 특화 작업 자동화처럼 최종 사용자 애플리케이션에 더 의미가 있다는 주장이다. 또 다른 피드백은 더 많은 도구에 접근하고 훨씬 복잡한 작업을 처리할 수 있는 미래를 보아야 한다는 것이었다.
내 현재 입장은, 내 데이터가 가리키는 바에 따르면 지금의 MCP는 추론 의존성 때문에 언제나 코드를 직접 쓰는 것보다 쓰기 어려울 것이라는 것이다. 오늘날 도구 수를 늘리려는 접근을 보면 모두가 필터링 레이어를 포함한다. 모든 도구를 LLM에 넘겨 작업에 맞춰 걸러 달라고 요청하는 식이다. 지금까지는 그보다 나은 방법이 별로 제안되지 않았다.
내가 생각하기에 이것은 비프로그래밍, 도메인 특화 작업에서도 마찬가지로 성립한다 — 현재 형태의 MCP를 쓰지 말아야 하는 이유. 그 경우에도 합성 능력 덕분에 코드 생성이 더 나은 선택이기 때문이다.
이 문제를 생각하는 방식은 이렇다. AI가 없을 때, 소프트웨어 엔지니어로서 문제를 해결하는 도구는 코드다. 비개발자라면 코드는 멀리 느껴질 수 있다. 하지만 사람들이 수작업으로 하는 많은 일들은 사실 소프트웨어로 자동화가 가능하다. 문제는 그 소프트웨어를 써 줄 사람을 찾는 것이다. 틈새 환경에서 일하고 본인이 프로그래머가 아니라면, 굳이 프로그래밍 책을 집어 들고 배우려 하지도 않을 것이고, 당신의 특정 문제를 해결하기 위해 맞춤 소프트웨어를 만들어 줄 개발자를 찾기도 어렵다. 그래, 어떤 과제는 추론이 조금 필요할 수 있다. 하지만 모든 단계에서 항상 추론이 필요한 것은 아니다.
“자기 자신을 셸 스크립트로 대체한다”는 말을 하는 데에는 이유가 있다. 예전부터 그래 왔기 때문이다. LLM과 프로그래밍을 결합하면, 셸 스크립트로 자신을 대체하는 대신 LLM으로 자신을 대체하는 아이디어로 이어진다. 하지만 여기에는 세 가지 문제가 있다: 비용, 속도, 그리고 전반적 신뢰성. 이 모든 문제를 도구 사용을 생각해 보기 전 혹은 MCP를 고려하기 전에 먼저 해결해야 한다. 자동화된 작업이 대규모에서도 제대로 동작하는지 보장하는 방법을 먼저 찾아야 한다.
자동화의 핵심은 정말로 반복될 일을 자동화하는 데 있다. 다시는 일어나지 않을 단발성 변경을 자동화하지는 않는다. 실제로는 기계가 진짜 생산성 향상을 줄 수 있는 일을 자동화하기 시작한다. 한두 번 시행착오를 거치며 작동 방식을 찾고, 그다음에는 기계가 그걸 천 번 반복하게 하는 것이다. 이런 반복에는 코드 사용을 항상 권장할 강력한 이유가 있다. 기계에게 추론을 통해 하라고 지시하면, 특히 작은 작업에서는 작동할 수 있다. 하지만 그 경우 검증이 필요하고, 검증에는 처음부터 사람이 하는 것과 맞먹는 시간이 들 수 있다. LLM에게 직접 계산을 시키면 어느 정도는 된다. 하지만 LLM이 계산을 수행하는 파이썬 코드를 쓰게 하는 편이 훨씬 낫다. 왜냐하면 첫째, 우리는 계산 결과가 아니라 공식을 검토할 수 있기 때문이다. 우리가 직접 검토할 수도 있고, LLM을 판정자(judge)로 삼아 그 접근법 이 올바른지 판단하게 할 수도 있다. 파이썬이 올바르게 계산하는지는 굳이 검증할 필요가 없다. 그건 신뢰할 수 있다. 그래서 과제 해결에 코드 생성을 택하면, LLM이 제대로 추론했기를 바라는 대신 우리가 접근을 더 쉽게 검토·검증할 수 있는 쪽으로 조금 더 다가가게 된다.
이건 단순 계산을 훨씬 넘어선다. 예컨대 이 블로그를 보자. 나는 최근 전체 블로그를 reStructuredText에서 Markdown으로 변환했다. 이 변환을 꽤 오래 미뤘는데, 이유는 조금 게을렀던 탓도 있다. 하지만 LLM을 투입해 볼까 할 정도로 게을러졌을 때도, LLM이 컨텍스트가 부족해지면 텍스트를 환각으로 채우거나 표현을 살짝 바꿔서 회귀(regression)를 만들지 모른다는 불신이 있었다. 미묘한 회귀가 생길까 봐 걱정이 컸다.
그래도 LLM은 썼다. 다만 그 변환을 코드 로 하게 했다.
LLM에게 reStructuredText를 Markdown으로 변환하는 핵심 작업을 시키되, 반드시 기반 AST(추상 구문 트리)를 활용하도록 지시했다. 즉, reStructuredText를 실제 reStructuredText AST로 파싱하고, 그것을 Markdown AST로 변환한 뒤, 최종적으로 HTML로 렌더링하라고 했다. 기존과 비교 가능한 최종 산출물과 함께 중간 변환 단계를 갖게 된 셈이다.
그런 다음, 예전 HTML과 새 HTML을 비교하는 스크립트를 작성하라고 했다. 비교를 위해 필요한 기본 정리를 거친 뒤 diff를 수행하도록 했다. 또한 어떤 종류의 변환 오류가 허용 가능한지 고민하라고 했다. 사용 중인 Markdown 라이브러리와 reStructuredText 라이브러리가 예컨대 각주를 다르게 렌더링하기 때문에, 구문이 정확히 매칭되어도 HTML이 다르게 나올 수 있다. 이런 알려진 기술적 제한으로 원본과 일치하지 않는 부분을 스스로 파악하고, 그 격차를 스크립트에서 보정하도록 했다.
그다음에는 수백 개 파일의 출력물 전반을 훑어 차이를 분석하고, 다시 에이전틱 루프로 되돌아가 추가 반복을 하도록 도와줄 세 번째 스크립트를 만들게 했다.
그 후 이 과정을 루프로 돌렸다. 모든 포스트를 한꺼번에 주지 않고, 처음에는 10개로 시작해 차이가 충분히 줄어들 때까지 반복했고, 그다음 전부로 확장했다. 대략 30분쯤 돌린 뒤 돌아와 보니 꽤 만족스러운 상태였다.
이 변환의 핵심은 LLM이 이 일을 해낼 수 있었느냐가 아니다. 내가 이 프로세스를 신뢰할 수 있었다 는 점이다. 접근법을 검토할 수 있었기 때문이다. 게다가 다른 LLM에게 첫 번째 LLM이 작성한 코드와 변경 사항에 대해 의견을 묻기도 했다. 데이터가 손실되지 않을 것이라는 확신이 훨씬 커졌다. 기계적으로 옳은 과정이라는 느낌이 들었고, 관찰하며 부분 점검을 할 수 있었다. 최악의 경우에도 회귀는 사소한 Markdown 구문 오류에 그쳤고, 텍스트 자체가 망가지는 일은 없었다.
또 하나 중요한 점은 추론이 비교적 일정하기 때문에, 이 과정에서의 추론 비용은 반복 횟수와 샘플 크기에 비례해 늘어나지만, 전체적으로 변환하려는 문서 수에는 좌우되지 않는다는 것이다. 결국에는 항상 전체 문서를 대상으로 돌렸지만, 15개 문서와 150개 문서를 돌리는 수고는 거의 비슷했다. 마지막 LLM 기반 분석 단계가 검토해야 할 것이 그리 많이 늘어나지 않았기 때문이다(파일의 사소한 차이는 이미 모두 건너뛰도록 해 두었다).
장황하게 말했지만, 이 전체 변환은 전부 코드로 흘렀다. 사람의 입력에서 시작해 코드를 만들고, LLM을 판정 단계로 쓰며 반복한다. 이 변환 방식을 일반적인 과제에도 똑같이 적용할 수 있다.
예를 들어, 여러분이 사용할 수 있는 MCP 중 하나는 Playwright다. 모든 경우에 Playwright를 코드 접근법으로 대체하는 일은 아주 어렵다. 본질적으로는 브라우저를 원격 제어하는 일이고, 페이지를 읽고, 내용을 이해하고, 다음 버튼을 클릭하는 식의 작업이기 때문이다. 이런 시나리오는 매 단계의 추론을 없애기가 매우 어렵다.
하지만 이미 어떤 페이지인지 알고 있다면 — 이를테면 여러분이 작업 중인 자신의 앱을 탐색하는 경우라면 — 이제는 Playwright 파이썬 스크립트를 쓰게 하고 그걸 실행하도록 지시할 수 있다. 이 스크립트는 그 많은 단계를 추론 없이 순차적으로 수행할 수 있다. 내 경험상 이 접근은 훨씬 빠르고, 모델이 여러분의 코드를 이해하기 때문에 일반적으로 결과도 정확하다. 실시간으로 내비게이션하고, 페이지 내용을 읽고, 버튼을 찾고, 입력을 누를 필요가 없다. 대신 전체 과정을 한 번에 자동화하는 단일 파이썬 스크립트를 작성하며, 비교할 수 없을 만큼 적은 컨텍스트만 요구한다.
이 과정은 반복 가능하다. 스크립트를 한 번 작성하고 나면 추가 추론 없이 100번, 200번, 300번도 실행할 수 있다. 이는 MCP가 보통 제공하지 못하는 커다란 이점이다. 일반적이고 추상적인 MCP 도구 호출을 LLM이 제대로 이해하게 만드는 일은 극도로 어렵다. 예컨대 MCP 클라이언트를 셸 스크립트에 바로 내장해 코드 생성으로 원격 MCP 서비스를 효율적으로 호출하게 만들고 싶지만, 실제로 그렇게 하는 건 매우 어렵다. MCP 도구들이 비추론 기반 자동화를 염두에 두고 작성되어 있지 않기 때문이다.
또 한 가지 아이러니지만 사실인 점: 나는 인간이지 MCP 클라이언트가 아니다. 나는 스크립트를 실행하고 디버그할 수 있지만, MCP 호출을 신뢰성 있게 하는 방법은 도무지 모르겠다. 매번 도박 같고 디버그가 엄청나게 어렵다. 반면 코드 생성 중 Claude Code가 만들어 주는 작은 도구들은 정말 좋아한다. 그중 몇 개는 내 개발 프로세스의 장기적인 구성요소로 편입하기도 했다.
나도 모른다. 하지만 목적 있는 에이전틱 코딩을 위한 코드 생성을 어떻게 더 좋게 만들 수 있을지 생각해 볼 흥미로운 시점임은 분명하다. MCP는 잘만 돌아가면 사실 꽤 훌륭하다. 하지만 현재 형태는 확장 불가능한 막다른 골목처럼 느껴진다. 특히 대규모 자동화로 갈수록 그렇다. 추론에 너무 크게 의존하기 때문이다.
아마 그래서 MCP가 잘하는 것과 코드 생성을 아우르는 더 나은 추상을 찾아야 할지도 모르겠다. 그러려면 더 좋은 샌드박스를 만들고, 에이전트가 추론을 위해 일종의 팬아웃/팬인을 할 수 있도록 API를 노출하는 방식을 고민해야 할 것이다. 요지는 가능한 한 많은 일을 생성된 코드에서 수행하고, 그다음 대량 코드 실행 이후에 LLM의 마법으로 우리가 한 일을 판정하게 만드는 것이다.
또 비개발자도 이해할 수 있도록, 생성된 코드가 무엇을 하는지 LLM이 인간 언어로 설명할 수 있을 만큼 충분한 컨텍스트를 함께 제공하는 코드 생성 방식도 꽤 흥미로울 것 같다. 그러면 개발자가 아닌 사용자도 이런 플로우를 활용할 수 있을 것이다.
어쨌든 나는 사람들이 MCP를 우회해 다른 가능성을 탐색해 보기를 권한다. LLM에 코드를 쓸 권한을 주면 훨씬 더 많은 일을 해낼 수 있다.
다음은 읽어 보면 좋을 글과 보면 좋을 영상들이다:
이 글의 태그: ai