>_ DevTrendspt

Idioma

Início

Linguagens

Seções

Frontend Backend Mobile DevOps AI / ML GameDev Blockchain Embarcados Segurança
Python

Como Fazer uma Rede Neural Gerar JSON Válido Sem Gambiarras e Novas Tentativas

Todo mundo que tentou conectar um modelo de linguagem a um backend real já encontrou esse problema. Você escreve um prompt detalhado, pede ao modelo para retornar estritamente JSON com a estrutura necessária, testa em dez exemplos — tudo funciona perfeitamente. Mas na centésima requisição, a rede neural de repente esquece de fechar uma aspa, adiciona a frase "Aqui está sua resposta!" no início da resposta, ou inventa um campo inexistente. Como resultado, o Pydantic lança um erro de validação e seu serviço quebra.

Normalmente, os desenvolvedores resolvem esse problema com novas tentativas de requisição à API, expressões regulares complexas, ou tentativas de "corrigir" a resposta corrompida depois que ela já foi gerada. Os desenvolvedores da equipe .txt adotaram uma abordagem diferente e criaram o Outlines — uma biblioteca que orienta o processo de geração de texto no nível do token individual.

Como a Geração Controlada Funciona

A maioria dos frameworks trabalha com LLMs como uma caixa-preta: enviam texto e esperam uma string pronta. O Outlines intercepta o controle durante o sampling. A cada etapa de geração, a biblioteca verifica quais tokens do vocabulário do modelo correspondem ao schema especificado e quais violam as regras.

Se você solicitou um número, a biblioteca simplesmente zera a probabilidade de sampling para todos os tokens que contêm letras ou pontuação. O modelo fisicamente não consegue selecionar um símbolo inválido. O resultado não é esperança de JSON válido, mas uma estrutura garantidamente correta desde a primeira tentativa.

Essa abordagem economiza tokens e tempo. Você não precisa mais pedir ao modelo no prompt para "não adicionar texto extra" ou executar regeneração quando a análise falha.

O Que a Biblioteca Pode Fazer

A interface do Outlines tenta imitar a sintaxe familiar de tipos Python. Você simplesmente passa o tipo de dado desejado junto com o prompt.

Fixando Opções de Resposta

Se você precisa de uma escolha de um conjunto limitado de valores, defina através de Literal ou Enum. O modelo não escreverá raciocínio longo — ele imediatamente produzirá um dos valores especificados.

import outlines
from typing import Literal
from transformers import AutoTokenizer, AutoModelForCausalLM

model_name = "microsoft/Phi-3-mini-4k-instruct"
model = outlines.from_transformers(
    AutoModelForCausalLM.from_pretrained(model_name, device_map="auto"),
    AutoTokenizer.from_pretrained(model_name)
)

# Модель вернет строго одно из трех слов
sentiment = model(
    "Оцени тональность ответа: 'Сервис работает отлично, спасибо!'",
    Literal["Positive", "Negative", "Neutral"]
)
print(sentiment)  # Positive

Geração a Partir de Schemas Pydantic

Para objetos complexos, você pode usar modelos Pydantic padrão. O Outlines constrói uma gramática baseada no schema e garante que a estrutura da resposta esteja totalmente em conformidade com ele.

from pydantic import BaseModel
from enum import Enum

class TicketPriority(str, Enum):
    low = "low"
    medium = "medium"
    high = "high"
    urgent = "urgent"

class ServiceTicket(BaseModel):
    priority: TicketPriority
    category: str
    requires_manager: bool
    summary: str

prompt = """
Проанализируй обращение:
Срочно! Не могу войти в личный кабинет после оплаты. Через час презентация клиенту!
"""

# Модель сгенерирует JSON, который точно совпадает со структурой ServiceTicket
ticket_json = model(prompt, ServiceTicket, max_new_tokens=200)
ticket = ServiceTicket.model_validate_json(ticket_json)

print(ticket.priority)          # TicketPriority.urgent
print(ticket.requires_manager)  # True

Expressões Regulares e Gramáticas

Se os modelos Pydantic forem muito pesados para sua tarefa, você pode definir uma expressão regular estrita. Isso é conveniente para extrair números de telefone, datas, códigos postais ou criar DSLs internos.

Com Quais Modelos Isso Funciona

O Outlines se adapta à sua stack. A biblioteca suporta múltiplos modos:

  • Inferência local via transformers e llama.cpp
  • Soluções de servidor baseadas em vLLM e Ollama
  • APIs externas como OpenAI e Gemini

O maior benefício da biblioteca é realizado ao trabalhar com seus próprios modelos locais ou servidores de inferência on-premises. É aí que o controle direto de máscara de tokens fornece uma garantia de 100% de estrutura e acelera a operação.

Casos de Uso em Produção

Na prática, a biblioteca resolve várias tarefas comuns de desenvolvimento de uma vez:

  1. Triagem automática de tickets. Extraindo categoria, urgência e tags de e-mails recebidos de clientes sem o risco de obter um objeto corrompido.
  2. Extração de entidades com tratamento de dados incompletos. Através de tipos Union, você pode permitir que o modelo retorne um objeto preenchido ou uma string explícita com uma mensagem sobre informações ausentes.
  3. Function calling. Você pode passar uma função Python regular para o modelo, e o Outlines automaticamente extrai tipos de seus argumentos para formar parâmetros de chamada corretos.
  4. Categorização de catálogo de produtos. Analisando rapidamente descrições de produtos em categorias, marcas e características principais.

Limitações e Nuances

Com todos os benefícios, é importante entender as especificidades da tecnologia. Calcular máscaras para tokens requer recursos adicionais. Se o seu schema Pydantic consiste em dezenas de objetos aninhados e expressões regulares complexas, o preparo da gramática antes do início da geração pode levar algum tempo.

Além disso, se você trabalha exclusivamente através da API OpenAI, a biblioteca usará os mecanismos internos do provedor (Structured Outputs / JSON Mode). Neste caso, o Outlines atua como uma interface unificada conveniente, mas o próprio processo de sampling é controlado pelo servidor da OpenAI.

O Outlines resolve um problema real de engenharia que qualquer equipe enfrenta ao levar LLMs para produção. O projeto remove a instabilidade da geração e permite trabalhar com redes neurais como funções tipadas regulares. Se você está construindo serviços de backend ou agentes autônomos baseados em modelos abertos, esta ferramenta definitivamente merece um lugar no seu toolkit.

Projetos relacionados