개발자 입장에서 본 LLM 에이전트와 도구 호출(Tool Calling)의 개념에 대해 말씀드린 포스팅 보고 오셨나요? 이제부터 LLM에 도구 등록하는 방법, LLM에게 도구를 설명하는 방법, Tool Calling 수행 과정 예시까지 차근차근 같이 살펴보겠습니다.
LLM에 도구 등록하기: 마법 지팡이 쥐어주기
LLM에게 외부 도구를 사용하게 하려면 마치 마법사에게 지팡이를 쥐여주듯 도구를 등록해야 합니다. 이 과정은 다음과 같습니다.
-
도구 정의: Python 함수와 같이 실행 가능한 형태로 도구를 만듭니다. 각 도구에는 이름, 기능 설명(description), 입력 매개변수(parameters)를 명확히 정의합니다.
# 예시: 두 수의 합을 계산하는 도구 def add_numbers(a: float, b: float) -> float: """두 숫자를 더합니다.""" return a + b -
도구 등록: LangChain, OpenAI Functions 등 LLM 프레임워크의 API를 사용하여 도구를 등록합니다. 프레임워크는 이 정보를 LLM이 이해할 수 있는 JSON 형식 등으로 자동 변환합니다.
# LangChain 예시 (개념적) from langchain.tools import StructuredTool tool = StructuredTool.from_function( func=add_numbers, name="SumCalculator", description="두 숫자를 더하는 도구", ) # agent에 tool 추가 -
System Prompt 통합: 등록된 도구 정보는 자동으로 system prompt에 포함되어, LLM이 어떤 도구를 사용할 수 있는지 알게 됩니다. 사용자는 별도로 명시할 필요가 없습니다.
LLM에게 도구를 설명하는 방법: OpenAI Function Description
LLM에게 도구를 효과적으로 설명하는 방법 중 하나는 OpenAI Function Description 형식을 사용하는 것입니다. 이 형식은 JSON 스키마를 사용하여 도구의 이름, 설명, 매개변수 등을 정의합니다. 도구 등록은 LLM이 도구의 기능과 파라미터 등 사용법을 System prompt에 추가하여 LLM이 이해하게 하는 과정이라고 볼 수 있습니다.
{
"name": "get_weather",
"description": "Get the current weather in a given location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["location"]
}
}
OpenAI Function Description의 장점:
-
표준화된 형식: LLM이 이해하기 쉬운 표준화된 형식으로 도구를 설명할 수 있습니다.
-
명확한 정의: 도구의 기능, 입력/출력 형식을 명확하게 정의하여 LLM의 오해를 줄일 수 있습니다.
-
자동화 가능: LangChain과 같은 프레임워크를 사용하면 OpenAI Function Description을 자동으로 생성하고 관리할 수 있습니다.
LLM이 Tool Calling을 수행하는 과정 – with Prompt 예제
각 단계별로 LLM이 내부적으로 어떤 처리를 하는지, 그리고 사용자는 어떤 입출력을 주고받게 되는지 예시와 함께 자세히 설명하겠습니다.
-
사용자 입력
사용자: (자연어 형태로 LLM에게 요청) “오늘 서울 날씨 어때? 섭씨 온도로 알려줘.” -
도구 목록 확인
LLM (내부): 시스템에 등록된 사용 가능한 도구 목록 (OpenAI Function Description 형식)을 확인합니다.
[
{
"name": "get_weather",
"description": "Get the current weather in a given location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["location"]
}
},
{
"name": "search_internet",
"description": "Search the internet for a given query",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "The search query"
}
},
"required": ["query"]
}
}
]
-
도구 선택 및 파라미터 추론
LLM (내부): 사용자 요청(“오늘 서울 날씨 어때? 섭씨 온도로 알려줘.”)과 도구 목록을 비교/분석합니다.
LLM (내부 추론 과정 – 예시):
– 사용자가 날씨를 묻고 있다. → get_weather 도구가 적합하다.
– 서울’이라는 위치 정보가 있다. → location 파라미터는 ‘서울’이다.
– 섭씨 온도로 알려달라고 했다. → unit 파라미터는 ‘celsius’이다. -
함수 호출(Function Call) 생성
LLM (출력 – Function Call):
{
"name": "get_weather",
"arguments": {
"location": "서울",
"unit": "celsius"
}
}
이 JSON 객체는 어떤 도구 (get_weather)를 어떤 파라미터 (location: “서울”, unit: “celsius”)와 함께 호출할지를 나타냅니다. 이것은 사용자에게 직접 보여주는 것이 아니라 백엔드 시스템(개발자가 구현한 코드 또는 LangChain과 같은 프레임워크)에 전달됩니다.
-
도구 실행
개발자/프레임워크 (역할): LLM이 생성한 Function Call (JSON)을 받아서 실제로 get_weather 함수(또는 API)를 실행합니다.-
get_weather(“서울”, “celsius”)와 같이 함수를 호출합니다.
-
외부 API, 데이터베이스 등으로부터 날씨 정보를 가져옵니다.
-
도구 (실행 결과 – 예시)
-
{
"temperature": 25,
"condition": "맑음",
"humidity": 60
}
-
응답 생성:
-
도구 실행결과를 LLM에 전달: 개발자/프레임워크는 도구 실행 결과(위의 JSON)를 다시 LLM에게 전달합니다.
-
LLM (내부): 도구 실행 결과를 바탕으로 최종 응답을 생성합니다.
-
LLM (최종 출력 – 사용자에게 보여지는 응답): “오늘 서울 날씨는 맑고, 온도는 25℃입니다. 습도는 60%입니다.”
-
Prompt와 응답의 흐름 (정리)
-
사용자 Prompt (입력): “오늘 서울 날씨 어때? 섭씨 온도로 알려줘.”
-
LLM (내부 처리): 도구 목록 확인, 도구 선택, 파라미터 추론, Function Call 생성
-
Function Call (LLM 출력 → 개발자/프레임워크)
{
"name": "get_weather",
"arguments": {
"location": "서울",
"unit": "celsius"
}
}
-
도구 실행 (개발자/프레임워크): Function Call에 따라 실제 get_weather 도구 실행
-
도구 실행 결과 (개발자/프레임워크 → LLM)
{
"temperature": 25,
"condition": "맑음",
"humidity": 60
}
-
최종 응답(LLM 출력 → 사용자): “오늘 서울 날씨는 맑고, 온도는 25℃입니다. 습도는 60%입니다.”
이처럼 LLM은 사용자의 자연어 요청을 이해하고, 필요한 도구를 선택하여 실행하고, 그 결과를 종합하여 사용자에게 자연어 형태로 응답하는 복잡한 과정을 수행합니다. 이 과정에서 OpenAI Function Description과 같은 형식이 LLM과 개발자/프레임워크 간의 효율적인 소통을 가능하게 합니다.
Tool Calling을 활용한 최종 결과: 무한한 가능성
Tool Calling을 통해 LLM 에이전트는 단순한 질의응답을 넘어 실제 세계와 상호작용할 수 있게 됩니다. 몇 가지 예시를 살펴보겠습니다.
-
개인 비서: 이메일 관리, 일정 예약, 정보 검색, 알림 설정 등 다양한 작업을 자동화합니다.
-
데이터 분석: 데이터베이스 쿼리, 데이터 시각화, 보고서 작성 등을 자동화합니다.
-
고객 지원: FAQ 답변, 문제 해결, 티켓 생성 등 고객 지원 업무를 효율화합니다.
-
콘텐츠 생성: 블로그 게시물 작성, 소셜 미디어 콘텐츠 생성, 광고 카피 작성 등을 자동화합니다.
-
코드 생성: 코드 작성, 디버깅, 테스트, 배포 등 개발 프로세스를 자동화합니다.
결론: LLM 에이전트, 소프트웨어 개발의 미래를 엿보다
LLM 에이전트는 단순한 생산성 도구를 넘어 소프트웨어 개발 방식에 혁신적인 변화를 가져올 잠재력을 지니고 있습니다. 개발자는 LLM 에이전트를 활용함으로써 이전보다 훨씬 복잡하고 지능적인 애플리케이션을 더욱 빠르고 효율적으로 개발할 수 있게 됩니다.
이 글에서 소개해드린 내용은 현재 시점에서 LLM 활용의 한 단면일 뿐입니다. 앞으로 AI 에이전트는 더욱 발전하여 마치 인간처럼 스스로 판단하고 행동하는, 상상 속의 인공지능 비서와 같은 역할을 수행하며 우리의 기대를 뛰어넘는 혁신을 가져올 것입니다.
이 글이 LLM 에이전트에 대한 이해를 높이고, 실제 개발에 활용하는 데 유용한 인사이트를 제공했기를 바랍니다. 끊임없이 발전해나가는 LLM 에이전트 기술에 대해서 앞으로도 유익한 정보와 인사이트를 전달해 드릴 수 있도록 준비해서 돌아오겠습니다.
