개념
함수 호출(function calling), 또는 툴 유즈(tool use)는 모델이 자연어 답변 대신 어떤 함수를 어떤 인자로 부를지를 정해진 형식으로 내놓게 하는 기능이다. 개발자는 사용할 수 있는 함수의 이름과 설명, 인자 구조를 스키마로 미리 정의해 요청에 함께 실어 보낸다. 모델은 사용자의 말을 읽고 그중 맞는 함수를 골라 인자를 채운 호출 요청을 반환한다.
여기서 핵심은 모델이 함수를 직접 실행하지 않는다는 점이다. 모델이 하는 일은 무엇을 부를지 정해 구조화된 형태로 알려 주는 데까지이고, 실제 실행은 애플리케이션 코드가 한다. 실행 결과를 다시 모델에게 넘겨 주면 모델은 그 값을 근거로 최종 답변을 만든다. 즉 모델의 호출 요청, 앱의 실행, 결과 반환, 모델의 답변으로 이어지는 왕복 구조다.
이 기능 덕분에 LLM은 학습 데이터에 없는 정보에도 손을 뻗을 수 있다. 오늘 날씨, 현재 재고, 사내 데이터베이스 조회처럼 모델이 알 수 없는 값을 함수로 가져와 답에 반영하는 식이다. 도구 연결 방식을 표준화하려는 MCP 역시 결국 이 호출 규격을 공통화하려는 시도다.
한 번에 여러 함수를 동시에 부르게 하거나, 결과를 보고 다시 다른 함수를 부르는 식으로 여러 차례 왕복하도록 만들 수도 있다. 이 왕복이 반복되면서 작업이 앞으로 나아가는 형태가 곧 에이전트의 동작이다.
쓰임새
AI 에이전트가 실제로 무언가를 해내는 수단이 바로 이 함수 호출이다. 에이전트가 목표를 향해 여러 단계를 밟아 나갈 때, 각 단계에서 실행에 해당하는 부분은 대부분 도구 호출로 이루어진다. 조회에 그치지 않고 메일 발송, 결제, 파일 수정처럼 상태를 바꾸는 함수까지 연결하는 경우도 많다.
안정적으로 쓰려면 함수 설명과 인자 스키마를 정확하게 쓰는 것이 중요하다. 모델은 그 설명만 보고 언제 부를지를 판단하므로, 설명이 모호하면 엉뚱한 상황에서 호출하거나 정작 필요한 순간에 부르지 않는다. 이름이 비슷한 함수가 여럿 있으면 특히 헷갈리므로, 각 함수가 언제 쓰이는지를 설명에 한 문장으로 못박아 두는 편이 좋다. 인자로 들어온 값은 코드 쪽에서 반드시 검증해야 한다.
실행 결과를 모델에게 돌려줄 때는 원본을 통째로 넘기기보다 필요한 부분만 추려 넘기는 편이 낫다. 조회 결과가 수백 줄이면 그대로 문맥에 쌓여 이후 판단을 흐리게 만든다. 오류가 났을 때도 실패했다고만 알리는 대신 무엇이 어떻게 잘못됐는지 문장으로 돌려주면, 모델이 인자를 고쳐 다시 시도하는 경우가 많다.
자주 하는 오해
함수 호출은 모델이 직접 실행하는 것 아닌가?
모델은 호출하겠다는 의사를 구조화된 형태로 낼 뿐이고, 실행 여부와 권한은 전적으로 애플리케이션이 통제한다. 이 지점이 가드레일을 걸 자리이기도 하다.
함수를 많이 등록할수록 똑똑해지지 않나?
후보가 많아질수록 잘못 고를 확률이 올라가고, 스키마가 길어져 토큰 비용도 함께 늘어난다.
스키마를 정의했으니 인자는 안전한 것 아닌가?
형식이 맞아도 값이 타당하다는 보장은 없다. 삭제 범위나 금액, 대상 계정처럼 위험한 인자는 코드에서 별도로 확인해야 한다. 사용자가 요청하지 않은 값이 인자에 들어오는 경우도 있으므로, 원래 요청과 대조하는 절차를 두면 더 안전하다.