함수 호출을 활용하여 더 스마트한 LLM 애플리케이션 구축하기
대규모 언어 모델 (LLMs)은 더 이상 텍스트 생성에만 국한되지 않으며, 이제 더 복잡하고 맥락 기반의 작업을 처리합니다. 이 분야의 핵심 발전은 function calling으로, LLM이 외부 도구, 데이터베이스, API와 상호작용하여 동적 작업을 수행할 수 있게 합니다. 이를 통해 LLM은 텍스트 생성을 넘어 실제 데이터와 서비스를 활용할 수 있습니다.
Zilliz가 주최한 최근 Berlin Unstructured Data Meetup에서 Google의 customer engineer인 Nikolai Danylchyk는 최신 LLM인 Gemini가 function calling을 사용하여 기능을 확장하는 방법에 대해 논의했습니다. 이 블로그에서는 그의 인사이트를 요약하고, 이 강력한 기능을 활용하여 고급 LLM 애플리케이션을 구축하는 방법을 보여드립니다. 더 자세한 내용을 알고 싶다면 YouTube에서 Nikolai의 발표 다시보기를 시청하시길 권장합니다.
LLM의 고급 Function Calling 이해하기
LLM은 크게 발전해 왔지만, 진정한 잠재력은 function call을 통해 외부 시스템과 상호작용할 때 드러납니다. 이 기능을 통해 LLM은 라이브 데이터베이스를 쿼리하거나, 명령을 실행하거나, 실시간 계산을 수행함으로써 정적인 학습 데이터의 한계를 넘어설 수 있습니다. function calling을 통합하면 LLM은 다른 시스템과 원활하게 연결되어 더 정확하고 최신이며 동적인 응답을 제공할 수 있습니다. Gemini를 예로 들어 function calling이 어떻게 작동하는지 살펴보겠습니다.
그림 1- 런타임에 사용되는 function calling 단계 및 구성 요소
그림 1: 런타임에 사용되는 function calling 단계 및 구성 요소.
프로세스는 사용자가 Gemini API에 요청을 제출할 때 시작됩니다. 이 시점에서 개발자는 이미 도구 내에 하나 이상의 함수 선언을 정의하여 Gemini에 사용 가능한 함수와 실행 방법을 알려둔 상태입니다. 사용자 입력이 수신되면 Gemini API는 콘텐츠와 프롬프트를 분석하고 "Function Call" 응답을 반환합니다. 이 응답에는 호출할 함수의 이름과 관련 매개변수와 같은 구조화된 데이터가 포함됩니다.
다음 단계는 Gemini 시스템 외부에서 발생합니다: 애플리케이션은 Gemini의 응답에서 얻은 함수 이름과 매개변수를 사용하여 외부 서비스에 API 요청을 보냅니다. 여기서 개발자는 Python의
requests라이브러리와 같은 도구를 사용하여 REST API 또는 필요에 맞는 다른 클라이언트 라이브러리를 호출합니다.외부 시스템이 응답을 반환한 후, 애플리케이션은 해당 데이터를 Gemini로 다시 보냅니다. 그런 다음 모델은 이 새로운 정보를 사용하여 사용자에게 최종 응답을 생성합니다. 추가 데이터가 필요한 경우 Gemini는 또 다른 function call을 실행하여 필요에 따라 이 사이클을 계속할 수 있습니다.
이 고급 기능의 중요성을 이해하려면 function-calling 기능이 없는 기존 LLM을 생각해 보세요. 그 응답은 학습된 데이터를 기반으로 생성되며, 이 데이터는 오래되었거나 범위가 제한적일 수 있습니다. 그러나 function call을 사용하면 LLM은 명령을 실행하여 데이터베이스에서 실시간 정보를 가져오거나, 고객 관계 관리(CRM) 시스템의 레코드를 업데이트하거나, 티켓 예약 또는 주문과 같은 작업을 트리거할 수도 있습니다. 이 접근 방식은 모델의 활용성을 단순히 응답을 생성하는 것에서 작업을 수행하는 것으로 확장합니다.
기술적으로 말하면, LLM에서의 함수 호출은 모델과 외부 API 또는 서비스 간의 구조화된 상호작용을 포함합니다. 모델은 함수 호출이 필요한 적절한 시나리오를 식별하고, 호출을 위한 매개변수를 구성한 뒤 실행합니다.
예를 들어, 사용자가 “What’s the weather in Berlin?”이라고 묻는다면, 함수 호출은 날씨 API를 트리거하여 실시간 데이터를 가져와 응답을 생성합니다. 이 경우 LLM은 사용자와 외부 시스템 사이의 지능형 중개자 역할을 하며, 더 정확하고 유용한 상호작용을 조율합니다.
이제 함수 호출의 기본 개념을 살펴보았으니, 실제 API와 상호작용하는 Gemini를 사용한 실용적인 구현을 살펴보겠습니다—환율 정보를 가져오는 예입니다.
예시: 환율 정보 조회를 위한 함수 호출 사용
Gemini 함수 호출을 통해 환율 API를 어떻게 활용할 수 있는지 살펴보겠습니다:
필요한 라이브러리 설치 및 프로젝트 변수 설정
먼저 Google Cloud의 Vertex AI 플랫폼과 상호작용하는 데 필요한 google-cloud-aiplatform 라이브러리를 업그레이드하고 설치하겠습니다. 그런 다음 프로젝트 ID와 위치를 변수로 제공합니다.
!pip3 install --upgrade --user --quiet google-cloud-aiplatform
PROJECT_ID = "[your-project-id]" # @param {type:"string"}
LOCATION = "us-central1" # @param {type:"string"}
이는 Google Cloud에서 작업 중인 프로젝트와 리전을 식별하기 위한 플레이스홀더입니다.
필요한 모듈 가져오기 및 생성형 모델 정의
그런 다음 Vertex AI의 생성형 모델을 정의하고 사용하기 위해 필요한 모듈을 가져옵니다. requests 라이브러리는 나중에 외부 API에서 데이터를 가져오는 데 사용됩니다.
import requests
from vertexai.generative_models import (
Content,
FunctionDeclaration,
GenerativeModel,
Part,
Tool,
)
model = GenerativeModel("gemini-1.5-pro-001")
마지막 줄은 생성형 모델을 초기화하며, 이 경우 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],
)
매개변수에는 currency_date(YYYY-MM-DD 형식 또는 키워드 latest), currency_from(변환할 원래 통화의 ISO 4217 코드), currency_to(변환할 대상 통화의 ISO 4217 코드)가 포함됩니다. required 섹션은 currency_from과 currency_date가 필수임을 지정합니다. 그런 다음 get_exchange_rate 함수 선언을 감싸는 exchange_rate_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],
)
response.candidates[0].content
params = {}
for key, value in response.candidates[0].content.parts[0].function_call.args.items():
params[key[9:]] = value
params
위 코드는 Australian dollars와 Swedish krona 간의 환율을 묻는 프롬프트를 정의합니다. 그런 다음 exchange_rate_tool과 함께 프롬프트를 전달하여 generate_content를 사용해 모델을 호출합니다. 모델은 응답 생성을 시도합니다.
그런 다음 응답이 파싱됩니다. params 딕셔너리는 function_call.args의 키와 값을 반복하고, 예상되는 매개변수 이름과 일치하도록 키의 처음 9자를 제거하여 채워집니다.
API에서 환율 가져오기 및 사용자에게 응답 제공하기
이제 이전 응답에서 추출한 매개변수를 사용하여 Frankfurter API(무료 외환 환율 API)에 요청하고 사용자에게 응답을 생성해 보겠습니다.
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
위 코드에서는 환율 API로부터 응답을 받으면 generate_content 메서드를 다시 호출합니다. 이번에는 여러 콘텐츠를 전달합니다. 사용자로부터 온 콘텐츠(자세한 단계와 맥락 요청), get_exchange_rate에 대한 함수 호출, 그리고 Frankfurter API의 응답입니다. 이 조합은 모델이 더 철저한 단계별 응답을 제공하도록 유도합니다. 마지막으로 모델이 생성한 콘텐츠의 텍스트 부분을 출력합니다. 이것이 사용자에게 다시 제공하는 응답입니다.
다음은 샘플 응답입니다:
그림 2- Australian dollars에서 Swedish Krona로의 환율을 보여주는 프로그램 출력
그림 2: Australian dollars에서 Swedish Krona로의 환율을 보여주는 프로그램 출력
응답은 함수 호출이 작동했으며 Frankfurter API에 나열된 현재 환율을 제공했음을 보여줍니다.
지금까지 Gemini 및 다른 많은 LLM의 고급 기능인 함수 호출을 다루었습니다. 함수 호출만으로도 통화 조회와 같은 복잡한 작업을 수행할 수 있지만, 그 진정한 잠재력은 Retrieval Augmented Generation (RAG)와 같은 다른 강력한 기법과 결합될 때 실현됩니다.
향상된 상호작용을 위한 Function Calling과 Retrieval-Augmented Generation (RAG) 결합하기
검색 증강 생성(Retrieval Augmented Generation, RAG)은 자연어 처리(NLP)에서 가장 중요한 트렌드 중 하나가 되었습니다. RAG 시스템은 LLM의 생성 능력과 Milvus 및 Zilliz Cloud(관리형 Milvus)와 같은 벡터 데이터베이스 기반 검색 시스템의 효율성을 결합합니다. 구체적으로, RAG 시스템에서는 벡터 데이터베이스가 LLM을 위한 컨텍스트 정보를 검색한 다음, LLM이 검색된 정보를 기반으로 더 정확한 응답을 생성합니다. 함수 호출은 LLM과 외부 데이터베이스 또는 시스템 간의 더 동적인 상호작용을 가능하게 하여 이 프로세스를 향상합니다. 함수 호출이 추가되면 LLM은 관련 데이터를 검색할 뿐만 아니라 이를 실시간으로 처리하고 상호작용함으로써 기능을 확장할 수 있습니다.
예를 들어, RAG와 함수 호출을 모두 사용하는 고객 지원 애플리케이션에서 LLM은 더 풍부하고 개인화된 상호작용을 제공합니다. 사용자가 “최근 주문은 어디에 있나요?”라고 묻는 경우, 시스템은 먼저 RAG를 사용하여 Milvus 벡터 데이터베이스에서 주문 처리에 관한 일반 정보를 검색해 컨텍스트를 제공합니다. 예를 들어, 검색된 정보는 “주문은 일반적으로 배송까지 영업일 기준 3~5일이 걸립니다.”입니다. 동시에 함수 호출을 통해 고객 계정을 쿼리하여 실시간 데이터에 접근합니다. 최종 응답은 “주문 #12345는 9월 10일에 발송되었으며 9월 15일에 도착할 예정입니다.”가 됩니다.
RAG와 함수 호출의 이러한 통합은 관련성 있고 유익한 응답을 생성할 뿐만 아니라 실시간 데이터 및 서비스와 능동적으로 연계되어 상호작용적 차원을 제공하는 동적 시스템을 만듭니다. 이 조합은 LLM 기반 지능형 에이전트가 복잡한 실제 상호작용을 수행할 수 있게 합니다.
- RAG 시스템을 향상하기 위해 LLM 함수 호출 기능을 활용하는 방법에 대한 단계별 가이드는 이 튜토리얼을 참조하세요.
RAG와 함수 호출 결합의 사용 사례
이러한 실제 상호작용 몇 가지를 살펴보겠습니다.
헬스케어: 의료 기록 검색 및 진료 예약 일정 관리
헬스케어에서 RAG와 함수 호출을 결합하면 LLM이 환자와 의료 제공자 모두에게 고도로 개인화된 데이터 기반 지원을 제공할 수 있습니다. 의사가 시스템에 환자의 과거 데이터를 요청하면, 시스템은 Milvus와 같은 벡터 데이터베이스에서 RAG를 사용해 관련 의료 기록을 검색할 수 있습니다. 동시에 함수 호출을 통해 LLM은 외부 병원 시스템과 상호작용하여 후속 진료 예약을 잡거나 실시간 진단 데이터를 검색할 수 있습니다.
예시: 의사가 “환자 X의 최신 검사 결과는 무엇이며, 다음 주에 후속 진료 예약을 잡아줄 수 있나요?”라고 묻습니다. 시스템은 먼저 Milvus를 쿼리하여 환자 이력에서 관련 문서를 검색하고, 추세와 상태에 대한 인사이트를 제공합니다. 다음으로 함수 호출을 사용하여 병원의 일정 관리 API에 접근해 환자의 예약을 잡습니다.
금융: 개인화된 투자 인사이트 및 실시간 거래
금융 부문에서 RAG는 Milvus와 같은 벡터 데이터베이스에 저장된 관련 시장 정보와 과거 금융 데이터를 검색하는 데 사용됩니다. 이를 함수 호출과 결합하면 LLM은 실시간 데이터를 기반으로 주식 매수 또는 매도, 자금 이체, 맞춤형 포트폴리오 추천 생성과 같은 실시간 작업도 수행할 수 있습니다.
예시: 사용자가 “지난 6개월 동안 내 포트폴리오는 어떤 성과를 냈고, Apple 주식 $1000어치를 매수해 줄 수 있나요?”라고 묻습니다. 시스템은 먼저 RAG를 사용해 Milvus에서 사용자의 포트폴리오 이력을 검색하여 과거 성과 요약을 제공합니다. 그런 다음 function calling을 사용해 거래 API와 상호작용하여 주식 매수를 실행하고 사용자에게 거래를 확인해 줍니다.
E-Commerce: 제품 추천 및 실시간 주문 추적
전자상거래에서 RAG는 Milvus에서 제품 정보, 리뷰 또는 고객 이력을 검색하여 쇼핑 경험을 개인화하는 데 도움을 줄 수 있습니다. function calling과 결합하면, 시스템은 실시간 재고 시스템과 상호작용하여 재고 가용성을 제공하고, 주문을 실시간으로 추적하거나, 결제까지 처리할 수 있습니다.
예시: 고객이 제 마지막 구매와 비슷한 노트북을 추천해 주고, 현재 주문이 언제 도착할지 알려줄 수 있나요?라고 묻습니다. LLM은 Milvus에서 고객의 이전 구매 정보를 검색하고 비슷한 제품을 추천합니다. 그런 다음 function calling을 사용해 주문 추적 API를 조회하여 현재 주문의 배송 상태에 대한 실시간 업데이트를 제공합니다.
Travel: 여행 일정 제안 및 예약 관리
여행 및 hospitality 분야에서 RAG는 Milvus와 같은 벡터 데이터베이스에 저장된 여행지, 호텔, 여행 일정에 대한 세부 정보를 가져올 수 있습니다. function calling과 함께 사용하면, 시스템은 예약을 관리하고, 개인화된 여행 일정을 제안하거나, 항공편 및 예약에 대한 실시간 업데이트를 제공할 수 있습니다.
예시: 여행자가 이탈리아에서의 5일 일정을 제안해 주고, 내 호텔 예약을 더 이른 날짜로 변경해 줄 수 있나요?라고 묻습니다. 시스템은 먼저 여행자의 선호도와 과거 여행을 기반으로 Milvus에서 여행 일정 제안을 검색합니다. 그런 다음 function calling을 사용해 호텔의 예약 시스템과 상호작용하여 예약을 수정하고 사용자에게 변경 사항을 확인해 줍니다.
function calling이 RAG와 같은 시스템을 어떻게 향상시키는지 살펴보았듯이, 이러한 기술을 실제 애플리케이션에 배포할 때의 실질적인 과제와 이점을 인식하는 것이 중요합니다.
실제 사용 사례에서 Function Calling의 과제와 이점
function calling의 잠재력은 막대하지만, 그 자체의 과제도 따릅니다. 주요 우려 사항 중 하나는 상호작용의 보안과 개인정보 보호를 보장하는 것입니다. LLM이 function call을 발행할 때 사용자 계정이나 금융 정보와 같은 민감한 데이터에 접근해야 할 수 있습니다. 이러한 거래가 안전하고 데이터 개인정보 보호 규정을 준수하도록 보장하는 것은 매우 중요합니다.
또한 단일 워크플로에서 여러 function call을 관리하는 복잡성은 지연 시간 문제로 이어질 수 있습니다. 예를 들어 LLM이 여러 시스템에 여러 function call을 발행하는 경우, 응답 시간이 증가하여 사용자 경험에 영향을 미칠 수 있습니다. 이는 속도가 중요한 실시간 애플리케이션에서 특히 중요합니다.
긍정적인 측면에서 function calling은 향상된 작업 자동화, 더 정확한 실시간 응답, 개선된 사용자 상호작용을 포함한 여러 이점을 제공합니다. 의료, 금융, 고객 서비스와 같은 산업에서 function calling은 반복적인 작업을 자동화하여 운영을 간소화할 수 있습니다. 예를 들어 의료 분야에서 LLM은 function call을 통해 환자 기록을 가져오고, 진료 예약을 잡고, 알림을 보내 의료 전문가가 더 복잡한 사례에 집중할 시간을 확보해 줄 수 있습니다.
실질적인 이점과 과제를 넘어, 특히 데이터 보안과 시스템 신뢰성을 중심으로 간과해서는 안 되는 윤리적 및 기술적 고려 사항이 있습니다.
윤리적 및 기술적 고려 사항
기술적인 관점에서, 개발자인 우리는 잠재적인 함정을 피하기 위해 함수 호출이 구현되는 방식을 신중하게 관리해야 합니다. 흔한 문제 중 하나는 외부 시스템에 대한 과도한 의존입니다. LLM이 타사 서비스에 지속적으로 함수 호출을 보내는 경우, 시스템의 신뢰성은 해당 서비스의 가동 시간과 성능에 의존하게 됩니다. 외부 서비스를 사용할 수 없는 경우에도 시스템이 원활하게 계속 작동하도록 보장하려면 적절한 오류 처리와 대체 메커니즘이 마련되어 있어야 합니다.
윤리적으로, 함수 호출은 투명성과 사용자 동의에 대한 우려를 제기합니다. LLM이 사용자를 대신해 결정을 내리거나 행동을 취하는 경우, 사용자가 시스템이 무엇을 하고 있는지 완전히 인지하는 것이 필수적입니다. 예를 들어 금융 서비스에서 LLM이 거래를 실행하거나 자금을 이체하는 경우, 사용자는 수행되는 작업에 대해 안내받아야 하며 필요한 경우 개입할 수 있어야 합니다. 명확한 문서화와 사용자 동의 메커니즘은 이러한 시스템에 대한 신뢰를 유지하는 데 매우 중요합니다.
또 다른 윤리적 우려는 데이터 사용을 둘러싼 것입니다. 함수 호출이 개인 데이터나 민감한 데이터에 접근하는 경우, 사용자 개인정보를 보호하기 위한 엄격한 조치가 마련되어 있어야 합니다. 개발자는 데이터가 책임감 있게 처리되고 함수 호출이 GDPR 또는 HIPAA와 같은 개인정보 보호 규정을 준수하도록 보장해야 합니다.
결론
Nikolai는 함수 호출이 대규모 언어 모델에 중요한 향상을 제공하여 외부 시스템 및 데이터와 상호작용함으로써 실제 작업을 수행할 수 있게 하는 방식을 훌륭하게 조명했습니다. 환율을 검색하는 것이든 Retrieval-Augmented Generation (RAG)을 통해 더 복잡한 상호작용을 구동하는 것이든, 함수 호출은 LLM이 달성할 수 있는 범위를 확장합니다.
추가 자료
계속 읽기

We spent 8 years making vector databases faster. Then we stopped.
Rarely queried embeddings still need to stay searchable. See how Vector Lakebase enables on-demand vector search without always-on compute costs.

How Zilliz Ended Up at the Center of NVIDIA’s Unstructured Data Story at GTC 2026
If unstructured data is the context of AI, then the ceiling of AI applications will be set not just by models, but by how mature the infrastructure for unstructured data becomes.

What is the K-Nearest Neighbors (KNN) Algorithm in Machine Learning?
KNN is a supervised machine learning technique and algorithm for classification and regression. This post is the ultimate guide to KNN.


