Le chiamate di strumenti, note anche come chiamate di funzioni, sono un modo strutturato per consentire agli LLM di inviare richieste all'applicazione che li ha chiamati. Tu definisci gli strumenti che vuoi rendere disponibili al modello, che farà richieste di strumenti alla tua app in base alle necessità per soddisfare i prompt che gli fornisci.
I casi d'uso delle chiamate allo strumento rientrano generalmente in alcuni temi:
Fornire a un LLM l'accesso a informazioni con cui non è stato addestrato
- Informazioni che cambiano di frequente, ad esempio il prezzo di un'azione o il meteo corrente.
- Informazioni specifiche per il dominio della tua app, ad esempio informazioni sui prodotti o profili degli utenti.
Tieni presente la sovrapposizione con la retrieval-augmented generation (RAG), che è anche un modo per consentire a un LLM di integrare informazioni oggettive nelle sue generazioni. La RAG è una soluzione più complessa, adatta quando hai una grande quantità di informazioni o quando le informazioni più pertinenti per un prompt sono ambigue. D'altra parte, se è sufficiente una chiamata di funzione o una ricerca nel database per recuperare le informazioni di cui ha bisogno l'LLM, la chiamata dello strumento è più appropriata.
Introduzione di un grado di determinismo in un flusso di lavoro LLM
- Eseguire calcoli che l'LLM non è in grado di completare in modo affidabile.
- Forzare un LLM a generare un testo letterale in determinate circostanze, ad esempio quando si risponde a una domanda sui termini di servizio di un'app.
Eseguire un'azione quando viene avviata da un modello LLM
- Accendere e spegnere le luci in un'assistente domestica basata su LLM
- Prenotazione di tavoli in un agente di ristoranti basato su LLM
Prima di iniziare
Se vuoi eseguire gli esempi di codice in questa pagina, completa prima i passaggi descritti nella guida Inizia. Tutti gli esempi presuppongono che tu abbia già configurato un progetto con le dipendenze Genkit installate.
Questa pagina illustra una delle funzionalità avanzate dell'astrazione del modello di Genkit, quindi, prima di addentrarti troppo in profondità, devi conoscere i contenuti della pagina Generare contenuti con i modelli di IA. Inoltre, devi conoscere il sistema di Genkit per la definizione degli schemi di input e output, descritto nella pagina Fluidi.
Panoramica delle chiamate allo strumento
A livello generale, un'interazione di chiamata dello strumento con un LLM è simile alla seguente:
- L'applicazione chiamante presenta all'LLM una richiesta e include anche nel prompt un elenco di strumenti che l'LLM può utilizzare per generare una risposta.
- L'LLM genera una risposta completa o una richiesta di chiamata allo strumento in un formato specifico.
- Se il chiamante riceve una risposta completa, la richiesta viene soddisfatta e l'interazione termina. Se invece il chiamante riceve una chiamata allo strumento, esegue la logica appropriata e invia una nuova richiesta all'LLM contenente il prompt originale o una sua variante, nonché il risultato della chiamata allo strumento.
- L'LLM gestisce il nuovo prompt come indicato nel passaggio 2.
Affinché questa operazione funzioni, devono essere soddisfatti diversi requisiti:
- Il modello deve essere addestrato a effettuare richieste di strumenti quando è necessario per completare un prompt. La maggior parte dei modelli più grandi forniti tramite API web come Gemini può farlo, ma spesso i modelli più piccoli e specializzati non possono. Genkit genererà un errore se provi a fornire strumenti a un modello che non lo supporta.
- L'applicazione chiamante deve fornire al modello le definizioni degli strumenti nel formato che prevede.
- L'applicazione chiamante deve chiedere al modello di generare richieste di chiamata allo strumento nel formato previsto dall'applicazione.
Chiamate di strumenti con Genkit
Genkit fornisce un'unica interfaccia per le chiamate allo strumento con i modelli che lo supportano.
Ogni plug-in del modello garantisce che gli ultimi due criteri menzionati nella sezione precedente siano soddisfatti e la funzione genkit.Generate()
esegue automaticamente il loop di chiamata dello strumento descritto in precedenza.
Supporto dei modelli
Il supporto delle chiamate allo strumento dipende dal modello, dall'API del modello e dal plug-in Genkit. Consulta la documentazione pertinente per stabilire se è probabile che le chiamate allo strumento siano supportate. Inoltre:
- Genkit genera un errore se provi a fornire strumenti a un modello che non li supporta.
- Se il plug-in esporta i riferimenti ai modelli, la proprietà
ModelInfo.Supports.Tools
indicarà se supporta le chiamate allo strumento.
Strumenti di definizione
Utilizza la funzione genkit.DefineTool()
per scrivere le definizioni degli strumenti:
import (
"context"
"log"
"github.com/firebase/genkit/go/ai"
"github.com/firebase/genkit/go/genkit"
"github.com/firebase/genkit/go/plugins/googlegenai"
)
func main() {
ctx := context.Background()
g, err := genkit.Init(ctx,
genkit.WithPlugins(&googlegenai.GoogleAI{}),
genkit.WithDefaultModel("googleai/gemini-2.0-flash"),
)
if err != nil {
log.Fatal(err)
}
getWeatherTool := genkit.DefineTool(
g, "getWeather", "Gets the current weather in a given location",
func(ctx *ai.ToolContext, location string) (string, error) {
// Here, we would typically make an API call or database query. For this
// example, we just return a fixed value.
return fmt.Sprintf("The current weather in %s is 63°F and sunny.", location);
})
}
La sintassi è la stessa di genkit.DefineFlow()
, ma devi scrivere una descrizione. Presta particolare attenzione alla formulazione e alla descrittività della descrizione, in quanto è fondamentale per l'LLM decidere di utilizzarla in modo appropriato.
Utilizzare gli strumenti
Includi strumenti definiti nei prompt per generare contenuti.
Genera
resp, err := genkit.Generate(ctx, g,
ai.WithPrompt("What is the weather in San Francisco?"),
ai.WithTools(getWeatherTool),
)
DefinePrompt
weatherPrompt, err := genkit.DefinePrompt(g, "weatherPrompt",
ai.WithPrompt("What is the weather in {{location}}?"),
ai.WithTools(getWeatherTool),
)
if err != nil {
log.Fatal(err)
}
resp, err := weatherPrompt.Execute(ctx,
with.Input(map[string]any{"location": "San Francisco"}),
)
File dei prompt
---
system: "Answer questions using the tools you have."
tools: [getWeather]
input:
schema:
location: string
---
What is the weather in {{location}}?
Poi puoi eseguire il prompt nel codice come segue:
// Assuming prompt file named weatherPrompt.prompt exists in ./prompts dir.
weatherPrompt := genkit.LookupPrompt("weatherPrompt")
if weatherPrompt == nil {
log.Fatal("no prompt named 'weatherPrompt' found")
}
resp, err := weatherPrompt.Execute(ctx,
ai.WithInput(map[string]any{"location": "San Francisco"}),
)
Genkit gestirà automaticamente la chiamata allo strumento se l'LLM deve utilizzare lo strumentogetWeather
per rispondere al prompt.
Gestire esplicitamente le chiamate allo strumento
Se vuoi il controllo completo su questo ciclo di chiamata dello strumento, ad esempio per applicare una logica più complessa, imposta l'opzione WithReturnToolRequests()
su true
. Ora è tua responsabilità garantire che tutte le richieste di strumenti vengano soddisfatte:
getWeatherTool := genkit.DefineTool(
g, "getWeather", "Gets the current weather in a given location",
func(ctx *ai.ToolContext, location string) (string, error) {
// Tool implementation...
})
resp, err := genkit.Generate(ctx, g,
ai.WithPrompt("What is the weather in San Francisco?"),
ai.WithTools(getWeatherTool),
ai.WithReturnToolRequests(true),
)
if err != nil {
log.Fatal(err)
}
parts := []*Part{}
for _, req := range resp.ToolRequests() {
tool := genkit.LookupTool(g, req.Name)
if tool == nil {
log.Fatalf("tool %q not found", req.Name)
}
output, err := tool.RunRaw(ctx, req.Input)
if err != nil {
log.Fatalf("tool %q execution failed: %v", err)
}
parts = append(parts,
ai.NewToolResponsePart(&ai.ToolResponse{
Name: req.Name,
Ref: req.Ref,
Output: output,
}))
}
resp, err = genkit.Generate(ctx, g,
ai.WithMessages(resp.History()..., NewMessage(ai.RoleTool, nil, parts...)),
)
if err != nil {
log.Fatal(err)
}