ذكاء البيانات التوليدية

أنشئ حلاً قويًا لتحويل النص إلى SQL لإنشاء استعلامات معقدة وتصحيح ذاتي والاستعلام عن مصادر بيانات متنوعة | خدمات الويب الأمازون

التاريخ:

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

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

يهدف حلنا إلى معالجة تلك التحديات باستخدام أمازون بيدروك و خدمات تحليلات AWS. نحن نستخدم الأنثروبي كلود v2.1 على Amazon Bedrock بصفته LLM لدينا. ولمواجهة التحديات، يتضمن الحل الذي نقدمه أولاً البيانات الوصفية لمصادر البيانات داخل كتالوج بيانات AWS Glue لزيادة دقة استعلام SQL الذي تم إنشاؤه. يتضمن سير العمل أيضًا حلقة تقييم وتصحيح نهائية، في حالة تحديد أي مشكلات تتعلق بـ SQL أمازون أثينا، والذي يتم استخدامه كمحرك SQL. تسمح لنا أثينا أيضًا باستخدام عدد كبير من نقاط النهاية والموصلات المدعومة لتغطية مجموعة كبيرة من مصادر البيانات.

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

حل نظرة عامة

هناك ثلاثة مكونات مهمة في بنيتنا: إنشاء الاسترجاع المعزز (RAG) مع بيانات تعريف قاعدة البيانات، وحلقة تصحيح ذاتي متعددة الخطوات، وAthena كمحرك SQL الخاص بنا.

نحن نستخدم طريقة RAG لاسترداد أوصاف الجدول وأوصاف المخطط (الأعمدة) من AWS Glue metastore للتأكد من أن الطلب مرتبط بالجدول ومجموعات البيانات الصحيحة. في الحل الذي نقدمه، قمنا ببناء الخطوات الفردية لتشغيل إطار عمل RAG باستخدام كتالوج بيانات AWS Glue لأغراض العرض التوضيحي. ومع ذلك، يمكنك أيضًا استخدام قواعد المعرفة في Amazon Bedrock لبناء حلول RAG بسرعة.

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

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

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

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

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

يتم عرض بنية الحل وتدفق العملية.

الشكل 1. بنية الحل وتدفق العملية.

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

  1. قم بإنشاء كتالوج بيانات AWS Glue باستخدام زاحف AWS Glue (أو طريقة مختلفة).
  2. باستخدام نموذج Titan-Text-Embeddings على Amazon Bedrock، قم بتحويل البيانات الوصفية إلى تضمينات وقم بتخزينها في ملف أمازون أوبن سيرش سيرفرليس متجر ناقلات، والتي تعد بمثابة قاعدة معرفتنا في إطار عمل RAG الخاص بنا.

في هذه المرحلة، تكون العملية جاهزة لتلقي الاستعلام باللغة الطبيعية. تمثل الخطوات من 7 إلى 9 حلقة تصحيح، إن أمكن.

  1. يقوم المستخدم بإدخال استعلامه باللغة الطبيعية. يمكنك استخدام أي تطبيق ويب لتوفير واجهة مستخدم الدردشة. لذلك، لم نقم بتغطية تفاصيل واجهة المستخدم في منشورنا.
  2. يطبق الحل إطار عمل RAG عبر بحث التشابه، الذي يضيف السياق الإضافي من البيانات التعريفية من قاعدة بيانات المتجهات. يُستخدم هذا الجدول للعثور على الجدول وقاعدة البيانات والسمات الصحيحة.
  3. يتم دمج الاستعلام مع السياق وإرساله إلى الأنثروبي كلود v2.1 على أمازون بيدروك.
  4. يحصل النموذج على استعلام SQL الذي تم إنشاؤه ويتصل بـ Athena للتحقق من صحة بناء الجملة.
  5. إذا قدمت Athena رسالة خطأ تشير إلى أن بناء الجملة غير صحيح، فسيستخدم النموذج نص الخطأ من استجابة Athena.
  6. يضيف الموجه الجديد استجابة أثينا.
  7. يقوم النموذج بإنشاء SQL المصحح ويستمر في العملية. يمكن تنفيذ هذا التكرار عدة مرات.
  8. وأخيرًا، نقوم بتشغيل SQL باستخدام Athena وإنشاء المخرجات. وهنا يتم عرض الإخراج للمستخدم. ومن أجل البساطة المعمارية لم نعرض هذه الخطوة.

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

بالنسبة لهذا المنشور ، يجب عليك إكمال المتطلبات الأساسية التالية:

  1. أحصل على حساب AWS.
  2. تثبيت ال واجهة سطر الأوامر AWS (AWS CLI).
  3. إعداد SDK لبيثون (Boto3).
  4. قم بإنشاء كتالوج بيانات AWS Glue باستخدام زاحف AWS Glue (أو طريقة مختلفة).
  5. باستخدام نموذج Titan-Text-Embeddings على Amazon Bedrock، قم بتحويل البيانات التعريفية إلى تضمينات وقم بتخزينها في OpenSearch Serverless متجر ناقلات.

تنفيذ الحل

يمكنك استخدام ما يلي دفتر جوبيتر، والذي يتضمن كافة مقتطفات التعليمات البرمجية المتوفرة في هذا القسم، لبناء الحل. نوصي باستخدام أمازون ساجميكر ستوديو لفتح دفتر الملاحظات هذا بمثيل ml.t3.medium مع نواة Python 3 (علوم البيانات). للحصول على التعليمات، راجع تدريب نموذج التعلم الآلي. أكمل الخطوات التالية لإعداد الحل:

  1. قم بإنشاء قاعدة المعرفة في خدمة OpenSearch لإطار عمل RAG:
    def add_documnets(self,index_name: str,file_name:str):
    
    documents = JSONLoader(file_path=file_name, jq_schema='.', text_content=False, json_lines=False).load()
    docs = OpenSearchVectorSearch.from_documents(embedding=self.embeddings, opensearch_url=self.opensearch_domain_endpoint, http_auth=self.http_auth, documents=documents, index_name=index_name, engine="faiss")
    index_exists = self.check_if_index_exists(index_name,aws_region,opensearch_domain_endpoint,http_auth)
    if not index_exists :
    logger.info(f'index :{index_name} is not existing ')
    sys.exit(-1)
    else:
    logger.info(f'index :{index_name} Got created')

  2. بناء المطالبة (final_question) من خلال الجمع بين مدخلات المستخدم باللغة الطبيعية (user_query)، البيانات الوصفية ذات الصلة من متجر المتجهات (vector_search_match)، وتعليماتنا (details):
    def userinput(user_query):
    logger.info(f'Searching metadata from vector store')
    
    # vector_search_match=rqst.getEmbeddding(user_query)
    vector_search_match = rqst.getOpenSearchEmbedding(index_name,user_query)
    
    # print(vector_search_match)
    details = "It is important that the SQL query complies with Athena syntax. 
    During join if column name are same please use alias ex llm.customer_id 
    in select statement. It is also important to respect the type of columns: 
    if a column is string, the value should be enclosed in quotes. 
    If you are writing CTEs then include all the required columns. 
    While concatenating a non string column, make sure cast the column to string. 
    For date columns comparing to string , please cast the string input."
    final_question = "nnHuman:"+details + vector_search_match + user_query+ "nnAssistant:"
    answer = rqst.generate_sql(final_question)
    return answer

  3. قم باستدعاء Amazon Bedrock للحصول على LLM (Claude v2) واطلب منه إنشاء استعلام SQL. في التعليمة البرمجية التالية، يقوم بمحاولات متعددة لتوضيح خطوة التصحيح الذاتي:x
    try:
    logger.info(f'we are in Try block to generate the sql and count is :{attempt + 1}')
    generated_sql = self.llm.predict(prompt)
    query_str = generated_sql.split("```")[1]
    query_str = " ".join(query_str.split("n")).strip()
    sql_query = query_str[3:] if query_str.startswith("sql") else query_str
    
    # return sql_query
    syntaxcheckmsg=rqstath.syntax_checker(sql_query)
    if syntaxcheckmsg=='Passed':
    logger.info(f'syntax checked for query passed in attempt number :{attempt + 1}')
    return sql_query

  4. إذا تم تلقي أية مشكلات في استعلام SQL الذي تم إنشاؤه ({sqlgenerated}) من رد أثينا ({syntaxcheckmsg})، المطالبة الجديدة (prompt) بناءً على الاستجابة ويحاول النموذج مرة أخرى إنشاء SQL الجديد:
    else:
    prompt = f"""{prompt} 
    This is syntax error: {syntaxcheckmsg}.
    To correct this, please generate an alternative SQL query which will correct the syntax error. The updated query should take care of all the syntax issues encountered. Follow the instructions mentioned above to remediate the error.
    Update the below SQL query to resolve the issue:
    {sqlgenerated}
    Make sure the updated SQL query aligns with the requirements provided in the initial question."""
    prompts.append(prompt)

  5. بعد إنشاء SQL، يتم استدعاء عميل Athena لتشغيل وإنشاء الإخراج:
    query_execution = self.athena_client.start_query_execution(
    QueryString=query_string,
    ResultConfiguration=result_config,
    QueryExecutionContext=query_execution_context, )
    execution_id = query_execution["QueryExecutionId"]

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

في هذا القسم، نقوم بتشغيل الحل الخاص بنا باستخدام سيناريوهات أمثلة مختلفة لاختبار مستويات التعقيد المختلفة لاستعلامات SQL.

لاختبار تحويل النص إلى SQL، نستخدم اثنين مجموعات البيانات المتاحة من موقع IMDB. مجموعات فرعية من بيانات IMDb متاحة للاستخدام الشخصي وغير التجاري. يمكنك تنزيل مجموعات البيانات وتخزينها فيها خدمة تخزين أمازون البسيطة (أمازون إس 3). يمكنك استخدام مقتطف Spark SQL التالي لإنشاء جداول في AWS Glue. في هذا المثال نستخدم title_ratings و title:

source_title_ratings3_path = 's3://llm-athena-output/input_data/title.ratings.tsv'
target_title_s3_path='s3://llm-athena-output/output_data/imdb_stg/title_ratings'
source_titleratingdf=spark.read.csv(source_title_ratings3_path,sep="t",header=True)
source_titleratingdf.write.mode('overwrite').format('parquet').option('path', target_title_s3_path).saveAsTable('imdb_stg.title_ratings')

قم بتخزين البيانات في Amazon S3 والبيانات التعريفية في AWS Glue

في هذا السيناريو، يتم تخزين مجموعة البيانات الخاصة بنا في حاوية S3. تمتلك Athena موصل S3 الذي يسمح لك باستخدام Amazon S3 كمصدر بيانات يمكن الاستعلام عنه.

بالنسبة للاستعلام الأول، نقدم الإدخال "أنا جديد على هذا. هل يمكنك مساعدتي في رؤية جميع الجداول والأعمدة في مخطط imdb؟

فيما يلي الاستعلام الذي تم إنشاؤه:

WITH tables AS (
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'imdb_stg'),
columns AS (
SELECT
c.table_name,
c.column_name,
c.data_type,
c.is_nullable,
c.column_default,
c.ordinal_position
FROM information_schema.columns c
WHERE c.table_schema = 'imdb_stg')
SELECT
t.table_name,
c.column_name,
c.data_type,
c.is_nullable,
c.column_default,
c.ordinal_position
FROM tables t
INNER JOIN columns c
ON t.table_name = c.table_name
ORDER BY
t.table_name,
c.ordinal_position
LIMIT 10;

تظهر لقطة الشاشة والكود التاليين مخرجاتنا.

جدول يوضح سمات مجموعة بيانات IMBD النموذجية.

table_name column_name data_type
0 title titleid varchar
1 title ordering integer
2 title title varchar
3 title region varchar
4 title language varchar

بالنسبة للاستعلام الثاني، نسأل "أرني كل العناوين والتفاصيل في منطقة الولايات المتحدة التي يزيد تصنيفها عن 9.5".

ما يلي هو الاستعلام الذي تم إنشاؤه:

WITH us_titles AS (
SELECT t.title, t.region, tr.averageRating, tr.numVotes
FROM imdb_stg.title t
INNER JOIN imdb_stg.title_ratings tr
ON t.titleId = tr.tconst
WHERE t.region = 'US' AND cast(tr.averageRating as varchar) > '9.5'
)
SELECT title, region, averageRating, numVotes
FROM us_titles
LIMIT 100;

الرد على النحو التالي.

جدول يوضح نتائج استعلام SQL

title region averageRating numVotes
0 The Way You Saw Me US 9.7 8
1 The Brother Side of the Wake US 9.6 20
2 Ignis Fatuus US 9.6 11
3 Love and Hip Hop Atlanta US 9.9 11
4 ronny/lily US 9.7 14781

بالنسبة للاستعلام الثالث، ندخل "استجابة رائعة! أرني الآن جميع العناوين من النوع الأصلي التي لديها تقييمات تزيد عن 7.5 وليست في منطقة الولايات المتحدة.

تم إنشاء الاستعلام التالي:

WITH titles AS (
SELECT t.titleId,
t.title,
t.types,
t.isOriginalTitle,
cast(tr.averageRating as decimal(3,1)) as averageRating,
tr.numVotes,
t.region
FROM imdb_stg.title t
INNER JOIN imdb_stg.title_ratings tr
ON t.titleId = tr.tconst
WHERE t.isOriginalTitle = '1'
AND cast(tr.averageRating as decimal(3,1)) > 7.5
AND t.region != 'US')
SELECT *
FROM titles
LIMIT 100;

نحصل على النتائج التالية.

صف واحد يعرض نتيجة استعلام SQL.

titleId title types isOriginalTitle averageRating numVotes region
0 tt0986264 Taare Zameen Par original 1 8.3 203760 XWW

إنشاء SQL ذاتي التصحيح

يحاكي هذا السيناريو استعلام SQL به مشكلات في بناء الجملة. هنا، سيتم تصحيح SQL الذي تم إنشاؤه ذاتيًا بناءً على استجابة Athena. في الرد التالي، أعطت أثينا أ COLUMN_NOT_FOUND خطأ وذكر ذلك table_description لا يمكن حلها:

Status : {'State': 'FAILED', 'StateChangeReason': "COLUMN_NOT_FOUND: line 1:50: Column 'table_description' 
cannot be resolved or requester is not authorized to access requested resources",
'SubmissionDateTime': datetime.datetime(2024, 1, 14, 14, 38, 57, 501000, tzinfo=tzlocal()),
'CompletionDateTime': datetime.datetime(2024, 1, 14, 14, 38, 57, 778000, tzinfo=tzlocal()),
'AthenaError': {'ErrorCategory': 2, 'ErrorType': 1006, 'Retryable': False, 'ErrorMessage': "COLUMN_NOT_FOUND: 
line 1:50: Column 'table_description' cannot be resolved or requester is not authorized to 
access requested resources"}}
COLUMN_NOT_FOUND: line 1:50: Column 'table_description' cannot be resolved or requester is not authorized to access requested resources
Try Count: 2
2024-01-14 14:39:02,521,llm_execute,MainProcess,INFO,Try Count: 2
we are in Try block to generate the sql and count is :2
2024-01-14 14:39:02,521,llm_execute,MainProcess,INFO,we are in Try block to generate the sql and count is :2
Executing: Explain WITH tables AS ( SELECT table_name FROM information_schema.tables WHERE table_schema = 'imdb_stg' ), columns AS ( SELECT c.table_name, c.column_name, c.data_type, c.is_nullable, c.column_default, c.ordinal_position FROM information_schema.columns c WHERE c.table_schema = 'imdb_stg' ) SELECT t.table_name, c.column_name, c.data_type, c.is_nullable, c.column_default, c.ordinal_position FROM tables t INNER JOIN columns c ON t.table_name = c.table_name ORDER BY t.table_name, c.ordinal_position LIMIT 10;
I am checking the syntax here
execution_id: 904857c3-b7ac-47d0-8e7e-6b9d0456099b
Status : {'State': 'SUCCEEDED', 'SubmissionDateTime': datetime.datetime(2024, 1, 14, 14, 39, 29, 537000, tzinfo=tzlocal()), 'CompletionDateTime': datetime.datetime(2024, 1, 14, 14, 39, 30, 183000, tzinfo=tzlocal())}
syntax checked for query passed in tries number :2

استخدام الحل مع مصادر البيانات الأخرى

لاستخدام الحل مع مصادر بيانات أخرى، تتولى Athena المهمة نيابةً عنك. للقيام بذلك، تستخدم أثينا موصلات مصدر البيانات التي يمكن استخدامها مع الاستفسارات الموحدة. يمكنك اعتبار الموصل بمثابة امتداد لمحرك استعلام Athena. توجد موصلات مصدر بيانات Athena المعدة مسبقًا لمصادر البيانات مثل سجلات الأمازون CloudWatch, الأمازون DynamoDB, Amazon DocumentDB (مع التوافق مع MongoDB)و خدمة قاعدة بيانات الأمازون (Amazon RDS)، ومصادر البيانات الارتباطية المتوافقة مع JDBC مثل MySQL وPostgreSQL بموجب ترخيص Apache 2.0. بعد إعداد اتصال بأي مصدر بيانات، يمكنك استخدام قاعدة التعليمات البرمجية السابقة لتوسيع الحل. لمزيد من المعلومات، راجع استعلم عن أي مصدر بيانات باستخدام الاستعلام الموحد الجديد الخاص بـ Amazon Athena.

تنظيف

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

وفي الختام

في هذا المنشور، قدمنا ​​حلاً يسمح لك باستخدام البرمجة اللغوية العصبية (NLP) لإنشاء استعلامات SQL معقدة باستخدام مجموعة متنوعة من الموارد التي تتيحها Athena. لقد قمنا أيضًا بزيادة دقة استعلامات SQL التي تم إنشاؤها عبر حلقة تقييم متعددة الخطوات استنادًا إلى رسائل الخطأ الواردة من العمليات النهائية. بالإضافة إلى ذلك، استخدمنا البيانات التعريفية في AWS Glue Data Catalog للنظر في أسماء الجداول المطلوبة في الاستعلام من خلال إطار عمل RAG. قمنا بعد ذلك باختبار الحل في سيناريوهات واقعية مختلفة بمستويات مختلفة من تعقيد الاستعلام. أخيرًا، ناقشنا كيفية تطبيق هذا الحل على مصادر البيانات المختلفة التي تدعمها Athena.

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


حول المؤلف

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

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

بقعة_صورة

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

بقعة_صورة