v1.2 — Edição de 2026. Um curso em áudio aprofundado sobre a framework de orquestração LangChain v1.0. Construa aplicações de IA multi-agente fiáveis com tool calling padronizado, structured outputs, validação human-in-the-loop e context engineering avançado.
Orquestração de LLMFrameworks de AI/MLSistemas Multi-Agente
Exploramos o motivo pelo qual o LangChain evoluiu de um wrapper para uma framework de orquestração completa. Irá aprender a história do desenvolvimento de aplicações LLM e como o lançamento da v1.0 padroniza as interações com os modelos.
3m 52s
2
A Abstração Unificada de Agentes
Mergulhamos na função central create_agent que unifica as abstrações anteriores do LangChain. Irá aprender como o ciclo ReAct opera nos bastidores para gerir o raciocínio do modelo e a execução de ferramentas.
3m 28s
3
Padronizar o Caos
Examinamos como o LangChain padroniza as interações com modelos entre diferentes fornecedores. Irá aprender a inicializar modelos de chat e a alternar de forma fluida entre OpenAI, Anthropic e Google.
3m 11s
4
A Linguagem Universal dos LLMs
Analisamos a unidade fundamental de contexto no LangChain: Messages. Irá aprender a estruturar mensagens System, Human, AI e Tool para construir históricos de conversação robustos.
3m 39s
5
Capacitar Agentes com Ferramentas
Exploramos como dar ações aos seus modelos utilizando o decorador @tool. Irá aprender como os type hints e as docstrings são automaticamente convertidos em esquemas JSON precisos para o modelo.
3m 33s
6
Injetar Contexto de Ferramentas
Mergulhamos na passagem de informações de runtime diretamente para as suas ferramentas sem as expor ao LLM. Irá aprender a utilizar o parâmetro ToolRuntime para configurações seguras e com injeção de dependências.
3m 48s
7
Persistência ao Nível da Thread
Abordamos a memória de curto prazo e como manter o histórico de conversação. Irá aprender a anexar checkpointers ao seu agente para permitir que as conversas sejam pausadas, retomadas e lembradas.
3m 28s
8
Comprimir Contexto com Middleware
Exploramos como evitar que conversas longas bloqueiem o seu modelo. Irá aprender a utilizar o SummarizationMiddleware para comprimir automaticamente mensagens antigas e poupar tokens.
3m 38s
9
Formatos de Dados Garantidos
Discutimos como forçar os modelos de linguagem a devolver estruturas de dados estritas e previsíveis. Irá aprender a diferença entre ProviderStrategy e ToolStrategy para gerar modelos Pydantic.
3m 37s
10
Intercetar o Ciclo do Agente
Introduzimos o paradigma de middleware, dando-lhe um controlo cirúrgico sobre a execução do seu agente. Irá aprender a utilizar hooks wrap-style e node-style para intercetar chamadas de modelos.
3m 31s
11
Engenharia de Contexto Dinâmica
Mergulhamos na engenharia de contexto através da geração dinâmica de prompts de sistema. Irá aprender a utilizar middleware para alterar instruções com base no papel do utilizador atual e no ambiente.
4m 03s
12
IA Segura com Guardrails Determinísticos
Protegemos os nossos agentes contra fugas de dados utilizando middleware integrado. Irá aprender a aplicar o PIIMiddleware para ocultar automaticamente informações sensíveis antes que cheguem ao modelo.
4m 13s
13
Pausar para Aprovação Humana
Exploramos a execução de ferramentas de alto risco adicionando um humano ao ciclo. Irá aprender a interromper a execução de um agente para aprovar, editar ou rejeitar ações sensíveis.
3m 38s
14
Feedback de Agentes em Tempo Real
Mergulhamos no streaming para melhorar drasticamente a experiência do utilizador. Irá aprender a interpretar modos de stream para exibir tokens de LLM em tempo real juntamente com atualizações personalizadas da execução de ferramentas.
3m 40s
15
Persistência Entre Sessões
Exploramos a memória a longo prazo para construir agentes que conhecem verdadeiramente os seus utilizadores. Irá aprender a utilizar as stores do LangGraph para guardar documentos JSON em conversas totalmente diferentes.
3m 13s
16
O Paradigma Multi-Agente
Explicamos por que razão os agentes únicos falham e introduzimos a arquitetura de Subagents. Irá aprender como um agente supervisor principal coordena subagentes como janelas de contexto isoladas para evitar a sobrecarga de tokens.
4m 18s
17
Agentes Orientados a Estado
Exploramos como os agentes podem alterar dinamicamente o seu comportamento. Irá aprender o padrão Handoffs para transferir o controlo e o padrão Skills para carregar prompts especializados a pedido.
4m 03s
18
Workflows Personalizados e Routers
Saímos do ciclo padrão do agente. Irá aprender a utilizar o LangGraph para construir arquiteturas de routing personalizadas, misturando lógica determinística com raciocínio agêntico não determinístico.
4m 05s
19
Comunicação Agente-para-Agente
Exploramos o endpoint LangSmith A2A. Irá aprender como agentes distribuídos implementados em servidores totalmente diferentes podem conversar nativamente utilizando o protocolo A2A RPC da Google.
4m 39s
20
O Futuro é o MCP
Olhamos para o futuro com o Model Context Protocol, padronizando a forma como os agentes acedem a ferramentas externas. Irá aprender a ligar servidores MCP remotos ao seu agente utilizando transportes padrão.
4m 32s
Episódios
1
A Era da Orquestração
3m 52s
Exploramos o motivo pelo qual o LangChain evoluiu de um wrapper para uma framework de orquestração completa. Irá aprender a história do desenvolvimento de aplicações LLM e como o lançamento da v1.0 padroniza as interações com os modelos.
Olá, daqui fala o Alex da DEV STORIES DOT EU. LangChain v1.0, Orchestration Framework, episódio 1 de 20. É incrivelmente fácil construir um protótipo de um AI agent, mas é notoriamente difícil construir um que seja fiável o suficiente para pôr em produção. A diferença entre uma demo fixe de fim de semana e uma aplicação enterprise é enorme. A solução para colmatar essa diferença é o que chamamos de Era da Orquestração.
Primeiro, vamos esclarecer um mal-entendido muito comum. As pessoas confundem frequentemente o LangChain com um provider de modelos. O LangChain não treina, não aloja, nem serve large language models. É a camada de orquestração que fica diretamente por cima desses modelos. Pensa nele como o centro de controlo que gere a forma como a tua aplicação interage com qualquer modelo que escolhas usar.
Para perceberes por que razão uma camada de orquestração é necessária, temos de olhar para a forma como a tecnologia evoluiu. Em 2022, interagir com um modelo de linguagem era simples. Enviavas uma string de texto e recebias uma string de texto de volta. Prompt chains simples eram suficientes para fazer o trabalho. Não precisavas de uma framework pesada para gerir um workflow básico de text-in, text-out. Podias facilmente escrever um script onde o output do prompt A era simplesmente colado no prompt B.
Mas, à medida que avançamos por 2025 e olhamos para 2026, o panorama é completamente diferente. Os modelos já não processam apenas plain text. Ingerem e geram blocos multimodais complexos. Uma única interação pode envolver fazer o routing de um prompt do utilizador, acionar uma tool call externa, processar uma imagem e devolver um bloco de dados estruturado. Um modelo pode devolver um pedido para um database lookup logo ao lado de um resumo em texto. Se o código da tua aplicação tiver de inspecionar manualmente cada resposta para perceber se é uma string, uma tool invocation ou um ficheiro de imagem, a tua codebase vai rapidamente tornar-se numa confusão frágil e impossível de manter.
Aqui está o ponto chave. Passar o contexto exato para um modelo no momento exato é muito mais difícil do que simplesmente escolher o modelo mais poderoso do mercado. Podes trocar para o reasoning engine mais inteligente disponível, mas se ele receber dados desorganizados e não padronizados, toda a interação vai falhar.
É por isso que o LangChain evoluiu de uma simples chaining library para uma camada de orquestração padronizada na sua release 1.0. Fornece um formato de mensagem standard que funciona de forma consistente em todos os principais providers de modelos. Em vez de escreveres lógica de parsing customizada para cada API diferente, usas uma estrutura uniforme. Ao padronizar o formato da mensagem, o LangChain garante que uma tool call de um provider é exatamente igual no teu código a uma tool call de um provider concorrente. Defines uma sequência onde entra uma mensagem do utilizador, a camada de orquestração normaliza-a, envia-a para o modelo, apanha a resposta multimodal e traduz essa resposta de volta para um formato standard que a tua aplicação consiga realmente usar. Escreves a lógica da tua aplicação uma única vez, e a camada de orquestração trata da tradução.
O modelo em si já não é a aplicação inteira, é meramente o reasoning engine, e a camada de orquestração é o que determina se esse engine resolve realmente o teu problema de negócio.
Se nos quiseres ajudar a continuar a fazer estes episódios, podes apoiar o programa procurando por DevStoriesEU no Patreon. É tudo por este episódio. Obrigado por ouvires, e continua a construir!
2
A Abstração Unificada de Agentes
3m 28s
Mergulhamos na função central create_agent que unifica as abstrações anteriores do LangChain. Irá aprender como o ciclo ReAct opera nos bastidores para gerir o raciocínio do modelo e a execução de ferramentas.
Olá, daqui é o Alex da DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episódio 2 de 20. E se pudesses substituir todo o teu complexo reasoning loop por uma única function call de dez linhas? Passas horas a escrever custom parsers e while-loops só para fazer um language model acionar uma função de forma fiável. A Unified Agent Abstraction é a arquitetura que te tira esse peso de cima.
Para perceberes porque é que isto importa, temos de esclarecer uma confusão comum em relação às versões mais antigas da framework. Na versão zero ponto x, os developers tinham de navegar por um labirinto de classes de agents específicas. Tinhas conversational agents, zero-shot agents e custom chains complexas. Se estás a fazer upgrade ao teu código, podes esquecer tudo isso. A Unified Agent Abstraction substitui completamente todas as chains antigas e legacy agents. Fornece um entry point claro e standard através de uma função simplesmente chamada create agent.
Esta função existe para gerir o ReAct loop. ReAct significa Reason and Act. Quando um utilizador faz uma pergunta complexa, um language model não pode simplesmente executar código. Tem de raciocinar sobre o problema, decidir tomar uma ação, fazer output de texto a pedir essa ação, e depois esperar por uma observation antes de poder raciocinar novamente. Lidar com este ciclo manualmente é trabalhoso. Tens de fazer parse do texto gerado pelo modelo, mapeá-lo para uma função local, executar essa função, formatar o output, passá-lo de volta para o modelo, e avaliar se a task está terminada. A função create agent abstrai todo este processo de orchestration.
Vamos ver uma implementação simples a usar uma tool de verificação da meteorologia. Primeiro, defines a tua tool específica, talvez uma função chamada get weather que recebe o nome de uma cidade. A seguir, inicializas o teu language model escolhido. Depois vem a abstraction. Chamas a função create agent e passas-lhe três argumentos. Passas o teu language model, uma lista a conter a tua tool get weather, e um system prompt que dita as regras para o agent. Esta única chamada devolve um objecto agent executável. Finalmente, invocas este objecto com uma user query, a pedir a meteorologia atual em Londres.
Aqui está o ponto-chave do execution flow. Quando invocas o agent, estás a iniciar o ReAct loop. O agent envia a query e as descrições das tools para o modelo. O modelo decide que precisa de dados em tempo real e faz output de uma tool call standard. A agent abstraction interceta esta chamada automaticamente. Executa a tua tool get weather com o argumento Londres, pega nos dados de temperatura resultantes, e passa-os de volta ao modelo como uma nova observation. O modelo avalia estes dados, percebe que tem a resposta para a user query, e gera uma resposta final.
Não escreveste um único loop, e não escreveste um output parser. Apenas forneceste as tools, o modelo e as instruções. O poder da Unified Agent Abstraction reside em estabelecer uma fronteira arquitetural estrita. Isola completamente a mecânica do reasoning cycle, permitindo-te dedicar todo o teu esforço de engenharia a refinar a qualidade das tuas tools e a clareza dos teus prompts.
É tudo por agora. Obrigado por ouvires, e continua a programar!
3
Padronizar o Caos
3m 11s
Examinamos como o LangChain padroniza as interações com modelos entre diferentes fornecedores. Irá aprender a inicializar modelos de chat e a alternar de forma fluida entre OpenAI, Anthropic e Google.
Olá, daqui é o Alex da DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episódio 3 de 20. Diferentes providers de modelos têm APIs muito distintas, o que significa que experimentar um novo modelo geralmente te obriga a reescrever metade da tua aplicação. Acabas por ficar preso a um vendor simplesmente porque o custo técnico de mudar é demasiado alto. Standardizar esta confusão é exatamente o objetivo deste episódio.
Antes de entrarmos nos detalhes de como o LangChain resolve isto, ajuda esclarecer uma confusão comum. Se trabalhaste com modelos de linguagem antigos, provavelmente estás familiarizado com as classes LLM legacy que aceitam uma única string de texto raw como input. Os modelos de chat modernos são diferentes. Eles exigem estritamente uma sequência estruturada de mensagens, onde cada mensagem tem um role específico associado, como system, human ou AI. Tudo o que vamos discutir agora aplica-se a estes modelos de chat modernos, e não aos de text completion legacy.
Quando constróis uma aplicação, fazer hardcode de um provider específico cria um vendor lock-in imediato. Para quebrar esta dependência, o LangChain introduz uma única factory function chamada init chat model. Pensa nisto como um tradutor universal para inicializar clients de inteligência artificial. Em vez de importares uma classe específica para a OpenAI, outra para a Anthropic e ainda outra para o Google, dependes exclusivamente desta única função.
Aqui está o ponto chave. A função init chat model usa uma sintaxe de string simples para saber o que construir. Forneces uma string formatada com o nome do provider, seguido de dois pontos, e depois a versão específica do modelo. Imagina um agent que está a correr no GPT-5 da OpenAI. Inicializas o teu modelo simplesmente passando a string openai colon gpt-5.
Agora, supõe que a Anthropic lança um novo modelo que lida melhor com a geração de código, e tu queres testá-lo. Como usaste a função init chat model, não tocas na lógica do teu agent. Não importas um novo package de client. Apenas alteras essa string de inicialização para anthropic colon claude-sonnet-4-6. O LangChain resolve a string dinamicamente e carrega a classe de integração subjacente correta.
Isso trata do modelo em si, mas os providers também divergem nas settings de configuração. Uma API pode esperar um parâmetro chamado max sampled tokens, enquanto outra espera max length. A função init chat model resolve isto aceitando parâmetros standard. Quando inicializas o teu modelo, podes passar argumentos como temperature ou max tokens diretamente para a função.
Se definires a tua temperature para zero ponto dois e os max tokens para mil, o LangChain mapeia esses termos genéricos para as keys exatas de payload exigidas por qualquer provider que tenhas especificado na tua string. Configuras o teu modelo uma única vez usando a terminologia standard, e a framework traduz isso para a API de destino.
Ao separar o código da tua aplicação dos detalhes de implementação específicos do vendor, ganhas agilidade arquitetural, permitindo-te avaliar modelos concorrentes em segundos, em vez de dias.
É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
4
A Linguagem Universal dos LLMs
3m 39s
Analisamos a unidade fundamental de contexto no LangChain: Messages. Irá aprender a estruturar mensagens System, Human, AI e Tool para construir históricos de conversação robustos.
Olá, daqui é o Alex da DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episódio 4 de 20. Se ainda estás a passar strings de texto simples para os teus modelos de linguagem, estás a limitar severamente as tuas aplicações. As strings simples perdem o contexto. Não conseguem guardar com segurança referências a imagens, resultados da execução de tools, ou papéis de interação distintos. Para resolver isto, o LangChain usa message objects padronizados, que atuam como a linguagem universal dos LLMs.
Uma mensagem no LangChain é uma estrutura de dados que contém um role específico, o payload e metadados opcionais. Diferentes providers de API lidam com roles de conversação e inputs multimodais de maneira diferente nas suas raw APIs. O LangChain abstrai esta fricção em quatro classes distintas.
A primeira é a SystemMessage. Este objeto estabelece as regras de fundo, a persona ou as restrições estritas para a interação. A seguir temos a HumanMessage, que representa o prompt do utilizador ou os ficheiros enviados. Depois, temos a AIMessage, que captura a resposta gerada pelo modelo. Finalmente, existe a ToolMessage. Este objeto transporta especificamente o resultado da execução de uma função externa de volta para o modelo, separando claramente o raw input do utilizador dos dados factuais gerados pelo sistema.
Orquestras conversas passando um array destes message objects para o modelo. Podes construir este array manualmente para moldar o output. Primeiro, crias uma lista e inseres uma SystemMessage, atribuindo ao modelo o role de um especialista em poesia com formatação rigorosa. Segundo, adicionas uma HumanMessage a pedir um haiku sobre migrações de bases de dados. Aqui está o ponto chave. Não tens de esperar que o modelo gere a próxima resposta. Podes instanciar manualmente uma AIMessage e injetá-la no array logo a seguir ao prompt humano, contendo uma linha de abertura específica. Quando passas todo este array para o modelo, ele interpreta a AIMessage injetada como o seu próprio comportamento passado. Ele vai continuar o haiku perfeitamente a partir do teu ponto de partida exato, aderindo à estrutura que lhe impuseste.
Quando finalmente recebes uma AIMessage de volta do modelo, precisas de extrair o que ele realmente produziu. Os developers costumam confundir o atributo de raw content com o parsed payload. Cada message object possui uma propriedade content. No entanto, este atributo de raw content reflete diretamente o que o provider de LLM específico retornou. Dependendo do provider do modelo e do prompt, isto pode ser uma simples string de texto, ou pode ser uma lista altamente aninhada de dicionários contendo text chunks misturados, URLs de imagens e identificadores de tools. Fazer o parsing disto manualmente torna o teu código incrivelmente frágil.
Em vez de leres o raw content, deves usar a propriedade content blocks. A propriedade content blocks é a representação padronizada e estritamente tipada do payload da mensagem no LangChain. Ao leres dos content blocks, o LangChain traduz a resposta específica do provider numa lista uniforme de block objects. Podes iterar por esta lista com segurança. Primeiro verificas se um bloco é um text block, e se for, extrais o text payload. A seguir verificas se é um tool call block, e extrais os argumentos. Construir a tua lógica de parsing em torno da propriedade padronizada content blocks é a única maneira de garantir que a tua aplicação permanece totalmente desacoplada das mudanças nos formatos de resposta dos providers de modelos individuais.
É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
5
Capacitar Agentes com Ferramentas
3m 33s
Exploramos como dar ações aos seus modelos utilizando o decorador @tool. Irá aprender como os type hints e as docstrings são automaticamente convertidos em esquemas JSON precisos para o modelo.
Olá, daqui é o Alex da DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episódio 5 de 20. Um agente de IA sem acesso ao mundo exterior é apenas um gerador de texto. Para o transformares num sistema que realmente executa tarefas, tens de lhe dar mãos. Hoje vamos falar sobre como capacitar agentes com tools, especificamente usando o decorator at-tool.
Uma tool no LangChain é uma ponte entre o motor de raciocínio de um language model e os teus sistemas externos. Mas há aqui um equívoco comum. Muitos developers assumem que o language model de alguma forma analisa a lógica dentro da tua função Python para descobrir como a usar. Não o faz. O language model nunca vê o teu código Python. Apenas vê um schema que descreve a função.
Para criar uma tool, escreves uma função Python normal e colocas o decorator at-tool diretamente por cima dela. Este decorator faz algo crucial. Inspeciona a signature da tua função, extrai o nome da função, lê as type hints de cada parâmetro e faz o parse da docstring. Pega em todos estes metadados e agrupa-os num formato estruturado que o language model consegue realmente ler.
Como o modelo apenas lê este schema gerado, a precisão no teu código é crítica. Vejamos um cenário. Supõe que escreves uma função chamada search database. Se lhe deres uma docstring fraca que apenas diga, pesquisa na base de dados, e omitires completamente as type hints, o language model fica a voar às cegas. Não sabe que tipo de base de dados é, e não sabe que argumentos fornecer. Pode tentar passar uma frase de conversação completa como search query, fazendo com que a tua função Python dê crash quando for executada.
Aqui está o ponto chave. Quando usas o decorator at-tool, tens de escrever as tuas docstrings para o language model, não para o developer humano. Em vez de uma descrição vaga, escreves uma instrução clara, como, pesquisa na base de dados de clientes por endereço de email para recuperar o histórico de faturação passado.
A seguir, aplicas type hints rigorosas aos teus parâmetros de input. Especificas que o argumento email tem de ser uma string. Podes até adicionar uma descrição ao próprio argumento. Cada pedaço de informação de tipo que adicionas dá ao language model um limite mais apertado sobre o que lhe é permitido gerar.
Quando passas esta tool recém-decorada a um agente, o agente lê o schema detalhado antes de fazer qualquer outra coisa. Quando um utilizador pergunta sobre o reembolso de um cliente, o agente analisa as tools disponíveis e reconhece que a tool search database é a escolha certa, com base na tua docstring precisa. Graças à tua type hint rigorosa, sabe exatamente como formatar o argumento. Extrai a string de email a partir do prompt do utilizador, interrompe a sua geração de texto e faz o output de uma tool call.
O LangChain interceta essa tool call. Pega na string de email que o modelo gerou, passa-a para a tua função Python subjacente e executa o código. A tua função comunica com a base de dados, vai buscar o histórico de faturação e devolve os dados em bruto diretamente ao LangChain. O LangChain depois alimenta esses dados de volta ao agente como uma observação. O agente retoma o seu processo de pensamento, mas agora tem os dados reais que acabaste de fornecer.
A capacidade de agir do language model é completamente limitada pela qualidade da signature da tua função. Trata as tuas docstrings e type hints como restrições de engenharia rigorosas, porque para o language model, elas são as únicas instruções que existem. É tudo neste episódio. Obrigado por ouvires, e continua a desenvolver!
6
Injetar Contexto de Ferramentas
3m 48s
Mergulhamos na passagem de informações de runtime diretamente para as suas ferramentas sem as expor ao LLM. Irá aprender a utilizar o parâmetro ToolRuntime para configurações seguras e com injeção de dependências.
Olá, daqui é o Alex da DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episódio 6 de 20. Se dependes de um modelo de linguagem para passar corretamente um token de autenticação ou a identidade de um utilizador para uma tool de base de dados, estás a preparar-te para uma enorme falha de segurança. O modelo não sabe quem é o utilizador atual e, certamente, não deves confiar nele para adivinhar. Precisas de uma forma de passar dados sensíveis do backend diretamente para as tuas tools, ignorando o modelo por completo. É exatamente isto que a injeção de Tool Context resolve.
Quando constróis uma tool, alguns argumentos são para o modelo gerar, como uma search string ou um intervalo de datas. Outros argumentos são estritamente para a tua infraestrutura de backend. É aqui que o objeto ToolRuntime entra em ação. Ele permite-te injetar configuração estática numa tool exatamente quando ela é executada.
Podes pensar que basta passar um dicionário de configuração como um argumento normal da tool e dizer ao prompt para o ignorar. Não faças isso. Quando defines um parâmetro chamado config ou runtime na função da tua tool, o LangChain trata-os como palavras-chave reservadas. Ele oculta-os intencionalmente do schema da tool que é enviado para o modelo de linguagem. O modelo nunca os vê. Só vê os argumentos que é responsável por fornecer. Isto significa que o modelo não pode alucinar uma configuração falsa nem tentar contornar os teus limites de segurança.
Considera um cenário concreto. Estás a construir uma tool get account info para uma aplicação bancária. A tool requer um ID de utilizador para ir buscar os registos corretos à base de dados. Se o modelo fornecer este ID, um prompt injection inteligente poderia enganar o modelo, fazendo-o pedir dados de um cliente completamente diferente. Em vez disso, desenhas a função da tua tool para aceitar dois argumentos. O primeiro é o tipo de conta, que o modelo vai fornecer. O segundo é um argumento chamado runtime.
Dentro do código principal da tua aplicação, antes da tool ser invocada, preenches este objeto runtime. Especificamente, usas a propriedade runtime ponto context. Colocas o ID de utilizador real e autenticado da pessoa que está a fazer o pedido diretamente neste context. Também podes colocar lá uma ligação ativa à base de dados ou um endereço de endpoint regional.
O modelo avalia o pedido do utilizador e decide chamar a tool get account info. Ele olha para o schema, vê que precisa de fornecer um tipo de conta e faz output da palavra poupança. Não faz output de mais nada. O LangChain interceta esta chamada de execução. Ele tira o tipo de conta do modelo, combina-o de forma transparente com o runtime context do teu backend e executa a função Python. Dentro da função, extrais o ID de utilizador do context e corres a tua query à base de dados com segurança.
Este mecanismo dá-te uma dependency injection segura. Podes injetar qualquer coisa que a tua tool precise para funcionar e que o modelo não tem nada que saber. API keys para serviços de faturação de terceiros, file system paths ou tenant identifiers numa arquitetura multi-tenant, tudo isto pertence ao runtime context.
Aqui está o ponto chave. Ocultar os argumentos de configuração por trás do runtime context garante que o teu modelo atue puramente como um logic router, enquanto o teu código de aplicação mantém um controlo absoluto e sem compromissos sobre o acesso aos dados e a segurança da execução.
Obrigado por passares uns minutos comigo. Até à próxima, fica bem.
7
Persistência ao Nível da Thread
3m 28s
Abordamos a memória de curto prazo e como manter o histórico de conversação. Irá aprender a anexar checkpointers ao seu agente para permitir que as conversas sejam pausadas, retomadas e lembradas.
Olá, daqui é o Alex da DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episódio 7 de 20. Sem memória, cada interação com o teu agente de IA parece uma cena do filme A Primeira Vez. O modelo começa completamente em branco, esquecendo tudo o que discutiste há segundos. A solução é a persistência ao nível da thread.
Os large language models são totalmente stateless. Processam texto e devolvem texto, não retendo absolutamente nada entre requests. Para manter uma conversa, um agente precisa de uma forma de guardar e recuperar interações passadas. No contexto de uma única sessão ativa, lidamos com isto através da memória de curto prazo, que é gerida como parte do state do agente e persistida usando checkpointers.
As pessoas costumam pensar que a memória na IA é uma capacidade interna do modelo, onde a rede neural magicamente se lembra de ti. Não é. A memória é apenas o histórico de mensagens. A persistência ao nível da thread significa simplesmente pegar na lista contínua de mensagens, guardá-la numa base de dados após cada step, e inseri-la de volta no prompt antes que o modelo veja o próximo input. O checkpointer gere isto automaticamente para que não tenhas de escrever a lógica de armazenamento e recuperação manualmente.
No LangGraph, o state é guardado por thread. Uma thread representa uma sessão contínua. Para ativar isto, precisas de um checkpointer. Para desenvolvimento e testes, podes usar o In Memory Saver. Quando compilas o graph do teu agente, passas este objeto saver como argumento do checkpointer. Esta integração diz ao agente que, no final da execução de cada node, ele deve fazer um snapshot do seu state atual e entregá-lo ao saver. O state inclui tudo o que definiste no teu graph, que normalmente é uma lista contínua de mensagens.
Vejamos um cenário concreto. Compilas o teu agente com um In Memory Saver. Agora, queres invocar o agente. Em vez de passares apenas uma mensagem do utilizador, passas também um objeto de configuração com um thread ID específico. Vamos usar o valor de string conversation one. Envias a mensagem, my name is Bob. O agente recebe isto, gera uma saudação educada e termina. Nos bastidores, o checkpointer guarda o state atualizado, que agora contém a mensagem a dizer que o teu nome é Bob, indexada sob conversation one.
Mais tarde, invocas o agente uma segunda vez. Envias uma nova mensagem a perguntar, what is my name. Crucialmente, passas exatamente o mesmo objeto de configuração com o thread ID conversation one.
Aqui está o ponto chave. Antes de o agente encaminhar a tua nova pergunta para o modelo, o checkpointer interceta o processo. Ele procura por conversation one no In Memory Saver. Recupera o snapshot do state da tua interação anterior, carrega o histórico de mensagens guardado e anexa a tua nova pergunta no final. O language model recebe o contexto histórico completo, vê a mensagem anterior onde te apresentaste, e responde com sucesso que o teu nome é Bob.
Se mudasses o thread ID para conversation two e perguntasses o teu nome, o checkpointer procuraria por esse novo ID, não encontraria nenhum state existente, e inicializaria uma lista de mensagens nova e vazia. O agente não faria ideia de quem tu és. O thread ID é a única chave que une uma sequência de chamadas ao modelo isoladas e stateless numa sessão coerente de memória de curto prazo.
O checkpointer abstrai o trabalho repetitivo de gerir arrays de mensagens e consultar bases de dados, garantindo que o teu agente pode retomar o trabalho exatamente onde parou, desde que forneças o thread ID correto.
Obrigado por ouvires — até à próxima.
8
Comprimir Contexto com Middleware
3m 38s
Exploramos como evitar que conversas longas bloqueiem o seu modelo. Irá aprender a utilizar o SummarizationMiddleware para comprimir automaticamente mensagens antigas e poupar tokens.
Olá, daqui fala o Alex da DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episódio 8 de 20. Quanto mais longa for uma conversa, mais um large language model se distrai com informação obsoleta. Perdes precisão enquanto pagas custos de tokens mais altos a cada turno. Comprimir o contexto com um middleware resolve exatamente este problema.
À medida que o histórico do chat cresce, acabas por atingir o limite da context window do teu modelo. Mesmo antes de atingires esse limite rígido, alimentar o modelo com milhares de tokens de conversas antigas degrada a performance. A solução é o SummarizationMiddleware no LangChain. Em vez de simplesmente cortar as mensagens antigas, comprime-as num único bloco de resumo. Isto retém o significado semântico da conversa sem o enorme overhead de tokens.
Existe uma ideia errada muito comum sobre como isto funciona. As pessoas assumem frequentemente que o agent principal tem de fazer a sumarização ele próprio. Não tem, e realmente não devia. Tu queres o teu agent principal a correr no teu modelo mais inteligente e capaz para lidar com lógica complexa. Fazer o resumo é uma tarefa muito mais simples. Atribuis um modelo mais pequeno e mais barato ao SummarizationMiddleware exclusivamente para este trabalho.
Configurar o middleware requer a definição de dois parâmetros principais. O primeiro é o trigger. O trigger diz ao middleware quando deve intervir. Podes configurar o trigger para ativar sempre que a contagem total de tokens da conversa atingir os 4000 tokens. O segundo parâmetro é a keep condition. Isto diz ao middleware quanto do contexto recente deve deixar completamente intocado. Podes definir o valor de keep para 20, o que significa que as 20 mensagens mais recentes permanecem intocadas.
Aqui tens o fluxo lógico na prática. O teu utilizador está a conversar com o agent principal. A conversa cresce. No turno seguinte, o histórico total de mensagens ultrapassa o limite de 4000 tokens. Antes mesmo de o agent principal ver o novo input do utilizador, o SummarizationMiddleware interceta o request. Ele analisa o histórico e identifica tudo o que for mais antigo do que as 20 mensagens mais recentes. Pega nesse chunk mais antigo da conversa e entrega-o ao teu modelo mais pequeno designado. Digamos que configuraste o middleware para usar o gpt-4.1-mini.
Esse modelo mais pequeno lê as mensagens antigas e gera um parágrafo conciso a resumir o que foi discutido. O middleware depois reescreve o array de histórico. Substitui todas essas mensagens antigas e individuais por uma única system message que contém o novo resumo. Se já havia um resumo mais antigo de um ciclo de compressão anterior, o middleware inclui-o no prompt para que o novo resumo atualize a narrativa em curso.
O pacote final enviado ao teu agent principal é altamente otimizado. Contém a nova mensagem de resumo, seguida pelas 20 mensagens recentes não comprimidas, seguidas pelo último input do utilizador.
Aqui está o ponto chave. O agent principal nunca percebe que o histórico foi comprimido nos bastidores. Recebe apenas uma context window limpa e altamente relevante. Preservas o significado semântico a longo prazo do chat, manténs o modelo focado e reduzes drasticamente os teus custos de tokens em cada turno subsequente.
Se achas estes episódios úteis e queres apoiar o programa, podes procurar por DevStoriesEU no Patreon. Por este episódio é tudo. Obrigado por ouvires, e continua a programar!
9
Formatos de Dados Garantidos
3m 37s
Discutimos como forçar os modelos de linguagem a devolver estruturas de dados estritas e previsíveis. Irá aprender a diferença entre ProviderStrategy e ToolStrategy para gerar modelos Pydantic.
Olá, daqui é o Alex da DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episódio 9 de 20. Construir software que depende de fazer parsing de respostas em linguagem natural com expressões regulares é uma bomba-relógio. Pedes a um modelo de linguagem um data object simples, e ele dá-te dados perfeitos, exceto que adiciona uma saudação educada no início e envolve tudo em formatação markdown. O teu parser vai abaixo instantaneamente. Guaranteed Data Formats são a forma de resolveres isto permanentemente.
O structured output força o modelo de linguagem a devolver a informação exatamente da forma que a tua aplicação espera. Transforma a geração de texto imprevisível em software objects fiáveis. Considera um sistema que processa mensagens inbound de suporte ao cliente. Um utilizador envia um parágrafo confuso e não estruturado a queixar-se de um problema de login, mas enterra o seu nome, endereço de email e número de telefone algures no texto. Precisas desses três dados para desencadear uma pesquisa na base de dados.
Em vez de escreveres um prompt complexo a implorar ao modelo para formatar a sua resposta corretamente, defines um modelo Pydantic standard. Crias uma class chamada ContactInfo e defines name, email e phone como campos obrigatórios. Depois, simplesmente passas este schema Pydantic para o parâmetro response format da configuração do teu modelo de linguagem. Não precisas de fornecer exemplos nem de escrever scripts de validação custom.
Esta é a parte que interessa. Quando forneces esse schema Pydantic, o LangChain determina automaticamente a forma mais fiável de o aplicar. Faz isto selecionando silenciosamente entre dois execution paths diferentes.
Primeiro, verifica se o modelo de linguagem que escolheste tem uma funcionalidade oficial de structured output integrada na sua API. Se tiver, o LangChain seleciona automaticamente a Provider Strategy. Esta estratégia envia o teu schema diretamente para o provider, tirando partido das suas constraints nativas server-side para garantir o formato de output.
Mas o hardware muda e os modelos são trocados. Se decidires usar um modelo diferente que não tenha structured output nativo, o LangChain deteta esta falha de capacidade. Faz automaticamente o fallback para a Tool Strategy. Under the hood, traduz o teu schema ContactInfo para uma function signature. Informa o modelo sobre uma tool falsa que requer exatamente um name, um email e um phone para correr. O modelo tenta fazer a call a esta tool, e ao fazê-lo, gera os argumentos estruturados exatos de que precisas. O código da tua aplicação nunca tem de mudar para acomodar a troca.
Quando a operação termina, os developers muitas vezes procuram os seus dados no sítio errado. Podes assumir que o output é devolvido como raw text que ainda tens de fazer parse. Não é raw text. O LangChain interceta o payload e instancia o objeto Pydantic para ti. Coloca este objeto Python totalmente validado diretamente no state da tua aplicação. Vais encontrá-lo capturado na key structured response do teu state dictionary. Simplesmente referencias essa key, e tens imediatamente o teu objeto ContactInfo, com campos type-safe prontos a passar para o resto da tua aplicação.
Ao transferir o peso da validação de schema da lógica de parsing custom para a layer do framework, as tuas integrações de modelo de linguagem tornam-se tão previsíveis como uma API call standard.
Obrigado por ouvires — até à próxima.
10
Intercetar o Ciclo do Agente
3m 31s
Introduzimos o paradigma de middleware, dando-lhe um controlo cirúrgico sobre a execução do seu agente. Irá aprender a utilizar hooks wrap-style e node-style para intercetar chamadas de modelos.
Olá, daqui fala o Alex da DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episódio 10 de 20. Se o teu agent falha silenciosamente em production, muitas vezes é porque não estás a monitorizar o que acontece entre os steps do seu reasoning loop. O modelo crasha, o loop quebra, e ficas a olhar para uma run incompleta. Intercetar o agent loop com um middleware custom é como recuperas o controlo.
Quando um agent corre um ciclo ReAct, ele troca constantemente o controlo com o language model. O middleware fornece hooks para executares a tua lógica exatamente quando precisas durante essa troca. Há dois tipos principais de hooks que vais usar: node-style hooks e wrap-style hooks. Um erro comum é tratá-los como se fossem a mesma coisa. Os node-style hooks correm sequencialmente. Os wrap-style hooks envolvem mesmo a execução e conseguem apanhar exceptions.
Os node-style hooks usam decorators chamados before model e after model. Quando ligas um before model hook a uma função, a framework corre a tua lógica até ao fim, e só depois é que chama a API do language model. Quando o modelo responde, corre um after model hook. Estes hooks são excelentes para fazer log do prompt exato enviado para a API, injetar contexto, ou limpar caracteres inválidos do output de texto final. Mas como correm estritamente em sequência, não oferecem qualquer proteção contra falhas. Se a API do language model der timeout, o teu after model hook nunca chega a correr. O erro sobe e crasha o agent loop inteiro.
Esta é a parte que interessa. Se precisares de lidar com instabilidade, usas um wrap-style hook. O decorator para isto é o wrap model call. Um wrap hook fica completamente à volta da execução do modelo. A tua função corre, faz algum setup, e depois cede explicitamente o controlo ao modelo. Como o teu código custom envolve a network call real, podes colocar essa execução dentro de estruturas standard de error handling.
Imagina construíres um middleware wrap model call para lidar com API rate limits através de um exponential backoff retry loop. Escreves uma função com o decorator wrap model call. Dentro desta função, crias um retry loop. Colocas o comando que passa o controlo para o modelo dentro de um bloco try. Se o modelo tiver sucesso, apanhas a response, fazes o return, e o loop termina. Se o modelo atirar um erro, o teu bloco catch interceta-o. Em vez de falhar o agent, o teu bloco catch dispara uma pausa. Calculas um pequeno delay, esperas, e depois deixas o loop tentar a call novamente, duplicando o delay de cada vez.
O agent orchestrator nunca chega a ver as falhas. O middleware apanha as exceptions, gere a retry logic de forma isolada, e devolve suavemente uma response com sucesso ao ReAct loop principal quando finalmente for bem-sucedido.
Os node-style hooks preparam os inputs e formatam os outputs, mas os wrap-style hooks protegem a execução. Por agora é tudo. Até à próxima!
11
Engenharia de Contexto Dinâmica
4m 03s
Mergulhamos na engenharia de contexto através da geração dinâmica de prompts de sistema. Irá aprender a utilizar middleware para alterar instruções com base no papel do utilizador atual e no ambiente.
Olá, daqui é o Alex do DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episódio 11 de 20. A razão número um para o teu agent falhar não é porque o modelo subjacente seja estúpido. É porque lhe deste o contexto errado para o trabalho. Se o teu sistema trata um superuser e um guest exatamente da mesma forma, a tua aplicação está cega para a realidade. Para corrigir isto, usamos Dynamic Context Engineering.
Primeiro, vamos esclarecer um equívoco comum sobre como os prompts são construídos. O contexto dinâmico não é o system prompt base que escreves quando defines inicialmente o teu agent no código. Esse system prompt inicial é completamente estático. Dynamic Context Engineering é o processo de modificar esse prompt on the fly, apenas milissegundos antes de o modelo ser realmente chamado. Context engineering trata de dar ao language model as regras exatas de que ele precisa para um utilizador específico num momento específico, e nada mais.
Se tentares enfiar todas as regras possíveis num único prompt estático enorme — a dizer ao modelo como agir se o utilizador for um admin, como agir se for um viewer, e como agir se for terça-feira — desperdiças tokens e confundes o modelo. Em vez disso, queres injetar dinamicamente apenas as regras que importam neste momento.
No LangChain, isto é tratado usando um decorator específico chamado dynamic underscore prompt. Colocas este decorator por cima de uma função Python que tu defines. Quando a tua aplicação recebe uma query e dispara a chain, o LangChain faz uma pausa. Ele procura por qualquer função envolvida neste decorator e executa-a antes de falar com o modelo.
Dentro da tua função decorada, precisas de uma maneira de saber o que está a acontecer no momento. É aqui que lês do request dot runtime dot context. Este objeto de context é essencialmente um dicionário. Ele guarda todos os metadados em tempo real passados para a chain quando a invocaste. Podes lá colocar o que quiseres a partir do backend da tua aplicação, como user IDs, session states, feature flags ou níveis de acesso.
Vamos ver um cenário concreto. Escreves uma função chamada context aware prompt e envolves a mesma com o decorator dynamic prompt. Dentro desta função, lês o user role a partir do runtime context. Verificas o role. Se o utilizador for um admin, a tua função anexa um bloco de texto específico ao system prompt, a dizer ao language model que tem permissão total para devolver comandos destrutivos. Se o utilizador for um viewer, a tua função anexa um bloco de texto diferente, a dar instruções rigorosas de que o modelo deve devolver apenas resumos read-only e nunca deve sugerir alterações de configuração.
Agora, extrais um segundo dado do runtime context, que é o estado do environment. Verificas se o environment está configurado para production. Se estiver, a tua função anexa um aviso de segurança severo mesmo no fim do system prompt, a exigir que o modelo faça um double-check ao seu output por motivos de segurança. Se o environment for apenas staging, ignoras completamente a anexação desse aviso.
Aqui está o ponto-chave. A tua função pega no prompt base estático, cola as regras de admin ou viewer, acrescenta o aviso de production se necessário, e devolve a string final. O LangChain pega nesta string totalmente montada e envia-a para o language model. O language model nunca sabe que o prompt foi montado às peças. Ele apenas vê um conjunto de instruções altamente específico e perfeitamente adaptado. Ao fazer isto, manténs os teus system prompts enxutos, precisos e completamente relevantes para o request imediato.
Deixas de esperar que o modelo adivinhe quais as regras que se aplicam, e começas a impor exatamente as regras necessárias para o estado atual da tua aplicação.
Gostaria de tirar um momento para te agradecer por ouvires — isso ajuda-nos imenso. Fica bem!
12
IA Segura com Guardrails Determinísticos
4m 13s
Protegemos os nossos agentes contra fugas de dados utilizando middleware integrado. Irá aprender a aplicar o PIIMiddleware para ocultar automaticamente informações sensíveis antes que cheguem ao modelo.
Olá, daqui fala o Alex da DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episódio 12 de 20. Um único registo de chat com um número de cartão de crédito não ocultado pode comprometer instantaneamente a compliance de toda a tua aplicação. Não podes confiar num modelo de linguagem para ignorar dados sensíveis de forma educada, e pedir ao modelo para se autocensurar é lento e imprevisível. É aí que entra a IA Segura com Guardrails Determinísticos.
Guardrails determinísticos são verificações hardcoded, baseadas em regras. Baseiam-se em padrões e lógica previsíveis, como expressões regulares ou algoritmos fixos, em vez de pedir a outro modelo de linguagem para avaliar o texto. Como evitam a network call para uma IA, executam-se em milissegundos e têm um custo praticamente nulo. Se estás a desenvolver para produção, esta camada determinística é obrigatória para a segurança.
No framework, implementas isto usando o PII Middleware. Um erro frequente que os developers cometem é tentar filtrar informações sensíveis à posteriori, analisando o output do modelo. Mas, para proteger a privacidade do utilizador, o PII Middleware foi desenhado para intercetar a raw message assim que o utilizador carrega em enviar. Processa o texto antes mesmo da model call ser iniciada. Configuras explicitamente este comportamento definindo o parâmetro apply to input como true.
Vamos analisar um cenário de um agente de apoio ao cliente. Um utilizador stressado envia uma mensagem a informar que a sua conta está bloqueada, incluindo o seu endereço de email pessoal, e de seguida cola o número completo do seu cartão de crédito de dezasseis dígitos para verificar a compra. Se o teu código passar essa raw string para um provider de IA de terceiros, violaste a compliance básica de dados. Precisas de uma estratégia para neutralizar o texto, e o middleware dá-te três ações built-in: block, redact e mask.
Se usares a estratégia block, o middleware age como uma barreira rígida. No momento em que deteta o formato do cartão de crédito, lança um erro estrito e termina a chain por completo. O request é rejeitado imediatamente.
Se escolheres a estratégia redact, o middleware remove cirurgicamente os dados específicos e coloca um placeholder limpo. O endereço de email pessoal é completamente apagado da string e substituído pela palavra email entre parênteses retos. O modelo de linguagem continua a ler uma frase coerente e percebe que um email foi fornecido, mas os dados reais desapareceram.
A terceira estratégia é mask. O masking retém uma parte segura dos dados originais. O middleware substitui os primeiros doze dígitos do cartão de crédito por asteriscos, deixando apenas os últimos quatro números expostos. Isto é altamente eficaz quando o teu sistema de backend precisa de verificar uma conta sem expor todo o registo financeiro.
Implementar isto requer a configuração do middleware antes da tua chain correr. Instancias o PII Middleware e forneces-lhe uma lista de entidades alvo. Neste caso, especificas email e cartão de crédito. De seguida, atribuis as tuas estratégias escolhidas a essas entidades, talvez optando por redact para o email e mask para o cartão. Finalmente, anexas este componente de middleware à tua chain principal, garantindo que defines o parâmetro apply to input. No momento em que o utilizador submete a sua mensagem, as regras determinísticas limpam o texto, e a IA recebe apenas um prompt sanitizado.
Aqui está o ponto chave. A forma mais segura de lidar com informações pessoais sensíveis em qualquer arquitetura de IA generativa é garantir que o modelo de linguagem nunca as chega a ver. É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
13
Pausar para Aprovação Humana
3m 38s
Exploramos a execução de ferramentas de alto risco adicionando um humano ao ciclo. Irá aprender a interromper a execução de um agente para aprovar, editar ou rejeitar ações sensíveis.
Olá, daqui fala o Alex da DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episódio 13 de 20. Um agente autónomo é incrivelmente poderoso, até ao momento em que envia por e-mail um rascunho dos teus relatórios financeiros para o cliente errado. Algumas ações são simplesmente demasiado arriscadas para serem executadas sem supervisão humana. É exatamente por isso que usamos a pausa para aprovação humana.
Os agentes executam tools automaticamente com base nos prompts do utilizador. Este comportamento é ideal para ler dados, mas é perigoso para ações destrutivas ou irreversíveis. Precisamos de uma forma de pausar a execução, perguntar a um humano se uma ação é segura e, depois, retomar ou abortar.
Antes de discutirmos a mecânica, temos de esclarecer um ponto de falha comum. Os engenheiros às vezes configuram interrupts e depois perguntam-se por que razão o agente simplesmente crasha ou reinicia. Tens de ter um checkpointer ativado. Não podes pausar um agente se ele não se conseguir lembrar de onde parou. Toda a memória do agente e o progresso atual devem ser guardados na persistence layer enquanto ele aguarda a resposta de um humano. Sem checkpointer, não há pausa.
Com a persistência ativa, podes gerir a execução de tools com segurança usando o middleware Human In The Loop. Considera uma configuração em que o teu agente tem duas tools: uma search tool e uma delete database tool. Queres que o agente pesquise livremente, mas não queres de todo que ele faça drop de tabelas sem permissão.
Ao configurares este middleware, defines um argumento chamado interrupt on. Passas-lhe os nomes específicos das tools que requerem supervisão. No nosso cenário, configuras o interrupt on para monitorizar apenas a delete database tool. A search tool é ignorada pelo middleware e executa imediatamente sempre que o agente a chama. No entanto, quando o agente decide que precisa de utilizar a delete database tool, o middleware interceta o pedido. Pausa o graph, guarda o estado atual no teu checkpointer e interrompe a execução por completo.
O graph está agora suspenso na persistence layer, a aguardar intervenção humana. O operador humano revê a tool call pendente e tem três formas de responder ao middleware.
O primeiro tipo de decisão é approve. O humano analisa os parâmetros que o agente gerou, concorda que estão corretos e envia um comando de aprovação. O graph acorda e executa a eliminação exatamente como o agente planeou originalmente.
O segundo tipo de decisão é reject. O operador vê que o agente está a tentar eliminar o alvo errado e envia uma rejeição. A tool não executa. Em vez disso, o agente recebe uma observação a indicar que a ação foi bloqueada por um humano. O agente depois processa este feedback e pode tentar uma abordagem diferente ou pedir esclarecimentos ao utilizador.
Aqui está o ponto-chave. A terceira opção é edit. Às vezes, o agente está quase correto, mas comete um pequeno erro, como apontar para o ambiente de produção em vez do ambiente de staging. Em vez de rejeitar a ação por completo e forçar o agente a raciocinar sobre o problema novamente, o operador pode modificar os parâmetros de input da tool diretamente. O humano altera o ambiente de destino para staging e submete a call corrigida. O agente retoma e executa a ação usando os parâmetros modificados, prosseguindo sem problemas.
Ao usares este middleware, proteges o teu sistema de erros perigosos. Pausar para aprovação humana não previne apenas catástrofes, transforma o teu agente de uma entidade imprevisível num colaborador supervisionado que consegue lidar com segurança com operações de alto risco.
É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
14
Feedback de Agentes em Tempo Real
3m 40s
Mergulhamos no streaming para melhorar drasticamente a experiência do utilizador. Irá aprender a interpretar modos de stream para exibir tokens de LLM em tempo real juntamente com atualizações personalizadas da execução de ferramentas.
Olá, daqui é o Alex da DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episódio 14 de 20. Os utilizadores não se importam de esperar dez segundos por uma resposta complexa, desde que lhes mostres o que o cérebro está a fazer durante esses dez segundos. Um ecrã em branco dá a sensação de uma aplicação avariada. A solução para a latência percebida é o Real-Time Agent Feedback.
Para resolver o problema do ecrã em branco, o LangChain expõe um parâmetro chamado stream mode quando executas o teu agent ou graph. Ele controla exatamente que tipo de dados o agent envia de volta pela ligação enquanto está a correr. O primeiro modo que precisas de conhecer é o messages mode. Este modo trata do clássico efeito de digitação. Faz stream dos raw tokens do language model à medida que são gerados. Se o modelo estiver a escrever um parágrafo, a tua aplicação recebe os chunks de texto um a um, permitindo que o teu frontend atualize de forma suave em vez de esperar pelo bloco de texto inteiro.
As pessoas costumam confundir o streaming dos tokens da resposta final com o streaming do raciocínio intermédio. São coisas completamente diferentes. Se o teu agent decidir chamar uma tool de pesquisa, a geração de tokens para. O language model fica à espera que a tool termine. Se essa tool demorar cinco segundos a correr, a tua interface de utilizador congela durante cinco segundos. O messages mode por si só não diz ao utilizador o que o agent está realmente a fazer em background. Apenas mostra o que o language model está a dizer.
Para resolver o problema da tool silenciosa, usas o custom mode. O custom mode permite que as tuas tools e nodes internos emitam as suas próprias atualizações de status em tempo real diretamente para a stream. Para implementar isto, usas um utilitário do LangChain chamado get stream writer. Chamas esta função dentro do código da tua tool. Ela dá-te um objeto writer, que podes usar para emitir eventos custom de volta para o cliente a qualquer momento durante a execução da tool.
Imagina uma tool lenta de verificação da meteorologia. O teu agent recebe um prompt a pedir a previsão e decide chamar a tool de meteorologia. Dentro da função Python dessa tool, vais buscar o stream writer. À medida que a tool começa a consultar uma API remota lenta, usas o writer para emitir um evento custom com um status como Acquired data. O teu frontend recebe este evento custom imediatamente e mostra um loading spinner com esse texto. O utilizador sabe que o agent está a trabalhar. Assim que a API remota devolve os dados, a tool termina e o language model retoma o controlo. Ele pega nos dados meteorológicos brutos, formula uma resposta amigável para o utilizador, e a messages stream volta a entrar em ação, a digitar a previsão final no ecrã.
Aqui está o ponto chave. Não tens de escolher apenas um modo. Podes passar uma lista com messages e custom para o parâmetro stream mode. O LangChain vai intercalar automaticamente os tokens do language model e os logs da tua custom tool num único feed contínuo. O teu frontend apenas verifica o tipo de evento à medida que chega. Se for um evento custom, atualizas o indicador de status. Se for um evento message, adicionas o token ao balão de chat. A latência percebida cai para zero porque o sistema está sempre a falar com o utilizador.
Se quiseres ajudar a manter estes episódios a sair, podes apoiar o programa procurando por DevStoriesEU no Patreon. Obrigado por ouvirem, e happy coding para todos!
15
Persistência Entre Sessões
3m 13s
Exploramos a memória a longo prazo para construir agentes que conhecem verdadeiramente os seus utilizadores. Irá aprender a utilizar as stores do LangGraph para guardar documentos JSON em conversas totalmente diferentes.
Olá, daqui é o Alex da DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episódio 15 de 20. Para construíres um assistente verdadeiramente personalizado, ele precisa de se lembrar que preferes respostas breves, mesmo que lhe tenhas dito isso há três semanas num chat completamente diferente. Se dependeres apenas da memória de conversação standard, essa preferência desaparece no momento em que inicias uma nova thread. O mecanismo que impede esta amnésia é a Cross-Session Persistence usando o paradigma de Store.
Muitos developers confundem o checkpointer com a store. Aqui está a diferença. Um checkpointer gere o state de curto prazo. Ele lembra-se de uma única thread de conversação. Quando o utilizador cria um novo chat, o checkpointer começa do zero. A Store ultrapassa esses limites de thread. Ela permite que os teus agents persistam e recuperem informação globalmente, em todas as interações com um utilizador específico.
Na sua essência, a memória de longo prazo no LangChain é apenas uma key-value store hierárquica. Ela persiste documentos JSON. A hierarquia baseia-se em namespaces. Um namespace é uma sequência de strings que funciona exatamente como o path de uma pasta no teu computador. Se quiseres guardar dados de perfil, podes usar um namespace contendo a string "users", seguido pelo identificador do utilizador. Dentro desse namespace, tu guardas itens. Cada item requer uma string key única e um dictionary que representa o valor JSON.
É aqui que a coisa fica interessante. As tools interagem com esta store diretamente através do runtime context. Tu nunca passas a store manualmente pelo teu graph state.
Considera uma custom tool chamada save user info. O seu trabalho é capturar uma preferência de idioma falado. Durante o setup, tu inicializas a tua aplicação com uma store de suporte, como uma in-memory store para testes locais. Dentro da lógica da tua tool, acedes à instância da store diretamente a partir da runtime configuration injetada. Extrais o identificador do utilizador a partir do context atual. A seguir, chamas o método put na store. Forneces o namespace tuple contendo a palavra "users" e o user ID. Defines uma key, como "language preference", e finalmente passas o dictionary JSON contendo o valor, talvez "Spanish".
A store persiste este documento. Semanas depois, o utilizador inicia uma thread completamente nova. O thread state está vazio. Mas como o agent tem acesso a uma retrieval tool, ele pode chamar o método get na runtime store usando exatamente o mesmo namespace e key. Ele extrai o documento JSON, lê a preferência e responde imediatamente em espanhol.
Separar o conversational context de curto prazo da memória factual de longo prazo mantém a tua aplicação leve. O checkpointer não fica sobrecarregado com anos de histórico do utilizador, e o state permanece limpo. A store carrega apenas os documentos JSON específicos que o agent decide ir buscar explicitamente.
Tratar o context e a persistência como dois sistemas completamente distintos é a única maneira de escalar um agent de forma fiável. O checkpointer guarda o presente, enquanto a store guarda o passado.
É tudo por hoje. Obrigado por ouvires — vai construir algo fixe.
16
O Paradigma Multi-Agente
4m 18s
Explicamos por que razão os agentes únicos falham e introduzimos a arquitetura de Subagents. Irá aprender como um agente supervisor principal coordena subagentes como janelas de contexto isoladas para evitar a sobrecarga de tokens.
Olá, daqui é o Alex da DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episódio 16 de 20. Quando o teu agente de IA individual começa a falhar devido à sua enorme lista de tools e instruções concorrentes, atirar-lhe com uma context window maior não vai resolver o problema. Está na hora de parares de construir um script monolítico e começares a contratar uma equipa. É exatamente aí que entra o paradigma multi-agent.
Construímos sistemas multi-agent porque os agentes individuais atingem um limite cognitivo. Dá a um agente trinta tools, cinco páginas de system prompts e um longo histórico de conversação, e ele vai perder o foco. Ele vai chamar a tool errada ou esquecer-se das restrições. A abordagem multi-agent divide isto em partes. Permite o desenvolvimento distribuído, onde diferentes equipas gerem diferentes agentes. Permite a execução paralela. Mais importante ainda, impõe um context isolation rigoroso.
Hoje, vamos focar-nos numa arquitetura específica chamada padrão de subagents. Isto envolve um agente supervisor principal que delega tarefas a subagents especializados. As pessoas muitas vezes confundem um supervisor com um simples router. Um router é apenas uma função estática que olha para uma query e a envia por um caminho fixo. Um supervisor é um agente ativo e pensante. Ele mantém o state da conversa, decide que subagents invocar ao longo de múltiplos turnos e sintetiza as suas respostas.
Aqui está o ponto-chave. Os subagents proporcionam um context isolation perfeito. Quando o supervisor pede a um subagent para fazer algo, o subagent arranca com uma context window completamente limpa. Ele tem apenas as instruções e tools específicas de que precisa para o seu trabalho exato. O subagent pode cometer erros, chamar tools três vezes e encher o seu próprio scratchpad enquanto descobre a resposta. O supervisor nunca vê essa confusão. Ele recebe apenas o resultado final limpo. Isto protege o teu agente principal do context bloat e previne alucinações.
Para ligares o supervisor aos subagents, encapsulas os subagents como tools. Existem duas maneiras de fazer isto no LangChain. O primeiro método é tool-per-agent. Dás ao supervisor uma tool específica para cada subagent. Se tiveres cinco subagents, o supervisor tem cinco tools. O segundo método é uma single-dispatch tool. Aqui, o supervisor recebe exatamente uma tool chamada algo como delegate task. Esta tool requer dois inputs: o nome do agente target e a descrição da tarefa.
Considera um cenário de single-dispatch. Tens um agente principal, um agente de pesquisa e um agente de redação. Um utilizador pede um relatório de mercado complexo. O agente principal decide que precisa de dados primeiro. Ele chama a single-dispatch tool, passando o agente de pesquisa como target e a query de mercado como payload. O agente de pesquisa arranca no seu próprio contexto isolado, pesquisa na web, faz o parse de documentos e retorna um parágrafo de resumo. O agente principal recebe este texto. A seguir, o agente principal chama a dispatch tool novamente, desta vez com o agente de redação como target, passando o resumo da pesquisa e as instruções de formatação. O agente de redação redige o relatório final e retorna-o ao agente principal, que o entrega ao utilizador.
Podes executar estas subtarefas de maneiras diferentes, dependendo das tuas necessidades. Podes correr os subagents de forma síncrona, onde o supervisor espera que o agente de pesquisa termine antes de tomar qualquer outra ação. Se tiveres tarefas independentes, como pesquisar três concorrentes diferentes, podes correr os subagents de forma assíncrona. O supervisor faz o dispatch das três tarefas ao mesmo tempo, elas executam em paralelo, e o supervisor espera que todas retornem antes de avançar.
Agrupar tarefas em subagents não é apenas sobre organizar o teu código, é sobre controlar rigorosamente o que o modelo de linguagem é forçado a manter em memória a qualquer momento.
É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
17
Agentes Orientados a Estado
4m 03s
Exploramos como os agentes podem alterar dinamicamente o seu comportamento. Irá aprender o padrão Handoffs para transferir o controlo e o padrão Skills para carregar prompts especializados a pedido.
Olá, daqui é o Alex da DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episódio 17 de 20. Não precisas de sobrecarregar o cérebro do teu agent com todos os cenários possíveis à partida. Enfiar cinquenta páginas de instruções num único system prompt só deixa o teu modelo confuso, lento e caro. Só precisas de lhe ensinar a pedir o manual certo quando chegar a hora. Este é o mecanismo central por trás dos State-Driven Agents.
Os state-driven agents operam com base num princípio simples. O comportamento do agent muda dinamicamente com base no state atual da aplicação. Nós lidamos com isto usando dois patterns principais, que são Skills e Handoffs. Ambos os patterns dependem de tools para atualizar variáveis de state, que, por sua vez, ditam o que acontece a seguir no workflow.
Vamos olhar primeiro para o pattern de Skills. Este pattern tem a ver com a revelação progressiva de conhecimento. Em vez de dares a um agent todas as suas instruções logo ao início, dás-lhe uma tool. Quando o agent decide que precisa de mais informação para resolver um problema, ele chama esta tool. A tool é executada, mas faz mais do que simplesmente devolver uma string ao modelo. Ela atualiza uma variável de state específica na tua aplicação. A tua orchestration layer monitoriza este state. Quando deteta a mudança, injeta dinamicamente um novo conjunto de instruções ou capacidades no system prompt do agent logo para o turno seguinte.
Pensa num agent de suporte ao cliente normal. Inicialmente, o seu único trabalho é descobrir o que o cliente quer. Um utilizador pergunta sobre um produto avariado. O agent chama uma tool para recolher um ID de garantia. A execução desta tool atualiza uma variável de state para indicar que um pedido de garantia está ativo. A aplicação lê este novo state e carrega dinamicamente uma skill especializada de reembolso no prompt. Esta skill pode incluir as regras específicas para processar devoluções e acesso a uma base de dados de inventário segura. As capacidades do agent evoluíram a meio da conversa, impulsionadas inteiramente por um state update.
Agora, e se a tarefa necessária for demasiado complexa para o agent inicial resolver, mesmo com novas skills? É aí que entra o pattern de Handoff. Os handoffs também usam tools para atualizar o state, mas, em vez de carregar novas instruções no agent atual, a mudança de state transfere o controlo para um agent completamente diferente. Voltando ao nosso cenário. O agent de suporte recolhe o ID da garantia, mas, em vez de processar o reembolso ele próprio, chama uma handoff tool. Esta tool atualiza uma variável de routing no state, mudando o agent ativo do bot de triagem para um agent especialista, desenhado exclusivamente para devoluções de alto valor. A orchestration layer vê esta mudança de state e direciona o próximo passo do workflow para o especialista.
É neste ponto de transição que as coisas muitas vezes correm mal. Ao fazer o handoff entre agents, o novo agent precisa do contexto da conversa. Muitos developers tentam limpar o histórico passando apenas as mensagens raw do utilizador para o novo agent. Não faças isso. Ao fazer o handoff entre agents, tens de incluir a mensagem da IA que contém a própria tool call que iniciou o handoff, e a Tool message resultante que confirma que o handoff ocorreu. Se removeres a tool call e a tool message do array de mensagens, o histórico da conversa quebra. O novo modelo perde a chain lógica de eventos. Ele não vai saber como chegou ali, e provavelmente vai repetir perguntas a que o utilizador já respondeu. Passa sempre o histórico de mensagens sem quebras.
Aqui está o insight principal. O state não é apenas um memory store passivo, mas sim o control plane que dita exatamente o que o teu sistema é capaz de fazer a qualquer milissegundo.
É tudo por este episódio. Obrigado por ouvires, e continua a programar!
18
Workflows Personalizados e Routers
4m 05s
Saímos do ciclo padrão do agente. Irá aprender a utilizar o LangGraph para construir arquiteturas de routing personalizadas, misturando lógica determinística com raciocínio agêntico não determinístico.
Olá, daqui é o Alex da DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episódio 18 de 20. Às vezes, não queres que um agent de IA decida livremente o que fazer a seguir. Só queres que ele execute um fluxograma estrito e determinístico. Custom Workflows e Routers dão-te exatamente esse nível de controlo.
Quando dependes exclusivamente de um standard agent loop, estás a confiar que o language model descubra cada passo por conta própria. Pode pesquisar numa base de dados, perceber que precisa de mais dados, pesquisar novamente e, por fim, responder. Isto é poderoso, mas é imprevisível e muitas vezes lento. Os custom workflows no LangGraph permitem-te sair desse loop. És tu que desenhas o mapa. Podes misturar perfeitamente lógica determinística, como executar scripts exatos de data retrieval, com o raciocínio não-determinístico do agent. Colocas o language model dentro de uma sequência estrita de eventos.
Antes de construirmos um, precisamos de esclarecer uma confusão comum entre um router e um supervisor. Um supervisor orquestra ativamente uma conversa multi-turn. Observa os agents a falar, decide quem fala a seguir e gere o diálogo ao longo do tempo. Um router não é isso. Um router é apenas um passo de classificação. Analisa o input, decide qual o caminho que o workflow deve seguir, faz o routing dos dados, e o seu trabalho está feito. Pode ser stateless ou stateful, mas não é um gestor de conversas.
Vejamos um cenário concreto. Estás a construir uma ferramenta de knowledge base multi-source. Um utilizador faz uma pergunta, e a resposta pode estar enterrada em pull requests do GitHub, threads do Slack, ou em ambos. Não queres que um único agent ande a adivinhar às cegas onde procurar. Queres um workflow estruturado.
Primeiro, crias um routing node. Passas a query do utilizador para um language model e pedes-lhe para dar como output uma lista simples de destinos. Se a query for sobre um bug fix recente, o modelo pode dar como output as palavras GitHub e Slack.
Esta é a parte que interessa. Não tens de escolher apenas um caminho. Podes correr múltiplos agents exatamente ao mesmo tempo usando a Send API. No LangGraph, em vez de devolveres um único próximo passo da tua lógica condicional, a tua routing function devolve uma lista de comandos Send. Cada comando emparelha um destination node com os dados específicos de que ele precisa. O graph vê múltiplos comandos Send e executa automaticamente todos esses target nodes em paralelo. A isto chama-se fanning out.
Durante o fanning out, o workflow atinge os teus agent nodes. Num custom workflow, invocar um agent é simples. Um agent é simplesmente um processo runnable executado dentro de uma standard node function. O node do Slack recebe a query, corre um agent dedicado do Slack para pesquisar nos canais, extrai o contexto, e devolve-o ao graph state geral. O node do GitHub faz a mesma coisa simultaneamente para os repositórios de código. Isolar estes agents dentro de nodes específicos garante que eles só fazem o trabalho para o qual foram construídos.
Finalmente, todas essas branches paralelas têm de convergir. Fazes o fan in. Crias um synthesizer node que espera que os agents paralelos terminem. Lê o graph state geral, pega no contexto recolhido do Slack e no contexto recolhido do GitHub, entrega ambos a um language model final, e gera uma resposta única e limpa para o utilizador.
O verdadeiro poder dos custom workflows é encapsular a natureza imprevisível dos large language models dentro da fiabilidade previsível do standard software routing.
Ficamos por aqui neste episódio. Até à próxima!
19
Comunicação Agente-para-Agente
4m 39s
Exploramos o endpoint LangSmith A2A. Irá aprender como agentes distribuídos implementados em servidores totalmente diferentes podem conversar nativamente utilizando o protocolo A2A RPC da Google.
Olá, daqui é o Alex da DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episódio 19 de 20. O que acontece quando um agente desenvolvido em Python precisa de conversar nativamente com um agente desenvolvido por uma equipa completamente diferente, a correr num servidor completamente diferente? Se dependes de function calls internas hardcoded, o teu sistema falha no momento em que cruza uma fronteira de rede. A solução é a comunicação Agent-to-Agent.
Agent-to-Agent, ou A2A, é um protocolo de comunicação que permite sistemas multi-agente verdadeiramente distribuídos. Permite que agentes alojados em servidores totalmente diferentes mantenham uma conversa contínua sem precisarem de partilhar a mesma codebase subjacente ou espaço de memória local. Em vez de encapsulares tudo numa única aplicação massiva, encaminhas as requests pela rede.
A comunicação depende estritamente de um formato de endpoint definido: barra a2a barra, seguido do ID do assistente. Cada agente que participa nesta rede distribuída expõe exatamente este path de endpoint. Quando um agente precisa da ajuda de outro, envia para lá uma request HTTP POST. O payload enviado para este endpoint é estruturado como uma mensagem JSON-RPC standard.
Para manter a conversa coerente através de múltiplos network hops e servidores diferentes, o protocolo usa dois identificadores distintos no seu payload. Os developers às vezes confundem estes dois, por isso vamos definir as suas fronteiras. O primeiro é o Context ID. O Context ID é responsável pela continuidade geral da thread. Representa todo o histórico abrangente da conversa, desde o primeiro prompt até ao output final. O segundo é o Task ID. O Task ID identifica a request ou passo específico dentro desse único turno. O Context ID abrange toda a sessão. O Task ID muda sempre que um agente pede ao outro para executar uma nova ação.
Considera um cenário prático onde o Agente A está a correr num servidor à escuta na porta 2024, e o Agente B está a correr num servidor diferente na porta 2025. O Agente A percebe que precisa que o Agente B lide com uma subtask específica, talvez verificar um inventário externo. O Agente A prepara uma mensagem JSON-RPC. Dentro desta mensagem, inclui o Context ID existente para que o Agente B saiba a que conversa em curso esta pertence. O Agente A também gera um Task ID completamente novo para esta request de inventário específica.
O Agente A envia este payload para o endpoint A2A na porta 2025, inserindo o ID de assistente específico do Agente B diretamente no path do URL. O Agente B recebe a request. Lê o Context ID para recordar qualquer state de background necessário, processa a task pedida nos parâmetros JSON-RPC, e calcula o resultado. O Agente B constrói então uma response JSON-RPC. Esta response inclui explicitamente o Task ID exato que o Agente A forneceu originalmente. O Agente B envia esta response de volta para o Agente A na porta 2024. O Agente A recebe o resultado, faz o match do Task ID com a sua request pendente, e continua a sua própria execução interna.
Aqui está a ideia-chave. Como o protocolo impõe o JSON-RPC standard e isola o state tracking em identificadores de Context e Task específicos, nenhum dos agentes precisa de saber como o outro opera internamente. Não mantêm uma ligação de socket aberta e constante. Simplesmente revezam-se a passar mensagens estruturadas de um lado para o outro através de fronteiras HTTP standard. Um servidor faz uma pergunta, o outro responde, e a task global progride.
Quando separas a thread de conversa a longo prazo da execução individual de tasks a curto prazo, consegues escalar redes multi-agente através de diferentes servidores e frameworks indefinidamente. Se achas estes episódios úteis e queres ajudar a apoiar o programa, podes procurar por DevStoriesEU no Patreon. É tudo por este episódio. Obrigado por ouvires, e continua a programar!
20
O Futuro é o MCP
4m 32s
Olhamos para o futuro com o Model Context Protocol, padronizando a forma como os agentes acedem a ferramentas externas. Irá aprender a ligar servidores MCP remotos ao seu agente utilizando transportes padrão.
Olá, daqui fala o Alex da DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episódio 20 de 20. Sempre que queres que o teu agente fale com uma nova base de dados ou API, acabas por escrever um custom wrapper. A tua codebase fica cheia de integrações frágeis que falham sempre que uma API externa muda. Isto limita a velocidade com que podes escalar as tuas aplicações. A solução para este bottleneck de integração é o Model Context Protocol, ou MCP.
Pensa no MCP como o USB-C para agentes de IA. Ele padroniza a forma como as tools e o context são expostos aos large language models. Antes deste protocolo, se quisesses que o teu agente fizesse uma query a uma base de dados e verificasse um serviço de meteorologia, tinhas de escrever funções Python específicas para ambos, definir os seus input schemas manualmente, e fazer o bind deles ao teu model. Com o MCP, o próprio serviço externo fornece uma interface padronizada. O teu agente simplesmente liga-se a ele e percebe instantaneamente que tools estão disponíveis, que argumentos exigem e como executá-las.
Um mal-entendido comum é achar que usar um servidor MCP remoto significa que a lógica do teu agente se está a mover pela rede. Aqui está o ponto-chave. O teu agente permanece completamente local. O servidor remoto não corre o teu agente nem controla o seu raciocínio. Ele apenas expõe uma lista de JSON schemas padronizados que representam as tools que suporta. O teu agente local lê esses schemas, decide qual tool usar com base no user prompt, e envia um request de execução de volta para o servidor. A execução acontece lá, e o resultado raw é devolvido ao teu agente local.
No LangChain, geres estas ligações usando o MultiServerMCPClient. Este componente atua como um hub central. Ele permite que um único agente se ligue a vários servidores MCP diferentes em simultâneo, reunindo tools de todos eles. O client lida com a comunicação subjacente usando diferentes transport layers. Os dois transports principais que vais configurar são o standard input e output, referidos como stdio, e HTTP.
Vamos analisar um cenário concreto. Estás a construir um agente que precisa de realizar cálculos complexos usando um script Python local, enquanto também vai buscar dados meteorológicos em tempo real a um serviço remoto. Em vez de escreveres tool wrappers customizados para estas tarefas, configuras o MultiServerMCPClient para lidar com ambas.
Primeiro, defines o teu servidor de matemática local usando o transport stdio. Configuras o client com o comando a correr, como o executável Python do teu sistema, e o path para o teu script de matemática. Quando o client inicializa, ele arranca este script como um processo local em background. O client LangChain e o script trocam mensagens diretamente através de streams de standard input e standard output.
A seguir, defines o servidor de meteorologia usando o transport HTTP. Para isto, basta fornecer o URL do endpoint do serviço de meteorologia remoto. Esta configuração normalmente depende de Server-Sent Events para manter uma ligação persistente, permitindo que o agente peça ações e faça stream das respostas pela web.
Assim que ambos os transports estiverem definidos, inicializas o MultiServerMCPClient. O client liga-se imediatamente ao processo de matemática local via stdio e ao URL de meteorologia remoto via HTTP. Ele pede a ambos os servidores para entregarem as suas definições de tools. Ele recolhe os schemas, faz o merge deles numa lista contínua, e fornece-os ao teu agente LangChain. Da perspetiva do agente, ele vê apenas uma lista unificada de tools disponíveis. Ele não faz a mínima ideia de que uma tool é executada num processo binário local e a outra dispara um request HTTP para um servidor do outro lado do mundo.
A mudança para protocolos padronizados significa que podes passar o teu tempo a construir uma melhor lógica de agente em vez de manteres infinitos API wrappers. Como este é o episódio final da série, recomendo vivamente que leias a documentação oficial do LangChain e tentes configurar um servidor MCP local na prática. Se tiveres sugestões de tópicos que queiras ver na nossa próxima série, visita devstories dot eu e envia-nos uma mensagem. O verdadeiro poder de um agente não reside no que ele sabe, mas sim naquilo a que se consegue ligar de forma transparente.
É tudo por este episódio. Obrigado por ouvires, e continua a construir!
Tap to start playing
Browsers block autoplay
Share this episode
Episode
—
Copy this episode in another language:
Este site não utiliza cookies. O nosso fornecedor de alojamento pode registar o seu endereço de IP para efeitos analíticos. Saber mais.