함수 호출

개요

함수 호출을 사용하여 커스텀 함수를 정의하고 이를 생성형 AI 모델에 제공할 수 있습니다. 쿼리를 처리하는 동안 모델은 특정 데이터 처리 태스크를 이러한 함수에 위임할 수 있습니다. 함수를 호출하지 않습니다. 대신 선택한 함수의 이름과 모델에서 호출할 함수를 제안하는 인수가 포함된 정형 데이터 출력을 제공합니다. 이 출력을 사용하여 외부 API를 호출할 수 있습니다. 그런 다음 API 출력을 다시 모델에 제공하여 쿼리에 대한 응답을 완료할 수 있습니다. 이러한 방식으로 사용될 경우 함수 호출을 통해 LLM이 실시간 정보에 액세스하고 SQL 데이터베이스, 고객 관계 관리 시스템, 문서 저장소와 같은 다양한 서비스와 상호작용할 수 있습니다.

다음 다이어그램에서는 함수 호출 작동 방식을 보여줍니다. 함수 호출 상호작용 

함수 호출 사용 사례는 함수 호출 사용 사례를 참조하세요. 함수 호출 애플리케이션을 만드는 방법은 함수 호출 애플리케이션 만들기를 참조하세요. 권장사항은 권장사항을 참조하세요.

함수 호출은 gemini-1.0-pro-001 모델의 기능이며 gemini-1.0-pro-002 모델의 미리보기 기능입니다.

함수 호출은 Gemini 1.5 Pro(미리보기) 모델의 기능입니다.

함수 호출 사용 사례

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

함수 호출 애플리케이션 만들기

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

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

사용 가능한 함수 집합 정의 및 설명

애플리케이션은 모델에서 쿼리를 처리하는 데 사용할 수 있는 함수 집합을 선언해야 합니다. 각 함수 선언에는 함수 이름함수 매개변수가 포함되어야 합니다. 또한 각 함수 선언에 함수 설명을 포함하는 것이 좋습니다.

함수 이름

애플리케이션과 모델은 함수 이름을 사용하여 함수를 식별합니다.

함수 이름과 관련된 권장사항은 권장사항 - 함수 이름을 참조하세요.

함수 매개변수

함수 매개변수는 OpenAPI 스키마와 호환되는 형식으로 제공되어야 합니다.

Vertex AI는 OpenAPI 스키마를 제한적으로 지원합니다. type, nullable, required, format, description, properties, items, enum 속성이 지원됩니다. default, optional, maximum, oneOf 속성은 지원되지 않습니다.

curl을 사용하는 경우 JSON을 사용하여 스키마를 지정합니다. Python용 Vertex AI SDK를 사용하는 경우 Python 사전을 사용하여 스키마를 지정합니다.

함수 매개변수와 관련된 권장사항은 권장사항 - 함수 매개변수를 참조하세요.

함수 설명

모델은 함수 설명을 사용하여 함수 목적을 이해하고 이러한 함수가 사용자 쿼리를 처리하는 데 유용한지 여부를 확인합니다.

함수 설명과 관련된 권장사항은 권장사항 - 함수 설명을 참조하세요.

함수 선언 예시

다음은 Python의 간단한 함수 선언 예시입니다.

get_current_weather_func = FunctionDeclaration(
    name="get_current_weather",
    description="Get the current weather in a given location",
    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"],
   },
)

모델에 쿼리 및 함수 선언 제출

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

사용자 프롬프트

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

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

생성 구성

모델은 서로 다른 매개변수 값에 대해 서로 다른 결과를 생성할 수 있습니다. 강도 매개변수는 이 생성의 무작위성 수준을 제어합니다. 강도가 낮을수록 결정론적 매개변수 값이 필요한 함수에 적합하고, 강도가 높을수록 보다 다양하거나 창의적인 매개변수 값을 허용하는 매개변수를 사용하는 함수에 적합합니다. 강도가 0이면 결정론적 응답 즉, 확률이 가장 높은 응답이 항상 선택됩니다. 자세한 내용은 Gemini API를 참조하세요.

이 매개변수를 설정하려면 프롬프트 및 함수 선언과 함께 생성 구성(generation_config)을 제출합니다.

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

도구 구성

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

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

모드 설명
자동 기본 모델 동작입니다. 모델이 함수 호출과 자연어 응답 중 무엇을 예측할지 결정합니다.
전체 모델이 함수 호출만 예측합니다. 모델이 일부 함수만 예측하도록 제한하려면 allowed_function_names에 허용되는 함수 이름을 정의합니다.
없음 모델이 함수 호출을 예측하지 않습니다. 이 동작은 연결된 함수 선언이 없는 모델 요청과 동일합니다.

도구 구성의 ANY 모드는 미리보기 기능입니다. Gemini 1.5 Pro 모델에서만 지원됩니다.

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

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

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

# Initialize Vertex AI
from vertexai.preview.generative_models import ToolConfig

vertexai.init(project=project_id, location=location)

# Initialize Gemini model
model = GenerativeModel("Gemini 1.5 Pro")

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

# 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(prompt),
    ],
)

# 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={"temperature": 0},
    tools=[weather_tool],
    tool_config=ToolConfig(
        function_calling_config=ToolConfig.FunctionCallingConfig(
            # ANY mode forces the model to predict a function call
            mode=ToolConfig.FunctionCallingConfig.Mode.ANY,
            # Allowed functions to call when the mode is ANY. If empty, any one of
            # the provided functions are called.
            allowed_function_names=["get_current_weather"],
    ))
)
response_function_call_content = response.candidates[0].content

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

다음은 모델 응답의 예시입니다. 모델은 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"
              }
            }
          }
        }
      }
    }
    ...
}

외부 API 호출

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

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

# Check the function name that the model responded with, and make an API call to an external system
if (
    response.candidates[0].content.parts[0].function_call.name
    == "get_current_weather"
):
    # Extract the arguments to use in your API call
    location = (
        response.candidates[0].content.parts[0].function_call.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 호출을 참조하세요.

모델에 함수 출력 제공

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

response = model.generate_content(
    [
        user_prompt_content,  # User prompt
        response_function_call_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.candidates[0].content.parts[0].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.는 쿼리 응답의 예시입니다.

모델에서 쿼리에 응답하는 데 다른 함수 출력이 필요하다고 판단하면 애플리케이션이 모델에서 수신하는 응답에는 다른 함수 이름과 다른 매개변수 값 집합이 포함됩니다.

권장사항

함수 이름

함수 이름에 마침표(.), 대시(-) 또는 공백 문자를 사용하지 마세요. 대신 밑줄(_) 문자나 다른 문자를 사용합니다.

함수 매개변수

원하는 형식 또는 값과 같은 세부정보를 포함하여 명확하고 자세한 매개변수 설명을 작성합니다. 예를 들어 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로 설정합니다.

함수 설명

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

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

사용자 프롬프트

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

  • 모델의 추가 컨텍스트(예: 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자(영문 기준)로 자릅니다.

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

함수 호출 샘플

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

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

함수 호출을 사용하여 단일 텍스트 응답을 생성하는 방법은 텍스트 예시를 참조하세요. 함수 호출을 사용하여 채팅 세션을 지원하는 방법은 채팅 예시를 참조하세요.

텍스트 예시

Python

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

Python

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

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

def generate_function_call(prompt: str, project_id: str, location: str) -> tuple:
    # Initialize Vertex AI
    vertexai.init(project=project_id, location=location)

    # Initialize Gemini model
    model = GenerativeModel("gemini-1.0-pro-001")

    # Specify a function declaration and parameters for an API request
    get_current_weather_func = FunctionDeclaration(
        name="get_current_weather",
        description="Get the current weather in a given location",
        # Function parameters are specified in OpenAPI 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],
    )

    # 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(prompt),
        ],
    )

    # 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],
    )
    response_function_call_content = response.candidates[0].content

    # Check the function name that the model responded with, and make an API call to an external system
    if (
        response.candidates[0].content.parts[0].function_call.name
        == "get_current_weather"
    ):
        # Extract the arguments to use in your API call
        location = (
            response.candidates[0].content.parts[0].function_call.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" } }"""

    # 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_function_call_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.candidates[0].content.parts[0].text

    return summary, response

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 functionCallingStreamChat(
  projectId = 'PROJECT_ID',
  location = 'us-central1',
  model = 'gemini-1.0-pro'
) {
  // Initialize Vertex with your Cloud project and location
  const vertexAI = new VertexAI({project: projectId, location: location});

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

  const request = {
    contents: [
      {role: 'user', parts: [{text: 'What is the weather in Boston?'}]},
      {
        role: 'model',
        parts: [
          {
            functionCall: {
              name: 'get_current_weather',
              args: {location: 'Boston'},
            },
          },
        ],
      },
      {role: 'function', 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-autopush-aiplatform.sandbox.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
}
}
  

채팅 예시

Python

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

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

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

def generate_function_call_chat(project_id: str, location: str) -> tuple:
    prompts = []
    summaries = []

    # Initialize Vertex AI
    vertexai.init(project=project_id, location=location)

    # Specify a function declaration and parameters for an API request
    get_product_info_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 OpenAPI 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_info_func,
            get_store_location_func,
        ],
    )

    # Initialize Gemini model
    model = GenerativeModel(
        "gemini-1.0-pro-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
    prompt = "Do you have the Pixel 8 Pro in stock?"
    response = chat.send_message(prompt)
    prompts.append(prompt)

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

        # 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 summary response
    summary = response.candidates[0].content.parts[0].text
    summaries.append(summary)

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

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

        # 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 summary response
    summary = response.candidates[0].content.parts[0].text
    summaries.append(summary)

    return prompts, summaries

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.0-pro'
) {
  // Initialize Vertex with your Cloud project and location
  const vertexAI = new VertexAI({project: projectId, location: location});

  // Instantiate the model
  const generativeModel = vertexAI.preview.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);
}

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.0-pro";

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

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

  public static String whatsTheWeatherLike(String projectId, String location,
                                           String modelName, String promptText)
      throws IOException {

    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 =
          GenerativeModel.newBuilder()
              .setModelName(modelName)
              .setVertexAi(vertexAI)
              .setTools(Arrays.asList(tool))
              .build();
      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"
)

// functionCalls opens a chat session and sends 2 messages to the model:
// - first, to convert a text into a structured function call request
// - second, to convert a structured function call response into natural language
func functionCalls(w io.Writer, prompt, projectID, location, modelName string) error {
	// prompt := "What's the weather like in Paris?"
	// location := "us-central1"
	// modelName := "gemini-1.0-pro"
	ctx := context.Background()
	client, err := genai.NewClient(ctx, projectID, location)
	if err != nil {
		return fmt.Errorf("unable to create client: %v", err)
	}
	defer client.Close()

	model := client.GenerativeModel(modelName)

	// Build an OpenAPI schema, in memory
	params := &genai.Schema{
		Type: genai.TypeObject,
		Properties: map[string]*genai.Schema{
			"location": {
				Type:        genai.TypeString,
				Description: "location",
			},
		},
	}
	fundecl := &genai.FunctionDeclaration{
		Name:        "getCurrentWeather",
		Description: "Get the current weather in a given location",
		Parameters:  params,
	}
	model.Tools = []*genai.Tool{
		{FunctionDeclarations: []*genai.FunctionDeclaration{fundecl}},
	}

	chat := model.StartChat()

	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 `getCurrentWeather`
	// with a value for the argument `location`.
	jsondata, err := json.MarshalIndent(resp.Candidates[0].Content.Parts[0], "", "  ")
	if err != nil {
		return fmt.Errorf("json.Marshal: %w", err)
	}
	fmt.Fprintf(w, "function call generated by the model:\n%s\n\n", string(jsondata))

	// Create a function call response, to simulate the result of a call to a
	// real service
	funresp := &genai.FunctionResponse{
		Name: "getCurrentWeather",
		Response: map[string]any{
			"currentWeather": "sunny",
		},
	}
	jsondata, err = json.MarshalIndent(funresp, "", "  ")
	if err != nil {
		return fmt.Errorf("json.Marshal: %w", err)
	}
	fmt.Fprintf(w, "function call response sent to the model:\n%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], "", "  ")
	if err != nil {
		return fmt.Errorf("json.Marshal: %w", err)
	}
	fmt.Fprintf(w, "Answer generated by the model:\n%s\n", string(jsondata))

	return nil
}