Chat API
La Chat API di Emblema fornisce conversazioni AI avanzate con supporto per:
- Streaming responses con Server-Sent Events
- Multimodal input (testo, immagini, documenti)
- Context awareness tramite Knowledge Base
- Agent integration con prompt personalizzati
- MCP tools per funzionalità estese
Endpoint
POST /api/v1/chat
Timeout: 240 secondi (4 minuti)
Headers
| Nome | Tipo | Richiesto | Descrizione |
|---|---|---|---|
| Authorization | string | ✅ | Bearer token JWT |
| Content-Type | string | ✅ | application/json |
| Accept-Language | string | ❌ | it or en (default: it) |
Request Body
Parametri Principali
interface ChatRequest {
id: string; // UUID della conversazione
messages: UIMessage[]; // Array di messaggi
selectedChatModel: string; // Modello LLM da utilizzare
knowledgeBaseIds?: string[]; // Knowledge Base per RAG
agentIds?: string[]; // Agent con prompt personalizzati
contextItemIds?: string[]; // Context items (KB + Agents)
parentId?: string; // ID conversazione parent
}
interface UIMessage {
id: string;
role: "user" | "assistant" | "system";
content: string;
parts?: MessagePart[]; // Contenuto multimodale
}
interface MessagePart {
type: "text" | "image" | "file" | "source";
content: string;
url?: string; // Per immagini e file
mimeType?: string;
}
Esempio Request Body
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"messages": [
{
"id": "msg-1",
"role": "user",
"content": "Analizza questo documento e riassumi i punti chiave",
"parts": [
{
"type": "text",
"content": "Analizza questo documento e riassumi i punti chiave"
},
{
"type": "image",
"url": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQ...",
"mimeType": "image/jpeg"
}
]
}
],
"selectedChatModel": "gpt-4o",
"knowledgeBaseIds": ["kb-uuid-1", "kb-uuid-2"],
"agentIds": ["agent-uuid-1"]
}
Response
Response Headers
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Cache-Control: no-cache
Connection: keep-alive
Streaming Response Format
La risposta utilizza il formato Server-Sent Events (SSE) con diversi tipi di eventi:
1. Text Delta Events
event: text-delta
data: {"type":"text-delta","textDelta":"Ciao"}
event: text-delta
data: {"type":"text-delta","textDelta":" mondo"}
2. Tool Call Events
event: tool-call-delta
data: {"type":"tool-call-delta","toolCallId":"call_123","toolName":"web_search","argsTextDelta":"{\"query\":\""}
event: tool-call
data: {"type":"tool-call","toolCallId":"call_123","toolName":"web_search","args":{"query":"emblema AI"}}
3. Tool Result Events
event: tool-result
data: {"type":"tool-result","toolCallId":"call_123","toolName":"web_search","result":{"results":[...]}}
4. Source Events (RAG)
event: source
data: {"type":"source","sourceType":"knowledge-base","content":"Contenuto del documento...","title":"Documento.pdf","uri":"document://uuid"}
5. Usage Events
event: usage
data: {"type":"usage","promptTokens":150,"completionTokens":75,"totalTokens":225}
6. Finish Event
event: finish
data: {"type":"finish","finishReason":"stop","usage":{"promptTokens":150,"completionTokens":75}}
Esempio Response Completa
event: text-delta
data: {"type":"text-delta","textDelta":"Basandomi sui documenti nella tua Knowledge Base, posso riassumere i punti chiave:\n\n"}
event: source
data: {"type":"source","sourceType":"knowledge-base","content":"# Report Q1 2024\n\nVendite aumentate del 25%...","title":"Report Q1 2024.pdf","uri":"document://550e8400-e29b-41d4-a716-446655440001"}
event: text-delta
data: {"type":"text-delta","textDelta":"## Punti Chiave\n\n1. **Vendite**: Aumento del 25% rispetto al Q4 2023\n2. **Ricavi**: Crescita del 18% su base annuale"}
event: tool-call
data: {"type":"tool-call","toolCallId":"call_analytics","toolName":"calculate_metrics","args":{"values":[25,18],"operation":"average"}}
event: tool-result
data: {"type":"tool-result","toolCallId":"call_analytics","result":"21.5%"}
event: text-delta
data: {"type":"text-delta","textDelta":"\n\n**Media crescita**: 21.5%"}
event: usage
data: {"type":"usage","promptTokens":450,"completionTokens":125,"totalTokens":575}
event: finish
data: {"type":"finish","finishReason":"stop"}
Modelli Supportati
OpenAI Models
gpt-4o- Multimodal flagship modelgpt-4o-mini- Veloce ed economicogpt-4-turbo- Analisi avanzatagpt-3.5-turbo- Conversazioni leggere
Anthropic Models
claude-3-5-sonnet-20241022- Reasoning avanzatoclaude-3-haiku-20240307- Veloce e preciso
Local Models (via Ollama)
llama3.1:8b- Open source modelqwen2.5:14b- Multilingual model
Configurazione Context
Knowledge Base Integration
{
"knowledgeBaseIds": ["kb-1", "kb-2"]
// Abilita Retrieval Augmented Generation
// I documenti rilevanti vengono recuperati automaticamente
// e inclusi nel context come "source" events
}
Agent Integration
{
"agentIds": ["agent-1"]
// L'agent fornisce:
// - Custom system prompt
// - Configurazione LLM specifica
// - Knowledge Base associate
// - MCP tools integrate
}
MCP Tools
Quando si utilizza un agent con MCP servers configurati:
// Request normale - gli MCP tools sono caricati automaticamente dall'agent
{
"agentIds": ["agent-with-mcp-tools"],
"messages": [{"role": "user", "content": "Cerca informazioni su Emblema"}]
}
// Response con tool usage
event: tool-call
data: {"type":"tool-call","toolName":"web_search","args":{"query":"Emblema AI platform"}}
Context Optimization
La Chat API implementa automaticamente l'ottimizzazione del context per rimanere entro i limiti del modello:
Limiti per Modello
| Modello | Max Context | Max Output | Multimodal |
|---|---|---|---|
| gpt-4o | 128K tokens | 4K tokens | ✅ |
| gpt-4o-mini | 128K tokens | 16K tokens | ✅ |
| claude-3-5-sonnet | 200K tokens | 8K tokens | ✅ |
| llama3.1:8b | 8K tokens | 2K tokens | ❌ |
Strategia di Ottimizzazione
- Message History Truncation: Mantiene gli ultimi N messaggi
- Image Compression: Ridimensiona immagini se necessario
- Source Filtering: Limita contenuto da Knowledge Base
- Token Counting: Usa tokenizer specifico del modello
Gestione Conversazioni
Creazione Nuova Conversazione
Se l'ID conversazione non esiste, viene creata automaticamente:
{
"id": "new-conversation-uuid",
"messages": [{ "role": "user", "content": "Inizia nuova chat" }],
"selectedChatModel": "gpt-4o"
}
// Genera automaticamente titolo con AI
// Salva conversazione nel database
// Assegna permessi utente
Continuazione Conversazione
Per continuare una conversazione esistente:
{
"id": "existing-conversation-uuid",
"messages": [
// Storico messaggi + nuovo messaggio utente
{ "role": "user", "content": "Messaggio precedente" },
{ "role": "assistant", "content": "Risposta precedente" },
{ "role": "user", "content": "Nuovo messaggio" }
]
}
Errori
Codici di Errore
| Codice | Descrizione | Azione |
|---|---|---|
400 | Invalid messages format | Verifica formato array messages |
400 | No user message found | Includi almeno un messaggio utente |
400 | Invalid message content | Verifica contenuto multimodale |
401 | Unauthorized | Fornire token JWT valido |
403 | Knowledge Base access denied | Verificare permessi KB |
413 | Content too large | Ridurre dimensioni immagini/file |
429 | Rate limit exceeded | Attendere prima di riprovare |
500 | LLM provider error | Riprovare o cambiare modello |
Esempi Response di Errore
400 - Invalid Messages
{
"error": "Invalid messages format",
"code": "INVALID_MESSAGES_FORMAT",
"message": "Messages must be an array",
"timestamp": "2024-01-15T10:00:00Z"
}
400 - Content Validation
{
"error": "Invalid message content",
"code": "INVALID_MESSAGE_CONTENT",
"message": "Image size exceeds 5MB limit, Unsupported file type: .exe",
"details": {
"validationErrors": [
"Image size exceeds 5MB limit",
"Unsupported file type: .exe"
]
}
}
403 - Permission Denied
{
"error": "Knowledge Base access denied",
"code": "NOT_AUTHORIZED",
"message": "You don't have read access to knowledge base",
"details": {
"deniedKnowledgeBaseIds": ["kb-uuid-1"],
"requiredPermission": "read"
}
}
Esempi di Utilizzo
1. Chat Semplice
curl -X POST https://your-domain.com/api/v1/chat \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "'$(uuidgen)'",
"messages": [
{
"id": "msg-1",
"role": "user",
"content": "Ciao, come stai?"
}
],
"selectedChatModel": "gpt-4o"
}'
2. Chat con Knowledge Base
curl -X POST https://your-domain.com/api/v1/chat \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "'$(uuidgen)'",
"messages": [
{
"id": "msg-1",
"role": "user",
"content": "Riassumi i documenti caricati questa settimana"
}
],
"selectedChatModel": "gpt-4o",
"knowledgeBaseIds": ["kb-company-docs"]
}'
3. Chat Multimodale
curl -X POST https://your-domain.com/api/v1/chat \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "'$(uuidgen)'",
"messages": [
{
"id": "msg-1",
"role": "user",
"content": "Analizza questa immagine",
"parts": [
{
"type": "text",
"content": "Analizza questa immagine"
},
{
"type": "image",
"url": "data:image/jpeg;base64,'$(base64 -i image.jpg)'",
"mimeType": "image/jpeg"
}
]
}
],
"selectedChatModel": "gpt-4o"
}'
4. Chat con Agent
curl -X POST https://your-domain.com/api/v1/chat \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "'$(uuidgen)'",
"messages": [
{
"id": "msg-1",
"role": "user",
"content": "Analizza le vendite di questo mese"
}
],
"selectedChatModel": "gpt-4o",
"agentIds": ["sales-analyst-agent"]
}'
5. JavaScript Client con Streaming
const chatStream = async (messages, model = "gpt-4o") => {
const response = await fetch("/api/v1/chat", {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
id: crypto.randomUUID(),
messages,
selectedChatModel: model,
}),
});
const reader = response.body?.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
const lines = chunk.split("\n");
for (const line of lines) {
if (line.startsWith("data: ")) {
try {
const data = JSON.parse(line.slice(6));
switch (data.type) {
case "text-delta":
console.log("Text:", data.textDelta);
break;
case "source":
console.log("Source:", data.title);
break;
case "tool-call":
console.log("Tool:", data.toolName, data.args);
break;
case "usage":
console.log("Tokens:", data.totalTokens);
break;
}
} catch (e) {
// Ignora errori parsing JSON
}
}
}
}
};
// Utilizzo
await chatStream([{ id: "msg-1", role: "user", content: "Ciao!" }]);
6. Python Client con Streaming
import requests
import json
import uuid
def chat_stream(messages, model='gpt-4o', knowledge_base_ids=None):
url = 'https://your-domain.com/api/v1/chat'
headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
payload = {
'id': str(uuid.uuid4()),
'messages': messages,
'selectedChatModel': model
}
if knowledge_base_ids:
payload['knowledgeBaseIds'] = knowledge_base_ids
response = requests.post(url, headers=headers, json=payload, stream=True)
for line in response.iter_lines():
if line:
line = line.decode('utf-8')
if line.startswith('data: '):
try:
data = json.loads(line[6:])
if data['type'] == 'text-delta':
print(data['textDelta'], end='', flush=True)
elif data['type'] == 'source':
print(f"\n[Source: {data['title']}]")
elif data['type'] == 'finish':
print(f"\n[Tokens: {data.get('usage', {}).get('totalTokens', 'N/A')}]")
except json.JSONDecodeError:
pass
# Utilizzo
chat_stream([
{'id': 'msg-1', 'role': 'user', 'content': 'Riassumi i documenti di oggi'}
], knowledge_base_ids=['kb-daily-reports'])
Rate Limiting
- Rate Limit: 100 richieste/ora per utente
- Concurrent Limit: 5 chat simultanee per utente
- Token Limit: 100K token/ora per utente
- Headers:
X-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Reset
Best Practices
Performance
- Riusa conversazioni - Non creare nuove conversazioni per ogni messaggio
- Ottimizza immagini - Comprimi immagini prima dell'upload
- Limita history - Invia solo i messaggi necessari nel context
- Cache Knowledge Base - Riusa Knowledge Base per conversazioni simili
Sicurezza
- Valida input - Sanifica sempre il contenuto utente
- Limita file - Controlla tipo e dimensione file
- Monitora usage - Traccia utilizzo token per prevenire abusi
- Filtra output - Implementa filtri per contenuti inappropriati
UX
- Streaming UI - Mostra response in tempo reale
- Loading states - Indica quando il sistema sta "pensando"
- Error handling - Gestisci elegantemente timeout e errori
- Source attribution - Mostra fonti per risposte RAG