Contents
see ListAI 에이전트란 무엇인가
AI 에이전트(AI Agent)는 사용자의 목표를 달성하기 위해 스스로 판단하고 외부 도구를 호출하며 여러 단계의 작업을 자율적으로 수행하는 시스템입니다. 단순히 텍스트를 생성하는 LLM과 달리, 에이전트는 파일 시스템 접근, API 호출, 데이터베이스 조회, 웹 검색 등 실질적인 행동을 취할 수 있습니다.
2026년 현재 AI 에이전트 개발의 핵심 축은 두 가지입니다. 첫째, Claude API의 Tool Use(도구 호출) 기능으로 LLM이 정의된 함수를 직접 실행하는 패턴입니다. 둘째, Anthropic이 주도하고 전 주요 AI 공급사(OpenAI, Google, Microsoft, Amazon)가 채택한 Model Context Protocol(MCP)입니다. MCP는 2026년 2월 기준 월 9,700만 SDK 다운로드를 기록하며 사실상 AI-도구 통신의 표준이 됐습니다.
Tool Use 라이프사이클 이해
Claude API에서 Tool Use는 아래 순서로 동작합니다.
- 정의:
tools배열에 도구 이름, 설명, JSON Schema 형태의 입력 스키마를 선언합니다. - 요청: 사용자 메시지와 함께
tools를 API에 전송합니다. - 결정: Claude가 도구 호출이 필요하다고 판단하면
stop_reason: "tool_use"와tool_use블록을 반환합니다. - 실행: 애플리케이션에서 실제 함수를 실행합니다.
- 결과 반환:
tool_result블록으로 결과를 다음 메시지에 포함시킵니다. - 최종 응답: Claude가 결과를 바탕으로 자연어 답변을 생성합니다(
stop_reason: "end_turn").
Ring 1: 단일 Tool Call 구현
아래는 캘린더 이벤트 생성 도구를 정의하고 한 번 호출하는 가장 기본적인 예제입니다.
import anthropic
client = anthropic.Anthropic()
tools = [
{
"name": "create_calendar_event",
"description": "Create a calendar event with attendees and optional recurrence.",
"input_schema": {
"type": "object",
"properties": {
"title": {"type": "string"},
"start": {"type": "string", "format": "date-time"},
"end": {"type": "string", "format": "date-time"},
"attendees": {
"type": "array",
"items": {"type": "string", "format": "email"},
},
},
"required": ["title", "start", "end"],
},
}
]
response = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
tools=tools,
messages=[{"role": "user", "content": "내일 오전 10시에 팀 미팅을 잡아줘. alice@example.com 초대해."}],
)
# stop_reason == "tool_use"이면 도구 호출 필요
tool_use = next(b for b in response.content if b.type == "tool_use")
print(f"도구: {tool_use.name}")
print(f"입력: {tool_use.input}")
# 실제 함수 실행 후 결과 반환
result = {"event_id": "evt_001", "status": "created"}
followup = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
tools=tools,
messages=[
{"role": "user", "content": "내일 오전 10시에 팀 미팅을 잡아줘."},
{"role": "assistant", "content": response.content},
{"role": "user", "content": [
{"type": "tool_result", "tool_use_id": tool_use.id, "content": str(result)}
]},
],
)
print(followup.content[0].text)
Ring 2: 에이전트 루프 (While Loop 패턴)
실제 에이전트는 도구를 여러 번 연속으로 호출해야 합니다. stop_reason이 "end_turn"이 될 때까지 반복하는 while 루프가 필수입니다.
import anthropic
client = anthropic.Anthropic()
def run_agent(user_message: str, tools: list) -> str:
messages = [{"role": "user", "content": user_message}]
while True:
response = client.messages.create(
model="claude-opus-4-6",
max_tokens=4096,
tools=tools,
messages=messages,
)
# 에이전트 루프 종료 조건
if response.stop_reason == "end_turn":
return next(
(b.text for b in response.content if b.type == "text"), ""
)
# 도구 호출 처리 (여러 개일 수 있음)
if response.stop_reason == "tool_use":
messages.append({"role": "assistant", "content": response.content})
tool_results = []
for block in response.content:
if block.type != "tool_use":
continue
# 실제 도구 실행
result = dispatch_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": str(result),
})
messages.append({"role": "user", "content": tool_results})
def dispatch_tool(name: str, inputs: dict) -> dict:
if name == "create_calendar_event":
# 실제 캘린더 API 호출 로직
return {"event_id": "evt_123", "status": "created"}
elif name == "get_weather":
return {"temp": 22, "condition": "맑음"}
return {"error": f"unknown tool: {name}"}
병렬 Tool Call 처리
Claude는 독립적인 도구 호출이 여러 개인 경우 하나의 응답에 tool_use 블록을 여러 개 반환합니다. 모든 결과를 하나의 user 메시지에 담아 보내야 합니다.
# response.content에 tool_use 블록이 여러 개일 수 있음
tool_results = []
for block in response.content:
if block.type == "tool_use":
result = dispatch_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id, # 각 블록의 id를 정확히 매핑
"content": str(result),
})
# 모든 결과를 단일 메시지로 전송
messages.append({"role": "user", "content": tool_results})
Model Context Protocol(MCP) 서버 구축
MCP는 도구 서버와 AI 클라이언트 사이의 통신을 표준화합니다. Python SDK로 MCP 서버를 직접 구현할 수 있습니다.
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp import types
app = Server("my-tools-server")
@app.list_tools()
async def list_tools() -> list[types.Tool]:
return [
types.Tool(
name="search_docs",
description="내부 문서를 검색합니다.",
inputSchema={
"type": "object",
"properties": {
"query": {"type": "string", "description": "검색어"},
"limit": {"type": "integer", "default": 5},
},
"required": ["query"],
},
)
]
@app.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "search_docs":
query = arguments["query"]
limit = arguments.get("limit", 5)
results = search_internal_docs(query, limit)
return [types.TextContent(type="text", text=str(results))]
async def main():
async with stdio_server() as streams:
await app.run(*streams, app.create_initialization_options())
if __name__ == "__main__":
import asyncio
asyncio.run(main())
이 서버는 claude_desktop_config.json 또는 Claude Code의 settings.json에 등록하면 Claude에서 바로 사용할 수 있습니다.
프로덕션 에이전트 설계 원칙
- 도구 설명을 상세하게: 도구 성능에 가장 큰 영향을 주는 요소는 description 품질입니다. 언제 사용해야 하는지, 파라미터의 의미, 주의사항 등을 3-4문장 이상으로 기술하세요.
- 관련 도구 통합: create_pr, review_pr, merge_pr 대신 action 파라미터를 가진 하나의 pr_manager 도구로 통합하면 Claude의 선택 오류가 줄어듭니다.
- 최대 반복 횟수 설정: 무한 루프를 방지하기 위해 while 루프에 max_iterations 제한을 두세요.
- 에러 핸들링: 도구 실행 실패 시
is_error: true와 함께 에러 메시지를tool_result로 반환하면 Claude가 대안을 시도합니다. - Managed Agents 활용: 장시간 실행, 상태 유지, 클라우드 인프라가 필요한 워크로드에는 Claude Managed Agents를 사용하면 인프라 관리 부담을 줄일 수 있습니다.
A2A 프로토콜: 멀티 에이전트 통신 표준
Google이 2025년 4월 제안하고 Linux Foundation에 기증한 A2A(Agent-to-Agent) 프로토콜은 서로 다른 프레임워크로 개발된 에이전트들이 서로를 발견하고 통신하는 방법을 표준화합니다. MCP가 에이전트-도구 통신의 표준이라면, A2A는 에이전트-에이전트 통신의 표준입니다. 2026년 현재 LangChain, AutoGen, CrewAI 등 주요 에이전트 프레임워크가 A2A를 지원하며, 복잡한 멀티 에이전트 시스템을 구축할 때 활용도가 높아지고 있습니다.
정리
2026년 AI 에이전트 개발의 핵심은 Claude API의 Tool Use 패턴(단일 호출 → while 루프 → 병렬 처리)을 익히고, MCP로 재사용 가능한 도구 서버를 구축하며, A2A로 멀티 에이전트를 연결하는 것입니다. 특히 MCP는 전 AI 공급사가 채택한 표준으로, 한 번 구현하면 Claude뿐 아니라 OpenAI, Gemini 등 어떤 LLM 클라이언트에서도 동일하게 활용할 수 있어 투자 대비 효과가 매우 높습니다.