도구 호출(함수 호출이라고도 함)은 LLM이 이를 호출한 애플리케이션에 다시 요청할 수 있는 기능을 제공하는 구조화된 방법입니다. 개발자는 모델에 제공할 도구를 정의하고 모델은 개발자가 제공하는 프롬프트를 실행하는 데 필요한 경우 앱에 도구를 요청합니다.
도구 호출의 사용 사례는 일반적으로 다음과 같은 몇 가지 주제에 해당합니다.
학습되지 않은 정보에 LLM이 액세스하도록 허용
- 주식 가격 또는 현재 날씨와 같이 자주 변경되는 정보
- 제품 정보 또는 사용자 프로필과 같이 앱 도메인에만 해당하는 정보
LLM이 사실 정보를 생성 과정에 통합할 수 있는 방법이기도 한 검색 증강 생성 (RAG)과 중복되는 부분에 유의하세요. RAG는 더 무거운 솔루션으로, 정보가 많거나 프롬프트와 가장 관련성이 높은 정보가 모호한 경우에 가장 적합합니다. 반면에 LLM에 필요한 정보를 가져오는 것이 간단한 함수 호출이나 데이터베이스 조회인 경우 도구 호출이 더 적절합니다.
LLM 워크플로에 결정론 정도 도입
- LLM이 자체적으로 안정적으로 완료할 수 없는 계산을 실행합니다.
- 앱 서비스 약관에 관한 질문에 답변할 때와 같이 특정 상황에서 LLM이 그대로 텍스트를 생성하도록 강제합니다.
LLM에서 시작된 경우 작업 실행
- LLM 기반 홈 어시스턴트에서 조명 켜기 및 끄기
- LLM 지원 레스토랑 상담사에서 테이블 예약
시작하기 전에
이 페이지의 코드 예시를 실행하려면 먼저 시작하기 가이드의 단계를 완료하세요. 모든 예에서는 Genkit 종속 항목이 설치된 프로젝트를 이미 설정했다고 가정합니다.
이 페이지에서는 Genkit 모델 추상화의 고급 기능 중 하나를 설명하므로 너무 깊이 들어가기 전에 AI 모델로 콘텐츠 생성 페이지의 콘텐츠를 숙지해야 합니다. 또한 입력 및 출력 스키마를 정의하는 Genkit의 시스템도 숙지해야 합니다. 이 시스템은 흐름 페이지에서 설명합니다.
도구 호출 개요
대략적으로 LLM과 일반적인 도구 호출 상호작용은 다음과 같습니다.
- 호출 애플리케이션은 요청을 포함하는 프롬프트를 LLM에 표시하고 LLM이 응답을 생성하는 데 사용할 수 있는 도구 목록도 프롬프트에 포함합니다.
- LLM은 전체 응답을 생성하거나 특정 형식의 도구 호출 요청을 생성합니다.
- 호출자가 전체 응답을 수신하면 요청이 처리되고 상호작용이 종료됩니다. 하지만 호출자가 도구 호출을 수신하면 적절한 로직을 실행하고 원래 프롬프트 또는 그 변형과 도구 호출의 결과가 포함된 새 요청을 LLM에 전송합니다.
- LLM은 2단계에서와 같이 새 프롬프트를 처리합니다.
이를 위해서는 다음과 같은 몇 가지 요구사항을 충족해야 합니다.
- 프롬프트를 완료하는 데 필요한 경우 도구 요청을 하도록 모델을 학습해야 합니다. Gemini 및 Claude와 같이 웹 API를 통해 제공되는 대부분의 대규모 모델은 이를 실행할 수 있지만 더 작고 특수화된 모델은 종종 실행할 수 없습니다. 지원하지 않는 모델에 도구를 제공하려고 하면 Genkit에서 오류가 발생합니다.
- 호출 애플리케이션은 모델에 예상되는 형식으로 도구 정의를 제공해야 합니다.
- 호출 애플리케이션은 모델에 애플리케이션이 예상하는 형식으로 도구 호출 요청을 생성하도록 프롬프트해야 합니다.
Genkit을 사용한 도구 호출
Genkit은 이를 지원하는 모델을 사용하여 도구를 호출하기 위한 단일 인터페이스를 제공합니다.
각 모델 플러그인은 위의 기준 중 마지막 두 가지가 충족되도록 하고 Genkit 인스턴스의 generate()
함수는 앞에서 설명한 도구 호출 루프를 자동으로 실행합니다.
모델 지원
도구 호출 지원은 모델, 모델 API, Genkit 플러그인에 따라 다릅니다. 관련 문서를 참고하여 도구 호출이 지원될 가능성이 있는지 확인합니다. 또한 다음 사항도 적용됩니다.
- 도구를 지원하지 않는 모델에 도구를 제공하려고 하면 Genkit에 오류가 발생합니다.
- 플러그인이 모델 참조를 내보내는 경우
info.supports.tools
속성은 도구 호출을 지원하는지 나타냅니다.
도구 정의
Genkit 인스턴스의 defineTool()
함수를 사용하여 도구 정의를 작성합니다.
import { genkit, z } from 'genkit';
import { googleAI, gemini15Flash } from '@genkit-ai/google-ai';
const ai = genkit({
plugins: [googleAI()],
model: gemini15Flash,
});
const getWeather = ai.defineTool(
{
name: 'getWeather',
description: 'Gets the current weather in a given location',
inputSchema: z.object({
location: z.string().describe('The location to get the current weather for')
}),
outputSchema: z.string(),
},
async (input) => {
// Here, we would typically make an API call or database query. For this
// example, we just return a fixed value.
return 'The current weather in ${input.location} is 63°F and sunny.';
}
);
여기의 구문은 defineFlow()
구문과 똑같지만 name
, description
, inputSchema
, outputSchema
매개변수 4개가 모두 필요합니다. 도구 정의를 작성할 때는 이러한 매개변수의 문구와 설명성에 특히 주의하세요. LLM이 사용 가능한 도구를 효과적으로 활용하는 데 매우 중요하기 때문입니다.
도구 사용
콘텐츠를 생성하는 프롬프트에 정의된 도구를 포함합니다.
생성
const response = await ai.generate({
prompt: 'What is the weather in Baltimore?',
tools: [getWeather],
});
definePrompt
const weatherPrompt = ai.definePrompt(
{
name: 'weatherPrompt',
tools: [getWeather],
},
'What is the weather in {{location}}?'
);
const response = await weatherPrompt({ location: 'Baltimore' });
프롬프트 파일
---
system: "Answer questions using the tools you have."
tools: [getWeather]
input:
schema:
location: string
---
What is the weather in {{location}}?
그런 다음 다음과 같이 코드에서 프롬프트를 실행할 수 있습니다.
// assuming prompt file is named weatherPrompt.prompt
const weatherPrompt = ai.prompt('weatherPrompt');
const response = await weatherPrompt({ location: 'Baltimore' });
채팅
const chat = ai.chat({
system: 'Answer questions using the tools you have.',
tools: [getWeather],
});
const response = await chat.send('What is the weather in Baltimore?');
// Or, specify tools that are message-specific
const response = await chat.send({
prompt: 'What is the weather in Baltimore?',
tools: [getWeather],
});
LLM이 getWeather
도구를 사용하여 프롬프트에 대답해야 하는 경우 Genkit에서 도구 호출을 자동으로 처리합니다.
도구 호출 명시적 처리
기본적으로 Genkit은 모든 도구 호출이 해결될 때까지 LLM을 반복적으로 호출합니다. 더 복잡한 로직을 적용하는 등 이 도구 호출 루프를 더 세부적으로 제어하려면 returnToolRequests
매개변수를 true
로 설정하세요.
이제 모든 도구 요청이 처리되도록 하는 것이 관리자의 책임입니다.
const getWeather = ai.defineTool(
{
// ... tool definition ...
},
async ({ location }) => {
// ... tool implementation ...
},
);
const generateOptions: GenerateOptions = {
prompt: "What's the weather like in Baltimore?",
tools: [getWeather],
returnToolRequests: true,
};
let llmResponse;
while (true) {
llmResponse = await ai.generate(generateOptions);
const toolRequests = llmResponse.toolRequests;
if (toolRequests.length < 1) {
break;
}
const toolResponses: ToolResponsePart[] = await Promise.all(
toolRequests.map(async (part) => {
switch (part.toolRequest.name) {
case 'specialTool':
return {
toolResponse: {
name: part.toolRequest.name,
ref: part.toolRequest.ref,
output: await getWeather(part.toolRequest.input),
},
};
default:
throw Error('Tool not found');
}
})
);
generateOptions.messages = llmResponse.messages;
generateOptions.prompt = toolResponses;
}