Вызов инструмента , также известный как вызов функции , представляет собой структурированный способ дать LLM возможность отправлять запросы обратно к приложению, которое его вызвало. Вы определяете инструменты, которые хотите сделать доступными для модели, и модель будет отправлять запросы инструментов вашему приложению по мере необходимости для выполнения заданных вами подсказок.
Варианты использования вызова инструментов обычно делятся на несколько тем:
Предоставление LLM доступа к информации, с которой он не был обучен
- Часто меняющаяся информация, например цена акций или текущая погода.
- Информация, относящаяся к вашему домену приложения, например информация о продукте или профили пользователей.
Обратите внимание на совпадение с генерацией с расширенным поиском (RAG), которая также позволяет LLM интегрировать фактическую информацию в свои генерации. RAG — более тяжелое решение, которое лучше всего подходит, когда у вас есть большой объем информации или когда информация, наиболее релевантная для подсказки, неоднозначна. С другой стороны, если вызов функции или поиск в базе данных — это все, что необходимо для получения информации, необходимой LLM, более подходящим является вызов инструмента.
Введение степени детерминизма в рабочий процесс LLM
- Выполнение вычислений, которые LLM не может выполнить самостоятельно.
- Принуждение LLM генерировать дословный текст при определенных обстоятельствах, например, при ответе на вопрос об условиях обслуживания приложения.
Выполнение действия по инициативе LLM
- Включение и выключение света в домашнем помощнике на базе LLM
- Резервирование столиков в ресторанном агенте на базе LLM
Прежде чем начать
Если вы хотите запустить примеры кода на этой странице, сначала выполните действия, описанные в руководстве по началу работы . Во всех примерах предполагается, что вы уже настроили проект с установленными зависимостями Genkit.
На этой странице обсуждается одна из расширенных функций абстракции модели Genkit, поэтому, прежде чем углубляться в нее, вам следует ознакомиться с содержимым на странице «Генерация контента с помощью моделей ИИ» . Вы также должны быть знакомы с системой Genkit для определения схем ввода и вывода, которая обсуждается на странице «Потоки» .
Обзор вызова инструментов
На высоком уровне вот как выглядит типичное взаимодействие вызова инструмента с LLM:
- Вызывающее приложение отправляет LLM запрос, а также включает в запрос список инструментов, которые LLM может использовать для генерации ответа.
- LLM либо генерирует полный ответ, либо генерирует запрос на вызов инструмента в определенном формате.
- Если вызывающий абонент получает полный ответ, запрос выполняется и взаимодействие завершается; но если вызывающая сторона получает вызов инструмента, она выполняет любую подходящую логику и отправляет новый запрос в LLM, содержащий исходное приглашение или его вариацию, а также результат вызова инструмента.
- LLM обрабатывает новое приглашение, как на шаге 2.
Чтобы это работало, необходимо выполнить несколько требований:
- Модель должна быть обучена отправлять запросы к инструментам, когда необходимо выполнить запрос. Большинство более крупных моделей, предоставляемых через веб-API, таких как Gemini, могут это сделать, но более мелкие и более специализированные модели часто не могут. Genkit выдаст ошибку, если вы попытаетесь предоставить инструменты модели, которая ее не поддерживает.
- Вызывающее приложение должно предоставить модели определения инструментов в ожидаемом формате.
- Вызывающее приложение должно предложить модели сгенерировать запросы вызова инструмента в формате, ожидаемом приложением.
Вызов инструмента с помощью Genkit
Genkit предоставляет единый интерфейс для вызова инструментов с моделями, которые его поддерживают. Каждый плагин модели гарантирует соблюдение двух последних критериев, упомянутых в предыдущем разделе, а функция genkit.Generate()
автоматически выполняет цикл вызова инструмента, описанный ранее.
Поддержка модели
Поддержка вызова инструментов зависит от модели, API модели и плагина Genkit. Обратитесь к соответствующей документации, чтобы определить, будет ли поддерживаться вызов инструментов. Кроме того:
- Genkit выдаст ошибку, если вы попытаетесь предоставить инструменты модели, которая ее не поддерживает.
- Если плагин экспортирует ссылки на модели, свойство
ModelInfo.Supports.Tools
укажет, поддерживает ли он вызов инструментов.
Определение инструментов
Используйте функцию genkit.DefineTool()
для записи определений инструментов:
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);
})
}
Синтаксис здесь выглядит так же, как синтаксис genkit.DefineFlow()
; однако вы должны написать описание. Будьте особенно внимательны к формулировке и информативности описания, поскольку для LLM жизненно важно принять решение использовать его надлежащим образом.
Использование инструментов
Включите определенные инструменты в свои подсказки для создания контента.
Генерировать
resp, err := genkit.Generate(ctx, g,
ai.WithPrompt("What is the weather in San Francisco?"),
ai.WithTools(getWeatherTool),
)
ОпределитьПодсказку
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"}),
)
Подскажите файл
---
system: "Answer questions using the tools you have."
tools: [getWeather]
input:
schema:
location: string
---
What is the weather in {{location}}?
Затем вы можете выполнить приглашение в своем коде следующим образом:
// 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 автоматически обработает вызов инструмента, если LLM потребуется использовать инструмент getWeather
для ответа на запрос.
Явная обработка вызовов инструментов
Если вы хотите получить полный контроль над этим циклом вызова инструментов, например, для применения более сложной логики, установите для параметра WithReturnToolRequests()
значение true
. Теперь вы обязаны обеспечить выполнение всех запросов инструментов:
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)
}