Zephyrnet-Logo

Transformieren Sie persönliche Kundeninteraktionen: Erstellen Sie sprachfähige Auftragsabwicklungsagenten mit AWS und generativer KI | Amazon Web Services

Datum:

In der heutigen Landschaft der Eins-zu-Eins-Interaktion mit Kunden bei der Bestellung ist die vorherrschende Praxis weiterhin auf menschliche Bedienung angewiesen, selbst in Umgebungen wie Drive-in-Cafés und Fast-Food-Restaurants. Dieser traditionelle Ansatz birgt mehrere Herausforderungen: Er hängt stark von manuellen Prozessen ab, lässt sich nur schwer effizient an steigende Kundenanforderungen anpassen, birgt die Möglichkeit menschlicher Fehler und arbeitet innerhalb bestimmter Verfügbarkeitszeiten. Darüber hinaus kann es für Unternehmen, die sich ausschließlich an manuelle Prozesse halten, in wettbewerbsintensiven Märkten schwierig sein, einen effizienten und wettbewerbsfähigen Service zu bieten. Trotz technologischer Fortschritte ist das menschenzentrierte Modell in der Auftragsabwicklung nach wie vor tief verwurzelt, was zu diesen Einschränkungen führt.

Die Aussicht, Technologie zur persönlichen Unterstützung bei der Auftragsabwicklung einzusetzen, besteht schon seit einiger Zeit. Bestehende Lösungen lassen sich jedoch häufig in zwei Kategorien einteilen: regelbasierte Systeme, die viel Zeit und Aufwand für die Einrichtung und Wartung erfordern, oder starre Systeme, denen die Flexibilität fehlt, die für menschenähnliche Interaktionen mit Kunden erforderlich ist. Daher stehen Unternehmen und Organisationen vor der Herausforderung, solche Lösungen schnell und effizient umzusetzen. Glücklicherweise mit dem Aufkommen von generative KI und Große Sprachmodelle (LLMs)ist es jetzt möglich, automatisierte Systeme zu erstellen, die natürliche Sprache effizient und mit einem beschleunigten Zeitrahmen verarbeiten können.

Amazonas Grundgestein ist ein vollständig verwalteter Dienst, der über eine einzige API eine Auswahl leistungsstarker Basismodelle (FMs) von führenden KI-Unternehmen wie AI21 Labs, Anthropic, Cohere, Meta, Stability AI und Amazon sowie ein breites Spektrum an Funktionen bietet müssen generative KI-Anwendungen mit Sicherheit, Datenschutz und verantwortungsvoller KI entwickeln. Neben Amazon Bedrock können Sie auch andere AWS-Dienste wie nutzen Amazon SageMaker-JumpStart und Amazon Lex um vollautomatische und leicht anpassbare generative KI-Auftragsverarbeitungsagenten zu erstellen.

In diesem Beitrag zeigen wir Ihnen, wie Sie mit Amazon Lex, Amazon Bedrock und einen sprachfähigen Auftragsverarbeitungsagenten erstellen AWS Lambda.

Lösungsüberblick

Das folgende Diagramm zeigt unsere Lösungsarchitektur.

Der Arbeitsablauf besteht aus den folgenden Schritten:

  1. Ein Kunde gibt die Bestellung über Amazon Lex auf.
  2. Der Amazon Lex-Bot interpretiert die Absichten des Kunden und löst eine aus DialogCodeHook.
  3. Eine Lambda-Funktion ruft die entsprechende Eingabeaufforderungsvorlage aus der Lambda-Ebene ab und formatiert Modelleingabeaufforderungen, indem sie die Kundeneingabe in die zugehörige Eingabeaufforderungsvorlage einfügt.
  4. Das RequestValidation prompt verifiziert die Bestellung mit dem Menüpunkt und teilt dem Kunden über Amazon Lex mit, ob er etwas bestellen möchte, das nicht Teil des Menüs ist, und gibt Empfehlungen. Die Eingabeaufforderung führt auch eine vorläufige Validierung der Vollständigkeit der Bestellung durch.
  5. Das ObjectCreator prompt wandelt die Anfragen in natürlicher Sprache in eine Datenstruktur (JSON-Format) um.
  6. Die Lambda-Funktion des Kundenvalidators überprüft die erforderlichen Attribute für die Bestellung und bestätigt, ob alle erforderlichen Informationen zur Bearbeitung der Bestellung vorhanden sind.
  7. Eine Kunden-Lambda-Funktion verwendet die Datenstruktur als Eingabe für die Verarbeitung der Bestellung und übergibt die Bestellsumme an die orchestrierende Lambda-Funktion zurück.
  8. Die orchestrierende Lambda-Funktion ruft den Amazon Bedrock LLM-Endpunkt auf, um eine endgültige Bestellzusammenfassung einschließlich der Bestellsumme aus dem Kundendatenbanksystem zu generieren (z. B. Amazon DynamoDB).
  9. Die Bestellzusammenfassung wird über Amazon Lex an den Kunden zurückgesendet. Nachdem der Kunde die Bestellung bestätigt hat, wird die Bestellung bearbeitet.

Voraussetzungen:

In diesem Beitrag wird davon ausgegangen, dass Sie über ein aktives AWS-Konto verfügen und mit den folgenden Konzepten und Diensten vertraut sind:

Um über die Lambda-Funktionen auf Amazon Bedrock zugreifen zu können, müssen Sie außerdem sicherstellen, dass die Lambda-Laufzeit über die folgenden Bibliotheken verfügt:

  • boto3>=1.28.57
  • awscli>=1.29.57
  • Botocore>=1.31.57

Dies kann mit a erfolgen Lambda-Schicht oder durch Verwendung eines bestimmten AMI mit den erforderlichen Bibliotheken.

Darüber hinaus sind diese Bibliotheken erforderlich, wenn Sie die Amazon Bedrock-API aufrufen Amazon SageMaker-Studio. Dies kann durch Ausführen einer Zelle mit dem folgenden Code erfolgen:

%pip install --no-build-isolation --force-reinstall 
"boto3>=1.28.57" 
"awscli>=1.29.57" 
"botocore>=1.31.57"

Abschließend erstellen Sie die folgende Richtlinie und fügen sie später jeder Rolle hinzu, die auf Amazon Bedrock zugreift:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Action": "bedrock:*",
            "Resource": "*"
        }
    ]
}

Erstellen Sie eine DynamoDB-Tabelle

In unserem speziellen Szenario haben wir eine DynamoDB-Tabelle als unser Kundendatenbanksystem erstellt, Sie können diese aber auch verwenden Relationaler Amazon-Datenbankdienst (Amazon RDS). Führen Sie die folgenden Schritte aus, um Ihre DynamoDB-Tabelle bereitzustellen (oder passen Sie die Einstellungen nach Bedarf für Ihren Anwendungsfall an):

  1. Wählen Sie in der DynamoDB-Konsole Tische im Navigationsbereich.
  2. Auswählen Tabelle erstellen.

  1. Aussichten für TabellennameGeben Sie einen Namen ein (z. B. ItemDetails).
  2. Aussichten für Partitionsschlüssel, geben Sie einen Schlüssel ein (für diesen Beitrag verwenden wir Item).
  3. Aussichten für Schlüssel sortieren, geben Sie einen Schlüssel ein (für diesen Beitrag verwenden wir Size).
  4. Auswählen Tabelle erstellen.

Jetzt können Sie die Daten in die DynamoDB-Tabelle laden. Für diesen Beitrag verwenden wir eine CSV-Datei. Sie können die Daten mit Python-Code in einem SageMaker-Notebook in die DynamoDB-Tabelle laden.

Zuerst müssen wir ein Profil namens dev einrichten.

  1. Öffnen Sie ein neues Terminal in SageMaker Studio und führen Sie den folgenden Befehl aus:
aws configure --profile dev

Mit diesem Befehl werden Sie aufgefordert, Ihre AWS-Zugriffsschlüssel-ID, Ihren geheimen Zugriffsschlüssel, die Standard-AWS-Region und das Ausgabeformat einzugeben.

  1. Kehren Sie zum SageMaker-Notizbuch zurück und schreiben Sie einen Python-Code, um mithilfe der Boto3-Bibliothek in Python eine Verbindung zu DynamoDB einzurichten. Dieses Code-Snippet erstellt eine Sitzung mit einem bestimmten AWS-Profil namens dev und erstellt dann einen DynamoDB-Client unter Verwendung dieser Sitzung. Das Folgende ist das Codebeispiel zum Laden der Daten:
%pip install boto3
import boto3
import csv

# Create a session using a profile named 'dev'
session = boto3.Session(profile_name='dev')

# Create a DynamoDB resource using the session
dynamodb = session.resource('dynamodb')

# Specify your DynamoDB table name
table_name = 'your_table_name'
table = dynamodb.Table(table_name)

# Specify the path to your CSV file
csv_file_path = 'path/to/your/file.csv'

# Read CSV file and put items into DynamoDB
with open(csv_file_path, 'r', encoding='utf-8-sig') as csvfile:
    csvreader = csv.reader(csvfile)
    
    # Skip the header row
    next(csvreader, None)

    for row in csvreader:
        # Extract values from the CSV row
        item = {
            'Item': row[0],  # Adjust the index based on your CSV structure
            'Size': row[1],
            'Price': row[2]
        }
        
        # Put item into DynamoDB
        response = table.put_item(Item=item)
        
        print(f"Item added: {response}")
print(f"CSV data has been loaded into the DynamoDB table: {table_name}")

Alternativ können Sie auch verwenden NoSQL-Workbench oder andere Tools, um die Daten schnell in Ihre DynamoDB-Tabelle zu laden.

Das Folgende ist ein Screenshot, nachdem die Beispieldaten in die Tabelle eingefügt wurden.

Erstellen Sie Vorlagen in einem SageMaker-Notizbuch mithilfe der Amazon Bedrock-Aufruf-API

Um unsere Eingabeaufforderungsvorlage für diesen Anwendungsfall zu erstellen, verwenden wir Amazon Bedrock. Sie können auf Amazon Bedrock zugreifen AWS-Managementkonsole und über API-Aufrufe. In unserem Fall greifen wir bequem über ein SageMaker Studio-Notizbuch über eine API auf Amazon Bedrock zu, um nicht nur unsere Eingabeaufforderungsvorlage, sondern auch unseren vollständigen API-Aufrufcode zu erstellen, den wir später für unsere Lambda-Funktion verwenden können.

  1. Greifen Sie in der SageMaker-Konsole auf eine vorhandene SageMaker Studio-Domäne zu oder erstellen Sie eine neue, um von einem SageMaker-Notizbuch aus auf Amazon Bedrock zuzugreifen.

  1. Nachdem Sie die SageMaker-Domäne und den Benutzer erstellt haben, wählen Sie den Benutzer aus und klicken Sie auf Einführung und Studio. Dadurch wird eine JupyterLab-Umgebung geöffnet.
  2. Wenn die JupyterLab-Umgebung bereit ist, öffnen Sie ein neues Notebook und beginnen Sie mit dem Import der erforderlichen Bibliotheken.

Über das Amazon Bedrock Python SDK sind viele FMs verfügbar. In diesem Fall verwenden wir Claude V2, ein leistungsstarkes Basismodell, das von Anthropic entwickelt wurde.

Der Auftragsabwickler benötigt einige unterschiedliche Vorlagen. Dies kann sich je nach Anwendungsfall ändern, wir haben jedoch einen allgemeinen Workflow entworfen, der für mehrere Einstellungen gelten kann. Für diesen Anwendungsfall wird die Amazon Bedrock LLM-Vorlage Folgendes erreichen:

  • Validieren Sie die Absicht des Kunden
  • Bestätigen Sie die Anfrage
  • Erstellen Sie die Auftragsdatenstruktur
  • Geben Sie eine Zusammenfassung der Bestellung an den Kunden weiter
  1. Um das Modell aufzurufen, erstellen Sie ein Bedrock-Runtime-Objekt aus Boto3.

#Model api request parameters
modelId = 'anthropic.claude-v2' # change this to use a different version from the model provider
accept = 'application/json'
contentType = 'application/json'

import boto3
import json
bedrock = boto3.client(service_name='bedrock-runtime')

Beginnen wir mit der Arbeit an der Eingabeaufforderungsvorlage für den Intent-Validator. Dies ist ein iterativer Prozess, aber dank des Prompt-Engineering-Leitfadens von Anthropic können Sie schnell einen Prompt erstellen, der die Aufgabe erfüllen kann.

  1. Erstellen Sie die erste Eingabeaufforderungsvorlage zusammen mit einer Hilfsfunktion, die dabei hilft, den Textkörper für die API-Aufrufe vorzubereiten.

Das Folgende ist der Code für prompt_template_intent_validator.txt:

"{"prompt": "Human: I will give you some instructions to complete my request.n<instructions>Given the Conversation between Human and Assistant, you need to identify the intent that the human wants to accomplish and respond appropriately. The valid intents are: Greeting,Place Order, Complain, Speak to Someone. Always put your response to the Human within the Response tags. Also add an XML tag to your output identifying the human intent.nHere are some examples:n<example><Conversation> H: hi there.nnA: Hi, how can I help you today?nnH: Yes. I would like a medium mocha please</Conversation>nnA:<intent>Place Order</intent><Response>nGot it.</Response></example>n<example><Conversation> H: hellonnA: Hi, how can I help you today?nnH: my coffee does not taste well can you please re-make it?</Conversation>nnA:<intent>Complain</intent><Response>nOh, I am sorry to hear that. Let me get someone to help you.</Response></example>n<example><Conversation> H: hinnA: Hi, how can I help you today?nnH: I would like to speak to someone else please</Conversation>nnA:<intent>Speak to Someone</intent><Response>nSure, let me get someone to help you.</Response></example>n<example><Conversation> H: howdynnA: Hi, how can I help you today?nnH:can I get a large americano with sugar and 2 mochas with no whipped cream</Conversation>nnA:<intent>Place Order</intent><Response>nSure thing! Please give me a moment.</Response></example>n<example><Conversation> H: hinn</Conversation>nnA:<intent>Greeting</intent><Response>nHi there, how can I help you today?</Response></example>n</instructions>nnPlease complete this request according to the instructions and examples provided above:<request><Conversation>REPLACEME</Conversation></request>nnAssistant:n", "max_tokens_to_sample": 250, "temperature": 1, "top_k": 250, "top_p": 0.75, "stop_sequences": ["nnHuman:", "nnhuman:", "nnCustomer:", "nncustomer:"]}"


  1. Speichern Sie diese Vorlage in einer Datei, um sie auf Amazon S3 hochzuladen und bei Bedarf über die Lambda-Funktion aufzurufen. Speichern Sie die Vorlagen als JSON-serialisierte Zeichenfolgen in einer Textdatei. Der vorherige Screenshot zeigt das Codebeispiel, um dies ebenfalls zu erreichen.
  2. Wiederholen Sie die gleichen Schritte mit den anderen Vorlagen.

Im Folgenden finden Sie einige Screenshots der anderen Vorlagen und die Ergebnisse beim Aufruf von Amazon Bedrock mit einigen davon.

Das Folgende ist der Code für prompt_template_request_validator.txt:

"{"prompt": "Human: I will give you some instructions to complete my request.n<instructions>Given the context do the following steps: 1. verify that the items in the input are valid. If customer provided an invalid item, recommend replacing it with a valid one. 2. verify that the customer has provided all the information marked as required. If the customer missed a required information, ask the customer for that information. 3. When the order is complete, provide a summary of the order and ask for confirmation always using this phrase: 'is this correct?' 4. If the customer confirms the order, Do not ask for confirmation again, just say the phrase inside the brackets [Great, Give me a moment while I try to process your order]</instructions>n<context>nThe VALID MENU ITEMS are: [latte, frappe, mocha, espresso, cappuccino, romano, americano].nThe VALID OPTIONS are: [splenda, stevia, raw sugar, honey, whipped cream, sugar, oat milk, soy milk, regular milk, skimmed milk, whole milk, 2 percent milk, almond milk].nThe required information is: size. Size can be: small, medium, large.nHere are some examples: <example>H: I would like a medium latte with 1 Splenda and a small romano with no sugar please.nnA: <Validation>:nThe Human is ordering a medium latte with one splenda. Latte is a valid menu item and splenda is a valid option. The Human is also ordering a small romano with no sugar. Romano is a valid menu item.</Validation>n<Response>nOk, I got: nt-Medium Latte with 1 Splenda and.nt-Small Romano with no Sugar.nIs this correct?</Response>nnH: yep.nnA:n<Response>nGreat, Give me a moment while I try to process your order</example>nn<example>H: I would like a cappuccino and a mocha please.nnA: <Validation>:nThe Human is ordering a cappuccino and a mocha. Both are valid menu items. The Human did not provide the size for the cappuccino. The human did not provide the size for the mocha. I will ask the Human for the required missing information.</Validation>n<Response>nSure thing, but can you please let me know the size for the Cappuccino and the size for the Mocha? We have Small, Medium, or Large.</Response></example>nn<example>H: I would like a small cappuccino and a large lemonade please.nnA: <Validation>:nThe Human is ordering a small cappuccino and a large lemonade. Cappuccino is a valid menu item. Lemonade is not a valid menu item. I will suggest the Human a replacement from our valid menu items.</Validation>n<Response>nSorry, we don't have Lemonades, would you like to order something else instead? Perhaps a Frappe or a Latte?</Response></example>nn<example>H: Can I get a medium frappuccino with sugar please?nnA: <Validation>:n The Human is ordering a Frappuccino. Frappuccino is not a valid menu item. I will suggest a replacement from the valid menu items in my context.</Validation>n<Response>nI am so sorry, but Frappuccino is not in our menu, do you want a frappe or a cappuccino instead? perhaps something else?</Response></example>nn<example>H: I want two large americanos and a small latte please.nnA: <Validation>:n The Human is ordering 2 Large Americanos, and a Small Latte. Americano is a valid menu item. Latte is a valid menu item.</Validation>n<Response>nOk, I got: nt-2 Large Americanos and.nt-Small Latte.nIs this correct?</Response>nnH: looks correct, yes.nnA:n<Response>nGreat, Give me a moment while I try to process your order.</Response></example>nn</Context>nnPlease complete this request according to the instructions and examples provided above:<request>REPLACEME</request>nnAssistant:n", "max_tokens_to_sample": 250, "temperature": 0.3, "top_k": 250, "top_p": 0.75, "stop_sequences": ["nnHuman:", "nnhuman:", "nnCustomer:", "nncustomer:"]}"

Das Folgende ist unsere Antwort von Amazon Bedrock unter Verwendung dieser Vorlage.

Das Folgende ist der Code für prompt_template_object_creator.txt:

"{"prompt": "Human: I will give you some instructions to complete my request.n<instructions>Given the Conversation between Human and Assistant, you need to create a json object in Response with the appropriate attributes.nHere are some examples:n<example><Conversation> H: I want a latte.nnA:nCan I have the size?nnH: Medium.nnA: So, a medium latte.nIs this Correct?nnH: Yes.</Conversation>nnA:<Response>{"1":{"item":"latte","size":"medium","addOns":[]}}</Response></example>n<example><Conversation> H: I want a large frappe and 2 small americanos with sugar.nnA: Okay, let me confirm:nn1 large frappenn2 small americanos with sugarnnIs this correct?nnH: Yes.</Conversation>nnA:<Response>{"1":{"item":"frappe","size":"large","addOns":[]},"2":{"item":"americano","size":"small","addOns":["sugar"]},"3":{"item":"americano","size":"small","addOns":["sugar"]}}</Response>n</example>n<example><Conversation> H: I want a medium americano.nnA: Okay, let me confirm:nn1 medium americanonnIs this correct?nnH: Yes.</Conversation>nnA:<Response>{"1":{"item":"americano","size":"medium","addOns":[]}}</Response></example>n<example><Conversation> H: I want a large latte with oatmilk.nnA: Okay, let me confirm:nnLarge latte with oatmilknnIs this correct?nnH: Yes.</Conversation>nnA:<Response>{"1":{"item":"latte","size":"large","addOns":["oatmilk"]}}</Response></example>n<example><Conversation> H: I want a small mocha with no whipped cream please.nnA: Okay, let me confirm:nnSmall mocha with no whipped creamnnIs this correct?nnH: Yes.</Conversation>nnA:<Response>{"1":{"item":"mocha","size":"small","addOns":["no whipped cream"]}}</Response>nn</example></instructions>nnPlease complete this request according to the instructions and examples provided above:<request><Conversation>REPLACEME</Conversation></request>nnAssistant:n", "max_tokens_to_sample": 250, "temperature": 0.3, "top_k": 250, "top_p": 0.75, "stop_sequences": ["nnHuman:", "nnhuman:", "nnCustomer:", "nncustomer:"]}"


Das Folgende ist der Code für prompt_template_order_summary.txt:

"{"prompt": "Human: I will give you some instructions to complete my request.n<instructions>Given the Conversation between Human and Assistant, you need to create a summary of the order with bullet points and include the order total.nHere are some examples:n<example><Conversation> H: I want a large frappe and 2 small americanos with sugar.nnA: Okay, let me confirm:nn1 large frappenn2 small americanos with sugarnnIs this correct?nnH: Yes.</Conversation>nn<OrderTotal>10.50</OrderTotal>nnA:<Response>nHere is a summary of your order along with the total:nn1 large frappenn2 small americanos with sugar.nYour Order total is $10.50</Response></example>n<example><Conversation> H: I want a medium americano.nnA: Okay, let me confirm:nn1 medium americanonnIs this correct?nnH: Yes.</Conversation>nn<OrderTotal>3.50</OrderTotal>nnA:<Response>nHere is a summary of your order along with the total:nn1 medium americano.nYour Order total is $3.50</Response></example>n<example><Conversation> H: I want a large latte with oat milk.nnA: Okay, let me confirm:nnLarge latte with oat milknnIs this correct?nnH: Yes.</Conversation>nn<OrderTotal>6.75</OrderTotal>nnA:<Response>nHere is a summary of your order along with the total:nnLarge latte with oat milk.nYour Order total is $6.75</Response></example>n<example><Conversation> H: I want a small mocha with no whipped cream please.nnA: Okay, let me confirm:nnSmall mocha with no whipped creamnnIs this correct?nnH: Yes.</Conversation>nn<OrderTotal>4.25</OrderTotal>nnA:<Response>nHere is a summary of your order along with the total:nnSmall mocha with no whipped cream.nYour Order total is $6.75</Response>nn</example>n</instructions>nnPlease complete this request according to the instructions and examples provided above:<request><Conversation>REPLACEME</Conversation>nn<OrderTotal>REPLACETOTAL</OrderTotal></request>nnAssistant:n", "max_tokens_to_sample": 250, "temperature": 0.3, "top_k": 250, "top_p": 0.75, "stop_sequences": ["nnHuman:", "nnhuman:", "nnCustomer:", "nncustomer:", "[Conversation]"]}"


Wie Sie sehen, haben wir unsere Eingabeaufforderungsvorlagen verwendet, um Menüelemente zu validieren, fehlende erforderliche Informationen zu identifizieren, eine Datenstruktur zu erstellen und die Bestellung zusammenzufassen. Die auf Amazon Bedrock verfügbaren Basismodelle sind sehr leistungsstark, sodass Sie mit diesen Vorlagen noch mehr Aufgaben erledigen können.

Sie haben die Erstellung der Eingabeaufforderungen abgeschlossen und die Vorlagen in Textdateien gespeichert. Sie können jetzt mit der Erstellung des Amazon Lex-Bots und der zugehörigen Lambda-Funktionen beginnen.

Erstellen Sie eine Lambda-Ebene mit den Eingabeaufforderungsvorlagen

Führen Sie die folgenden Schritte aus, um Ihre Lambda-Ebene zu erstellen:

  1. Erstellen Sie in SageMaker Studio einen neuen Ordner mit einem Unterordner namens python.
  2. Kopieren Sie Ihre Eingabeaufforderungsdateien in die python -Ordner.

  1. Sie können die ZIP-Bibliothek zu Ihrer Notebook-Instanz hinzufügen, indem Sie den folgenden Befehl ausführen.
!conda install -y -c conda-forge zip

  1. Führen Sie nun den folgenden Befehl aus, um die ZIP-Datei zum Hochladen auf die Lambda-Ebene zu erstellen.
!zip -r prompt_templates_layer.zip prompt_templates_layer/.

  1. Nachdem Sie die ZIP-Datei erstellt haben, können Sie die Datei herunterladen. Gehen Sie zu Lambda und erstellen Sie eine neue Ebene, indem Sie die Datei direkt hochladen oder zuerst auf Amazon S3 hochladen.
  2. Fügen Sie dann diese neue Ebene der Orchestrierungs-Lambda-Funktion hinzu.

Jetzt werden Ihre Eingabeaufforderungsvorlagendateien lokal in Ihrer Lambda-Laufzeitumgebung gespeichert. Dies beschleunigt den Prozess während Ihrer Bot-Läufe.

Erstellen Sie eine Lambda-Ebene mit den erforderlichen Bibliotheken

Führen Sie die folgenden Schritte aus, um Ihre Lambda-Ebene mit den erforderlichen Bibliotheken zu erstellen:

  1. Öffnen Sie eine AWS Cloud9 Erstellen Sie in der Instanzumgebung einen Ordner mit einem Unterordner namens python.
  2. Öffnen Sie ein Terminal im Inneren python -Ordner.
  3. Führen Sie die folgenden Befehle vom Terminal aus:
pip install “boto3>=1.28.57” -t .
pip install “awscli>=1.29.57" -t .
pip install “botocore>=1.31.57” -t .

  1. Führen Sie cd .. und positionieren Sie sich in Ihrem neuen Ordner, wo Sie auch die haben python Unterordner.
  2. Führen Sie den folgenden Befehl aus:
zip -r lambda-layer.zip

  1. Nachdem Sie die ZIP-Datei erstellt haben, können Sie die Datei herunterladen. Gehen Sie zu Lambda und erstellen Sie eine neue Ebene, indem Sie die Datei direkt hochladen oder zuerst auf Amazon S3 hochladen.
  2. Fügen Sie dann diese neue Ebene der Orchestrierungs-Lambda-Funktion hinzu.

Erstellen Sie den Bot in Amazon Lex v2

Für diesen Anwendungsfall erstellen wir einen Amazon Lex-Bot, der eine Eingabe-/Ausgabeschnittstelle für die Architektur bereitstellen kann, um Amazon Bedrock per Sprache oder Text von jeder Schnittstelle aus aufzurufen. Da das LLM den Gesprächsstoff dieses Auftragsverarbeitungsagenten übernimmt und Lambda den Arbeitsablauf orchestriert, können Sie einen Bot mit drei Absichten und ohne Slots erstellen.

  1. Erstellen Sie auf der Amazon Lex-Konsole einen neuen Bot mit der Methode Erstellen Sie einen leeren Bot.

Jetzt können Sie eine Absicht mit einer geeigneten ersten Äußerung hinzufügen, damit die Endbenutzer die Konversation mit dem Bot beginnen können. Wir verwenden einfache Begrüßungen und fügen eine erste Bot-Antwort hinzu, damit Endbenutzer ihre Anfragen stellen können. Stellen Sie beim Erstellen des Bots sicher, dass Sie einen Lambda-Code-Hook mit den Absichten verwenden. Dadurch wird eine Lambda-Funktion ausgelöst, die den Workflow zwischen dem Kunden, Amazon Lex und dem LLM orchestriert.

  1. Fügen Sie Ihre erste Absicht hinzu, die den Workflow auslöst und die Vorlage für die Absichtsvalidierungsaufforderung verwendet, um Amazon Bedrock aufzurufen und zu ermitteln, was der Kunde erreichen möchte. Fügen Sie ein paar einfache Äußerungen hinzu, damit Endbenutzer ein Gespräch beginnen können.

Sie müssen in keinem der Bot-Intents Slots oder Erstlesungen verwenden. Tatsächlich müssen Sie dem zweiten oder dritten Intent keine Äußerungen hinzufügen. Das liegt daran, dass das LLM Lambda durch den gesamten Prozess führt.

  1. Fügen Sie eine Bestätigungsaufforderung hinzu. Sie können diese Nachricht später in der Lambda-Funktion anpassen.

  1. Der Code-HakenWählen Verwenden Sie eine Lambda-Funktion zur Initialisierung und Validierung.

  1. Erstellen Sie eine zweite Absicht ohne Äußerung und ohne erste Antwort. Dies ist das PlaceOrder Absicht.

Wenn das LLM erkennt, dass der Kunde versucht, eine Bestellung aufzugeben, löst die Lambda-Funktion diese Absicht aus, validiert die Kundenanfrage anhand des Menüs und stellt sicher, dass keine erforderlichen Informationen fehlen. Denken Sie daran, dass dies alles in den Eingabeaufforderungsvorlagen enthalten ist. Sie können diesen Workflow also an jeden Anwendungsfall anpassen, indem Sie die Eingabeaufforderungsvorlagen ändern.

  1. Fügen Sie keine Slots hinzu, sondern eine Bestätigungsaufforderung und eine Ablehnungsantwort.

  1. Auswählen Verwenden Sie eine Lambda-Funktion zur Initialisierung und Validierung.

  1. Erstellen Sie eine dritte Absicht mit dem Namen ProcessOrder ohne Beispieläußerungen und ohne Slots.
  2. Fügen Sie eine erste Antwort, eine Bestätigungsaufforderung und eine Ablehnungsantwort hinzu.

Nachdem das LLM die Kundenanfrage validiert hat, löst die Lambda-Funktion den dritten und letzten Intent zur Bearbeitung der Bestellung aus. Hier verwendet Lambda die Objekterstellungsvorlage, um die JSON-Datenstruktur der Bestellung zu generieren, um die DynamoDB-Tabelle abzufragen, und verwendet dann die Bestellzusammenfassungsvorlage, um die gesamte Bestellung zusammen mit der Gesamtsumme zusammenzufassen, damit Amazon Lex sie an den Kunden weitergeben kann.

  1. Auswählen Verwenden Sie eine Lambda-Funktion zur Initialisierung und Validierung. Dieser kann jede Lambda-Funktion nutzen, um die Bestellung abzuwickeln, nachdem der Kunde die endgültige Bestätigung gegeben hat.

  1. Nachdem Sie alle drei Absichten erstellt haben, gehen Sie zum Visual Builder für die ValidateIntent, fügen Sie einen Go-to-Intent-Schritt hinzu und verbinden Sie die Ausgabe der positiven Bestätigung mit diesem Schritt.
  2. Nachdem Sie die Absicht „Go-to“ hinzugefügt haben, bearbeiten Sie sie und wählen Sie die Absicht „PlaceOrder“ als Absichtsnamen aus.

  1. Ebenso gehen Sie zum Visual Builder für PlaceOrder Absicht und verbinden Sie die Ausgabe der positiven Bestätigung mit der ProcessOrder Go-to-Absicht. Es ist keine Bearbeitung erforderlich ProcessOrder Absicht.
  2. Sie müssen nun die Lambda-Funktion erstellen, die Amazon Lex orchestriert und die DynamoDB-Tabelle aufruft, wie im folgenden Abschnitt beschrieben.

Erstellen Sie eine Lambda-Funktion, um den Amazon Lex-Bot zu orchestrieren

Sie können jetzt die Lambda-Funktion erstellen, die den Amazon Lex-Bot und -Workflow orchestriert. Führen Sie die folgenden Schritte aus:

  1. Erstellen Sie eine Lambda-Funktion mit der Standardausführungsrichtlinie und lassen Sie Lambda eine Rolle für Sie erstellen.
  2. Fügen Sie im Codefenster Ihrer Funktion einige hilfreiche Hilfsfunktionen hinzu: Formatieren Sie die Eingabeaufforderungen, indem Sie den Lex-Kontext zur Vorlage hinzufügen, rufen Sie die Amazon Bedrock LLM-API auf, extrahieren Sie den gewünschten Text aus den Antworten und mehr. Siehe den folgenden Code:
import json
import re
import boto3
import logging

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

bedrock = boto3.client(service_name='bedrock-runtime')
def CreatingCustomPromptFromLambdaLayer(object_key,replace_items):
   
    folder_path = '/opt/order_processing_agent_prompt_templates/python/'
    try:
        file_path = folder_path + object_key
        with open(file_path, "r") as file1:
            raw_template = file1.read()
            # Modify the template with the custom input prompt
            #template['inputs'][0].insert(1, {"role": "user", "content": '### Input:n' + user_request})
            for key,value in replace_items.items():
                value = json.dumps(json.dumps(value).replace('"','')).replace('"','')
                raw_template = raw_template.replace(key,value)
            modified_prompt = raw_template

            return modified_prompt
    except Exception as e:
        return {
            'statusCode': 500,
            'body': f'An error occurred: {str(e)}'
        }
def CreatingCustomPrompt(object_key,replace_items):
    logger.debug('replace_items is: {}'.format(replace_items))
    #retrieve user request from intent_request
    #we first propmt the model with current order
    
    bucket_name = 'your-bucket-name'
    
    #object_key = 'prompt_template_order_processing.txt'
    try:
        s3 = boto3.client('s3')
        # Retrieve the existing template from S3
        response = s3.get_object(Bucket=bucket_name, Key=object_key)
        raw_template = response['Body'].read().decode('utf-8')
        raw_template = json.loads(raw_template)
        logger.debug('raw template is {}'.format(raw_template))
        #template_json = json.loads(raw_template)
        #logger.debug('template_json is {}'.format(template_json))
        #template = json.dumps(template_json)
        #logger.debug('template is {}'.format(template))

        # Modify the template with the custom input prompt
        #template['inputs'][0].insert(1, {"role": "user", "content": '### Input:n' + user_request})
        for key,value in replace_items.items():
            raw_template = raw_template.replace(key,value)
            logger.debug("Replacing: {} nwith: {}".format(key,value))
        modified_prompt = json.dumps(raw_template)
        logger.debug("Modified template: {}".format(modified_prompt))
        logger.debug("Modified template type is: {}".format(print(type(modified_prompt))))
        
        #modified_template_json = json.loads(modified_prompt)
        #logger.debug("Modified template json: {}".format(modified_template_json))
        
        return modified_prompt
    except Exception as e:
        return {
            'statusCode': 500,
            'body': f'An error occurred: {str(e)}'
        }
    
def validate_intent(intent_request):
    logger.debug('starting validate_intent: {}'.format(intent_request))
    #retrieve user request from intent_request
    user_request = 'Human: ' + intent_request['inputTranscript'].lower()
    #getting current context variable
    current_session_attributes =  intent_request['sessionState']['sessionAttributes']
    if len(current_session_attributes) > 0:
        full_context = current_session_attributes['fullContext'] + 'nn' + user_request
        dialog_context = current_session_attributes['dialogContext'] + 'nn' + user_request
    else:
        full_context = user_request
        dialog_context = user_request
    #Preparing validation prompt by adding context to prompt template
    object_key = 'prompt_template_intent_validator.txt'
    #replace_items = {"REPLACEME":full_context}
    #replace_items = {"REPLACEME":dialog_context}
    replace_items = {"REPLACEME":dialog_context}
    #validation_prompt = CreatingCustomPrompt(object_key,replace_items)
    validation_prompt = CreatingCustomPromptFromLambdaLayer(object_key,replace_items)

    #Prompting model for request validation
    intent_validation_completion = prompt_bedrock(validation_prompt)
    intent_validation_completion = re.sub(r'["]','',intent_validation_completion)

    #extracting response from response completion and removing some special characters
    validation_response = extract_response(intent_validation_completion)
    validation_intent = extract_intent(intent_validation_completion)
    
    

    #business logic depending on intents
    if validation_intent == 'Place Order':
        return validate_request(intent_request)
    elif validation_intent in ['Complain','Speak to Someone']:
        ##adding session attributes to keep current context
        full_context = full_context + 'nn' + intent_validation_completion
        dialog_context = dialog_context + 'nnAssistant: ' + validation_response
        intent_request['sessionState']['sessionAttributes']['fullContext'] = full_context
        intent_request['sessionState']['sessionAttributes']['dialogContext'] = dialog_context
        intent_request['sessionState']['sessionAttributes']['customerIntent'] = validation_intent
        return close(intent_request['sessionState']['sessionAttributes'],intent_request['sessionState']['intent']['name'],'Fulfilled','Close',validation_response)
    if validation_intent == 'Greeting':
        ##adding session attributes to keep current context
        full_context = full_context + 'nn' + intent_validation_completion
        dialog_context = dialog_context + 'nnAssistant: ' + validation_response
        intent_request['sessionState']['sessionAttributes']['fullContext'] = full_context
        intent_request['sessionState']['sessionAttributes']['dialogContext'] = dialog_context
        intent_request['sessionState']['sessionAttributes']['customerIntent'] = validation_intent
        return close(intent_request['sessionState']['sessionAttributes'],intent_request['sessionState']['intent']['name'],'InProgress','ConfirmIntent',validation_response)

def validate_request(intent_request):
    logger.debug('starting validate_request: {}'.format(intent_request))
    #retrieve user request from intent_request
    user_request = 'Human: ' + intent_request['inputTranscript'].lower()
    #getting current context variable
    current_session_attributes =  intent_request['sessionState']['sessionAttributes']
    if len(current_session_attributes) > 0:
        full_context = current_session_attributes['fullContext'] + 'nn' + user_request
        dialog_context = current_session_attributes['dialogContext'] + 'nn' + user_request
    else:
        full_context = user_request
        dialog_context = user_request
   
    #Preparing validation prompt by adding context to prompt template
    object_key = 'prompt_template_request_validator.txt'
    replace_items = {"REPLACEME":dialog_context}
    #validation_prompt = CreatingCustomPrompt(object_key,replace_items)
    validation_prompt = CreatingCustomPromptFromLambdaLayer(object_key,replace_items)

    #Prompting model for request validation
    request_validation_completion = prompt_bedrock(validation_prompt)
    request_validation_completion = re.sub(r'["]','',request_validation_completion)

    #extracting response from response completion and removing some special characters
    validation_response = extract_response(request_validation_completion)

    ##adding session attributes to keep current context
    full_context = full_context + 'nn' + request_validation_completion
    dialog_context = dialog_context + 'nnAssistant: ' + validation_response
    intent_request['sessionState']['sessionAttributes']['fullContext'] = full_context
    intent_request['sessionState']['sessionAttributes']['dialogContext'] = dialog_context
    
    return close(intent_request['sessionState']['sessionAttributes'],'PlaceOrder','InProgress','ConfirmIntent',validation_response)
    
def process_order(intent_request):
    logger.debug('starting process_order: {}'.format(intent_request))

     #retrieve user request from intent_request
    user_request = 'Human: ' + intent_request['inputTranscript'].lower()
    #getting current context variable
    current_session_attributes =  intent_request['sessionState']['sessionAttributes']
    if len(current_session_attributes) > 0:
        full_context = current_session_attributes['fullContext'] + 'nn' + user_request
        dialog_context = current_session_attributes['dialogContext'] + 'nn' + user_request
    else:
        full_context = user_request
        dialog_context = user_request
    #   Preparing object creator prompt by adding context to prompt template
    object_key = 'prompt_template_object_creator.txt'
    replace_items = {"REPLACEME":dialog_context}
    #object_creator_prompt = CreatingCustomPrompt(object_key,replace_items)
    object_creator_prompt = CreatingCustomPromptFromLambdaLayer(object_key,replace_items)
    #Prompting model for object creation
    object_creation_completion = prompt_bedrock(object_creator_prompt)
    #extracting response from response completion
    object_creation_response = extract_response(object_creation_completion)
    inputParams = json.loads(object_creation_response)
    inputParams = json.dumps(json.dumps(inputParams))
    logger.debug('inputParams is: {}'.format(inputParams))
    client = boto3.client('lambda')
    response = client.invoke(FunctionName = 'arn:aws:lambda:us-east-1:<AccountNumber>:function:aws-blog-order-validator',InvocationType = 'RequestResponse',Payload = inputParams)
    responseFromChild = json.load(response['Payload'])
    validationResult = responseFromChild['statusCode']
    if validationResult == 205:
        order_validation_error = responseFromChild['validator_response']
        return close(intent_request['sessionState']['sessionAttributes'],'PlaceOrder','InProgress','ConfirmIntent',order_validation_error)
    #invokes Order Processing lambda to query DynamoDB table and returns order total
    response = client.invoke(FunctionName = 'arn:aws:lambda:us-east-1: <AccountNumber>:function:aws-blog-order-processing',InvocationType = 'RequestResponse',Payload = inputParams)
    responseFromChild = json.load(response['Payload'])
    orderTotal = responseFromChild['body']
    ###Prompting the model to summarize the order along with order total
    object_key = 'prompt_template_order_summary.txt'
    replace_items = {"REPLACEME":dialog_context,"REPLACETOTAL":orderTotal}
    #order_summary_prompt = CreatingCustomPrompt(object_key,replace_items)
    order_summary_prompt = CreatingCustomPromptFromLambdaLayer(object_key,replace_items)
    order_summary_completion = prompt_bedrock(order_summary_prompt)
    #extracting response from response completion
    order_summary_response = extract_response(order_summary_completion)  
    order_summary_response = order_summary_response + '. Shall I finalize processing your order?'
    ##adding session attributes to keep current context
    full_context = full_context + 'nn' + order_summary_completion
    dialog_context = dialog_context + 'nnAssistant: ' + order_summary_response
    intent_request['sessionState']['sessionAttributes']['fullContext'] = full_context
    intent_request['sessionState']['sessionAttributes']['dialogContext'] = dialog_context
    return close(intent_request['sessionState']['sessionAttributes'],'ProcessOrder','InProgress','ConfirmIntent',order_summary_response)
    

""" --- Main handler and Workflow functions --- """

def lambda_handler(event, context):
    """
    Route the incoming request based on intent.
    The JSON body of the request is provided in the event slot.
    """
    logger.debug('event is: {}'.format(event))

    return dispatch(event)

def dispatch(intent_request):
    """
    Called when the user specifies an intent for this bot. If intent is not valid then returns error name
    """
    logger.debug('intent_request is: {}'.format(intent_request))
    intent_name = intent_request['sessionState']['intent']['name']
    confirmation_state = intent_request['sessionState']['intent']['confirmationState']
    # Dispatch to your bot's intent handlers
    if intent_name == 'ValidateIntent' and confirmation_state == 'None':
        return validate_intent(intent_request)
    if intent_name == 'PlaceOrder' and confirmation_state == 'None':
        return validate_request(intent_request)
    elif intent_name == 'PlaceOrder' and confirmation_state == 'Confirmed':
        return process_order(intent_request)
    elif intent_name == 'PlaceOrder' and confirmation_state == 'Denied':
        return close(intent_request['sessionState']['sessionAttributes'],intent_request['sessionState']['intent']['name'],'Fulfilled','Close','Got it. Let me know if I can help you with something else.')
    elif intent_name == 'PlaceOrder' and confirmation_state not in ['Denied','Confirmed','None']:
        return close(intent_request['sessionState']['sessionAttributes'],intent_request['sessionState']['intent']['name'],'Fulfilled','Close','Sorry. I am having trouble completing the request. Let me get someone to help you.')
        logger.debug('exiting intent {} here'.format(intent_request['sessionState']['intent']['name']))
    elif intent_name == 'ProcessOrder' and confirmation_state == 'None':
        return validate_request(intent_request)
    elif intent_name == 'ProcessOrder' and confirmation_state == 'Confirmed':
        return close(intent_request['sessionState']['sessionAttributes'],intent_request['sessionState']['intent']['name'],'Fulfilled','Close','Perfect! Your order has been processed. Please proceed to payment.')
    elif intent_name == 'ProcessOrder' and confirmation_state == 'Denied':
        return close(intent_request['sessionState']['sessionAttributes'],intent_request['sessionState']['intent']['name'],'Fulfilled','Close','Got it. Let me know if I can help you with something else.')
    elif intent_name == 'ProcessOrder' and confirmation_state not in ['Denied','Confirmed','None']:
        return close(intent_request['sessionState']['sessionAttributes'],intent_request['sessionState']['intent']['name'],'Fulfilled','Close','Sorry. I am having trouble completing the request. Let me get someone to help you.')
        logger.debug('exiting intent {} here'.format(intent_request['sessionState']['intent']['name']))
    raise Exception('Intent with name ' + intent_name + ' not supported')
    
def prompt_bedrock(formatted_template):
    logger.debug('prompt bedrock input is:'.format(formatted_template))
    body = json.loads(formatted_template)

    modelId = 'anthropic.claude-v2' # change this to use a different version from the model provider
    accept = 'application/json'
    contentType = 'application/json'

    response = bedrock.invoke_model(body=body, modelId=modelId, accept=accept, contentType=contentType)
    response_body = json.loads(response.get('body').read())
    response_completion = response_body.get('completion')
    logger.debug('response is: {}'.format(response_completion))

    #print_ww(response_body.get('completion'))
    #print(response_body.get('results')[0].get('outputText'))
    return response_completion

#function to extract text between the <Response> and </Response> tags within model completion
def extract_response(response_completion):
    
    if '<Response>' in response_completion:
        customer_response = response_completion.replace('<Response>','||').replace('</Response>','').split('||')[1]
        
        logger.debug('modified response is: {}'.format(response_completion))

        return customer_response
    else:
        
        logger.debug('modified response is: {}'.format(response_completion))

        return response_completion
        
#function to extract text between the <Response> and </Response> tags within model completion
def extract_intent(response_completion):
    if '<intent>' in response_completion:
        customer_intent = response_completion.replace('<intent>','||').replace('</intent>','||').split('||')[1]
        return customer_intent
    else:
        return customer_intent
        
def close(session_attributes, intent, fulfillment_state, action_type, message):
    #This function prepares the response in the appropiate format for Lex V2

    response = {
        "sessionState": {
            "sessionAttributes":session_attributes,
            "dialogAction": {
                "type": action_type
            },
            "intent": {
                "name":intent,
                "state":fulfillment_state
                
            },
            
            },
        "messages":
            [{
                "contentType":"PlainText",
                "content":message,
            }]
            ,
        
    }
    return response

  1. Hängen Sie die zuvor erstellte Lambda-Ebene an diese Funktion an.
  2. Hängen Sie die Ebene außerdem an die von Ihnen erstellten Eingabeaufforderungsvorlagen an.
  3. Fügen Sie in der Lambda-Ausführungsrolle die Richtlinie für den Zugriff auf Amazon Bedrock hinzu, die zuvor erstellt wurde.

Die Lambda-Ausführungsrolle sollte über die folgenden Berechtigungen verfügen.

Hängen Sie die Orchestration Lambda-Funktion an den Amazon Lex-Bot an

  1. Nachdem Sie die Funktion im vorherigen Abschnitt erstellt haben, kehren Sie zur Amazon Lex-Konsole zurück und navigieren Sie zu Ihrem Bot.
  2. Der Sprachen Wählen Sie im Navigationsbereich Englisch.
  3. Aussichten für Quelle, wählen Sie Ihren Bestellverarbeitungs-Bot.
  4. Aussichten für Lambda-Funktionsversion oder Alias, wählen $NEUESTE.
  5. Auswählen Speichern.

Erstellen Sie unterstützende Lambda-Funktionen

Führen Sie die folgenden Schritte aus, um zusätzliche Lambda-Funktionen zu erstellen:

  1. Erstellen Sie eine Lambda-Funktion, um die zuvor erstellte DynamoDB-Tabelle abzufragen:
import json
import boto3
import logging

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
# Initialize the DynamoDB client
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('your-table-name')

def calculate_grand_total(input_data):
    # Initialize the total price
    total_price = 0
    
    try:
        # Loop through each item in the input JSON
        for item_id, item_data in input_data.items():
            item_name = item_data['item'].lower()  # Convert item name to lowercase
            item_size = item_data['size'].lower()  # Convert item size to lowercase
            
            # Query the DynamoDB table for the item based on Item and Size
            response = table.get_item(
                Key={'Item': item_name,
                    'Size': item_size}
            )
            
            # Check if the item was found in the table
            if 'Item' in response:
                item = response['Item']
                price = float(item['Price'])
                total_price += price  # Add the item's price to the total
    
        return total_price
    except Exception as e:
        raise Exception('An error occurred: {}'.format(str(e)))

def lambda_handler(event, context):
    try:
       
        # Parse the input JSON from the Lambda event
        input_json = json.loads(event)

        # Calculate the grand total
        grand_total = calculate_grand_total(input_json)
    
        # Return the grand total in the response
        return {'statusCode': 200,'body': json.dumps(grand_total)}
    except Exception as e:
        return {
            'statusCode': 500,
            'body': json.dumps('An error occurred: {}'.format(str(e)))

  1. Navigieren Sie zu der Konfiguration Tab in der Lambda-Funktion und wählen Sie Berechtigungen.
  2. Hängen Sie eine ressourcenbasierte Richtlinienanweisung an, die es der Auftragsverarbeitungs-Lambda-Funktion ermöglicht, diese Funktion aufzurufen.

  1. Navigieren Sie zur IAM-Ausführungsrolle für diese Lambda-Funktion und fügen Sie eine Richtlinie für den Zugriff auf die DynamoDB-Tabelle hinzu.

  1. Erstellen Sie eine weitere Lambda-Funktion, um zu überprüfen, ob alle erforderlichen Attribute vom Kunden übergeben wurden. Im folgenden Beispiel validieren wir, ob das Größenattribut für eine Bestellung erfasst wird:
import json
import logging

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

def lambda_handler(event, context):
    # Define customer orders from the input event
    customer_orders = json.loads(event)

    # Initialize a list to collect error messages
    order_errors = {}
    missing_size = []
    error_messages = []
    # Iterate through each order in customer_orders
    for order_id, order in customer_orders.items():
        if "size" not in order or order["size"] == "":
            missing_size.append(order['item'])
            order_errors['size'] = missing_size
    if order_errors:
        items_missing_size = order_errors['size']
        error_message = f"could you please provide the size for the following items: {', '.join(items_missing_size)}?"
        error_messages.append(error_message)

    # Prepare the response message
    if error_messages:
        response_message = "n".join(error_messages)
        return {
        'statusCode': 205,
        'validator_response': response_message
            }   
    else:
        response_message = "Order is validated successfully"
        return {
        'statusCode': 200,
        'validator_response': response_message
        }

  1. Navigieren Sie zu der Konfiguration Tab in der Lambda-Funktion und wählen Sie Berechtigungen.
  2. Hängen Sie eine ressourcenbasierte Richtlinienanweisung an, die es der Auftragsverarbeitungs-Lambda-Funktion ermöglicht, diese Funktion aufzurufen.

Testen Sie die Lösung

Jetzt können wir die Lösung anhand von Beispielbestellungen testen, die Kunden über Amazon Lex aufgeben.

In unserem ersten Beispiel fragte der Kunde nach einem Frappuccino, der nicht auf der Speisekarte steht. Das Modell validiert mithilfe der Bestellvalidierungsvorlage und schlägt einige Empfehlungen basierend auf dem Menü vor. Nachdem der Kunde seine Bestellung bestätigt hat, wird ihm der Gesamtbetrag und die Bestellübersicht mitgeteilt. Die Bestellung wird auf Grundlage der endgültigen Bestätigung des Kunden bearbeitet.

In unserem nächsten Beispiel bestellt der Kunde einen großen Cappuccino und ändert dann die Größe von groß auf mittel. Das Modell erfasst alle notwendigen Änderungen und fordert den Kunden auf, die Bestellung zu bestätigen. Das Modell stellt die Bestellsumme und die Bestellübersicht dar und verarbeitet die Bestellung auf der Grundlage der endgültigen Bestätigung des Kunden.

In unserem letzten Beispiel hat der Kunde mehrere Artikel bestellt und bei einigen Artikeln fehlt die Größe. Das Modell und die Lambda-Funktion überprüfen, ob alle erforderlichen Attribute zur Bearbeitung der Bestellung vorhanden sind, und fordern dann den Kunden auf, die fehlenden Informationen anzugeben. Nachdem der Kunde die fehlenden Informationen (in diesem Fall die Größe des Kaffees) angegeben hat, werden ihm die Bestellsumme und die Bestellübersicht angezeigt. Die Bestellung wird auf Grundlage der endgültigen Bestätigung des Kunden bearbeitet.

LLM-Einschränkungen

LLM-Ausgaben sind von Natur aus stochastisch, was bedeutet, dass die Ergebnisse unseres LLM im Format oder sogar in der Form unwahrer Inhalte (Halluzinationen) variieren können. Daher müssen sich Entwickler im gesamten Code auf eine gute Fehlerbehandlungslogik verlassen, um diese Szenarien zu bewältigen und eine beeinträchtigte Endbenutzererfahrung zu vermeiden.

Aufräumen

Wenn Sie diese Lösung nicht mehr benötigen, können Sie die folgenden Ressourcen löschen:

  • Lambda-Funktionen
  • Amazon Lex-Box
  • DynamoDB-Tabelle
  • S3-Eimer

Fahren Sie außerdem die SageMaker Studio-Instanz herunter, wenn die Anwendung nicht mehr benötigt wird.

Kostenschätzung

Preisinformationen für die wichtigsten von dieser Lösung verwendeten Dienste finden Sie hier:

Beachten Sie, dass Sie Claude v2 ohne Bereitstellung verwenden können, sodass die Gesamtkosten minimal bleiben. Um die Kosten weiter zu senken, können Sie die DynamoDB-Tabelle mit der On-Demand-Einstellung konfigurieren.

Zusammenfassung

In diesem Beitrag wurde gezeigt, wie man mithilfe von Amazon Lex, Amazon Bedrock und anderen AWS-Diensten einen sprachgesteuerten KI-Agenten für die Auftragsabwicklung erstellt. Wir haben gezeigt, wie Prompt Engineering mit einem leistungsstarken generativen KI-Modell wie Claude ein robustes Verständnis natürlicher Sprache und Konversationsabläufe für die Auftragsabwicklung ermöglichen kann, ohne dass umfangreiche Trainingsdaten erforderlich sind.

Die Lösungsarchitektur nutzt serverlose Komponenten wie Lambda, Amazon S3 und DynamoDB, um eine flexible und skalierbare Implementierung zu ermöglichen. Durch das Speichern der Eingabeaufforderungsvorlagen in Amazon S3 können Sie die Lösung für verschiedene Anwendungsfälle anpassen.

Zu den nächsten Schritten könnte die Erweiterung der Fähigkeiten des Agenten gehören, um ein breiteres Spektrum an Kundenanfragen und Grenzfällen zu bearbeiten. Die Eingabeaufforderungsvorlagen bieten eine Möglichkeit, die Fähigkeiten des Agenten iterativ zu verbessern. Zusätzliche Anpassungen könnten die Integration der Bestelldaten in Backend-Systeme wie Inventar, CRM oder POS umfassen. Schließlich könnte der Agent mithilfe der Multi-Channel-Funktionen von Amazon Lex über verschiedene Kundenkontaktpunkte wie mobile Apps, Drive-Thru, Kioske und mehr verfügbar gemacht werden.

Weitere Informationen finden Sie in den folgenden verwandten Ressourcen:

  • Bereitstellung und Verwaltung von Multi-Channel-Bots:
  • Prompte Technik für Claude und andere Modelle:
  • Serverlose Architekturmuster für skalierbare KI-Assistenten:

Über die Autoren

Moumita Dutta ist Partner Solution Architect bei Amazon Web Services. In ihrer Rolle arbeitet sie eng mit Partnern zusammen, um skalierbare und wiederverwendbare Assets zu entwickeln, die Cloud-Bereitstellungen rationalisieren und die betriebliche Effizienz steigern. Sie ist Mitglied der AI/ML-Community und Expertin für generative KI bei AWS. In ihrer Freizeit arbeitet sie gerne im Garten und fährt Fahrrad.

Fernando Lammoglia ist Partner Solutions Architect bei Amazon Web Services und arbeitet eng mit AWS-Partnern zusammen, um die Entwicklung und Einführung modernster KI-Lösungen in allen Geschäftsbereichen voranzutreiben. Eine strategische Führungspersönlichkeit mit Fachwissen in den Bereichen Cloud-Architektur, generative KI, maschinelles Lernen und Datenanalyse. Er ist auf die Umsetzung von Markteinführungsstrategien und die Bereitstellung wirkungsvoller KI-Lösungen spezialisiert, die auf die Unternehmensziele abgestimmt sind. In seiner Freizeit verbringt er gerne Zeit mit seiner Familie und reist in andere Länder.

Mitul Patel ist Senior Solution Architect bei Amazon Web Services. In seiner Rolle als Cloud-Technologie-Enabler arbeitet er mit Kunden zusammen, um ihre Ziele und Herausforderungen zu verstehen, und bietet präskriptive Anleitungen, um ihre Ziele mit AWS-Angeboten zu erreichen. Er ist Mitglied der AI/ML-Community und Botschafter für generative KI bei AWS. In seiner Freizeit geht er gerne wandern und spielt Fußball.

spot_img

Neueste Intelligenz

spot_img