Wywoływanie narzędzi, nazywane też wywołaniem funkcji, to ustrukturyzowany sposób przekazywania Możliwość wysyłania żądań z powrotem do aplikacji, która je wywołała. Ty narzędzia, które chcesz udostępnić modelowi, w razie potrzeby wysyłać do aplikacji żądania narzędzi, aby spełnić Twoje oczekiwania.
Przypadki użycia funkcji wywoływania narzędzi można ogólnie podzielić na kilka tematów:
Przyznawanie LLM dostępu do informacji, na których nie był trenowany
- często zmieniające się informacje, takie jak menu dnia restauracji czy stanie asortymentu w Twoim sklepie.
- Informacje dotyczące domeny aplikacji, np. informacje o produkcie.
Zwróć uwagę na pokrywanie się z generowaniem rozszerzonego przez wyszukiwanie (RAG), które jest też umożliwia LLM integrowanie faktów z pokoleniami. RAG to cięższe rozwiązanie, które najlepiej sprawdza się w przypadku dużej czy informacje, które są najważniejsze w odniesieniu do promptu, są niejednoznaczne. Wł. Z drugiej strony przy pobieraniu informacji potrzebnych LLM jest funkcja wywołaniem usługi lub bazą danych, bardziej odpowiednie są wywołania narzędzia.
Wprowadzenie pewnego determinizmu do przepływu pracy LLM
- wykonywanie obliczeń, których LLM nie jest w stanie w niezawodny sposób wykonać.
- Wymuszanie generowania przez LLM dosłownego tekstu w określonych okolicznościach, takich jak w odpowiedzi na pytanie o warunki korzystania z aplikacji.
Wykonywanie działania po zainicjowaniu przez LLM
- Włączanie i wyłączanie oświetlenia w asystencie domowym z technologią LLM
- Rezerwowanie stolików w restauracji opartej na LLM
Zanim zaczniesz
Jeśli chcesz uruchomić przykładowe fragmenty kodu z tej strony, najpierw wykonaj czynności podane w Pierwsze kroki. We wszystkich przykładach zakładamy, że ma już skonfigurowany projekt z zainstalowanymi zależnościami Genkit.
Na tej stronie omawiamy jedną z zaawansowanych funkcji abstrakcji modelu Genkit generate(), więc zanim zagłębimy się w temat funkcji, zapoznaj się z treści dostępnych na stronie Generowanie treści za pomocą modeli AI. Zalecenia Warto też znać system Genkit do definiowania schematów wejściowych i wyjściowych Zostało to omówione na stronie Przepływy.
Omówienie funkcji wywoływania narzędzi
Ogólnie to taka interakcja z LLM przy użyciu funkcji wywoływania narzędzi wygląda jak:
- Aplikacja wywołująca wysyła do LLM żądanie, a także zawiera listę narzędzi, których LLM może użyć do wygenerowania odpowiedzi.
- LLM generuje pełną odpowiedź lub wywołanie narzędzia w określonym formacie.
- Jeśli rozmówca otrzyma pełną odpowiedź, żądanie zostanie zrealizowane, zakończenie interakcji; ale jeśli rozmówca otrzyma wywołanie narzędzia, za pomocą dowolnej logiki i wysyła nowe żądanie do LLM zawierające oryginalny prompt lub jego odmianę, a także wynik jako wywołania narzędzia.
- LLM obsługuje nowy prompt tak jak w kroku 2.
Aby to działało, musi być spełnione kilka warunków:
- Model musi być wytrenowany tak, aby wysyłał żądania narzędzi, gdy jest wymagane do wykonania . Większość większych modeli udostępnianych przez internetowe interfejsy API, takie jak Gemini i Claude, ale mniejsze i bardziej wyspecjalizowane modele często nie są w stanie tego zrobić. Genkit zwróci błąd, jeśli spróbujesz udostępnić narzędzia modelowi, który tego nie robi. są obsługiwane.
- Aplikacja wywołująca musi dostarczyć definicje narzędzi dla modelu w funkcji w oczekiwanym formacie.
- Aplikacja wywołująca musi poprosić model o wygenerowanie wywołania narzędzia w oczekiwanym przez aplikację formacie.
Wywoływanie narzędzi w usłudze Genkit
Genkit to pojedynczy interfejs do wywoływania narzędzi z modelami, które go obsługują.
Każda wtyczka modelu zapewnia spełnienie 2 ostatnich z powyższych kryteriów.
funkcja generate()
automatycznie wykonuje pętlę wywołania narzędzia
omówiono to wcześniej.
Obsługa modelu
Obsługa wywoływania narzędzi zależy od modelu, interfejsu API modelu i wtyczki Genkit. Zapoznaj się z odpowiednią dokumentacją, aby określić, czy wywołanie narzędzia może być obsługiwane. Dodatkowo:
- Genkit zwróci błąd, jeśli spróbujesz udostępnić narzędzia modelowi, który tego nie robi. są obsługiwane.
- Jeśli wtyczka eksportuje odwołania do modelu, właściwość
info.supports.tools
wskazuje, czy obsługuje ona wywołania narzędzi.
Narzędzia do definiowania
Za pomocą funkcji defineTool()
wpisz definicje narzędzi:
const specialToolInputSchema = z.object({ meal: z.enum(["breakfast", "lunch", "dinner"]) });
const specialTool = defineTool(
{
name: "specialTool",
description: "Retrieves today's special for the given meal",
inputSchema: specialToolInputSchema,
outputSchema: z.string(),
},
async ({ meal }): Promise<string> => {
// Retrieve up-to-date information and return it. Here, we just return a
// fixed value.
return "Baked beans on toast";
}
);
Składnia używana w tym miejscu wygląda tak samo jak składnia defineFlow()
. jednak wszystkie cztery
parametry name
, description
, inputSchema
i outputSchema
są
Podczas tworzenia definicji narzędzia zwróć szczególną uwagę na sformułowania
opisowych parametrów, ponieważ są one niezbędne dla LLM do
efektywne wykorzystanie dostępnych narzędzi.
Dodawanie narzędzi do promptów
Po zdefiniowaniu narzędzi określ je w parametrze narzędzi
generate()
:
const llmResponse = await generate({
model: gemini15Flash,
prompt,
tools: [specialTool],
});
Możesz udostępnić wiele narzędzi, LLM w razie potrzeby będzie wywoływać narzędzia aby dokończyć prompt.
Bezpośrednia obsługa wywołań narzędzi
Domyślnie Genkit wywołuje LLM wielokrotnie, aż każde wywołanie narzędzia
. Jeśli chcesz mieć większą kontrolę nad pętlą wywołań narzędzia, na przykład
zastosuj bardziej skomplikowaną logikę, ustaw parametr returnToolRequests
na true
.
Teraz to Ty musisz zadbać o realizację wszystkich żądań narzędzia:
let generateOptions: GenerateOptions = {
model: gemini15Flash,
prompt,
tools: [specialTool],
returnToolRequests: true,
};
let llmResponse;
while (true) {
llmResponse = await 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 specialTool(specialToolInputSchema.parse(part.toolRequest?.input)),
},
};
default:
throw Error('Tool not found');
}
}));
generateOptions.history = llmResponse.toHistory();
generateOptions.prompt = toolResponses;
}