Chamada de ferramenta

A chamada de ferramenta, também conhecida como chamada de função, é uma forma estruturada de oferecer Os LLMs podem fazer solicitações de volta ao aplicativo que o chamou. Você defina as ferramentas que você quer disponibilizar ao modelo, fazer solicitações de ferramentas ao app conforme necessário para atender aos comandos.

Os casos de uso de chamada de ferramenta geralmente se enquadram em alguns temas:

Conceder a um LLM acesso a informações com as quais ele não foi treinado

  • Mudar informações com frequência, como o cardápio diário de um restaurante ou um o status do inventário da loja.
  • Informações específicas ao domínio do app, como informações do produto.

Observe a sobreposição com a geração aumentada de recuperação (RAG), que também é uma maneira de permitir que um LLM integre informações factuais às gerações. O RAG é um mais complexa e mais adequada quando você tem uma grande quantidade de informações ou as informações mais relevantes para um comando são ambíguas. Ativado por outro lado, se recuperar as informações necessárias para o LLM for uma função simples ou a pesquisa de banco de dados, a chamada de ferramenta é mais apropriada.

Como introduzir um grau de determinismo em um fluxo de trabalho de LLM

  • Realizar cálculos que o LLM não consegue concluir de maneira confiável.
  • Forçar um LLM a gerar texto literal em determinadas circunstâncias, como ao responder a uma pergunta sobre os Termos de Serviço de um app.

Executar uma ação quando iniciado por um LLM

  • Acendendo e apagando luzes em um assistente residencial com LLM
  • Como reservar reservas em um agente de restaurante com tecnologia LLM

Antes de começar

Se você quiser executar os exemplos de código nesta página, primeiro conclua as etapas em o guia de Primeiros passos. Todos os exemplos pressupõem que você já configurou um projeto com dependências do Genkit instaladas.

Esta página discute um dos recursos avançados da abstração do modelo Genkit e a função generate(). Portanto, antes de se aprofundar muito, conheça na página Como gerar conteúdo com modelos de IA. Você deve conhecer o sistema Genkit para definir esquemas de entrada e saída, que é discutido na página Fluxos.

Visão geral de chamadas de ferramentas

De modo geral, isso é o que uma interação típica de chamada de ferramenta com um LLM é semelhante a:

  1. O aplicativo de chamada envia uma solicitação ao LLM e também inclui em ao comando, uma lista das ferramentas que o LLM pode usar para gerar uma resposta.
  2. O LLM gera uma resposta completa ou uma chamada de ferramenta em um formato específico.
  3. Se o autor da chamada receber uma resposta completa, a solicitação é atendida e o a interação termina; mas se o autor da chamada recebe uma chamada de ferramenta, ele realiza qualquer lógica apropriada e envia uma nova solicitação ao LLM contendo o comando original ou alguma variação dele, bem como o resultado da chamada de ferramenta.
  4. O LLM processa o novo comando como na Etapa 2.

Para que isso funcione, vários requisitos precisam ser atendidos:

  • O modelo precisa ser treinado para fazer solicitações de ferramentas quando necessário prompt de comando. A maioria dos modelos maiores fornecidos por APIs da Web, como o Gemini e Claude, podem fazer isso, mas modelos menores e mais especializados muitas vezes não. O Genkit vai gerar um erro se você tentar fornecer ferramentas para um modelo que não apoiá-la.
  • O aplicativo de chamada precisa fornecer definições de ferramenta ao modelo na o formato esperado.
  • O aplicativo de chamada precisa pedir ao modelo que gere a chamada de ferramenta solicitações no formato esperado pelo aplicativo.

Chamadas de ferramentas com o Genkit

O Genkit fornece uma única interface para chamadas de ferramentas com modelos compatíveis. Cada plug-in de modelo garante que os dois últimos critérios acima sejam atendidos, e a função generate() executa automaticamente o loop de chamada da ferramenta descritos anteriormente.

Suporte do modelo

O suporte a chamadas de ferramentas depende do modelo, da API do modelo e do plug-in Genkit. Consulte a documentação relevante para determinar se a chamada da ferramenta provavelmente será suporte. Além disso:

  • O Genkit vai gerar um erro se você tentar fornecer ferramentas para um modelo que não apoiá-la.
  • Se o plug-in exportar referências de modelo, a propriedade info.supports.tools indica se ele oferece suporte a chamadas de ferramentas.

Como definir ferramentas

Use a função defineTool() para escrever definições de ferramentas:

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";
  }
);

A sintaxe aqui é semelhante à sintaxe defineFlow(). No entanto, os quatro os parâmetros name, description, inputSchema e outputSchema são obrigatórios. Ao redigir uma definição de ferramenta, tenha cuidado especial com a redação e a descrição desses parâmetros, já que são vitais para que o LLM e fazer uso eficaz das ferramentas disponíveis.

Incluir ferramentas com seus comandos

Depois de definir suas ferramentas, especifique-as no parâmetro de ferramentas da generate():

const llmResponse = await generate({
  model: gemini15Flash,
  prompt,
  tools: [specialTool],
});

É possível disponibilizar várias ferramentas, o LLM chamará as ferramentas conforme necessário para concluir o comando.

Processar explicitamente chamadas de ferramenta

Por padrão, o Genkit chama repetidamente o LLM até que todas as chamadas de ferramenta tenham sido resolvido. Se você quiser mais controle sobre o loop de chamada da ferramenta, por exemplo, para aplicar uma lógica mais complicada, defina o parâmetro returnToolRequests como true. Agora é sua responsabilidade garantir que todas as solicitações de ferramentas sejam atendidas:

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;
}