Sugerencias con IA
Rellena el formulario de un ticket con IA a partir de texto, audio o imágenes, recibe el resultado por consulta periódica o en tiempo real y registra qué aceptó la persona.
Actualizado el . 5 min de lectura
Incluido en los planes Profesional y Avanzado. Ver precios
Las sugerencias con IA proponen el título, la descripción, la categoría y la prioridad de un ticket a partir de lo que cuenta la persona: un texto, una nota de voz o capturas de pantalla. Tu aplicación muestra la propuesta, la persona la acepta o la corrige, y con eso abres el ticket. La generación es una tarea en segundo plano: la pides, y recoges el resultado consultando su estado o escuchándolo en tiempo real. Funciona con la clave de tu aplicación externa, siempre desde tu servidor.
De la descripción de la persona al ticket propuesto
Participan: Persona, Tu aplicación, UTILIA OS.
De Persona a Tu aplicación:
Cuenta el problema
Por escrito, con una nota de voz o con capturas.De Tu aplicación a UTILIA OS:
POST /api/external/v1/tickets/ai-suggest
Encola la tarea con el texto, el audio o las imágenes.De UTILIA OS a Tu aplicación:
jobId (respuesta)
De Tu aplicación a UTILIA OS:
GET /api/external/v1/tickets/ai-suggest/:jobId/stream
Abre la conexión de eventos.De UTILIA OS a Tu aplicación:
Eventos progress y completed (respuesta)
completed trae suggestions, la transcripción si hubo audio y analyticsEventId.De Tu aplicación a Persona:
Muestra la propuesta
De Persona a Tu aplicación:
La acepta, la corrige o la descarta
De Tu aplicación a UTILIA OS:
POST /api/external/v1/tickets/ai-track-action
trackAiAction registra la decisión con analyticsEventId.
Antes de empezar
Todos los métodos de IA exigen el scope support:tickets:ai, además del aplicativo Tickets de soporte y la capacidad «Tickets propios» en el plan. Si mandas audio, primero se transcribe y las sugerencias se generan sobre esa transcripción; para transcribir sin pedir sugerencias, mira Transcripción de audio.
Qué envías y qué recibes
| JavaScript | Python | Qué es |
|---|---|---|
userId | user_id | Obligatorio: el externalId de la persona. |
text | text | El problema contado por escrito. Hace falta text o audio. |
audioBase64, audioFilename | audio_base64, audio_filename | Nota de voz en base64 y su nombre con extensión (webm, mp4, mp3 o wav). |
existingFields | existing_fields | Lo que ya está escrito en el formulario (title, description, category, priority) y el contexto (currentUrl, userAgent, appVersion), para afinar la propuesta. |
images | images | Hasta 5 capturas en base64, cada una con base64, filename y mimeType (mime_type). |
El resultado trae suggestions (con title, description, category y priority; cualquiera puede venir vacío), transcription si mandaste audio, y analyticsEventId (analytics_event_id), que usarás después para registrar qué hizo la persona con la propuesta.
Tres formas de recoger el resultado
| Forma | JavaScript | Python | Cuándo |
|---|---|---|---|
| Todo en uno, consultando | getSuggestions(datos, opciones?) | get_suggestions(datos, opciones, on_progress=...) | La más sencilla. |
| En tiempo real | streamSuggestions(datos, opciones?) | stream_suggestions(datos, opciones) o stream_suggestions_handle(datos, opciones) | Progreso inmediato y opción de cancelar. |
| Paso a paso | requestSuggestions(datos) y getSuggestionsStatus(jobId) | request_suggestions(datos) y get_suggestions_status(job_id) | Si quieres controlar tú cada consulta. |
Todo en uno
getSuggestions encola la tarea y consulta su estado hasta que termina. Opciones: intervalo entre consultas (1 s por defecto), espera máxima (60 s) y función de progreso. En JavaScript van en milisegundos (pollInterval, maxWait, onProgress); en Python, en segundos (GetSuggestionsOptions(poll_interval, max_wait)) y el progreso como on_progress. Si la tarea falla, no se encuentra o se agota la espera, lanza un error normal (Error en JavaScript, RuntimeError en Python) con el motivo.
const result = await sdk.ai.getSuggestions(
{
userId: 'usr-456',
text: 'No puedo descargar las facturas del mes de enero',
existingFields: { currentUrl: 'https://app.ejemplo.com/facturas', appVersion: '2.1.0' },
},
{ pollInterval: 500, maxWait: 30000, onProgress: (p) => console.log(`${p}%`) },
);
console.log(result?.suggestions?.title);
console.log(result?.suggestions?.category); // BUG, CONSULTA o SUGERENCIAEn tiempo real
Abre una conexión de eventos (Server-Sent Events) y recibe el progreso y el resultado en cuanto están listos, sin consultas repetidas. Opciones: función de progreso, función para errores no fatales y tiempo máximo (120 s por defecto; en milisegundos en JavaScript y en segundos en Python).
- JavaScript:
streamSuggestionsdevuelve un objeto conresult(una promesa con el resultado) yabort()para cancelar. NecesitaEventSource: en Node.js, instala un polyfill comoeventsourcey asígnalo aglobalThis.EventSource. - Python:
stream_suggestionsdevuelve directamente el resultado. Si necesitas poder cancelar,stream_suggestions_handledevuelve un objeto conresult(una tarea que esperas conawait) yabort().
const handle = await sdk.ai.streamSuggestions(
{
userId: 'usr-456',
text: 'El botón de pago no responde',
images: [{ base64: capturaBase64, filename: 'captura.png', mimeType: 'image/png' }],
},
{ onProgress: (p) => console.log(`${p}%`), timeout: 60000 },
);
// handle.abort() si la persona cancela
const result = await handle.result;
console.log(result?.suggestions?.title);La conexión de eventos lleva la credencial en la dirección, porque EventSource no admite cabeceras. Úsala desde tu servidor: esas direcciones pueden quedar en los registros de servidores intermedios y la clave nunca debe llegar al navegador.
Si consumes los eventos sin el SDK
El servidor envía todos los eventos con el tipo genérico message, sin línea event:. El tipo real (progress, completed, failed o heartbeat) va dentro del JSON, en el campo event. Escuchar addEventListener('completed', ...) no recibe nada nunca. El formato exacto está en Endpoints de sugerencias con IA.
Paso a paso
requestSuggestions encola la tarea y devuelve su identificador: { jobId } en JavaScript y el identificador como texto en Python. getSuggestionsStatus devuelve el estado: pending, processing, completed (con el resultado en result), failed (con el motivo en error) o not_found, y el progreso de 0 a 100.
const { jobId } = await sdk.ai.requestSuggestions({ userId: 'usr-456', text: 'No carga el panel' });
let status = await sdk.ai.getSuggestionsStatus(jobId);
while (status.status === 'pending' || status.status === 'processing') {
await new Promise((r) => setTimeout(r, 1000));
status = await sdk.ai.getSuggestionsStatus(jobId);
}
if (status.status === 'completed') console.log(status.result?.suggestions);Registrar qué hizo la persona
Después de enseñar la propuesta, registra con trackAiAction (track_ai_action) si la aceptó, la corrigió o la descartó. Así tu organización puede medir si las sugerencias ayudan.
| JavaScript | Python | Qué es |
|---|---|---|
eventId | event_id | El analyticsEventId del resultado. Obligatorio. |
userAction | user_action | ACCEPTED_ALL, ACCEPTED_PARTIAL, REJECTED, MODIFIED o IGNORED. Obligatorio. |
fieldsAccepted, fieldsModified, fieldsRejected | fields_accepted, fields_modified, fields_rejected | Qué campos aceptó, cambió o rechazó. |
timeToDecisionMs | time_to_decision_ms | Milisegundos desde que vio la propuesta hasta que decidió. |
source | source | SDK_EXTERNAL o WIDGET. |
await sdk.ai.trackAiAction({
eventId: result!.analyticsEventId!,
userAction: 'ACCEPTED_PARTIAL',
fieldsAccepted: ['title', 'description'],
fieldsModified: ['priority'],
timeToDecisionMs: Date.now() - shownAt,
source: 'SDK_EXTERNAL',
});Avisar de fallos del cliente
reportError (report_error) envía a UTILIA OS un fallo de tu integración de IA o de tu formulario, con severidad baja y componente sdk si no indicas otro. No lanza nunca: si el aviso falla, se descarta en silencio. Acepta message (obligatorio) y, si quieres, stack, code, component, context, endpoint, method, requestId, url y userAgent. En JavaScript context es texto; en Python, un diccionario.
Para notificar los errores de negocio de tu aplicación, con agrupación y estadísticas, usa el servicio Notificar errores de tu aplicación.
await sdk.ai.reportError({
message: 'No se pudieron generar las sugerencias',
code: 'SUGGESTIONS_FAILED',
component: 'formulario-soporte',
});