/AI & 자동화/LLM Agent Tool Use: From Function Calling to MCP
AI & AutomationLLM에이전트

LLM Agent Tool Use: From Function Calling to MCP

A complete breakdown of tool use, the core mechanism that lets LLM agents interact with the outside world. We compare OpenAI Function Calling, Anthropic Tool Use, and the Model Context Protocol (MCP) side by side with code.

LLM Agent Tool Use: From Function Calling to MCP

Mastering LLM Agent Tool Use: From Function Calling to MCP

What makes an agent an agent is tool use. It is the mechanism that takes LLMs beyond mere text generation and lets them call external APIs, query databases, and execute code.

How Tool Use Works

LLMs only accept text as input and only produce text as output. Tool use bypasses that constraint with the following flow.

CODE
1. User message + tool spec → LLM
2. LLM → "Call this tool with these arguments" (JSON output)
3. Runtime executes the actual function
4. Execution result → passed back to the LLM
5. LLM → generates the final natural-language answer

The key point is that the LLM does not execute functions itself. The runtime does, then hands the results back to the LLM.

OpenAI Function Calling

Python
from openai import OpenAI
import json

client = OpenAI()

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_stock_price",
            "description": "특정 종목의 현재 주가를 조회합니다",
            "parameters": {
                "type": "object",
                "properties": {
                    "symbol": {
                        "type": "string",
                        "description": "주식 티커 (예: AAPL, TSLA)"
                    },
                    "currency": {
                        "type": "string",
                        "enum": ["USD", "KRW"]
                    }
                },
                "required": ["symbol"]
            }
        }
    }
]

def get_stock_price(symbol, currency="USD"):
    return {"symbol": symbol, "price": 192.5, "currency": currency}

def run_agent(user_message):
    messages = [{"role": "user", "content": user_message}]

    while True:
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=messages,
            tools=tools,
            tool_choice="auto"
        )
        msg = response.choices[0].message
        messages.append(msg)

        if msg.tool_calls is None:
            return msg.content

        for tc in msg.tool_calls:
            args = json.loads(tc.function.arguments)
            result = get_stock_price(**args)
            messages.append({
                "role": "tool",
                "tool_call_id": tc.id,
                "content": json.dumps(result)
            })

Anthropic Tool Use

Claude's tool use issues calls as tool_use content blocks and returns results as tool_result.

Python
import anthropic, json

client = anthropic.Anthropic()

tools = [{
    "name": "search_docs",
    "description": "내부 문서 데이터베이스에서 관련 문서를 검색합니다",
    "input_schema": {
        "type": "object",
        "properties": {
            "query": {"type": "string"},
            "max_results": {"type": "integer", "default": 5}
        },
        "required": ["query"]
    }
}]

def search_docs(query, max_results=5):
    return [{"title": "API 인증 가이드", "content": "Bearer 토큰 방식을 사용합니다..."}]

messages = [{"role": "user", "content": "우리 API 인증 방식이 어떻게 돼?"}]

while True:
    response = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=1024,
        tools=tools,
        messages=messages
    )

    if response.stop_reason == "end_turn":
        text_block = next(b for b in response.content if b.type == "text")
        print(text_block.text)
        break

    messages.append({"role": "assistant", "content": response.content})

    tool_results = []
    for block in response.content:
        if block.type == "tool_use":
            result = search_docs(**block.input)
            tool_results.append({
                "type": "tool_result",
                "tool_use_id": block.id,
                "content": json.dumps(result, ensure_ascii=False)
            })
    messages.append({"role": "user", "content": tool_results})

Model Context Protocol (MCP)

MCP is a tool standardization protocol proposed by Anthropic. It is not tied to any individual LLM SDK; tools are provided independently through a server–client architecture.

Python
# MCP 서버 구현
from mcp.server import Server
import mcp.types as types

server = Server("my-tools-server")

@server.list_tools()
async def handle_list_tools():
    return [
        types.Tool(
            name="query_database",
            description="SQL 쿼리를 실행하고 결과를 반환합니다",
            inputSchema={
                "type": "object",
                "properties": {
                    "sql": {"type": "string", "description": "실행할 SELECT 쿼리"}
                },
                "required": ["sql"]
            }
        )
    ]

@server.call_tool()
async def handle_call_tool(name, arguments):
    if name == "query_database":
        results = execute_query(arguments["sql"])
        return [types.TextContent(type="text", text=str(results))]

MCP's advantage is reusability. An MCP server you build once can be connected from Claude Desktop, Claude Code, your own agents, and more.

Tool Design Principles

The difference between a good tool and a bad one is in the description.

Bad exampleGood example
"Fetches data""Looks up status, amount, and shipping info for a specific order by order ID. Canceled orders can also be retrieved."
No parameter descriptionsExplicit type, allowed values, and defaults for each parameter

The LLM reads the description to choose a tool. If the description is inaccurate, it will call the wrong tool or pass the wrong arguments.

Parallel Tool Calls

Running multiple tools sequentially is slow. Both GPT-4o and Claude support parallel tool calls.

Python
import asyncio

async def execute_tools_parallel(tool_calls):
    tasks = [dispatch_tool(tc.function.name, json.loads(tc.function.arguments))
             for tc in tool_calls]
    return await asyncio.gather(*tasks)

In the next installment, we cover memory system design—how to let agents maintain conversation context and carry out long-running tasks.

Editor's Note — From the Field

It feels like attaching more tools should make an agent smarter, but in practice, once you go past five or six tools, the LLM frequently misjudges which tool to use and when. What helped most was cutting the number of tools and writing each description so specifically that a human wouldn't get confused either—search_internal_docs (search the internal wiki) rather than search. Tool design is an extension of prompt engineering.

References

확인 정보
✦ ✦ ✦
편집 검토 · Editorial Review

Nodelog는 모든 콘텐츠의 내용과 출처를 공개 전에 검토합니다. 환경(OS·버전)에 따라 결과가 달라질 수 있는 기술 정보는 공식 문서와 함께 확인하며, 검토 기준과 정정 원칙은 편집 정책에서 안내합니다. 오류를 발견하시면 이메일로 제보해 주세요 — 확인 후 신속히 정정합니다.

편집 책임 · Nodelog 기술 편집팀·발행 · ·업데이트 ·

Comments

Be the first to comment.