Configuracion del Agente de IA
Este documento describe la estructura y configuracion del Agente de IA en Plazbot. Un agente puede estar vinculado a un portal web, widget o canal de mensajeria como WhatsApp o cualquier software que tengas.
Repositorio con ejemplos funcionales para crear tus agentes.
Inicializacion
Puedes usar la clase unificada Plazbot o importar Agent de forma individual:
01import { Plazbot } from 'plazbot';0203const plazbot = new Plazbot({04 workspaceId: "YOUR_WORKSPACE_ID",05 apiKey: "YOUR_API_KEY",06 zone: "LA" // "EU" para Europa07});0809// Usar: plazbot.agent.addAgent(...)
Creacion del Agente
El agente es la unidad base del SDK. Puedes crear agentes con caracteristicas especificas y desplegarlos en diferentes canales: Portal de IA, Widget, WhatsApp o cualquier herramienta empresarial.
01const agent = await plazbot.agent.addAgent(config);02const agentId = agent.agentId;
Actualizar Agente
01await plazbot.agent.updateAgent(agentId, {02 name: "Agente Actualizado",03 buffer: 804});
Para trabajar con los agentes, existe un archivo JSON que funciona como el configurador inicial. No es necesario completar todos los campos, configura solo lo que necesites.
Proporcionamos archivos de configuracion basico y avanzado en el Repositorio de GitHub.
Estructura del Archivo agent.config.json
01{02 "name": "Sales Clinic",03 "description": "Virtual Agent IA assistant of the Dental Clinic Smiles",04 "prompt": "You are Máximo, a professional virtual assistant for Smiles Dental Clinic. Help patients with appointments, general information, and guide them through our services. Always maintain a professional yet friendly tone.",05 "zone": "LA",06 "buffer": 15,07 "color": "blue",08 "question": "How can I help you today?",09 "timezone": "America/Lima",10 "enable": true,11 "tags": [12 "health",13 "dentistry",14 "ia",15 "plazbot"16 ],17 "showInChat": false,18 "useToolCalling": true,19 "enableWebSearch": false,20 "enableContingency": false,21 "enableAudioInput": false,22 "responseMode": "direct",23 "batchWaitSeconds": 3,24 "version": "v2.0",25 "enableWidget": true,26 "darkWidget": true,27 "nameWidget": "Dental Assistant",28 "initialShowWidget": true,29 "examples": [30 { "value": "How to schedule an appointment?", "color": "green" },31 { "value": "What are your office hours?", "color": "blue" },32 { "value": "Do you accept insurance?", "color": "orange" },33 { "value": "Emergency contact information", "color": "gray" },34 { "value": "Location and directions", "color": "white" }35 ],36 "instructions": {37 "tone": "professional",38 "style": "short answers",39 "personality": "friendly",40 "objective": "help with clarity",41 "language": "es-419",42 "emojis": false,43 "preferredFormat": "plain text",44 "maxWords": 80,45 "avoidTopics": [46 "laboratory costs",47 "external claims",48 "specific medical diagnoses"49 ],50 "respondOnlyIfKnows": true,51 "maintainToneBetweenMessages": true,52 "greeting": "Hello, I am Máximo, your virtual assistant from Smiles Dental Clinic. How can I help you today?"53 },54 "person": {55 "name": "Máximo",56 "role": "Virtual customer service assistant",57 "speaksInFirstPerson": true,58 "isHuman": false59 },60 "fallbacks": {61 "noAnswer": "Sorry, I don't have information on that topic. Let me connect you with one of our specialists.",62 "serviceError": "There was a problem processing your request. Please try again later or contact us directly.",63 "doNotUnderstand": "Could you please repeat it in another way? I want to make sure I help you correctly."64 },65 "rules": {66 "doNotMentionPrices": false,67 "doNotDiagnose": true,68 "doNotRespondOutsideHours": "Our office hours are Monday to Saturday, from 8am to 6pm. For emergencies, please call our emergency line."69 },70 "customAIConfig": true,71 "aiProviders": [72 {73 "provider": "openai",74 "model": "gpt-4o",75 "apiToken": "sk-proj-xxxxxxxxxxxxx",76 "temperature": 0.7,77 "maxTokens": 4096,78 "isDefault": true79 },80 {81 "provider": "claude",82 "model": "claude-sonnet-4-6",83 "apiToken": "sk-ant-xxxxxxxxxxxxx",84 "temperature": 0.5,85 "maxTokens": 8192,86 "isDefault": false87 }88 ],89 "channels": [90 {91 "channel": "whatsapp",92 "key": "+51987654321",93 "multianswer": false94 },95 {96 "channel": "telegram",97 "key": "smiles_clinic_bot",98 "multianswer": true99 }100 ],101 "services": [102 {103 "intent": "schedule_appointment",104 "reference": "Service for scheduling patient appointments at the dental clinic",105 "enabled": true,106 "method": "POST",107 "tags": ["appointment", "scheduling"],108 "endpoint": "https://api.smilesclinic.com/v1/appointments/schedule",109 "requiredFields": [110 {111 "name": "patient_name",112 "description": "Full name of the patient who wants to schedule the appointment",113 "promptHint": "Could you please provide your full name?",114 "type": "string"115 },116 {117 "name": "email",118 "description": "Patient's email address for appointment confirmation",119 "promptHint": "What's your email address for the appointment confirmation?",120 "type": "email"121 },122 {123 "name": "phone",124 "description": "Patient's phone number for contact",125 "promptHint": "Could you provide your phone number?",126 "type": "phone"127 },128 {129 "name": "preferred_date",130 "description": "Preferred date and time for the appointment",131 "promptHint": "What date and time would work best for your appointment?",132 "type": "datetime"133 },134 {135 "name": "service_type",136 "description": "Type of dental service needed",137 "promptHint": "What type of dental service do you need? (cleaning, consultation, etc.)",138 "type": "string"139 }140 ],141 "headers": {142 "Authorization": "Bearer {{clinic_api_key}}",143 "Content-Type": "application/json",144 "X-Clinic-ID": "smiles_001"145 },146 "bodyTemplate": {147 "patient": {148 "name": "{{patient_name}}",149 "email": "{{email}}",150 "phone": "{{phone}}"151 },152 "appointment": {153 "datetime": "{{preferred_date|format('yyyy-MM-dd HH:mm')}}",154 "service": "{{service_type}}",155 "timezone": "America/Lima"156 }157 },158 "bodySchema": {159 "patient_name": "string",160 "email": "string",161 "preferred_date": "date",162 "service_type": "string"163 },164 "responseMapping": {165 "confirmation_id": "$.data.appointment.id",166 "scheduled_date": "$.data.appointment.datetime",167 "status": "$.status",168 "doctor_name": "$.data.appointment.doctor.name",169 "conflict_reason": "$.error.reason"170 },171 "responseMessage": "Your appointment has been successfully scheduled for {{scheduled_date}} with Dr. {{doctor_name}}",172 "responseConditions": [173 {174 "condition": "$.status == 'confirmed'",175 "message": "¡Perfect! Your appointment has been confirmed for {{scheduled_date}} with Dr. {{doctor_name}}. We'll send you a reminder 24 hours before. Confirmation ID: {{confirmation_id}}",176 "nextService": "send_appointment_reminder"177 },178 {179 "condition": "$.status == 'conflict'",180 "message": "Sorry, that time slot is not available. {{conflict_reason}}. Would you like me to suggest other available times?",181 "nextService": "suggest_alternative_times"182 },183 {184 "condition": "$.status == 'error' && $.error.code == 'invalid_email'",185 "message": "The email address provided seems invalid. Could you please verify your email address?",186 "nextService": "verify_contact_info"187 },188 {189 "condition": "$.status == 'error' && $.error.code == 'past_date'",190 "message": "I cannot schedule appointments for past dates. Could you please choose a future date?"191 },192 {193 "condition": "$.status == 'pending'",194 "message": "Your appointment request is being reviewed. We'll contact you within 24 hours to confirm availability and finalize the details."195 }196 ],197 "action": "conversar_humano"198 },199 {200 "intent": "check_insurance",201 "reference": "Service to verify patient insurance coverage and benefits",202 "enabled": true,203 "method": "GET",204 "tags": ["insurance", "verification"],205 "endpoint": "https://api.smilesclinic.com/v1/insurance/verify",206 "requiredFields": [207 {208 "name": "insurance_provider",209 "description": "Name of the insurance company",210 "promptHint": "What's your insurance provider name?",211 "type": "string"212 },213 {214 "name": "policy_number",215 "description": "Insurance policy or member ID number",216 "promptHint": "Could you provide your policy or member ID number?",217 "type": "string"218 }219 ],220 "headers": {221 "Authorization": "Bearer {{insurance_api_key}}",222 "Content-Type": "application/json"223 },224 "responseMapping": {225 "coverage_status": "$.data.coverage.status",226 "deductible": "$.data.coverage.deductible",227 "copay": "$.data.coverage.copay",228 "covered_services": "$.data.coverage.services"229 },230 "responseMessage": "Your insurance verification is complete. Coverage status: {{coverage_status}}",231 "responseConditions": [232 {233 "condition": "$.data.coverage.status == 'active'",234 "message": "Great news! Your insurance is active. Your copay is ${{copay}} and your remaining deductible is ${{deductible}}. Covered services include: {{covered_services}}."235 },236 {237 "condition": "$.data.coverage.status == 'inactive'",238 "message": "It appears your insurance policy is not currently active. Please contact your insurance provider or we can discuss our self-pay options."239 },240 {241 "condition": "$.data.coverage.status == 'not_found'",242 "message": "I couldn't find your policy in our system. Please verify your insurance information or contact us directly for assistance."243 }244 ]245 }246 ],247248 "actions": [249 {250 "intent": "assign_urgent_tag",251 "reference": "Tags patients as urgent when they mention emergency dental situations",252 "tags": ["emergency", "urgent"],253 "enabled": true,254 "responseMessage": "I've marked your case as urgent and notified our emergency team.",255 "responseJson": false,256 "responseExact": true,257 "action": [258 {259 "type": "action.tag",260 "value": "urgent_case"261 },262 {263 "type": "action.asign",264 "value": "emergency@smilesclinic.com"265 }266 ]267 },268 {269 "intent": "schedule_follow_up",270 "reference": "Automatically schedules follow-up appointments and assigns appropriate case management",271 "tags": ["follow-up", "scheduling"],272 "enabled": true,273 "responseMessage": "Your follow-up has been scheduled and assigned to our treatment coordinator.",274 "responseJson": false,275 "responseExact": false,276 "action": [277 {278 "type": "action.stage",279 "value": "follow_up_scheduled"280 },281 {282 "type": "action.segmentation",283 "value": "post_treatment_care"284 }285 ]286 },287 {288 "intent": "end_consultation",289 "reference": "Ends the AI consultation when the patient no longer needs assistance",290 "tags": ["consultation", "end"],291 "enabled": true,292 "responseMessage": "Thank you for contacting Smiles Dental Clinic. Have a great day!",293 "responseJson": false,294 "responseExact": true,295 "action": [296 {297 "type": "action.agentShutDown",298 "value": "true"299 },300 {301 "type": "action.solved",302 "value": "true"303 }304 ]305 }306 ]307}
Canales (channels)
Los canales definen dónde y cómo tu agente puede comunicarse con los usuarios.
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
channel | string | Sí | Tipo de canal: whatsapp, telegram, messenger, etc. |
key | string | Sí | Identificador del canal (número de teléfono para WhatsApp). |
multianswer | boolean | No | Si es true, divide la respuesta del agente en varios mensajes consecutivos (split por doble salto de línea). Default: false. |
Ejemplo de Canales
01"channels": [02 { "channel": "whatsapp", "key": "123456789", "multianswer": true },03 { "channel": "telegram", "key": "@mi_bot" },04 { "channel": "messenger", "key": "page_id_123" }05]
Campos principales del agente
| Campo | Descripción |
|---|---|
| name | Nombre del agente. Visible en el panel. Requerido |
| prompt | Instrucciones base para el comportamiento del agente. Requerido |
| imagePrompt | Instrucción usada cuando llega una imagen o archivo sin texto del usuario (caption vacío). |
| buffer | Cantidad de mensajes que se mantienen como contexto. Rango: 3 a 20. Requerido |
| color | Color de presentación. Valores: blue, orange, gray, green, white. |
| question | Pregunta principal que se muestra en el portal. |
| description | Descripción general del agente. |
| zone | Zona donde opera el agente: LA (Latinoamérica) o EU (Europa). Requerido |
| timezone | Zona horaria. Ejemplo: America/Lima. TimeZone Formats |
| tags | Etiquetas internas para clasificar agentes. |
| examples | Preguntas sugeridas. Hasta 5. |
| showInChat | Si el agente se muestra en el widget/chat. (boolean) |
| enable | Si el agente esta habilitado o no. (boolean) |
| version | Version del agente (auto-incrementado). Formato: v2.0, v2.1, etc. |
| useToolCalling | Si usa el orquestador de Tool Calling (true) o el clasico (false). Default: true. |
| responseMode | Modo de respuesta: direct (inmediato) o batched (espera mensajes consecutivos). Default: direct. |
| batchWaitSeconds | Segundos de espera para acumular mensajes consecutivos (solo si responseMode=batched). Rango: 2-10. Default: 3. |
| customAIConfig | Habilita configuracion personalizada de proveedores de IA. (boolean) |
| aiProviders | Array de proveedores de IA configurados. Ver seccion "Modelo IA". |
| enableContingency | Si es true y existen varios aiProviders, reintenta con los proveedores restantes cuando falla el proveedor por defecto. Solo orquestador Tool Calling. Default: false. |
| enableWebSearch | Permite al agente buscar en la web usando la herramienta nativa del proveedor (OpenAI web_search_preview, Claude web_search, Gemini google_search). No requiere API key adicional. Default: false. |
| enableAudioInput | Si es true, transcribe los audios de voz recibidos (Whisper) y el agente responde en texto. Solo orquestador Tool Calling. Default: false. |
| variables | Variables personalizadas del agente con valores por defecto. Ver seccion "Variables personalizadas". |
| source | Fuente de Datos del agente (catalogo nativo de Plazbot o Google Sheets). Ver seccion "Fuente de Datos". |
| voiceConfig | Configuracion del agente de voz para llamadas telefonicas. Ver seccion "Agente de Voz". |
Instrucciones (instructions)
| Campo | Tipo | Descripción |
|---|---|---|
| tone | string | Tono de comunicación: professional, friendly, etc. |
| style | string | Estilo de respuestas: short answers, detailed. |
| personality | string | Personalidad del agente. |
| objective | string | Objetivo principal del agente. |
| language | string | Idioma en que debe responder. Ver tabla de idiomas. |
| emojis | boolean | Si puede usar emojis. |
| preferredFormat | string | plain text o markdown. |
| maxWords | number | Máximo de palabras por respuesta. |
| avoidTopics | array | Lista de temas prohibidos. |
| respondOnlyIfKnows | boolean | Si debe evitar responder sin información confiable. |
| maintainToneBetweenMessages | boolean | Mantiene el mismo tono entre mensajes. |
| greeting | string | Mensaje de bienvenida. |
Opciones Objetive "help with clarity" Enfocado en brindar respuestas claras "sell more" Promociona productos o servicios "support users" Ayuda a resolver problemas "guide actions" Brinda pasos concretos o instrucciones
Opciones Personalidad "friendly" Agradable y empático "serious" Reservado y directo "funny" Con toques de humor sutil "robotic" Más neutral, tipo IA técnica
Opciones preferredFormat "plain text" Texto simple "markdown" Permite negritas, listas, enlaces "html" Usado si se integrará en un entorno web
Opciones Style "short answers" Respuestas breves y directas "detailed" Respuestas explicativas, útiles para asistencia técnica "bullet points" Instrucciones u opciones en lista (ideal para pasos o listas) "conversational" Estilo fluido y natural, más humano
Opciones Tono "professional" Tono formal, educado, propio para empresas "friendly" Tono amigable, cercano, ideal para atención al cliente "casual" Informal, con lenguaje relajado y natural "neutral" Objetivo, sin inclinación emocional
Persona del Agente (person)
| Campo | Tipo | Descripción |
|---|---|---|
| name | string | Nombre que usará el agente. |
| role | string | Rol representado. |
| speaksInFirstPerson | boolean | Habla en primera persona. |
| isHuman | boolean | Simula ser una persona real. |
Reglas y Fallbacks
Fallbacks
| Campo | Tipo | Descripción |
|---|---|---|
| noAnswer | string | Mensaje si no tiene respuesta. |
| serviceError | string | Mensaje de error de servicio. |
| doNotUnderstand | string | Mensaje si no entiende la consulta. |
Reglas
| Campo | Tipo | Descripción |
|---|---|---|
| doNotMentionPrices | boolean | No hablar de precios. |
| doNotDiagnose | boolean | No hacer diagnósticos médicos. |
| doNotRespondOutsideHours | string | Mensaje fuera del horario definido. Trabaja junto con el campo de Timezone |
Configuración de Modelo IA
Plazbot te permite configurar proveedores de IA personalizados para cada agente. Por defecto, los agentes usan el token de OpenAI configurado en tu workspace, pero puedes habilitar configuración personalizada para usar diferentes proveedores (OpenAI, Claude, Gemini) con sus propios tokens y parámetros.
Habilitar Configuración Personalizada
01{02 "customAIConfig": true,03 "aiProviders": [04 {05 "provider": "openai",06 "model": "gpt-4o",07 "apiToken": "sk-proj-xxxxxxxxxxxxx",08 "temperature": 0.7,09 "maxTokens": 4096,10 "isDefault": true11 },12 {13 "provider": "claude",14 "model": "claude-sonnet-4-6",15 "apiToken": "sk-ant-xxxxxxxxxxxxx",16 "temperature": 0.5,17 "maxTokens": 8192,18 "isDefault": false19 }20 ]21}
Campos de aiProviders
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
| provider | string | Sí | Proveedor de IA: openai, claude, o gemini |
| model | string | Sí | Modelo específico a usar. Ver modelos disponibles abajo. |
| apiToken | string | Sí | Token de API del proveedor. |
| temperature | number | No | Controla creatividad (0-2). Default: 0.7 |
| maxTokens | number | No | Longitud máxima de respuesta. Recomendado: 4096 |
| isDefault | boolean | No | Define cuál proveedor usar por defecto. |
Modelos Disponibles por Proveedor
OpenAI:
gpt-5.4gpt-4o(recomendado)
Claude (Anthropic):
claude-sonnet-4-6(recomendado)claude-opus-4-6
Gemini (Google):
gemini-2.5-progemini-2.5-flash(recomendado)
Puedes usar cualquier modelo vigente del proveedor: el campo model acepta el nombre exacto del modelo tal como aparece en la documentacion de OpenAI, Anthropic o Google.
Parámetros de Temperature
| Valor | Descripción | Uso Recomendado |
|---|---|---|
| 0 - 0.3 | Respuestas muy predecibles y consistentes | Soporte técnico, datos precisos |
| 0.5 - 0.7 | Balance entre creatividad y precisión | Uso general (recomendado) |
| 1.0 - 1.5 | Respuestas más creativas y variadas | Marketing, contenido creativo |
| 1.5 - 2.0 | Muy creativo e impredecible | Escritura creativa, brainstorming |
Parámetros de MaxTokens
| Valor | Descripción | Uso Recomendado |
|---|---|---|
| 1024 | Respuestas cortas | Respuestas breves, preguntas simples |
| 2048 | Respuestas medianas | Explicaciones moderadas |
| 4096 | Respuestas largas (recomendado) | Uso general |
| 8192 | Respuestas muy largas | Análisis detallados |
| 16384 | Respuestas extensas | Documentos completos |
Importante: Si activas customAIConfig: true, debes agregar al menos un proveedor en el array aiProviders. Si el array está vacío, el sistema usará la configuración por defecto del workspace.
Tip: Puedes configurar múltiples proveedores y el agente usará el que tenga isDefault: true. Esto es útil para A/B testing o para tener proveedores de respaldo.
Contingencia entre proveedores (enableContingency)
Si configuras varios proveedores en aiProviders y activas enableContingency: true, cuando el proveedor por defecto falle el sistema reintenta automáticamente con los proveedores restantes. Solo aplica con el orquestador de Tool Calling.
01{02 "customAIConfig": true,03 "enableContingency": true,04 "aiProviders": [05 { "provider": "openai", "model": "gpt-4o", "apiToken": "sk-proj-xxx", "isDefault": true },06 { "provider": "claude", "model": "claude-sonnet-4-6", "apiToken": "sk-ant-xxx" }07 ]08}
Códigos de Idioma
| Valor | Descripción |
|---|---|
| es | Español general |
| es-419 | Español latinoamericano neutral |
| es-ES | Español de España |
| en | Inglés general |
| en-US | Inglés estadounidense |
| en-GB | Inglés británico |
| fr | Francés general |
| fr-FR | Francés de Francia |
| pt-BR | Portugués brasileño |
| de | Alemán |
Variables personalizadas (variables)
Permiten definir variables propias del agente con valores por defecto. Estas variables se pueden sobrescribir al enviar un mensaje (on-message) y usarse en prompts, servicios y respuestas.
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
code | string | Sí | Código único de la variable (alfanumérico + underscore). |
name | string | Sí | Nombre legible de la variable. |
type | string | Sí | Tipo de dato: string, number o boolean. |
defaultValue | string | No | Valor por defecto si no se envía en el on-message. |
description | string | No | Descripción de para qué se usa la variable. |
01"variables": [02 {03 "code": "sucursal",04 "name": "Sucursal",05 "type": "string",06 "defaultValue": "Lima Centro",07 "description": "Sucursal desde donde responde el agente"08 }09]
Fuente de Datos (source)
Conecta el agente a una fuente de datos estructurada (catálogo nativo de Plazbot o una hoja de Google Sheets). El agente consulta esta fuente cuando necesita responder sobre catálogos, stock, precios, etc.
| Campo | Tipo | Descripción |
|---|---|---|
enabled | boolean | Activa la Fuente de Datos. Default: false. |
reference | string | Descripción que lee la IA para decidir cuándo consultar la fuente. |
sourceType | string | Tipo de fuente: plazbot (nativa) o googlesheets. |
businessType | string | Tipo de negocio para el mapeo semántico: products, services, menu, real_estate, courses, vehicles, hospitality, healthcare, events, parts, custom. |
columnMapping | object | Mapeo de nombre semántico a la columna real de la fuente. |
plazbotSource | object | { "sourceId": "..." } cuando sourceType es plazbot. |
googleSheets | object | { "integrationId", "spreadsheetId", "sheetName", "sheetId", "detectedColumns" } cuando sourceType es googlesheets. |
01"source": {02 "enabled": true,03 "reference": "Catalogo de productos con precios y stock actualizado",04 "sourceType": "googlesheets",05 "businessType": "products",06 "columnMapping": { "nombre": "Producto", "precio": "Precio", "stock": "Stock" },07 "googleSheets": {08 "integrationId": "int_xxx",09 "spreadsheetId": "1AbC...",10 "sheetName": "Catalogo",11 "sheetId": 012 }13}
Agente de Voz (voiceConfig)
Configura el agente para atender llamadas telefónicas con voz (TTS + transcripción).
| Campo | Tipo | Descripción |
|---|---|---|
enabled | boolean | Activa el agente de voz. |
phoneNumber | string | Número DID asignado. Ej: +573151234567. |
ttsProvider | string | Proveedor de voz: google, openai o elevenlabs. |
ttsVoiceId | string | ID de la voz. Ej: nova, es-US-Journey-D. |
ttsLanguage | string | Código de idioma. Ej: es-CO, es-MX. |
greeting | string | Saludo inicial que se reproduce al contestar. |
maxCallDurationSeconds | integer | Duración máxima de la llamada. Rango: 60-1800. Default: 300. |
silenceTimeoutMs | integer | Tiempo de silencio antes de cortar. Rango: 15000-60000. Default: 15000. |
transferExtension | string | Extensión SIP para transferir a un humano. |
voiceType | string | compact (rápido, sin herramientas) o complete (Tool Calling + RAG completo). |
languageInstruction | string | Instrucción de idioma personalizada para el LLM. Si está vacía se genera automáticamente según ttsLanguage. |
fillersEnabled | boolean | Frases de relleno (ej: "Déjame revisar") mientras la IA procesa la respuesta. Default: true. |
Si usas ttsProvider: "elevenlabs" puedes configurar tu propia cuenta (BYOK):
| Campo | Tipo | Descripción |
|---|---|---|
elevenlabsApiKey | string | API Key de ElevenLabs. |
elevenlabsVoiceId | string | ID de la voz. |
elevenlabsVoiceName | string | Nombre visible de la voz. |
elevenlabsModelId | string | Modelo. Ej: eleven_multilingual_v2. |
elevenlabsStability | number | Estabilidad de la voz (0-100). |
elevenlabsSimilarity | number | Similitud de la voz (0-100). |
elevenlabsStyle | number | Exageración de estilo (0-100). |
elevenlabsSpeakerBoost | boolean | Activa speaker boost. |
01"voiceConfig": {02 "enabled": true,03 "phoneNumber": "+573151234567",04 "ttsProvider": "openai",05 "ttsVoiceId": "nova",06 "ttsLanguage": "es-CO",07 "greeting": "Hola, gracias por llamar a Smiles Dental Clinic. En que puedo ayudarte?",08 "maxCallDurationSeconds": 300,09 "voiceType": "complete",10 "fillersEnabled": true11}
Enviar mensaje al Agente de IA
01const response = await bot.onMessage({02 agentId: "agentId",03 question: "Can you give me a summary of the new Meta WhatsApp prices?",04 sessionId: "2aff0c11-434f-4d7c-a325-697128bb8a20",05 file: "https://.../archivo.pdf", //06 multipleAnswers: true // Optional07});0809console.log(" IA Response:", respuesta);
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
agentId | string | Sí | Identificador único del agente. Se utiliza para recuperar su configuración y conocimiento. |
question | string | Sí | Pregunta o mensaje del usuario que la IA debe responder. |
sessionId | string | Sí | Identificador de sesión único para mantener el contexto y el historial (buffer) de la conversación. |
file | string | No | URL pública opcional de una imagen o archivo PDF. El contenido será extraído y usado si es relevante para la respuesta. |
multipleAnswers | boolean | No | Si se establece en true, la respuesta será devuelta en múltiples bloques (array) en lugar de un único texto. Ideal para respuestas estructuradas. |
Tipos de Archivos Soportados en onMessage (OCR)
| Tipo de Archivo | Soportado | Notas |
|---|---|---|
.jpg, .png, .bmp, .gif, .tiff | Sí | Formatos estándar de imagen |
.pdf | Sí | Solo si el PDF contiene texto incrustado o es una imagen escaneada |
.docx, .xlsx | No | No se admite para procesamiento OCR |
.txt, .json, etc. | No | No relevantes para extracción OCR |
Respuesta esperada:
01{02 "answer": "Los precios de Meta WhatsApp se actualizaron...",03 "sources": [04 {05 "title": "Documento de precios",06 "content": "Fragmento relevante del documento..."07 }08 ],09 "actionsExecuted": [10 {11 "name": "action.tag",12 "intent": "consulta_precios",13 "result": {}14 }15 ]16}
| Campo | Tipo | Descripcion |
|---|---|---|
answer | string | Respuesta del agente en texto. Si multipleAnswers = true, se devuelve como array en answers. |
sources | array | Fuentes del knowledge base usadas para generar la respuesta (si aplica). |
actionsExecuted | array | Acciones que se ejecutaron durante la respuesta (si aplica). |
Streaming SSE (Server-Sent Events)
Los endpoints /on-message y /on-message-portal soportan streaming SSE. Cuando envias stream: true, la respuesta se emite como text/event-stream con chunks progresivos en vez de esperar la respuesta completa.
Requisito: El agente debe tener useToolCalling: true para que el streaming funcione. Si useToolCalling es false, el endpoint retorna JSON normal aunque envies stream: true.
Portal y Widget: Los agentes asociados a Portales de IA y Widgets siempre deben tener useToolCalling: true activado para una experiencia optima con streaming.
Request con Stream
01const response = await fetch('https://api.plazbot.com/api/agent/on-message', {02 method: 'POST',03 headers: {04 'Content-Type': 'application/json',05 'Authorization': 'Bearer YOUR_API_KEY',06 'x-workspace-id': 'YOUR_WORKSPACE_ID'07 },08 body: JSON.stringify({09 agentId: "agentId",10 question: "Cuales son los horarios?",11 sessionId: "2aff0c11-434f-4d7c-a325-697128bb8a20",12 stream: true13 })14});
Formato de Chunks SSE
Cada linea sigue el formato data: {json}\n\n. Los tipos de chunks son:
| Tipo | Descripcion | Campos |
|---|---|---|
text | Token parcial de texto | content: texto parcial |
tool_call | El agente ejecuta una herramienta (API, accion) | tool_name: nombre de la herramienta |
tool_result | Resultado de la herramienta ejecutada | tool_name, tool_result |
done | Stream finalizado | input_tokens, output_tokens, estimated_cost |
error | Error durante el procesamiento | error: mensaje de error |
Ejemplo de Chunks
01data: {"type":"tool_call","tool_name":"search_knowledge_base"}0203data: {"type":"tool_result","tool_name":"search_knowledge_base"}0405data: {"type":"text","content":"Los"}0607data: {"type":"text","content":" horarios"}0809data: {"type":"text","content":" de atencion son..."}1011data: {"type":"done","input_tokens":1250,"output_tokens":380,"estimated_cost":0.0045}
Consumir el Stream (JavaScript/TypeScript)
01const reader = response.body.getReader();02const decoder = new TextDecoder();03let buffer = '';04let fullText = '';0506while (true) {07 const { done, value } = await reader.read();08 if (done) break;0910 buffer += decoder.decode(value, { stream: true });11 const lines = buffer.split('\n');12 buffer = lines.pop() || '';1314 for (const line of lines) {15 if (!line.startsWith('data: ')) continue;16 const chunk = JSON.parse(line.substring(6));1718 if (chunk.type === 'text') {19 fullText += chunk.content;20 // Actualizar la UI progresivamente21 } else if (chunk.type === 'tool_call') {22 // Mostrar indicador: "Buscando informacion..."23 } else if (chunk.type === 'done') {24 // Stream finalizado25 console.log('Tokens:', chunk.input_tokens, chunk.output_tokens);26 }27 }28}
Proveedores Soportados
| Proveedor | Streaming | Notas |
|---|---|---|
| OpenAI | Soportado | Tokens emitidos uno a uno |
| Claude (Anthropic) | Soportado | Chunks mas grandes que OpenAI |
| Gemini (Google) | Soportado | Tokens emitidos progresivamente |
Retrocompatibilidad
El parametro stream es opcional con default false. Los clientes existentes que no envien stream continuan recibiendo la respuesta JSON completa sin ningun cambio.
Listar Agentes
Devuelve todos los agentes dentro del workspace.
01const agents = await plazbot.agent.getAgents();
Obtener Agente por ID
01const agent = await plazbot.agent.getAgentById({ id: agentId });
Copiar Agente
Crea una copia exacta del agente.
01const copy = await plazbot.agent.copyAgent({ id: agentId });
Obtener Agente por Canal
Busca un agente por su canal y clave asociada.
01const agent = await plazbot.agent.getAgentByChannel({02 channel: "whatsapp",03 key: "+51987654321"04});
Eliminar Agente
Elimina un agente y remueve su referencia de cualquier portal asociado.
01await plazbot.agent.deleteAgent({ id: agentId });
Configuracion Rapida (Quick Config)
Actualiza secciones especificas del agente sin enviar toda la configuracion:
01// Instrucciones02await plazbot.agent.setInstructions(agentId, {03 tone: "professional",04 style: "short answers",05 language: "es-419",06 emojis: false,07 maxWords: 10008});0910// Persona11await plazbot.agent.setPersona(agentId, {12 name: "Maximo",13 role: "Asistente virtual",14 speaksInFirstPerson: true,15 isHuman: false16});1718// Fallbacks19await plazbot.agent.setFallbacks(agentId, {20 noAnswer: "No tengo informacion sobre ese tema.",21 serviceError: "Hubo un problema. Intenta mas tarde.",22 doNotUnderstand: "Podrias reformular tu pregunta?"23});2425// Reglas26await plazbot.agent.setRules(agentId, {27 doNotMentionPrices: false,28 doNotDiagnose: true,29 doNotRespondOutsideHours: "Lunes a Viernes 9am a 6pm."30});3132// Tags33await plazbot.agent.setTags(agentId, ["ventas", "soporte"]);3435// Greeting (saludo)36await plazbot.agent.setGreeting(agentId, "Hola! Soy tu asistente virtual.");
Debug Logs
Obtener los logs de debug del agente para diagnosticar problemas:
01const logs = await plazbot.agent.getDebugLogs(agentId);02console.log(logs);
Utilidades de IA
Mejora un prompt usando inteligencia artificial:
01const result = await plazbot.agent.improvePrompt("eres un bot que ayuda personas");02console.log(result.result); // Prompt mejorado
Manejo de Errores
01try {02 const response = await plazbot.agent.onMessage({03 agentId: "agent_123",04 question: "Cuales son los horarios?",05 sessionId: "session_456"06 });07} catch (error) {08 if (error.status === 401) {09 // Error de autenticacion - Revisa tu API Key10 } else if (error.status === 404) {11 // Agente no encontrado12 } else if (error.status === 429) {13 // Rate limit - Espera antes de reintentar14 }15}
Usa multipleAnswers: true en onMessage cuando necesites respuestas estructuradas para integraciones complejas.
Contacta a nuestro equipo en support@plazbot.com o revisa los ejemplos en el repositorio de GitHub.