fix: Definindo json_schema no prompt das histórias
Some checks are pending
Docker Build and Push / build (push) Waiting to run

This commit is contained in:
Lucas Santana 2025-02-05 09:07:37 -03:00
parent f3fbdb8228
commit 66866602e7
2 changed files with 128 additions and 10 deletions

View File

@ -23,6 +23,7 @@ export interface GeneratedStory {
content: {
pages: {
text: string;
text_syllables: string;
image?: string;
}[];
};

View File

@ -44,6 +44,7 @@ interface StoryResponse {
content: {
pages: Array<{
text: string;
text_syllables: string;
imagePrompt: string;
keywords?: string[];
phonemes?: string[];
@ -128,6 +129,7 @@ serve(async (req) => {
console.log('[GPT] Prompt construído:', prompt);
console.log('[GPT] Iniciando geração da história...');
const completion = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [
@ -136,15 +138,131 @@ serve(async (req) => {
content: "Você é um contador de histórias infantis especializado em conteúdo educativo."
},
{
role: "user",
role: "user",
content: prompt
}
],
temperature: 0.7,
max_tokens: 1000,
response_format: { type: "json_object" }
store: true,
response_format: {
type: "json_schema",
json_schema: {
name: "story",
schema: {
type: "object",
properties: {
title: {
type: "string",
description: "Título da história"
},
content: {
type: "object",
properties: {
pages: {
type: "array",
items: {
type: "object",
properties: {
text: {
type: "string",
description: "Texto completo da página"
},
text_syllables: {
type: "string",
description: "Texto separado em sílabas"
},
imagePrompt: {
type: "string",
description: "Descrição para gerar imagem"
},
keywords: {
type: "array",
items: {
type: "string"
}
},
phonemes: {
type: "array",
items: {
type: "string"
}
},
syllablePatterns: {
type: "array",
items: {
type: "string",
enum: ["CV", "CVC", "CCVC"]
}
}
},
required: ["text", "text_syllables", "imagePrompt", "keywords", "phonemes", "syllablePatterns"],
additionalProperties: false
}
}
},
required: ["pages"],
additionalProperties: false
},
metadata: {
type: "object",
properties: {
targetAge: {
type: "number"
},
difficulty: {
type: "string"
},
exerciseWords: {
type: "object",
properties: {
pronunciation: {
type: "array",
items: {
type: "string"
}
},
formation: {
type: "array",
items: {
type: "string"
}
},
completion: {
type: "array",
items: {
type: "string"
}
}
},
required: ["pronunciation", "formation", "completion"],
additionalProperties: false
}
},
required: ["targetAge", "difficulty", "exerciseWords"],
additionalProperties: false
}
},
required: ["title", "content", "metadata"],
additionalProperties: false
},
strict: true
}
},
temperature: 0.7
});
if (completion.choices[0].finish_reason === "length") {
throw new Error("Resposta incompleta do modelo");
}
const story_response = completion.choices[0].message;
if (story_response.refusal) {
console.log(story_response.refusal);
throw new Error("História recusada pelo modelo");
} else if (!story_response.content) {
throw new Error("Sem conteúdo na resposta");
}
console.log('[GPT] História gerada:', completion.choices[0].message);
const storyContent = JSON.parse(completion.choices[0].message.content || '{}') as StoryResponse;
@ -236,6 +354,7 @@ serve(async (req) => {
story_id: payload.story_id,
page_number: index + 1,
text: page.text,
text_syllables: page.text_syllables,
image_url: page.image,
image_path: page.image_path
}))
@ -313,9 +432,6 @@ serve(async (req) => {
);
} catch (error) {
console.error('[Error] Erro ao gerar história:', error);
console.error('[Error] Stack trace:', error.stack);
return new Response(
JSON.stringify({
error: error.message,
@ -364,16 +480,16 @@ function buildPrompt(base: StoryPrompt, voice?: string) {
- ${selectedLanguage.instructions}
- Linguagem clara e envolvente
- 3-8 páginas de conteúdo
- Cada página deve ter um texto curto e sugestão para uma imagem
- Cada página deve ter um texto curto, o mesmo texto separado em sílabas e uma sugestão para uma imagem
- Evitar conteúdo sensível ou inadequado
- Incluir elementos de ${base.theme_id}
- Ambientado em ${base.setting_id}
- Personagem principal baseado em ${base.character_id}
- A resposta precisa ser em JSON
- Use a jornada no héroi para escrever as histórias.
Requisitos específicos para exercícios:
1. Para o exercício de completar frases:
- Selecione 5-8 palavras importantes do texto
- Selecione 8-12 palavras importantes do texto
- Escolha palavras que sejam substantivos, verbos ou adjetivos
- Evite artigos, preposições ou palavras muito simples
- As palavras devem ser relevantes para o contexto da história
@ -395,6 +511,7 @@ function buildPrompt(base: StoryPrompt, voice?: string) {
"pages": [
{
"text": "Texto da página com frases completas...",
"text_syllables": "Texto da página com frases completas separadas em sílabas em ${selectedLanguage.language}...",
"imagePrompt": "Descrição para gerar imagem...",
"keywords": ["palavra1", "palavra2"],
"phonemes": ["fonema1", "fonema2"],