Creación de un cliente personalizado utilizando la API
Función de aprendizaje automático en watsonx Assistant
A partir del 16 de junio de 2025, la función de aprendizaje automático dejará de funcionar en watsonx Assistant. Después de esta fecha, los ajustes de aprendizaje automático
se eliminan de la página de ajustes globales de Acciones y se desactivan todas las funciones de aprendizaje automático.
Si ninguna de las integraciones incorporadas satisface sus necesidades, puede desplegar su asistente desarrollando una aplicación cliente personalizada que interactúe con sus usuarios y se comunique con el servicio IBM® watsonx™ Assistant.
Los SDK de Watson le ayudan a escribir código que interactúa con watsonx Assistant. Para obtener más información sobre los SDK, consulte IBM Watson APIs.
Configuración del asistente
La aplicación de ejemplo que creamos en implementa varias funciones simples para ilustrar cómo interactúa una aplicación cliente con watsonx Assistant. El código de aplicación recopila la entrada y la envía a un asistente, que envía las respuestas que la aplicación muestra al usuario.
Para probar este ejemplo usted mismo, primero debe configurar el asistente de ejemplo simple al que se conecta el cliente:
- Descargue las acciones archivo JSON.
- Cree un asistente.
- En el nuevo asistente, abra los valores de acción global. Vaya a la pestaña Cargar/Descargar e importe las acciones del archivo que ha descargado.
Las acciones de ejemplo incluyen una acción Greet customer que solicita el nombre del cliente y acciones simples para concertar y cancelar citas.
Obtención de información del servicio
Para acceder a las API REST de watsonx Assistant, la aplicación debe poder autenticarse con IBM Cloud® y conectarse al asistente en el entorno donde se despliega. Debe copiar las credenciales de servicio y el ID de entorno y pegarlos en el código
de su aplicación. También necesita la dirección URL para la ubicación de su instancia de servicio (por ejemplo, https://api.us-south.assistant.watson.cloud.ibm.com).
Para encontrar esta información:
-
Vaya a la página Entornos y elija el entorno al que desea conectarse.
-
Haga clic en el icono de Configuración icono
para abrir la configuración del entorno.
-
Seleccione Detalles de la API para ver los detalles del entorno, incluida la URL la instancia de servicio y el ID del entorno. Para encontrar la clave de API, siga el enlace de la sección Credenciales de servicio.
Comunicación con el servicio watsonx Assistant
Es muy sencillo interactuar con el servicio watsonx Assistant desde la aplicación cliente. Comenzamos con un ejemplo que se conecta al servicio, envía un único mensaje vacío e imprime la salida en la consola:
// Example 1: Creates service object, sends initial message, and
// receives response.
const AssistantV2 = require('ibm-watson/assistant/v2');
const { IamAuthenticator } = require('ibm-watson/auth');
// Create Assistant service object.
const assistant = new AssistantV2({
version: '2021-11-27',
authenticator: new IamAuthenticator({
apikey: '{apikey}', // replace with API key
}),
url: '{url}', // replace with URL
});
const assistantId = '{environment_id}'; // replace with environment ID
// Start conversation with empty message
messageInput = {
messageType: 'text',
text: '',
};
sendMessage(messageInput);
// Send message to assistant.
function sendMessage(messageInput) {
assistant
.messageStateless({
assistantId,
input: messageInput,
})
.then(res => {
processResult(res.result);
})
.catch(err => {
console.log(err); // something went wrong
});
}
// Process the result.
function processResult(result) {
// Print responses from actions, if any. Supports only text responses.
if (result.output.generic) {
if (result.output.generic.length > 0) {
result.output.generic.forEach( response => {
if (response.response_type == 'text') {
console.log(response.text);
}
});
}
}
}
# Example 1: Creates service object, sends initial message, and
# receives response.
from ibm_watson import AssistantV2
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator
# Create Assistant service object.
authenticator = IAMAuthenticator('{apikey}') # replace with API key
assistant = AssistantV2(
version = '2021-11-27',
authenticator = authenticator
)
assistant.set_service_url('{url}') # replace with service instance URL
assistant_id = '{environment_id}' # replace with environment ID
# Start conversation with empty message.
result = assistant.message_stateless(
assistant_id,
).get_result()
# Print responses from actions, if any. Supports only text responses.
if result['output']['generic']:
for response in result['output']['generic']:
if response['response_type'] == 'text':
print(response['text'])
El primer paso consiste en crear un objeto de servicio, una especie de envoltorio para el servicio watsonx Assistant.
El objeto de servicio se utiliza para enviar información de entrada al servicio y para recibir información de salida de este. Cuando crea el objeto de servicio, especifica la clave de API para la autenticación y la versión de la API de watsonx Assistant que está utilizando.
En este ejemplo de Node.js, el objeto de servicio es una instancia de AssistantV2 almacenada en la variable assistant. Los SDK de Watson para otros idiomas proporcionan mecanismos equivalentes para crear una instancia
de un objeto de servicio.
En este ejemplo de Python, el objeto de servicio es una instancia de watson_developer_cloud.AssistantV2, almacenada en la variable assistant. Los SDK de Watson para otros idiomas proporcionan mecanismos equivalentes
para crear una instancia de un objeto de servicio.
Después de crear el objeto de servicio, lo utilizamos para enviar un mensaje al asistente, mediante el método sin estado message. En este ejemplo, el mensaje está vacío; queremos desencadenar la acción Greet customer para
iniciar la conversación, por lo que no necesitamos ningún texto de entrada. A continuación, imprimimos las respuestas de texto que se devuelven en la matriz generic en la salida devuelta.
Utilice el mandato node <filename.js> para ejecutar la aplicación de ejemplo.
Utilice el mandato python3 <filename.py> para ejecutar la aplicación de ejemplo.
Nota: Asegúrese de instalar Watson SDK for Node.js utilizando npm install ibm-watson.
Nota: Asegúrese de instalar el SDK Watson para Python utilizando pip install --upgrade ibm-watson o easy_install --upgrade ibm-watson.
Suponiendo que todo funciona como se espera, el asistente devuelve la salida del asistente, que la aplicación imprime en la consola:
Welcome to the watsonx Assistant example. What's your name?
Esta salida nos indica que nos hemos comunicado con el asistente y hemos recibido el mensaje de saludo especificado por la acción Greet customer. Pero aún no tenemos una forma de responder a la pregunta del asistente.
Procesando entrada de usuario
Para poder procesar la entrada de usuario, debemos añadir una interfaz de usuario a nuestra aplicación cliente. Para este ejemplo, mantendremos las cosas simples y utilizaremos la entrada y salida estándar.
Puede utilizar el módulo prompt-sync de Node.js. (Puede instalar prompt-sync utilizando npm install prompt-sync.)
Puede utilizar la función Python 3 input.
// Example 2: Adds user input.
const prompt = require('prompt-sync')();
const AssistantV2 = require('ibm-watson/assistant/v2');
const { IamAuthenticator } = require('ibm-watson/auth');
// Create Assistant service object.
const assistant = new AssistantV2({
version: '2021-11-27',
authenticator: new IamAuthenticator({
apikey: '{apikey}', // replace with API key
}),
url: '{url}', // replace with URL
});
const assistantId = '{environment_id}'; // replace with environment ID
// Start conversation with empty message
messageInput = {
messageType: 'text',
text: '',
};
sendMessage(messageInput);
// Send message to assistant.
function sendMessage(messageInput) {
assistant
.messageStateless({
assistantId,
input: messageInput,
})
.then(res => {
processResult(res.result);
})
.catch(err => {
console.log(err); // something went wrong
});
}
// Process the result.
function processResult(result) {
// Print responses from actions, if any. Supports only text responses.
if (result.output.generic) {
if (result.output.generic.length > 0) {
result.output.generic.forEach( response => {
if (response.response_type === 'text') {
console.log(response.text);
}
});
}
}
// Prompt for the next round of input unless skip_user_input is true.
let newMessageFromUser = '';
if (result.context.global.system.skip_user_input !== true) {
newMessageFromUser = prompt('>> ');
}
if (newMessageFromUser !== 'quit') {
newMessageInput = {
messageType: 'text',
text: newMessageFromUser,
}
sendMessage(newMessageInput);
}
}
# Example 2: Adds user input.
from ibm_watson import AssistantV2
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator
# Create Assistant service object.
authenticator = IAMAuthenticator('{apikey}') # replace with API key
assistant = AssistantV2(
version = '2021-11-27',
authenticator = authenticator
)
assistant.set_service_url('{url}') # replace with service instance URL
assistant_id = '{environment_id}' # replace with environment ID
# Initialize with empty value to start the conversation.
message_input = {
'message_type:': 'text',
'text': ''
}
context = None
# Main input/output loop
while message_input['text'] != 'quit':
# Send message to assistant.
result = assistant.message_stateless(
assistant_id,
input = message_input,
context=context
).get_result()
context = response['context']
# Print responses from actions, if any. Supports only text responses.
if result['output']['generic']:
for response in result['output']['generic']:
if response['response_type'] == 'text':
print(response['text'])
# Prompt for the next round of input unless skip_user_input is True.
if not result['context']['global']['system'].get('skip_user_input', False):
user_input = input('>> ')
message_input = {
'text': user_input
}
Esta versión de la aplicación empieza igual que antes: enviando un mensaje vacío al asistente para empezar la conversación.
La función processResult() muestra el texto de las respuestas que se reciben del asistente. Luego solicita el texto que rodea la entrada de usuario.
A continuación, muestra el texto de las respuestas que se reciben del asistente y solicita la siguiente ronda de entrada de usuario.
El ejemplo comprueba la variable de contexto global skip_user_input y solicita la entrada de usuario sólo si esta variable no está establecida en true
True. La variable skip_user_input la establece el asistente en algunas situaciones en las que no se necesita ninguna entrada de usuario (por ejemplo, si el asistente ha llamado a un servicio externo pero sigue
esperando el resultado). Es una buena práctica siempre realizar esta comprobación antes de solicitar la entrada del usuario.
Debido a que necesitamos una forma de finalizar la conversación, la aplicación cliente también está pendiente del mandato literal quit para indicar que el programa debe salir.
Pero aún hay algo que no es correcto:
Welcome to the watsonx Assistant example. What's your name?
>> Robert
I'm afraid I don't understand. Please rephrase your question.
>> I want to make an appointment.
What day would you like to come in?
>> Thursday
I'm afraid I don't understand. Please rephrase your question.
>>
El asistente está empezando con el saludo correcto, pero no entiende cuándo le dices tu nombre. Y si le dices que quieres hacer una cita, se desencadena la acción correcta; pero de nuevo, no entiende cuando respondes a la pregunta de seguimiento.
La razón es porque estamos utilizando el método sin estado message, lo que significa que es responsabilidad de nuestra aplicación cliente mantener la información de estado para la conversación. Como todavía no estamos haciendo nada
para mantener el estado, el asistente ve cada ronda de entrada del usuario como el primer turno de una nueva conversación. Debido a que no tiene memoria de hacer una pregunta, trata de interpretar su respuesta como una nueva pregunta o solicitud.
Mantenimiento del estado
La información de estado de tu conversación se mantiene utilizando el contexto. El contexto es un objeto que se pasa de un lado a otro entre tu aplicación y el asistente, almacenando información que puede conservarse y actualizarse
a medida que avanza la conversación. Dado que estamos utilizando el método message sin estado, el asistente no almacena el contexto, por lo que es responsabilidad de nuestra aplicación cliente mantenerla entre los distintos turnos
de conversación.
El contexto incluye un identificador de sesión para cada conversación y un contador que se incrementa con cada turno de la conversación. El asistente actualiza el contexto y lo devuelve con cada respuesta. Sin embargo, nuestra versión anterior del ejemplo no conservó el contexto, por lo que se perdieron estas actualizaciones y cada serie de entrada parecía ser el inicio de una nueva conversación. Podemos solucionarlo guardando el contexto y devolviéndolo al asistente cada vez.
Además de mantener nuestro lugar en la conversación, el contexto puede contener variables de acción que almacenen otros datos que quieras pasar de un lado a otro entre tu aplicación y el asistente. Por ejemplo, puede incluir datos persistentes que desee mantener a lo largo de la conversación (como el nombre o número de cuenta de un cliente), o cualquier otro dato que desee rastrear (como el contenido de un carro de la compra o las preferencias de usuario).
// Example 3: Preserves context to maintain state.
const prompt = require('prompt-sync')();
const AssistantV2 = require('ibm-watson/assistant/v2');
const { IamAuthenticator } = require('ibm-watson/auth');
// Create Assistant service object.
const assistant = new AssistantV2({
version: '2021-11-27',
authenticator: new IamAuthenticator({
apikey: '{apikey}', // replace with API key
}),
url: '{url}', // replace with URL
});
const assistantId = '{environment_id}'; // replace with environment ID
// Start conversation with empty message
messageInput = {
messageType: 'text',
text: '',
};
context = {};
sendMessage(messageInput);
// Send message to assistant.
function sendMessage(messageInput, context) {
assistant
.messageStateless({
assistantId,
input: messageInput,
context: context,
})
.then(res => {
processResult(res.result);
})
.catch(err => {
console.log(err); // something went wrong
});
}
// Process the result.
function processResult(result) {
let context = result.context;
// Print responses from actions, if any. Supports only text responses.
if (result.output.generic) {
if (result.output.generic.length > 0) {
result.output.generic.forEach( response => {
if (response.response_type === 'text') {
console.log(response.text);
}
});
}
}
// Prompt for the next round of input unless skip_user_input is true.
let newMessageFromUser = '';
if (result.context.global.system.skip_user_input !== true) {
newMessageFromUser = prompt('>> ');
}
if (newMessageFromUser !== 'quit') {
newMessageInput = {
messageType: 'text',
text: newMessageFromUser,
}
sendMessage(newMessageInput, context);
}
}
# Example 3: Preserves context to maintain state.
from ibm_watson import AssistantV2
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator
# Create Assistant service object.
authenticator = IAMAuthenticator('{apikey}') # replace with API key
assistant = AssistantV2(
version = '2021-11-27',
authenticator = authenticator
)
assistant.set_service_url('{url}') # replace with service instance URL
assistant_id = '{environment_id}' # replace with environment ID
# Initialize with empty message to start the conversation.
message_input = {
'message_type:': 'text',
'text': ''
}
context = {}
# Initialize with empty message to start the conversation.
message_input = {
'message_type:': 'text',
'text': ''
}
context = {}
# Main input/output loop
while message_input['text'] != 'quit':
# Send message to assistant.
result = assistant.message_stateless(
assistant_id,
input = message_input,
context = context
).get_result()
context = result['context']
# Print responses from actions, if any. Supports only text responses.
if result['output']['generic']:
for response in result['output']['generic']:
if response['response_type'] == 'text':
print(response['text'])
# Prompt for the next round of input unless skip_user_input is True.
if not result['context']['global']['system'].get('skip_user_input', False):
user_input = input('>> ')
message_input = {
'text': user_input
}
El único cambio con respecto al ejemplo anterior es que ahora estamos almacenando el contexto que se recibe del asistente en una variable que se llama context, y lo estamos enviando de vuelta con la siguiente ronda de entrada del
usuario:
El único cambio con respecto al ejemplo anterior es que ahora estamos almacenando el contexto que se recibe del asistente en una variable que se llama context, y lo estamos enviando de vuelta con la siguiente ronda de entrada del
usuario:
assistant
.messageStateless({
assistantId,
input: messageInput,
context: context,
})
response = assistant.message_stateless(
assistant_id,
input = message_input,
context = context
).get_result()
Esto garantiza que se mantiene el contexto entre una ronda y la siguiente, de modo que el servicio watsonx Assistant ya no piensa que cada ronda es la primera:
Welcome to the watsonx Assistant example. What's your name?
>> Robert
Hi, Robert! How can I help you?
>> I want to make an appointment.
What day would you like to come in?
>> Next Monday
What time works for you?
>> 10 AM
OK, Robert. You have an appointment for 10:00 AM on Sep 12. See you then!
Satisfactorio. La aplicación ahora utiliza el servicio watsonx Assistant para comprender la entrada de lenguaje natural y muestra las respuestas adecuadas.
Este sencillo ejemplo ilustra cómo puede crear una aplicación cliente personalizada para comunicarse con el asistente. Una aplicación del mundo real utilizaría una interfaz de usuario más sofisticada y podría integrarse con otras aplicaciones como una base de datos de clientes u otros sistemas empresariales. También tendría que enviar más datos al asistente, como un ID de usuario para identificar a cada usuario único. Pero los principios básicos sobre cómo la aplicación interactúa con el servicio watsonx Assistant seguirían siendo los mismos.
Incluidas las preguntas aclaratorias
Si el asistente detecta que hay más de una acción que puede satisfacer la solicitud del cliente, puede pedir automáticamente una aclaración. Para obtener más información, consulte Preguntas aclaratorias.
Para incluir la aclaración de preguntas en el cliente personalizado, debe:
- Visualizar las opciones de sugerencia de aclaración que se devuelven desde la API de
message - Llame a la API de
messageen la siguiente ronda con una carga útil que corresponda a la opción de sugerencia que un cliente ha elegido para responder a la pregunta aclaratoria. Si no implementa la llamada, autolearning y utilizando solicitudes no reconocidas para obtener recomendaciones de acción no funcionan correctamente.
Cada sugerencia de aclaración incluye:
- Una etiqueta que se puede mostrar al cliente
- Un valor que especifica la entrada que se envía al asistente si el usuario elige la sugerencia correspondiente
Para implementar sugerencias de aclaración en la aplicación:
-
Utilice el objeto
value.inputde la sugerencia seleccionada como la siguiente ronda de entrada de mensaje, en lugar de crear un nuevo objeto de entrada. A continuación, el asistente responde desencadenando la acción que está asociada con la opción de sugerencia para iniciar. -
Verifique que lo ha implementado correctamente utilizando el cliente personalizado utilizando la página Analizar. Especifique una entrada que desencadene una aclaración y, a continuación, pulse la opción Ninguno de los anteriores. Cuando vea la solicitud en Conversaciones, compruebe que la solicitud de usuario que ha iniciado la aclaración esté marcada con No reconocido, lo que indica que el cliente está enviando correctamente la entrada de aclaración a su asistente.
Utilización de la API de tiempo de ejecución v1
El uso de la API v2 es el método recomendado para crear una aplicación cliente de tiempo de ejecución que se comunique con el servicio watsonx Assistant. Sin embargo, es posible que algunas aplicaciones más antiguas sigan utilizando la API de tiempo de ejecución v1, que incluye un método similar para enviar mensajes al espacio de trabajo en un conocimiento de diálogo. Si su aplicación utiliza la API de tiempo de ejecución v1, se comunica directamente con el espacio de trabajo, evitando las capacidades de orquestación de habilidades y gestión de estados del asistente.
Para obtener más información sobre el método v1 /message y el contexto, consulte la Referencia de la API v1.