(def instrutor {:nome "Cácio José da Costa Silva"
:empresa "Alura"
:cargo "Instrutor e pagodeiro nas horas vagas"})Conceitos básicos, interface e building blocks
IA Generativa no Copilot Studio
Publicar, compartilhar e proteger agente
Laboratório
(outro momento)
Esse workshop foi desenhado para citizen developers
"Tecniquês" vai ser evitado
Demonstrações práticas
Uma analogia simples
Custom topicsSystem topicsRecebendo dados dos usuários
(Com exemplo é melhor)
Mergulhando mais fundo
Início da conversa (Conversation start)
Disparado quando o chat inicia
Dita o tom da conversa
Dar contexto ao usuário
Quick replies
Opção para selecionar tópicos mais rapidamente
Pode ser usado para inicializar variáveis (globais)
Escalonar (Escalate)
Acionado quando o usuário deseja falar com um humano
Oferecer os telefones de contato
Quando não houver essa possibilidade, deve ser desabilitado
Conversational boosting
Acionado como última tentativa de dar uma resposta ao usuário
Nenhum outro tópico foi escolhido
Oferece resposta com base em IA generativa por padrão
Fallback
Acionado quando nenhum tópico satisfaz a mensagem do usuário
Ideal para uma mensagem amigável quando não for possível ajudar
Fim da conversa (End of conversation)
Acionado com redirect
Você quem invoca ele a partir de outro tópico
Não é inicializado por evento espontâneo
Redefinir conversa (Reset conversation)
Também acionado com redirect
Limpa todas as variáveis
Finaliza todos os tópicos
Solicita ao usuário para iniciar uma nova conversa
Se houver erro (On Error)
Acionado quando algum erro de processamento acontece no chatbot
Não aparece para o usuário, somente no teste
Vários Tópicos Correspondentes e Entrar
Entrar
Acionado quando o chatbot precisa autenticar o usuário
Vários Tópicos correspondentes
Acionado quando a mensagem do usuário pode ser tratada por mais de um tópico
Preparação do ambiente
Mudando o modo de pensar
Imperativo ➡
Reativo ➡
Operações em paralelo
Mono e Flux
public class ExemploDeCoreTypes {
/**
* Mono representa um fluxo de 0..1 elementos
*/
public Mono<String> getMensagem() {
return Mono.just("Olá, mundo reativo!");
}
/**
* Flux representa um fluxo de 0..N elementos
*/
public Flux<Integer> getFlux() {
return Flux.range(1, 5);
}
}Map, FlatMap e Filter
public class OperadoresReativos {
public Flux<String> processaDados() {
return Flux.just(1, 2, 3, 4, 5)
// `map` transforma um valor em outro
.map(i -> i * 2)
// `filter` remove elementos que não passam no predicado
.filter(i -> i > 5)
// `flatMap` mapeia e "achata" fluxos aninhados.
.flatMap(i -> Flux.just("Número: " + i, "Potência: " + (i * i)));
}
}Zip
public class OperadoresReativos {
// atributos e construtor
public Mono<RelatorioDeInadimpletes> getCombinedData() {
return Mono.zip(
relatorioService.getQuantidadeDeInadimplementes(),
relatorioService.getMontanteAReceber(),
relatorioService.getClientesInadimplementes(),
(quantidade, montante, clientes) ->
new RelatorioDeInadimplentes (quantidade, montante, clientes)
);
}
}Lidando com altas cargas
@RestController
public class OperadoresReativos {
// atributos e construtor
@GetMapping(value = "/stream-data-drop", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Data> fluxoComDrop() {
return dataSource.getData()
.limitRate(100) // Controle de backpressure
.onBackpressureDrop(); // Descarta elementos que o cliente não conseguir processar
}
@GetMapping(value = "/stream-data-buffer", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Data> fluxoComBuffer() {
return dataSource.getData()
.limitRate(100) // Controle de backpressure
.onBackpressureBuffer(10); // Cria um buffer com 10 elementos
}
}Concorrência simplificada
@RestController
public class SchedulersController {
// atributos e construtor
@GetMapping("/processo-paralelo")
public Flux<Result> processoParalelo() {
return Flux.range(1, 100)
.parallel()
.runOn(Schedulers.parallel())
.map(this::processaItem)
.sequential();
}
private void processaItem(Integer numero) {
// processamento pesado...
}
}ImmediateExecuta processamento na thread atual.
SingleExecuta em uma única thread dedicada.
ParallelExecuta em um pool de threads paralelo.
Tipos
Bounded ElasticCria threads sob demanda com um limite máximo.
Combinando Schedulers
@RestController
public class SchedulersController {
// atributos e construtor
@GetMapping("/tarefa-intensa")
public Flux<Result> tarefaIntensa() {
return Flux.range(1, 100)
.flatMap(i -> Mono.fromCallable(() -> executaComputacaoPesada(i))
.subscribeOn(Schedulers.boundedElastic()))
.publishOn(Schedulers.parallel());
}
private Result executaComputacaoPesada(int input) {
// Simulação de uma tarefa pesada
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return new Result(input, input * input);
}
}onErrorReturn
Flux.just("A", "B")
.concatWith(Flux.error(new RuntimeException("Erro"))) // concatena fluxo de erro
.onErrorReturn("Default") // retorna valor padrão em caso de erro
.subscribe(
valor -> System.out.println("Recebeu: " + valor),
erro -> System.err.println("Erro: " + erro)
);
// SAÍDA
Recebeu: A
Recebeu: B
Recebeu: DefaultonErrorResume
Flux.just("A", "B")
.concatWith(Flux.error(new RuntimeException("Erro")))
.onErrorResume(e -> Flux.just("Fallback1", "Fallback2")) // altera para fluxo alternativo
.subscribe(
valor -> System.out.println("Recebeu: " + valor),
erro -> System.err.println("Erro: " + erro)
);
// SAÍDA
Recebeu: A
Recebeu: B
Recebeu: Fallback1
Recebeu: Fallback2onErrorContinue
Flux.range(1, 5)
.map(i -> {
if (i == 3) {
throw new RuntimeException("Erro");
}
return i;
})
.onErrorContinue((erro, item) ->
System.err.println("Erro aconteceu no item " + item)
)
.subscribe(
valor -> System.out.println("Recebeu: " + valor),
erro -> System.err.println("Erro: " + erro)
);
// SAÍDA
Received: 1
Received: 2
Received: 4
Received: 5
Erro aconteceu no item 3Tratando erros específicos
Flux.just("A", "B")
.concatWith(Flux.error(new RuntimeException("Erro")))
.onErrorResume(IOException.class, e -> Flux.just("IO Fallback"))
.onErrorResume(RuntimeException.class, e -> Flux.just("Runtime Fallback"))
.subscribe(
valor -> System.out.println("Recebeu: " + valor),
erro -> System.err.println("Erro: " + erro)
);
// SAÍDA
Recebeu: A
Recebeu: B
Recebeu: Runtime FallbackDiferenças
(def recursos {:linkedin "/cacio-costa/"
:email "cacio.costa@alura.com.br"
:ig-grupo-qdqa "@grupoqdqa"})