지난 3년간 ChatGPT 플러그인, 커스텀 지시문, MCP, Claude Code의 스킬까지 이어진 LLM 확장 방식의 변천과 앞으로의 방향을 정리한 글
3년 전만 해도 “LLM을 쓴다”는 건 긴 텍스트를 채팅창에 붙여 넣고 유용한 답이 나오길 바라는 정도를 의미했다. 오늘날 우리는 에이전트를 코드베이스와 브라우저에 붙여 두고, 우리의 대리인처럼 행동하게 만든다. 이 과정 내내 수면 아래에서 끓고 있던 핵심 질문은 다음이다. 도대체 어떻게 하면 최종 사용자가 이런 시스템을 직접 커스터마이즈할 수 있을까?
모델의 성능이 향상됨에 따라, 사용자가 모델을 커스터마이즈할 수 있는 방법과 메커니즘도 함께 확장되어 왔다. 우리는 단순한 시스템 프롬프트에서 출발해 복잡한 클라이언트-서버 프로토콜까지 갔다가, 다시 되돌아오기도 했다.
이 글에서는 지난 3년간의 LLM 확장(Extension) 역사를 되짚고, 앞으로 어디로 갈지에 대한 개인적인 전망을 정리해 보려고 한다.
출시 후 불과 네 달 만에, OpenAI는 ChatGPT Plugins를 발표했다. 지금 돌아보면, 당시 기준으로 믿기 어려울 만큼 시대를 앞선 기능이었다.
아이디어는 야심찼다. LLM에 OpenAPI 스펙 링크를 주고, REST 엔드포인트를 마음껏 호출하게 두는 것이다. 표준 API를 통해 범용 도구 사용을 가능하게 하겠다는, AGI 스타일의 사고와 거의 직결된 구상이었다.
json{ "schema_version": "v1", "name_for_human": "TODO Manager", "name_for_model": "todo_manager", "description_for_human": "Manages your TODOs!", "description_for_model": "An app for managing a user's TODOs", "api": { "url": "/openapi.json" }, "auth": { "type": "none" }, "logo_url": "https://example.com/logo.png", "legal_info_url": "http://example.com", "contact_email": "hello@example.com" }
문제는? 모델이 준비가 안 되어 있었다. GPT-3.5(그리고 초기 GPT-4조차도)는 거대한 API 스펙을 다루면서 환각(hallucination)에 빠지거나, 컨텍스트 안에서 길을 잃기 일쑤였다. UX도 어색했다. 매 대화마다 일일이 플러그인을 켜고 끄는 식으로 설정해야 했다.
그 모습은 대략 이런 느낌이었다:
(당시 UI 예시를 떠올려 보면 된다.)
하지만 이때 미래의 단면을 엿볼 수 있었다. Code Interpreter 플러그인(이후 Advanced Data Analysis로 이름이 바뀜)은 없어서는 안 될 기능이 되었고, 오늘날 우리가 사용하는 강력한 샌드박스 실행 환경을 예고했다.
커스텀 지시문은 플러그인의 복잡성에 대한, 일종의 “주름 펴진(smooth brain)” 카운터 리액션이었다. 글을 쓰면서도 “이 기능이 분명 플러그인보다 먼저 나온 거 아니었나?” 하고 두 번은 확인했다.
실제로는 그냥 사용자가 정의한 프롬프트를 모든 대화 뒤에 자동으로 덧붙이는 기능이었다. 단순하고, 명확하다. 하지만 이 단순함이 큰 문제 하나를 해결했다. 바로 매번 같은 컨텍스트를 반복해서 설명해야 하는 문제였다.
이 기능은 이후 등장한 .cursorrules, CLAUDE.md 같은 파일들의 정신적 조상이라고 할 수 있다.
OpenAI는 지시문과 도구를 다시 포장해 Custom GPTs라는 형태로 내놓았다. 이건 일종의 “프롬프트 엔지니어링의 제품화” 시도였다. 페르소나, 몇 개의 파일, 그리고 몇 가지 액션을 하나로 묶어서 공유 가능한 링크로 배포할 수 있었다.
이는 플러그인이 보여줬던 개방형 약속(“아무 도구나 연결 가능하다”)에서 한발 물러나, 더 큐레이션된 단일 목적 ‘앱’ 쪽으로 방향을 튼 것이다.
지금까지는 LLM을 확장하는 수동적인 방법들을 살펴봤다. Memory 기능은 여기서 한 걸음 더 나아가, 자동 개인화 쪽으로 방향을 틀었다.
ChatGPT Memory는 대화 속에서 나온 정보를 기록해 두었다가, 이후 컨텍스트에 조용히 삽입한다. 스스로 작성되는 시스템 프롬프트에 가깝다. 예를 들어, 당신이 채식주의자라고 언급하면, 몇 주 뒤에 다시 대화해도 그 사실을 기억한다. 기능 자체는 소소해 보일 수 있지만, 사용자 개입 없이 장기 상태를 유지하는 에이전트의 시작을 의미한다는 점에서 중요하다.
Cursor는 커스텀 지시문을 제자리에 갖다 놓음으로써 판을 바꾸었다. 바로 레포 안에 말이다.
.cursorrules 파일은 하나의 계시 같은 존재였다. 더 이상 긴 컨텍스트를 채팅창에 붙여 넣을 필요 없이, 그냥 git에 커밋하면 끝이다.
처음에는 단일 파일로 시작했지만, 이후 .cursor/rules 폴더와 정교한 스코핑 구조로 진화했다. 여러 개의 룰 파일을 조직적으로 관리할 수 있게 되었고, 특정 파일 타입이나 서브디렉터리에만 적용되도록 조건을 달 수도 있었다. 확장이 처음으로 코드에 ‘자연스럽게 녹아든’ 순간이었다.
이후 Cursor는 LLM이 스스로 언제 어떤 룰을 적용할지 선택하게 하는 기능도 도입했다. 이 패턴은 뒤에서도 다시 등장한다.
2024년 말이 되자, 모델들은 마침내 실제 도구를 안정적으로 활용할 수 있을 만큼 똑똑해졌다. Anthropic의 **Model Context Protocol (MCP)**은 그에 대한 해답으로 등장했다.
MCP는 묵직한 솔루션이다. MCP 클라이언트는 MCP 서버와 지속적인 연결을 유지해야 한다. 서버는 툴 정의, 리소스, 프롬프트를 클라이언트(대부분은 에이전트)에게 제공하고, 클라이언트는 “이 도구를 호출했다”라는 메시지를 서버에 보내면, 서버가 결과를 돌려준다.
커스텀 지시문이 단지 컨텍스트를 더해 줄 뿐인 것과 달리, MCP는 모델에게 실제 능력(capabilities)을 부여한다. 레포를 읽거나, Postgres DB를 쿼리하거나, Vercel에 배포하는 것도 가능하다. 단순히 도구만 제공하는 게 아니라, 서버가 리소스(문서, 로그)와 프롬프트도 직접 에이전트에게 공급할 수 있다.
강력하긴 하지만, 다소 과한 면도 있다. 에이전트를 개발하는 입장에서는 이 복잡성이 감당할 만한 가치가 있을 수 있지만, 사용자가 직접 MCP를 설정하고 연결하도록 요구하는 것은 마찰이 크다. 이 틈을 파고들어 Smithery 같은 스타트업 전체 생태계가, MCP 사용을 쉽게 만들어 주겠다는 목표로 등장했다.
덧붙이자면, 2025년 10월에 발표된 ChatGPT apps는 MCP를 베이스 레이어로 삼아 구축되어 있다. 이는 최종 사용자가 MCP를 의식하지 않고도 쓸 수 있게 하려는 시도라고 볼 수 있다.
2025년 초에는 Claude Code가 등장했다. 이 제품은 말 그대로 생각할 수 있는 거의 모든 확장 메커니즘을 에이전트에 집어넣었다.
CLAUDE.md: 레포 단위 지시문의 사실상 표준.이 기능들이 장기적으로 얼마나 살아남게 될지는 두고 봐야겠지만, Anthropic은 이미 Output Styles를 폐지하려는 시도를 했다.
Claude Code에 추가된 다음 확장 메커니즘은, 따로 깊게 살펴볼 만할 정도로 중요하다. Agent Skills는 ChatGPT 플러그인의 부활이다.
MCP가 클라이언트-서버 프로토콜 전체를 포함하는 반면, Agent Skills는 단지 마크다운 파일과 스크립트(언어는 아무거나 가능)로 이루어진 폴더일 뿐이다.
에이전트는 단순히 skills/ 디렉터리를 스캔해서, 각 SKILL.md의 frontmatter를 읽고, 가벼운 인덱스를 만든다. 그리고 현재 작업에 적합하다고 판단될 때에만 그 스킬의 전체 내용을 읽는다. 이는 MCP의 주요 문제 중 하나, 즉 모든 툴 정의를 한꺼번에 컨텍스트 윈도우에 억지로 넣으면서 생기는 컨텍스트 부풀기(bloat) 문제를 해결한다.
Anthropic의 Skills examples 리포지토리에서, Playwright를 이용한 e2e 테스트용 스킬 구조 일부를 가져오면 다음과 같다.
textwebapp-testing/ ├── examples/ │ ├── console_logging.py │ ├── element_discovery.py │ └── static_html_automation.py ├── scripts/ │ └── with_server.py └── SKILL.md
스크립트, 예제, 일반 텍스트 지시문이 섞여 있다. 필수 파일은 오직 SKILL.md 하나다. 이 파일을 살펴보자.
markdown--- name: webapp-testing description: Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs. license: Complete terms in LICENSE.txt --- # Web Application Testing To test local web applications, write native Python Playwright scripts. **Helper Scripts Available**: - `scripts/with_server.py` - Manages server lifecycle (supports multiple servers) **Always run scripts with `--help` first** to see usage. DO NOT read the source until you try running the script first and find that a customized solution is absolutely necessary. These scripts can be very large and thus pollute your context window. They exist to be called directly as black-box scripts rather than ingested into your context window. ... skill continues ...
이건 메타데이터와 스킬 설명이 담긴 평범한 마크다운 파일일 뿐이다. 에이전트는 이 파일을 읽고, 그 안에서 자유롭게 참조되는 다른 파일들을 또 읽을 수 있다. 반면, Playwright MCP 서버는 브라우저를 조작하기 위한 수십 개의 툴 정의를 포함하고 있는 반면, 이 스킬은 단지 “bash를 쓸 수 있으니, 이렇게 Playwright 스크립트를 작성해 실행하면 된다”고 말해 줄 뿐이다.
물론 스킬을 제대로 활용하려면 에이전트가 범용적인 컴퓨터 접근 권한을 가져야 한다. 하지만 바로 여기서 Bitter Lesson이 작동한다. 일반 목적 도구를 에이전트에 쥐여 주고, 그 도구를 활용해 과제를 달성하는 방법은 에이전트가 스스로 학습하도록 믿어 주는 전략이, 특정 과제마다 특수한 도구를 만드는 전략보다 결국 더 우세할 수 있다는 이야기다.
Skills는 ChatGPT 플러그인이 처음 꿈꿨던 비전을 실제로 구현한 것에 가깝다. 모델에게 지시문과 몇 가지 범용 도구만 주고, 사이에 필요한 ‘접착(glue)’ 작업은 모델에게 맡기는 것이다. 그런데 지금 와서야 이 방식이 통할 수 있는 이유는, 아마도 이제 모델이 정말로 충분히 똑똑해졌기 때문일 것이다.
Agent Skills가 잘 작동하는 이유는 에이전트가 자기 손으로 도구를 만들 수 있다고 가정하기 때문이다(bash 명령을 통해). 코드 스니펫 몇 개만 주고, 현재 과제에 맞게 이 코드를 어떻게 실행할지 스스로 알아내라고 부탁할 수 있다.
중요한 점은, Skills가 우리가 “에이전트”를 어떻게 정의해야 하는지에 대한 새로운 관점을 제시한다는 것이다. 에이전트는 단순히 while 루프 안에 들어간 LLM이 아니다. 컴퓨터가 덧붙여진( strapped to it ) LLM이다.
Claude Code는 이 개념을 처음으로 내게 명확히 깨닫게 해 준 소프트웨어였지만, 지금 형태는 개발자에게 너무 초점이 맞춰져 있어서 최종 형태라고 보기는 어렵다. Zo Computer 같은 다른 애플리케이션은 LLM과 컴퓨터를 하나의 앱으로 묶어 보려 하지만, 여전히 최종 사용자 관점에서 컴퓨터를 충분히 추상화하지는 못했다고 느낀다. 동료에게 일을 부탁할 때, 그 사람의 파일 시스템 전체를 볼 필요는 없다. 그 사람이 컴퓨터를 가지고 있다는 사실만 알면 충분하다.
2026년을 바라보면, 우리가 사용하는 LLM 애플리케이션 대다수는 — 우리가 인식하든 못 하든 — 새로운 흥미로운 방식으로 “컴퓨터가 줄줄이 붙어 있는” 형태가 될 것이라고 예상한다.
만약 MCP를 공매도할 수 있다면 나는 그렇게 할 것이다. 그리고 우리는 다시, 에이전트를 확장하는 가장 접근성 좋은 프로그래밍 언어, 즉 자연어로 되돌아가게 되리라 본다.