1. 왜 tool-call을 이해해야 할까
간단히 말해, 일반 웹앱은 “사용자가 버튼을 눌렀다 — 우리가 함수를 호출했다”라는 흐름으로 동작합니다. ChatGPT Apps의 세계는 다릅니다. 사용자가 무언가 말하면 모델이 생각하고, 필요하다고 판단하면 구조화된 도구 호출(tool-call)을 생성합니다.
즉, 여러분은 다음처럼 작성하지 않습니다:
onClick={() => callSuggestGiftsApi(formData)}
그 대신 이렇게 합니다:
- suggest_gifts 도구를 설명합니다(이름, 설명, 인자 스키마).
- system-prompt에서 이 도구가 언제 유용한지 모델에 설명합니다.
- 결정을 모델에 맡깁니다. 언제 어떻게 호출할지 모델이 스스로 결정합니다.
따라서 초기에 두 가지를 명확히 이해하는 것이 중요합니다:
- GPT는 여러분의 백엔드 코드를 보지 않습니다. 도구의 “헤더”: 이름, 설명, 파라미터 스키마만 봅니다.
- 모델이 앱을 얼마나 “영리하게” 사용할지는 여러분이 그 설명을 어떻게 썼는지에 거의 비례합니다. 좋은 설명이 곧 여러분의 “도구를 위한 프롬프트”입니다.
오늘 강의는 바로 사용자와 여러분의 서버 사이에 있는 이 “두뇌”에 관한 것입니다.
2. tool-call의 멘탈 모델: 무슨 일이 일어나는가
전체 그림부터 보겠습니다. GiftGenius의 전형적인 시나리오:
- 사용자: “30살 친구에게 줄 선물 추천, 예산 100달러, 비디오게임을 좋아함”.
- GPT가 이 메시지를 읽고 어떤 도구가 있는지 봅니다. 예를 들어 우리 앱에는 suggest_gifts가 있습니다.
- GPT는 “좋은 답변을 하려면 이 도구를 호출해야겠다”고 결정합니다.
- 일반 텍스트 응답 대신 도구 이름과 JSON 인자를 가진 구조를 생성합니다.
- ChatGPT 클라이언트는 “아, 이것은 tool-call이구나”라고 인식하고 여러분의 MCP/서버로 보냅니다.
- 서버가 비즈니스 로직을 실행하고 구조화된 결과를 반환합니다.
- GPT는 결과를 읽고 이를 바탕으로 사용자에게 이해하기 쉬운 답을 생성하거나 위젯을 업데이트합니다.
OpenAI API 관점에서 이것은 LLM-function-calling과 동일한 메커니즘입니다. 모델의 답변에는 일반 텍스트 대신 도구의 name과 arguments가 담긴 객체가 나타나고, finish_reason은 tool_calls로 표시됩니다. 모델이 직접 코드를 실행하는 것이 아니라 “어떤 도구를 호출해야 하는지”를 제안하고, 실제 호출은 클라이언트(ChatGPT/Apps SDK)가 수행합니다.
대략 다음과 같습니다(단순화된 순서):
sequenceDiagram
participant U as 사용자
participant G as GPT (모델)
participant C as ChatGPT 클라이언트
participant S as MCP/Backend
U->>G: "친구에게 줄 선물 골라줘..."
G->>C: tool-call: { name: "suggest_gifts", args: {...} }
C->>S: HTTP /mcp tools/call (suggest_gifts, args)
S-->>C: 결과(선물 목록이 담긴 JSON)
C-->>G: tool result
G-->>U: 응답 + 업데이트된 위젯
핵심 요점: 여러분은 if(userAskedAboutGifts) callSuggestGifts()를 쓰지 않습니다. 도구와 그 설명을 만들고, 결정은 모델이 내립니다.
3. 모델이 보는 것: System Prompt + 도구 목록
GPT가 무엇을 할지 결정하는 과정을 이해하려면, 그 순간 모델이 어떤 정보를 갖고 있는지 분명히 알아야 합니다.
모델이 대략적으로 보는 것:
- 앱의 system‑prompt(자세한 내용은 모듈 5에서 다룹니다);
- 대화 히스토리: 사용자 메시지, 자신의 이전 응답, 과거 tool-call 결과;
- 사용 가능한 도구 목록(tools): 각 도구의 이름, 설명, 파라미터 스키마;
- 추가적인 도구 주석(readOnly/destructive 등).
모델이 보지 못하는 것:
- 함수 구현;
- SQL 쿼리;
- 테이블 구조;
- 서비스가 들어 있는 프라이빗 리포지토리의 내용.
MCP에 대해서는 곧 자세히 이야기하겠습니다. 지금은 MCP 레벨에서 도구가 디스크립터로 선언된다는 것만 알면 충분합니다. 각 도구에는 name, description, inputSchema(JSON Schema)가 있습니다. 핸드셰이크 시 ChatGPT는 MCP 서버에서 도구 목록을 받아들이고, 그것들을 사용 가능한 “행동”으로 간주합니다.
GiftGenius용 디스크립터 예시(단순화된 JSON):
{
"name": "suggest_gifts",
"description": "나이, 관심사, 예산에 따라 선물 아이디어를 추천합니다",
"inputSchema": {
"type": "object",
"properties": {
"age": { "type": "integer" },
"budget": { "type": "number" }
},
"required": ["age", "budget"]
}
}
모델은 여기서 텍스트와 구조만 “읽습니다”: age가 무엇인지, budget이 무엇인지, 그리고 도구가 전반적으로 무엇을 하는지. 다음 강의에서는 inputSchema를 잘 설계하는 방법을 다룹니다. 지금은 이 설명을 바탕으로 “그렇다면 suggest_gifts를 호출하자”라는 결정이 어떻게 나오는지에 집중하겠습니다.
4. API 관점에서 본 tool-call
ChatGPT는 여러분의 MCP 서버(tools)에 있는 도구를, OpenAI Agent가 여러분의 백엔드 함수들을 호출하는 것과 거의 같은 방식으로 호출합니다. ChatGPT Apps SDK에서는 이것이 조금 더 래핑되어 있지만, 기본 메커니즘은 동일합니다.
상상해봅시다. 우리 백엔드에서 OpenAI API에 일반 요청을 보내면서, 모델이 응답에서 호출할 수 있는 suggest_gifts 도구를 함께 전달한다고 합시다:
const response = await openai.responses.create({
model: 'gpt-5-mini',
messages: [
{
role: 'user',
content: '30살 친구에게 줄 선물이 필요해요, 예산은 100달러예요'
}
],
tools: [ // 여기에서 LLM이 "호출"할 수 있는 함수 목록을 전달합니다
{
name: 'suggest_gifts',
description: '나이, 예산, 관심사에 따라 선물을 추천합니다',
parameters: {
type: 'object',
properties: {
age: { type: 'integer' },
budget: { type: 'number' }
},
required: ['age', 'budget']
}
}
]
});
모델이 도구 호출을 선택하면, 텍스트가 아니라 다음과 비슷한 어시스턴트 메시지를 받게 됩니다:
{
"role": "assistant",
"tool_calls": [
{
"id": "call_1",
"name": "suggest_gifts",
"arguments": "{\"age\":30,\"budget\":100}"
}
],
"content": []
}
이 방식으로 LLM은 여러분의 백엔드에 suggest_gifts(30,100)을 호출해야 한다고 말합니다.
여기서 중요한 점 세 가지:
- 도구의 이름(name): 첫 요청에서 여러분이 tools 설명에 제공한 그 문자열을 모델이 그대로 넣습니다.
- 인자(arguments): parameters/inputSchema를 기반으로 조립된 JSON 문자열입니다.
- 일반 텍스트 응답이 없음(일단은): 그 대신 도구 호출을 위한 구조를 받습니다.
ChatGPT 애플리케이션에서도 동일합니다. 모델은 “suggest_gifts를 이런 파라미터로 호출하고 싶다”고 반환하고, 클라이언트(ChatGPT)가 여러분의 MCP/서버에 tools/call HTTP 요청을 보냅니다. 이때 도구 이름과 인자가 함께 전달됩니다.
5. 모델은 어떻게 결정하는가: 도구 또는 텍스트
이제 가장 흥미로운 부분입니다. GPT는 언제 여러분의 도구를 떠올릴까요?
간단히 말하면 메커니즘은 이렇습니다:
- 모델은 새 사용자 메시지와 현재 컨텍스트를 봅니다.
- 내부적으로 다음 어시스턴트 메시지를 생성하는 “층”이 있는데, 항상 텍스트를 내보내는 대신 모델은 종료 방식을 선택할 수 있습니다:
- 일반 텍스트 응답(finish_reason: "stop");
- 하나 이상의 tool-call(finish_reason: "tool_calls");
- 때로는 다른 선택지(예: “사용자 메시지가 더 필요함”).
- 이 선택에 영향을 주는 요소:
- 사용자 요청이 도구 설명에 있는 작업들과 얼마나 유사한가;
- 도구 설명이 “이런 경우 나를 사용해”라고 얼마나 명확히 말하고 있는가;
- Apps SDK의 설정으로 지정된 app system prompt의 지시사항.
쉽게 말해, 모델은 현재 요청에 여러분의 도구를 “대입”해 봅니다. 설명이 “나이와 관심사에 따라 선물을 추천한다”인데 사용자가 “국가 예산 분석”을 요구하면 모델은 호출을 시도하지 않을 것입니다. 설명이 “멋진 작업을 함”처럼 모호하면, 어떤 요청에 써야 하는지 모델이 이해하지 못합니다.
흥미로운 점: 도구를 정의했다고 해서 반드시 호출되는 것은 아닙니다. GPT는 “이건 내가 그냥 답하면 되겠다, tool‑call 없이”라고 판단할 수도 있습니다. 그래서 다음 강의들에서는 모델이 도구를 최대한 명확하고 이득 있게 사용하도록 만드는 좋은 도구 설명을 연습할 것입니다.
6. 도구 이름: 왜 tool1은 나쁜 아이디어인가
도구 이름은 모델이 호출에 사용할 식별자입니다. 기술적 필드처럼 보이지만, 실제로 이름은 모델의 행동에 큰 영향을 줍니다.
도구를 tool1이라고 부르면, 모델은 아무것도 이해하지 못합니다. 단지 문자들의 조합일 뿐입니다. 반면 suggest_gifts, search_products, fetch_user_orders처럼 이름만으로도 무엇을 하는지 드러나는 경우가 좋습니다.
낯선 코드를 읽을 때를 떠올려 보세요. calculateCartTotal이라는 함수를 보면 대략 무엇을 할지 짐작이 갑니다. 모델에게도 그런 “의미적 앵커”가 필요합니다.
GiftGenius에 적합한 도구 이름 예:
suggest_gifts
search_products
get_product_details
create_order
좋은 이름의 기준:
- 짧지만 의미가 명확할 것;
- 일관된 스타일(snake_case, 영문, 동사_명사 패턴);
- 하나의 구체적인 행동을 나타낼 것.
여러 행동을 하나의 도구에 섞는 것은 좋지 않습니다. 예: do_all_gift_stuff. 모델이 언제 사용해야 하는지 이해하기 어려워지고, 이후 강의에서 보겠지만 인자 스키마가 망가지고 디버깅도 복잡해집니다.
7. 도구 설명: 모델을 위한 여러분의 프롬프트
이름이 제목이라면, description은 미니 문서입니다. 하지만 사람(개발자)을 위한 게 아니라 바로 GPT를 위한 문서입니다. 개발자는 코드를 읽을 수 있지만 모델은 못 봅니다. 모델은 도구를 언제 호출하고 어떤 인자를 넣어야 할지 결정할 때 설명 텍스트에 의존합니다.
“사용 지침” 스타일로 설명을 작성하세요:
- 언제 도구를 사용할지;
- 어떤 제약이 있는지;
- 무엇을 하지 않아야 하는지.
suggest_gifts를 예로 들어 세 가지 설명을 보겠습니다.
너무 광범위함:
"선물을 추천합니다."
누구를 위해, 어떤 경우에, 어떤 파라미터를 받는지 모델이 알 수 없습니다. 이 도구는 모델의 일반 지식과 “경합”하게 되고, 모델은 종종 그냥 텍스트로 답하려 할 수 있습니다.
너무 협소함:
"어린 남동생의 생일 선물에만 해당합니다."
사실상 거의 항상 사용을 금지한 셈입니다. 엄마, 동료, 기념일 등 다른 모든 시나리오는 “해당 없음”이 되어 모델이 호출을 피하게 됩니다.
적절함:
"나이, 관계 유형(친구, 파트너, 동료 등), 예산, 관심사를 기준으로 특정 사람에게 맞는 선물을 추천해야 할 때 이 도구를 사용하라.
선물과 관련 없는 질문(예: 정치, 날씨)에는 호출하지 말라."
무엇을 하는 도구인지, 어떤 파라미터가 있는지, 언제 호출해야 하는지, 그리고 언제 호출하지 말아야 하는지(부정 조건)까지 명확합니다.
모델은 이런 명확한 경계를 “좋아”합니다. 어떤 사용자 표현(의도)에서 도구가 적절한지 분명히 할수록, 앱의 동작은 더 예측 가능해집니다.
미니 연습
지금 바로 여러분의 앱(선물 추천이 아니어도 됨)을 떠올리고, 그중 한 도구에 대해 설명을 세 가지 써 보세요: 너무 넓은 것, 너무 좁은 것, 그리고 균형 잡힌 것. 그리고 각 버전으로 GPT의 동작이 어떻게 달라지는지 테스트해 보세요.
8. 인자 스키마: 결정에 어떻게 도움이 되는가
JSON Schema는 다음 강의에서 자세히 다루겠지만, tool-call을 이해하려면 상위 레벨 감각만 있어도 충분합니다.
모델이 도구를 호출하기로 하면 해야 할 일:
- 이 도구가 어떤 인자를 기대하는지 이해.
- 그 값을 사용자 텍스트(또는 컨텍스트)에서 추출.
- 이 인자들로 JSON을 구성.
이를 위해 도구 설명에는 모델에게 알려 주는 파라미터 스키마(inputSchema)가 있습니다:
- 어떤 필드가 있는지(age, budget, relationship_type, interests 등);
- 어떤 필드가 필수인지(required);
- 타입은 무엇인지(integer, number, string, 배열 등);
- 가끔은 허용 가능한 값(enum)과 필드 설명(description)도 포함됩니다.
suggest_gifts의 간단한 TypeScript 인터페이스는 다음과 같을 수 있습니다:
interface SuggestGiftsParams {
age: number;
relationship_type: 'friend' | 'partner' | 'colleague';
budget: number;
interests?: string[];
}
모델 관점에서는 이것이 JSON Schema로 변환되고, 모델은 각 필드의 이름과 설명을 보고 다음을 추론합니다:
- age: “30살”, “청소년용” 같은 표현에서 추출;
- budget: “예산 100달러”, “최대 50유로” 같은 표현에서 추출;
- relationship_type: “친구”, “동료” 같은 표현에서 추출;
- interests: “비디오게임을 좋아함” 같은 표현에서 추출.
설명 없이 a, b, c 같은 추상적인 필드명만 주면, 모델은 인자 채우기에서 훨씬 더 자주 실수합니다. 이 주제는 로컬라이제이션과 UX 힌트 모듈에서 다시 다룹니다. 핵심은 간단합니다. 스키마는 백엔드 검증용일 뿐 아니라, 모델에게 무엇을 어디에 넣어야 하는지 알려 주는 힌트입니다.
지금까지 스키마가 모델이 인자를 올바르게 구성하도록 돕는 방식을 다뤘습니다. 하지만 “무엇을 어떻게 호출하느냐”만큼이나 “지금 바로 호출해도 되는가, 얼마나 안전한가”도 중요합니다. 여기서 권한과 도구의 메타 정보가 역할을 합니다.
9. 권한과 컨텍스트: 모든 도구가 항상 사용 가능한 것은 아니다
도구에는 이름, 설명, 인자 스키마 외에 보안과 접근이라는 중요한 차원이 있습니다. 실제 앱에서 도구들은 “위험도”가 각기 다릅니다. 공개 카탈로그에서 선물 검색을 하는 것과 사용자 카드에서 돈을 차감하는 것은 전혀 다른 일입니다.
Apps SDK와 MCP는 도구 설명과 주석에서 이를 반영할 수 있게 해 줍니다. 예를 들어 read-only 또는 destructive로 표시할 수 있습니다.
아이디어는 이렇습니다:
- 공개 데이터를 읽기만 하는 도구(search_products, get_weather)는 추가 확인 없이 호출할 수 있습니다.
- 무언가를 변경하는 도구(create_order, cancel_order, charge_user)는 “파괴적”으로 표시합니다. ChatGPT UI는 사용자에게 추가 확인(“정말 주문하시겠습니까?”)을 요청할 수 있고, 모델 역시 명시적 요청 없이는 이런 도구를 덜 제안합니다.
MCP를 설정할 때 _meta, destructiveHint, readOnlyHint 같은 주석이 실제 JSON 디스크립터에서 어떻게 보이는지, 그것들이 UX와 호출 전 “Are you sure?” 대화 상자 형성에 어떤 영향을 주는지 살펴볼 것입니다. 지금은 다음만 이해하면 충분합니다:
- GPT는 설명 텍스트뿐 아니라 보안 메타 정보도 고려합니다.
- 인증이 필요한 도구는 사용자가 로그인하기 전(또는 앱이 필요한 토큰을 얻기 전)에는 사용되지 않습니다.
이는 “도구를 실행할지 말지” 결정에 영향을 주는 또 다른 요소입니다. 의미상 적합하더라도 권한상 사용할 수 없으면 모델은 다른 길을 택할 수 있습니다.
10. ChatGPT에서 도구는 어디서 오는가
아키텍처 관점에서 도구는 두 가지 경로로 모델에 도달합니다.
첫째, 여러분의 ChatGPT App 구성에서 옵니다. 앱을 등록할 때 어떤 MCP 서버(및 그 도구들)를 연결할지, 또는 앱 자체에 어떤 내장 tools가 있는지 지정합니다. 세션이 시작되면 ChatGPT는 이 구성을 받아 어떤 도구가 사용 가능한지 알게 됩니다.
둘째, MCP에서 직접 옵니다. MCP(Model Context Protocol)는 클라이언트(여기서는 ChatGPT/Apps SDK)가 여러분의 서버가 무엇을 할 수 있는지를 표준 방식으로 알아내는 방법을 정의합니다. 클라이언트는 tools/list를 요청하고, 도구 설명이 담긴 JSON을 받아 이를 capabilities로 보관합니다. 자세한 메커니즘은 MCP 모듈에서 다룹니다. 지금은 큰 흐름만 이해하면 충분합니다.
간단히 도식화하면:
flowchart LR A[ChatGPT Client] -->|handshake| B[MCP Server] B -->|tools/list| A A -->|목록 전달| G[GPT Model]
그 후 도구 목록은 모델의 컨텍스트 일부가 됩니다. 서버에서 도구의 스키마나 설명을 바꾸고 앱을 재시작하면, 다음 핸드셰이크 때 ChatGPT가 새로운 디스크립터를 받아 모델은 그에 맞춰 호출 결정을 새롭게 내리기 시작합니다.
그리고 중요한 실무 팁: 백엔드(도구 구현)만 바꾸면 모델은 그것을 알지 못합니다. 하지만 name/description/schema를 바꾸면 앱의 “두뇌”를 실제로 바꾸는 것입니다. 때로는 description의 한 줄을 다듬는 것이, 수십~수백 줄의 휴리스틱 코드를 쓰는 것보다 더 큰 효과를 냅니다.
11. GiftGenius에 적용: 모델이 호출하고 싶어 하는 도구 만들기
이제 학습용 앱 GiftGenius에 연결해 봅시다. MCP 서버나 백엔드 레이어가 있다고 가정하고, 그 안에 도구를 등록합니다. server.registerTool(...)로 suggest_gifts를 등록해 보겠습니다.
TypeScript로 작성한 아주 단순한 스케치(아직 실제 로직 없음):
// pseudo-mcp-server/tools/suggestGifts.ts
server.registerTool(
'suggest_gifts', // 도구 이름
{
title: '선물 추천',
description:
'나이, 관계 유형, 예산을 기준으로 선물 아이디어를 추천할 때 이 도구를 사용하세요. ' +
'선물과 관련 없는 질문에는 호출하지 마세요.',
inputSchema: { // 도구 매개변수 설명
type: 'object',
properties: {
age: { type: 'integer', description: '받는 사람의 나이(연)' },
relationship_type: {
type: 'string',
description: '관계 유형: friend, partner, colleague'
},
budget: {
type: 'number',
description: '사용자 통화 기준 최대 예산'
}
},
required: ['age', 'budget']
}
},
async ({ age, relationship_type, budget }) => { // 함수/도구 코드
// 실제 로직은 나중에 구현
return { suggestions: [] };
}
);
아직 로직은 “스텁”이지만, 이 단계에서 이미 다음을 신경 썼습니다:
- 이름: suggest_gifts, tool1이 아님.
- 설명: 언제 도구를 호출하고 언제 호출하지 말아야 하는지 명시.
- 필드 설명: 모델이 사용자 텍스트를 인자에 올바르게 매핑하도록 도움.
그 결과, 사용자가 “동료에게 줄 50달러 선물 추천”이라고 쓰면, 모델은 다음을 보게 됩니다:
- suggest_gifts라는 이름의 도구가 있고, 선물 추천에 관한 설명이 있음;
- age, relationship_type, budget 필드가 존재함;
- budget은 “선물에 쓸 최대 예산”, relationship_type은 “관계 유형: friend, partner, colleague”.
사용자가 “오십 불 정도”, “프로젝트 파트너”처럼 모호하게 말하더라도, 모델은 인자 JSON을 그럴듯하게 구성할 수 있을 만큼의 컨텍스트를 갖게 됩니다.
백엔드와 MCP 모듈에서 이 도구가 실제로 동작하기 시작하면, 여러분은 이미 이 주제에 익숙해져 있을 것입니다. 우리가 인터페이스와 설명을 잘 설계했기 때문에, GPT는 예측 가능하게 이 도구를 호출할 것입니다.
12. 작지만 유용한 실습
이론에만 머물지 않도록, 강의 직후 간단한 실험을 해 보길 권합니다.
먼저 GiftGenius의 시나리오 중 하나를 선택하거나 새로운 앱을 구상하세요. 모델에게 제공하고 싶은 함수 하나를 적어 봅니다 — 예: search_products, find_hotels, calculate_shipping.
그리고 같은 도구에 대해 “이름 + 설명” 세 가지 버전을 만듭니다:
- 매우 추상적인 이름과 설명.
- 지나치게 구체적인 버전(거의 특수 케이스 수준).
- 좋은 균형의 이름 + 설명: 언제 호출하고 무엇을 하지 말아야 하는지 명확히 서술.
선택 사항으로, 일반 OpenAI SDK를 사용해 이 버전들로 간단한 요청을 만들어 보며 모델의 동작이 어떻게 달라지는지 확인해 보세요. 도구가 호출되는지, 인자를 어떻게 채우는지 등을 비교합니다. 이 주제 연구에서는 suggest_gifts를 가지고 이런 유형의 연습을 예로 듭니다.
13. tool-call과 설명 설계에서 흔한 실수
실수 №1: 도구 이름을 tool1, handler, doStuff 처럼 짓기.
이런 네이밍은 모델에게 아무 도움이 되지 않습니다. GPT는 파일명으로 “개발자의 의도”를 추측하지 않습니다. 의미가 분명한 이름이 필요합니다. tool1, tool2, tool3처럼 설명 없이 주면, 모델은 각 도구가 무엇을 하는지 이해하지 못해 거의 호출하지 않거나, 우연히 하나를 고를 뿐입니다.
실수 №2: description을 사람을 위한 주석으로만 여김.
“선물 추천 함수”처럼 형식적으로만 적고, 자세한 내용은 코드에 있으니 괜찮다고 생각하는 경우가 많습니다. 하지만 모델은 코드를 보지 못합니다. 설명 텍스트와 인자 스키마만 볼 수 있습니다. 모호한 설명은 환각의 원인이 됩니다. 원래 도구를 호출해야 할 때 모델이 그냥 스스로 답하려 하거나, 엉뚱한 상황에서 도구를 호출하기도 합니다.
실수 №3: 설명을 너무 넓거나 너무 좁게 작성.
“멋진 일을 수행함”이라고 쓰면 적용 범위를 모델이 이해하지 못합니다. “어린 남동생의 18번째 생일 선물에만 해당”이라고 쓰면, 대부분의 상황에서 사용을 금지한 셈입니다. 최적의 설명은 명확한 적용 범위(여러 파라미터를 바탕으로 선물 추천), 핵심 파라미터 목록(나이, 관계, 예산, 관심사), 사용하지 말아야 할 질문 범위를 함께 제시합니다.
실수 №4: 인자 스키마를 “프롬프트”의 일부로 보지 않음.
일부 개발자는 JSON Schema를 서버 측 검증 용도로만 봅니다. 실제로 모델은 필드 이름, 타입, 설명을 적극적으로 분석하여 사용자 텍스트에서 어떤 데이터를 뽑아야 하는지 판단합니다. x 같은 이름을 설명 없이 옵션으로 두면, GPT는 그것을 제멋대로 채우거나 아예 비워 둘 것입니다. 명확한 이름과 간결한 설명이 있는 올바른 스키마는 잘못된 tool-call을 크게 줄여 줍니다.
실수 №5: 모델이 “반드시” 도구를 호출할 것이라 기대.
“왜 GPT가 내 도구를 호출하지 않았지? 있는데도?”라는 놀라움을 종종 봅니다. 답은 거의 같습니다. 설명이나 system‑prompt만으로는 해당 질문에 도구가 필요하다는 결론이 나오지 않거나, 그보다 모델이 스스로 답하는 것이 더 쉽다고 판단했기 때문입니다.
실수 №6: 서로 다른 여러 행동을 한 도구에 섞기.
manage_orders 하나에 주문 조회, 생성, 취소를 모두 넣고 싶을 수 있습니다. 사람에겐 설명이 가능할지 몰라도, 모델에게는 경계가 흐릿한 도구가 됩니다. 언제 호출해야 하는지 이해하기 어려워지고, 내부에 옵션 필드가 잔뜩 생겨 인자 채우기도 복잡해집니다. get_order, create_order, cancel_order처럼 여러 좁은 도구로 분리하고, 각 도구에 명확한 설명과 스키마를 주는 편이 낫습니다.
실수 №7: 도구 설계에서 권한과 보안을 고려하지 않음.
파괴적 행동(결제, 데이터 삭제 등)을 할 수 있는 도구를 설명하면서 destructive로 표시하지 않거나, 설명에서 사용 범위를 제한하지 않으면 위험을 만들게 됩니다. ChatGPT UI가 추가 확인을 묻지 않을 수 있고, 모델이 “경계선” 시나리오에서도 도구 호출을 제안할 수 있습니다. 적절한 주석과 신중한 설명(“사용자의 명시적 동의가 있는 경우에만 사용”)은 tool‑call 단계에서부터 이런 위험을 낮춰 줍니다.
GO TO FULL VERSION