Amazon Lex es un servicio de IA de gestión completo que utiliza modelos de lenguaje natural para diseñar, construir, probar y distribuir interfaz interactiva para aplicaciones. Por lo tanto, el chatbot hecho de Amazon Lex puede identificar intenciones para que pueda enviar y recibir una conversación continua, para que pueda mostrar la información que necesita para cumplir con sus intenciones. Además, Amazon Kendra se puede usar para responder las intenciones que no se identifican en Amazon Lex. Del mismo modo, utilizando la API abierta de terceros, puede obtener efectos similares. En noviembre de 2022, se lanzó ChatGPT, mostrando una excelente capacidad de conversación, lo que permite usar ChatGPT como API abierto y Kendra. En esta publicación, me gustaría explicar cómo implementar un chatbot interactivo que use ChatGPT como una API abierta para responder intenciones que no se definen de antemano.
La arquitectura que implementa aquí es la siguiente. Usando Amazon CloudFront, proporcionamos una página web para el chat. El mensaje de chat que ingresó por el usuario usa Amazon API Gateway y AWS Lambda para responder la intención en LEX. Sin embargo, si hay una intención que no se reconoce en LEX, la función Lambda se usará para consultar en el CHATGPT, y el resultado se muestra en la ventana de chat. La infraestructura para configurar dicho chatbot interactivo se crea y gestiona utilizando AWS CDK. Dado que toda infraestructura está compuesta de sin servidor (sin servidor), es posible operar de manera estable el sistema a través de la escala automática incluso en el tráfico eficiente y fluctuante en la superficie de mantenimiento.

Consulte a continuación la operación detallada.
Paso 1: El usuario intenta conectarse a la página web de chatbot con un dominio de CloudFront y carga HTML, CSS y JavaScript almacenados en S3.
Paso 2: ingrese un mensaje de chat en la página web. En este momento, el recurso "/chat" solicitará un mensaje de texto en el formato JSON en el recurso "/chat".
Paso 3: CloudFront envía una solicitud a API Gateway.
Paso 4: API Gateway llama a la función Lambda conectada al recurso /chat.
Paso 5: Las funciones de Lambda pasan el mensaje de chat a LEX usando la API LEX V2.
Paso 6: LEX realiza el comportamiento correspondiente si hay una intención de intención definida. Si no puede reconocer sus intenciones, envíe una solicitud para contactar a ChatGPT.
Paso 7: Si responde en ChatGPT, la respuesta se entrega al orden inverso de la etapa anterior y se entrega al usuario.
La región de Seúl no es compatible con Lex V1, pero solo admite LEX V2. Por lo tanto, el reconocimiento de reconocimiento del LEX V2 se usa para enviar la entrada del usuario al mensaje al mensaje. Lex Runtime V2 Client define de la siguiente manera.
import { LexRuntimeV2Client , RecognizeTextCommand } from "@aws-sdk/client-lex-runtime-v2" ; La función Lambda se separa del evento y entrega el mensaje utilizando la botaliasida o botid como se muestra a continuación, y extrae y pasa el mensaje de la respuesta entregada de LEX.
const text = event . text ;
let lexParams = {
botAliasId : process . env . botAliasId ,
botId : process . env . botId ,
localeId : process . env . localeId ,
text : text ,
sessionId : process . env . sessionId ,
};
const lexClient = new LexRuntimeV2Client ();
const command = new RecognizeTextCommand ( lexParams );
const data = await lexClient . send ( command );
return {
statusCode : 200 ,
msg : data [ 'messages' ][ 0 ]. content ,
};En marzo de 2023, se lanzó la API abierta oficial de ChatGPT. La ruta de la nueva API es "/v1/chat/terminals" y usa el modelo "GPT-3.5-TURBO". Este modelo se puede usar a un costo 90% más bajo en comparación con el modelo existente "Text-Davinci-003", pero no se puede hacer para buscar el clima en ChatGPT. Aquí, describiremos cómo usar el modelo "Text-Davinci-003" que admite la búsqueda durante el chat con la API oficial de ChatGPT.
La solicitud es realizada por la API CHATGPT proporcionada por OpenAI, "V1/CHAT/Finalations" a la publicación HTTPS. Para hacer esto, usamos Fetch aquí. En este momento, el encabezado de la solicitud que se entregará al CHATGPT debe incluir autorización y tipo de contenido como se muestra a continuación. La clave API requerida para la autorización es emitida por OpenAI: la clave API y se almacena como una variable de entorno. Al solicitar un mensaje, el rol se puede especificar como "usuario", "sistema" o "asistente" de acuerdo con la Guía de transición de la API de ChatGPT. El código detallado se puede encontrar aquí (index.mjs).
import fetch from 'node-fetch' ;
const apiKey = process . env . OPENAI_API_KEY
let msg = "" ;
const res = await fetch ( 'https://api.openai.com/v1/chat/completions' ,{
method : "POST" ,
headers : {
"Authorization" : "Bearer " + apiKey ,
"Content-Type" : "application/json" ,
},
body : JSON . stringify ({
"model" : "gpt-3.5-turbo" ,
"messages" : [
{ "role" : "user" , "content" : prompt },
],
}),
});Cuando envía el mensaje de respuesta enviado por ChatGPT, debe enviarlo al formato a continuación al enviarlo a LEX. En este caso, el SessionState debe incluir dialogacción e intención, y el nombre de la intención debe extraerse de la entrada. Además, el mensaje de respuesta de ChatGPT se coloca en "contenido" de "mensajes" y se entrega de la siguiente manera.
if ( res . ok ) {
const data = await res . json ();
console . log ( "output: " , data . choices [ 0 ]);
msg = `[ ChatGPT ] $ { data . choices [ 0 ]. message . content }`;
console . log ( "msg: " + msg );
const intentName = event . interpretations [ 0 ]. intent . name ; // intent name
response = {
"sessionState" : {
"dialogAction" : {
"type" : "Close"
},
"intent" : {
"confirmationState" : "Confirmed" ,
"name" : intentName ,
"state" : "Fulfilled" ,
},
},
"messages" : [
{
"contentType" : "PlainText" ,
"content" : msg ,
}
]
}
} El modelo "Text-Davinci-003" usa "V1/finalizaciones" de acuerdo con la API de finalización. Aquí se implementa utilizando la biblioteca Node.js de OpenAI. El código detallado se puede encontrar aquí (index-Davinch.mjs).
import { Configuration , OpenAIApi } from " openai ";
const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);
const models = ['text-davinci-003','code-davinci-002'];
const frequency_penalty = 0.5;
const max_tokens = 2000;
const presence_penalty = 0.1;
const temperature = 0;
const top_p = 1;
const model_name = models[0];
const prompt = event.text;
const params = {
model: model_name,
prompt: prompt,
temperature: temperature,
max_tokens: max_tokens,
top_p: top_p,
frequency_penalty: frequency_penalty,
presence_penalty: presence_penalty,
};
const result = await openai.createCompletion(params);
const choices = result.data.choices;
return {
statusCode: 200,
id: result.data.id,
msg: choices[0].text,
}; El cliente transmite el mensaje de chat como se muestra a continuación en el servidor de chat y lo muestra en la burbuja de chat de recepción cuando llegue la respuesta. La dirección del servidor de chat aquí es el dominio de CloudFront. El código detallado se confirma aquí (chat.js).
function sendRequest ( text ) {
const uri = "/chat" ;
const xhr = new XMLHttpRequest ();
xhr . open ( "POST" , uri , true );
xhr . onreadystatechange = () => {
if ( xhr . readyState === 4 && xhr . status === 200 ) {
response = JSON . parse ( xhr . responseText );
console . log ( "response: " + JSON . stringify ( response ));
addReceivedMessage ( response . msg )
}
};
var requestObj = { "text" : text }
console . log ( "request: " + JSON . stringify ( requestObj ));
var blob = new Blob ([ JSON . stringify ( requestObj )], { type : 'application/json' });
xhr . send ( blob );
}Aquí puede configurar AWS CDK usando TypeScript. El código detallado se puede encontrar aquí (CDK-Chatbot-Sack.ts).
La función Lambda para LEX se define como a continuación. Debe incluir botid y botaliasida en el medio ambiente. Aquí, usamos chatbot en coreano, por lo que especificamos "ko_kr" como localid como se muestra a continuación. Esta función Lambda debe tener permisos para la puerta de enlace LEX y API.
// Lambda for lex
const lambdaLex = new lambda . Function ( this , 'lambda-function-lex' , {
description : 'lambda for chat' ,
functionName : 'lambda-function-lex' ,
handler : 'index.handler' ,
runtime : lambda . Runtime . NODEJS_18_X ,
code : lambda . Code . fromAsset ( path . join ( __dirname , '../../lambda-lex' )),
timeout : cdk . Duration . seconds ( 120 ),
environment : {
botId : "BSZQXD0ABN" ,
botAliasId : "TSTALIASID" ,
localeId : "ko_KR" , // en_US
sessionId : "mysession-01" ,
}
});
const lexPolicy = new iam . PolicyStatement ({
actions : [ 'lex:*' ],
resources : [ '*' ],
});
lambdaLex . role ?. attachInlinePolicy (
new iam . Policy ( this , 'rekognition-policy' , {
statements : [ lexPolicy ],
}),
);
// permission for api Gateway
lambdaLex . grantInvoke ( new iam . ServicePrincipal ( 'apigateway.amazonaws.com' )); La entrada de LEX está configurada para recibir el método de publicación con el recurso "/CHAT" como se muestra a continuación utilizando la puerta de enlace API.
const api = new apiGateway . RestApi ( this , 'api-chatbot' , {
description : 'API Gateway for chatbot' ,
endpointTypes : [ apiGateway . EndpointType . REGIONAL ],
deployOptions : {
stageName : stage ,
},
});
const chat = api . root . addResource ( 'chat' );
chat . addMethod ( 'POST' , new apiGateway . LambdaIntegration ( lambdaLex , {
passthroughBehavior : apiGateway . PassthroughBehavior . WHEN_NO_TEMPLATES ,
credentialsRole : role ,
integrationResponses : [{
statusCode : '200' ,
}],
proxy : false ,
}), {
methodResponses : [
{
statusCode : '200' ,
responseModels : {
'application/json' : apiGateway . Model . EMPTY_MODEL ,
},
}
]
}); Para evitar el CORS, registre el comportamiento para el recurso "/CHAT" como se muestra a continuación.
distribution . addBehavior ( "/chat" , new origins . RestApiOrigin ( api ), {
cachePolicy : cloudFront . CachePolicy . CACHING_DISABLED ,
allowedMethods : cloudFront . AllowedMethods . ALLOW_ALL ,
viewerProtocolPolicy : cloudFront . ViewerProtocolPolicy . REDIRECT_TO_HTTPS ,
});Envíe el texto al CHATGPT y prepare la función Lambda que recibe la respuesta. Donde OpenAI_API_Key es una clave API emitida por OpenAI.
const lambdachat = new lambda . Function ( this , 'lambda-chatgpt' , {
description : 'lambda for chatgpt' ,
functionName : 'lambda-chatgpt' ,
handler : 'index.handler' ,
runtime : lambda . Runtime . NODEJS_18_X ,
code : lambda . Code . fromAsset ( path . join ( __dirname , '../../lambda-chatgpt' )),
timeout : cdk . Duration . seconds ( 120 ),
environment : {
OPENAI_API_KEY : "123456" ,
}
}); Para conveniencia, preparamos la distribución utilizando Cloud9 en la región de Seúl. Cloud9 proporciona un entorno conveniente para crear, ejecutar y depurar código en el navegador. Ingrese la consola Cloud9, seleccione [Crear entorno] e ingrese el nombre como se muestra a continuación. Aquí, entré en "chatbot". Posteriormente, el resto se mantiene y selecciona [Crear].

Cuando se crea Cloud9, [Abra] y luego prepare el terminal como se muestra a continuación.

Descargue la fuente como se muestra a continuación.
git clone https : //github.com/kyopark2014/interactive-chat-using-Lex-and-ChatGPTVaya a la carpeta CDK e instale las bibliotecas necesarias. El AWS-CDK-LIB es una biblioteca CDK 2.0.
cd interactive - chat - using - Lex - and - ChatGPT / cdk - chatbot && npm installSi está utilizando CDK por primera vez, debe ejecutar el Bootstrap como se muestra a continuación. Donde el ID de cuenta aquí significa número de cuenta de 12 dígitos. Puede verificar en la pantalla de la consola AWS o verificar el comando "AWS STS Get-Caller-Identity-Query-ID-ID-Output Text".
cdk bootstrap aws : //account-id/ap-northeast-2Crea Helloworld Bot de acuerdo con Hello World Bot en Amazon Lex coreano Chatbot Build Workshop. "Hello World Bot" es un simple bot de saludo que pregunta y verifica el nombre.
Después de completar la creación de "Hello World Bot", acceda a la consola BOT y seleccione "Helloworldbot". Puede ver que el botid es "bszqxd0abn" como se muestra a continuación.

Si selecciona [alias] de "Helloworldbot", puede conocer los alias como se muestra a continuación. Seleccione "TestBotoalias" aquí.

Puede ver que Botaliasid es "Tstaliasid" como se muestra a continuación.

Regrese a Cloud9 y abra "Interactive-Chat-Use-LEx-To-ChTGPT/CDK-LEX/LIB/LIX-LEX-Sack.ts" en el explorador de archivos izquierdo y abra "lambda para lex" Actualizar botaliasid. Donde el SessionId mantiene el valor actual o ingresó cualquier valor.

Además, ingrese "OpenAI_API_KEY" en el entorno de "Lambda para chatgpt". Si no tiene una tecla previa a la recepción, se le emitirá desde OpenAI: API Key.

Ahora cree una infraestructura completa con CDK.
cdk deployCuando se instala normalmente, se muestra la siguiente "salida". Aquí, DistributionDomainName es "d3ndv6lhze8yc5.cloudfront.net" y Weburl es "https://d3ndv6lhze8yc5.cloudfront.net/chat.html".

Seleccione "HellowWorldBot" de la consola AWS Lex y seleccione [Idiomas] en "Alias" y seleccione [Corea (Corea del Sur)] como se muestra a continuación.

Seleccione "Lambda-ChatGPT" como [Soucet], y [Versión de función Lambda o alias] Seleccione "$ último" y seleccione [Guardar].

Luego seleccione [FallbackIntent] como se muestra a continuación en [Intentos] de "HellowWorldBot".

Desplácese hacia abajo y seleccione [Opciones avanzadas] de Fullfillment y habilita [use una función Lambda para su cumplimiento] del pop -UP a continuación.

Seleccione [construir] en la parte superior de la pantalla para aplicar el contenido cambiado.

"" Https://d3ndv6lhze8yc5.cloudfront.net/chat.html "está conectado a la pantalla de chat en el navegador. Puede chatear con LEX en el navegador web como se muestra a continuación. La cuestión de "lex", que es la pregunta después de la operación de intención, no se registró como una intención. Dependiendo de la configuración del navegador, es posible que no pueda recibir parte de la respuesta a ChatGPT.

Si ya no usa la infraestructura, puede eliminar todos los recursos como se muestra a continuación.
cdk destroy Implementé el chatbot interactivo usando Amazon Lex y ChatGPT, y expliqué cómo usar AWS CDK para desarrollar y operar de manera efectiva la infraestructura. Al usar CHATGPT, también puede mejorar su usabilidad al dar a los usuarios la respuesta adecuada a las intenciones que no se reconocen en LEX. ChatGPT ya ha demostrado su excelente capacidad de conversación, y actualmente se están anunciando varios modelos GPT. Por lo tanto, al introducir estos modelos de inteligencia artificial en servicios de chatbot, como LEX, se espera que mejore la usabilidad del usuario y brinde un mejor servicio.