Skip to main content
Assistant API (Deprecated)

Function calling (Deprecated)

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.

Início rápido

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.

Antes de começar

Instale as bibliotecas de dependência necessárias, como requests e dashscope, executando o seguinte comando:
pip install requests dashscope

Etapa 1: Crie a função "translate_text"

Primeiro, crie uma função de tradução simples. Para fins de demonstração, esta função usa uma tabela de tradução predefinida.
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.

Etapa 2: Descreva a função "translate_text"

Descreva a função translate_text para o agente. O agente usa essa descrição para chamar a função corretamente.
from dashscope import Assistants, Messages, Runs, Threads
import json

# Define the translation tool
translation_tool = {
    "type": "function",
    "function": {
        "name": "translate_text",
        "description": "Translates text into the specified target language",
        "parameters": {
            "type": "object",
            "properties": {
                "text": {
                    "type": "string",
                    "description": "The text to translate"
                },
                "target_language": {
                    "type": "string",
                    "description": "The target language code (for example, 'zh', 'es', or 'ja')"
                }
            },
            "required": ["text", "target_language"]
        }
    }
}
from dashscope import Assistants, Messages, Runs, Threads
import json
import dashscope
dashscope.base_http_api_url = 'https://dashscope-intl.aliyuncs.com/api/v1'
# Define the translation tool
translation_tool = {
    "type": "function",
    "function": {
        "name": "translate_text",
        "description": "Translates text into the specified target language",
        "parameters": {
            "type": "object",
            "properties": {
                "text": {
                    "type": "string",
                    "description": "The text to translate"
                },
                "target_language": {
                    "type": "string",
                    "description": "The target language code (for example, 'zh', 'es', or 'ja')"
                }
            },
            "required": ["text", "target_language"]
        }
    }
}
Explicação:
  • name: O nome da função é translate_text. O agente usa esse identificador para realizar a chamada.
  • description: Descrição da ferramenta que auxilia o agente a compreender sua finalidade.
  • parameters: Define os parâmetros da função, incluindo o texto a ser traduzido e o idioma de destino.

Etapa 3: Crie um agente

Crie uma instância de Assistant. Essa instância representa o agente que usará a ferramenta de tradução definida anteriormente.
# Create an Assistant
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]
)
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.
# Create a new thread
thread = Threads.create()

# Add a user message to the thread
Messages.create(
    thread_id=thread.id,
    role="user",
    content="Please translate 'Hello world' into Chinese."
)

# Run the Assistant
run = Runs.create(thread_id=thread.id, assistant_id=assistant.id)

# Wait for the run to complete
run = 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.
# Check if a function call is required
if 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.

Etapa 6:Obtenha a resposta do agente

Após a conclusão do processamento, recupere a resposta do agente no thread de conversa e exiba-a para o usuário.
# Get the Assistant's response
messages = Messages.list(thread_id=thread.id)
for message in messages.data:
    if message.role == "assistant":
        print(f"Assistant: {message.content[0].text.value}")

Resumo

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.
import inspect

def 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:
translation_tool = function_to_schema(translate_text)
print(json.dumps(translation_tool, indent=4, ensure_ascii=False))
A função translate_text é convertida automaticamente para:
{
    "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.
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]
)

Use saída em streaming

Antes de ler esta seção, recomendamos que você aprenda sobre o uso básico de saída em streaming .
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.
# 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 mapping
tools_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.
Function calling (Deprecated) - Alibaba Cloud Model Studio