개요

30편은 모델에 무엇을 읽힐 것인가의 이야기였다. 검색해서 문서를 찾아 프롬프트에 넣어주는 것까지 봤다. 그런데 거기까지는 모델이 여전히 읽고 쓰기만 한다.

언어모델이 직접 밖을 건드리게 하려면, 무엇이 더 필요한가?

날씨를 알려주려면 날씨 API를 호출해야 하고, 계산을 정확히 하려면 계산기를 써야 한다. 문장을 아무리 잘 이어 써도 오늘 서울 기온은 모델 안에 없다.

이번 편은 그 손에 해당하는 것들이다. 에이전트가 무엇인지, 도구를 어떻게 쥐여주는지, 그리고 그 도구들이 제각각이라 생긴 혼란을 정리한 MCP까지 본다.

30편에서 다룬 RAG와 헷갈리기 쉬운데, 둘의 차이도 중간에 짚는다.

교육 자료는 대외비라 슬라이드 이미지나 예제 데이터는 싣지 않는다. 개념 흐름만 내가 이해한 방식으로 재구성했고, 그림은 전부 직접 그렸다.


1. 에이전트란 무엇인가 — 관찰하고, 행동하는 것

에이전트라는 말은 AI 교과서에서 오래전부터 쓰던 단어다. 정의도 이미 있다.

센서로 환경을 인지하고, 액추에이터로 환경에 영향을 미칠 수 있는 모든 것

여기서 중요한 건 두 방향이다. 들어오는 것(관찰)과 나가는 것(행동). 온도계는 관찰만 하니까 에이전트가 아니고, 타이머로 도는 선풍기는 행동만 하니까 에이전트가 아니다. 둘 다 있어야 한다.

LLM 에이전트 — 언어모델을 머리로 쓴다

LLM 에이전트는 거대 언어모델을 핵심 두뇌(backbone) 로 삼아 환경을 이해하고 행동하는 에이전트다. 여기에는 보는 방향이 두 가지 있다.

관점 무엇을 만드는가
LLM 우선 기존 언어모델에 능력을 붙여 에이전트로 만든다 검색 에이전트, 코드 에이전트
에이전트 우선 이미 있는 에이전트에 언어모델을 넣어 말을 통하게 한다 로봇, 임바디드 에이전트

앞쪽이 우리가 흔히 만나는 쪽이다. 뒤쪽은 몸이 먼저 있고 거기에 언어 능력을 얹는 경우다.

이건 에이전트인가?

강의에서 판별 문제를 몇 개 던졌는데, 이게 개념을 잡는 데 제일 도움이 됐다.

시스템 에이전트인가
웹을 돌아다니며 정보를 모으는 LLM 그렇다 — 관찰하고 행동한다
파일을 찾아 코드를 실행해 처리하는 LLM 그렇다 — 환경을 바꾼다
검색해서 문서를 가져와 답하는 LLM (RAG) 애매하다 — 한 번 검색하고 끝, 결과를 보고 다시 판단하지 않는다
아주 복잡한 추론만 하는 LLM 아니다 — 머리만 좋을 뿐 도구도 없고 밖을 안 건드린다

세 번째가 핵심이다. 30편에서 본 RAG는 검색 한 번 → 생성 한 번으로 끝난다. 결과가 시원찮아도 다시 검색하지 않는다. 에이전트는 결과를 보고 다음 행동을 정한다. 이 되먹임이 있느냐가 갈림길이다.

RAG는 한 번 찾아보고 답하는 것, 에이전트는 찾아보고 → 확인하고 → 다시 찾는 것이다.

더 쉬운 비유로

RAG: 시험 볼 때 참고서 한 페이지를 펴놓고 답을 쓴다 에이전트: 답을 쓰다가 막히면 책을 다시 뒤지고, 계산기를 꺼내고, 틀린 것 같으면 지우고 다시 쓴다

요리로 바꿔도 된다. 레시피를 한 번 읽고 그대로 만드는 게 RAG다. 중간에 맛을 보고, 싱거우면 소금을 더 넣고, 불이 세면 줄이는 게 에이전트다. 중간에 확인하고 고치는 동작이 있느냐가 전부다.


2. 에이전트 프레임워크 — 부품 네 개와 사람 하나

에이전트가 잘 굴러가려면 갖춰야 할 게 다섯 가지라고 정리해줬다.

  • 도구 사용 — 외부 기능을 호출할 수 있는가
  • 추론과 계획 — 무엇을 어떤 순서로 할지 정할 수 있는가
  • 환경 표현 — 주변 상황을 어떤 형태로 담을 것인가
  • 환경 이해 — 그 표현을 제대로 해석하는가
  • 상호작용 — 사람이나 다른 에이전트와 말이 통하는가

이걸 부품으로 그리면 네 개가 나온다.

LLM 에이전트 프레임워크

부품 하는 일
Controller 언어모델이 앉는 자리. 요청을 이해하고 실행 계획을 세운다
Tool Set 서로 다른 기능을 가진 도구들의 모음
Environment 도구가 실제로 작동하는 무대
Perceiver 돌아온 피드백을 요약해서 컨트롤러에 넘긴다

여기에 사람(Human) 이 가운데 붙는다. 사람이 하는 일도 두 가지다. 컨트롤러에 지시를 넣고, 진행 상황을 보며 퍼시버에 피드백을 준다.

Perceiver라는 부품이 따로 있는 게 처음엔 의아했는데, 그림을 그려보고 이해했다. 퍼시버로 들어오는 입력이 두 갈래다.

  • 환경 피드백 — 도구를 실행한 결과. 로그 수천 줄, JSON 덩어리로 날것 그대로 돌아온다
  • 사람 피드백 — “그거 말고 저거”, “다시 해봐” 같은 사람의 개입

이 둘을 그대로 컨트롤러에 밀어 넣으면 컨텍스트가 터진다. 형식도 제각각이다. 그래서 한 곳에서 받아 합치고 줄이는 담당이 따로 있는 것이다.

컨트롤러는 계획을 세우고, 툴셋은 일을 하고, 퍼시버는 기계와 사람에게서 온 말을 한 덩어리로 줄여서 넘긴다.


3. 도구(Tool) — 언어모델이 손을 얻는 법

도구는 이렇게 정의됐다.

언어모델 외부에서 실행되는 프로그램에 연결되는 함수 인터페이스

중요한 건 “외부에서 실행된다”는 부분이다. 언어모델은 함수를 직접 실행하지 않는다. 함수 이름과 입력값을 생성할 뿐이다. 실행은 밖에서 한다.

도구는 세 종류

종류 무엇을 조작하나
물리 기반 실제 세계 로봇 팔, 센서, 이동 장치
GUI 기반 사람이 쓰는 화면 웹 브라우저 조작, 데스크톱 앱 클릭
프로그램 기반 코드와 데이터 API 호출, 데이터베이스 질의, 계산기

우리가 만들 서비스는 대부분 세 번째다. 두 번째는 요즘 컴퓨터 조작 에이전트로 빠르게 커지고 있는 영역이다.

두 모드를 오간다

도구를 쓴다는 건 결국 모드 전환이다.

텍스트 생성 모드와 도구 실행 모드

  1. 평소에는 텍스트 생성 모드 — 그냥 다음 토큰을 이어 쓴다
  2. 도구가 필요한 순간, 함수 호출을 나타내는 토큰을 뱉는다
  3. 그 순간 도구 실행 모드로 넘어간다. 밖에서 함수가 실제로 돌아간다
  4. 결과가 돌아오면 그 값이 호출 자리에 끼워지고, 다시 텍스트 생성 모드로 복귀한다

말로 풀면 복잡한데, 실제로는 문장 중간에 빈칸을 만들고 밖에서 채워 넣는 것에 가깝다.

이걸 유도하는 방법이 두 가지다.

방법 어떻게 성격
추론 시 프롬프트 “필요하면 이 도구를 써라”고 프롬프트에 적어준다 학습 없이 즉시 가능, 대신 불안정
툴 러닝(학습) 도구 쓰는 법을 모델에 학습시킨다 안정적, 대신 데이터와 학습 비용

4. 툴 러닝 — 도구 쓰는 법을 어떻게 가르치나

학습으로 가르치는 쪽을 조금 더 봤다. 세 갈래로 발전해왔다.

① 모방 학습 — 사람이 하는 걸 그대로 따라 한다

가장 단순하고 직관적인 방법이다. 사람이 도구를 쓰는 과정을 기록해서 그걸 따라 하게 학습시킨다.

OpenAI의 WebGPT가 이 방식이다. 사람이 검색 엔진을 쓰면서 질문에 답하는 과정 — 검색어를 넣고, 결과를 훑고, 인용할 문단을 고르고 — 을 통째로 기록했다. 그 기록을 모방하도록 지도 학습을 시키고, 거기에 강화학습을 얹었다.

인상적이었던 건 데이터가 6천 건 정도밖에 안 들었다는 점이다. 그런데 긴 답을 요구하는 질문에서는 사람이 쓴 답보다 더 선호되는 결과가 나오기도 했다.

도구를 쓰는 절차 자체는 생각보다 적은 예시로도 배워진다.

문제는 그 6천 건을 사람이 직접 만들어야 한다는 것이다.

② 자기지도 학습 — 모델이 스스로 데이터를 만든다

그래서 나온 게 Meta의 Toolformer다. 발상이 재밌다. 모델이 스스로 학습 데이터를 만든다.

Toolformer의 3단계

  1. 샘플링 — 평범한 텍스트를 놓고, “여기에 API를 넣는다면 어디에 뭘 넣을까”를 모델이 후보로 잔뜩 만든다
  2. 실행 — 만든 API 호출을 실제로 실행해서 응답을 받는다
  3. 필터링 — 그 응답을 끼워 넣었더니 뒷부분을 예측하기가 더 쉬워졌는가를 본다. 쉬워진 것만 남긴다

3번이 핵심이다. 좋은 도구 호출인지 아닌지를 사람이 판정하지 않는다. “이 값을 알고 나니 다음 내용이 더 잘 예측된다”면 유용한 호출이었던 것이다. 채점 기준이 자동으로 생긴다.

30편에서 본 RLVR과 성격이 비슷하다. 사람 대신 자동으로 채점할 수 있는 기준을 찾아낸 것이다.

③ 규모로 밀어붙이기

ToolLLM은 방향이 또 다르다. 기존 연구들이 다루는 도구가 너무 적고 종류가 뻔하다는 문제를 정면으로 건드렸다.

실제로 쓰이는 REST API를 1만 6천 개 넘게 긁어모아, 그걸로 대규모 학습 데이터셋과 평가 벤치마크를 만들었다. 도구가 몇 개 있는 세계가 아니라 수만 개 중에 골라 써야 하는 세계를 상정한 것이다.

연구 데이터를 누가 만드나 특징
WebGPT 사람이 시연 적은 데이터(6천 건)로도 됨. 대신 사람 손이 든다
Toolformer 모델이 스스로 손실이 줄었는지로 자동 필터링
ToolLLM 실제 API를 대량 수집 1만 6천 개 이상. 도구 선택 자체가 문제가 됨

최근에는 여기에 두 갈래가 더 붙었다. 하나는 멀티모달 툴 러닝 — 화면을 보고 클릭하는 GUI 에이전트다. 다른 하나는 지도 학습을 넘어 에이전트 행동에 강화학습을 적용하는 쪽이다.


5. MCP — 도구가 늘어나자 규격이 문제가 됐다

여기까지 오면 자연스럽게 문제가 생긴다. 도구를 쓰는 방식이 회사마다, 모델마다 다르다.

같은 “날씨를 가져오는 도구”인데 어떤 모델은 이런 형식으로, 다른 모델은 저런 형식으로 요구한다. 필드 이름부터 감싸는 구조까지 제각각이다.

문제 결과
호환성 부족 모델을 바꾸면 도구 연결을 다시 짜야 한다
재사용 어려움 같은 도구를 모델 수만큼 중복 정의한다

MCP(Model Context Protocol) 는 여기에 대한 답이다. 언어모델이 외부 도구와 주고받는 방식을 하나의 공통 규격으로 정한 프로토콜이다.

MCP 이전과 이후

강의에서 USB 단자에 비유했는데 정확했다. 예전에는 기기마다 충전 단자가 달라서 케이블을 종류별로 들고 다녀야 했다. 지금은 하나로 대충 다 된다. 기기가 줄어든 게 아니라 규격이 하나로 모인 것이다.

더 쉬운 비유로

이 대목에서 예전에 했던 작업이 바로 떠올랐다.

TCP 멀티플레이 프로젝트에서 클라이언트와 서버가 주고받을 패킷 구조를 protobuf로 정의했었다. request, response, notification 폴더를 나누고 .proto 파일에 필드를 적어두면, 양쪽이 같은 명세를 보고 같은 방식으로 직렬화한다.

그때 명세를 미리 못 박아두는 게 왜 중요한지 몸으로 배웠다. 한쪽이 필드 이름을 바꾸면 그 순간 통신이 깨진다. 그래서 말로 합의하지 않고 파일로 합의한다.

MCP는 언어모델과 도구 사이에 놓는 .proto 파일 같은 것이다. 양쪽이 같은 명세를 보게 만든다.

아키텍처 — 셋으로 나뉜다

구성요소 정체
MCP Host MCP 클라이언트들을 조정하고 관리하는 AI 애플리케이션
MCP Client 서버와의 연결을 유지하며 컨텍스트를 가져오는 구성요소
MCP Server 클라이언트에게 실제 컨텍스트와 기능을 제공하는 프로그램

클라이언트와 서버는 1:1로 연결된다. 호스트 하나가 클라이언트를 여러 개 들고, 각 클라이언트가 서버 하나씩과 짝을 짓는 구조다. 파일 시스템 서버, 데이터베이스 서버, 모니터링 서버를 각각 붙이는 식이다.

두 계층으로 나뉜다

MCP를 이해할 때 제일 헷갈렸던 부분인데, 계층이 두 개다.

MCP의 두 계층

계층 무엇을 정하나
데이터 계층 (Data Layer) 무엇을 주고받을지. JSON-RPC 기반으로 도구·리소스·프롬프트의 형식과 연결 수명주기를 정의한다
전송 계층 (Transport Layer) 어떻게 실어 나를지. stdio, HTTP 같은 실제 통신 채널과 연결 수립·인증을 담당한다

개념적으로 데이터 계층이 안쪽, 전송 계층이 바깥쪽이다. 편지의 내용과 봉투를 나눈 것이라고 보면 된다. 내용 형식이 같으면 봉투가 우편이든 택배든 상관없다.

이 분리 덕분에 같은 도구 정의를 로컬(stdio)에서도, 원격(HTTP)에서도 그대로 쓸 수 있다.

얻는 것

장점
표준화 모든 모델과 도구가 같은 호출 규격을 쓴다
확장성 새 도구를 붙이기 쉽다
호환성 모델과 플랫폼이 달라도 같은 도구가 돈다
재사용성 한 번 정의한 도구를 여러 모델에서 쓴다
투명성 호출 과정이 기록되고 검증된다

서버를 만드는 것 자체는 어렵지 않다. FastMCP 같은 라이브러리를 쓰면 함수에 데코레이터 하나 붙이는 수준이다. 타입 힌트를 보고 스키마를 자동으로 만들어준다.

from fastmcp import FastMCP

mcp = FastMCP("calc")

@mcp.tool()
def add(a: int, b: int) -> int:
    """두 수를 더한다"""
    return a + b

if __name__ == "__main__":
    mcp.run()

함수에 붙인 독스트링이 도구 설명이 되고, 타입 힌트가 입력 스키마가 된다. 언어모델은 이 설명을 읽고 언제 이 도구를 쓸지 판단한다. 그래서 독스트링을 대충 쓰면 모델이 도구를 안 쓰거나 엉뚱하게 쓴다.

도구 설명은 주석이 아니라 모델이 읽는 사용설명서다.

지금은

MCP는 Anthropic이 공개한 규격인데, 경쟁 관계인 OpenAI까지 채택하면서 사실상 업계 표준이 됐다. 한 회사의 사양이 표준으로 굳는 과정을 실시간으로 본 셈이다.

웹 개발과 AI 개발의 경계가 흐려지는 데도 한몫하고 있다. 서버를 띄우고, 스키마를 맞추고, 인증을 붙이는 일 — 전부 백엔드에서 하던 일이다.


정리

  • 에이전트 — 환경을 관찰(센서) 하고 행동(액추에이터) 하는 것. 둘 다 있어야 한다
    • LLM 우선 관점(언어모델에 능력을 붙임) vs 에이전트 우선 관점(에이전트에 언어를 붙임)
    • RAG는 에이전트가 아니다 — 검색 한 번, 생성 한 번으로 끝. 결과를 보고 다시 판단하지 않는다
  • 프레임워크 네 부품 — Controller(계획) / Tool Set(기능) / Environment(무대) / Perceiver(피드백을 요약) + 사람
    • 사람은 컨트롤러에 지시를 넣고 퍼시버에 피드백을 준다. 퍼시버는 환경 피드백과 사람 피드백 둘 다 받아 한 덩어리로 줄인다
  • 도구 — 모델 외부에서 실행되는 프로그램의 함수 인터페이스. 모델은 호출을 생성만 하고 실행은 밖에서 한다
    • 물리 / GUI / 프로그램 기반 세 종류
    • 텍스트 생성 모드 ↔ 도구 실행 모드를 오간다. 문장에 빈칸을 만들고 밖에서 채우는 것
  • 툴 러닝 세 갈래
    • WebGPT — 사람의 도구 사용을 모방. 6천 건 정도로도 성능이 났다
    • Toolformer — 모델이 스스로 호출을 만들고 실행해보고, 뒷부분 예측이 쉬워졌는지로 자동 필터링
    • ToolLLM — 실제 REST API 1만 6천 개 이상. 도구 선택 자체가 문제가 되는 규모
  • MCP — 모델마다 다른 도구 호출 규격을 하나로 통일한 프로토콜
    • Host / Client / Server, 클라이언트와 서버는 1:1
    • 데이터 계층(무엇을 주고받나, JSON-RPC 기반) + 전송 계층(어떻게 실어 나르나, stdio·HTTP)
    • 도구의 독스트링과 타입 힌트가 곧 모델이 읽는 명세가 된다
  • 겹치는 글 — RAG와의 차이는 30편, 지시를 따르도록 학습시키는 이야기는 16편

참고 자료

한줄 평

  • MCP 설명을 듣는 내내 예전에 .proto 파일로 패킷 구조 맞추던 게 겹쳐 보였는데, 결국 새로운 개념이 아니라 통신하는 쪽끼리 규격을 먼저 정한다는 오래된 원칙이 AI 쪽으로 넘어온 것뿐이었다!