함수 호출 튜토리얼

함수 호출을 통해 생성 모델에서 구조화된 데이터 출력을 더 쉽게 가져올 수 있습니다. 그런 다음 이러한 출력을 사용하여 다른 API를 호출하고 관련 응답 데이터를 모델에 반환할 수 있습니다. 즉, 함수 호출은 생성 모델을 외부 시스템에 연결하여 생성된 콘텐츠에 가장 정확한 최신 정보가 포함되도록 하는 데 도움이 됩니다.

Gemini 모델에 함수에 대한 설명을 제공할 수 있습니다. 이러한 함수는 개발자가 앱의 언어로 작성하는 함수입니다 (즉, Google Cloud Functions가 아님). 모델이 쿼리를 처리하는 데 도움이 되도록 함수를 호출하고 결과를 다시 보내도록 요청할 수 있습니다.

자세한 내용은 함수 호출 소개를 참고하세요. Google Colab에서 이 기능을 사용해 보거나 Gemini API 설명서 저장소에서 예시 코드를 볼 수도 있습니다.

조명 제어를 위한 API의 예

애플리케이션 프로그래밍 인터페이스 (API)가 있는 기본 조명 제어 시스템이 있으며 사용자가 간단한 텍스트 요청을 통해 조명을 제어할 수 있도록 한다고 가정해 보겠습니다. 함수 호출 기능을 사용하여 사용자의 광원 변경 요청을 해석하고 API 호출로 변환하여 광원 값을 설정할 수 있습니다. 이 가상의 조명 제어 시스템을 사용하면 두 개의 개별 매개변수로 정의된 빛의 밝기와 색상 온도를 제어할 수 있습니다.

파라미터 유형 필수 설명
brightness 숫자 0~100 사이의 빛 밝기입니다. 0은 꺼져 있고 100은 최대 밝기입니다.
colorTemperature 문자열 조명 기구의 색상 온도입니다(daylight, cool, warm일 수 있음).

편의상 이 가상의 조명 시스템에는 하나의 광원만 있으므로 사용자는 방이나 위치를 지정할 필요가 없습니다. 다음은 조명 제어 API에 전송하여 일광 색상 온도를 사용하여 조도를 50%로 변경하도록 할 수 있는 JSON 요청의 예입니다.

{
  "brightness": "50",
  "colorTemperature": "daylight"
}

이 튜토리얼에서는 Gemini API에 대한 함수 호출을 설정하여 사용자의 조명 요청을 해석하고 이를 API 설정에 매핑하여 조명의 밝기 및 색상 온도 값을 제어하는 방법을 보여줍니다.

시작하기 전에: 프로젝트 및 API 키 설정

Gemini API를 호출하기 전에 프로젝트를 설정하고 API 키를 구성해야 합니다.

API 함수 정의

API 요청을 하는 함수를 만듭니다. 이 함수는 애플리케이션의 코드 내에서 정의해야 하지만 애플리케이션 외부의 서비스나 API를 호출할 수 있습니다. Gemini API는 이 함수를 직접 호출하지 않으므로 애플리케이션 코드를 통해 이 함수가 실행되는 방법과 시기를 제어할 수 있습니다. 시연을 위해 이 튜토리얼에서는 요청된 조명 값만 반환하는 모의 API 함수를 정의합니다.

def set_light_values(brightness, color_temp):
    """Set the brightness and color temperature of a room light. (mock API).

    Args:
        brightness: Light level from 0 to 100. Zero is off and 100 is full brightness
        color_temp: Color temperature of the light fixture, which can be `daylight`, `cool` or `warm`.

    Returns:
        A dictionary containing the set brightness and color temperature.
    """
    return {
        "brightness": brightness,
        "colorTemperature": color_temp
    }

모델의 함수 호출에 사용할 함수를 만들 때는 함수 및 매개변수 설명에 최대한 많은 세부정보를 포함해야 합니다. 생성 모델은 이 정보를 사용하여 선택할 함수와 함수 호출에서 매개변수 값을 제공하는 방법을 결정합니다.

모델 초기화 중 함수 선언

모델에서 함수 호출을 사용하려면 모델 객체를 초기화할 때 함수를 선언해야 합니다. 모델의 tools 매개변수를 설정하여 함수를 선언합니다.

model = genai.GenerativeModel(model_name='gemini-1.5-flash',
                              tools=[set_light_values])

함수 호출 생성

함수 선언으로 모델을 초기화한 후에는 정의된 함수를 사용하여 모델에 프롬프트를 표시할 수 있습니다. 채팅 프롬프팅 (sendMessage())을 사용하는 함수 호출을 사용해야 합니다. 일반적으로 함수 호출에는 이전 프롬프트와 응답의 컨텍스트가 있으면 이점이 있기 때문입니다.

chat = model.start_chat()
response = chat.send_message('Dim the lights so the room feels cozy and warm.')
response.text

Python SDK의 ChatSession 객체는 대화 기록을 처리하여 채팅 세션 관리를 간소화합니다. enable_automatic_function_calling를 사용하여 SDK가 자동으로 실행되도록 할 수 있습니다.

# Create a chat session that automatically makes suggested function calls
chat = model.start_chat(enable_automatic_function_calling=True)

병렬 함수 호출

위에서 설명한 기본 함수 호출 외에도 한 번에 여러 함수를 호출할 수 있습니다. 이 섹션에서는 병렬 함수 호출을 사용하는 방법의 예를 보여줍니다.

도구를 정의합니다.

def power_disco_ball(power: bool) -> bool:
    """Powers the spinning disco ball."""
    print(f"Disco ball is {'spinning!' if power else 'stopped.'}")
    return True


def start_music(energetic: bool, loud: bool, bpm: int) -> str:
    """Play some music matching the specified parameters.

    Args:
      energetic: Whether the music is energetic or not.
      loud: Whether the music is loud or not.
      bpm: The beats per minute of the music.

    Returns: The name of the song being played.
    """
    print(f"Starting music! {energetic=} {loud=}, {bpm=}")
    return "Never gonna give you up."


def dim_lights(brightness: float) -> bool:
    """Dim the lights.

    Args:
      brightness: The brightness of the lights, 0.0 is off, 1.0 is full.
    """
    print(f"Lights are now set to {brightness:.0%}")
    return True

이제 지정된 모든 도구를 사용할 수 있는 명령으로 모델을 호출하세요.

# Set the model up with tools.
house_fns = [power_disco_ball, start_music, dim_lights]

model = genai.GenerativeModel(model_name="gemini-1.5-flash", tools=house_fns)

# Call the API.
chat = model.start_chat()
response = chat.send_message("Turn this place into a party!")

# Print out each of the function calls requested from this single call.
for part in response.parts:
    if fn := part.function_call:
        args = ", ".join(f"{key}={val}" for key, val in fn.args.items())
        print(f"{fn.name}({args})")
power_disco_ball(power=True)
start_music(energetic=True, loud=True, bpm=120.0)
dim_lights(brightness=0.3)

출력된 각 결과는 모델이 요청한 단일 함수 호출을 반영합니다. 결과를 반환하려면 요청된 응답 순서대로 포함합니다.

# Simulate the responses from the specified tools.
responses = {
    "power_disco_ball": True,
    "start_music": "Never gonna give you up.",
    "dim_lights": True,
}

# Build the response parts.
response_parts = [
    genai.protos.Part(function_response=genai.protos.FunctionResponse(name=fn, response={"result": val}))
    for fn, val in responses.items()
]

response = chat.send_message(response_parts)
print(response.text)
Let's get this party started! I've turned on the disco ball, started playing some upbeat music, and dimmed the lights. 🎶✨  Get ready to dance! 🕺💃

함수 호출 데이터 유형 매핑

Python 함수에서 스키마 자동 추출이 모든 경우에 작동하지는 않습니다. 예를 들어 중첩된 사전 객체의 필드를 설명하는 사례는 처리하지 않지만 API는 이를 지원합니다. API는 다음 유형을 설명할 수 있습니다.

AllowedType = (int | float | bool | str | list['AllowedType'] | dict[str, AllowedType])

google.ai.generativelanguage 클라이언트 라이브러리는 전체 제어가 가능한 하위 수준 유형에 대한 액세스를 제공합니다.

먼저 모델의 _tools 속성을 들여다보면 모델에 전달한 함수를 어떻게 설명하는지 확인할 수 있습니다.

def multiply(a:float, b:float):
    """returns a * b."""
    return a*b

model = genai.GenerativeModel(model_name='gemini-1.5-flash',
                             tools=[multiply])

model._tools.to_proto()
[function_declarations {
   name: "multiply"
   description: "returns a * b."
   parameters {
     type_: OBJECT
     properties {
       key: "b"
       value {
         type_: NUMBER
       }
     }
     properties {
       key: "a"
       value {
         type_: NUMBER
       }
     }
     required: "a"
     required: "b"
   }
 }]

그러면 API로 전송될 genai.protos.Tool 객체의 목록이 반환됩니다. 인쇄된 형식이 익숙하지 않다면 이는 Google protobuf 클래스이기 때문입니다. 각 genai.protos.Tool (이 경우 1)에는 함수와 그 인수를 설명하는 genai.protos.FunctionDeclarations 목록이 포함됩니다.

다음은 genai.protos 클래스를 사용하여 작성된 동일한 곱하기 함수의 선언입니다. 이러한 클래스는 API의 함수만 설명하고 구현을 포함하지 않습니다. 따라서 이를 사용하는 것이 자동 함수 호출에서는 작동하지 않지만 함수에 항상 구현이 필요한 것은 아닙니다.

calculator = genai.protos.Tool(
    function_declarations=[
      genai.protos.FunctionDeclaration(
        name='multiply',
        description="Returns the product of two numbers.",
        parameters=genai.protos.Schema(
            type=genai.protos.Type.OBJECT,
            properties={
                'a':genai.protos.Schema(type=genai.protos.Type.NUMBER),
                'b':genai.protos.Schema(type=genai.protos.Type.NUMBER)
            },
            required=['a','b']
        )
      )
    ])

마찬가지로 이를 JSON 호환 객체로 설명할 수 있습니다.

calculator = {'function_declarations': [
      {'name': 'multiply',
       'description': 'Returns the product of two numbers.',
       'parameters': {'type_': 'OBJECT',
       'properties': {
         'a': {'type_': 'NUMBER'},
         'b': {'type_': 'NUMBER'} },
       'required': ['a', 'b']} }]}
genai.protos.Tool(calculator)
function_declarations {
  name: "multiply"
  description: "Returns the product of two numbers."
  parameters {
    type_: OBJECT
    properties {
      key: "b"
      value {
        type_: NUMBER
      }
    }
    properties {
      key: "a"
      value {
        type_: NUMBER
      }
    }
    required: "a"
    required: "b"
  }
}

어떤 방법을 사용하든 genai.protos.Tool 또는 도구 목록의 표현을

model = genai.GenerativeModel('gemini-1.5-flash', tools=calculator)
chat = model.start_chat()

response = chat.send_message(
    f"What's 234551 X 325552 ?",
)

모델이 계산기의 multiply 함수를 호출하는 genai.protos.FunctionCall를 반환하기 전과 마찬가지로 다음을 실행합니다.

response.candidates
[index: 0
content {
  parts {
    function_call {
      name: "multiply"
      args {
        fields {
          key: "b"
          value {
            number_value: 325552
          }
        }
        fields {
          key: "a"
          value {
            number_value: 234551
          }
        }
      }
    }
  }
  role: "model"
}
finish_reason: STOP
]

함수를 직접 실행합니다.

fc = response.candidates[0].content.parts[0].function_call
assert fc.name == 'multiply'

result = fc.args['a'] * fc.args['b']
result
76358547152.0

결과를 모델에 전송하여 대화를 계속합니다.

response = chat.send_message(
    genai.protos.Content(
    parts=[genai.protos.Part(
        function_response = genai.protos.FunctionResponse(
          name='multiply',
          response={'result': result}))]))