- MANUAL-PRODUTO.md: Manual do usuário final - MANUAL-VENDAS.md: Estratégia comercial e vendas - MANUAL-TECNICO.md: Infraestrutura e deploy - README.md: Visão geral do projeto
87 lines
3.1 KiB
Python
87 lines
3.1 KiB
Python
import json
|
|
from openai import AsyncOpenAI
|
|
from app.config import settings
|
|
|
|
SYSTEM_PROMPT = """Você é um nutricionista especialista brasileiro que analisa rótulos de alimentos.
|
|
Responda SEMPRE em JSON válido com esta estrutura exata:
|
|
{
|
|
"score": <int 0-100>,
|
|
"summary": "<resumo em 2-3 frases para leigo, em português>",
|
|
"positives": ["<ponto positivo 1>", ...],
|
|
"negatives": ["<ponto negativo 1>", ...],
|
|
"ingredients": [
|
|
{
|
|
"name": "<nome no rótulo>",
|
|
"popular_name": "<nome popular ou null>",
|
|
"explanation": "<o que é, 1 frase>",
|
|
"classification": "<good|warning|bad>",
|
|
"reason": "<motivo da classificação, 1 frase>"
|
|
}
|
|
]
|
|
}
|
|
|
|
Critérios para o score:
|
|
- 90-100: Alimento natural, minimamente processado, sem aditivos
|
|
- 70-89: Bom, com poucos aditivos ou processamento leve
|
|
- 50-69: Médio, processado mas aceitável com moderação
|
|
- 30-49: Ruim, ultraprocessado com vários aditivos
|
|
- 0-29: Péssimo, alto em açúcar/sódio/gordura trans, muitos aditivos
|
|
|
|
Considere Nutri-Score, classificação NOVA, e ingredientes problemáticos.
|
|
Seja direto e honesto. Use linguagem simples."""
|
|
|
|
async def analyze_product(product_data: dict) -> dict:
|
|
if not settings.OPENAI_API_KEY:
|
|
return _mock_analysis(product_data)
|
|
|
|
client = AsyncOpenAI(api_key=settings.OPENAI_API_KEY)
|
|
|
|
user_msg = f"""Produto: {product_data.get('name', 'Desconhecido')}
|
|
Marca: {product_data.get('brand', '')}
|
|
Categoria: {product_data.get('category', '')}
|
|
Ingredientes: {product_data.get('ingredients_text', 'Não disponível')}
|
|
Nutri-Score: {product_data.get('nutri_score', 'N/A')}
|
|
NOVA: {product_data.get('nova_group', 'N/A')}
|
|
|
|
Analise este produto."""
|
|
|
|
try:
|
|
resp = await client.chat.completions.create(
|
|
model=settings.OPENAI_MODEL,
|
|
messages=[
|
|
{"role": "system", "content": SYSTEM_PROMPT},
|
|
{"role": "user", "content": user_msg}
|
|
],
|
|
response_format={"type": "json_object"},
|
|
temperature=0.3,
|
|
timeout=15,
|
|
)
|
|
return json.loads(resp.choices[0].message.content)
|
|
except Exception as e:
|
|
print(f"OpenAI error: {e}")
|
|
return _mock_analysis(product_data)
|
|
|
|
def _mock_analysis(product_data: dict) -> dict:
|
|
ingredients = product_data.get("ingredients_text", "")
|
|
score = 50
|
|
if any(w in ingredients.lower() for w in ["açúcar", "sugar", "xarope", "glucose"]):
|
|
score -= 15
|
|
if any(w in ingredients.lower() for w in ["hidrogenada", "trans"]):
|
|
score -= 20
|
|
if product_data.get("nova_group") == 4:
|
|
score -= 10
|
|
ns = product_data.get("nutri_score", "")
|
|
if ns == "e": score -= 10
|
|
elif ns == "d": score -= 5
|
|
elif ns == "a": score += 15
|
|
elif ns == "b": score += 10
|
|
score = max(0, min(100, score))
|
|
|
|
return {
|
|
"score": score,
|
|
"summary": f"Análise baseada em regras para {product_data.get('name', 'este produto')}. Configure OPENAI_API_KEY para análise completa com IA.",
|
|
"positives": ["Dados nutricionais disponíveis"],
|
|
"negatives": ["Análise IA indisponível - usando fallback"],
|
|
"ingredients": []
|
|
}
|