Toda ferramenta que cresce rápido ganha uma aura. LangChain ganhou a de “framework de IA”: você instala, empilha uma chain, liga um retriever e o aplicativo aparece. Durante alguns meses de 2023 isso pareceu suficiente. Depois os sistemas reais chegaram — custo, falha, prompt que ninguém encontra, modelo trocado sem querer — e a aura ralou.
LangChain é útil. Não é mágica. É uma biblioteca de orquestração: encadeia prompt, modelo, parser e ferramenta. O valor está em tornar esse encadeamento explícito. O prejuízo começa quando a biblioteca esconde justamente o que você precisa ver para consertar o sistema.
O que uma chain de fato faz
Uma chain não “pensa”. Ela define uma ordem. Entrada vira prompt. Prompt vai ao modelo. Texto volta e é parseado. Se houver ferramenta, o texto vira chamada, a observação volta, outro prompt se forma. Isso é encanamento. Encanamento bom evita que cada arquivo reinvente a mesma sequência. Encanamento ruim esconde o cano que vaza.
Na editora, isso se parece com um fluxo de produção: original, revisão, diagramação, prova. Ninguém acha que o fluxo escreve o livro. Ele só impede que a prova saia antes da revisão. LangChain, no melhor uso, faz o mesmo para chamadas a modelos.
Ferramentas (tools) entram nesse quadro como ações com nome e esquema: buscar um trecho, consultar um preço, abrir um chamado. O modelo escolhe a ferramenta se você deixar. Isso já não é uma chain linear. É um pequeno agente. A distinção importa, porque o custo e o modo de falhar mudam.
flowchart LR
E[Entrada] --> P[Prompt]
P --> M[Modelo]
M --> A[Parser]
A --> T[Ferramenta]
T --> S[Saída]
classDef ouro fill:#FBF5E4,stroke:#C9A227,color:#0B1F18,stroke-width:1.4px
classDef verde fill:#F3FAF7,stroke:#1E7A57,color:#0B1F18,stroke-width:1.4px
classDef fim fill:#14513B,stroke:#0F3328,color:#FBFAF6,stroke-width:1.4px
class E ouro
class P,M,A,T verde
class S fim
LCEL é composição, não feitiço
LCEL — LangChain Expression Language — é a forma recente de dizer “isto depois daquilo” com um operador de pipe. Prompt | modelo | parser. Dicionários viram ramos em paralelo. Funções viram etapas. A leitura fica mais próxima de um fluxo de dados do que de uma classe com dezessete argumentos.
Isso é composição. Quem já encadeou funções puras reconhece o gesto. O ganho é legibilidade e a chance de reutilizar um pedaço — o parser de JSON, o retriever, o template — em outro fluxo. O ganho não é inteligência. Um pipe elegante ainda envia um prompt ruim a um modelo caro.
Três hábitos tornam LCEL honesto:
- cada etapa tem um nome que aparece no trace;
- o prompt vive num arquivo ou constante visível, não gerado por três camadas de “helper”;
- o modelo é um parâmetro, não um default enterrado.
Se você não consegue imprimir o prompt final e o nome do modelo antes de pagar a API, a composição já passou do ponto útil.
O custo de esconder o prompt e o modelo
Abstração boa esconde o irrelevante. Abstração ruim esconde a decisão.
O prompt é decisão. Ele define tom, recusa, formato, o que conta como evidência. Quando o framework monta o prompt a partir de um objeto StuffDocumentsChain ou de um template com nome genérico, o time discute a API e não o texto. Semanas depois, ninguém sabe por que o modelo inventa prazo de envio. A causa está numa frase de sistema que ninguém abriu.
O modelo também é decisão. Trocar um modelo “compatível” muda custo, latência, recusa e qualidade. Se a chain pede “um chat model” e o default muda entre versões da biblioteca, você não fez deploy de uma feature. Fez deploy de um sorteio.
Há um custo operacional extra: a superfície da biblioteca. LangChain moveu APIs com frequência. Chains antigas, novas, LCEL, agentes clássicos, agentes de ferramenta. Código de tutorial de 2023 não roda em 2025 sem reescrita. Isso não é pecado. É o preço de um ecossistema jovem. Só se torna problema quando o seu domínio — o prompt da política comercial, o parser da ficha do livro — fica refém da próxima refatoração.
Uma regra prática: a biblioteca pode orquestrar. O contrato da aplicação (prompt, esquema de saída, modelo, política de recusa) deve ser seu. Se amanhã você trocar LangChain por uma função de vinte linhas, o comportamento visível ao leitor não deveria desabar.
Quando uma chamada de API é mais clara
Há casos em que a chain é teatro.
Você tem um prompt, um modelo, um JSON de saída. Não há retriever. Não há ferramenta. Não há ramificação. Uma chamada HTTP, um response_format e um teste que compara o JSON com um exemplo bastam. Introduzir uma chain, um parser genérico e um callback “para o futuro” adiciona arquivos sem adicionar controle.
Outro caso: o fluxo tem três passos rígidos que você decide, não o modelo. Resumir o capítulo, depois extrair termos, depois gerar perguntas. Isso é um script. Um script com logs e retries é mais fácil de explicar a quem entra no time do que um grafo com nomes herdados de um tutorial.
Use a biblioteca quando ela paga o aluguel:
- você realmente reutiliza etapas entre fluxos;
- precisa de streaming, batch e trace no mesmo contrato;
- ferramentas e recuperação entram no caminho, e o glue ameaça virar um novelo.
Não use para parecer que tem “arquitetura de agentes”. Nome bonito não reduz a conta de tokens.
Orquestração visível, domínio visível
O desenho que tem funcionado, aqui e em outros times que publicam texto com modelo no meio, é chato de propósito.
O domínio fica em tipos e funções suas: Pergunta, Trecho, Resposta, recusar_se_vazio(). A orquestração chama essas funções. O prompt é um texto versionado, revisado como se revisa orelha de livro: em voz alta, com exemplo ruim ao lado do exemplo bom.
Quando a chain falha, o primeiro log mostra: modelo, número de tokens, o prompt completo, os trechos, a saída crua. Sem isso, debugar LangChain vira arqueologia de objetos.
O mesmo critério vale para ferramentas. Uma ferramenta “buscar no catálogo” precisa de esquema estreito, timeout e um resultado que um humano entenda. Se a descrição da ferramenta for vaga, o modelo chama a ferramenta errada com argumentos inventados. A biblioteca executa. A culpa não é do pipe. É da interface que você descreveu.
Uma prova de honestidade
Pegue o fluxo mais importante do seu produto e responda, sem abrir o GitHub da biblioteca:
- Qual é o prompt de sistema, palavra por palavra?
- Qual modelo, com qual temperatura?
- O que acontece se o retriever voltar zero trechos?
- Onde o JSON é validado — antes de ir para a tela?
- Quanto custa uma chamada típica, em tokens e em segundos?
Se a resposta a qualquer item for “o LangChain cuida disso”, você não tem orquestração. Tem fé. Fé é má engenharia de prompt.
LangChain, LCEL e as ferramentas ao redor são peças. Peças boas, quando você as vê. A mágica começa na hora em que o texto some atrás de uma classe. Aí o sistema ainda gera frases. Só não gera responsabilidade.
Leia também: RAG: por que recuperar contexto em vez de encher o prompt.