شعار زيفيرنت

تحويل التفاعلات الفردية مع العملاء: أنشئ وكلاء معالجة أوامر قادرين على الكلام باستخدام AWS والذكاء الاصطناعي التوليدي | خدمات الويب الأمازون

التاريخ:

في مشهد اليوم الذي يتسم بالتفاعلات الفردية مع العملاء لتقديم الطلبات، تستمر الممارسة السائدة في الاعتماد على الحاضرين من البشر، حتى في أماكن مثل المقاهي ومؤسسات الوجبات السريعة. يطرح هذا النهج التقليدي العديد من التحديات: فهو يعتمد بشكل كبير على العمليات اليدوية، ويكافح من أجل التوسع بكفاءة مع طلبات العملاء المتزايدة، ويطرح احتمال حدوث أخطاء بشرية، ويعمل خلال ساعات محددة من التوفر. بالإضافة إلى ذلك، في الأسواق التنافسية، قد تجد الشركات التي تلتزم بالعمليات اليدوية فقط صعوبة في تقديم خدمة فعالة وتنافسية. على الرغم من التقدم التكنولوجي، لا يزال النموذج المتمركز حول الإنسان متأصلًا بعمق في معالجة الطلبات، مما يؤدي إلى هذه القيود.

لقد كان احتمال استخدام التكنولوجيا للمساعدة في معالجة الطلبات الفردية متاحًا لبعض الوقت. ومع ذلك، يمكن أن تنقسم الحلول الحالية في كثير من الأحيان إلى فئتين: الأنظمة القائمة على القواعد والتي تتطلب وقتًا وجهدًا كبيرين للإعداد والصيانة، أو الأنظمة الصارمة التي تفتقر إلى المرونة المطلوبة للتفاعلات الشبيهة بالإنسان مع العملاء. ونتيجة لذلك، تواجه الشركات والمؤسسات تحديات في تنفيذ مثل هذه الحلول بسرعة وكفاءة. ولحسن الحظ، مع ظهور الذكاء الاصطناعي التوليدي و نماذج اللغات الكبيرة (LLMs)، أصبح من الممكن الآن إنشاء أنظمة آلية يمكنها التعامل مع اللغة الطبيعية بكفاءة، وبجدول زمني متسارع.

أمازون بيدروك هي خدمة مُدارة بالكامل توفر مجموعة مختارة من النماذج الأساسية عالية الأداء (FMs) من شركات الذكاء الاصطناعي الرائدة مثل AI21 Labs وAnthropic وCohere وMeta وStability AI وAmazon عبر واجهة برمجة تطبيقات واحدة، إلى جانب مجموعة واسعة من الإمكانات التي يمكنك بحاجة إلى بناء تطبيقات ذكاء اصطناعي منتجة تتمتع بالأمان والخصوصية والذكاء الاصطناعي المسؤول. بالإضافة إلى Amazon Bedrock، يمكنك استخدام خدمات AWS الأخرى مثل أمازون سيج ميكر جومب ستارت و أمازون ليكس لإنشاء وكلاء معالجة أوامر الذكاء الاصطناعي التوليدي مؤتمتين بالكامل وقابلين للتكيف بسهولة.

في هذا المنشور، نوضح لك كيفية إنشاء وكيل معالجة أوامر قادر على الكلام باستخدام Amazon Lex وAmazon Bedrock و AWS لامدا.

حل نظرة عامة

يوضح الرسم البياني التالي بنية الحلول لدينا.

يتكون سير العمل من الخطوات التالية:

  1. يقدم العميل الطلب باستخدام Amazon Lex.
  2. يفسر روبوت Amazon Lex نوايا العميل ويطلق عملية DialogCodeHook.
  3. تقوم وظيفة Lambda بسحب قالب المطالبة المناسب من طبقة Lambda وتقوم بتنسيق مطالبات النموذج عن طريق إضافة مدخلات العميل في قالب المطالبة المرتبط.
  4. RequestValidation تتحقق المطالبة من الطلب باستخدام عنصر القائمة وتسمح للعميل بمعرفة عبر Amazon Lex إذا كان هناك شيء يريد طلبه ليس جزءًا من القائمة وسيقدم توصيات. يقوم الموجه أيضًا بإجراء التحقق الأولي من اكتمال الطلب.
  5. ObjectCreator يقوم المطالبة بتحويل طلبات اللغة الطبيعية إلى بنية بيانات (تنسيق JSON).
  6. تتحقق وظيفة Lambda للتحقق من صحة العميل من السمات المطلوبة للطلب وتؤكد ما إذا كانت جميع المعلومات الضرورية موجودة لمعالجة الطلب.
  7. تأخذ وظيفة Lambda الخاصة بالعميل بنية البيانات كمدخل لمعالجة الطلب وتمرير إجمالي الطلب مرة أخرى إلى وظيفة Lambda المنسقة.
  8. تستدعي وظيفة Lambda المنسقة نقطة نهاية Amazon Bedrock LLM لإنشاء ملخص الطلب النهائي بما في ذلك إجمالي الطلب من نظام قاعدة بيانات العملاء (على سبيل المثال، الأمازون DynamoDB).
  9. يتم إرسال ملخص الطلب مرة أخرى إلى العميل عبر Amazon Lex. بعد تأكيد العميل للطلب، سيتم معالجة الطلب.

المتطلبات الأساسية المسبقة

يفترض هذا المنشور أن لديك حساب AWS نشطًا وأنك على دراية بالمفاهيم والخدمات التالية:

وأيضًا، من أجل الوصول إلى Amazon Bedrock من وظائف Lambda، يتعين عليك التأكد من أن وقت تشغيل Lambda يحتوي على المكتبات التالية:

  • boto3>=1.28.57
  • أوسلي>=1.29.57
  • بوتوكو>=1.31.57

يمكن القيام بذلك باستخدام ملف طبقة لامدا أو باستخدام AMI محدد مع المكتبات المطلوبة.

علاوة على ذلك، تكون هذه المكتبات مطلوبة عند الاتصال بـ Amazon Bedrock API من أمازون ساجميكر ستوديو. يمكن القيام بذلك عن طريق تشغيل خلية بالرمز التالي:

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

أخيرًا، يمكنك إنشاء السياسة التالية وإرفاقها لاحقًا بأي دور يصل إلى Amazon Bedrock:

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

إنشاء جدول DynamoDB

في السيناريو الخاص بنا، قمنا بإنشاء جدول DynamoDB كنظام قاعدة بيانات العملاء لدينا، ولكن يمكنك أيضًا استخدامه خدمة قاعدة بيانات الأمازون (أمازون آر دي إس). أكمل الخطوات التالية لتوفير جدول DynamoDB الخاص بك (أو قم بتخصيص الإعدادات حسب الحاجة لحالة الاستخدام الخاصة بك):

  1. في وحدة تحكم DynamoDB ، اختر طاولات الطعام في جزء التنقل.
  2. اختار إنشاء الجدول.

  1. في حالة اسم الطاولة، أدخل اسمًا (على سبيل المثال ، ItemDetails).
  2. في حالة مفتاح التقسيم، أدخل مفتاحًا (لهذا المنشور، نستخدم Item).
  3. في حالة مفتاح الفرز، أدخل مفتاحًا (لهذا المنشور، نستخدم Size).
  4. اختار إنشاء الجدول.

يمكنك الآن تحميل البيانات في جدول DynamoDB. في هذه المقالة، نستخدم ملف CSV. يمكنك تحميل البيانات إلى جدول DynamoDB باستخدام رمز Python الموجود في دفتر ملاحظات SageMaker.

أولاً، نحتاج إلى إعداد ملف تعريف باسم dev.

  1. افتح محطة جديدة في SageMaker Studio وقم بتشغيل الأمر التالي:
aws configure --profile dev

سيطالبك هذا الأمر بإدخال معرف مفتاح الوصول إلى AWS، ومفتاح الوصول السري، ومنطقة AWS الافتراضية، وتنسيق الإخراج.

  1. ارجع إلى دفتر ملاحظات SageMaker واكتب كود Python لإعداد اتصال بـ DynamoDB باستخدام مكتبة Boto3 في Python. يقوم مقتطف الكود هذا بإنشاء جلسة باستخدام ملف تعريف AWS محدد يسمى dev، ثم يقوم بإنشاء عميل DynamoDB باستخدام تلك الجلسة. وفيما يلي نموذج التعليمات البرمجية لتحميل البيانات:
%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}")

بدلا من ذلك ، يمكنك استخدام منضدة NoSQL أو أدوات أخرى لتحميل البيانات بسرعة إلى جدول DynamoDB الخاص بك.

فيما يلي لقطة شاشة بعد إدراج البيانات النموذجية في الجدول.

قم بإنشاء قوالب في دفتر ملاحظات SageMaker باستخدام واجهة برمجة تطبيقات استدعاء Amazon Bedrock

لإنشاء قالب المطالبة الخاص بنا لحالة الاستخدام هذه، نستخدم Amazon Bedrock. يمكنك الوصول إلى Amazon Bedrock من وحدة تحكم إدارة AWS وعبر دعوات API. في حالتنا، يمكننا الوصول إلى Amazon Bedrock عبر واجهة برمجة التطبيقات (API) من خلال دفتر ملاحظات SageMaker Studio ليس لإنشاء قالب المطالبة الخاص بنا فحسب، بل أيضًا رمز استدعاء واجهة برمجة التطبيقات (API) الكامل الذي يمكننا استخدامه لاحقًا في وظيفة Lambda الخاصة بنا.

  1. على وحدة تحكم SageMaker، يمكنك الوصول إلى مجال SageMaker Studio موجود أو إنشاء نطاق جديد للوصول إلى Amazon Bedrock من دفتر ملاحظات SageMaker.

  1. بعد إنشاء مجال ومستخدم SageMaker، اختر المستخدم ثم اختر إطلاق و استوديو. سيؤدي هذا إلى فتح بيئة JupyterLab.
  2. عندما تصبح بيئة JupyterLab جاهزة، افتح دفتر ملاحظات جديدًا وابدأ في استيراد المكتبات الضرورية.

هناك العديد من FMs المتاحة عبر Amazon Bedrock Python SDK. في هذه الحالة، نستخدم Claude V2، وهو نموذج تأسيسي قوي طورته Anthropic.

يحتاج وكيل معالجة الطلب إلى بعض القوالب المختلفة. يمكن أن يتغير هذا وفقًا لحالة الاستخدام، ولكننا قمنا بتصميم سير عمل عام يمكن تطبيقه على إعدادات متعددة. بالنسبة لحالة الاستخدام هذه، سيحقق قالب Amazon Bedrock LLM ما يلي:

  • التحقق من صحة نية العميل
  • التحقق من صحة الطلب
  • إنشاء بنية بيانات الطلب
  • تمرير ملخص الطلب إلى العميل
  1. لاستدعاء النموذج، قم بإنشاء كائن أساسي لوقت التشغيل من 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')

لنبدأ بالعمل على قالب موجه التحقق من النية. هذه عملية تكرارية، ولكن بفضل الدليل الهندسي السريع الخاص بـ Anthropic، يمكنك إنشاء موجه يمكنه إنجاز المهمة بسرعة.

  1. قم بإنشاء قالب المطالبة الأول مع وظيفة الأداة المساعدة التي ستساعد في إعداد النص لاستدعاءات واجهة برمجة التطبيقات (API).

ما يلي هو الكود الخاص بـ 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. احفظ هذا القالب في ملف لتحميله على Amazon S3 والاتصال من وظيفة Lambda عند الحاجة. احفظ القوالب كسلاسل متسلسلة JSON في ملف نصي. تعرض لقطة الشاشة السابقة نموذج التعليمات البرمجية لإنجاز ذلك أيضًا.
  2. كرر نفس الخطوات مع القوالب الأخرى.

فيما يلي بعض لقطات الشاشة للنماذج الأخرى والنتائج عند الاتصال بـ Amazon Bedrock مع بعضها.

ما يلي هو الكود الخاص بـ 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:"]}"

فيما يلي ردنا من Amazon Bedrock باستخدام هذا القالب.

ما يلي هو رمز 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:"]}"


ما يلي هو الكود الخاص بـ 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]"]}"


كما ترى، فقد استخدمنا قوالب المطالبة الخاصة بنا للتحقق من صحة عناصر القائمة، وتحديد المعلومات المطلوبة المفقودة، وإنشاء بنية بيانات، وتلخيص الطلب. النماذج الأساسية المتوفرة على Amazon Bedrock قوية للغاية، لذا يمكنك إنجاز المزيد من المهام عبر هذه القوالب.

لقد أكملت هندسة المطالبات وحفظت النماذج في ملفات نصية. يمكنك الآن البدء في إنشاء روبوت Amazon Lex ووظائف Lambda المرتبطة به.

قم بإنشاء طبقة Lambda باستخدام قوالب المطالبة

أكمل الخطوات التالية لإنشاء طبقة Lambda الخاصة بك:

  1. في SageMaker Studio، قم بإنشاء مجلد جديد بمجلد فرعي اسمه python.
  2. انسخ ملفات المطالبة الخاصة بك إلى python المجلد.

  1. يمكنك إضافة مكتبة ZIP إلى مثيل دفتر الملاحظات الخاص بك عن طريق تشغيل الأمر التالي.
!conda install -y -c conda-forge zip

  1. الآن، قم بتشغيل الأمر التالي لإنشاء ملف ZIP للتحميل إلى طبقة Lambda.
!zip -r prompt_templates_layer.zip prompt_templates_layer/.

  1. بعد إنشاء ملف ZIP، يمكنك تنزيل الملف. انتقل إلى Lambda، وقم بإنشاء طبقة جديدة عن طريق تحميل الملف مباشرة أو عن طريق التحميل إلى Amazon S3 أولاً.
  2. ثم قم بإرفاق هذه الطبقة الجديدة بوظيفة Lambda للتنسيق.

يتم الآن تخزين ملفات قالب المطالبة محليًا في بيئة تشغيل Lambda لديك. سيؤدي هذا إلى تسريع العملية أثناء تشغيل الروبوت الخاص بك.

قم بإنشاء طبقة Lambda بالمكتبات المطلوبة

أكمل الخطوات التالية لإنشاء طبقة Lambda الخاصة بك باستخدام المكتبات المطلوبة:

  1. فتح سحابة AWS 9 بيئة المثيل، قم بإنشاء مجلد بمجلد فرعي يسمى python.
  2. افتح محطة داخل python المجلد.
  3. قم بتشغيل الأوامر التالية من المحطة:
pip install “boto3>=1.28.57” -t .
pip install “awscli>=1.29.57" -t .
pip install “botocore>=1.31.57” -t .

  1. يجري cd .. ووضع نفسك داخل المجلد الجديد حيث يوجد لديك أيضًا ملف python مجلد فرعي.
  2. قم بتشغيل الأمر التالي:
zip -r lambda-layer.zip

  1. بعد إنشاء ملف ZIP، يمكنك تنزيل الملف. انتقل إلى Lambda، وقم بإنشاء طبقة جديدة عن طريق تحميل الملف مباشرة أو عن طريق التحميل إلى Amazon S3 أولاً.
  2. ثم قم بإرفاق هذه الطبقة الجديدة بوظيفة Lambda للتنسيق.

قم بإنشاء الروبوت في Amazon Lex v2

بالنسبة لحالة الاستخدام هذه، قمنا ببناء روبوت Amazon Lex الذي يمكنه توفير واجهة إدخال/إخراج للبنية من أجل الاتصال بـ Amazon Bedrock باستخدام الصوت أو النص من أي واجهة. نظرًا لأن LLM سيتعامل مع جزء المحادثة الخاص بوكيل معالجة الطلب هذا، وستقوم Lambda بتنسيق سير العمل، فيمكنك إنشاء روبوت بثلاثة أغراض وبدون فتحات.

  1. على وحدة تحكم Amazon Lex، قم بإنشاء روبوت جديد باستخدام الطريقة إنشاء بوت فارغ.

يمكنك الآن إضافة نية مع أي عبارة أولية مناسبة للمستخدمين النهائيين لبدء المحادثة مع الروبوت. نحن نستخدم تحيات بسيطة ونضيف استجابة روبوت أولية حتى يتمكن المستخدمون النهائيون من تقديم طلباتهم. عند إنشاء الروبوت، تأكد من استخدام رابط تعليمات Lambda مع الأغراض؛ سيؤدي هذا إلى تشغيل وظيفة Lambda التي ستقوم بتنسيق سير العمل بين العميل وAmazon Lex وLLM.

  1. أضف نيتك الأولى، التي تقوم بتشغيل سير العمل وتستخدم قالب المطالبة للتحقق من صحة النية للاتصال بـ Amazon Bedrock وتحديد ما يحاول العميل تحقيقه. أضف بعض العبارات البسيطة للمستخدمين النهائيين لبدء المحادثة.

لا تحتاج إلى استخدام أي فتحات أو قراءة أولية في أي من أهداف الروبوت. في الواقع، لا تحتاج إلى إضافة ألفاظ إلى المقصد الثاني أو الثالث. وذلك لأن LLM ستوجه Lambda طوال العملية.

  1. أضف رسالة تأكيد. يمكنك تخصيص هذه الرسالة في وظيفة Lambda لاحقًا.

  1. تحت خطاف كود، حدد استخدم وظيفة Lambda للتهيئة والتحقق من الصحة.

  1. أنشئ نية ثانية بدون نطق أو استجابة أولية. هذا ال PlaceOrder القصد.

عندما يحدد LLM أن العميل يحاول تقديم طلب، ستقوم وظيفة Lambda بتشغيل هذه النية والتحقق من صحة طلب العميل مقابل القائمة، والتأكد من عدم فقدان أي معلومات مطلوبة. تذكر أن كل هذا موجود في قوالب الموجهات، حتى تتمكن من تكييف سير العمل هذا مع أي حالة استخدام عن طريق تغيير قوالب الموجهات.

  1. لا تضف أي خانات، ولكن أضف رسالة تأكيد ورفض الرد.

  1. أختار استخدم وظيفة Lambda للتهيئة والتحقق من الصحة.

  1. قم بإنشاء نية ثالثة تسمى ProcessOrder مع عدم وجود عينة من الكلام ولا فتحات.
  2. قم بإضافة استجابة أولية، ومطالبة تأكيد، واستجابة رفض.

بعد قيام LLM بالتحقق من صحة طلب العميل، تقوم وظيفة Lambda بتشغيل النية الثالثة والأخيرة لمعالجة الطلب. هنا، ستستخدم Lambda قالب منشئ الكائن لإنشاء بنية بيانات الطلب JSON للاستعلام عن جدول DynamoDB، ثم تستخدم قالب ملخص الطلب لتلخيص الطلب بالكامل مع الإجمالي حتى يتمكن Amazon Lex من تمريره إلى العميل.

  1. أختار استخدم وظيفة Lambda للتهيئة والتحقق من الصحة. يمكن أن يستخدم هذا أي وظيفة Lambda لمعالجة الطلب بعد أن يقدم العميل التأكيد النهائي.

  1. بعد إنشاء جميع الأغراض الثلاثة، انتقل إلى Visual Builder لـ ValidateIntent، أضف خطوة الانتقال إلى الهدف، وقم بتوصيل مخرجات التأكيد الإيجابي بتلك الخطوة.
  2. بعد إضافة هدف الانتقال، قم بتحريره واختر هدف PlaceOrder كاسم الهدف.

  1. وبالمثل، للذهاب إلى المنشئ المرئي لـ PlaceOrder نية وربط إخراج التأكيد الإيجابي إلى ProcessOrder الذهاب إلى القصد. لا يلزم التحرير ل ProcessOrder القصد.
  2. أنت الآن بحاجة إلى إنشاء وظيفة Lambda التي تنظم Amazon Lex وتستدعي جدول DynamoDB، كما هو مفصل في القسم التالي.

قم بإنشاء وظيفة Lambda لتنسيق روبوت Amazon Lex

يمكنك الآن إنشاء وظيفة Lambda التي تنظم روبوت Amazon Lex وسير العمل. أكمل الخطوات التالية:

  1. قم بإنشاء وظيفة Lambda باستخدام سياسة التنفيذ القياسية واسمح لـ Lambda بإنشاء دور لك.
  2. في نافذة التعليمات البرمجية الخاصة بوظيفتك، أضف بعض الوظائف المساعدة التي ستساعد: تنسيق المطالبات عن طريق إضافة سياق lex إلى القالب، واستدعاء Amazon Bedrock LLM API، واستخراج النص المطلوب من الردود، والمزيد. انظر الكود التالي:
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. قم بإرفاق طبقة Lambda التي قمت بإنشائها مسبقًا بهذه الوظيفة.
  2. بالإضافة إلى ذلك، قم بإرفاق الطبقة بقوالب المطالبة التي قمت بإنشائها.
  3. في دور تنفيذ Lambda، قم بإرفاق سياسة الوصول إلى Amazon Bedrock، التي تم إنشاؤها مسبقًا.

يجب أن يتمتع دور تنفيذ Lambda بالأذونات التالية.

قم بإرفاق وظيفة Orchestration Lambda إلى روبوت Amazon Lex

  1. بعد إنشاء الوظيفة في القسم السابق، ارجع إلى وحدة تحكم Amazon Lex وانتقل إلى الروبوت الخاص بك.
  2. تحت اللغات في جزء التنقل ، اختر عربي.
  3. في حالة مصدر، اختر روبوت معالجة الطلب الخاص بك.
  4. في حالة إصدار دالة Lambda أو الاسم المستعار، اختر $الأحدث.
  5. اختار حفظ.

إنشاء وظائف Lambda المساعدة

أكمل الخطوات التالية لإنشاء وظائف Lambda إضافية:

  1. قم بإنشاء دالة Lambda للاستعلام عن جدول DynamoDB الذي قمت بإنشائه مسبقًا:
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. انتقل إلى الاعداد علامة التبويب في وظيفة Lambda واختر أذونات.
  2. قم بإرفاق بيان سياسة قائم على الموارد مما يسمح لوظيفة Lambda لمعالجة الطلب باستدعاء هذه الوظيفة.

  1. انتقل إلى دور تنفيذ IAM لوظيفة Lambda هذه وأضف سياسة للوصول إلى جدول DynamoDB.

  1. أنشئ دالة Lambda أخرى للتحقق مما إذا تم تمرير جميع السمات المطلوبة من العميل. في المثال التالي، نقوم بالتحقق من صحة ما إذا تم التقاط سمة الحجم للطلب:
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. انتقل إلى الاعداد علامة التبويب في وظيفة Lambda واختر أذونات.
  2. قم بإرفاق بيان سياسة قائم على الموارد مما يسمح لوظيفة Lambda لمعالجة الطلب باستدعاء هذه الوظيفة.

اختبر المحلول

يمكننا الآن اختبار الحل من خلال نماذج الطلبات التي يقدمها العملاء عبر Amazon Lex.

في مثالنا الأول، طلب العميل مشروب فرابتشينو، وهو غير موجود في القائمة. يتم التحقق من صحة النموذج بمساعدة قالب التحقق من الطلب ويقترح بعض التوصيات بناءً على القائمة. بعد تأكيد العميل لطلبه، يتم إعلامه بإجمالي الطلب وملخص الطلب. ستتم معالجة الطلب بناءً على التأكيد النهائي للعميل.

في المثال التالي، يطلب العميل كابتشينو كبير ثم يقوم بتعديل الحجم من كبير إلى متوسط. يلتقط النموذج جميع التغييرات اللازمة ويطلب من العميل تأكيد الطلب. يعرض النموذج إجمالي الطلب وملخص الطلب، ويقوم بمعالجة الطلب بناءً على التأكيد النهائي للعميل.

بالنسبة لمثالنا الأخير، قدم العميل طلبًا لعناصر متعددة وكان الحجم مفقودًا لعدد من العناصر. سيتحقق النموذج ووظيفة Lambda من وجود جميع السمات المطلوبة لمعالجة الطلب ثم يطلبان من العميل تقديم المعلومات المفقودة. بعد أن يقدم العميل المعلومات المفقودة (في هذه الحالة، حجم القهوة)، يتم عرض إجمالي الطلب وملخص الطلب. ستتم معالجة الطلب بناءً على التأكيد النهائي للعميل.

قيود LLM

تعتبر مخرجات LLM عشوائية بطبيعتها، مما يعني أن نتائج LLM لدينا يمكن أن تختلف في التنسيق، أو حتى في شكل محتوى غير صادق (الهلوسة). لذلك، يحتاج المطورون إلى الاعتماد على منطق جيد لمعالجة الأخطاء في التعليمات البرمجية الخاصة بهم من أجل التعامل مع هذه السيناريوهات وتجنب تجربة المستخدم النهائي المتدهورة.

تنظيف

إذا لم تعد بحاجة إلى هذا الحل، يمكنك حذف الموارد التالية:

  • وظائف لامدا
  • صندوق أمازون ليكس
  • جدول DynamoDB
  • دلو S3

بالإضافة إلى ذلك، قم بإيقاف تشغيل مثيل SageMaker Studio إذا لم يعد التطبيق مطلوبًا.

تقدير التكلفة

للحصول على معلومات التسعير للخدمات الرئيسية التي يستخدمها هذا الحل، راجع ما يلي:

لاحظ أنه يمكنك استخدام Claude v2 دون الحاجة إلى التوفير، لذلك تظل التكاليف الإجمالية عند الحد الأدنى. ولتقليل التكاليف بشكل أكبر، يمكنك تكوين جدول DynamoDB بالإعداد حسب الطلب.

وفي الختام

يوضح هذا المنشور كيفية إنشاء وكيل معالجة أوامر مدعوم بالذكاء الاصطناعي وممكن باستخدام Amazon Lex وAmazon Bedrock وخدمات AWS الأخرى. لقد أظهرنا كيف يمكن للهندسة السريعة باستخدام نموذج ذكاء اصطناعي توليدي قوي مثل كلود أن تتيح فهمًا قويًا للغة الطبيعية وتدفقات المحادثة لمعالجة الطلبات دون الحاجة إلى بيانات تدريب مكثفة.

تستخدم بنية الحل مكونات بدون خادم مثل Lambda وAmazon S3 وDynamoDB لتمكين التنفيذ المرن والقابل للتطوير. يتيح لك تخزين قوالب المطالبة في Amazon S3 تخصيص الحل لحالات الاستخدام المختلفة.

يمكن أن تتضمن الخطوات التالية توسيع قدرات الوكيل للتعامل مع نطاق أوسع من طلبات العملاء وحالات الحافة. توفر قوالب المطالبة طريقة لتحسين مهارات الوكيل بشكل متكرر. يمكن أن تتضمن التخصيصات الإضافية دمج بيانات الطلب مع أنظمة الواجهة الخلفية مثل المخزون أو إدارة علاقات العملاء أو نقطة البيع. وأخيرًا، يمكن إتاحة الوكيل عبر نقاط اتصال العملاء المختلفة مثل تطبيقات الأجهزة المحمولة، وخدمة الطلب من السيارة، والأكشاك، والمزيد باستخدام إمكانيات القنوات المتعددة في Amazon Lex.

لمعرفة المزيد، راجع المصادر ذات الصلة التالية:

  • نشر وإدارة الروبوتات متعددة القنوات:
  • الهندسة السريعة لكلود ونماذج أخرى:
  • أنماط معمارية بدون خادم لمساعدي الذكاء الاصطناعي القابلين للتطوير:

حول المؤلف

موميتا دوتا هو مهندس حلول الشركاء في Amazon Web Services. ومن خلال دورها، تتعاون بشكل وثيق مع الشركاء لتطوير أصول قابلة للتطوير وإعادة الاستخدام تعمل على تبسيط عمليات نشر السحابة وتعزيز الكفاءة التشغيلية. وهي عضو في مجتمع الذكاء الاصطناعي/تعلم الآلة وخبيرة الذكاء الاصطناعي التوليدي في AWS. وفي أوقات فراغها، تستمتع بالبستنة وركوب الدراجات.

فرناندو لاموجليا هو مهندس حلول الشركاء في Amazon Web Services، ويعمل بشكل وثيق مع شركاء AWS في قيادة تطوير واعتماد حلول الذكاء الاصطناعي المتطورة عبر وحدات الأعمال. قائد استراتيجي يتمتع بخبرة في الهندسة السحابية والذكاء الاصطناعي التوليدي والتعلم الآلي وتحليلات البيانات. وهو متخصص في تنفيذ استراتيجيات الذهاب إلى السوق وتقديم حلول الذكاء الاصطناعي المؤثرة التي تتماشى مع الأهداف التنظيمية. يحب في أوقات فراغه قضاء الوقت مع عائلته والسفر إلى بلدان أخرى.

ميتول باتيل هو مهندس حلول أول في Amazon Web Services. ومن خلال دوره كعامل تمكين للتكنولوجيا السحابية، فهو يعمل مع العملاء لفهم أهدافهم وتحدياتهم، ويقدم إرشادات إرشادية لتحقيق هدفهم من خلال عروض AWS. وهو عضو في مجتمع الذكاء الاصطناعي/تعلم الآلة وسفير الذكاء الاصطناعي التوليدي في AWS. وفي أوقات فراغه، يستمتع بالمشي لمسافات طويلة ولعب كرة القدم.

بقعة_صورة

أحدث المعلومات الاستخباراتية

بقعة_صورة