Roteie respostas do LLM para operações do Studio usando chamadas de função no Jitterbit Studio
Introdução
A chamada de função é uma capacidade do LLM onde, em vez de retornar texto livre, o modelo retorna uma seleção estruturada de qual função chamar e quais argumentos passar. No Studio, isso significa que o LLM pode selecionar qual operação executar em resposta a um pedido do usuário, roteando uma mensagem sobre um pagamento ausente para uma operação de notificação de RH, por exemplo, enquanto roteia uma mensagem sobre um pedido de acesso a software para uma operação de provisionamento de TI.
Este guia cobre duas abordagens para implementar esse padrão:
- Parte 1: Chamada de função formal: Defina esquemas de ferramentas em JSON, envie-os com o pedido do LLM via o conector HTTP v2, e receba uma resposta estruturada
tool_calls. Um script extrai o nome da função e os argumentos, e então despacha para a operação correta. Essa abordagem produz uma saída estruturada e confiável e é recomendada para uso em produção. - Parte 2: Roteamento baseado em prompt: Descreva as operações disponíveis como texto simples no prompt do sistema, e então analise a resposta de texto do LLM para o nome da função selecionada e despache usando uma declaração
Case. Essa abordagem não requer a criação de esquemas de ferramentas, mas depende do LLM seguir a instrução do prompt com precisão.
Este guia assume familiaridade com a atividade Prompt da OpenAI e o conector HTTP v2. Para detalhes de configuração, veja Use OpenAI para processar dados em uma operação do Studio e Chame uma API REST usando o conector HTTP v2.
Padrão de design
Ambas as abordagens compartilham o mesmo fluxo conceitual e estrutura de operação:
- O LLM recebe a mensagem do usuário junto com uma descrição das operações disponíveis (a lista de ferramentas).
- O LLM seleciona a operação apropriada e retorna um nome de função (e na Parte 1, argumentos estruturados).
- Um script do Studio extrai o nome da função e roteia a execução para a operação correspondente.
A cadeia de operações segue esta estrutura:
A operação de Prompt LLM envia a mensagem do usuário para o modelo e armazena a resposta. A operação de script Dispatcher lê a resposta, extrai o nome da função selecionada e chama a operação correspondente usando RunOperation. Cada operação de destino realiza o trabalho real para essa função.
Variáveis globais transportam o nome da função extraído e os argumentos do dispatcher para cada operação de destino.
Parte 1: Chamada de função formal
A API de Conclusões de Chat da OpenAI aceita um array tools no corpo da solicitação. Cada entrada no array define uma função disponível: seu nome, uma descrição que o modelo usa para decidir quando chamá-la, e um objeto JSON Schema descrevendo seus parâmetros. Quando o modelo seleciona uma função, ele retorna um array tool_calls em sua resposta em vez de preencher message.content.
Etapa 1: Definir os esquemas de ferramentas
Cada esquema de ferramenta é um objeto JSON com três campos: name, description e parameters.
O name é o identificador que seu script dispatcher verificará. A description informa ao modelo quando chamar esta ferramenta: escreva como uma declaração clara do propósito da função. O objeto parameters segue as convenções do JSON Schema: liste cada parâmetro sob properties, defina seu type e description, e liste os parâmetros obrigatórios sob required.
Exemplos de esquemas para duas ferramentas (uma para notificar o RH, uma para notificar o TI):
[
{
"type": "function",
"function": {
"name": "notify_hr",
"description": "Send a message to the HR team, for example about onboarding, payroll, or leave requests.",
"parameters": {
"type": "object",
"properties": {
"email_body": {
"type": "string",
"description": "The full text of the message to send."
},
"recipient_name": {
"type": "string",
"description": "The name of the HR contact to address."
}
},
"required": ["email_body", "recipient_name"]
}
}
},
{
"type": "function",
"function": {
"name": "notify_it",
"description": "Send a message to the IT team, for example about software access, hardware, or account issues.",
"parameters": {
"type": "object",
"properties": {
"email_body": {
"type": "string",
"description": "The full text of the message to send."
},
"issue_type": {
"type": "string",
"description": "A short label for the type of issue, for example 'access request' or 'hardware fault'."
}
},
"required": ["email_body", "issue_type"]
}
}
}
]
Dica
Escreva descrições de ferramentas do ponto de vista do modelo: descreva a situação em que o modelo deve chamar essa função, não o que a operação subjacente faz. Descrições vagas fazem com que o modelo selecione a ferramenta errada.
Passo 2: Incluir as ferramentas na solicitação LLM
Use uma atividade HTTP v2 POST para chamar o endpoint de Completions do Chat da OpenAI (https://api.openai.com/v1/chat/completions). Na transformação do corpo da solicitação, construa a solicitação JSON completa como uma string e mapeie-a para o campo body.
Um corpo de solicitação representativo, usando uma variável de projeto para a chave da API e variáveis globais para a mensagem do usuário e o histórico da conversa:
{
"model": "gpt-4",
"messages": [
{
"role": "system",
"content": "You are a helpful assistant. Use the available functions to handle the user's request."
},
{
"role": "user",
"content": "$user_message"
}
],
"tools": <tools array from Step 1>,
"tool_choice": "auto"
}
Definir tool_choice como "auto" permite que o modelo decida se deve chamar uma função ou retornar uma resposta em texto simples. Para forçar uma chamada de função, defina tool_choice como "required".
Para configuração de conexão e autenticação HTTP v2, consulte Chamar uma API REST usando o conector HTTP v2.
Passo 3: Analisar a resposta tool_calls
Quando o modelo seleciona uma ferramenta, o corpo da resposta inclui um array tool_calls em choices[0].message. Adicione um nó de script de transformação para extrair o nome da função e os argumentos e armazená-los como variáveis globais para uso nas operações de despachante e alvo.
Na transformação que segue a atividade HTTP v2, adicione um nó de script no nível raiz:
<trans>
// Check whether the model made a function call
toolCalls = Source.choices[0].message.tool_calls;
If(Length(toolCalls) > 0,
// Extract the function name and parse the arguments JSON string
$function_name = toolCalls[0].function.name;
args = JSONParser(toolCalls[0].function.arguments);
// Store individual arguments as global variables for downstream operations
$arg_email_body = args["email_body"];
$arg_recipient_name = args["recipient_name"];
$arg_issue_type = args["issue_type"];
WriteToOperationLog("Function selected: " + $function_name);
,
// No function call: model returned plain text
$function_name = "";
WriteToOperationLog("No function call in response");
);
</trans>
JSONParser converte a string arguments (um objeto JSON) em um dicionário. As chaves em args correspondem aos nomes dos parâmetros definidos no esquema da ferramenta.
Nota
tool_calls está ausente da resposta quando o modelo retorna texto simples em vez de chamar uma função. O ramo $function_name = "" lida com esse caso para que o script do despachante na próxima etapa possa direcioná-lo para uma operação de fallback.
Passo 4: Despachar para a operação alvo
Crie uma segunda operação, encadeada ao sucesso da operação de Prompt LLM. Esta operação contém uma única ferramenta de Script que lê function_name e chama a operação alvo apropriada:
Case($function_name == "notify_hr",
RunOperation("<TAG>operation:Notify HR</TAG>");,
$function_name == "notify_it",
RunOperation("<TAG>operation:Notify IT</TAG>");,
true,
// Default case: unknown function name or plain text response
WriteToOperationLog("No matching function for: " + $function_name)
);
RunOperation executa a operação de destino de forma síncrona. As variáveis globais definidas na Etapa 3 (arg_email_body, arg_recipient_name, etc.) estão disponíveis dentro de cada operação de destino.
Dica
Para armazenar o histórico de conversas entre as interações, use Cloud Datastore para persistir o array de mensagens entre as execuções da operação. Se você enviar prompts através de um conector LLM nativo em vez de HTTP v2, os conectores OpenAI, Azure OpenAI e Amazon Bedrock podem reter o contexto do chat entre as operações para você em grupos de agentes na nuvem (com agentes privados retendo isso na memória).
Parte 2: Roteamento baseado em prompts
Essa abordagem incorpora a lista de operações disponíveis diretamente no prompt do sistema como texto simples, instruindo o modelo a responder com exatamente um nome de função e usa uma declaração Case para despachar. Nenhum JSON de esquema de ferramenta é necessário.
Etapa 1: Construir o manifesto da ferramenta
Use AddToDict para registrar cada operação disponível. Armazene a descrição e a lista de parâmetros opcionais juntas em uma única string, separadas por um caractere |:
AddToDict($tools_dict, "get_account_info",
"Retrieve account details for a customer.|(account_name)");
AddToDict($tools_dict, "create_ticket",
"Create a support ticket for a reported issue.|(subject,description)");
AddToDict($tools_dict, "send_notification",
"Send a notification message to a user.|(user_id,message)");
AddToDict($tools_dict, "unknown_route",
"Ask the user for clarification when the request is ambiguous.");
Inclua uma entrada unknown_route para que o modelo tenha uma opção de fallback segura quando a intenção do usuário não estiver clara.
Etapa 2: Converter o manifesto em texto
Use GetKeys para iterar sobre o dicionário e construir uma lista em texto simples para incorporar no prompt do sistema:
toolText = "";
keys = GetKeys($tools_dict);
i = 0;
while(i < Length(keys),
key = keys[i];
entry = $tools_dict[key];
desc = Split(entry, "|")[0];
params = Split(entry, "|")[1];
toolText = toolText + "- " + key + ": " + desc;
If(Length(params) > 0,
toolText = toolText + " Parameters: " + params
);
toolText = toolText + "\n";
i++
);
$tools_text = toolText;
Etapa 3: Incluir o manifesto no prompt do sistema
No corpo da solicitação LLM, insira tools_text na mensagem do sistema e instrua o modelo a responder com exatamente um nome de função. Inclua a mensagem do usuário como uma mensagem de papel user separada para que o modelo tenha uma solicitação a ser roteada. A instrução do sistema deve ser explícita: o modelo precisa saber o formato de saída esperado.
{
"model": "gpt-4",
"messages": [
{
"role": "system",
"content": "You are a routing assistant. Based on the user's message, respond with exactly one function name from the list below. Do not include any explanation or other text.\n\nAvailable functions:\n$tools_text"
},
{
"role": "user",
"content": "$user_message"
}
]
}
A mensagem do sistema carrega a instrução de roteamento e o manifesto da ferramenta (tools_text); a mensagem do usuário carrega a solicitação real (user_message) que o modelo roteia.
Nota
O roteamento baseado em prompt depende do modelo seguir a instrução de formato de saída. Se o modelo retornar mais do que o nome da função, a chamada Trim na Etapa 4 remove espaços em branco ao redor, mas não pode corrigir respostas de várias palavras ou formatadas. Teste o prompt com o modelo alvo antes de implantar.
Etapa 4: Extraia o nome da função da resposta
O modelo retorna o nome da função em choices[0].message.content. Adicione um nó de script na transformação após a atividade HTTP v2 para armazená-lo como uma variável global:
<trans>
$function_name = Trim(Source.choices[0].message.content);
WriteToOperationLog("Routing to: " + $function_name);
</trans>
Trim remove quaisquer espaços em branco à frente ou atrás da resposta do modelo.
Etapa 5: Despachar para a operação alvo
Encadeie uma operação de despachante no sucesso da operação LLM Prompt, usando o mesmo padrão Case que a Parte 1:
Case($function_name == "get_account_info",
RunOperation("<TAG>operation:Get Account Info</TAG>");,
$function_name == "create_ticket",
RunOperation("<TAG>operation:Create Ticket</TAG>");,
$function_name == "send_notification",
RunOperation("<TAG>operation:Send Notification</TAG>");,
$function_name == "unknown_route",
RunOperation("<TAG>operation:Ask For Clarification</TAG>");,
true,
WriteToOperationLog("Unrecognised function name: " + $function_name)
);
O ramo final true captura qualquer resposta que não corresponda a um nome de função conhecido (por exemplo, se o modelo retornar uma frase em vez de uma única palavra-chave).
Verifique a integração
Verificando a Parte 1 (chamada de função formal)
-
Implante e execute a operação LLM Prompt com uma mensagem do usuário que deve acionar uma ferramenta específica (por exemplo, uma mensagem sobre um problema de folha de pagamento para acionar
notify_hr). -
No logs de operação, confirme que a entrada do log mostra
Função selecionada: notify_hr(ou o nome da função esperado). -
Confirme que a operação do despachante foi executada e que a operação de destino correspondente (
Notificar RH) foi concluída com sucesso. -
Envie uma mensagem que não deve acionar nenhuma ferramenta (por exemplo, uma saudação geral). Confirme que o log mostra
Nenhuma chamada de função em respostae que nenhuma operação de destino foi chamada inesperadamente. -
Se o modelo consistentemente selecionar a ferramenta errada, revise as descrições das ferramentas. Descrições que se sobrepõem ou carecem de especificidade fazem com que o modelo adivinhe incorretamente.
-
Se
JSONParsergerar um erro, confirme quechoices[0].message.tool_calls[0].function.argumentsé uma string JSON válida na resposta bruta. Um campo de argumentos vazio ou malformado geralmente indica um problema de configuração do modelo ou do prompt.
Verificando a Parte 2 (roteamento baseado em prompt)
-
Implante e execute a operação LLM Prompt com uma mensagem que mapeie claramente para uma função disponível.
-
No logs de operação, confirme que a entrada do log mostra
Roteando para:seguida pelo nome da função esperado como uma única palavra. -
Confirme que a operação de destino correspondente foi executada e concluída com sucesso.
-
Envie uma mensagem ambígua. Confirme que o log mostra
Roteando para: unknown_routee que a operação de esclarecimento foi executada. -
Se o ramo final
truefor acionado inesperadamente, inspecione o valor bruto dechoices[0].message.contentno log. Uma resposta contendo texto extra (como"Eu chamaria: get_account_info") indica que a instrução do prompt do sistema precisa ser mais direta. Adicione um exemplo explícito ao prompt, como:Exemplo de resposta: get_account_info.