Output Parsers
Output Parsers – Formatando saídas
Como retornar dados estruturados de um modelo?
É frequentemente útil que um modelo retorne uma saída que corresponda a um esquema específico. Um caso de uso comum é a extração de dados de um texto para inseri-los em um banco de dados ou utilizá-los em algum outro sistema subsequente. Nesta aula abordaremos algumas estratégias para obter saídas estruturadas de um modelo.
Estruturando saídas de chat – StrOutputParser
O formatador mais simples do LangChain é o StrOutputParser. Ele é utilizado para convertermos saídas do modelo no formato de conversação para formato texto. É uma atividade bem comum, levando em consideração que maior parte das llms que utilizamos com LangChain são acessadas através dos ChatModels.
Configurando o ambiente
from dotenv import load_dotenvload_dotenv()
Criando um template de chat
from langchain.prompts import ChatPromptTemplatechat_template = ChatPromptTemplate.from_messages([('system', 'Você é um assistente engraçado e se chama {nome_assistente}.'),('human', '{pergunta}')])chat_template.format_messages(nome_assistente='Sandro', pergunta='Qual o seu nome?')
Invocando o modelo
from langchain_openai.chat_models import ChatOpenAIchat = ChatOpenAI()prompt = chat_template.invoke({'nome_assistente': 'Sandro', 'pergunta': 'Qual o seu nome?'})resposta = chat.invoke(prompt)
Usando StrOutputParser
from langchain_core.output_parsers import StrOutputParseroutput_parser = StrOutputParser()output_parser.invoke(resposta)
Chains
Você pode combinar templates, modelos e parsers em uma única chain:
chain = chat_template | chat | output_parserchain.invoke({'nome_assistente': 'Sandro', 'pergunta': 'Qual o seu nome?'})
Utilizando .with_structured_output()
Esta é a maneira mais fácil e confiável de obter saídas estruturadas. O método .with_structured_output()
é implementado para modelos que fornecem APIs nativas para estruturar saídas, como chamadas de ferramentas/funções ou modo JSON, e aproveita essas capacidades internamente.
Este método recebe um esquema como entrada, que especifica os nomes, tipos e descrições dos atributos desejados na saída. Ele retorna um objeto similar a um Runnable, exceto que, em vez de gerar strings ou mensagens, produz objetos correspondentes ao esquema fornecido. O esquema pode ser especificado como uma classe TypedDict, um JSON Schema ou uma classe Pydantic.
Exemplo com Pydantic
from typing import Optionalfrom pydantic import BaseModel, Fieldclass Piada(BaseModel):"""Piada para contar ao usuário"""introducao: str = Field(description='A introdução da piada')punchline: str = Field(description='A conclusão da piada')avaliacao: Optional[int] = Field(description='O quão engraçada é a piada de 1 a 10')llm_estruturada = chat.with_structured_output(Piada)resposta = llm_estruturada.invoke('Conte uma piada sobre gatinhos')
Você pode acessar os campos individualmente:
resposta.introducao # 'Por que os gatinhos são tão bons em matemática?'
Um exemplo mais prático
Digamos que temos a seguinte review de um produto:
"Este soprador de folhas é bastante incrível. Ele tem quatro configurações: sopro de vela, brisa suave, cidade ventosa e tornado. Chegou em dois dias, bem a tempo para o presente de aniversário da minha esposa. Acho que minha esposa gostou tanto que ficou sem palavras. Até agora, fui o único a usá-lo, e tenho usado em todas as manhãs alternadas para limpar as folhas do nosso gramado. É um pouco mais caro do que os outros sopradores de folhas disponíveis no mercado, mas acho que vale a pena pelas características extras."
E queremos que o modelo de linguagem processe esta review para estruturá-la em um formato específico:
from typing import Optionalfrom pydantic import BaseModel, Fieldclass AvaliacaoReview(BaseModel):"""Avalia review do cliente"""presente: bool = Field(description='True se foi para presente e False se não foi')dias_entrega: int = Field(description='Quantos dias para entrega do produto')percepcao_valor: list[str] = Field(description='Extraia qualquer frase sobre o valor ou preço do produto. Retorne uma lista.')llm_estruturada = chat.with_structured_output(AvaliacaoReview)resposta = llm_estruturada.invoke(review_cliente)
O resultado será um objeto estruturado com os campos especificados:
# AvaliacaoReview(presente=True, dias_entrega=2, percepcao_valor=['incrível', 'bem a tempo', 'mais caro', 'vale a pena'])
Este guia resume os principais conceitos e exemplos práticos sobre Output Parsers no LangChain, demonstrando como estruturar e formatar as saídas dos modelos de linguagem de forma eficiente.