A Assistant API oferece suporte a chamadas de função. Esse recurso permite que um agente invoque automaticamente funções externas para executar tarefas, como traduzir textos. Este tópico usa um exemplo simples de "Agente de Tradução" para ajudar você a compreender rapidamente os fundamentos das chamadas de função.
A Assistant API está sendo descontinuada. Migre para a Responses API como alternativa. A Responses API inclui diversas ferramentas integradas e oferece suporte ao gerenciamento de contexto em múltiplas interações.
Neste exemplo, você criará um agente de tradução e uma função chamada translate_text que o agente poderá invocar. Em seguida, solicite ao agente que traduza "Hello world" para chinês.
Primeiro, crie uma função de tradução simples. Para fins de demonstração, esta função usa uma tabela de tradução predefinida.
Copy
def translate_text(text, target_language): """ Translates text into the specified target language. This is a simple demonstration that uses a predefined translation. Parameters: text (str): The text to translate. target_language (str): The target language code (for example, 'zh', 'es', or 'ja'). Returns: str: The translated text or an error message. """ # A translation dictionary for demonstration. mock_translations = { ('Hello world', 'zh'): '你好世界', ('Hello world', 'es'): '¡Hola Mundo!', ('Hello world', 'ja'): 'こんにちは世界', ('How are you?', 'zh'): '你好吗?', ('How are you?', 'es'): '¿Cómo estás?', ('How are you?', 'ja'): 'お元気ですか?' } try: return mock_translations.get((text, target_language), f"Translation not found. In a production environment, a translation service would be called here.") except Exception as e: return f"Translation failed: {str(e)}"
Explicação:
Recurso de tradução: Simula uma funcionalidade de tradução usando uma tabela predefinida que permite a conversão entre vários idiomas.
Tratamento de erros: A função possui um mecanismo básico de tratamento de exceções para garantir respostas adequadas em qualquer situação.
Agora, use a Assistant API para criar um agente. Ele processará automaticamente as consultas do usuário e invocará a função translate_text definida para fornecer serviços de tradução.
Crie uma instância de Assistant. Essa instância representa o agente que usará a ferramenta de tradução definida anteriormente.
Copy
# Create an Assistantassistant = Assistants.create( model='qwen-plus', name='Translation Agent', description='An agent that can translate text between different languages', instructions='You are a translation agent. When a user requests a translation, use the translate_text function to help them.', tools=[translation_tool])
Explicação:
model: Especifica o modelo a ser usado. Este exemplo emprega o qwen-plus, compatível com compreensão de linguagem e processamento de tarefas.
name: Nome do agente. Defina o valor como "Translation Assistant".
description: Descreve o objetivo do agente: auxiliar os usuários na tradução de textos.
tools: Registra a translation_tool definida previamente, habilitando o agente a invocá-la.
Etapa 4: Crie um thread de conversa e interaja com o agente
Crie um novo thread de conversa, adicione uma mensagem de usuário e execute o agente para processar a consulta.
Copy
# Create a new threadthread = Threads.create()# Add a user message to the threadMessages.create( thread_id=thread.id, role="user", content="Please translate 'Hello world' into Chinese.")# Run the Assistantrun = Runs.create(thread_id=thread.id, assistant_id=assistant.id)# Wait for the run to completerun = Runs.wait(thread_id=thread.id, run_id=run.id)
Explicação:
Threads.create(): Inicia um novo thread de conversa para as mensagens subsequentes.
Messages.create(): Adiciona uma mensagem do usuário ao thread. Neste caso, solicita-se a tradução de "Hello world" para chinês.
Runs.create(): Aciona o início do processamento da mensagem do usuário pelo agente.
Runs.wait(): Aguarda a conclusão do processamento pelo agente.
Etapa 5: Trate a chamada de função e retorne o resultado
Se o agente precisar invocar uma ferramenta durante o processamento, a função translate_text será chamada e o resultado retornado.
Copy
# Check if a function call is requiredif run.required_action: for tool_call in run.required_action.submit_tool_outputs.tool_calls: if tool_call.function.name == "translate_text": args = json.loads(tool_call.function.arguments) translation = translate_text(args["text"], args["target_language"]) # Submit the tool output Runs.submit_tool_outputs( thread_id=thread.id, run_id=run.id, tool_outputs=[{"tool_call_id": tool_call.id, "output": translation}] ) # Wait for the new run to complete run = Runs.wait(thread_id=thread.id, run_id=run.id)
Explicação:
Verificação de chamada de função: Se o agente precisar chamar uma função, seu código verifica se a função solicitada é translate_text e executa a tradução usando a função definida anteriormente.
Envio do resultado: Envie o resultado da tradução para o agente usando Runs.submit_tool_outputs e aguarde a próxima resposta.
Após a conclusão do processamento, recupere a resposta do agente no thread de conversa e exiba-a para o usuário.
Copy
# Get the Assistant's responsemessages = Messages.list(thread_id=thread.id)for message in messages.data: if message.role == "assistant": print(f"Assistant: {message.content[0].text.value}")
Ao seguir estas etapas, você criou com sucesso um agente capaz de lidar com solicitações de tradução dos usuários e usar uma função de tradução para converter texto. A Assistant API simplifica e torna eficiente a construção de agentes complexos e orientados a tarefas.Conforme necessário, estenda os recursos do agente adicionando mais ferramentas ou modificando as instruções de comportamento.
Gere rapidamente descrições para funções de negócio
No exemplo de Início Rápido, é preciso descrever a função "translate_text" para o agente. Esse processo pode ser tedioso. Por isso, fornecemos uma função de conversão simples para ajudar você a descrever rapidamente suas funções de negócio.
Copy
import inspectdef function_to_schema(func) -> dict: # Map Python types to JSON schema types type_map = { str: "string", int: "integer", float: "number", bool: "boolean", list: "array", dict: "object", type(None): "null", } # Try to get the function's signature try: signature = inspect.signature(func) except ValueError as e: # If getting the signature fails, raise an error with the error message raise ValueError( f"Failed to get signature for function {func.__name__}: {str(e)}" ) # Initialize a dictionary to store parameter types parameters = {} # Iterate over the function's parameters and map their types for param in signature.parameters.values(): try: param_type = type_map.get(param.annotation, "string") except KeyError as e: # If the parameter's type annotation is unknown, raise an error raise KeyError( f"Unknown type annotation {param.annotation} for parameter {param.name}: {str(e)}" ) parameters[param.name] = {"type": param_type} # Create a list of required parameters (those without a default value) required = [ param.name for param in signature.parameters.values() if param.default == inspect._empty ] # Return the function's schema as a dictionary return { "type": "function", "function": { "name": func.__name__, "description": (func.__doc__ or "").strip(), # Get the function description (docstring) "parameters": { "type": "object", "properties": parameters, # Parameter types "required": required, # List of required parameters }, }, }
Por exemplo, considere a função translate_text do Início Rápido:
A função translate_text é convertida automaticamente para:
Copy
{ "type": "function", "function": { "name": "translate_text", "description": "Translates text into the specified target language.\n This is a simple demonstration that uses a predefined translation.\n\n Parameters:\n text (str): The text to translate.\n target_language (str): The target language code (for example, 'zh', 'es', or 'ja').\n\n Returns:\n str: The translated text or an error message.", "parameters": { "type": "object", "properties": { "text": { "type": "string" }, "target_language": { "type": "string" } }, "required": [ "text", "target_language" ] } }}
Agora, passe a descrição da função para o modelo.
Copy
assistant = Assistants.create( model='qwen-plus', name='Translation Agent', description='An agent that can translate text between different languages', instructions='You are a translation agent. When a user requests a translation, use the translate_text function to help them.', tools=[translation_tool])
Ao usar saída em streaming, modifique a lógica do código na Etapa 5: Trate a chamada de função e retorne o resultado. Isso ocorre porque o objeto Runs agora retorna um fluxo de eventos do Assistant.Quando o Assistant decide chamar uma função, o objeto Runs retorna o evento thread.run.requires_action e os parâmetros de entrada data.required_action.submit_tool_outputs.tool_calls fornecidos pelo Large Language Model (LLM). Nesse momento, envie a saída da função.Observe que também é necessário ativar a saída em streaming ao enviar a saída da função com run = Runs.submit_tool_outputs.
Copy
# This code is for demonstration only. Integrate it into your project after you fully understand the logic.# Assume that the assistant, thread, and message objects have been created.# Define the tool function mappingtools_map = { "translate_text": translate_text, # Translation function}run = Runs.create( thread_id=thread.id, assistant_id=assistant.id, stream=True # Enable streaming output )while True: # Add an outer loop for event, data in run: # For more information about the event stream and event data, see the Assistant API streaming output documentation. if event == 'thread.run.requires_action': # The Assistant has called a tool and is waiting for the function output. tool_outputs = [] # The method for submitting the output is similar to that in Step 5. for tool in data.required_action.submit_tool_outputs.tool_calls: name = tool.function.name args = json.loads(tool.function.arguments) output = tools_map[name](**args) tool_outputs.append({ "tool_call_id": tool.id, "output": output, }) run = Runs.submit_tool_outputs( # Submit the function output thread_id=thread.id, run_id=data.id, tool_outputs=tool_outputs, stream=True # Streaming output must also be enabled here. ) break # Break out of the current for loop. The next loop will poll the new Runs object. else: break # If the first for loop finishes normally without triggering a function call, break out of the while loop.
Note que há um loop while extra fora do loop for que processa o fluxo de eventos. Isso acontece porque o sistema gera um novo objeto Runs quando você envia a saída da função. O loop while ajuda a rastrear automaticamente o fluxo de eventos mais recente, permitindo que o Assistant continue gerando uma resposta após receber o resultado da chamada de função.