Skip to main content
Assistant API (Deprecated)

Assistant API best practices (deprecated)

Para desenvolver aplicações de modelos de linguagem grandes (LLM) em ambiente de produção com a Assistant API, domine as operações básicas dos componentes Assistant, Thread, Message, Run e Step. Compreenda também tópicos avançados como gerenciamento de ciclo de vida, armazenamento de dados, workspaces e alta concorrência.

A Assistant API está sendo descontinuada. Recomendamos a migração para a Responses API. Ela serve como solução alternativa com várias ferramentas integradas e suporte ao gerenciamento de contexto de múltiplas interações.

1. Componentes principais

Ao criar aplicações conversacionais com a Assistant API, gerencie os seguintes objetos principais:
  • Assistant: Entidade principal de uma aplicação conversacional baseada em LLM. Inclui o modelo de linguagem, instruções, ferramentas e nome.
  • Thread: Contêiner independente para o contexto de uma conversa. Todas as mensagens e chamadas relacionadas a uma conversa pertencem à mesma Thread.
  • Message: Mensagem individual em uma conversa. Inclui o role, o content e os metadata.
  • Run: Solicitação específica de invocação do modelo. Ao solicitar que um Assistant gere uma resposta, o sistema aciona uma Run.
  • Step: Etapa de execução mais granular dentro de uma Run. Por exemplo, recuperar informações antes de gerar uma resposta ou fazer várias chamadas a ferramentas externas.
Relacionamento entre os objetos:
Assistant
 ┣─ (manages multiple) Thread
      ┣─ (has many) Message
      ┗─ (has many) Run
            ┗─ (has multiple) Step
O servidor do Alibaba Cloud Model Studio salva esses objetos, e cada um possui um id exclusivo. Use os respectivos métodos retrieve (ou get) para recuperá-los ou o método delete para excluí-los.

2. Por que usar esses componentes

A Assistant API fornece cinco componentes principais para desenvolver aplicações conversacionais: Assistant, Thread, Message, Run e Step. Embora independentes, esses componentes trabalham juntos na camada da aplicação para oferecer um fluxo de trabalho completo, desde a configuração global até o gerenciamento de conversas com múltiplos usuários e múltiplas interações. Esta seção descreve a função e os cenários comuns de cada componente.

2,1 Assistant

Função:
  • O Assistant é o objeto central para gerenciar configurações do modelo e estratégias de conversa. Ele determina a "personalidade" geral e o objetivo da conversa, além das ferramentas ou bases de conhecimento utilizadas.
  • Considere-o como o "cérebro" do chatbot. Ele armazena o modelo base, instruções, uma lista de ferramentas externas acionáveis e metadados gerais.
Cenários comuns:
  1. Definição de função e instruções do sistema: Em certos cenários, atribua uma função ou instrução específica ao assistente, como "Você é um especialista em programação". Isso diferencia seu estilo de conversa ou foco do modo normal.
  2. Integração de ferramentas e bases de conhecimento: Quando a conversa exige suporte de informações externas, como plugins ou recuperação de banco de dados, defina as ferramentas disponíveis na configuração do Assistant. O sistema agenda automaticamente essas ferramentas durante o fluxo da conversa.
  3. Gerenciamento de múltiplos modelos ou versões: Caso precise utilizar modelos diferentes em situações distintas, como qwen-plus e qwen-max, crie vários objetos Assistant para gerenciá-los separadamente.

2,2 Thread

Função:
  • Uma Thread representa um contexto de conversa independente ou uma instância de sessão. Todas as mensagens e chamadas de aplicação relacionadas à sessão pertencem a essa thread.
  • Pense nela como um "canal de chat" entre o usuário e o assistente ou como um contêiner de contexto de fluxo de trabalho.
Cenários comuns:
  1. Gerenciamento de múltiplos usuários e sessões: Aplicações reais frequentemente lidam com vários usuários simultâneos. Crie uma Thread separada para cada usuário ou sessão para isolar eficazmente seus contextos de conversa.
  2. Manutenção do histórico de conversas: A Thread salva todos os registros associados de Message e Run. Isso permite continuar a conversa no mesmo contexto posteriormente ou auditar o histórico.
  3. Contexto de fluxo de trabalho: Para cenários de negócios que exigem manutenção de estado em várias etapas ou processos longos, a Thread atua como contêiner de contexto para evitar perda de informações.

2,3 Message

Função:
  • A Message é uma entidade de mensagem única em uma conversa. Ela registra o remetente (role), o content e metadados relacionados, como carimbos de data/hora e sinalizadores de filtro.
  • Na camada da aplicação, a Message funciona como registro de chat. Internamente, também é uma fonte importante de informações para construir prompts ou contexto.
Cenários comuns:
  1. Entrada e saída de usuário e sistema: Sempre que um usuário insere uma frase ou o assistente gera uma resposta, o sistema cria uma nova Message.
  2. Visualização do fluxo de conversa: Quando o frontend precisa exibir o histórico de conversas, ele pode renderizar uma lista ou exibição em estilo de balão diretamente com base nos objetos Message.
  3. Filtragem e marcação de dados: Em processos de negócios, talvez seja necessário detectar palavras sensíveis, corrigir erros ou tokenizar o conteúdo de entrada. Armazene os resultados do processamento ou tags nos metadados da Message para auditoria e processamento posteriores.

2,4 Run

Função:
  • Uma Run refere-se a um único processo de invocação de um LLM ou outro serviço de inferência. Sempre que você pede ao assistente para gerar uma resposta ou realizar uma inferência, o sistema cria uma nova Run.
  • Geralmente, a Run contém o prompt de entrada, o resultado de saída e metadados como status de execução e tempo consumido.
Cenários comuns:
  1. Rastreamento do processo de inferência: Durante a depuração ou monitoramento, verifique a entrada e a saída de cada Run para entender a qualidade da resposta do modelo, a duração da execução e possíveis mensagens de erro.
  2. Necessidades de faturamento ou estatísticas: Se o modelo subjacente for cobrado com base no número de chamadas ou uso de tokens, adicione um campo de estatísticas de custo à Run para liquidação posterior ou análise de relatórios.
  3. Gerenciamento passo a passo de conversas com múltiplas interações: Embora uma Thread possa ter várias interações, registre cada chamada de modelo independentemente como uma Run para facilitar o rastreamento e a rastreabilidade.

2,5 Step

Função:
  • Um Step é um estágio de execução mais granular. Serve para dividir uma única Run em várias fases ou processos de chamada. Isso é especialmente útil em cenários complexos, como múltiplas recuperações externas, chamadas de plugins ou inferências encadeadas.
  • Encare o Step como uma "subtarefa" ou "processo intermediário". Ele ajuda desenvolvedores ou engenheiros de O&M a obter insights profundos sobre o comportamento do modelo durante um único processo de geração ou inferência.
Cenários comuns:
  1. Chamadas complexas de cadeia de ferramentas: Em alguns casos, o modelo primeiro chama um plugin externo, usa o resultado para uma segunda análise e finalmente gera uma mensagem. Considere cada geração de mensagem ou chamada externa como um Step.
  2. Solução de problemas e visualização: Quando o modelo responde lentamente ou produz resultados anormais, os desenvolvedores podem verificar o tempo de execução e a saída de cada Step para localizar rapidamente gargalos ou falhas.
  3. Logs detalhados opcionais: Em ambiente de produção, talvez você registre apenas informações no nível de Run para economizar armazenamento. No entanto, em ambientes de homologação ou para aplicações que exigem auditoria profunda, ative o registro de Step para obter logs mais detalhados do processo de execução.

2,6 Resumo

  • O Assistant determina as "capacidades conversacionais" e os "recursos de ferramentas".
  • A Thread define o "objeto e contexto da conversa" e o ciclo de vida da conversa.
  • A Message registra o conteúdo específico de cada interação.
  • A Run representa uma chamada real, usada para medir ou auditar o desempenho do modelo na conversa.
  • O Step pode detalhar ainda mais inferências de múltiplas etapas ou chamadas externas, ajudando os desenvolvedores na visualização e solução de problemas em cenários complexos.
Funcionalmente, esses cinco componentes trabalham juntos para demonstrar a facilidade de uso e a escalabilidade da Assistant API no gerenciamento de conversas, permitindo personalizar e rastrear fluxos de conversa. As seções a seguir abordam considerações práticas sobre seu uso em gerenciamento de ciclo de vida, armazenamento de dados e cenários de concorrência e múltiplos usuários. Para mais informações sobre detalhes de chamadas ou exemplos de API, consulte a Referência de Desenvolvimento da Assistant API.

3. Ciclo de vida, armazenamento de dados e política de exclusão

3,1 Armazenamento no lado do servidor DashScope

  • Ao chamar métodos como Assistants.create, Threads.create ou Messages.create, o DashScope cria um registro correspondente no servidor e retorna uma instância de objeto contendo um id.
  • Atualmente, não há tempo de expiração. Um tempo de expiração poderá ser definido no futuro.

3,2 Mecanismo de exclusão

  • Excluir umAssistant Use Assistants.delete(assistant_id) para excluir um Assistant e seus recursos associados. Execute esta operação com extrema cautela.
  • Excluir umaThread Use Threads.delete(thread_id) para realizar uma exclusão em cascata de todos os registros de Message, Run e Step na sessão.
  • Exclusão de uma única Message, Run ou Step: O DashScope atualmente não suporta a exclusão individual desses itens. A limpeza em cascata só é possível excluindo um objeto de nível superior, como uma sessão inteira ou um Assistant inteiro.

3,3 Armazenamento em banco de dados local (opcional)

Em alguns cenários de negócios, pode ser necessário armazenar dados de conversas do DashScope, como objetos Thread e Message, em um banco de dados local. Isso atende a requisitos de retenção de histórico de longo prazo, mineração de dados, análise estatística ou reprodução de mensagens. Para evitar que o banco de dados cresça indefinidamente ou acumule grandes quantidades de dados expirados, geralmente se aplica uma política de tempo de vida (TTL) para limpar ou arquivar sessões desnecessárias. O exemplo a seguir mostra como salvar informações essenciais em um banco de dados local ao criar ou atualizar uma Thread. Também demonstra como usar uma tarefa agendada para limpar dados locais expirados e excluir sincronizadamente os recursos no servidor DashScope.

3.3.1 Armazenar dados localmente ao criar uma Thread

Suponha que você use SQLite ou PostgreSQL para armazenar dados de conversas. O pseudocódigo a seguir mostra a lógica principal:
# This sample code is for reference only. Do not use it directly in a production environment.
import sqlite3
from dashscope import Threads

# This example assumes you have an SQLite database with a table named threads(thread_id TEXT PRIMARY KEY, user_id TEXT, created_at TIMESTAMP, last_active TIMESTAMP, metadata TEXT).

def create_thread_in_db(user_id: str) -> str:
    """
    1. Create a DashScope Thread.
    2. Write the thread_id, user_id, and other information to the local database.
    3. Return the new thread_id.
    """
    # 1. Create the thread on DashScope.
    thread = Threads.create(metadata={"created_by": user_id})

    # 2. Save to the local database.
    conn = sqlite3.connect("app.db")
    cursor = conn.cursor()
    cursor.execute(
        "INSERT INTO threads (thread_id, user_id, created_at, last_active, metadata) VALUES (?, ?, datetime('now'), datetime('now'), ?)",
        (thread.id, user_id, str(thread.metadata))
    )
    conn.commit()
    conn.close()

    return thread.id

def update_thread_activity(thread_id: str):
    """
    When a message is received, update the last_active time for the thread in the local database.
    """
    conn = sqlite3.connect("app.db")
    cursor = conn.cursor()
    cursor.execute(
        "UPDATE threads SET last_active = datetime('now') WHERE thread_id = ?",
        (thread_id, )
    )
    conn.commit()
    conn.close()
  • Quando um usuário iniciar uma nova conversa, chame create_thread_in_db() para obter um thread_id.
  • Ao receber uma nova mensagem, chame update_thread_activity() para atualizar o horário da última atividade. Isso fornece a base para verificações de expiração futuras.

3.3.2 Limpar conversas expiradas e sincronizar exclusões no servidor DashScope

Suponha que seu requisito de negócio seja manter apenas conversas ativas nos últimos 7 dias. Conversas inativas por mais de 7 dias são consideradas expiradas e devem ser excluídas. O exemplo a seguir demonstra uma tarefa agendada (usando Celery, cron job, etc.) que varre o banco de dados local, exclui registros expirados e remove os recursos correspondentes no servidor DashScope.
# This sample code is for reference only. Do not use it directly in a production environment.
import datetime
import sqlite3
from dashscope import Threads

def cleanup_expired_threads(days: int = 7):
    """
    Delete Threads from the local database that have been inactive for more than the specified number of days, and sync the deletion on the DashScope side.
    """
    cutoff_time = datetime.datetime.utcnow() - datetime.timedelta(days=days)

    conn = sqlite3.connect("app.db")
    cursor = conn.cursor()
    cursor.execute(
        "SELECT thread_id FROM threads WHERE last_active < ?",
        (cutoff_time.strftime("%Y-%m-%d %H:%M:%S"),)
    )

    expired_threads = cursor.fetchall()

    for (thread_id,) in expired_threads:
        try:
            # First, delete the Thread from DashScope.
            Threads.delete(thread_id)
        except Exception as e:
            print(f"Error deleting thread {thread_id} from DashScope: {e}")

        # Then, delete the record from the local database.
        cursor.execute("DELETE FROM threads WHERE thread_id = ?", (thread_id,))

    conn.commit()
    conn.close()

# You can run this function once every day at midnight using a scheduler:
# 0 0 * * * /path/to/python your_script.py
Dessa forma, mantém-se a consistência dos dados entre o banco de dados local e o servidor DashScope. Isso garante que históricos inúteis não sejam armazenados a longo prazo e reduz o risco de violações de dados ou desperdício de recursos de armazenamento.

4. Práticas para ambiente de produção

Em um ambiente de produção real, a Assistant API do DashScope geralmente precisa lidar com desafios como concorrência de múltiplos usuários, requisitos de alta disponibilidade, isolamento de workspaces e auditorias de segurança. As seções a seguir descrevem o gerenciamento de concorrência e múltiplos usuários, estratégias de balanceamento de carga e dimensionamento, segurança e controle de acesso, além do gerenciamento de workspaces.

4,1 Gerenciamento de concorrência e múltiplos usuários

Muitas aplicações conversacionais precisam fornecer serviços interativos em tempo real para vários usuários. Portanto, é crucial gerenciar objetos como Assistant, Thread e Message em um ambiente concorrente. Em alguns cenários, convém que diferentes usuários (ou diferentes inquilinos de negócios) usem configurações de Assistant separadas (seus próprios modelos, instruções de sistema, conjuntos de ferramentas, etc.) para aumentar a segurança e o isolamento. Veja um exemplo simplificado:
# This sample code is for reference only. Do not use it directly in a production environment.
def get_assistant_for_user(user_id: str):
    """
    Retrieve or create a dedicated Assistant based on the user_id. This is suitable for multi-tenant scenarios.
    """
    # Look for an existing assistant_id in the local database.
    record = get_assistant_record_by_user(user_id)
    if record:
        return record.assistant_id

    # If none exists, create one.
    user_assistant = Assistants.create(
        model="qwen-plus",
        instructions=f"You are a personal assistant for {user_id}.",
        metadata={"owner": user_id}
    )
    save_assistant_to_db(user_id, user_assistant.id)
    return user_assistant.id

def user_send_message(user_id: str, content: str):
    # Get the user's dedicated Assistant.
    assistant_id = get_assistant_for_user(user_id)
    # Create a thread or retrieve an existing thread based on the assistant...
    # Specific implementation is omitted.
Em um cenário concorrente, o Assistant de cada usuário é independente, o que reduz significativamente o risco de conflitos de contexto e configuração. Naturalmente, isso introduz requisitos adicionais de gerenciamento para a quantidade de objetos Assistant e armazenamento de dados, que devem ser planejados uniformemente no banco de dados e no lado do DashScope.

4,2 Estratégias de balanceamento de carga e dimensionamento

À medida que a demanda por concorrência cresce, projete estratégias de balanceamento de carga e dimensionamento para garantir a estabilidade e a velocidade de resposta da Assistant API do DashScope. Abaixo estão vários métodos comuns e exemplos:

4.2.1 Serviço de múltiplas instâncias com balanceamento de carga

Se sua aplicação estiver implantada na nuvem, utilize um Server Load Balancer para distribuir as solicitações dos usuários para várias instâncias de backend. Cada instância pode executar um conjunto de lógicas do kit de desenvolvimento de software (SDK) do DashScope para interagir com o servidor DashScope.
  • Vantagens: Simples e fácil de implementar, dimensionamento elástico.
  • Desvantagens: Se a aplicação tiver um cache de memória interno, compartilhe o estado da sessão entre as instâncias (o que pode ser feito com Redis ou Memcached).
# This sample code is for reference only. Do not use it directly in a production environment.
# Example: NGINX load balancing configuration snippet
upstream dashscope_app_cluster {
    server 192.168.1.10:8000;
    server 192.168.1.11:8000;
}
server {
    listen 80;
    location / {
        proxy_pass http://dashscope_app_cluster;
    }
}
Na camada da aplicação backend, execute vários processos gunicorn ou uvicorn. Cada processo carrega o SDK do DashScope e lida com uma parte das solicitações.

4.2.2 Enfileiramento de tarefas e processamento assíncrono

Para cenários que podem acionar tarefas de longa duração ou alta carga para o LLM, introduza uma fila de mensagens (como RabbitMQ ou Kafka) ou um executor de tarefas assíncronas (como Celery) para enfileirar solicitações de usuários ou distribuí-las para processos de trabalho. Isso evita falhas no serviço causadas por picos repentinos de concorrência e melhora a observabilidade e a tolerância a falhas do sistema.
# This sample code is for reference only. Do not use it directly in a production environment.
# Celery pseudocode example
from celery import Celery
from dashscope.threads import Runs

celery_app = Celery('tasks', broker='redis://localhost:6379/0')

@celery_app.task
def process_run(thread_id, assistant_id):
    run = Runs.create(thread_id=thread_id, assistant_id=assistant_id)
    final_run = Runs.wait(run.id, thread_id=thread_id, timeout_seconds=60)
    return final_run.id

4.2.3 Dimensionamento horizontal versus vertical

  • Dimensionamento horizontal (scale-out): Adicione mais instâncias de aplicação ou nós de contêiner. Cada nó pode chamar a API do DashScope.
  • Dimensionamento vertical (scale-up): Atualize a configuração do servidor (CPU, memória, largura de banda) para suportar mais solicitações simultâneas em uma única máquina.
Em ambientes modernos nativos da nuvem, o dimensionamento horizontal é mais comum. Combinado com orquestração de contêineres (como Kubernetes) ou Auto Scaling, aumente automaticamente o número de réplicas durante picos de solicitações e reduza durante períodos de baixa demanda para economizar custos.

4,3 Segurança e controle de acesso

Ao usar o DashScope em ambientes de múltiplos usuários, multilocatários e de produção, a segurança e a conformidade são cruciais. As seções a seguir fornecem exemplos e explicações sobre transmissão e armazenamento de dados, chave de API e controle de acesso, filtragem de conteúdo sensível e auditoria e conformidade.

4.3.1 Segurança na transmissão e armazenamento de dados

  • Criptografia na camada de transporte: O DashScope usa HTTPS por padrão para garantir que a comunicação de dados com o servidor seja criptografada.
  • Criptografia/dessensibilização de informações sensíveis: Se as mensagens do usuário contiverem privacidade pessoal ou segredos comerciais, criptografe ou dessensibilize campos sensíveis antes de chamar Messages.create.
  • Segurança do banco de dados local: Ao armazenar informações retornadas pelo DashScope, como objetos Message, Thread e Run, em um banco de dados local, ative a criptografia no nível de linha ou de campos sensíveis e implemente o controle de acesso adequado.

4.3.2 Chave de API e controle de acesso

O DashScope usa uma chave de API para autenticar chamadores. Armazene sua chave de API em uma variável de ambiente segura ou sistema de gerenciamento de chaves. Evite codificá-la permanentemente em repositórios públicos. Considere também as seguintes estratégias:
  1. Separação por ambiente/função: Configure chaves de API diferentes para ambientes de desenvolvimento, homologação e produção. Ou configure chaves separadas para diferentes inquilinos.
  2. Menor privilégio: Conceda apenas as permissões de acesso ao workspace necessárias para evitar que um vazamento de chave afete dados em outros workspaces.
  3. Rotação regular: Atualize periodicamente sua chave de API de acordo com sua política de segurança e revogue a chave antiga no console do DashScope.

4.3.3 Filtragem de conteúdo sensível

  • Detecção de palavras sensíveis: Antes de chamar Messages.create, realize uma detecção baseada em palavras-chave ou modelo no content.
  • Restrições de regras de negócio: Se uma mensagem do usuário não estiver em conformidade com as políticas da plataforma (por exemplo, contiver informações inadequadas), rejeite-a na camada da aplicação e notifique o usuário.
  • Log de auditoria: Registre o conteúdo enviado e os resultados gerados para revisões de segurança ou verificações de conformidade.

4.3.4 Auditoria e conformidade

Em setores com requisitos rigorosos de conformidade (como saúde, finanças e órgãos governamentais), salve logs de auditoria de operações e registre operações sensíveis no conteúdo de conversas geradas pelos usuários. Você pode:
  1. Registrar logs de operação: Sempre que chamar uma API do DashScope, registre o horário da solicitação, o operador (ID do usuário), o objeto alvo (ID da Thread, ID do Assistant), entre outros.
  2. Criptografar ou dessensibilizar para armazenamento: Ao reter conteúdo de conversas sensíveis, dessensibilize ou criptografe-o primeiro para garantir a segurança e a conformidade dos dados.

4,4 Gerenciamento de workspaces

O Alibaba Cloud Model Studio oferece um recurso de gerenciamento de workspaces. Os desenvolvedores podem criar vários workspaces no console. Esses espaços são completamente isolados uns dos outros e identificados por um workspace ID. Todas as operações da Assistant API aceitam um parâmetro workspace para distinguir operações de negócios em diferentes workspaces.

4.4.1 Introdução

  • Isolamento de dados multilocatários: Registros como Assistant, Thread, Message e Run não se afetam mutuamente entre diferentes workspaces.
  • Segurança e gerenciabilidade de dados: Execute exclusões, arquivamentos e controles de acesso de forma independente.
  • Permissões e faturamento: Gerencie o acesso a cada workspace separadamente no console, o que também facilita estatísticas e faturamento.

4.4.2 Como usar o parâmetro workspace

Todas as operações principais, como Assistants.create, Threads.retrieve e Runs.list, aceitam um parâmetro opcional workspace para especificar o workspace alvo. Se não for passado, o sistema usa o "workspace padrão" ou o espaço vinculado à chave atual.
# This sample code is for reference only. Do not use it directly in a production environment.
assistant = Assistants.create(
    model="qwen-plus",
    workspace="WSID123"
)
thread = Threads.create(
    metadata={"key": "value"},
    workspace="WSID123"
)
Para recuperar ou excluir um objeto, forneça o id e o workspace corretos:
# This sample code is for reference only. Do not use it directly in a production environment.
retrieved_assistant = Assistants.retrieve(
    assistant_id="AID_XXX",
    workspace="WSID123"
)
Assistants.delete(
    assistant_id="AID_XXX",
    workspace="WSID123"
)

4.4.3 Cenários típicos

  1. Plataforma SaaS multilocatária: Atribua um workspace independente a cada cliente empresarial para isolar seus dados.
  2. Gerenciamento entre linhas de negócios: Diferentes departamentos ou projetos usam workspaces separados para facilitar o gerenciamento de suas próprias configurações e estatísticas.
  3. Separação de ambientes de desenvolvimento, homologação e produção: Crie workspaces como dev, test e prod no console para gerenciar dados de diferentes ambientes separadamente e evitar interferências.

4.4.4 Observações

  • Chave de API e workspace: Configure as permissões de acesso correspondentes no console.
  • Escopo de busca de ID de objeto: Ao recuperar um objeto, pesquise-o no workspace correspondente.
  • Operação de exclusão: Exclua objetos apenas no workspace especificado. Isso não afeta dados em outros workspaces.
Ao combinar workspaces com cenários de múltiplos usuários, os desenvolvedores podem construir facilmente sistemas conversacionais multilocatários, entre linhas de negócios ou multiambientes, garantindo tanto isolamento quanto manutenibilidade.

5. Exemplo de referência: Criar um chatbot simples

O exemplo abrangente a seguir demonstra como usar o SDK do DashScope para gerenciar o fluxo básico de Assistant para Thread, Message e Run.

from dashscope import Assistants, Threads, Messages, Runs

def init_assistant() -> str:
    """Create and return an assistant_id."""
    assistant = Assistants.create(
        model="qwen-plus",  # Model list: https://www.alibabacloud.com/help/en/model-studio/getting-started/models
        name="ChatAssistant",
        instructions="You are a helpful assistant.",
        metadata={"env": "test"}
    )
    return assistant.id

def start_session(assistant_id: str, user_input: str) -> str:
    """Create a thread and send the first user message."""
    # Create a thread.
    thread = Threads.create(
        metadata={"session_owner": "User123"}
    )
    # Send the user's first message.
    Messages.create(
        thread_id=thread.id,
        content=user_input,
        role="user"
    )
    return thread.id

def get_assistant_reply(assistant_id: str, thread_id: str) -> str:
    """Have the assistant generate a reply on this thread and return the text."""
    run = Runs.create(
        thread_id=thread_id,
        assistant_id=assistant_id,
        # You can override parameters such as model and instructions.
        model="qwen-plus"
    )
    # Wait for the run to complete.
    final_run = Runs.wait(run.id, thread_id=thread_id, timeout_seconds=60)
    # The generated assistant message is recorded in the thread. The first message is the assistant's message.
    # Note: Messages.list returns messages in reverse chronological order of creation.
    thread_messages = Messages.list(thread_id=thread_id)
    if thread_messages.data:
        last_msg = thread_messages.data[0]
        return last_msg.content[0].text.value if last_msg.content else "No reply."
    return "No reply."

def end_session(thread_id: str):
    """Delete the thread, which performs a cascade delete of all messages and runs."""
    Threads.delete(thread_id)

# Example demo
assistant_id = init_assistant()
thread_id = start_session(assistant_id, "Hello, what's the weather like today?")
reply = get_assistant_reply(assistant_id, thread_id)
print("Assistant reply:", reply)
end_session(thread_id)
Neste exemplo:
  1. init_assistant(): Primeiro, crie um Assistant global, especificando o modelo, instruções padrão, etc.
  2. start_session(): Crie uma nova Thread de conversa e adicione a mensagem do usuário.
  3. get_assistant_reply(): Crie uma Run para chamar o modelo e gerar uma resposta. Como a execução é assíncrona, use Runs.wait() para aguardar a conclusão. Após a conclusão, o sistema insere a nova Message na thread. Recupere todas as mensagens e retorne a última, que geralmente é a resposta do Assistant.
  4. end_session(): Após o término da sessão, exclua a Thread para remover todos os recursos do servidor.

6. Perguntas frequentes

  1. P: Como exibir o histórico de mensagens em uma caixa de diálogo local? R: Recupere todas as mensagens no backend usando Messages.list(thread_id=xxx). Em seguida, renderize-as no frontend com base na função (usuário/assistente). Você também pode armazená-las em seu próprio banco de dados para exibição paginada.
  2. P: Como bloquear ou filtrar mensagens de usuários? R: Antes de chamar Messages.create, realize detecção de texto ou limpeza no content. Você também pode marcar a sensibilidade nos metadata.
  3. P: Existe alguma maneira de excluir apenas uma única Message? R: Não, a exclusão de uma única mensagem não é suportada atualmente. É necessário realizar uma exclusão em cascata de toda a sessão usando Threads.delete(thread_id).
  4. P: Quando uma Thread deve terminar? R: Isso depende das suas necessidades de negócios. Chame Threads.delete após o logout do usuário ou o tempo limite da sessão. Ou mantenha-a por um período para que o usuário possa voltar e continuar a conversa.
  5. P: O que devo fazer se uma Run atingir o tempo limite? R: Use Runs.wait(run_id, thread_id, timeout_seconds=...). Se o tempo limite for atingido, o SDK lançará uma TimeoutException. Capture-a e tente novamente ou notifique o usuário sobre o tempo limite da solicitação.
  6. P: Como obter monitoramento mais detalhado para cenários de inferência de múltiplas etapas? R: Visualize Steps.list(run_id, thread_id) para obter as informações de execução de cada etapa. Você também pode registrar logs localmente ou acionar alertas, como enviar um alerta para uma etapa que excedeu o tempo limite.

7. Resumo

O conteúdo e os exemplos anteriores explicam detalhadamente os módulos Assistants, Threads, Messages, Runs e Steps no SDK do DashScope:
  1. Criar / Recuperar / Atualizar / Excluir: Cada objeto possui métodos para criação, exclusão, recuperação e modificação no servidor.
  2. Ciclo de vida e armazenamento: Os objetos são armazenados no servidor DashScope por padrão e não expiram automaticamente. Chame o método delete ou use um banco de dados local para gerenciamento secundário.
  3. Gerenciamento concorrente de múltiplos usuários: Implemente segurança de threads, isolamento de contexto e controle de acesso na camada de negócios.
  4. Melhores práticas:
    • Associe os IDs de objetos retornados pelo DashScope aos seus próprios dados de negócios.
    • Implemente registro de logs e auditoria quando necessário.
    • Gerencie rigorosamente informações sensíveis e políticas de exclusão.
    • Use Runs.wait() ou stream=True para lidar com o processo de geração.
    • Em cenários complexos, visualize Steps para obter informações de execução de múltiplos estágios.
Você também pode conhecer usos mais avançados, como saída em streaming e chamada de ferramentas. Para exemplos detalhados e explicações de parâmetros de todos os componentes, consulte a Referência de Desenvolvimento da Assistant API.