🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

Tool Schema 설계 완벽 가이드 - 슬라이드 1/6
A

AI Generated

2025. 12. 27. · 4 Views

Tool Schema 설계 완벽 가이드

LLM 기반 AI 에이전트에서 도구를 호출할 때 필수적인 Tool Schema 설계 방법을 다룹니다. JSON Schema 작성부터 파라미터 정의, 타입 최적화, 복잡한 도구 스키마 실습까지 초급 개발자도 쉽게 따라할 수 있도록 설명합니다.


목차

  1. JSON_Schema_작성
  2. 파라미터_정의_required와_optional
  3. 타입과_설명_최적화
  4. 실습_복잡한_도구_스키마
  5. 실습_도구_문서_자동_생성

1. JSON Schema 작성

어느 날 김개발 씨는 회사에서 새로운 프로젝트를 맡게 되었습니다. ChatGPT나 Claude 같은 LLM에 날씨 조회, 데이터베이스 검색 같은 기능을 연결하는 AI 에이전트를 만드는 일이었습니다.

그런데 막상 시작하려니 막막했습니다. "LLM이 내가 만든 함수를 어떻게 알고 호출하지?"

JSON Schema는 JSON 데이터의 구조를 정의하는 표준 명세입니다. 마치 건축 설계도가 건물의 구조를 미리 정해두는 것처럼, JSON Schema는 데이터가 어떤 형태여야 하는지 미리 정의해둡니다.

LLM에게 도구를 알려줄 때 바로 이 JSON Schema를 사용합니다.

다음 코드를 살펴봅시다.

// 기본적인 Tool Schema 구조
const weatherToolSchema = {
  name: "get_weather",
  description: "특정 도시의 현재 날씨 정보를 조회합니다",
  parameters: {
    type: "object",
    properties: {
      city: {
        type: "string",
        description: "날씨를 조회할 도시 이름 (예: 서울, 부산)"
      },
      unit: {
        type: "string",
        enum: ["celsius", "fahrenheit"],
        description: "온도 단위"
      }
    },
    required: ["city"]
  }
};

김개발 씨는 입사 6개월 차 주니어 개발자입니다. 최근 회사에서 AI 에이전트 개발 프로젝트에 투입되었는데, 처음 접하는 개념들이 많아 고민이 깊었습니다.

"선배님, LLM이 외부 API를 호출하려면 어떻게 해야 하나요?" 김개발 씨가 옆자리 박시니어 씨에게 조심스럽게 물었습니다. 박시니어 씨가 모니터를 돌려 보여주며 말했습니다.

"LLM은 똑똒하지만, 우리가 만든 함수가 어떻게 생겼는지는 모르거든요. 그래서 Tool Schema라는 걸 통해 함수의 사용 설명서를 전달해줘야 해요." 그렇다면 JSON Schema란 정확히 무엇일까요?

쉽게 비유하자면, JSON Schema는 마치 이케아 조립 설명서와 같습니다. 이케아에서 가구를 사면 어떤 부품이 필요하고, 각 부품이 어떤 모양이어야 하는지 상세하게 적혀 있습니다.

JSON Schema도 마찬가지로 "이 데이터는 이런 형태여야 해"라고 미리 정의해두는 것입니다. JSON Schema가 없던 시절에는 어땠을까요?

개발자들은 API 문서를 읽고 직접 데이터 형식을 맞춰야 했습니다. 문제는 사람마다 해석이 달랐다는 점입니다.

누군가는 날짜를 "2024-01-01"로 보내고, 다른 누군가는 "01/01/2024"로 보냈습니다. 이런 혼란을 방지하기 위해 표준화된 스키마가 필요했습니다.

LLM의 Function Calling 기능은 바로 이 JSON Schema를 활용합니다. 우리가 스키마를 전달하면 LLM은 "아, 이 도구는 city라는 문자열 파라미터가 필요하구나"라고 이해하게 됩니다.

위의 코드를 살펴보겠습니다. 가장 먼저 name 필드가 있습니다.

이것은 도구의 고유한 이름입니다. LLM이 이 도구를 호출할 때 사용하는 식별자이므로, 명확하고 간결하게 작성해야 합니다.

다음으로 description 필드가 있습니다. 이 부분이 매우 중요합니다.

LLM은 이 설명을 읽고 언제 이 도구를 사용해야 하는지 판단합니다. 마치 도서관 사서에게 "이 책은 어떤 내용이에요?"라고 물었을 때 돌아오는 대답과 같습니다.

parameters 필드는 도구가 받아들이는 입력값들을 정의합니다. type이 "object"인 것은 여러 개의 파라미터를 묶어서 전달한다는 의미입니다.

properties 안에 각각의 파라미터가 정의됩니다. 실제 현업에서는 이 스키마를 OpenAI API나 Anthropic API에 전달합니다.

API는 사용자의 질문을 받으면 스키마를 참고하여 적절한 도구를 선택하고, 필요한 파라미터를 추출하여 호출합니다. 김개발 씨가 고개를 끄덕였습니다.

"아, 그래서 스키마를 잘 작성해야 LLM이 제대로 이해하는 거군요!" 박시니어 씨가 웃으며 답했습니다. "맞아요.

스키마가 곧 LLM과 우리 코드 사이의 계약서인 셈이죠."

실전 팁

💡 - name은 snake_case로 작성하고, 동사로 시작하면 의도가 명확해집니다

  • description은 LLM이 도구 선택의 근거로 삼으므로 구체적으로 작성하세요

2. 파라미터 정의 required와 optional

김개발 씨는 날씨 조회 도구를 만들면서 고민에 빠졌습니다. 도시 이름은 반드시 필요하지만, 온도 단위는 사용자가 지정하지 않으면 기본값을 쓰면 됩니다.

"이걸 어떻게 구분하지?"

파라미터는 크게 **required(필수)**와 **optional(선택)**으로 나뉩니다. 마치 음식점에서 메인 메뉴는 반드시 주문해야 하지만 사이드 메뉴는 선택인 것처럼, 도구 호출에도 반드시 있어야 하는 값과 없어도 되는 값이 있습니다.

다음 코드를 살펴봅시다.

// 필수와 선택 파라미터를 구분하는 스키마
const searchProductSchema = {
  name: "search_products",
  description: "상품을 검색합니다. 키워드로 검색하거나 카테고리별로 필터링할 수 있습니다",
  parameters: {
    type: "object",
    properties: {
      keyword: {
        type: "string",
        description: "검색할 상품 키워드"
      },
      category: {
        type: "string",
        enum: ["electronics", "clothing", "books", "food"],
        description: "상품 카테고리 (선택사항)"
      },
      maxPrice: {
        type: "number",
        description: "최대 가격 필터 (선택사항)"
      },
      sortBy: {
        type: "string",
        enum: ["price", "rating", "newest"],
        default: "newest",
        description: "정렬 기준, 기본값은 newest"
      }
    },
    required: ["keyword"]  // keyword만 필수
  }
};

김개발 씨가 쇼핑몰 검색 기능을 만들던 중이었습니다. 사용자가 "노트북 검색해줘"라고 하면 키워드만으로 검색하고, "전자제품 카테고리에서 50만원 이하 노트북 찾아줘"라고 하면 여러 조건을 함께 적용해야 했습니다.

"필수 파라미터와 선택 파라미터를 어떻게 구분해야 할까요?" 김개발 씨의 질문에 박시니어 씨가 화이트보드로 다가갔습니다. "생각해봐요.

검색을 하려면 최소한 뭘 검색할지는 알아야 하잖아요. 그게 필수 파라미터예요.

반면에 카테고리나 가격 필터는 있으면 좋지만 없어도 검색은 가능하죠. 그게 선택 파라미터고요." 이것은 마치 택시를 탈 때와 같습니다.

목적지는 반드시 말해야 합니다. "강남역이요"라고요.

하지만 "고속도로로 가주세요"나 "조용한 음악 틀어주세요"는 말하지 않아도 됩니다. 목적지가 required이고, 나머지는 optional인 셈입니다.

JSON Schema에서 required 필드는 배열 형태입니다. 이 배열에 포함된 파라미터 이름들이 필수 파라미터가 됩니다.

배열에 없는 파라미터는 자동으로 선택 파라미터가 됩니다. 위 코드에서 required 배열에는 오직 "keyword"만 들어 있습니다.

따라서 LLM은 keyword가 없으면 도구를 호출할 수 없습니다. 반면 category, maxPrice, sortBy는 없어도 호출이 가능합니다.

여기서 중요한 것이 default 값입니다. sortBy 파라미터를 보면 default가 "newest"로 지정되어 있습니다.

사용자가 정렬 기준을 말하지 않으면 자동으로 최신순으로 정렬한다는 의미입니다. 실무에서 흔히 하는 실수 중 하나는 너무 많은 파라미터를 required로 지정하는 것입니다.

사용자가 "노트북 검색해줘"라고만 했는데 "카테고리도 말씀해주세요, 가격 범위도 말씀해주세요"라고 계속 물어보면 사용자 경험이 나빠집니다. 반대로 모든 것을 optional로 만드는 것도 문제입니다.

아무 정보 없이 검색을 실행하면 의미 있는 결과를 얻기 어렵습니다. 적절한 균형이 필요합니다.

enum 필드도 살펴봅시다. category의 enum을 보면 정해진 값들만 허용한다는 것을 알 수 있습니다.

LLM은 이 목록을 보고 사용자가 "옷"이라고 하면 "clothing"으로 매핑해줍니다. 김개발 씨가 이해했다는 듯 말했습니다.

"그러면 필수는 도구가 작동하기 위한 최소 조건이고, 선택은 더 정교한 결과를 위한 추가 옵션이네요." 박시니어 씨가 고개를 끄덕였습니다. "정확해요.

그리고 description에 '선택사항'이라고 명시해주면 LLM이 더 잘 이해해요."

실전 팁

💡 - 필수 파라미터는 도구가 작동하기 위한 최소한의 정보만 포함하세요

  • 선택 파라미터의 description에는 기본 동작이 무엇인지 명시하면 좋습니다
  • enum을 사용하면 LLM이 유효한 값만 선택하도록 제한할 수 있습니다

3. 타입과 설명 최적화

김개발 씨가 만든 도구가 자꾸 이상하게 동작했습니다. 분명히 숫자를 기대했는데 "삼"이라는 문자열이 들어오고, 날짜를 기대했는데 "내일"이라는 애매한 값이 들어왔습니다.

"타입을 더 명확하게 지정할 방법이 없을까요?"

타입 정의설명 최적화는 Tool Schema의 품질을 결정짓는 핵심 요소입니다. 마치 계약서의 조항을 명확하게 작성해야 분쟁을 예방할 수 있듯이, 스키마의 타입과 설명을 정교하게 작성해야 LLM이 정확한 값을 전달합니다.

다음 코드를 살펴봅시다.

// 타입과 설명이 최적화된 스키마
const createMeetingSchema = {
  name: "create_meeting",
  description: "새로운 회의를 생성합니다. 참석자에게 자동으로 초대 메일이 발송됩니다",
  parameters: {
    type: "object",
    properties: {
      title: {
        type: "string",
        minLength: 1,
        maxLength: 100,
        description: "회의 제목 (1-100자)"
      },
      startTime: {
        type: "string",
        format: "date-time",
        description: "회의 시작 시간 (ISO 8601 형식, 예: 2024-03-15T14:00:00+09:00)"
      },
      durationMinutes: {
        type: "integer",
        minimum: 15,
        maximum: 480,
        description: "회의 시간(분), 15분~8시간 사이"
      },
      attendees: {
        type: "array",
        items: { type: "string", format: "email" },
        minItems: 1,
        description: "참석자 이메일 주소 목록 (최소 1명)"
      },
      isRecurring: {
        type: "boolean",
        default: false,
        description: "반복 회의 여부"
      }
    },
    required: ["title", "startTime", "durationMinutes", "attendees"]
  }
};

어느 날 김개발 씨가 만든 회의 생성 도구에 문제가 생겼습니다. 사용자가 "내일 오후 3시에 회의 잡아줘"라고 했는데, LLM이 startTime에 "내일 오후 3시"라는 문자열을 그대로 전달한 것입니다.

"선배님, ISO 8601 형식으로 받고 싶은데 자꾸 자연어가 들어와요." 김개발 씨가 한숨을 쉬었습니다. 박시니어 씨가 스키마를 살펴보더니 말했습니다.

"description에 형식을 명시하지 않아서 그래요. LLM은 우리 생각보다 친절하게 안내해줘야 해요." 타입 시스템을 제대로 활용하는 것은 마치 주차장 입구 높이 제한과 같습니다.

"높이 2m 이하 차량만 진입 가능"이라고 써놓으면 대형 트럭은 알아서 들어오지 않습니다. 스키마도 마찬가지로 제한을 명시하면 잘못된 값이 들어오는 것을 방지할 수 있습니다.

JSON Schema는 다양한 검증 키워드를 제공합니다. 문자열에는 minLength, maxLength, pattern, format을 사용할 수 있습니다.

숫자에는 minimum, maximum, exclusiveMinimum을 사용할 수 있습니다. 배열에는 minItems, maxItems, uniqueItems를 사용할 수 있습니다.

위 코드에서 format 필드를 주목해보세요. format: "date-time"은 ISO 8601 형식의 날짜-시간 문자열을 기대한다는 의미입니다.

format: "email"은 이메일 형식을 기대합니다. 이렇게 명시하면 LLM이 알아서 적절한 형식으로 변환해줍니다.

integernumber의 차이도 중요합니다. integer는 정수만 허용하고, number는 소수점도 허용합니다.

회의 시간을 분 단위로 받는다면 integer가 적절합니다. 30.5분짜리 회의는 이상하니까요.

description 작성에도 요령이 있습니다. 단순히 "회의 시작 시간"이라고 쓰는 것보다 **"회의 시작 시간 (ISO 8601 형식, 예: 2024-03-15T14:00:00+09:00)"**이라고 쓰는 것이 훨씬 효과적입니다.

예시를 포함하면 LLM이 기대하는 형식을 정확히 파악합니다. 제약조건의 의미도 설명해주면 좋습니다.

"15분~8시간 사이"라고 쓰면 왜 그런 제한이 있는지 LLM이 이해합니다. 사용자가 "10분 회의 잡아줘"라고 하면 LLM이 "최소 15분 이상이어야 합니다"라고 안내할 수 있습니다.

array 타입을 사용할 때는 items 필드로 배열 요소의 타입을 지정합니다. attendees 필드를 보면 items에 문자열이면서 이메일 형식이어야 한다고 정의되어 있습니다.

minItems: 1은 최소 한 명의 참석자가 필요하다는 의미입니다. 김개발 씨가 스키마를 수정한 후 다시 테스트했습니다.

이번에는 "내일 오후 3시"가 "2024-03-15T15:00:00+09:00"으로 제대로 변환되어 들어왔습니다. "description 하나 바꿨을 뿐인데 이렇게 달라지네요!" 김개발 씨가 감탄했습니다.

박시니어 씨가 웃으며 말했습니다. "LLM과의 소통에서 description은 정말 중요해요.

친절하고 구체적으로 써주세요."

실전 팁

💡 - description에는 반드시 예시를 포함하세요. 예시가 있으면 LLM의 정확도가 크게 올라갑니다

  • 숫자 타입에는 minimum, maximum으로 유효 범위를 지정하세요
  • format 필드를 활용하면 date-time, email, uri 등 표준 형식을 강제할 수 있습니다

4. 실습 복잡한 도구 스키마

김개발 씨가 이제 기본기를 익혔다고 생각했을 때, 박시니어 씨가 새로운 과제를 던졌습니다. "이번에는 주문 생성 API를 연결해봐요.

여러 상품을 한 번에 주문하고, 배송 정보도 받아야 해요." 복잡한 중첩 구조를 어떻게 스키마로 표현할 수 있을까요?

실제 서비스에서는 단순한 파라미터만으로 부족할 때가 많습니다. **중첩 객체(nested object)**와 **객체 배열(array of objects)**을 활용하면 복잡한 데이터 구조도 스키마로 표현할 수 있습니다.

마치 택배 상자 안에 작은 상자들이 들어있는 것처럼, 객체 안에 객체를 넣을 수 있습니다.

다음 코드를 살펴봅시다.

// 복잡한 중첩 구조를 가진 주문 생성 스키마
const createOrderSchema = {
  name: "create_order",
  description: "새로운 주문을 생성합니다. 여러 상품을 한 번에 주문할 수 있습니다",
  parameters: {
    type: "object",
    properties: {
      items: {
        type: "array",
        description: "주문할 상품 목록",
        minItems: 1,
        items: {
          type: "object",
          properties: {
            productId: { type: "string", description: "상품 ID" },
            quantity: { type: "integer", minimum: 1, description: "수량" },
            options: {
              type: "object",
              properties: {
                color: { type: "string" },
                size: { type: "string", enum: ["S", "M", "L", "XL"] }
              }
            }
          },
          required: ["productId", "quantity"]
        }
      },
      shipping: {
        type: "object",
        description: "배송 정보",
        properties: {
          recipientName: { type: "string", description: "수령인 이름" },
          phone: { type: "string", pattern: "^01[0-9]-?[0-9]{4}-?[0-9]{4}$" },
          address: { type: "string", description: "배송 주소" },
          memo: { type: "string", description: "배송 메모 (선택)" }
        },
        required: ["recipientName", "phone", "address"]
      },
      paymentMethod: {
        type: "string",
        enum: ["card", "bank_transfer", "kakao_pay", "naver_pay"]
      }
    },
    required: ["items", "shipping", "paymentMethod"]
  }
};

김개발 씨 앞에 놓인 과제는 만만치 않았습니다. 쇼핑몰 주문 시스템을 AI 에이전트와 연결해야 했습니다.

사용자가 "빨간색 L사이즈 티셔츠 2개랑 검은색 M사이즈 바지 1개 주문해줘. 집으로 배송하고 카드로 결제할게"라고 하면 이 모든 정보를 구조화해서 API에 전달해야 했습니다.

"이건 단순한 key-value로는 안 되겠는데요..." 김개발 씨가 머리를 긁적였습니다. 박시니어 씨가 다가와 화면을 보더니 말했습니다.

"중첩 객체를 사용해야 해요. 객체 안에 또 객체를 넣는 거죠." 이것은 마치 러시안 인형 마트료시카와 같습니다.

큰 인형 안에 작은 인형이 들어있고, 그 안에 더 작은 인형이 들어있습니다. JSON Schema도 마찬가지로 객체 안에 객체를 정의할 수 있고, 그 깊이에는 제한이 없습니다.

위 코드의 items 필드를 살펴봅시다. type이 "array"이고, items 속성으로 배열 요소의 구조를 정의합니다.

여기서 배열 요소 자체가 또 하나의 객체입니다. productId, quantity, options라는 속성을 가진 객체가 배열의 각 요소가 됩니다.

더 깊이 들어가면 options가 또 다른 객체입니다. color와 size 속성을 가지고 있습니다.

이렇게 3단계 중첩이 발생했습니다: 최상위 객체 > items 배열 > items 요소 객체 > options 객체. shipping 필드도 중첩 객체입니다.

배송에 필요한 정보들을 하나의 논리적 그룹으로 묶었습니다. 이렇게 관련된 정보를 객체로 묶으면 스키마가 더 읽기 쉬워지고, 실제 API 호출 시에도 데이터 구조가 명확해집니다.

pattern 필드를 주목해보세요. phone 필드에 정규표현식 패턴이 지정되어 있습니다.

"^01[0-9]-?[0-9]{4}-?[0-9]{4}$"는 한국 휴대폰 번호 형식을 의미합니다. 이렇게 하면 LLM이 전화번호를 올바른 형식으로 전달합니다.

중첩 구조에서도 required는 각 레벨에서 독립적으로 동작합니다. 최상위에서 required: ["items", "shipping", "paymentMethod"]는 이 세 필드가 필수라는 의미입니다.

items 배열의 각 요소에서 required: ["productId", "quantity"]는 각 상품에 ID와 수량이 필수라는 의미입니다. shipping 객체 내부의 required는 배송 정보 중 필수 항목을 지정합니다.

실무에서 이런 복잡한 스키마를 만들 때 주의할 점이 있습니다. 너무 깊은 중첩은 피하는 것이 좋습니다.

3-4단계 이상 중첩되면 LLM이 구조를 파악하기 어려워질 수 있습니다. 또한 스키마가 복잡해지면 description을 더 상세하게 작성해야 합니다.

김개발 씨가 스키마를 완성하고 테스트해봤습니다. "빨간색 L사이즈 티셔츠 2개 주문해줘"라고 입력하니, LLM이 다음과 같이 구조화된 데이터를 반환했습니다.

json { "items": [{ "productId": "SHIRT-001", "quantity": 2, "options": { "color": "red", "size": "L" }}], "shipping": { ... }, "paymentMethod": "card" } "오, 정말 잘 되네요!" 김개발 씨가 기뻐했습니다.

박시니어 씨가 덧붙였습니다. "복잡한 스키마일수록 테스트를 많이 해봐야 해요.

다양한 표현으로 같은 주문을 시도해보세요."

실전 팁

💡 - 중첩은 3단계 이내로 유지하고, 더 복잡해지면 여러 도구로 분리하는 것을 고려하세요

  • 각 중첩 레벨의 객체에도 description을 작성해서 LLM이 구조를 이해하도록 도와주세요
  • 정규표현식 pattern은 강력하지만, description에도 예시를 함께 적어주면 좋습니다

5. 실습 도구 문서 자동 생성

김개발 씨의 프로젝트에 도구가 점점 늘어났습니다. 어느새 20개가 넘는 도구가 생겼는데, 팀원들이 어떤 도구가 있는지 파악하기 어려워했습니다.

"스키마를 기반으로 문서를 자동으로 만들 수 있으면 좋겠는데..."

Tool Schema는 그 자체로 문서입니다. 스키마에 이미 도구의 이름, 설명, 파라미터 정보가 모두 담겨있기 때문에, 이를 파싱하면 자동으로 사람이 읽을 수 있는 문서를 생성할 수 있습니다.

이렇게 하면 스키마와 문서가 항상 동기화됩니다.

다음 코드를 살펴봅시다.

// Tool Schema로부터 마크다운 문서를 생성하는 유틸리티
function generateToolDocs(schemas: ToolSchema[]): string {
  let markdown = "# AI Agent Tool Reference\n\n";

  for (const schema of schemas) {
    markdown += `## ${schema.name}\n\n`;
    markdown += `${schema.description}\n\n`;
    markdown += `### Parameters\n\n`;
    markdown += "| Name | Type | Required | Description |\n";
    markdown += "|------|------|----------|-------------|\n";

    const props = schema.parameters.properties;
    const required = schema.parameters.required || [];

    for (const [name, prop] of Object.entries(props)) {
      const isRequired = required.includes(name) ? "Yes" : "No";
      const type = formatType(prop);
      markdown += `| ${name} | ${type} | ${isRequired} | ${prop.description || "-"} |\n`;
    }
    markdown += "\n---\n\n";
  }
  return markdown;
}

// 타입 정보를 읽기 쉽게 포맷팅
function formatType(prop: any): string {
  if (prop.enum) return `enum: ${prop.enum.join(", ")}`;
  if (prop.type === "array") return `array<${prop.items?.type || "any"}>`;
  return prop.type + (prop.format ? ` (${prop.format})` : "");
}

어느 날 신입 개발자 이주니어 씨가 팀에 합류했습니다. 김개발 씨에게 물었습니다.

"AI 에이전트에 어떤 도구들이 있나요? 문서가 있으면 볼 수 있을까요?" 김개발 씨는 당황했습니다.

도구를 만들 때마다 따로 문서를 작성해둔 적이 없었기 때문입니다. 스키마 파일은 있지만, 개발자가 아닌 사람이 읽기에는 어려웠습니다.

"스키마에 이미 모든 정보가 있는데, 이걸 문서로 자동 변환하면 되지 않을까요?" 김개발 씨에게 아이디어가 떠올랐습니다. 이것은 마치 재료 라벨로 요리책을 만드는 것과 같습니다.

식재료 포장에는 이미 이름, 원산지, 영양 성분이 적혀있습니다. 이 정보를 모아서 정리하면 훌륭한 요리 가이드가 됩니다.

Tool Schema도 마찬가지로 이미 모든 정보를 담고 있으므로, 이를 변환하면 문서가 됩니다. 문서 자동화의 가장 큰 장점은 동기화 문제가 없다는 것입니다.

수동으로 문서를 작성하면 코드가 바뀔 때 문서를 깜빡하고 업데이트하지 않는 경우가 많습니다. 하지만 자동 생성이면 스키마가 바뀌면 문서도 자동으로 바뀝니다.

위 코드의 generateToolDocs 함수를 살펴봅시다. schemas 배열을 받아서 각 스키마를 순회하며 마크다운을 생성합니다.

먼저 도구 이름을 h2 헤더로 출력하고, description을 그 아래에 배치합니다. 파라미터 테이블은 가장 중요한 부분입니다.

마크다운 테이블 문법을 사용해서 파라미터의 이름, 타입, 필수 여부, 설명을 한눈에 볼 수 있게 정리합니다. formatType 함수는 타입 정보를 사람이 읽기 쉽게 변환합니다.

enum이면 가능한 값들을 나열하고, array면 요소 타입을 표시하고, format이 있으면 함께 표시합니다. 실무에서는 이 기본 구조를 확장할 수 있습니다.

예를 들어 예제 코드 자동 생성 기능을 추가할 수 있습니다. 스키마를 기반으로 샘플 호출 코드를 만들어 문서에 포함시키는 것입니다.

typescript // 예제 자동 생성 확장 function generateExample(schema: ToolSchema): string { const example: any = {}; for (const [name, prop] of Object.entries(schema.parameters.properties)) { example[name] = getExampleValue(prop); } return JSON.stringify(example, null, 2); } 또한 CI/CD 파이프라인에 통합하면 더 강력해집니다. 코드가 푸시될 때마다 자동으로 문서를 생성하고 위키나 Notion에 업데이트하도록 설정할 수 있습니다.

김개발 씨가 문서 생성기를 만들고 실행해봤습니다. 20개 도구에 대한 깔끔한 마크다운 문서가 순식간에 만들어졌습니다.

이주니어 씨가 문서를 보며 말했습니다. "오, 이거 정말 보기 쉽네요!

어떤 도구가 있는지 한눈에 파악이 돼요." 박시니어 씨가 덧붙였습니다. "문서화는 협업의 기본이에요.

스키마가 곧 문서가 되도록 설계하면 관리 부담이 크게 줄어들죠."

실전 팁

💡 - 문서 생성 스크립트를 CI/CD에 통합하여 매 배포마다 자동으로 문서를 업데이트하세요

  • TypeScript를 사용한다면 스키마 타입 정의에서 직접 문서를 생성할 수도 있습니다
  • OpenAPI/Swagger 형식으로 변환하면 API 문서 도구들과 연동할 수 있습니다

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#LLM#ToolSchema#JSONSchema#AIAgent#FunctionCalling#LLM,Schema,설계

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.

함께 보면 좋은 카드 뉴스

Context Fundamentals - AI 컨텍스트의 기본 원리

AI 에이전트 개발의 핵심인 컨텍스트 관리를 다룹니다. 시스템 프롬프트 구조부터 Attention Budget, Progressive Disclosure까지 실무에서 바로 적용할 수 있는 컨텍스트 최적화 전략을 배웁니다.

프로덕션 워크플로 배포 완벽 가이드

LLM 기반 애플리케이션을 실제 운영 환경에 배포하기 위한 워크플로 최적화, 캐싱 전략, 비용 관리 방법을 다룹니다. Airflow와 서버리스 아키텍처를 활용한 실습까지 포함하여 초급 개발자도 프로덕션 수준의 배포를 할 수 있도록 안내합니다.

LangChain LCEL 완벽 가이드

LangChain Expression Language(LCEL)를 활용하여 AI 체인을 우아하게 구성하는 방법을 배웁니다. 파이프 연산자부터 커스텀 체인 개발까지, 실무에서 바로 활용할 수 있는 핵심 개념을 다룹니다.

Human-in-the-Loop Workflow 완벽 가이드

AI 시스템에서 인간의 판단과 승인을 통합하는 Human-in-the-Loop 워크플로를 알아봅니다. 자동화와 인간 감독의 균형을 맞추는 핵심 패턴을 초급자도 이해할 수 있게 설명합니다.

Router 패턴으로 배우는 LLM 워크플로 설계

LLM 애플리케이션에서 여러 전문가 모델을 효율적으로 연결하고 태스크에 따라 적절한 처리 경로를 선택하는 Router 패턴을 배웁니다. 실무에서 바로 적용할 수 있는 도메인별 라우터와 전문가 선택 시스템을 직접 구현해봅니다.