Continuidade de Conversas¶
O Nodexa mantém o histórico de conversas no servidor. Você não precisa reenviar todo o histórico de mensagens em cada request — basta referenciar o ID da resposta anterior.
Como Funciona¶
Cada resposta tem um id único com o prefixo resp_. Para continuar uma conversa, passe esse ID como previous_response_id na sua próxima request:
{
"model": "YOUR_ASSISTANT_ID",
"input": "What did I just ask you?",
"previous_response_id": "resp_01234567-89ab-cdef-0123-456789abcdef"
}
A plataforma vai:
- Carregar o histórico de conversa associado a esse ID de resposta
- Adicionar a nova mensagem do usuário ao histórico
- Gerar uma resposta no contexto da conversa completa
- Armazenar o novo turno e retornar um novo ID de resposta
Esse novo ID de resposta é o que você vai usar no próximo turno.
Exemplo de Conversa com Múltiplos Turnos¶
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://your-admin.example.com/v1',
apiKey: process.env.NODEXA_API_KEY,
});
const assistantId = 'YOUR_ASSISTANT_ID';
// Turno 1: apresentação
const turn1 = await client.responses.create({
model: assistantId,
input: 'My name is Alice and I work in software engineering.',
});
console.log('Assistant:', turn1.output_text);
// "Nice to meet you, Alice! What are you working on in software engineering?"
// Turno 2: acompanhamento, referenciando o turno 1
const turn2 = await client.responses.create({
model: assistantId,
input: 'What is my profession?',
previous_response_id: turn1.id,
});
console.log('Assistant:', turn2.output_text);
// "You mentioned that you work in software engineering."
// Turno 3: referencia o turno 2
const turn3 = await client.responses.create({
model: assistantId,
input: 'Can you suggest some career growth tips for someone in my field?',
previous_response_id: turn2.id,
});
console.log('Assistant:', turn3.output_text);
from openai import OpenAI
import os
client = OpenAI(
base_url="https://your-admin.example.com/v1",
api_key=os.environ['NODEXA_API_KEY'],
)
assistant_id = "YOUR_ASSISTANT_ID"
# Turno 1
turn1 = client.responses.create(
model=assistant_id,
input="My name is Alice and I work in software engineering.",
)
print("Assistant:", turn1.output_text)
# Turno 2
turn2 = client.responses.create(
model=assistant_id,
input="What is my profession?",
previous_response_id=turn1.id,
)
print("Assistant:", turn2.output_text)
# Turno 3
turn3 = client.responses.create(
model=assistant_id,
input="Can you suggest some career growth tips for someone in my field?",
previous_response_id=turn2.id,
)
print("Assistant:", turn3.output_text)
# Turno 1
TURN1=$(curl -s "https://your-admin.example.com/v1/responses" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "YOUR_ASSISTANT_ID",
"input": "My name is Alice and I work in software engineering."
}')
echo "Assistant: $(echo $TURN1 | jq -r '.output_text')"
RESP1_ID=$(echo $TURN1 | jq -r '.id')
# Turno 2
TURN2=$(curl -s "https://your-admin.example.com/v1/responses" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"model\": \"YOUR_ASSISTANT_ID\",
\"input\": \"What is my profession?\",
\"previous_response_id\": \"$RESP1_ID\"
}")
echo "Assistant: $(echo $TURN2 | jq -r '.output_text')"
RESP2_ID=$(echo $TURN2 | jq -r '.id')
# Turno 3
curl "https://your-admin.example.com/v1/responses" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"model\": \"YOUR_ASSISTANT_ID\",
\"input\": \"Can you suggest some career growth tips for someone in my field?\",
\"previous_response_id\": \"$RESP2_ID\"
}"
Iniciando uma Nova Conversa¶
Para iniciar uma conversa nova, omita previous_response_id. A plataforma cria automaticamente uma nova conversa.
Continuidade com Streaming¶
A continuidade funciona da mesma forma com streaming. Leia o ID da resposta do evento response.completed:
const stream = await client.responses.create({
model: 'YOUR_ASSISTANT_ID',
input: 'Tell me about black holes.',
previous_response_id: previousId,
stream: true,
});
let responseId = null;
for await (const event of stream) {
if (event.type === 'response.output_text.delta') {
process.stdout.write(event.delta);
}
if (event.type === 'response.completed') {
responseId = event.response.id;
}
}
// Use responseId para o próximo turno
Continuidade com Chamadas de Tool¶
Quando uma resposta tem status: "requires_action" (uma function tool foi chamada), você deve continuar a mesma conversa com o resultado da função:
// Passo 1: Requisição inicial
const response = await client.responses.create({
model: 'YOUR_ASSISTANT_ID',
input: 'What is the weather in Paris?',
tools: [
{
type: 'function',
name: 'get_weather',
parameters: {
type: 'object',
properties: {
location: { type: 'string' },
},
required: ['location'],
},
},
],
});
// Passo 2: response.status === 'requires_action'
// Extrair a chamada de tool
const toolCall = response.output.find(item => item.type === 'function_call');
// Passo 3: Executar a função
const weatherData = await myGetWeatherFunction(
JSON.parse(toolCall.arguments).location
);
// Passo 4: Retornar o resultado em uma nova request, continuando a MESMA conversa
const finalResponse = await client.responses.create({
model: 'YOUR_ASSISTANT_ID',
previous_response_id: response.id, // <- mesmo thread
input: [
{
type: 'function_call_output',
call_id: toolCall.call_id,
output: JSON.stringify(weatherData),
},
],
});
console.log(finalResponse.output_text);
Boas Práticas¶
Sempre armazene o ID da resposta mais recente. O ID da resposta do turno mais recente é o que você passa como previous_response_id — não o ID da primeira mensagem da conversa.
// Correto: armazene e atualize o ID a cada turno
let lastResponseId = null;
async function chat(message) {
const response = await client.responses.create({
model: assistantId,
input: message,
...(lastResponseId ? { previous_response_id: lastResponseId } : {}),
});
lastResponseId = response.id; // sempre atualiza
return response.output_text;
}
Inclua x-user-id para memória por usuário. Quando a continuidade é combinada com um user ID, o assistant também recupera itens de memória de longo prazo de sessões anteriores.
const response = await client.responses.create(
{
model: assistantId,
input: message,
previous_response_id: lastResponseId,
},
{
headers: { 'x-user-id': currentUserId },
}
);
Não reconstrua o histórico manualmente. Se você tem um previous_response_id, não precisa reenviar mensagens anteriores em input. A plataforma carrega o histórico completo automaticamente. Enviar histórico redundante em input junto com previous_response_id pode resultar em mensagens duplicadas.
Persistência da Conversa¶
O histórico de conversa é armazenado no servidor e persiste indefinidamente (sujeito à política de retenção da sua plataforma). As conversas sobrevivem a reinicializações do servidor e podem ser retomadas entre sessões do cliente.
Se você precisar invalidar uma conversa (por exemplo, a sessão do usuário terminou), simplesmente inicie uma nova omitindo previous_response_id.