R
Interview Deckreact · next.js · senior/staff
0·0·122
IA Avançado

LangChain e Orquestração de LLMs

Chains, LCEL, memory, e quando LangChain vale a pena vs código direto.

LangChain é o framework mais popular para orquestrar LLMs: LCEL (LangChain Expression Language) para compor chains declarativamente, integração com 100+ LLMs e vector stores, memory abstractions, e agents. Alternativas: LlamaIndex (foco em RAG/dados), Vercel AI SDK (streaming + React), Mastra (TypeScript-first agents). Trade-off: LangChain reduz boilerplate mas adiciona abstração — às vezes uma função direta é mais simples.

Problema
Código de LLM repetitivo: parsing de resposta, retry, formatação de prompt, integração com vector stores. Mas LangChain com muitas abstrações pode tornar o debug difícil e o código harder to understand.
Solução
Usar LangChain para: RAG pipelines complexos (DocumentLoaders + Splitters + VectorStore + Retriever já integrados), chains com múltiplos steps, memory gerenciada. Usar código direto para: chamadas simples ao LLM, casos onde você precisa de total controle, ou quando a abstração do LangChain não encaixa exatamente.
Tip
LCEL (pipe operator |) é o coração moderno do LangChain: composição explícita, streaming nativo, e compatibilidade com LangSmith para tracing. `prompt | llm | parser` é legível e poderoso. Mas se você está usando LangChain só para fazer uma chamada de API, remova a dependência — a SDK direta é mais simples.
// LCEL — composição declarativa moderna
import { ChatOpenAI } from '@langchain/openai'
import { ChatPromptTemplate } from '@langchain/core/prompts'
import { StringOutputParser } from '@langchain/core/output_parsers'
import { RunnableSequence, RunnableParallel } from '@langchain/core/runnables'

const model = new ChatOpenAI({ model: 'gpt-4o', temperature: 0 })

// Chain simples com pipe
const chain = ChatPromptTemplate.fromTemplate(
  'Explique {concept} em uma frase simples.'
) | model | new StringOutputParser()

const result = await chain.invoke({ concept: 'closures em JavaScript' })

// RAG chain com LCEL
const ragChain = RunnableSequence.from([
  RunnableParallel({
    context: retriever,           // busca no vector store
    question: (input) => input,   // passa a pergunta adiante
  }),
  promptTemplate,
  model,
  new StringOutputParser(),
])

// Streaming para UI
const stream = await chain.stream({ concept: 'React Server Components' })
for await (const chunk of stream) {
  process.stdout.write(chunk) // ou enviar para o cliente
}

// Vercel AI SDK — streaming no Next.js
// app/api/chat/route.ts
import { streamText } from 'ai'
import { openai } from '@ai-sdk/openai'
export async function POST(req: Request) {
  const { messages } = await req.json()
  const result = streamText({ model: openai('gpt-4o'), messages })
  return result.toDataStreamResponse()
}
Q.LCEL vs LangChain clássico (Chain classes)?
A.LCEL (LangChain Expression Language) substituiu as Chain classes antigas. Vantagens: composição explícita com pipe operator, streaming built-in, paralelismo (RunnableParallel), retry (RunnableRetry), e integração direta com LangSmith. Chains antigas (LLMChain, ConversationalRetrievalChain) ainda funcionam mas não recebem novos features.
Q.Quando usar Vercel AI SDK vs LangChain?
A.Vercel AI SDK: projetos Next.js com streaming de UI, useChat/useCompletion hooks React, deploy na Vercel, simplicidade máxima. LangChain: RAG complexo, agents multi-step, múltiplos providers, pipelines de data processing. Para apps Next.js simples: Vercel AI SDK. Para sistemas de agentes complexos: LangChain ou LlamaIndex.
Q.Como fazer streaming de respostas do LLM na UI?
A.Vercel AI SDK com useChat(): no servidor, `streamText()` com o provider. No cliente, `useChat()` hook que recebe chunks incrementalmente e atualiza `messages`. Para Next.js App Router: Route Handler com `return result.toDataStreamResponse()`. O usuário vê a resposta sendo digitada em vez de esperar o response completo.
92/122← →