Amazon Lex est un service complet de gestion AI qui utilise des modèles de langage naturel pour concevoir, construire, tester et distribuer une interface interactive pour les applications. Ainsi, le chatbot fabriqué d'Amazon Lex peut identifier les intentions afin que vous puissiez envoyer et recevoir une conversation continue, afin que vous puissiez afficher les informations dont vous avez besoin pour réaliser vos intentions. De plus, Amazon Kendra peut être utilisé pour répondre aux intentions qui ne sont pas identifiées dans Amazon Lex. De même, en utilisant l'API ouverte tierce, vous pouvez obtenir des effets similaires. En novembre 2022, Chatgpt a été publié, montrant une excellente capacité de conversation, ce qui permet d'utiliser Chatgpt en tant qu'API ouverte ainsi que Kendra. Dans cet article, je voudrais expliquer comment implémenter un chatbot interactif qui utilise Chatgpt comme une API ouverte pour répondre aux intentions qui ne sont pas définies à l'avance.
L'architecture que vous implémentez ici est la suivante. En utilisant Amazon CloudFront, nous fournissons une page Web pour le chat. Le message de chat que vous avez entré par l'utilisateur utilise Amazon API Gateway et AWS Lambda pour répondre à l'intention de Lex. Cependant, s'il y a une intention qui n'est pas reconnue dans Lex, la fonction lambda sera utilisée pour interroger dans le chatgpt, et le résultat s'affiche dans la fenêtre de chat. L'infrastructure pour la configuration de ces chatbot interactives est créée et gérée à l'aide d'AWS CDK. Étant donné que toute l'infrastructure est composée de serveur (sans serveur), il est possible de faire fonctionner de manière stable le système via une mise à l'échelle automatique même dans un trafic efficace et fluctuant dans la surface de maintenance.

Voir ci-dessous pour une opération détaillée.
Étape 1: L'utilisateur tente de se connecter à la page Web du chatbot avec un domaine de CloudFront et charge HTML, CSS et JavaScript stockés dans S3.
Étape 2: Entrez un message de chat sur la page Web. À l'heure actuelle, la ressource "/ chat" demandera un SMS au format JSON dans la ressource "/ chat".
Étape 3: CloudFront envoie une demande à la passerelle API.
Étape 4: API Gateway appelle la fonction lambda connectée à la ressource / chat.
Étape 5: Les fonctions Lambda transmettent le message de chat à Lex à l'aide de l'API LEX V2.
Étape 6: Lex effectue le comportement correspondant en cas d'intention définie par l'intention. Si vous ne pouvez pas reconnaître vos intentions, envoyez une demande pour contacter Chatgpt.
Étape 7: Si vous répondez dans Chatgpt, la réponse est livrée à l'ordre inverse de l'étape précédente et est livré à l'utilisateur.
La région de Séoul ne prend pas en charge Lex V1, mais seuls les supports Lex V2. Par conséquent, le reconnaissance du LEX V2 est utilisé pour envoyer l'entrée de l'utilisateur au message au message. Le client Runtime V2 définit comme suit.
import { LexRuntimeV2Client , RecognizeTextCommand } from "@aws-sdk/client-lex-runtime-v2" ; La fonction lambda est séparée de l'événement et transmet le message à l'aide du botaliaside ou du bodid comme indiqué ci-dessous, et extrait et transmet le message de la réponse délivrée 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 mars 2023, l'API Open Open de Chatgpt a été libéré. Le chemin de la nouvelle API est "/ v1 / chat / complétion" et utilise le modèle "GPT-3.5-turbo". Ce modèle peut être utilisé à un coût inférieur de 90% par rapport au modèle existant "Text-Davinci-003", mais il ne peut pas être fait pour rechercher la météo dans Chatgpt. Ici, nous décrirons comment utiliser le modèle "Text-Davinci-003" qui prend en charge la recherche pendant le chat avec l'API officielle de ChatGpt.
La demande est faite par l'API ChatGPT fournie par OpenAI, "V1 / Chat / Complétions" à HTTPS Post. Pour ce faire, nous utilisons Fetch ici. À l'heure actuelle, l'en-tête de la demande à livrer au Chatgpt doit inclure l'autorisation et le type de contenu comme indiqué ci-dessous. La clé API requise pour l'autorisation est émise par OpenAI: clé API et stockée comme variable d'environnement. Lorsque vous demandez un message, le rôle peut être spécifié en tant que "utilisateur", "système" ou "assistant" selon le guide de transition de l'API ChatGPT. Le code détaillé peut être trouvé ici (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 },
],
}),
});Lorsque vous envoyez le message de réponse envoyé par Chatgpt, vous devez l'envoyer au format ci-dessous lors de l'envoi à Lex. Dans ce cas, le SessionState doit inclure DialogAction et Intention, et le nom d'intention doit être extrait de l'entrée. De plus, le message de réponse de Chatgpt est mis en "contenu" des "messages" et livré comme suit.
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 ,
}
]
}
} Le modèle "text-davinci-003" utilise "v1 / complétions" en fonction de l'API de l'achèvement. Ici, vous êtes implémenté à l'aide de la bibliothèque Openai Node.js. Le code détaillé peut être trouvé ici (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,
}; Le client transmet le message de chat comme indiqué ci-dessous dans le serveur de chat et l'affiche dans la bulle de chat de réception lorsque la réponse arrive. L'adresse du serveur de chat ici est le domaine de CloudFront. Le code détaillé est confirmé ici (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 );
}Ici, vous pouvez configurer AWS CDK à l'aide de TypeScript. Le code détaillé peut être trouvé ici (cdk-chatbot-sacs.ts).
La fonction lambda pour Lex est définie comme ci-dessous. Il doit inclure le bodid et le botaliaside dans l'environnement. Ici, nous utilisons le chatbot en coréen, nous spécifions donc "ko_kr" comme localId comme indiqué ci-dessous. Cette fonction lambda doit avoir des autorisations pour lex et la passerelle 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' )); L'entrée de Lex est définie pour recevoir via la méthode Post avec la ressource "/ chat" comme indiqué ci-dessous à l'aide de la passerelle 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 ,
},
}
]
}); Pour contourner les COR, enregistrez le comportement de la ressource "/ chat" comme indiqué ci-dessous.
distribution . addBehavior ( "/chat" , new origins . RestApiOrigin ( api ), {
cachePolicy : cloudFront . CachePolicy . CACHING_DISABLED ,
allowedMethods : cloudFront . AllowedMethods . ALLOW_ALL ,
viewerProtocolPolicy : cloudFront . ViewerProtocolPolicy . REDIRECT_TO_HTTPS ,
});Envoyez le texte au chatppt et préparez la fonction lambda qui reçoit la réponse. Où OpenAI_API_KEY est une clé API publiée par 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" ,
}
}); Pour plus de commodité, nous préparons la distribution en utilisant Cloud9 dans la région de Séoul. Cloud9 fournit un environnement pratique pour la création, l'exécution et le débogage du code dans le navigateur. Entrez la console Cloud9, sélectionnez [Créer un environnement] et entrez le nom comme indiqué ci-dessous. Ici, je suis entré "chatbot". Ensuite, le reste est maintenu et sélectionnez [créer].

Lorsque Cloud9 est créé, [ouvrez], puis préparez le terminal comme indiqué ci-dessous.

Téléchargez la source comme indiqué ci-dessous.
git clone https : //github.com/kyopark2014/interactive-chat-using-Lex-and-ChatGPTAccédez au dossier CDK et installez les bibliothèques nécessaires. L'AWS-CDK-lib est une bibliothèque CDK 2.0.
cd interactive - chat - using - Lex - and - ChatGPT / cdk - chatbot && npm installSi vous utilisez CDK pour la première fois, vous devez exécuter le bootstrap comme indiqué ci-dessous. Où le compte ID ici signifie le numéro de compte à 12 chiffres. Vous pouvez vérifier l'écran de la console AWS ou en vérifiant la commande "AWS STS Get-Caller-Identity-Query-ID-ID-Output Text".
cdk bootstrap aws : //account-id/ap-northeast-2Créez un bot Helloworld selon le bot Hello World dans Amazon Lex Korean Chatbot Build Atelier. "Hello World Bot" est un simple bot de salutation qui demande et vérifie le nom.
Après avoir terminé la création de "Hello World Bot", accédez à la console de bot et sélectionnez "Helloworldbot". Vous pouvez voir que le Bodid est "BSZQXD0ABN" comme indiqué ci-dessous.

Si vous sélectionnez [Aliases] de "Helloworldbot", vous pouvez connaître les alias comme indiqué ci-dessous. Sélectionnez "TestBotoalias" ici.

Vous pouvez voir que le botaliaside est "tstaliaside" comme indiqué ci-dessous.

Retour à Cloud9 et ouvrez "Interactive-chat-use-lix-to-chtpt / cdk-flux / lib / lix-lix-sack.ts" dans l'explorateur de fichier de gauche et ouvrez "lambda pour lex" Mettre à jour le botaliasid. Où le SessionId maintient la valeur actuelle ou saisi n'importe quelle valeur.

De plus, entrez "Openai_API_KEY" dans l'environnement de "Lambda pour chatgpt". Si vous n'avez pas de clé pré-reçue, vous serez émis à partir de la clé OpenAi: API.

Créez maintenant une infrastructure complète avec CDK.
cdk deployLorsqu'il est installé normalement, la "sortie" suivante est affichée. Ici, DistributionDomainName est "d3ndv6lhze8yc5.cloudfront.net" et weurl est "https://d3ndv6lhze8yc.cloudfront.net/chat.html".

Sélectionnez "Hellowworldbot" dans la console AWS LEX et sélectionnez [Langues] dans "Aliases" et sélectionnez [Corée (Corée du Sud)] comme indiqué ci-dessous.

Sélectionnez "Lambda-chatgpt" comme [Soucet], et [version de la fonction lambda ou alias] Sélectionnez "$ le dernier" et sélectionnez [Enregistrer].

Sélectionnez ensuite [FallbackIntent] comme indiqué ci-dessous dans [Intentes] de "Hellowworldbot".

Faites défiler vers le bas et sélectionnez [Options avancées] dans FullFillement et permet [utilisez une fonction lambda pour l'accomplissement] de la pop -up ci-dessous.

Sélectionnez [build] en haut de l'écran pour appliquer le contenu modifié.

"Https://d3ndv6lhze8yc.cloudfront.net/chat.html" est connecté à l'écran de chat dans le navigateur. La question de "Lex", qui est la question après l'opération d'intention, n'a pas été enregistrée comme une intention. Selon les paramètres du navigateur, vous ne pourrez peut-être pas recevoir une partie de la réponse à Chatgpt.

Si vous n'utilisez plus l'infrastructure, vous pouvez supprimer toutes les ressources comme indiqué ci-dessous.
cdk destroy J'ai implémenté le chatbot interactif à l'aide d'Amazon Lex et Chatgpt, et j'ai expliqué comment utiliser AWS CDK pour développer et utiliser efficacement l'infrastructure. En utilisant Chatgpt, vous pouvez également améliorer votre convivialité en donnant aux utilisateurs la réponse appropriée aux intentions qui ne sont pas reconnues dans Lex. Chatgpt a déjà prouvé son excellente capacité de conversation et divers modèles GPT sont actuellement annoncés. Par conséquent, en introduisant ces modèles d'intelligence artificielle dans des services de chatbot tels que Lex, il devrait améliorer la convivialité des utilisateurs et fournir un meilleur service.