Pular para o conteúdo principal

Saídas estruturadas

Saídas Estruturadas garantem que os dados gerados pelos modelos sigam esquemas predefinidos fornecidos pelo usuário, como JSON, simplificando integrações em aplicações. Quando o formato da resposta é crítico, estratégias como expressões regulares (regex) podem ser usadas, mas essas abordagens são frequentemente frágeis, complexas e incapazes de garantir que todos os campos sejam extraídos de forma precisa e consistente. Por outro lado, Saídas Estruturadas oferecem uma solução mais confiável, reduzindo erros e facilitando a integração direta. Contudo, para casos em que respostas narrativas ou flexibilidade são prioritárias, seu uso não é necessário.

Exemplos de Uso

1. Extração de Dados

Extraia informações estruturadas de textos não estruturados:

from pydantic import BaseModel
import openai

client = openai.OpenAI(
api_key="", #Sua API_KEY
base_url="https://chat.maritaca.ai/api",
)

class DetalhesEvento(BaseModel):
nome_evento: str
data: str
participantes: list[str]
traje: list[str]

completion = client.beta.chat.completions.parse(
model="sabia-3",
messages=[
{"role": "system", "content": "Extraia detalhes do evento."},
{"role": "user", "content": "João e Maria vão a uma festa junina no sábado, às 18h, em Campina Grande. Eles vão vestidos a caráter: Maria com um vestido florido e João com camisa xadrez e chapéu de palha."},
],
response_format=DetalhesEvento,
)

evento = completion.choices[0].message.parsed

print(evento)

2. Análise de Sentimentos

Identifique sentimentos em textos:

import openai

client = openai.OpenAI(
api_key="", #Sua API_KEY
base_url="https://chat.maritaca.ai/api",
)

sentimento_schema = {
"type": "object",
"schema":{
"properties": {
"texto": {"type": "string"},
"sentimento": {"type": "string", "enum": ["positivo", "negativo", "neutro"]},
},
"required": ["texto", "sentimento"],
}
}

completion = client.beta.chat.completions.parse(
model="sabia-3",
messages=[
{"role": "system", "content": "Classifique o sentimento do texto em positivo, negativo ou neutro."},
{"role": "user", "content": "Odiei o trabalho oferecido!"},
],
response_format={"type": "json_schema", "json_schema": sentimento_schema}
)

resultado = completion.choices[0].message.content

print(resultado)

3. Plano de Leitura

Gere um plano de leitura estruturado com base na solicitação do usuário, validando os dados com um esquema JSON e exibindo os livros com seus detalhes.

from enum import Enum
from typing import List, Optional
from pydantic import BaseModel
import openai
import json

client = openai.OpenAI(
api_key="", #Sua API_KEY
base_url="https://chat.maritaca.ai/api",
)

class TipoLeitura(str, Enum):
classico = "clássico"
contemporaneo = "contemporâneo"

class Livro(BaseModel):
tipo: TipoLeitura
titulo: str
autor: str
descricao: str

Livro.model_rebuild()

class PlanoLeitura(BaseModel):
nome_plano: str
livros: List[Livro]


schema = {
"type": "object",
"schema": {
"properties": {
"nome_plano": {"type": "string"},
"livros": {
"type": "array",
"items": {
"type": "object",
"properties": {
"tipo": {"type": "string", "enum": ["clássico", "contemporâneo"]},
"titulo": {"type": "string"},
"autor": {"type": "string"},
"descricao": {"type": "string"},
"subitens": {"type": ["array", "null"]}
},
"required": ["tipo", "titulo", "autor", "descricao"]
}
}
},
"required": ["nome_plano", "livros"]
}
}

completion = client.beta.chat.completions.parse(
model="sabia-3",
messages=[
{"role": "system", "content": "Você é um gerador de planos de leitura. Converta a solicitação do usuário em um plano de leitura estruturado."},
{"role": "user", "content": "Crie um plano de leitura para explorar a literatura brasileira, incluindo clássicos e literatura contemporânea."}
],
response_format={"type": "json_schema", "json_schema": schema}
)

plano_leitura = PlanoLeitura.model_validate(json.loads(completion.choices[0].message.content))

print("Nome do Plano:", plano_leitura.nome_plano)
print("Livros:")
for livro in plano_leitura.livros:
print(f" - {livro.titulo} por {livro.autor}: {livro.descricao}")

4. Uso com stream

No caso de uso com stream, as saídas estruturadas podem ser processadas em tempo real, conforme são geradas, proporcionando uma experiência mais interativa. Esse método é particularmente vantajoso para lidar com tarefas que envolvem a geração de grandes volumes de dados ou respostas extensas. A seguir, apresentamos um exemplo:

from typing import List, Dict
from pydantic import BaseModel
import openai

class PratosTipicosModel(BaseModel):
pratos: List[str]

client = openai.OpenAI(
api_key="", #Sua API_KEY
base_url="https://chat.maritaca.ai/api",
)

with client.beta.chat.completions.stream(
model="sabia-3",
messages=[
{"role": "system", "content": "Identifique os pratos típicos brasileiros no texto fornecido."},
{
"role": "user",
"content": "Na festa junina, temos canjica, pamonha, curau e quentão, além de muita música e dança.",
},
],
response_format=PratosTipicosModel,
) as stream:
for event in stream:
if event.type == "content.delta":
if event.parsed is not None:
print("content.delta parsed:", event.parsed)
elif event.type == "content.done":
print("content.done")
elif event.type == "error":
print("Error in stream:", event.error)

final_completion = stream.get_final_completion()
print("Final completion:", final_completion)


Como usar o parâmetro response_format

O parâmetro response_format é usado para instruir que as respostas geradas pelo modelo sigam um formato estruturado predefinido. Os valores para o response_format são:

  1. Schema JSON (json_schema): Defina um esquema JSON para validar a estrutura e os tipos de dados da resposta.
response_format={ type: "json_schema", json_schema: {"strict": true, "schema": ...} }
ou
response_format={ type: "json_schema", schema: {...} }
  1. Modelos Pydantic: Utilize classes Pydantic para mapear e validar os dados retornados.
response_format=ModelPydantic
  1. Objeto JSON simples também conhecido por modo json onde é solicitado um objeto json sem validações adicionais:
response_format={"type": "json_object"}

Boas Práticas

  • Defina Esquemas Claros: Use ferramentas como JSON Schema ou Pydantic para projetar esquemas adequados.
  • Valide a Entrada: Certifique-se de que as entradas dos usuários sejam compatíveis com o esquema.
  • Manuseio de Erros: Inclua lógica para tratar recusas ou respostas malformadas programaticamente.

💡
MODO JSON

O modo JSON apenas garante que a saída do modelo seja JSON válido. Já o Structured Outputs corresponde de forma confiável à saída do modelo ao esquema que você especificar. Recomendamos que você use o Structured Outputs se ele for suportado para o seu caso de uso. Ao usar o modo JSON, caso a instrução de produzir um JSON não seja explicitamente passada para o modelo, este pode gerar um fluxo interminável de espaços em branco, e a solicitação pode ser executada continuamente até atingir o limite de tokens.