Gemini에서 함수 호출을 사용하여 API와 상호작용하는 방법

1. 개요

Gemini의 함수 호출이란 무엇인가요?

Vertex AI Gemini API는 멀티모달 사용 사례를 위해 설계되고 Google DeepMind에서 개발된 생성형 AI 모델 제품군입니다. 함수 호출은 개발자가 생성형 모델에서 구조화된 데이터 출력을 더 쉽게 가져올 수 있도록 지원하는 Gemini 모델의 기능입니다.

그런 다음 개발자는 이러한 출력을 사용하여 다른 API를 호출하고 관련 응답 데이터를 모델에 반환할 수 있습니다. 즉, 함수 호출을 사용하면 생성된 콘텐츠에 최신 정보와 정확한 정보가 포함되도록 생성형 모델을 외부 시스템에 연결할 수 있습니다.

함수 호출 작동 방식

함수는 함수 선언을 사용하여 설명되며, 이는 생성형 모델이 함수 내의 목적과 매개변수를 이해하는 데 도움이 됩니다. 쿼리의 함수 선언을 생성형 모델에 전달하면 모델은 사용자의 쿼리를 기반으로 관련 함수의 이름과 인수를 포함하는 구조화된 객체를 반환합니다. 함수 호출을 사용하면 모델이 실제로 함수를 호출하지 않습니다. 대신 반환된 함수와 매개변수를 사용하여 원하는 언어, 라이브러리 또는 프레임워크에서 함수를 호출할 수 있습니다.

API 인터페이스

빌드할 항목

이 Codelab에서는 Vertex AI Gemini API와 Python을 사용하여 생성형 AI 파이프라인을 빌드합니다. 사용자는 앱을 사용하여 환율을 물어볼 수 있으며, 시스템은 외부 API에서 최신 데이터를 가져와 사용자에게 답변을 제공합니다.

학습할 내용

  • Python 클라이언트 라이브러리를 사용하여 Gemini 모델과 상호작용하는 방법
  • 함수 선언을 정의하고 도구로 등록하는 방법
  • Gemini를 호출하고 함수 호출 응답을 받는 방법
  • Gemini에 함수 응답을 반환하고 사용자에게 응답하는 방법

필요한 항목

2. 설정 및 요건

Gemini에서 함수 호출을 사용하려면 먼저 Vertex AI API를 사용 설정하고 최신 버전의 Vertex AI Python 클라이언트 라이브러리를 설치해야 합니다.

Vertex AI API 사용 설정

Vertex AI API를 사용 설정하려면 다음 단계를 따르세요.

  1. 브라우저에서 Vertex AI API 서비스 세부정보 페이지로 이동합니다.
  2. 사용 설정 버튼을 클릭하여 Google Cloud 프로젝트에서 Vertex AI API를 사용 설정합니다.

Vertex AI용 Python 클라이언트 라이브러리 설치

Vertex AI용 Python 클라이언트 라이브러리를 설치하려면 다음 단계를 따르세요.

  1. 개발 환경에서 터미널을 엽니다.
  2. 유효한 Python 개발 환경이 있는지 확인하고 필요한 경우 이 가이드라인을 참고하세요.
  3. 다음 명령어를 실행하여 Vertex AI용 Python 클라이언트 라이브러리를 설치합니다.
    pip install --upgrade google-cloud-aiplatform
    
  4. 노트북 환경에서 실행하는 경우 새로 설치된 패키지를 사용하려면 런타임/커널을 다시 시작해야 할 수 있습니다.

이제 Vertex AI API를 사용할 준비가 되었습니다.

3. 문제 이해하기

대규모 언어 모델 또는 생성형 AI 모델과 상호작용하면서 실시간 또는 최신 정보를 물어봤는데 오래된 정보나 부정확한 정보가 포함된 대답을 받은 적이 있나요?

지금 바로 사용해 보세요. 먼저 관련 Python 패키지를 가져오고 Gemini 모델을 초기화합니다. Colab 또는 Colab Enterprise와 같은 Python 개발 환경에서 Vertex AI SDK for Python의 최신 버전을 설치하여 다음 코드를 실행할 수 있습니다.

import vertexai
from vertexai.generative_models import GenerativeModel
model = GenerativeModel("gemini-1.5-pro-001")

이제 오늘의 다양한 통화 환율에 대해 질문해 보겠습니다.

response = model.generate_content(
    "What's the exchange rate for euros to dollars today?"
)
print(response.text)

모델은 다음과 같이 제한적이거나 오래된 대답을 생성합니다.

As an AI language model, I don't have access to real-time currency exchange
rates. However, as of my last update in September 2021, the approximate exchange
rate between euros (EUR) and US dollars (USD) was:

1 EUR ≈ 1.18 USD

Please note that currency exchange rates constantly fluctuate and can vary
depending on various factors such as economic conditions, supply and demand,
political events, and more. To obtain the most up-to-date and accurate exchange
rate, I recommend using a reliable currency converter or financial website that
provides live rates.

[...]

최종 사용자가 이러한 유형의 대답을 받은 경우 컨텍스트를 전환하여 관심 있는 통화를 조회하고, 최신 환율을 가져오고, 직접 변환을 실행해야 합니다.

이상적으로는 생성형 모델 파이프라인이 사용자를 위해 이러한 작업을 일부 또는 전부 처리할 수 있습니다. 다음 섹션에서는 외부 시스템을 호출할 수 있도록 생성형 모델에서 구조화된 응답을 얻기 위한 몇 가지 일반적인 해결 방법을 시도해 봅니다.

4. 일반적인 해결 방법 시도

최신 정보 또는 외부 소스의 데이터가 필요한 시나리오에서 생성형 모델을 사용할 때 외부 API를 호출한 다음 결과를 생성형 모델에 다시 입력하여 대답에 사용할 수 있습니다.

외부 시스템을 호출하기 전에 사용할 올바른 함수를 결정하고, 사용자로부터 관련 매개변수를 추출하고, 매개변수를 구조화된 데이터 객체에 넣어야 합니다. 일반적으로 생성형 모델이 유효한 구조화된 데이터를 출력하도록 강제하기 위해 철저한 프롬프트 엔지니어링이 필요합니다.

이전 섹션에서 질문한 내용을 다시 살펴보고 모델에 추가 지침을 몇 가지 추가해 보겠습니다. Gemini 모델에 다음 요청을 보내 보세요.

user_prompt = "What's the exchange rate from euros to US dollars today?"

response = model.generate_content("""
Your task is to extract parameters from the user's input and return it as a
structured JSON payload. The user will ask about the exchange rate and which
currency they are converting from and converting to.

User input: {user_prompt}

Please extract the currencies as parameters and put them in a JSON object.
""".format(user_prompt=user_prompt))
print(response.text)

이로 인해 유효한 JSON이 아니며 Google에서 작업하기 어려운 다음과 같은 텍스트 응답이 생성됩니다.

```json
{
  "currency_from": "euros",
  "currency_to": "US dollars"
}
```

특히 텍스트 응답의 첫 번째 줄과 마지막 줄에는 코드 블록을 구분하는 백틱이 포함되어 있고, 첫 번째 줄에는 언어 지정자가 포함되어 있으며, JSON 객체의 값은 통화 환전 API에서 입력 매개변수로 예상하는 표준 3자리 통화 약어가 아닙니다.

Python을 사용하여 이 텍스트를 유효한 JSON 및 딕셔너리로 후처리하거나, 프롬프트에 추가 안내를 추가하거나, 원하는 출력의 예를 하나 이상 제공하거나, 모델을 미세 조정하거나, 생성형 모델에 JSON을 정리해 달라고 요청하는 다른 호출을 시도할 수 있습니다.

하지만 더 결정적인 방법이 있습니다. Gemini에서 함수 호출을 사용하여 외부 서비스의 정보를 쿼리하고 최종 사용자에게 관련 응답을 반환하는 방법을 알아보겠습니다.

5. 함수 호출 작동 방식

파라미터 추출 및 함수 호출을 시작하기 전에 함수 호출 단계와 런타임에 사용되는 구성요소를 살펴보겠습니다.

Gemini의 함수 호출 개요

Gemini API에 대한 사용자 입력

사용자의 프롬프트가 Gemini API로 전송되며, Gemini 모델에 대한 해당 API 호출에서 개발자는 Gemini 모델이 호출할 수 있는 함수와 호출 방법을 알 수 있도록 도구 내에 하나 이상의 함수 선언을 정의했습니다.

Gemini API가 함수 호출을 반환합니다.

사용자 입력 및 프롬프트의 콘텐츠에 따라 Gemini는 호출할 함수의 이름과 사용할 해당 매개변수가 포함된 구조화된 데이터가 포함된 함수 호출 응답을 반환합니다.

API 요청하기

그런 다음 함수 이름과 매개변수를 사용하여 외부 시스템 또는 API에서 정보를 가져오는 API 요청을 합니다. 이 API 요청 및 응답은 애플리케이션 코드에서 개발자가 구현하며 Gemini API 및 SDK의 범위를 벗어납니다. 예를 들어 Python에서 requests 라이브러리를 사용하여 REST API를 호출하고 JSON 응답을 받을 수 있습니다. 또는 원하는 방식과 클라이언트 라이브러리를 사용하여 함수를 호출할 수 있습니다.

Gemini에 API 응답 반환

마지막으로 API 응답을 Gemini 모델에 다시 전달하여 최종 사용자의 초기 프롬프트에 대한 응답을 생성하거나 Gemini 모델에서 추가 정보가 필요하다고 판단하는 경우 다른 함수 호출 응답을 호출할 수 있습니다.

6. API 선택

함수 호출의 전체 흐름과 구체적인 단계를 이해했으므로 이제 생성형 AI 파이프라인을 빌드하여 최신 환율을 가져옵니다. 먼저 정보 소스로 사용할 API를 선택해야 합니다.

환전 앱의 경우 https://www.frankfurter.app/의 REST API를 사용하여 전 세계 환율에 관한 최신 정보를 가져옵니다.

이 REST API와 상호작용하기 위해 Python에서 requests를 사용하여 다음과 같이 REST API 호출을 할 수 있습니다.

import requests
url = "https://api.frankfurter.app/latest"
response = requests.get(url)
response.text

또는 다음과 같은 cURL 요청

curl https://api.frankfurter.app/latest

그러면 다음과 비슷한 응답이 반환됩니다.

{
  "amount": 1,
  "base": "EUR",
  "date": "2023-12-20",
  "rates": {
    "AUD": 1.6186, "BGN": 1.9558, "BRL": 5.3287,
    "CAD": 1.4609, "CHF": 0.946, "CNY": 7.8121,
    "CZK": 24.538, "DKK": 7.4565, "GBP": 0.86555,
    "HKD": 8.5439, "HUF": 385.23, "IDR": 16994,
    "ILS": 3.9983, "INR": 91.06, "ISK": 150.3,
    "JPY": 157.12, "KRW": 1425.62, "MXN": 18.6867,
    "MYR": 5.0977, "NOK": 11.2895, "NZD": 1.7421,
    "PHP": 60.991, "PLN": 4.3413, "RON": 4.9699,
    "SEK": 11.129, "SGD": 1.4562, "THB": 38.252,
    "TRY": 31.883, "USD": 1.0944, "ZAR": 20.111
  }
}

Gemini의 함수 호출은 실제로 외부 API를 호출하지 않으므로 사용하는 API 유형에 이러한 제한이 없습니다. Cloud Run 서비스, Cloud Functions, Google Cloud 서비스에 대한 API 요청 또는 외부 REST API를 사용할 수 있습니다.

7. 함수 및 도구 정의

이제 사용할 REST API를 선택했으므로 API 사양을 정의하고 도구에 함수를 등록할 수 있습니다.

최신 버전의 Python용 Vertex AI SDK가 설치되어 있는지 확인합니다.

그런 다음 Python SDK에서 필요한 모듈을 가져오고 Gemini 모델을 초기화합니다.

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

model = GenerativeModel("gemini-1.5-pro-001")

https://api.frankfurter.app/의 REST API를 다시 살펴보면 다음 입력 매개변수를 허용하는 것을 알 수 있습니다.

매개변수

유형

설명

from

문자열

변환할 통화

to

문자열

변환할 통화

date

문자열

환율을 가져올 날짜

이러한 매개변수를 사용하여 YAML 형식의 이 REST API에 대한 부분 OpenAPI 사양은 다음과 같습니다.

openapi: 3.0.0
info:
  title: Frankfurter Exchange Rate API
  description: This API provides current and historical exchange rates
  version: 1.0.0
servers:
  - url: https://api.frankfurter.app
paths:
  /{date}:
    get:
      summary: Get the latest currency exchange rates.
      parameters:
        - name: date
          in: path
          description: Get currency rates for a specific date or 'latest' if a date is not specified
          required: true
          schema:
            type: string
        - name: from
          in: query
          description: The currency to convert from.
          required: true
          schema:
            type: string
        - name: to
          in: query
          description: The currency to convert to.
          schema:
            type: string

이제 Gemini용 Python SDK를 사용하여 이를 FunctionDeclaration로 등록해 보겠습니다.

get_exchange_rate_func = FunctionDeclaration(
    name="get_exchange_rate",
    description="Get the exchange rate for currencies between countries",
    parameters={
    "type": "object",
    "properties": {
        "currency_date": {
            "type": "string",
            "description": "A date that must always be in YYYY-MM-DD format or the value 'latest' if a time period is not specified"
        },
        "currency_from": {
            "type": "string",
            "description": "The currency to convert from in ISO 4217 format"
        },
        "currency_to": {
            "type": "string",
            "description": "The currency to convert to in ISO 4217 format"
        }
    },
         "required": [
            "currency_from",
            "currency_date",
      ]
  },
)

생성형 모델은 이 정보를 사용하여 선택할 함수와 함수 호출에서 매개변수를 채우는 방법을 결정하므로 함수 및 매개변수 설명에 최대한 많은 세부정보를 사용해야 합니다.

마지막으로 함수 선언이 포함된 Tool를 정의합니다.

exchange_rate_tool = Tool(
    function_declarations=[get_exchange_rate_func],
)

여기서는 도구 내에서 하나의 함수 선언을 사용하지만 도구에 하나 이상의 함수 선언을 등록할 수 있으며 모델은 런타임에 사용할 적절한 함수를 선택합니다. Gemini SDK for Python의 FunctionDeclaration, Tool 및 관련 클래스에 관한 자세한 내용은 Gemini API의 함수 호출에 관한 문서를 참고하세요.

함수 및 도구 정의 구성을 완료했습니다. 다음 섹션에서는 이 도구를 사용하여 생성 모델을 호출하고 REST API를 호출하는 데 사용할 수 있는 함수 호출을 가져옵니다.

8. 함수 호출 생성

이제 생성형 모델에 프롬프트를 표시하고 정의한 tool를 포함할 수 있습니다.

prompt = """What is the exchange rate from Australian dollars to Swedish krona?
How much is 500 Australian dollars worth in Swedish krona?"""

response = model.generate_content(
    prompt,
    tools=[exchange_rate_tool],
)

응답 객체를 살펴보겠습니다.

print(response.candidates[0].content)

role: "model"
parts {
  function_call {
    name: "get_exchange_rate"
    args {
      fields {
        key: "currency_to"
        value {
          string_value: "SEK"
        }
      }
      fields {
        key: "currency_from"
        value {
          string_value: "AUD"
        }
      }
      fields {
        key: "currency_date"
        value {
          string_value: "latest"
        }
      }
    }
  }
}

모델이 사용 가능한 함수를 선택하고 파라미터와 함께 get_exchange_rate 함수의 함수 호출을 반환한 것으로 보입니다. 파라미터가 원하는 올바른 형식으로 되어 있습니다. 생성형 모델에서 구조화된 응답을 얻을 수 있게 되었습니다.

다음 섹션에서는 응답의 정보를 사용하여 API 요청을 합니다.

9. API 요청하기

Gemini의 함수 호출은 실제로 외부 API를 호출하지 않습니다. 원하는 언어, 라이브러리 또는 프레임워크를 자유롭게 사용할 수 있습니다.

여기서는 Python의 requests 라이브러리를 사용하여 환율 REST API를 호출합니다.

응답을 Python 사전으로 압축 해제해 보겠습니다.

params = {}
for key, value in response.candidates[0].content.parts[0].function_call.args.items():
    params[key[9:]] = value
params

이제 requests 또는 다른 메서드를 호출할 수 있습니다.

import requests
url = f"https://api.frankfurter.app/{params['date']}"
api_response = requests.get(url, params=params)
api_response.text

그러면 다음과 비슷한 응답이 반환됩니다.

'{"amount":1.0,"base":"AUD","date":"2024-01-16","rates":{"SEK":6.8682}}'

오늘의 최신 환율 정보가 포함된 REST API의 응답이 있습니다. 다음 섹션에서는 모델이 사용자에게 관련성 있는 응답을 생성할 수 있도록 이 정보를 모델에 다시 전달합니다.

10. 대답 생성

마지막으로 다음 대화 턴에서 함수 응답을 모델에 다시 전달하여 사용자의 응답을 생성합니다.

response = model.generate_content(
    [
    Content(role="user", parts=[
        Part.from_text(prompt + """Give your answer in steps with lots of detail
            and context, including the exchange rate and date."""),
    ]),
    Content(role="function", parts=[
        Part.from_dict({
            "function_call": {
                "name": "get_exchange_rate",
            }
        })
    ]),
    Content(role="function", parts=[
        Part.from_function_response(
            name="get_exchange_rate",
            response={
                "content": api_response.text,
            }
        )
    ]),
    ],
    tools=[exchange_rate_tool],
)


response.candidates[0].content.parts[0].text

함수 응답을 모델에 다시 전달하면 모델은 API 응답의 관련 정보와 함께 사용자의 프롬프트에 응답합니다.

The exchange rate from Australian dollars to Swedish krona on January 16, 2024,
is 1 Australian dollar is equal to 6.8663 Swedish krona.

So, 500 Australian dollars would be worth 500 * 6.8663 = 3,433.15 Swedish krona.

11. 전체 코드 예 보기

이 시점에서 Cloud Run 서비스, Cloud 함수 또는 다른 Cloud 서비스를 사용하여 백엔드 API에 Python 코드를 넣고 이 백엔드 API를 사용하여 모델 쿼리 및 API 호출을 실행하는 프런트엔드 앱을 배포할 수 있습니다.

다음은 최종 솔루션의 전체 코드 예입니다.

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

model = GenerativeModel("gemini-1.5-pro-001")

get_exchange_rate_func = FunctionDeclaration(
    name="get_exchange_rate",
    description="Get the exchange rate for currencies between countries",
    parameters={
    "type": "object",
    "properties": {
        "currency_date": {
            "type": "string",
            "description": "A date that must always be in YYYY-MM-DD format or the value 'latest' if a time period is not specified"
        },
        "currency_from": {
            "type": "string",
            "description": "The currency to convert from in ISO 4217 format"
        },
        "currency_to": {
            "type": "string",
            "description": "The currency to convert to in ISO 4217 format"
        }
    },
         "required": [
            "currency_from",
            "currency_date",
      ]
  },
)

exchange_rate_tool = Tool(
    function_declarations=[get_exchange_rate_func],
)

prompt = """What is the exchange rate from Australian dollars to Swedish krona?
How much is 500 Australian dollars worth in Swedish krona?"""

response = model.generate_content(
    prompt,
    tools=[exchange_rate_tool],
)

response.candidates[0].content

params = {}
for key, value in response.candidates[0].content.parts[0].function_call.args.items():
    params[key[9:]] = value
params

import requests
url = f"https://api.frankfurter.app/{params['date']}"
api_response = requests.get(url, params=params)
api_response.text

response = model.generate_content(
    [
    Content(role="user", parts=[
        Part.from_text(prompt + """Give your answer in steps with lots of detail
            and context, including the exchange rate and date."""),
    ]),
    Content(role="function", parts=[
        Part.from_dict({
            "function_call": {
                "name": "get_exchange_rate",
            }
        })
    ]),
    Content(role="function", parts=[
        Part.from_function_response(
            name="get_exchange_rate",
            response={
                "content": api_response.text,
            }
        )
    ]),
    ],
    tools=[exchange_rate_tool],
)


response.candidates[0].content.parts[0].text

이 구현에서는 생성형 모델에 두 가지 요청을 사용했습니다. 하나는 함수 호출을 생성하는 요청이고 다른 하나는 함수 응답을 반환하는 요청입니다. 이는 Gemini로 함수 호출과 함수 응답을 처리하는 한 가지 방법일 뿐입니다. 추가 함수 호출을 통해 질문에 대한 자세한 정보를 얻거나 채팅 및 비동기 메서드와 함께 함수 호출을 사용할 수도 있습니다.

추가 코드 샘플은 Gemini의 함수 호출 샘플 노트북을 참고하세요.

12. 축하합니다

Gemini의 함수 호출을 사용하여 Vertex AI Gemini API 및 Python과 함께 사용할 수 있는 생성형 AI 파이프라인을 성공적으로 빌드했습니다. 사용자가 환율에 관해 질문하면 시스템이 외부 API에서 최신 데이터를 가져와 답변을 제공합니다.

최종 사용자의 프롬프트가 주어지면 Gemini의 함수 호출은 적절한 함수를 선택하고, 프롬프트에서 매개변수를 추출하고, 외부 API 호출을 수행할 수 있도록 구조화된 데이터 객체를 반환합니다.

Gemini의 함수 호출은 매개변수를 결정론적으로 추출하는 데 최적의 환경을 제공하면서 요약 및 콘텐츠 생성은 생성형 모델에 맡기도록 설계되었습니다. 파이프라인에서 다른 API와 프롬프트를 자유롭게 사용해 보고 Vertex AI Gemini API와 관련된 다른 기능을 살펴보세요.

API 인터페이스

삭제

다음과 같이 정리하면 이 Codelab에서 사용한 리소스의 비용이 Google Cloud 계정에 청구되지 않습니다.

자세히 알아보기

다음 가이드와 리소스를 통해 대화형 AI와 생성형 AI에 대해 계속 알아보세요.

라이선스

이 작업물은 Creative Commons Attribution 2.0 일반 라이선스에 따라 사용이 허가되었습니다.