SystemTce/dify-skills

Guia completo de otimização de performance para workflows e plugins do Dify.

O que é dify-skills?

Esta skill fornece um guia abrangente e prático para otimizar a performance de workflows e plugins no Dify, abordando desde a estrutura do grafo até o monitoramento de desempenho. Ela é ideal para desenvolvedores e engenheiros que enfrentam problemas como workflows lentos, altos custos com APIs de LLM, baixa capacidade de processamento concorrente ou gargalos em larga escala. A skill oferece estratégias quantificáveis (ex: redução de 40-60% no tempo de execução com paralelismo) e inclui 5 estudos de caso reais com comparações antes/depois. O guia cobre tópicos como otimização de grafos, estratégias de LLM (seleção de modelos, caching, prompts), ajuste do pool de workers, gerenciamento do pool de variáveis, e configuração de respostas em streaming. Além disso, fornece checklists de diagnóstico rápido em 5 dimensões e orientações sobre ferramentas de monitoramento (Prometheus, Grafana) e testes de carga (Locust, Apache Bench).

Funciona com✓Claude Code~Codex CLI~Cursor✓Gemini CLI
npx skills add https://github.com/SystemTce/dify-skills/tree/main/03-performance

Installed? Explore more Programação e Desenvolvimento skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

SKILL de Otimização de Performance do Dify

Visão Geral

Esta SKILL fornece um guia completo de otimização de performance para workflows e plugins do Dify, cobrindo tópicos principais como otimização da estrutura do grafo, controle de custos de LLM, ajuste do pool de workers, otimização do pool de variáveis, processamento paralelo e monitoramento de desempenho.

Cenários de Aplicação

Você deve usar esta SKILL quando:

  • ⏱️ O tempo de execução do workflow for muito longo, necessitando de otimização
  • 💰 O custo da API LLM for muito alto, precisando reduzir o consumo de Tokens
  • 🚀 A capacidade de processamento concorrente for insuficiente, exigindo maior throughput
  • 📊 A utilização dos recursos do sistema for baixa, necessitando de ajuste de configuração
  • 📈 Existirem gargalos de performance no processamento de dados em larga escala
  • 🔍 For necessário realizar diagnóstico e monitoramento de performance

Valor Principal

  • Efeitos de Otimização Quantificáveis: Execução paralela de branches reduz o tempo em 40-60%, cache de LLM reduz chamadas em 30-50%
  • Orientado por Casos Práticos: 5 casos reais de otimização, com comparações antes e depois
  • Estratégias de Otimização Abrangentes: Cobre todos os níveis de workflow, LLM, plugins e monitoramento
  • Ferramentas de Diagnóstico Rápido: Checklist de diagnóstico em 5 dimensões

Checklist de Diagnóstico Rápido

Antes de iniciar a otimização, use o checklist abaixo para localizar rapidamente os problemas de performance:

📊 Diagnóstico da Estrutura do Grafo

  • Existem muitas dependências em série?
  • É possível usar branches paralelos? (v0.8.0+)
  • Existem nós e conexões desnecessários?
  • O número de nós excede 50?
  • O padrão de design apropriado está sendo usado?

🤖 Diagnóstico de Uso de LLM

  • A seleção do modelo é adequada? (tarefas leves com modelos leves)
  • O Prompt é muito longo? (pode ser simplificado?)
  • O cache de resposta do LLM está ativado?
  • A saída estruturada está sendo usada? (JSON Schema)
  • O consumo de Token está dentro do orçamento?

⚙️ Diagnóstico do Pool de Workers

  • A configuração do número de Workers é razoável? (2-8 threads)
  • A profundidade da fila é muito grande?
  • Existem Workers ociosos desperdiçando recursos?
  • A estratégia de escala para cima/baixo é razoável?

💾 Diagnóstico do Pool de Variáveis

  • Objetos grandes estão sendo armazenados no pool de variáveis?
  • As variáveis são limpas rapidamente?
  • Referências estão sendo usadas em vez de cópias?
  • O escopo das variáveis é razoável?

🔄 Diagnóstico de Processamento Concorrente

  • O iterador está configurado com parallel_nums?
  • A resposta em streaming está sendo usada?
  • As tarefas assíncronas estão configuradas corretamente?
  • Existem operações de bloqueio?

Parte 1: Otimização da Estrutura do Grafo

1.1 Reduzir Dependências em Série

Problema: Muitas dependências em série fazem com que o tempo de execução do workflow cresça linearmente.

Estratégias de Otimização:

  1. Identificar nós paralelizáveis: Analise as dependências entre nós e encontre aqueles que podem ser executados em paralelo
  2. Usar branches paralelos: Dify v0.8.0+ suporta a funcionalidade de branches paralelos
  3. Reestruturar o workflow: Transforme fluxos em série no padrão paralelo + agregação

Exemplo:

# Antes da otimização: Execução em série (tempo total = 3 + 2 + 4 = 9 segundos)
Início → Chamada API1(3s) → Chamada API2(2s) → Chamada API3(4s) → Fim

# Após a otimização: Execução paralela (tempo total = max(3,2,4) = 4 segundos)
Início → [Chamada API1(3s), Chamada API2(2s), Chamada API3(4s)] → Agregador de Variáveis → Fim

Efeito da Otimização: Redução de 40-60% no tempo de execução

1.2 Funcionalidade de Branches Paralelos (v0.8.0+)

O Dify v0.8.0 introduziu a funcionalidade de branches paralelos, permitindo que múltiplos branches sejam executados simultaneamente.

Como Usar:

  1. Crie múltiplos branches no editor de workflow
  2. Certifique-se de que não há dependência de dados entre os branches
  3. Use um agregador de variáveis para coletar os resultados

Cenários de Aplicação:

  • Múltiplos nós HTTP Request chamados em paralelo
  • Múltiplos nós Tool executados em paralelo
  • Recuperação de Knowledge Base + Chamada de API processados em paralelo
  • Inferência paralela com múltiplos modelos (cenário de comparação de modelos)

Exemplo de Configuração:

# Configuração de branches paralelos
parallel_branches:
  - branch_1:
      nodes: [http_request_1, code_1]
  - branch_2:
      nodes: [http_request_2, code_2]
  - branch_3:
      nodes: [tool_1, llm_1]

1.3 Evitar Nós Desnecessários

Problemas Comuns:

  • Nós de transformação de dados redundantes
  • Nós de variáveis intermediárias desnecessárias
  • Nós de condição excessivos

Sugestões de Otimização:

  • Mesclar lógicas de processamento similares
  • Usar nós de código para substituir múltiplos nós simples
  • Simplificar a lógica de condição

1.4 Padrões de Design de Estrutura de Grafo

Escolha o padrão de design adequado com base no tipo de tarefa:

  1. Pipeline Sequencial: Início → LLM → Fim (tarefas simples)
  2. Branch Condicional: Início → LLM → If-Else → Múltiplos caminhos (tarefas de decisão)
  3. Processamento Iterativo: Início → Código → Iteração → LLM (tarefas em lote)
  4. Recuperação de Conhecimento: Início → Recuperação de Conhecimento → LLM (aplicações RAG)
  5. Agregação Multifonte: Múltiplos Tool/HTTP → Agregador de Variáveis → LLM (agregação de dados)

Documentação Detalhada: Consulte workflow-optimization/graph-structure.md


Parte 2: Estratégias de Otimização de LLM

2.1 Estratégia de Seleção de Modelo

Escolher o modelo certo é chave para a otimização de custos.

Matriz de Seleção de Modelo:

Tipo de TarefaModelo RecomendadoCusto de TokenCenário de Aplicação
Classificação SimplesQwen-Turbo, Gemini FlashBaixoClassificação de texto, análise de sentimento
Geração de TextoGPT-3.5-turbo, Qwen-PlusMédioGeração de conteúdo, sumarização
Raciocínio ComplexoGPT-4, Claude OpusAltoAnálise complexa, tomada de decisão
Implantação LocalOllama (Llama 3, Qwen)Custo zero de APICenários sensíveis à privacidade

Comparação de Custos:

  • GPT-4: $0.03/1K tokens (entrada) + $0.06/1K tokens (saída)
  • GPT-3.5-turbo: $0.0015/1K tokens (entrada) + $0.002/1K tokens (saída)
  • Qwen-Turbo: ¥0.0008/1K tokens (cerca de 20x de diferença de custo)

Sugestões de Otimização:

  • Tarefas leves usam modelos leves (Qwen/Gemini)
  • Tarefas complexas usam modelos potentes (GPT-4/Claude)
  • Considere usar modelos locais (Ollama) para reduzir custos

2.2 Técnicas de Otimização de Prompt

Simplificação de Prompt:

# Antes da otimização (150 tokens)
"""
Você é um assistente de suporte ao cliente profissional. Leia atentamente a pergunta do cliente abaixo e, com base em nossa base de conhecimento de produtos, forneça uma resposta detalhada, precisa e amigável. Ao responder, preste atenção aos seguintes pontos:
1. Mantenha um tom profissional e educado
2. Forneça soluções específicas
3. Se não tiver certeza, informe
4. Cite a documentação relevante do produto

Pergunta do cliente: {query}
"""

# Após a otimização (50 tokens)
"""
Como assistente de suporte ao cliente, responda à pergunta do cliente com base na base de conhecimento, mantendo profissionalismo e educação.

Pergunta: {query}
"""

Economia de Tokens: 66% (150 → 50 tokens)

Outras Técnicas de Otimização:

  • Remova explicações e exemplos redundantes
  • Use instruções concisas
  • Evite contexto repetido
  • Use saída estruturada para reduzir custos de parsing

2.3 Estratégias de Cache

Cache de Resposta do LLM:

Use Redis para armazenar em cache as respostas do LLM, evitando chamadas repetidas.

Implementação:

import hashlib
import redis

# Conectar ao Redis
r = redis.Redis(host='localhost', port=6379, db=0)

def get_llm_response_with_cache(prompt, model="gpt-3.5-turbo"):
    # Gerar chave de cache
    cache_key = f"llm:{model}:{hashlib.md5(prompt.encode()).hexdigest()}"

    # Verificar cache
    cached = r.get(cache_key)
    if cached:
        return cached.decode('utf-8')

    # Chamar LLM
    response = call_llm_api(prompt, model)

    # Armazenar em cache (TTL: 1 hora)
    r.setex(cache_key, 3600, response)

    return response

Estratégias de Cache:

  • Cache de Resposta do LLM: Mesmo Prompt retorna resultado em cache
  • Cache de Recuperação da Base de Conhecimento: Mesma consulta retorna vetor em cache
  • Cache de Resultado de Nó: Evita execução repetida do mesmo nó

Efeito da Otimização: Redução de 30-50% nas chamadas de API

2.4 Saída Estruturada

Use JSON Schema para garantir a estabilidade da saída do LLM, reduzindo erros de parsing e retentativas.

Exemplo de Configuração:

{
  "type": "object",
  "properties": {
    "category": {
      "type": "string",
      "enum": ["Técnico", "Vendas", "Pós-venda"]
    },
    "priority": {
      "type": "integer",
      "minimum": 1,
      "maximum": 5
    },
    "summary": {
      "type": "string",
      "maxLength": 100
    }
  },
  "required": ["category", "priority", "summary"]
}

Efeito da Otimização:

  • Reduz a quantidade de Tokens de saída
  • Evita erros de parsing e retentativas
  • Melhora a eficiência do processamento dos nós downstream

Documentação Detalhada: Consulte llm-optimization/


Parte 3: Ajuste do Pool de Workers

3.1 Pool de Threads de Trabalho Dinâmico

O Dify usa um pool de Workers dinâmico para executar nós em paralelo, com configuração padrão de 2-8 threads de trabalho.

Arquitetura do Pool de Workers:

GraphEngine
├── ReadyQueue (Fila de nós prontos)
├── EventQueue (Fila de eventos)
├── Dispatcher (Distribuidor de eventos)
└── WorkerPool (2-8 threads de trabalho)
    ├── Worker 1
    ├── Worker 2
    ├── ...
    └── Worker N

3.2 Parâmetros de Configuração

Configurações Chave:

ParâmetroValor PadrãoDescriçãoSugestão de Otimização
min_workers2Número mínimo de WorkersDefinir com base na necessidade mínima de concorrência
max_workers8Número máximo de WorkersDefinir com base no número de núcleos de CPU
queue_depth_threshold10Limiar para acionar escalaAjustar com base na profundidade média da fila
idle_timeout60sTempo limite de ociosidade do WorkerAjustar com base na frequência das tarefas

Estratégia de Escala:

# Condição para escalar para cima
if queue_depth > queue_depth_threshold and workers < max_workers:
    add_worker()

# Condição para escalar para baixo
if worker_idle_time > idle_timeout and workers > min_workers:
    remove_worker()

3.3 Benchmark de Performance

Cenário de Teste: Workflow com 100 nós

Número de WorkersTempo de ExecuçãoThroughputUso de CPU
245s2.2 nós/s40%
425s4.0 nós/s70%
815s6.7 nós/s95%

Efeito da Otimização: Aumentando o número de Workers de 2 para 8, o throughput aumenta 3x

3.4 Sugestões de Otimização

  1. Definir max_workers com base no número de núcleos de CPU: Geralmente, defina como 1-2 vezes o número de núcleos
  2. Monitore a profundidade da fila: Se a profundidade da fila permanecer alta, aumente max_workers
  3. Evite escalar excessivamente: Muitos Workers podem causar overhead de troca de contexto
  4. Use I/O assíncrono: Para tarefas intensivas de I/O, use processamento assíncrono para aumentar a eficiência

Documentação Detalhada: Consulte workflow-optimization/parallel-execution.md


Parte 4: Otimização do Pool de Variáveis

4.1 Evitar Armazenar Objetos Grandes

Problema: Armazenar objetos grandes (como arquivos grandes, textos longos) no pool de variáveis consome muita memória.

Estratégias de Otimização:

# ❌ Não recomendado: Armazenar objetos grandes
variables = {
    "large_file": open("large_file.pdf", "rb").read(),  # 10MB
    "long_text": "..." * 100000  # 1MB
}

# ✅ Recomendado: Armazenar referências
variables = {
    "file_path": "/path/to/large_file.pdf",
    "text_summary": summarize(long_text)  # Armazenar apenas o resumo
}

4.2 Usar Referências em Vez de Cópias

Problema: Copiar variáveis aumenta o uso de memória e o tempo de processamento.

Estratégias de Otimização:

# ❌ Não recomendado: Copiar variáveis
result = process_data(data.copy())

# ✅ Recomendado: Usar referências
result = process_data(data)  # Operações somente leitura usam referência

4.3 Limpar Variáveis Rapidamente

Problema: Variáveis não utilizadas ocupam memória.

Estratégias de Otimização:

# Limpar variáveis não utilizadas em nós de código
def main(args):
    # Processar dados
    large_data = process_large_data(args["input"])
    result = extract_result(large_data)

    # Limpar objeto grande
    del large_data

    return {"result": result}

4.4 Gerenciamento de Escopo de Variáveis

Tipos de Variáveis:

  • Variáveis de Sistema: sys.query, sys.files, sys.conversation_id
  • Variáveis de Nó: {{#node_id.output#}}
  • Variáveis de Ambiente: Gerenciamento de configuração e chaves
  • Variáveis de Iteração: Item atual e índice em loops

Sugestões de Otimização:

  • Use o menor escopo possível
  • Evite poluição por variáveis globais
  • Libere variáveis temporárias rapidamente

Documentação Detalhada: Consulte workflow-optimization/variable-pool.md


Parte 5: Processamento Paralelo e Resposta em Streaming

5.1 Processamento Paralelo com Iteradores

Use o parâmetro parallel_nums do iterador para processar dados de array em paralelo.

Exemplo de Configuração:

iteration_node:
  type: iteration
  inputs:
    items: "{{#code_node.output.items#}}"
  config:
    parallel_nums: 5  # Processar 5 itens em paralelo

Comparação de Performance:

Volume de DadosProcessamento SerialProcessamento Paralelo (5)Ganho
10 itens20s5s4x
50 itens100s25s4x
100 itens200s50s4x

5.2 Resposta em Streaming

Use resposta em streaming para melhorar a experiência do usuário, reduzindo o tempo até o primeiro byte (TTFB).

Implementação:

# Ativar resposta em streaming na chamada de API
response = requests.post(
    "https://api.dify.ai/v1/workflows/run",
    headers={"Authorization": f"Bearer {api_key}"},
    json={"inputs": {...}, "response_mode": "streaming"},
    stream=True
)

for line in response.iter_lines():
    if line:
        event = json.loads(line)
        print(event["data"])

Efeito da Otimização:

  • TTFB reduzido em 80%
  • Tempo de resposta percebido pelo usuário reduzido em 50%

5.3 Processamento de Tarefas Assíncronas

Use Celery para processar tarefas de longa duração de forma assíncrona.

Arquitetura:

Servidor API → Fila Celery → Pool de Workers → Execução de Tarefas

Cenários de Aplicação:

  • Processamento de arquivos grandes
  • Importação de dados em lote
  • Chamadas de API de longa duração
  • Tarefas agendadas

5.4 Otimização da Arquitetura Orientada a Eventos

O Dify adota uma arquitetura orientada a eventos, onde a execução dos nós gera um fluxo de eventos.

Estratégias de Otimização:

  • Use processamento de eventos não bloqueante
  • Processe filas de eventos em lote
  • Otimize a lógica de distribuição de eventos

Documentação Detalhada: Consulte workflow-optimization/parallel-execution.md


Parte 6: Casos de Otimização de Performance

Caso 1: Otimização de Consulta ao Banco de Dados (Problema N+1)

Cenário de Aplicação:

  • O workflow precisa consultar múltiplos dados relacionados
  • Existem consultas ao banco de dados em loops
  • O tempo de execução cresce linearmente com o volume de dados

Características do Problema:

  • Número de consultas = 1 + N (N é o número de registros)
  • Conexões com o banco são abertas e fechadas com frequência
  • Tempo de execução muito longo

Estado Antes da Otimização:

# Consultar lista de usuários
users = query("SELECT * FROM users LIMIT 100")

# Consultar pedidos para cada usuário (Problema N+1)
for user in users:
    orders = query(f"SELECT * FROM orders WHERE user_id = {user.id}")
    user.orders = orders
  • Número de consultas: 101 (1 + 100)
  • Tempo de execução: 10,5s
  • Carga no banco de dados: Alta

Solução:

# Consultar todos os dados de uma vez
users = query("SELECT * FROM users LIMIT 100")
user_ids = [user.id for user in users]

# Consultar pedidos em lote
orders = query(f"SELECT * FROM orders WHERE user_id IN ({','.join(map(str, user_ids))})")

# Associar dados em memória
orders_by_user = {}
for order in orders:
    if order.user_id not in orders_by_user:
        orders_by_user[order.user_id] = []
    orders_by_user[order.user_id].append(order)

for user in users:
    user.orders = orders_by_user.get(user.id, [])

Resultado Após a Otimização:

  • Número de consultas: 2 (redução de 98%)
  • Tempo de execução: 2,1s (redução de 80%)
  • Carga no banco de dados: Baixa

Benefícios Esperados:

  • Curto prazo: Redução de 80% no tempo de execução, carga reduzida no banco
  • Longo prazo: Suporte a volumes maiores de dados, escalabilidade do sistema melhorada
  • ROI: Custo de desenvolvimento de 2 horas, economia mensal de 30% em custos de servidor

Caso 2: Otimização de Renderização de Nós em Grande Escala (100+ nós)

Cenário de Aplicação:

  • Workflow contém 100+ nós
  • A renderização do frontend fica lenta
  • Resposta lenta no editor

Características do Problema:

  • Tempo de carregamento da página > 5s
  • Atraso perceptível ao arrastar nós
  • Alto uso de memória do navegador

Estado Antes da Otimização:

  • Número de nós: 150
  • Tempo de carregamento da página: 8,5s
  • Uso de memória: 500MB
  • Experiência do usuário: Travamentos severos

Solução:

  1. Rolagem Virtual: Renderizar apenas os nós na área visível
  2. Carregamento Preguiçoso de Nós: Carregar detalhes dos nós sob demanda
  3. Otimização com Canvas: Usar Canvas em vez de renderização DOM
  4. Otimização do Gerenciamento de Estado: Reduzir re-renderizações desnecessárias

Resultado Após a Otimização:

  • Tempo de carregamento da página: 2,1s (redução de 75%)
  • Uso de memória: 150MB (redução de 70%)
  • Experiência do usuário: Fluida

Benefícios Esperados:

  • Curto prazo: Melhoria significativa na experiência do usuário
  • Longo prazo: Suporte a workflows mais complexos
  • ROI: Custo de desenvolvimento de 1 semana, aumento de 40% na satisfação do usuário

Caso 3: Otimização de Performance na Exclusão de Logs de Workflow

Cenário de Aplicação:

  • Necessidade de limpar logs históricos periodicamente
  • Grande volume de dados de log (milhões)
  • Operação de exclusão demorada

Características do Problema:

  • Operação de exclusão bloqueia o banco de dados
  • Afeta as operações normais
  • Tempo de execução imprevisível

Estado Antes da Otimização:

  • Número de logs: 5 milhões
  • Tempo de exclusão: 45 minutos
  • Bloqueio do banco: Bloqueio prolongado de tabela
  • Impacto nos negócios: Severo

Solução:

# Antes da otimização: Exclusão única
DELETE FROM workflow_logs WHERE created_at < '2024-01-01';

# Após a otimização: Exclusão em lotes
batch_size = 10000
while True:
    deleted = DELETE FROM workflow_logs
              WHERE created_at < '2024-01-01'
              LIMIT batch_size;

    if deleted < batch_size:
        break

    # Pausa breve para liberar bloqueio do banco
    sleep(0.1)

Resultado Após a Otimização:

  • Tempo de exclusão: 50 minutos (levemente maior, mas não bloqueia os negócios)
  • Bloqueio do banco: Bloqueio curto (0,1s)
  • Impacto nos negócios: Nenhum

Benefícios Esperados:

  • Curto prazo: Negócios não são afetados
  • Longo prazo: Estabilidade do banco de dados melhorada
  • ROI: Custo de desenvolvimento de 4 horas, evita perdas por interrupção de negócios

Caso 4: Integração com Banco de Dados Distribuído TiDB

Cenário de Aplicação:

  • Grande volume de dados na base de conhecimento (nível TB)
  • Gargalo de performance com PostgreSQL monoinstância
  • Necessidade de capacidade de escalonamento horizontal

Características do Problema:

  • Tempo de resposta de consulta > 5s
  • Uso de CPU do banco > 90%
  • Impossibilidade de escalar ainda mais

Estado Antes da Otimização:

  • Banco de dados: PostgreSQL monoinstância
  • Volume de dados: 2TB
  • Tempo de resposta de consulta: 8,5s
  • Capacidade de escalonamento: Limitada

Solução:

  1. Migrar para TiDB: Banco de dados SQL distribuído
  2. Otimização de Índice de Vetor: Usar TiDB Vector para acelerar a recuperação
  3. Separação Leitura/Escrita: Distribuir requisições de leitura para múltiplas réplicas
  4. Tabelas Particionadas: Particionar por tempo para melhorar a eficiência da consulta

Resultado Após a Otimização:

  • Tempo de resposta de consulta: 1,2s (redução de 86%)
  • CPU do banco: 40% (redução de 50%)
  • Capacidade de escalonamento: Suporte a 10x o volume de dados

Benefícios Esperados:

  • Curto prazo: Melhoria significativa na performance de consulta
  • Longo prazo: Suporte ao rápido crescimento dos negócios
  • ROI: Custo de migração de 2 semanas, suporte a 10x de crescimento de negócios

Caso 5: Implantação de Alta Disponibilidade com Higress AI Gateway

Cenário de Aplicação:

  • Ambiente de produção precisa de alta disponibilidade
  • Balanceamento de carga entre múltiplos modelos LLM
  • Necessidade de capacidade de failover

Características do Problema:

  • Risco de ponto único de falha
  • Chamadas de API LLM instáveis
  • Incapacidade de lidar com picos de tráfego

Estado Antes da Otimização:

  • Arquitetura: Instância única do Dify
  • Disponibilidade: 95%
  • Tempo de recuperação de falha: 10 minutos
  • Pico de tráfego: Incapacidade de lidar

Solução:

# Configuração do Higress AI Gateway
apiVersion: networking.higress.io/v1
kind: McpBridge
metadata:
  name: dify-gateway
spec:
  replicas: 3  # 3 instâncias
  loadBalancer:
    algorithm: round-robin
  healthCheck:
    enabled: true
    interval: 10s
  failover:
    enabled: true
    maxRetries: 3

Arquitetura:

Requisição do usuário → Higress Gateway → [Instância Dify 1, Instância Dify 2, Instância Dify 3]
                ↓
          Balanceamento de carga + Failover

Resultado Após a Otimização:

  • Disponibilidade: 99,9%
  • Tempo de recuperação de falha: < 1 segundo (failover automático)
  • Pico de tráfego: Suporte a 10x o tráfego

Benefícios Esperados:

  • Curto prazo: Melhoria significativa na estabilidade do sistema
  • Longo prazo: Suporte a aplicações críticas de negócios
  • ROI: Custo de implantação de 3 dias, evita perdas por interrupção de negócios

Parte 7: Testes e Monitoramento de Performance

7.1 Sistema de Indicadores de Performance

Indicadores de Execução de Workflow:

IndicadorValor AlvoDescrição
Tempo Médio de Execução< 2sTempo total de execução do workflow
Tempo de Execução P95< 5sTempo de execução para 95% das requisições
Tempo de Execução P99< 10sTempo de execução para 99% das requisições
Taxa de Sucesso de Nós> 99%Proporção de execuções de nós bem-sucedidas
Taxa de Sucesso de Chamadas de API> 99,5%Taxa de sucesso de chamadas de API externas
Capacidade de Processamento Concorrente> 100 QPSNúmero de requisições processadas por segundo

Indicadores de Uso de Recursos:

IndicadorValor AlvoDescrição
Uso de CPU< 70%Uso médio de CPU
Uso de Memória< 80%Uso médio de memória
Número de Conexões com o Banco< 80%Uso do pool de conexões
Memória do Redis< 70%Uso de memória do Redis

Indicadores de Custo:

IndicadorValor AlvoDescrição
Custo de Uso de Token< OrçamentoCusto da API LLM
Custo de Infraestrutura< OrçamentoCusto de servidores, banco de dados
Custo/UsuárioEm redução contínuaCusto por usuário

7.2 Ferramentas de Monitoramento

Monitoramento LLMOps:

# Monitoramento embutido do Dify
from dify import Monitor

monitor = Monitor()

# Registrar execução do workflow
monitor.log_workflow_execution(
    workflow_id="xxx",
    execution_time=2.5,
    node_count=10,
    token_usage=1500,
    cost=0.003
)

# Consultar estatísticas
stats = monitor.get_workflow_stats(
    workflow_id="xxx",
    time_range="7d"
)

Rastreamento de Execução:

  • Histórico de execução do workflow
  • Estatísticas de passos de execução por nó
  • Estatísticas de uso do LLM
  • Logs de erros e registros de retentativas

Monitoramento de Recursos:

# Prometheus + Grafana
# Monitorar CPU, memória, rede, disco

# Exemplo de consulta
rate(dify_workflow_execution_total[5m])  # Taxa de execução de workflows
histogram_quantile(0.95, dify_workflow_duration_seconds)  # Tempo de execução P95

7.3 Métodos de Teste de Performance

Teste de Carga:

# Usar Locust para teste de carga
from locust import HttpUser, task, between

class DifyUser(HttpUser):
    wait_time = between(1, 3)

    @task
    def run_workflow(self):
        self.client.post(
            "/v1/workflows/run",
            headers={"Authorization": f"Bearer {self.api_key}"},
            json={"inputs": {"query": "Pergunta de teste"}}
        )

# Executar teste
# locust -f load_test.py --users 100 --spawn-rate 10

Teste de Estresse:

# Usar Apache Bench
ab -n 1000 -c 50 -H "Authorization: Bearer xxx" \
   -p request.json \
   https://api.dify.ai/v1/workflows/run

Teste de Benchmark:

# Teste de benchmark de performance
import time

def benchmark_workflow(workflow_id, iterations=100):
    times = []
    for i in range(iterations):
        start = time.time()
        run_workflow(workflow_id)
        end = time.time()
        times.append(end - start)

    return {
        "avg": sum(times) / len(times),
        "p50": sorted(times)[len(times) // 2],
        "p95": sorted(times)[int(len(times) * 0.95)],
        "p99": sorted(times)[int(len(times) * 0.99)]
    }

7.4 Ferramentas de Análise de Performance

Python Profiler:

import cProfile
import pstats

def profile_workflow():
    # Perfilha a execução do workflow
    profiler = cProfile.Profile()
    profiler.enable()
    
    # Executa o workflow
    result = run_workflow("workflow_id")
    
    profiler.disable()
    
    # Salva e analisa os resultados
    profiler.dump_stats("workflow_profile.prof")
    
    p = pstats.Stats("workflow_profile.prof")
    p.sort_stats("cumulative").print_stats(20)

Ferramentas de Análise de Banco de Dados:

  • Explique planos de consulta (EXPLAIN)
  • Identifique consultas lentas usando slow_query_log
  • Verifique índices e otimize consultas

Análise de Rede:

# Use curl para medir o tempo de resposta da API
curl -w "@curl-format.txt" -o /dev/null -s \
  -H "Authorization: Bearer xxx" \
  -X POST https://api.dify.ai/v1/workflows/run \
  -d '{"inputs": {"query": "test"}}'

Formato do arquivo curl-format.txt:

time_namelookup: %{time_namelookup}s
time_connect: %{time_connect}s
time_appconnect: %{time_appconnect}s
time_pretransfer: %{time_pretransfer}s
time_redirect: %{time_redirect}s
time_starttransfer: %{time_starttransfer}s
-----
time_total: %{time_total}s

Apêndice

A. Referência Rápida

CategoriaPrincipais AçõesGanho de Performance
Estrutura do GrafoParalelizar nós, otimizar dependênciasRedução de 40-60% no tempo
LLMModelos leves, cache, prompts curtosRedução de 30-50% nos custos
Pool de WorkersAjustar número de WorkersAumento de 3x no throughput
Pool de VariáveisReferências, evitar cópiasRedução de 50% no uso de memória
Processamento ConcorrenteProcessamento em lote, streamingMelhoria de 4x no throughput

B. Links de Referência

Individual skills in this repo

This repo contains 5 individual skills — each has its own dedicated page.

Habilidades Relacionadas