함수 호출 소개

대규모 언어 모델(LLM)은 여러 유형의 문제를 해결하는 데 효과적입니다. 그러나 다음과 같은 제한사항이 적용됩니다.

  • 학습 후 고정되므로 오래된 지식이 제공됩니다.
  • 외부 데이터를 쿼리하거나 수정할 수 없습니다.

함수 호출로 이러한 단점을 해결할 수 있습니다. 이를 통해 모델이 API 및 함수와 같은 외부 도구를 사용할 수 있기 때문에 함수 호출을 도구 사용이라고도 합니다.

LLM에 프롬프트를 제출할 때 사용자의 프롬프트에 대답하는 데 사용할 수 있는 도구 모음도 모델에 제공합니다. 예를 들어 위치 파라미터를 받아 해당 위치의 기상 조건에 대한 정보를 반환하는 get_weather 함수를 제공할 수 있습니다.

프롬프트를 처리하는 동안 모델은 사용자가 식별한 함수에 특정 데이터 처리 태스크를 위임할 수 있습니다. 모델은 함수를 직접 호출하지 않습니다. 대신 모델은 호출할 함수와 사용할 매개변수 값을 포함하는 정형 데이터 출력을 제공합니다. 예를 들어 프롬프트 What is the weather like in Boston?의 경우 모델은 처리를 get_weather 함수에 위임하고 위치 매개변수 값 Boston, MA를 제공할 수 있습니다.

모델의 정형 출력을 사용하여 외부 API를 호출할 수 있습니다. 예를 들어 날씨 서비스 API에 연결하고 Boston, MA 위치를 제공하면 온도, 구름 양, 바람 상태에 대한 정보를 받을 수 있습니다.

그런 다음 API 출력을 다시 모델에 제공하여 프롬프트에 대한 응답을 완료할 수 있습니다. 날씨 예시의 경우 모델은 다음과 같은 응답을 제공할 수 있습니다. It is currently 38 degrees Fahrenheit in Boston, MA with partly cloudy skies.

함수 호출 상호작용 

지원되는 모델

다음 모델은 함수 호출을 지원합니다.

모델 버전 함수 호출 실행 단계 병렬 함수 호출 지원 강제 함수 호출 지원
Gemini 1.0 Pro all versions 정식 버전 아니요 아니요
Gemini 1.5 Flash all versions 정식 버전
Gemini 1.5 Pro all versions 정식 버전

함수 호출 사용 사례

다음 태스크에 함수 호출을 사용할 수 있습니다.

사용 사례 예시 설명 예시 링크
외부 API와 통합 기상 API를 사용하여 날씨 정보 가져오기 Notebook 튜토리얼
주소를 위도/경도 좌표로 변환 Notebook 튜토리얼
Currency Exchange API를 사용하여 통화 변환 Codelab
고급 챗봇 빌드 제품 및 서비스에 관한 고객 질문에 답변 Notebook 튜토리얼
회사에 대한 금융 및 뉴스 질문에 답변하는 어시스턴트 만들기 메모장 튜토리얼
함수 호출 구조 및 제어 원시 로그 데이터에서 구조화된 항목 추출 Notebook 튜토리얼
사용자 입력에서 단일 또는 여러 매개변수 추출 메모장 튜토리얼
함수 호출에서 목록 및 중첩 데이터 구조 처리 메모장 튜토리얼
함수 호출 동작 처리 병렬 함수 호출 및 응답 처리 Notebook 튜토리얼
모델이 호출할 수 있는 시점 및 함수 관리 메모장 튜토리얼
자연어로 데이터베이스 쿼리 자연어 질문을 BigQuery용 SQL 쿼리로 변환 샘플 앱
멀티모달 함수 호출 이미지, 동영상, 오디오, PDF를 입력으로 사용하여 함수 호출 트리거 Notebook 튜토리얼

다음은 몇 가지 더 많은 사용 사례입니다.

  • 음성 명령 해석: 차내 태스크에 해당하는 함수를 만듭니다. 예를 들어 라디오를 켜거나 에어컨을 활성화하는 함수를 만들 수 있습니다. 사용자 음성 명령 오디오 파일을 모델에 전송하고 오디오를 텍스트로 변환하고 사용자가 호출하려는 함수를 식별하도록 모델에 요청합니다.

  • 환경 트리거를 기반으로 워크플로 자동화: 자동화할 수 있는 프로세스를 나타내는 함수를 만듭니다. 모델에 환경 센서의 데이터를 제공하고 데이터를 파싱 및 처리하여 워크플로 하나 이상이 활성화되어야 하는지 여부를 결정하도록 요청합니다. 예를 들어 모델이 창고에서 온도 데이터를 처리하고 스프링클러 함수를 활성화할 수 있습니다.

  • 지원 티켓 할당 자동화: 모델에 지원 티켓, 로그, 컨텍스트 인식 규칙을 제공합니다. 모델에 이 모든 정보를 모두 처리하여 티켓이 할당되어야 하는 대상을 결정하도록 요청합니다. 함수를 호출하여 모델이 추천한 사용자에게 티켓을 할당합니다.

  • 기술 자료에서 정보 검색: 특정 주제에 대한 학술 자료를 검색하고 요약하는 함수를 만듭니다. 모델이 학술 주제에 대한 질문에 답하고 답변에 대한 인용을 제공할 수 있도록 사용 설정합니다.

함수 호출 애플리케이션을 만드는 방법

사용자가 모델과 연결하고 함수 호출을 사용할 수 있게 하려면 다음 태스크를 수행하는 코드를 만들어야 합니다.

  1. 환경을 설정합니다.
  2. 함수 선언을 사용하여 사용 가능한 함수 집합을 정의하고 설명합니다.
  3. 사용자 프롬프트와 함수 선언을 모델에 제출합니다.
  4. 모델의 구조화된 데이터 출력을 사용하여 함수를 호출합니다.
  5. 함수 출력을 모델에 제공합니다.

이러한 모든 태스크를 관리하는 애플리케이션을 만들 수 있습니다. 이 애플리케이션은 문자 메시지 챗봇, 음성 에이전트, 자동 워크플로, 기타 프로그램 등일 수 있습니다.

함수 호출을 사용하여 단일 텍스트 응답을 생성하거나 채팅 세션을 지원할 수 있습니다. 임시 텍스트 응답은 코드 생성을 포함한 특정 비즈니스 태스크에 유용합니다. 채팅 세션은 사용자가 후속 질문을 할 가능성이 높은 자유 형식의 대화 시나리오에 유용합니다.

함수 호출을 사용하여 단일 응답을 생성하는 경우 모델에 상호작용의 전체 컨텍스트를 제공해야 합니다. 반면 채팅 세션 컨텍스트에서 함수 호출을 사용하는 경우 세션에서 자동으로 컨텍스트를 저장하고 모든 모델 요청에 컨텍스트를 포함합니다. 두 경우 모두 Vertex AI는 클라이언트 측에 상호작용 기록을 저장합니다.

이 가이드에서는 함수 호출을 사용하여 단일 텍스트 응답을 생성하는 방법을 보여줍니다. 엔드 투 엔드 샘플은 텍스트 예를 참고하세요. 함수 호출을 사용하여 채팅 세션을 지원하는 방법은 채팅 예시를 참조하세요.

1단계: 환경 설정

필요한 모듈을 가져오고 모델을 초기화합니다.

Python

import vertexai
from vertexai.generative_models import (
    Content,
    FunctionDeclaration,
    GenerationConfig,
    GenerativeModel,
    Part,
    Tool,
)

# Initialize Vertex AI
# TODO(developer): Update and un-comment below lines
# PROJECT_ID = 'your-project-id'
vertexai.init(project=PROJECT_ID, location="us-central1")

# Initialize Gemini model
model = GenerativeModel(model_name="gemini-1.5-flash-002")

2단계: 함수 집합 선언

애플리케이션은 모델에서 프롬프트를 처리하는 데 사용할 수 있는 함수 집합을 선언해야 합니다.

요청과 함께 제공할 수 있는 최대 함수 선언 수는 128개입니다.

OpenAPI 스키마와 호환되는 스키마 형식으로 함수 선언을 제공해야 합니다. Vertex AI는 OpenAPI 스키마를 제한적으로 지원합니다. type, nullable, required, format, description, properties, items, enum 속성이 지원됩니다. default, optional, maximum, oneOf 속성은 지원되지 않습니다. 이름 및 설명에 관한 팁을 비롯하여 함수 선언과 관련된 권장사항은 권장사항을 참고하세요.

REST API를 사용하는 경우 JSON을 사용하여 스키마를 지정합니다. Python용 Vertex AI SDK를 사용하는 경우 Python 사전을 사용하여 스키마를 수동으로 지정하거나 from_func 도우미 함수를 사용하여 자동으로 지정할 수 있습니다.

JSON

{
  "contents": ...,
  "tools": [
    {
      "function_declarations": [
        {
          "name": "find_movies",
          "description": "find movie titles currently playing in theaters based on any description, genre, title words, etc.",
          "parameters": {
            "type": "object",
            "properties": {
              "location": {
                "type": "string",
                "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
              },
              "description": {
                "type": "string",
                "description": "Any kind of description including category or genre, title words, attributes, etc."
              }
            },
            "required": [
              "description"
            ]
          }
        },
        {
          "name": "find_theaters",
          "description": "find theaters based on location and optionally movie title which are is currently playing in theaters",
          "parameters": {
            "type": "object",
            "properties": {
              "location": {
                "type": "string",
                "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
              },
              "movie": {
                "type": "string",
                "description": "Any movie title"
              }
            },
            "required": [
              "location"
            ]
          }
        },
        {
          "name": "get_showtimes",
          "description": "Find the start times for movies playing in a specific theater",
          "parameters": {
            "type": "object",
            "properties": {
              "location": {
                "type": "string",
                "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
              },
              "movie": {
                "type": "string",
                "description": "Any movie title"
              },
              "theater": {
                "type": "string",
                "description": "Name of the theater"
              },
              "date": {
                "type": "string",
                "description": "Date for requested showtime"
              }
            },
            "required": [
              "location",
              "movie",
              "theater",
              "date"
            ]
          }
        }
      ]
    }
  ]
}

Python 사전

다음 함수 선언은 단일 string 매개변수를 사용합니다.

function_name = "get_current_weather"
get_current_weather_func = FunctionDeclaration(
    name=function_name,
    description="Get the current weather in a given location",
    # Function parameters are specified in JSON schema format
    parameters={
        "type": "object",
        "properties": {
            "location": {"type": "string", "description": "The city name of the location for which to get the weather."}
        },
    },
)

다음 함수 선언은 객체 매개변수와 배열 매개변수를 모두 사용합니다.

extract_sale_records_func = FunctionDeclaration(
  name="extract_sale_records",
  description="Extract sale records from a document.",
  parameters={
      "type": "object",
      "properties": {
          "records": {
              "type": "array",
              "description": "A list of sale records",
              "items": {
                  "description": "Data for a sale record",
                  "type": "object",
                  "properties": {
                      "id": {"type": "integer", "description": "The unique id of the sale."},
                      "date": {"type": "string", "description": "Date of the sale, in the format of MMDDYY, e.g., 031023"},
                      "total_amount": {"type": "number", "description": "The total amount of the sale."},
                      "customer_name": {"type": "string", "description": "The name of the customer, including first name and last name."},
                      "customer_contact": {"type": "string", "description": "The phone number of the customer, e.g., 650-123-4567."},
                  },
                  "required": ["id", "date", "total_amount"],
              },
          },
      },
      "required": ["records"],
  },
)

함수에서 Python

다음 코드 샘플은 숫자 배열을 곱하고 from_func를 사용하여 FunctionDeclaration 스키마를 생성하는 함수를 선언합니다.

# Define a function. Could be a local function or you can import the requests library to call an API
def multiply_numbers(numbers):
  """
  Calculates the product of all numbers in an array.

  Args:
      numbers: An array of numbers to be multiplied.

  Returns:
      The product of all the numbers. If the array is empty, returns 1.
  """

  if not numbers:  # Handle empty array
      return 1

  product = 1
  for num in numbers:
      product *= num

  return product

multiply_number_func = FunctionDeclaration.from_func(multiply_numbers)

'''
multiply_number_func contains the following schema:

name: "multiply_numbers"
description: "Calculates the product of all numbers in an array."
parameters {
  type_: OBJECT
  properties {
    key: "numbers"
    value {
      description: "An array of numbers to be multiplied."
      title: "Numbers"
    }
  }
  required: "numbers"
  description: "Calculates the product of all numbers in an array."
  title: "multiply_numbers"
}
'''

3단계: 모델에 프롬프트 및 함수 선언 제출

사용자가 프롬프트를 제공하면 애플리케이션에서 사용자 프롬프트 및 함수 선언을 모델에 제공해야 합니다. 모델의 결과 생성 방법을 구성하기 위해 애플리케이션에서 생성 구성을 모델에 제공할 수 있습니다. 모델의 함수 선언 사용 방법을 구성하기 위해 애플리케이션에서 도구 구성을 모델에 제공할 수 있습니다.

사용자 프롬프트 정의

'보스턴 날씨는 어때?'는 사용자 프롬프트의 예시입니다.

다음은 사용자 메시지를 정의하는 방법의 예입니다.

Python

# Define the user's prompt in a Content object that we can reuse in model calls
user_prompt_content = Content(
    role="user",
    parts=[
        Part.from_text("What is the weather like in Boston?"),
    ],
)

사용자 프롬프트와 관련된 권장사항은 권장사항 - 사용자 프롬프트를 참조하세요.

생성 구성

모델은 서로 다른 매개변수 값에 대해 서로 다른 결과를 생성할 수 있습니다. 강도 매개변수는 이 생성의 무작위성 수준을 제어합니다. 강도가 낮을수록 결정론적 매개변수 값이 필요한 함수에 적합하고, 강도가 높을수록 보다 다양하거나 창의적인 매개변수 값을 허용하는 매개변수를 사용하는 함수에 적합합니다. 0의 강도는 결정론적입니다. 이 경우 특정 프롬프트에 대한 응답은 대부분 확정적이지만 여전히 약간의 변형이 가능합니다. 자세한 내용은 Gemini API를 참조하세요.

이 매개변수를 설정하려면 프롬프트 및 함수 선언과 함께 생성 구성(generation_config)을 제출합니다. Vertex AI API 및 업데이트된 generation_config를 사용하여 채팅 대화 중에 temperature 매개변수를 업데이트할 수 있습니다. temperature 매개변수를 설정하는 예는 프롬프트 및 함수 선언을 제출하는 방법을 참고하세요.

생성 구성과 관련된 권장사항은 권장사항 - 생성 구성을 참조하세요.

도구 구성

모델이 제공된 함수 선언을 사용하는 방법에 몇 가지 제약조건을 지정할 수 있습니다. 예를 들어 모델이 자연어 응답과 함수 호출 중에서 선택하도록 허용하는 대신 함수 호출 ('강제 함수 호출' 또는 '제어된 생성을 사용한 함수 호출')만 예측하도록 할 수 있습니다. 모델에 전체 함수 선언 집합을 제공할 수도 있지만 이러한 함수의 하위 집합으로 응답을 제한할 수도 있습니다.

이러한 제약조건을 적용하려면 프롬프트 및 함수 선언과 함께 도구 구성(tool_config)을 제출합니다. 구성에서는 다음 모드 중 하나를 지정할 수 있습니다.

모드 설명
AUTO 기본 모델 동작입니다. 모델이 함수 호출과 자연어 응답 중 무엇을 예측할지 결정합니다.
ANY 모델이 항상 함수 호출을 예측하도록 제한됩니다. allowed_function_names가 제공되지 않으면 모델은 사용 가능한 모든 함수 선언 중에서 선택합니다. allowed_function_names가 제공되면 모델은 허용된 함수 세트에서 선택합니다.
NONE 모델이 함수 호출을 예측하지 않습니다. 이 동작은 연결된 함수 선언이 없는 모델 요청과 동일합니다.

ANY 모드 ('강제 함수 호출')를 지원하는 모델 목록은 지원되는 모델을 참고하세요.

자세한 내용은 Function Calling API를 참조하세요.

프롬프트 및 함수 선언을 제출하는 방법

다음은 프롬프트 및 함수 선언을 모델에 제출하고 get_current_weather 함수 호출만 예측하도록 모델을 제한하는 방법에 대한 예시입니다.

Python

# Define a tool that includes some of the functions that we declared earlier
tool = Tool(
    function_declarations=[get_current_weather_func, extract_sale_records_func, multiply_number_func],
)

# Send the prompt and instruct the model to generate content using the Tool object that you just created
response = model.generate_content(
    user_prompt_content,
    generation_config=GenerationConfig(temperature=0),
    tools=[tool],
    tool_config=ToolConfig(
        function_calling_config=ToolConfig.FunctionCallingConfig(
            # ANY mode forces the model to predict only function calls
            mode=ToolConfig.FunctionCallingConfig.Mode.ANY,
            # Allowed function calls to predict when the mode is ANY. If empty, any  of
            # the provided function calls will be predicted.
            allowed_function_names=["get_current_weather"],
        )
    )
)

모델에서 특정 함수 출력이 필요하다고 판단하면 애플리케이션이 모델에서 수신하는 응답에는 함수 이름과 함수를 호출해야 하는 매개변수 값이 포함됩니다.

다음은 사용자 프롬프트인 '보스턴 날씨는 어때?'에 대한 모델 응답의 예시입니다. 모델은 Boston, MA 매개변수를 사용하여 get_current_weather 함수를 호출하도록 제안합니다.

candidates {
  content {
    role: "model"
    parts {
      function_call {
        name: "get_current_weather"
        args {
          fields {
            key: "location"
            value {
              string_value: "Boston, MA"
            }
          }
        }
      }
    }
  }
  ...
}

'뉴델리와 샌프란시스코의 날씨 세부정보를 가져올까요?'와 같은 프롬프트의 경우 모델은 여러 개의 병렬 함수 호출을 제안할 수 있습니다. 자세한 내용은 병렬 함수 호출 예시를 참고하세요.

4단계: 외부 API 호출

애플리케이션이 모델에서 함수 이름과 매개변수 값을 수신하면 애플리케이션에서 외부 API에 연결하고 함수를 호출해야 합니다.

다음 예시에서는 합성 데이터를 사용하여 외부 API의 응답 페이로드를 시뮬레이션합니다.

Python

# Check the function name that the model responded with, and make an API call to an external system
if (response.candidates[0].function_calls[0].name == "get_current_weather"):
    # Extract the arguments to use in your API call
    location = response.candidates[0].function_calls[0].args["location"]

    # Here you can use your preferred method to make an API request to fetch the current weather, for example:
    # api_response = requests.post(weather_api_url, data={"location": location})

    # In this example, we'll use synthetic data to simulate a response payload from an external API
    api_response = """{ "location": "Boston, MA", "temperature": 38, "description": "Partly Cloudy",
                    "icon": "partly-cloudy", "humidity": 65, "wind": { "speed": 10, "direction": "NW" } }"""

API 호출과 관련된 권장사항은 권장사항 - API 호출을 참조하세요.

5단계: 모델에 함수의 출력 제공

애플리케이션이 외부 API에서 응답을 수신하면 애플리케이션에서 이 응답을 모델에 제공해야 합니다. 다음은 Python을 사용하여 이 작업을 수행하는 방법에 대한 예시입니다.

Python

response = model.generate_content(
    [
        user_prompt_content,  # User prompt
        response.candidates[0].content,  # Function call response
        Content(
            parts=[
                Part.from_function_response(
                    name="get_current_weather",
                    response={
                        "content": api_response,  # Return the API response to Gemini
                    },
                )
            ],
        ),
    ],
    tools=[weather_tool],
)
# Get the model summary response
summary = response.text

모델이 여러 개의 병렬 함수 호출을 제안한 경우 애플리케이션은 모든 응답을 모델에 다시 제공해야 합니다. 자세한 내용은 병렬 함수 호출 예시를 참고하세요.

모델은 프롬프트에 응답하는 데 다른 함수의 출력이 필요하다고 판단할 수 있습니다. 이 경우 애플리케이션이 모델에서 수신하는 응답에는 다른 함수 이름과 다른 매개변수 값 집합이 포함됩니다.

모델에서 API 응답이 사용자 프롬프트에 응답하기에 충분하다고 판단하면 자연어 응답을 만들어 애플리케이션에 반환합니다. 이 경우 애플리케이션에서 응답을 다시 사용자에게 전달해야 합니다. 다음은 응답의 예시입니다.

It is currently 38 degrees Fahrenheit in Boston, MA with partly cloudy skies. The humidity is 65% and the wind is blowing at 10 mph from the northwest.

함수 호출 예

텍스트 예시

함수 호출을 사용하여 단일 텍스트 응답을 생성할 수 있습니다. 임시 텍스트 응답은 코드 생성을 포함한 특정 비즈니스 태스크에 유용합니다.

함수 호출을 사용하여 단일 응답을 생성하는 경우 모델에 상호작용의 전체 컨텍스트를 제공해야 합니다. Vertex AI는 클라이언트 측에 상호작용 기록을 저장합니다.

Python

이 예시에서는 함수 하나와 프롬프트 하나가 포함된 텍스트 시나리오를 보여줍니다. 여기서는 GenerativeModel 클래스와 해당 메서드를 사용합니다. Gemini 멀티모달 모델과 함께 Vertex AI SDK for Python을 사용하는 방법에 대한 자세한 내용은 Vertex AI SDK for Python의 멀티모달 클래스 소개를 참조하세요.

Python

Vertex AI SDK for Python을 설치하거나 업데이트하는 방법은 Vertex AI SDK for Python 설치를 참조하세요. 자세한 내용은 Python API 참고 문서를 확인하세요.

import vertexai

from vertexai.generative_models import (
    Content,
    FunctionDeclaration,
    GenerationConfig,
    GenerativeModel,
    Part,
    Tool,
)

# TODO(developer): Update & uncomment below line
# PROJECT_ID = "your-project-id"

# Initialize Vertex AI
vertexai.init(project=PROJECT_ID, location="us-central1")

# Initialize Gemini model
model = GenerativeModel("gemini-1.5-flash-002")

# Define the user's prompt in a Content object that we can reuse in model calls
user_prompt_content = Content(
    role="user",
    parts=[
        Part.from_text("What is the weather like in Boston?"),
    ],
)

# Specify a function declaration and parameters for an API request
function_name = "get_current_weather"
get_current_weather_func = FunctionDeclaration(
    name=function_name,
    description="Get the current weather in a given location",
    # Function parameters are specified in JSON schema format
    parameters={
        "type": "object",
        "properties": {"location": {"type": "string", "description": "Location"}},
    },
)

# Define a tool that includes the above get_current_weather_func
weather_tool = Tool(
    function_declarations=[get_current_weather_func],
)

# Send the prompt and instruct the model to generate content using the Tool that you just created
response = model.generate_content(
    user_prompt_content,
    generation_config=GenerationConfig(temperature=0),
    tools=[weather_tool],
)
function_call = response.candidates[0].function_calls[0]
print(function_call)

# Check the function name that the model responded with, and make an API call to an external system
if function_call.name == function_name:
    # Extract the arguments to use in your API call
    location = function_call.args["location"]  # noqa: F841

    # Here you can use your preferred method to make an API request to fetch the current weather, for example:
    # api_response = requests.post(weather_api_url, data={"location": location})

    # In this example, we'll use synthetic data to simulate a response payload from an external API
    api_response = """{ "location": "Boston, MA", "temperature": 38, "description": "Partly Cloudy",
                    "icon": "partly-cloudy", "humidity": 65, "wind": { "speed": 10, "direction": "NW" } }"""

# Return the API response to Gemini so it can generate a model response or request another function call
response = model.generate_content(
    [
        user_prompt_content,  # User prompt
        response.candidates[0].content,  # Function call response
        Content(
            parts=[
                Part.from_function_response(
                    name=function_name,
                    response={
                        "content": api_response,  # Return the API response to Gemini
                    },
                ),
            ],
        ),
    ],
    tools=[weather_tool],
)

# Get the model response
print(response.text)
# Example response:
# The weather in Boston is partly cloudy with a temperature of 38 degrees Fahrenheit.
# The humidity is 65% and the wind is blowing from the northwest at 10 mph.

C#

이 예시에서는 함수 하나와 프롬프트 하나가 포함된 텍스트 시나리오를 보여줍니다.

C#

이 샘플을 사용해 보기 전에 Vertex AI 빠른 시작: 클라이언트 라이브러리 사용C# 설정 안내를 따르세요. 자세한 내용은 Vertex AI C# API 참고 문서를 참조하세요.

Vertex AI에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.


using Google.Cloud.AIPlatform.V1;
using System;
using System.Threading.Tasks;
using Type = Google.Cloud.AIPlatform.V1.Type;
using Value = Google.Protobuf.WellKnownTypes.Value;

public class FunctionCalling
{
    public async Task<string> GenerateFunctionCall(
        string projectId = "your-project-id",
        string location = "us-central1",
        string publisher = "google",
        string model = "gemini-1.5-flash-001")
    {
        var predictionServiceClient = new PredictionServiceClientBuilder
        {
            Endpoint = $"{location}-aiplatform.googleapis.com"
        }.Build();

        // Define the user's prompt in a Content object that we can reuse in
        // model calls
        var userPromptContent = new Content
        {
            Role = "USER",
            Parts =
            {
                new Part { Text = "What is the weather like in Boston?" }
            }
        };

        // Specify a function declaration and parameters for an API request
        var functionName = "get_current_weather";
        var getCurrentWeatherFunc = new FunctionDeclaration
        {
            Name = functionName,
            Description = "Get the current weather in a given location",
            Parameters = new OpenApiSchema
            {
                Type = Type.Object,
                Properties =
                {
                    ["location"] = new()
                    {
                        Type = Type.String,
                        Description = "Get the current weather in a given location"
                    },
                    ["unit"] = new()
                    {
                        Type = Type.String,
                        Description = "The unit of measurement for the temperature",
                        Enum = {"celsius", "fahrenheit"}
                    }
                },
                Required = { "location" }
            }
        };

        // Send the prompt and instruct the model to generate content using the tool that you just created
        var generateContentRequest = new GenerateContentRequest
        {
            Model = $"projects/{projectId}/locations/{location}/publishers/{publisher}/models/{model}",
            GenerationConfig = new GenerationConfig
            {
                Temperature = 0f
            },
            Contents =
            {
                userPromptContent
            },
            Tools =
            {
                new Tool
                {
                    FunctionDeclarations = { getCurrentWeatherFunc }
                }
            }
        };

        GenerateContentResponse response = await predictionServiceClient.GenerateContentAsync(generateContentRequest);

        var functionCall = response.Candidates[0].Content.Parts[0].FunctionCall;
        Console.WriteLine(functionCall);

        string apiResponse = "";

        // Check the function name that the model responded with, and make an API call to an external system
        if (functionCall.Name == functionName)
        {
            // Extract the arguments to use in your API call
            string locationCity = functionCall.Args.Fields["location"].StringValue;

            // Here you can use your preferred method to make an API request to
            // fetch the current weather

            // In this example, we'll use synthetic data to simulate a response
            // payload from an external API
            apiResponse = @"{ ""location"": ""Boston, MA"",
                    ""temperature"": 38, ""description"": ""Partly Cloudy""}";
        }

        // Return the API response to Gemini so it can generate a model response or request another function call
        generateContentRequest = new GenerateContentRequest
        {
            Model = $"projects/{projectId}/locations/{location}/publishers/{publisher}/models/{model}",
            Contents =
            {
                userPromptContent, // User prompt
                response.Candidates[0].Content, // Function call response,
                new Content
                {
                    Parts =
                    {
                        new Part
                        {
                            FunctionResponse = new()
                            {
                                Name = functionName,
                                Response = new()
                                {
                                    Fields =
                                    {
                                        { "content", new Value { StringValue = apiResponse } }
                                    }
                                }
                            }
                        }
                    }
                }
            },
            Tools =
            {
                new Tool
                {
                    FunctionDeclarations = { getCurrentWeatherFunc }
                }
            }
        };

        response = await predictionServiceClient.GenerateContentAsync(generateContentRequest);

        string responseText = response.Candidates[0].Content.Parts[0].Text;
        Console.WriteLine(responseText);

        return responseText;
    }
}

Node.js

이 예시에서는 함수 하나와 프롬프트 하나가 포함된 텍스트 시나리오를 보여줍니다.

Node.js

이 샘플을 사용해 보기 전에 Vertex AI 빠른 시작: 클라이언트 라이브러리 사용Node.js 설정 안내를 따르세요. 자세한 내용은 Vertex AI Node.js API 참고 문서를 참조하세요.

Vertex AI에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

const {
  VertexAI,
  FunctionDeclarationSchemaType,
} = require('@google-cloud/vertexai');

const functionDeclarations = [
  {
    function_declarations: [
      {
        name: 'get_current_weather',
        description: 'get weather in a given location',
        parameters: {
          type: FunctionDeclarationSchemaType.OBJECT,
          properties: {
            location: {type: FunctionDeclarationSchemaType.STRING},
            unit: {
              type: FunctionDeclarationSchemaType.STRING,
              enum: ['celsius', 'fahrenheit'],
            },
          },
          required: ['location'],
        },
      },
    ],
  },
];

const functionResponseParts = [
  {
    functionResponse: {
      name: 'get_current_weather',
      response: {name: 'get_current_weather', content: {weather: 'super nice'}},
    },
  },
];

/**
 * TODO(developer): Update these variables before running the sample.
 */
async function functionCallingStreamContent(
  projectId = 'PROJECT_ID',
  location = 'us-central1',
  model = 'gemini-1.5-flash-001'
) {
  // Initialize Vertex with your Cloud project and location
  const vertexAI = new VertexAI({project: projectId, location: location});

  // Instantiate the model
  const generativeModel = vertexAI.getGenerativeModel({
    model: model,
  });

  const request = {
    contents: [
      {role: 'user', parts: [{text: 'What is the weather in Boston?'}]},
      {
        role: 'ASSISTANT',
        parts: [
          {
            functionCall: {
              name: 'get_current_weather',
              args: {location: 'Boston'},
            },
          },
        ],
      },
      {role: 'USER', parts: functionResponseParts},
    ],
    tools: functionDeclarations,
  };
  const streamingResp = await generativeModel.generateContentStream(request);
  for await (const item of streamingResp.stream) {
    console.log(item.candidates[0].content.parts[0].text);
  }
}

REST

이 예시에서는 함수 3개와 프롬프트 1개가 있는 텍스트 시나리오를 보여줍니다.

이 예시에서는 생성형 AI 모델을 두 번 호출합니다.

첫 번째 모델 요청

요청은 text 매개변수에 프롬프트를 정의해야 합니다. 이 예시는 '마운틴뷰의 어느 영화관에서 바비 영화를 상영하나요?'라는 프롬프트를 정의합니다.

또한 요청은 함수 선언 집합(functionDeclarations)을 사용하여 도구(tools)를 정의해야 합니다. 이러한 함수 선언은 OpenAPI 스키마와 호환되는 형식으로 지정되어야 합니다. 이 예에서는 다음 함수를 정의합니다.

  • find_movies는 영화관에서 상영 중인 영화를 찾습니다.
  • find_theatres는 위치를 기반으로 영화관을 찾습니다.
  • get_showtimes는 특정 영화관에서 상영하는 영화의 시작 시간을 찾습니다.

모델 요청의 매개변수에 관한 자세한 내용은 Gemini API를 참고하세요.

my-project를 Google Cloud 프로젝트의 이름으로 바꿉니다.

첫 번째 모델 요청

PROJECT_ID=my-project
MODEL_ID=gemini-1.0-pro
API=streamGenerateContent
curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" -H "Content-Type: application/json"  https://us-central1-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/us-central1/publishers/google/models/${MODEL_ID}:${API} -d '{
"contents": {
  "role": "user",
  "parts": {
    "text": "Which theaters in Mountain View show the Barbie movie?"
  }
},
"tools": [
  {
    "function_declarations": [
      {
        "name": "find_movies",
        "description": "find movie titles currently playing in theaters based on any description, genre, title words, etc.",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
            },
            "description": {
              "type": "string",
              "description": "Any kind of description including category or genre, title words, attributes, etc."
            }
          },
          "required": [
            "description"
          ]
        }
      },
      {
        "name": "find_theaters",
        "description": "find theaters based on location and optionally movie title which are is currently playing in theaters",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
            },
            "movie": {
              "type": "string",
              "description": "Any movie title"
            }
          },
          "required": [
            "location"
          ]
        }
      },
      {
        "name": "get_showtimes",
        "description": "Find the start times for movies playing in a specific theater",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
            },
            "movie": {
              "type": "string",
              "description": "Any movie title"
            },
            "theater": {
              "type": "string",
              "description": "Name of the theater"
            },
            "date": {
              "type": "string",
              "description": "Date for requested showtime"
            }
          },
          "required": [
            "location",
            "movie",
            "theater",
            "date"
          ]
        }
      }
    ]
  }
]
}'
  

'마운틴뷰에서 영화 바비를 상영하는 극장은 어디인가요?'라는 프롬프트의 경우 모델은 BarbieMountain View, CA 매개변수를 사용하여 find_theatres 함수를 반환할 수 있습니다.

첫 번째 모델 요청에 대한 응답

[{
"candidates": [
  {
    "content": {
      "parts": [
        {
          "functionCall": {
            "name": "find_theaters",
            "args": {
              "movie": "Barbie",
              "location": "Mountain View, CA"
            }
          }
        }
      ]
    },
    "finishReason": "STOP",
    "safetyRatings": [
      {
        "category": "HARM_CATEGORY_HARASSMENT",
        "probability": "NEGLIGIBLE"
      },
      {
        "category": "HARM_CATEGORY_HATE_SPEECH",
        "probability": "NEGLIGIBLE"
      },
      {
        "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
        "probability": "NEGLIGIBLE"
      },
      {
        "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
        "probability": "NEGLIGIBLE"
      }
    ]
  }
],
"usageMetadata": {
  "promptTokenCount": 9,
  "totalTokenCount": 9
}
}]
  

두 번째 모델 요청

이 예시에서는 외부 API를 호출하는 대신 합성 데이터를 사용합니다. 두 개의 매개변수가 있는 2개의 결과가 있습니다(nameaddress).

  1. name: AMC Mountain View 16, address: 2000 W El Camino Real, Mountain View, CA 94040
  2. name: Regal Edwards 14, address: 245 Castro St, Mountain View, CA 94040

my-project를 Google Cloud 프로젝트의 이름으로 바꿉니다.

두 번째 모델 요청

PROJECT_ID=my-project
MODEL_ID=gemini-1.0-pro
API=streamGenerateContent
curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" -H "Content-Type: application/json"  https://us-central1-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/us-central1/publishers/google/models/${MODEL_ID}:${API} -d '{
"contents": [{
  "role": "user",
  "parts": [{
    "text": "Which theaters in Mountain View show the Barbie movie?"
  }]
}, {
  "role": "model",
  "parts": [{
    "functionCall": {
      "name": "find_theaters",
      "args": {
        "location": "Mountain View, CA",
        "movie": "Barbie"
      }
    }
  }]
}, {
  "parts": [{
    "functionResponse": {
      "name": "find_theaters",
      "response": {
        "name": "find_theaters",
        "content": {
          "movie": "Barbie",
          "theaters": [{
            "name": "AMC Mountain View 16",
            "address": "2000 W El Camino Real, Mountain View, CA 94040"
          }, {
            "name": "Regal Edwards 14",
            "address": "245 Castro St, Mountain View, CA 94040"
          }]
        }
      }
    }
  }]
}],
"tools": [{
  "functionDeclarations": [{
    "name": "find_movies",
    "description": "find movie titles currently playing in theaters based on any description, genre, title words, etc.",
    "parameters": {
      "type": "OBJECT",
      "properties": {
        "location": {
          "type": "STRING",
          "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
        },
        "description": {
          "type": "STRING",
          "description": "Any kind of description including category or genre, title words, attributes, etc."
        }
      },
      "required": ["description"]
    }
  }, {
    "name": "find_theaters",
    "description": "find theaters based on location and optionally movie title which are is currently playing in theaters",
    "parameters": {
      "type": "OBJECT",
      "properties": {
        "location": {
          "type": "STRING",
          "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
        },
        "movie": {
          "type": "STRING",
          "description": "Any movie title"
        }
      },
      "required": ["location"]
    }
  }, {
    "name": "get_showtimes",
    "description": "Find the start times for movies playing in a specific theater",
    "parameters": {
      "type": "OBJECT",
      "properties": {
        "location": {
          "type": "STRING",
          "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
        },
        "movie": {
          "type": "STRING",
          "description": "Any movie title"
        },
        "theater": {
          "type": "STRING",
          "description": "Name of the theater"
        },
        "date": {
          "type": "STRING",
          "description": "Date for requested showtime"
        }
      },
      "required": ["location", "movie", "theater", "date"]
    }
  }]
}]
}'
  

모델의 응답은 다음과 비슷할 수 있습니다.

두 번째 모델 요청에 대한 응답

{
"candidates": [
  {
    "content": {
      "parts": [
        {
          "text": " OK. Barbie is showing in two theaters in Mountain View, CA: AMC Mountain View 16 and Regal Edwards 14."
        }
      ]
    }
  }
],
"usageMetadata": {
  "promptTokenCount": 9,
  "candidatesTokenCount": 27,
  "totalTokenCount": 36
}
}
  

채팅 예시

함수 호출을 사용하여 채팅 세션을 지원할 수 있습니다. 채팅 세션은 사용자가 후속 질문을 할 가능성이 높은 자유 형식의 대화 시나리오에 유용합니다.

채팅 세션 컨텍스트에서 함수 호출을 사용하는 경우 세션에서 자동으로 컨텍스트를 저장하고 모든 모델 요청에 컨텍스트를 포함합니다. Vertex AI는 클라이언트 측에 상호작용 기록을 저장합니다.

Python

이 예시에서는 함수 2개와 순차적 프롬프트 2개가 있는 채팅 시나리오를 보여줍니다. 여기서는 GenerativeModel 클래스와 해당 메서드를 사용합니다. 멀티모달 모델과 함께 Vertex AI SDK for Python을 사용하는 방법에 대한 자세한 내용은 Vertex AI SDK for Python의 멀티모달 클래스 소개를 참조하세요.

Python을 설치하거나 업데이트하는 방법은 Vertex AI SDK for Python 설치를 참조하세요. 자세한 내용은 Python API 참고 문서를 참조하세요.

import vertexai

from vertexai.generative_models import (
    FunctionDeclaration,
    GenerationConfig,
    GenerativeModel,
    Part,
    Tool,
)

# TODO(developer): Update & uncomment below line
# PROJECT_ID = "your-project-id"

# Initialize Vertex AI
vertexai.init(project=PROJECT_ID, location="us-central1")

# Specify a function declaration and parameters for an API request
get_product_sku = "get_product_sku"
get_product_sku_func = FunctionDeclaration(
    name=get_product_sku,
    description="Get the SKU for a product",
    # Function parameters are specified in OpenAPI JSON schema format
    parameters={
        "type": "object",
        "properties": {
            "product_name": {"type": "string", "description": "Product name"}
        },
    },
)

# Specify another function declaration and parameters for an API request
get_store_location_func = FunctionDeclaration(
    name="get_store_location",
    description="Get the location of the closest store",
    # Function parameters are specified in JSON schema format
    parameters={
        "type": "object",
        "properties": {"location": {"type": "string", "description": "Location"}},
    },
)

# Define a tool that includes the above functions
retail_tool = Tool(
    function_declarations=[
        get_product_sku_func,
        get_store_location_func,
    ],
)

# Initialize Gemini model
model = GenerativeModel(
    model_name="gemini-1.5-flash-001",
    generation_config=GenerationConfig(temperature=0),
    tools=[retail_tool],
)

# Start a chat session
chat = model.start_chat()

# Send a prompt for the first conversation turn that should invoke the get_product_sku function
response = chat.send_message("Do you have the Pixel 8 Pro in stock?")

function_call = response.candidates[0].function_calls[0]
print(function_call)

# Check the function name that the model responded with, and make an API call to an external system
if function_call.name == get_product_sku:
    # Extract the arguments to use in your API call
    product_name = function_call.args["product_name"]  # noqa: F841

    # Here you can use your preferred method to make an API request to retrieve the product SKU, as in:
    # api_response = requests.post(product_api_url, data={"product_name": product_name})

    # In this example, we'll use synthetic data to simulate a response payload from an external API
    api_response = {"sku": "GA04834-US", "in_stock": "Yes"}

# Return the API response to Gemini, so it can generate a model response or request another function call
response = chat.send_message(
    Part.from_function_response(
        name=get_product_sku,
        response={
            "content": api_response,
        },
    ),
)
# Extract the text from the model response
print(response.text)

# Send a prompt for the second conversation turn that should invoke the get_store_location function
response = chat.send_message(
    "Is there a store in Mountain View, CA that I can visit to try it out?"
)

function_call = response.candidates[0].function_calls[0]
print(function_call)

# Check the function name that the model responded with, and make an API call to an external system
if function_call.name == "get_store_location":
    # Extract the arguments to use in your API call
    location = function_call.args["location"]  # noqa: F841

    # Here you can use your preferred method to make an API request to retrieve store location closest to the user, as in:
    # api_response = requests.post(store_api_url, data={"location": location})

    # In this example, we'll use synthetic data to simulate a response payload from an external API
    api_response = {"store": "2000 N Shoreline Blvd, Mountain View, CA 94043, US"}

# Return the API response to Gemini, so it can generate a model response or request another function call
response = chat.send_message(
    Part.from_function_response(
        name="get_store_location",
        response={
            "content": api_response,
        },
    ),
)

# Extract the text from the model response
print(response.text)
# Example response:
# name: "get_product_sku"
# args {
#   fields { key: "product_name" value {string_value: "Pixel 8 Pro" }
#   }
# }
# Yes, we have the Pixel 8 Pro in stock.
# name: "get_store_location"
# args {
#   fields { key: "location" value { string_value: "Mountain View, CA" }
#   }
# }
# Yes, there is a store located at 2000 N Shoreline Blvd, Mountain View, CA 94043, US.

Java

이 샘플을 사용해 보기 전에 Vertex AI 빠른 시작: 클라이언트 라이브러리 사용Java 설정 안내를 따르세요. 자세한 내용은 Vertex AI Java API 참고 문서를 참조하세요.

Vertex AI에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

import com.google.cloud.vertexai.VertexAI;
import com.google.cloud.vertexai.api.Content;
import com.google.cloud.vertexai.api.FunctionDeclaration;
import com.google.cloud.vertexai.api.GenerateContentResponse;
import com.google.cloud.vertexai.api.Schema;
import com.google.cloud.vertexai.api.Tool;
import com.google.cloud.vertexai.api.Type;
import com.google.cloud.vertexai.generativeai.ChatSession;
import com.google.cloud.vertexai.generativeai.ContentMaker;
import com.google.cloud.vertexai.generativeai.GenerativeModel;
import com.google.cloud.vertexai.generativeai.PartMaker;
import com.google.cloud.vertexai.generativeai.ResponseHandler;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;

public class FunctionCalling {
  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "your-google-cloud-project-id";
    String location = "us-central1";
    String modelName = "gemini-1.5-flash-001";

    String promptText = "What's the weather like in Paris?";

    whatsTheWeatherLike(projectId, location, modelName, promptText);
  }

  // A request involving the interaction with an external tool
  public static String whatsTheWeatherLike(String projectId, String location,
                                           String modelName, String promptText)
      throws IOException {
    // Initialize client that will be used to send requests.
    // This client only needs to be created once, and can be reused for multiple requests.
    try (VertexAI vertexAI = new VertexAI(projectId, location)) {

      FunctionDeclaration functionDeclaration = FunctionDeclaration.newBuilder()
          .setName("getCurrentWeather")
          .setDescription("Get the current weather in a given location")
          .setParameters(
              Schema.newBuilder()
                  .setType(Type.OBJECT)
                  .putProperties("location", Schema.newBuilder()
                      .setType(Type.STRING)
                      .setDescription("location")
                      .build()
                  )
                  .addRequired("location")
                  .build()
          )
          .build();

      System.out.println("Function declaration:");
      System.out.println(functionDeclaration);

      // Add the function to a "tool"
      Tool tool = Tool.newBuilder()
          .addFunctionDeclarations(functionDeclaration)
          .build();

      // Start a chat session from a model, with the use of the declared function.
      GenerativeModel model = new GenerativeModel(modelName, vertexAI)
          .withTools(Arrays.asList(tool));
      ChatSession chat = model.startChat();

      System.out.println(String.format("Ask the question: %s", promptText));
      GenerateContentResponse response = chat.sendMessage(promptText);

      // The model will most likely return a function call to the declared
      // function `getCurrentWeather` with "Paris" as the value for the
      // argument `location`.
      System.out.println("\nPrint response: ");
      System.out.println(ResponseHandler.getContent(response));

      // Provide an answer to the model so that it knows what the result
      // of a "function call" is.
      Content content =
          ContentMaker.fromMultiModalData(
              PartMaker.fromFunctionResponse(
                  "getCurrentWeather",
                  Collections.singletonMap("currentWeather", "sunny")));
      System.out.println("Provide the function response: ");
      System.out.println(content);
      response = chat.sendMessage(content);

      // See what the model replies now
      System.out.println("Print response: ");
      String finalAnswer = ResponseHandler.getText(response);
      System.out.println(finalAnswer);

      return finalAnswer;
    }
  }
}

Go

이 샘플을 사용해 보기 전에 Vertex AI 빠른 시작: 클라이언트 라이브러리 사용Go 설정 안내를 따르세요. 자세한 내용은 Vertex AI Go API 참고 문서를 참조하세요.

Vertex AI에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"

	"cloud.google.com/go/vertexai/genai"
)

// functionCallsChat opens a chat session and sends 4 messages to the model:
// - convert a first text question into a structured function call request
// - convert the first structured function call response into natural language
// - convert a second text question into a structured function call request
// - convert the second structured function call response into natural language
func functionCallsChat(w io.Writer, projectID, location, modelName string) error {
	// location := "us-central1"
	// modelName := "gemini-1.5-flash-001"
	ctx := context.Background()
	client, err := genai.NewClient(ctx, projectID, location)
	if err != nil {
		return fmt.Errorf("unable to create client: %w", err)
	}
	defer client.Close()

	model := client.GenerativeModel(modelName)

	// Build an OpenAPI schema, in memory
	paramsProduct := &genai.Schema{
		Type: genai.TypeObject,
		Properties: map[string]*genai.Schema{
			"productName": {
				Type:        genai.TypeString,
				Description: "Product name",
			},
		},
	}
	fundeclProductInfo := &genai.FunctionDeclaration{
		Name:        "getProductSku",
		Description: "Get the SKU for a product",
		Parameters:  paramsProduct,
	}
	paramsStore := &genai.Schema{
		Type: genai.TypeObject,
		Properties: map[string]*genai.Schema{
			"location": {
				Type:        genai.TypeString,
				Description: "Location",
			},
		},
	}
	fundeclStoreLocation := &genai.FunctionDeclaration{
		Name:        "getStoreLocation",
		Description: "Get the location of the closest store",
		Parameters:  paramsStore,
	}
	model.Tools = []*genai.Tool{
		{FunctionDeclarations: []*genai.FunctionDeclaration{
			fundeclProductInfo,
			fundeclStoreLocation,
		}},
	}
	model.SetTemperature(0.0)

	chat := model.StartChat()

	// Send a prompt for the first conversation turn that should invoke the getProductSku function
	prompt := "Do you have the Pixel 8 Pro in stock?"
	fmt.Fprintf(w, "Question: %s\n", prompt)
	resp, err := chat.SendMessage(ctx, genai.Text(prompt))
	if err != nil {
		return err
	}
	if len(resp.Candidates) == 0 ||
		len(resp.Candidates[0].Content.Parts) == 0 {
		return errors.New("empty response from model")
	}

	// The model has returned a function call to the declared function `getProductSku`
	// with a value for the argument `productName`.
	jsondata, err := json.MarshalIndent(resp.Candidates[0].Content.Parts[0], "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.MarshalIndent: %w", err)
	}
	fmt.Fprintf(w, "function call generated by the model:\n\t%s\n", string(jsondata))

	// Create a function call response, to simulate the result of a call to a
	// real service
	funresp := &genai.FunctionResponse{
		Name: "getProductSku",
		Response: map[string]any{
			"sku":      "GA04834-US",
			"in_stock": "yes",
		},
	}
	jsondata, err = json.MarshalIndent(funresp, "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.MarshalIndent: %w", err)
	}
	fmt.Fprintf(w, "function call response sent to the model:\n\t%s\n\n", string(jsondata))

	// And provide the function call response to the model
	resp, err = chat.SendMessage(ctx, funresp)
	if err != nil {
		return err
	}
	if len(resp.Candidates) == 0 ||
		len(resp.Candidates[0].Content.Parts) == 0 {
		return errors.New("empty response from model")
	}

	// The model has taken the function call response as input, and has
	// reformulated the response to the user.
	jsondata, err = json.MarshalIndent(resp.Candidates[0].Content.Parts[0], "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.MarshalIndent: %w", err)
	}
	fmt.Fprintf(w, "Answer generated by the model:\n\t%s\n\n", string(jsondata))

	// Send a prompt for the second conversation turn that should invoke the getStoreLocation function
	prompt2 := "Is there a store in Mountain View, CA that I can visit to try it out?"
	fmt.Fprintf(w, "Question: %s\n", prompt)

	resp, err = chat.SendMessage(ctx, genai.Text(prompt2))
	if err != nil {
		return err
	}
	if len(resp.Candidates) == 0 ||
		len(resp.Candidates[0].Content.Parts) == 0 {
		return errors.New("empty response from model")
	}

	// The model has returned a function call to the declared function `getStoreLocation`
	// with a value for the argument `store`.
	jsondata, err = json.MarshalIndent(resp.Candidates[0].Content.Parts[0], "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.MarshalIndent: %w", err)
	}
	fmt.Fprintf(w, "function call generated by the model:\n\t%s\n", string(jsondata))

	// Create a function call response, to simulate the result of a call to a
	// real service
	funresp = &genai.FunctionResponse{
		Name: "getStoreLocation",
		Response: map[string]any{
			"store": "2000 N Shoreline Blvd, Mountain View, CA 94043, US",
		},
	}
	jsondata, err = json.MarshalIndent(funresp, "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.MarshalIndent: %w", err)
	}
	fmt.Fprintf(w, "function call response sent to the model:\n\t%s\n\n", string(jsondata))

	// And provide the function call response to the model
	resp, err = chat.SendMessage(ctx, funresp)
	if err != nil {
		return err
	}
	if len(resp.Candidates) == 0 ||
		len(resp.Candidates[0].Content.Parts) == 0 {
		return errors.New("empty response from model")
	}

	// The model has taken the function call response as input, and has
	// reformulated the response to the user.
	jsondata, err = json.MarshalIndent(resp.Candidates[0].Content.Parts[0], "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.MarshalIndent: %w", err)
	}
	fmt.Fprintf(w, "Answer generated by the model:\n\t%s\n\n", string(jsondata))
	return nil
}

Node.js

이 샘플을 사용해 보기 전에 Vertex AI 빠른 시작: 클라이언트 라이브러리 사용Node.js 설정 안내를 따르세요. 자세한 내용은 Vertex AI Node.js API 참고 문서를 참조하세요.

Vertex AI에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

const {
  VertexAI,
  FunctionDeclarationSchemaType,
} = require('@google-cloud/vertexai');

const functionDeclarations = [
  {
    function_declarations: [
      {
        name: 'get_current_weather',
        description: 'get weather in a given location',
        parameters: {
          type: FunctionDeclarationSchemaType.OBJECT,
          properties: {
            location: {type: FunctionDeclarationSchemaType.STRING},
            unit: {
              type: FunctionDeclarationSchemaType.STRING,
              enum: ['celsius', 'fahrenheit'],
            },
          },
          required: ['location'],
        },
      },
    ],
  },
];

const functionResponseParts = [
  {
    functionResponse: {
      name: 'get_current_weather',
      response: {name: 'get_current_weather', content: {weather: 'super nice'}},
    },
  },
];

/**
 * TODO(developer): Update these variables before running the sample.
 */
async function functionCallingStreamChat(
  projectId = 'PROJECT_ID',
  location = 'us-central1',
  model = 'gemini-1.5-flash-001'
) {
  // Initialize Vertex with your Cloud project and location
  const vertexAI = new VertexAI({project: projectId, location: location});

  // Instantiate the model
  const generativeModel = vertexAI.getGenerativeModel({
    model: model,
  });

  // Create a chat session and pass your function declarations
  const chat = generativeModel.startChat({
    tools: functionDeclarations,
  });

  const chatInput1 = 'What is the weather in Boston?';

  // This should include a functionCall response from the model
  const result1 = await chat.sendMessageStream(chatInput1);
  for await (const item of result1.stream) {
    console.log(item.candidates[0]);
  }
  await result1.response;

  // Send a follow up message with a FunctionResponse
  const result2 = await chat.sendMessageStream(functionResponseParts);
  for await (const item of result2.stream) {
    console.log(item.candidates[0]);
  }

  // This should include a text response from the model using the response content
  // provided above
  const response2 = await result2.response;
  console.log(response2.candidates[0].content.parts[0].text);
}

병렬 함수 호출 예시

'뉴델리와 샌프란시스코의 날씨 세부정보를 가져올까요?'와 같은 프롬프트의 경우 모델은 여러 개의 병렬 함수 호출을 제안할 수 있습니다. 병렬 함수 호출을 지원하는 모델 목록은 지원되는 모델을 참고하세요.

REST

이 예에서는 get_current_weather 함수가 하나 있는 시나리오를 보여줍니다. 사용자 프롬프트는 '뉴델리와 샌프란시스코의 날씨 세부정보를 확인해 줘'입니다. 모델은 매개변수가 New Delhiget_current_weather 함수 호출과 매개변수가 San Franciscoget_current_weather 함수 호출을 동시에 제안합니다.

모델 요청의 매개변수에 관한 자세한 내용은 Gemini API를 참고하세요.

{
"candidates": [
  {
    "content": {
      "role": "model",
      "parts": [
        {
          "functionCall": {
            "name": "get_current_weather",
            "args": {
              "location": "New Delhi"
            }
          }
        },
        {
          "functionCall": {
            "name": "get_current_weather",
            "args": {
              "location": "San Francisco"
            }
          }
        }
      ]
    },
    ...
  }
],
...
}

다음 명령어는 모델에 함수 출력을 제공하는 방법을 보여줍니다. my-project를 Google Cloud 프로젝트의 이름으로 바꿉니다.

모델 요청

PROJECT_ID=my-project
MODEL_ID=gemini-1.5-pro-002
VERSION="v1"
LOCATION="us-central1"
ENDPOINT=${LOCATION}-aiplatform.googleapis.com
API="generateContent"
curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" -H "Content-Type: application/json"  https://${ENDPOINT}/${VERSION}/projects/${PROJECT_ID}/locations/${LOCATION}/publishers/google/models/${MODEL_ID}:${API} -d '{
"contents": [
    {
        "role": "user",
        "parts": {
            "text": "What is difference in temperature in New Delhi and San Francisco?"
        }
    },
    {
        "role": "model",
        "parts": [
            {
                "functionCall": {
                    "name": "get_current_weather",
                    "args": {
                        "location": "New Delhi"
                    }
                }
            },
            {
                "functionCall": {
                    "name": "get_current_weather",
                    "args": {
                        "location": "San Francisco"
                    }
                }
            }
        ]
    },
    {
        "role": "user",
        "parts": [
            {
                "functionResponse": {
                    "name": "get_current_weather",
                    "response": {
                        "temperature": 30.5,
                        "unit": "C"
                    }
                }
            },
            {
                "functionResponse": {
                    "name": "get_current_weather",
                    "response": {
                        "temperature": 20,
                        "unit": "C"
                    }
                }
            }
        ]
    }
],
"tools": [
    {
        "function_declarations": [
            {
                "name": "get_current_weather",
                "description": "Get the current weather in a specific location",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
                        }
                    },
                    "required": [
                        "location"
                    ]
                }
            }
        ]
    }
]
}'
  

모델에서 생성한 자연어 응답은 다음과 비슷합니다.

모델 응답

[
{
    "candidates": [
        {
            "content": {
                "parts": [
                    {
                        "text": "The temperature in New Delhi is 30.5C and the temperature in San Francisco is 20C. The difference is 10.5C. \n"
                    }
                ]
            },
            "finishReason": "STOP",
            ...
        }
    ]
    ...
}
]
  

Python

import vertexai

from vertexai.generative_models import (
    FunctionDeclaration,
    GenerativeModel,
    Part,
    Tool,
)

# TODO(developer): Update & uncomment below line
# PROJECT_ID = "your-project-id"

# Initialize Vertex AI
vertexai.init(project=PROJECT_ID, location="us-central1")

# Specify a function declaration and parameters for an API request
function_name = "get_current_weather"
get_current_weather_func = FunctionDeclaration(
    name=function_name,
    description="Get the current weather in a given location",
    parameters={
        "type": "object",
        "properties": {
            "location": {
                "type": "string",
                "description": "The location for which to get the weather. \
                  It can be a city name, a city name and state, or a zip code. \
                  Examples: 'San Francisco', 'San Francisco, CA', '95616', etc.",
            },
        },
    },
)

# In this example, we'll use synthetic data to simulate a response payload from an external API
def mock_weather_api_service(location: str) -> str:
    temperature = 25 if location == "San Francisco" else 35
    return f"""{{ "location": "{location}", "temperature": {temperature}, "unit": "C" }}"""

# Define a tool that includes the above function
tools = Tool(
    function_declarations=[get_current_weather_func],
)

# Initialize Gemini model
model = GenerativeModel(
    model_name="gemini-1.5-pro-002",
    tools=[tools],
)

# Start a chat session
chat_session = model.start_chat()
response = chat_session.send_message(
    "Get weather details in New Delhi and San Francisco?"
)

function_calls = response.candidates[0].function_calls
print("Suggested finction calls:\n", function_calls)

if function_calls:
    api_responses = []
    for func in function_calls:
        if func.name == function_name:
            api_responses.append(
                {
                    "content": mock_weather_api_service(
                        location=func.args["location"]
                    )
                }
            )

    # Return the API response to Gemini
    response = chat_session.send_message(
        [
            Part.from_function_response(
                name="get_current_weather",
                response=api_responses[0],
            ),
            Part.from_function_response(
                name="get_current_weather",
                response=api_responses[1],
            ),
        ],
    )

    print(response.text)
    # Example response:
    # The current weather in New Delhi is 35°C. The current weather in San Francisco is 25°C.

함수 호출 권장사항

함수 이름

함수 이름은 문자 또는 밑줄로 시작해야 하며 a~z, A~Z, 0~9, 밑줄, 점 또는 대시 문자만 포함할 수 있으며 최대 길이는 64자(영문 기준)입니다.

함수 설명

함수 설명을 명확하고 상세하게 작성합니다. 예를 들어 book_flight_ticket 함수의 경우 다음과 같습니다.

  • book flight tickets after confirming users' specific requirements, such as time, departure, destination, party size and preferred airline은 좋은 함수 설명의 예시입니다.
  • book flight ticket은 잘못된 함수 설명의 예시입니다.

함수 매개변수

함수 매개변수 및 중첩된 속성 이름은 문자 또는 밑줄로 시작해야 하며 a~z, A~Z, 0~9 또는 밑줄 문자만 포함할 수 있으며 최대 길이는 64자(영문 기준)입니다. 함수 매개변수 이름 및 중첩된 속성에 마침표 (.), 대시 (-) 또는 공백 문자를 사용하지 마세요. 대신 밑줄(_) 문자나 다른 문자를 사용합니다.

설명

원하는 형식 또는 값과 같은 세부정보를 포함하여 명확하고 자세한 매개변수 설명을 작성합니다. 예를 들어 book_flight_ticket 함수의 경우 다음과 같습니다.

  • Use the 3 char airport code to represent the airport. For example, SJC or SFO. Don't use the city name.departure 매개변수 설명의 올바른 예시입니다.
  • the departure airportdeparture 매개변수 설명의 잘못된 예시입니다.

유형

가능하면 강력하게 유형화된 매개변수를 사용하여 모델 할루시네이션을 줄입니다. 예를 들어 매개변수 값이 유한한 집합에서 파생된 경우 값 집합을 설명에 포함하는 대신 enum 필드를 추가합니다. 매개변수 값이 항상 정수이면 유형을 number 대신 integer로 설정합니다.

시스템 안내

날짜, 시간 또는 위치 매개변수가 있는 함수를 사용할 때는 시스템 안내에 현재 날짜, 시간 또는 관련 위치 정보 (예: 도시 및 국가)를 포함합니다. 이렇게 하면 사용자 프롬프트에 세부정보가 없더라도 모델에 요청을 정확하게 처리하는 데 필요한 컨텍스트가 제공됩니다.

사용자 프롬프트

최상의 결과를 얻으려면 사용자 프롬프트 앞에 다음 세부정보를 추가합니다.

  • 모델의 추가 컨텍스트(예: You are a flight API assistant to help with searching flights based on user preferences.)
  • 함수 사용 방법과 시기에 대한 세부정보나 안내(예: Don't make assumptions on the departure or destination airports. Always use a future date for the departure or destination time.)
  • 사용자 쿼리가 모호한 경우 명확하게 질문하기 위한 안내(예: Ask clarifying questions if not enough information is available.)

생성 구성

강도 매개변수에는 0 또는 다른 낮은 값을 사용합니다. 이렇게 하면 모델이 보다 신뢰할 수 있는 결과를 생성하도록 할 수 있고 할루시네이션을 줄일 수 있습니다.

API 호출

모델이 주문을 전송하거나, 데이터베이스를 업데이트하거나, 그 밖의 이유로 중대한 결과가 발생할 수 있는 함수의 호출을 제안하는 경우에는 이를 실행하기 전에 사용자와 함께 함수 호출 유효성을 검사합니다.

가격 책정

함수 호출 가격은 텍스트 입력과 출력에 포함된 문자 수를 기준으로 책정됩니다. 자세한 내용은 Vertex AI 가격 책정을 참조하세요.

여기서 텍스트 입력(프롬프트)은 현재 대화 차례의 사용자 프롬프트, 현재 대화 차례의 함수 선언, 대화 기록을 나타냅니다. 대화 기록에는 쿼리, 함수 호출, 이전 대화 차례의 함수 응답이 포함됩니다. Vertex AI는 대화 기록을 32,000자(영문 기준)로 자릅니다.

텍스트 출력(응답)은 현재 대화 차례의 함수 호출 및 텍스트 응답을 나타냅니다.

다음 단계