Skip to content
OpenAI Function Calling: Examples to Get Started

OpenAI Function Calling: Examples to Get Started

Updated on

Learn how modern OpenAI function calling works with tools, JSON Schema, and Structured Outputs. See practical examples in Python and JavaScript for scheduling meetings, fetching stock prices, and booking travel.

끊임없이 변화하는 인공지능(AI) 분야에서 OpenAI의 function calling(현재는 tools라는 형태로 노출됨)은 실제 애플리케이션을 만들 때 가장 중요한 구성 요소 중 하나가 되었습니다. 이를 통해 gpt-4.1, gpt-4.1-mini 같은 강력한 언어 모델을 여러분의 API, 데이터베이스, 비즈니스 로직에 연결할 수 있습니다.

모델에게 “이 형식에 맞춰 JSON을 써 줘”라고 요청하고 운에 맡기는 대신, JSON Schema로 함수를 설명하면 모델이 코드에서 안전하게 실행할 수 있는 구조화된 함수 호출을 반환합니다.

이 가이드에서 배우게 될 내용은 다음과 같습니다:

  • OpenAI function calling이 무엇이며, 현재 어떻게 동작하는지
  • JSON Schema로 tools/functions를 정의하는 방법
  • 실용 예제: 미팅 일정 잡기, 주가 조회, 여행 예약
  • function calling을 더 신뢰성 있게 만들어 주는 Structured Outputs 같은 최신 기능 활용법
  • 베스트 프랙티스, 흔한 문제, 그리고 FAQ
📚

What Is OpenAI Function Calling (Tools)?

Function calling은 모델이 일반 텍스트 대신 기계가 읽을 수 있는 함수 호출로 응답하도록 해 줍니다. 최신 API에서는 이것이 tools로 표현됩니다:

  • tools 정의 시 다음을 포함합니다:
    • type: "function"
    • function.name, function.description
    • function.parameters (인자를 설명하는 JSON Schema)
  • 이 tools를 프롬프트와 함께 보냅니다.
  • 모델은 tool을 호출할지 여부를 스스로 결정하고, 함수 이름과 JSON 인자를 포함한 tool call을 반환합니다.
  • 여러분의 애플리케이션은:
    1. tool call을 파싱하고,
    2. 백엔드에서 해당하는 실제 함수를 실행한 뒤,
    3. 선택적으로 그 결과를 다시 모델에 보내 사용자에게 보여 줄 최종 답변을 생성합니다.

내부적으로 function calling은 다음에서 지원됩니다:

  • Responses API (POST /v1/responses) – 신규 애플리케이션에 권장되는 방식
  • 기존 Chat Completions API (POST /v1/chat/completions) – 여전히 널리 사용되고 지원됨

과거에는 function calling에 functionsfunction_call 파라미터를 사용했습니다. 이제는 toolstool_choice가 이를 대체하며, 이전 방식은 deprecated 상태입니다. 새로운 코드는 모두 새로운 스타일을 사용해야 합니다.


Basic Example: Schedule a Meeting (Chat Completions API)

먼저 Chat Completions API를 사용하는 간단한 예제로 시작해 보겠습니다. 모델에게 미팅 일정을 잡도록 요청하고, schedule_meeting 함수에 대한 구조화된 인자를 반환받습니다.

JSON request (conceptual)

{
    "model": "gpt-4.1-mini",
    "messages": [
        {
            "role": "user",
            "content": "Schedule a meeting with John Doe next Tuesday at 3 PM."
        }
    ],
    "tools": [
        {
            "type": "function",
            "function": {
                "name": "schedule_meeting",
                "description": "Schedule a meeting in the calendar.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "attendee": {
                            "type": "string",
                            "description": "Name of the attendee for the meeting."
                        },
                        "date": {
                            "type": "string",
                            "description": "Date of the meeting in ISO 8601 format."
                        },
                        "time": {
                            "type": "string",
                            "description": "Time of the meeting, including time zone."
                        }
                    },
                    "required": ["attendee", "date", "time"],
                    "additionalProperties": false
                },
                "strict": true
            }
        }
    ],
    "tool_choice": "auto"
}

모델의 응답에는 다음과 비슷한 내용이 포함됩니다:

{
    "role": "assistant",
    "tool_calls": [
        {
            "id": "call_123",
            "type": "function",
            "function": {
                "name": "schedule_meeting",
                "arguments": "{\"attendee\":\"John Doe\",\"date\":\"2025-11-18\",\"time\":\"15:00 Europe/Berlin\"}"
            }
        }
    ]
}

백엔드는 arguments를 파싱하고, 실제 schedule_meeting 함수(예: Google Calendar 또는 Outlook 사용)를 호출한 뒤, 필요하다면 그 결과를 다시 모델에 보내 사용자에게 보여 줄 친절한 확인 메시지를 생성하도록 할 수 있습니다.


Example: Stock Price Lookup

이번에는 좀 더 “API스러운” 예제로, 자연어를 기반으로 get_stock_price 함수를 호출해 보겠습니다.

Request with a get_stock_price tool

{
    "model": "gpt-4.1-mini",
    "messages": [
        {
            "role": "user",
            "content": "What's the current price of Apple stock?"
        }
    ],
    "tools": [
        {
            "type": "function",
            "function": {
                "name": "get_stock_price",
                "description": "Get the current stock price for a ticker symbol.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "ticker_symbol": {
                            "type": "string",
                            "description": "Ticker symbol of the stock, e.g. AAPL."
                        },
                        "currency": {
                            "type": "string",
                            "enum": ["USD", "EUR", "GBP"],
                            "description": "Currency for the price."
                        }
                    },
                    "required": ["ticker_symbol"],
                    "additionalProperties": false
                },
                "strict": true
            }
        }
    ],
    "tool_choice": "auto"
}

사용자가 “What’s the current price of Apple stock?”이라고 물으면, 모델은 다음과 같은 tool call을 생성합니다:

{
    "type": "function",
    "function": {
        "name": "get_stock_price",
        "arguments": "{\"ticker_symbol\":\"AAPL\",\"currency\":\"USD\"}"
    }
}

그 다음 여러분은:

  1. 실제 주가 API를 호출하고,
  2. 그 결과를 후속 요청에서 모델에게 다시 전달한 뒤,
  3. 모델이 사람 친화적인 설명을 생성하도록 합니다.

Example: Travel Booking with Function Calling

Function calling은 프롬프트가 다소 지저분하고 인간적인 반면, 백엔드는 깔끔하고 구조화된 파라미터를 필요로 할 때 빛을 발합니다.

예를 들어, 다음과 같은 발화를 생각해 봅시다:

“I need to book a trip from Bonn to Amsterdam for my wife, mother, my two sons, my daughter, and me. The airline must fly direct.”

여기서 모델이 추출해야 할 정보는:

  • departure
  • destination
  • number_people
  • travel_mode (예: plane / train)

Tool definition for book_travel

{
    "model": "gpt-4.1-mini",
    "messages": [
        {
            "role": "user",
            "content": "I need to book a trip from Bonn to Amsterdam for my wife, mother, my two sons and daughter, and me. The airline must fly direct."
        }
    ],
    "tools": [
        {
            "type": "function",
            "function": {
                "name": "book_travel",
                "description": "Search or book transportation for a group of travelers.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "departure": {
                            "type": "string",
                            "description": "City or airport you are traveling from."
                        },
                        "destination": {
                            "type": "string",
                            "description": "City or airport you are traveling to."
                        },
                        "number_people": {
                            "type": "integer",
                            "description": "How many people are traveling."
                        },
                        "travel_mode": {
                            "type": "string",
                            "enum": ["plane", "train", "bus", "car"],
                            "description": "Preferred mode of travel."
                        },
                        "non_stop_only": {
                            "type": "boolean",
                            "description": "Whether only non-stop options are allowed."
                        }
                    },
                    "required": ["departure", "destination", "number_people"],
                    "additionalProperties": false
                },
                "strict": true
            }
        }
    ],
    "tool_choice": "auto"
}

모델은 다음과 같이 응답할 수 있습니다:

{
    "name": "book_travel",
    "arguments": "{\"departure\":\"Bonn\",\"destination\":\"Amsterdam\",\"number_people\":6,\"travel_mode\":\"plane\",\"non_stop_only\":true}"
}

이제 이 값을 바로 항공권 검색 서비스의 입력으로 사용할 수 있습니다.


Using the Modern OpenAI SDKs (Python & JavaScript)

실제 개발에서는 보통 이런 JSON을 직접 만들지 않고, 공식 SDK를 사용해 타입이 있는 응답을 다루게 됩니다.

Python example (Chat Completions + tools)

from openai import OpenAI
 
client = OpenAI()
 
tools = [
    {
        "type": "function",
        "function": {
            "name": "schedule_meeting",
            "description": "Schedule a meeting in the calendar.",
            "parameters": {
                "type": "object",
                "properties": {
                    "attendee": {"type": "string"},
                    "date": {"type": "string"},
                    "time": {"type": "string"},
                },
                "required": ["attendee", "date", "time"],
                "additionalProperties": False,
            },
            "strict": True,
        },
    }
]
 
completion = client.chat.completions.create(
    model="gpt-4.1-mini",
    messages=[
        {
            "role": "user",
            "content": "Schedule a meeting with John Doe next Tuesday at 3 PM.",
        }
    ],
    tools=tools,
    tool_choice="auto",
)
 
tool_calls = completion.choices[0].message.tool_calls
if tool_calls:
    call = tool_calls[0]
    args = client.responses._client._utils.json.loads(call.function.arguments)
    # Your real implementation:
    # result = schedule_meeting(**args)

JavaScript example (Node.js)

import OpenAI from "openai";
 
const client = new OpenAI();
 
const tools = [
    {
        type: "function",
        function: {
            name: "get_stock_price",
            description: "Get the current price for a given ticker symbol.",
            parameters: {
                type: "object",
                properties: {
                    ticker_symbol: {
                        type: "string",
                        description: "Stock ticker symbol, e.g. AAPL",
                    },
                },
                required: ["ticker_symbol"],
                additionalProperties: false,
            },
            strict: true,
        },
    },
];
 
const response = await client.chat.completions.create({
    model: "gpt-4.1-mini",
    messages: [
        { role: "user", content: "What's the current price of Apple stock?" },
    ],
    tools,
    tool_choice: "auto",
});
 
const toolCalls = response.choices[0].message.tool_calls;

Structured Outputs: More Reliable Function Calling

JSON Mode는 모델이 유효한 JSON을 반환하도록 보장하지만, 그 JSON이 반드시 여러분의 스키마와 일치하는 것은 아닙니다. Structured Outputs는 tool을 호출할 때 JSON Schema를 더 엄격하게 적용하여 이를 보완하는 최신 기능입니다:

  • tool의 function 정의에 "strict": true를 설정합니다.
  • 그러면 모델이 생성하는 arguments가 스키마(타입, 필수 필드, 추가 속성 없음 등)를 반드시 만족하도록 강제되어, 파싱 및 검증 오류가 크게 줄어듭니다.

이 기능은 특히 다음과 같은 상황에서 유용합니다:

  • 비정형 텍스트에서 복잡하고 중첩된 데이터를 추출할 때
  • 각 단계가 정확한 구조 데이터에 의존하는 다단계 워크플로를 구축할 때
  • SQL, 분석 파이프라인, 데이터 시각화 시스템 등에 넘겨줄 파라미터를 생성할 때

Structured Outputs를 사용하더라도 출력값은 여전히 “신뢰할 수 없는 입력”으로 취급해야 합니다(예: 값 범위 확인, 누락된 ID 처리, 비즈니스 규칙 검증 등).


Design Patterns & Best Practices

1. Keep tools small and focused

하나의 거대한 do_everything 함수 대신, 작고 조합 가능한 tools를 정의하세요:

  • get_user_profile
  • get_user_orders
  • create_support_ticket
  • schedule_meeting

이렇게 하면 스키마 관리가 쉬워지고, 모델이 적절한 tool을 선택하기도 수월해집니다.

2. Use clear names and descriptions

  • 함수 이름은 동사 형태로: create_invoice, fetch_weather, book_travel.
  • 설명에는 함수가 언제 사용되어야 하는지도 포함하는 것이 좋습니다. 단순히 무엇을 하는지에 그치지 마세요.

나쁜 예:

“Get data from the system.”

좋은 예:

“Use this function whenever the user asks about their recent orders or order history.”

3. Be strict with schemas

  • required 필드와 additionalProperties: false를 적극적으로 사용합니다.
  • 가능한 경우 enum을 사용해 옵션을 제한합니다 ("enum": ["plane", "train"]).
  • 필요하다면 문자열 포맷, 최소 정수값 등 간단한 제약 조건도 추가합니다.

4. Validate and log everything

  • tool arguments는 항상 서버에서 검증한 뒤 실행합니다.
  • 디버깅을 위해 tool call과 자연어 프롬프트를 로깅합니다.
  • 검증이 실패할 경우, 짧은 교정용 system 메시지와 함께 재시도하는 전략도 고려해 보세요.

5. Chain tools when needed

좀 더 복잡한 워크플로(예: 사용자 조회 → 주문 조회 → 요약)를 구성할 때는:

  1. 모델이 한 번의 응답에서 여러 tool을 병렬로 호출하도록 하거나,
  2. 백엔드에서 단계별로 오케스트레이션하면서 이전 단계 결과를 모델에 계속 넘겨줄 수 있습니다.

A Concrete Multi-Step Example: Math with Mixed Formats

function calling이 단순한 장난감 수준이 아니라는 것을 보여주는 고전적인 예제를 다시 살펴보겠습니다.

“What’s the result of 22 plus 5 in decimal added to the hexadecimal number A?”

이를 해결하기 위해 다음 두 가지 tool을 정의할 수 있습니다:

  • add_decimal(a: number, b: number)
  • add_hex(a: string, b: string)

워크플로는 다음과 같습니다:

  1. 모델이 add_decimal{ "a": 22, "b": 5 } 인자로 호출 → 여러분의 코드가 27을 반환
  2. 이 결과와 원래 질문을 다시 모델에 전달
  3. 모델이 add_hex{ "a": "27", "b": "A" } 인자로 호출
  4. 여러분의 코드가 31을 반환하고, 모델이 최종 결과를 사용자에게 설명

이 패턴은 어떤 도메인에도 일반화할 수 있습니다: 금융, 분석, 데이터 시각화, DevOps, BI 대시보드 등. Function calling + 여러분의 tools 조합은 유연하고 도메인에 특화된 AI 어시스턴트를 만드는 기반입니다.


Want to Generate Any Type of Charts Easily with the Power of ChatGPT? Try VizGPT (opens in a new tab) — describe your data and chart in natural language and get beautiful charts with no code.

How to Create Charts with VizGPT (opens in a new tab)

VizGPT: Create Charts with the Power of ChatGPT (opens in a new tab)


Related OpenAI Updates (High-Level)

OpenAI는 function calling 및 tooling 경험을 다음과 같은 방식으로 지속적으로 개선해 왔습니다:

  • 최신 모델에서 더 커진 컨텍스트 윈도우를 제공하여, 긴 대화·문서·스키마를 더 쉽게 다룰 수 있게 함
  • tools와 response formats에 대한 Structured Outputs를 추가해, 모델 출력이 여러분의 JSON Schema를 확실히 따르도록 개선
  • 보다 풍부해진 Responses API와 tools 생태계(웹 검색, 파일 검색, 코드 실행 등)를 통해, 동일한 function-calling 개념으로 풀 에이전트형 워크플로를 구축하기 쉽게 만듦

요금 및 최신 모델 목록은 항상 공식 OpenAI 문서와 가격 페이지를 확인하세요.


Wrapping Up

Function calling은 LLM을 실용적이고 신뢰할 수 있는 스택의 구성 요소로 바꾸는 가장 강력한 방법 중 하나입니다:

  • 여러분은 JSON Schema로 함수가 할 수 있는 일을 설명하고,
  • 모델은 언제, 어떻게 그 함수를 호출할지 결정하며,
  • 백엔드는 호출을 실행하고, 모델과 함께 풍부한 사용자 경험을 만들어 냅니다.

미팅 일정 잡기, 주가 조회, 여행 예약에서부터 PyGWalker, VizGPT 같은 도구와 연동된 풀 BI 대시보드에 이르기까지, function calling은 자연어와 실제 동작을 이어주는 접착제 역할을 합니다.

간단한 단일 함수부터 시작해 모든 것을 꼼꼼히 검증하고, 애플리케이션이 성숙해질수록 다단계 에이전트 워크플로로 확장해 보세요.


Frequently Asked Questions

  1. What is OpenAI’s function calling feature?

    Function calling은 JSON Schema로 함수(tools)를 설명해 두면, 모델이 일반 텍스트 대신 구조화된 함수 호출을 반환하도록 해 주는 기능입니다. 모델이 직접 코드를 실행하는 것은 아니며, 애플리케이션이 tool call을 파싱해 실제 함수를 실행합니다.

  2. Which models support function calling?

    최신 GPT-4, GPT-4.1, GPT-4o, GPT-4o-mini, 그리고 이후의 GPT-5/o-series 모델들이 Chat Completions 및 Responses API를 통해 tools/function calling을 지원합니다. 지원 모델 목록은 항상 OpenAI 문서에서 최신 정보를 확인하세요.

  3. Should I use the old functions / function_call parameters?

    사용하지 않는 것이 좋습니다. 이들은 1세대 function-calling 파라미터로, 이제는 레거시로 간주됩니다. 새로운 코드는 더 유연하고 최신 모델·API 전반에서 동작하는 toolstool_choice를 사용해야 합니다.

  4. How is this different from JSON Mode or Structured Outputs?

    • JSON Mode (response_format: { "type": "json_object" })는 모델이 유효한 JSON을 반환하도록 보장하지만, 특정 스키마를 강제하진 않습니다.
    • Function calling with Structured Outputs(tool 정의에서 strict: true)는 arguments가 여러분이 제공한 JSON Schema를 반드시 따르도록 합니다.
    • 더 강력한 제어를 위해 function calling과 JSON Mode를 함께 사용할 수도 있습니다.
  5. What are some common use cases?

    • 외부 API(날씨, CRM, 티켓 시스템, 내부 도구 등)를 호출하는 챗봇
    • 자연어 → API 호출, SQL 쿼리, 검색 필터 생성
    • 비정형 텍스트를 구조화된 레코드로 바꾸는 데이터 추출 파이프라인
    • 자동화, 분석, BI를 위한 다단계 “에이전트” 워크플로
📚