البدء باسترجاع المعنى

الاطّلاع على ai.google.dev تجربة "مفكرة Colab" عرض دفتر الملاحظات على GitHub

نظرة عامة

يمكن للنماذج اللغوية الكبيرة (LLM) اكتساب قدرات جديدة بدون تدريبها عليها مباشرةً. ومع ذلك، من المعروف أنّ النماذج اللغوية الكبيرة "تُحلِم" عندما يتم تكليفها بتقديم ردود على أسئلة لم يتم تدريبها عليها. ويعود السبب جزئيًا إلى أنّ النماذج اللغوية الكبيرة لا تطّلع على الأحداث بعد التدريب. ومن الصعب أيضًا تتبُّع المصادر التي تستنِد إليها نماذج اللغة المحوسبة الكبيرة في تقديم إجاباتها. بالنسبة إلى التطبيقات الموثوقة والقابلة للتطوير، من المهم أن يقدّم النموذج اللغوي الكبير ردودًا مستندة إلى الحقائق وأن يكون قادرًا على الاستشهاد بمصادر المعلومات.

يُعرف النهج الشائع المستخدَم للتغلب على هذه القيود باسم "الإنشاء المعزّز لاسترداد المعلومات" (RAG)، والذي يعزّز الطلب المُرسَل إلى نموذج اللغة الكبيرة (LLM) بالبيانات ذات الصلة التي يتم استرجاعها من قاعدة معرفة خارجية من خلال آلية "استرداد المعلومات" (IR). يمكن أن تكون قاعدة المعارف هي مجموعتك الخاصة من المستندات أو قواعد البيانات أو واجهات برمجة التطبيقات.

يرشدك هذا المفكرة خلال سير العمل لتحسين ردّ نموذج اللغة الكبيرة (LLM) من خلال توسيع نطاقه المعرفي باستخدام مجموعات نصوص خارجية وتنفيذ استرداد المعلومات الدلالية للإجابة عن الأسئلة باستخدام واجهتَي برمجة التطبيقات Semantic Retriever وAttributed Question & Answering (AQA) من Generative Language API.

ضبط إعدادات الجهاز

استيراد واجهة برمجة التطبيقات Generative Language API

# Install the Client library (Semantic Retriever is only supported for versions >0.4.0)
pip install -U google.ai.generativelanguage

مصادقة

تتيح لك Semantic Retriever API إجراء بحث دلالي على بياناتك الخاصة. وبما أنّها بياناتك، يجب أن تكون عناصر التحكّم في الوصول أكثر صرامة من مفاتيح واجهة برمجة التطبيقات. يمكنك المصادقة باستخدام OAuth من خلال حسابات الخدمة أو من خلال بيانات اعتماد المستخدم.

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

إعداد بروتوكول OAuth باستخدام حسابات الخدمة

اتّبِع الخطوات التالية لإعداد بروتوكول OAuth باستخدام حسابات الخدمة:

  1. فعِّل Generative Language API.

  1. أنشئ حساب الخدمة باتّباع المستندات.

    • بعد إنشاء حساب الخدمة، أنشِئ مفتاح حساب خدمة.

  1. حمِّل ملف حساب الخدمة باستخدام رمز الملف في الشريط الجانبي الأيمن، ثم رمز التحميل، كما هو موضّح في لقطة الشاشة أدناه.

    • أعِد تسمية الملف المحمَّل إلى service_account_key.json أو غيِّر المتغيّر service_account_file_name في الرمز البرمجي أدناه.

pip install -U google-auth-oauthlib
service_account_file_name = 'service_account_key.json'

from google.oauth2 import service_account

credentials = service_account.Credentials.from_service_account_file(service_account_file_name)

scoped_credentials = credentials.with_scopes(
    ['https://www.googleapis.com/auth/cloud-platform', 'https://www.googleapis.com/auth/generative-language.retriever'])

ابدأ مكتبة العميل باستخدام بيانات اعتماد حساب الخدمة.

import google.ai.generativelanguage as glm
generative_service_client = glm.GenerativeServiceClient(credentials=scoped_credentials)
retriever_service_client = glm.RetrieverServiceClient(credentials=scoped_credentials)
permission_service_client = glm.PermissionServiceClient(credentials=scoped_credentials)

إنشاء قاعدة بيانات

تتيح لك واجهة برمجة التطبيقات Semantic Retriever API تحديد ما يصل إلى 5 مجموعات نصية مخصَّصة لكل مشروع. يمكنك تحديد أيّ من الحقول التالية أثناء تحديد مجموعات النصوص:

  • name: اسم مورد Corpus (رقم التعريف). يجب أن يتضمّن 40 حرفًا أبجديًا رقميًا كحدّ أقصى. إذا كانت السمة name فارغة عند الإنشاء، سيتم إنشاء اسم فريد لا يزيد طوله عن 40 حرفًا مع بادئة من display_name ولاحقة عشوائية مكوّنة من 12 حرفًا.
  • display_name: الاسم المعروض للCorpus والذي يمكن للمستخدمين قراءته يجب ألا يحتوي على أكثر من 512 حرفًا كحد أقصى، بما في ذلك الأحرف الأبجدية الرقمية والمسافات والشرطات.
example_corpus = glm.Corpus(display_name="Google for Developers Blog")
create_corpus_request = glm.CreateCorpusRequest(corpus=example_corpus)

# Make the request
create_corpus_response = retriever_service_client.create_corpus(create_corpus_request)

# Set the `corpus_resource_name` for subsequent sections.
corpus_resource_name = create_corpus_response.name
print(create_corpus_response)
name: "corpora/google-for-developers-blog-dqrtz8rs0jg"
display_name: "Google for Developers Blog"
create_time {
  seconds: 1713497533
  nanos: 587977000
}
update_time {
  seconds: 1713497533
  nanos: 587977000
}

الحصول على مجموعة النصوص التي تم إنشاؤها

استخدِم طريقة GetCorpusRequest للوصول آليًا إلى Corpus الذي أنشأته أعلاه. تشير قيمة المعلَمة name إلى اسم المورد الكامل لـ Corpus ويتم ضبطها في الخلية أعلاه على corpus_resource_name. التنسيق المتوقّع هو corpora/corpus-123.

get_corpus_request = glm.GetCorpusRequest(name=corpus_resource_name)

# Make the request
get_corpus_response = retriever_service_client.get_corpus(get_corpus_request)

# Print the response
print(get_corpus_response)

إنشاء مستند

يمكن أن يحتوي Corpus على ما يصل إلى 10,000 Document. يمكنك تحديد أيّ من الحقول التالية أثناء تحديد مستنداتك:

  • name: اسم المورد (ID) Document يجب ألا يحتوي على أكثر من 40 حرفًا (أحرف أبجدية رقمية أو شرطات فقط). لا يمكن أن يبدأ المعرّف أو ينتهي بعلامة دالٍ. إذا كان الاسم فارغًا عند الإنشاء، سيتم إنشاء اسم فريد من display_name مع إضافة لاحقة عشوائية من 12 حرفًا.
  • display_name: الاسم المعروض الذي يمكن للمستخدمين قراءته يجب ألا يزيد عدد الأحرف عن 512 حرفًا كحد أقصى، بما في ذلك الأحرف الأبجدية الرقمية والمسافات والشرطات.

تتيح Document أيضًا ما يصل إلى 20 حقل custom_metadata يحدّدها المستخدم، ويتم تحديدها كأزواج مفتاح/قيمة. يمكن أن تكون البيانات الوصفية المخصّصة سلاسل أو قوائم سلاسل أو رقمية. يُرجى العِلم أنّ قوائم السلاسل يمكن أن تتضمّن 10 قيم كحدّ أقصى، ويتم تمثيل القيم الرقمية كأعداد عائمة في واجهة برمجة التطبيقات.

# Create a document with a custom display name.
example_document = glm.Document(display_name="Introducing Project IDX, An Experiment to Improve Full-stack, Multiplatform App Development")

# Add metadata.
# Metadata also supports numeric values not specified here
document_metadata = [
    glm.CustomMetadata(key="url", string_value="https://developers.googleblog.com/2023/08/introducing-project-idx-experiment-to-improve-full-stack-multiplatform-app-development.html")]
example_document.custom_metadata.extend(document_metadata)

# Make the request
# corpus_resource_name is a variable set in the "Create a corpus" section.
create_document_request = glm.CreateDocumentRequest(parent=corpus_resource_name, document=example_document)
create_document_response = retriever_service_client.create_document(create_document_request)

# Set the `document_resource_name` for subsequent sections.
document_resource_name = create_document_response.name
print(create_document_response)

الحصول على المستند الذي تم إنشاؤه

استخدِم الطريقة GetDocumentRequest للوصول آليًا إلى المستند الذي أنشأته أعلاه. تشير قيمة المعلَمة name إلى اسم المورد الكامل للمستند ويتم ضبطها في الخلية أعلاه على أنّها document_resource_name. التنسيق المتوقّع هو corpora/corpus-123/documents/document-123.

get_document_request = glm.GetDocumentRequest(name=document_resource_name)

# Make the request
# document_resource_name is a variable set in the "Create a document" section.
get_document_response = retriever_service_client.get_document(get_document_request)

# Print the response
print(get_document_response)

نقل مستند إلى "مركز عمليّات التنقيب في البيانات" وتقسيمه إلى أجزاء

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

Chunk هو جزء فرعي من Document يتم التعامل معه كوحدة مستقلة لأغراض تمثيل المتجهات وتخزينها. يمكن أن يتضمّن Chunk 2043 رمزًا مميزًا كحد أقصى. يمكن أن يتضمّن Corpus مليون Chunk كحد أقصى.

على غرار Document، تتيح Chunks أيضًا ما يصل إلى 20 حقل custom_metadata يحدّدها المستخدم، ويتم تحديدها كأزواج مفتاح/قيمة. يمكن أن تكون البيانات الوصفية المخصّصة سلاسل أو قوائم سلاسل أو رقمية. يُرجى العِلم أنّ قوائم السلاسل يمكن أن تتضمّن 10 قيم كحدّ أقصى، ويتم تمثيل القيم الرقمية كأعداد عائمة في واجهة برمجة التطبيقات.

يستخدم هذا الدليل HtmlChunker مفتوح المصدر من Google.

تشمل أدوات تقسيم النصوص الأخرى التي يمكنك استخدامها LangChain أو LlamaIndex.

نقل HTML والمقطع عبر HtmlChunker

!pip install google-labs-html-chunker

from google_labs_html_chunker.html_chunker import HtmlChunker

from urllib.request import urlopen

الحصول على HTML DOM لموقع إلكتروني في هذه الحالة، تتم قراءة ملف HTML مباشرةً، ولكن سيكون من الأفضل الحصول على ملف HTML بعد العرض لتضمين ملف HTML تم حقنه باستخدام JavaScript مثل document.documentElement.innerHTML.

with(urlopen("https://developers.googleblog.com/2023/08/introducing-project-idx-experiment-to-improve-full-stack-multiplatform-app-development.html")) as f:
  html = f.read().decode("utf-8")

يمكنك تقسيم مستند النص إلى مقاطع وإنشاء Chunk من هذه المقاطع. تنشئ هذه الخطوة كائنات Chunk نفسها، ويحمّلها القسم التالي إلى واجهة برمجة التطبيقات Semantic Retriever API.

# Chunk the file using HtmlChunker
chunker = HtmlChunker(
    max_words_per_aggregate_passage=200,
    greedily_aggregate_sibling_nodes=True,
    html_tags_to_exclude={"noscript", "script", "style"},
)
passages = chunker.chunk(html)
print(passages)


# Create `Chunk` entities.
chunks = []
for passage in passages:
    chunk = glm.Chunk(data={'string_value': passage})
    # Optionally, you can add metadata to a chunk
    chunk.custom_metadata.append(glm.CustomMetadata(key="tags",
                                                    string_list_value=glm.StringList(
                                                        values=["Google For Developers", "Project IDX", "Blog", "Announcement"])))
    chunk.custom_metadata.append(glm.CustomMetadata(key="chunking_strategy",
                                                    string_value="greedily_aggregate_sibling_nodes"))
    chunk.custom_metadata.append(glm.CustomMetadata(key = "publish_date",
                                                    numeric_value = 20230808))
    chunks.append(chunk)
print(chunks)

إنشاء مجموعات دفعة واحدة

إنشاء أجزاء في دفعات يمكنك تحديد 100 قطعة كحد أقصى لكل طلب دفعة.

استخدِم CreateChunk() لإنشاء مقطع واحد.

# Option 1: Use HtmlChunker in the section above.
# `chunks` is the variable set from the section above.
create_chunk_requests = []
for chunk in chunks:
  create_chunk_requests.append(glm.CreateChunkRequest(parent=document_resource_name, chunk=chunk))

# Make the request
request = glm.BatchCreateChunksRequest(parent=document_resource_name, requests=create_chunk_requests)
response = retriever_service_client.batch_create_chunks(request)
print(response)

بدلاً من ذلك، يمكنك إنشاء أجزاء بدون استخدام HtmlChunker.

# Add up to 100 CreateChunk requests per batch request.
# document_resource_name is a variable set in the "Create a document" section.
chunks = []
chunk_1 = glm.Chunk(data={'string_value': "Chunks support user specified metadata."})
chunk_1.custom_metadata.append(glm.CustomMetadata(key="section",
                                                  string_value="Custom metadata filters"))
chunk_2 = glm.Chunk(data={'string_value': "The maximum number of metadata supported is 20"})
chunk_2.custom_metadata.append(glm.CustomMetadata(key = "num_keys",
                                                  numeric_value = 20))
chunks = [chunk_1, chunk_2]
create_chunk_requests = []
for chunk in chunks:
  create_chunk_requests.append(glm.CreateChunkRequest(parent=document_resource_name, chunk=chunk))

# Make the request
request = glm.BatchCreateChunksRequest(parent=document_resource_name, requests=create_chunk_requests)
response = retriever_service_client.batch_create_chunks(request)
print(response)

إدراج Chunks والحصول على الحالة

يمكنك استخدام طريقة ListChunksRequest لعرض كل Chunk المتاحة كقائمة مقسَّمة إلى صفحات وبحد أقصى للحجم يبلغ 100 Chunk لكل صفحة، ويتم ترتيبها تصاعديًا على Chunk.create_time. في حال عدم تحديد حدّ، يتم عرض 10 Chunk كحدّ أقصى.

قدِّم next_page_token المعروض في استجابة ListChunksRequest كوسيطة للطلب التالي لاسترداد الصفحة التالية. تجدر الإشارة إلى أنّه عند التقسيم على صفحات، يجب أن تتطابق جميع المَعلمات الأخرى المقدَّمة للسمة ListChunks مع الاستدعاء الذي قدّم الرمز المميّز للصفحة.

تعرض كل Chunk state. استخدِم هذا الإجراء للتحقّق من حالة Chunks قبل طلب Corpus. تشمل الولايات التي تتبع Chunk الولايات التالية: UNSPECIFIED وPENDING_PROCESSING وACTIVE وFAILED. يمكنك فقط طلب ACTIVE Chunk.

# Make the request
request = glm.ListChunksRequest(parent=document_resource_name)
list_chunks_response = retriever_service_client.list_chunks(request)
for index, chunks in enumerate(list_chunks_response.chunks):
  print(f'\nChunk # {index + 1}')
  print(f'Resource Name: {chunks.name}')
  # Only ACTIVE chunks can be queried.
  print(f'State: {glm.Chunk.State(chunks.state).name}')

نقل بيانات مستند آخر

أضِف Document آخرًا من خلال HtmlChunker وأضِف فلاتر.

# Create a document with a custom display name.
example_document = glm.Document(display_name="How it’s Made: Interacting with Gemini through multimodal prompting")

# Add document metadata.
# Metadata also supports numeric values not specified here
document_metadata = [
    glm.CustomMetadata(key="url", string_value="https://developers.googleblog.com/2023/12/how-its-made-gemini-multimodal-prompting.html")]
example_document.custom_metadata.extend(document_metadata)

# Make the CreateDocument request
# corpus_resource_name is a variable set in the "Create a corpus" section.
create_document_request = glm.CreateDocumentRequest(parent=corpus_resource_name, document=example_document)
create_document_response = retriever_service_client.create_document(create_document_request)

# Set the `document_resource_name` for subsequent sections.
document_resource_name = create_document_response.name
print(create_document_response)

# Chunks - add another webpage from Google for Developers
with(urlopen("https://developers.googleblog.com/2023/12/how-its-made-gemini-multimodal-prompting.html")) as f:
  html = f.read().decode("utf-8")

# Chunk the file using HtmlChunker
chunker = HtmlChunker(
    max_words_per_aggregate_passage=100,
    greedily_aggregate_sibling_nodes=False,
)
passages = chunker.chunk(html)

# Create `Chunk` entities.
chunks = []
for passage in passages:
    chunk = glm.Chunk(data={'string_value': passage})
    chunk.custom_metadata.append(glm.CustomMetadata(key="tags",
                                                    string_list_value=glm.StringList(
                                                        values=["Google For Developers", "Gemini API", "Blog", "Announcement"])))
    chunk.custom_metadata.append(glm.CustomMetadata(key="chunking_strategy",
                                                    string_value="no_aggregate_sibling_nodes"))
    chunk.custom_metadata.append(glm.CustomMetadata(key = "publish_date",
                                                    numeric_value = 20231206))
    chunks.append(chunk)

# Make the request
create_chunk_requests = []
for chunk in chunks:
  create_chunk_requests.append(glm.CreateChunkRequest(parent=document_resource_name, chunk=chunk))
request = glm.BatchCreateChunksRequest(parent=document_resource_name, requests=create_chunk_requests)
response = retriever_service_client.batch_create_chunks(request)
print(response)

الاستعلام عن المجموعة الكاملة

استخدِم طريقة QueryCorpusRequest لإجراء بحث دلالي للحصول على مقاطع ذات صلة.

  • results_count: حدِّد عدد الفقرات المطلوب عرضها. الحد الأقصى هو 100. في حال عدم تحديد هذا الحقل، ستعرض واجهة برمجة التطبيقات 10 Chunk كحد أقصى.
  • metadata_filters: الفلترة حسب chunk_metadata أو document_metadata يجب أن يكون لكل MetadataFilter مفتاح فريد. يتمّ دمج عناصر MetadataFilter متعددة باستخدام عوامل التشغيل المنطقية AND. يتمّ دمج شروط فلترة البيانات الوصفية المتشابهة باستخدام عوامل التشغيل المنطقية OR. إليك بعض الأمثلة:
(year >= 2020 OR year < 2010) AND (genre = drama OR genre = action)

metadata_filter = [
  {
    key = "document.custom_metadata.year"
    conditions = [
      {int_value = 2020, operation = GREATER_EQUAL},
      {int_value = 2010, operation = LESS}]
  },
  {
    key = "document.custom_metadata.genre"
    conditions = [
      {string_value = "drama", operation = EQUAL},
      {string_value = "action", operation = EQUAL} }]
  }]

يُرجى العلم أنّ القيم الرقمية فقط هي التي تتيح استخدام "و" للمفتاح نفسه. وتدعم قيم السلسلة "OR" للمفتاح نفسه فقط.

("Google for Developers" in tags) and (20230314 > publish_date)

metadata_filter = [
 {
    key = "chunk.custom_metadata.tags"
    conditions = [
    {string_value = 'Google for Developers', operation = INCLUDES},
  },
  {
    key = "chunk.custom_metadata.publish_date"
    conditions = [
    {numeric_value = 20230314, operation = GREATER_EQUAL}]
  }]
user_query = "What is the purpose of Project IDX?"
results_count = 5

# Add metadata filters for both chunk and document.
chunk_metadata_filter = glm.MetadataFilter(key='chunk.custom_metadata.tags',
                                           conditions=[glm.Condition(
                                              string_value='Google For Developers',
                                              operation=glm.Condition.Operator.INCLUDES)])

# Make the request
# corpus_resource_name is a variable set in the "Create a corpus" section.
request = glm.QueryCorpusRequest(name=corpus_resource_name,
                                 query=user_query,
                                 results_count=results_count,
                                 metadata_filters=[chunk_metadata_filter])
query_corpus_response = retriever_service_client.query_corpus(request)
print(query_corpus_response)

إجابة أسئلة الإحالة

استخدِم طريقة GenerateAnswer لإجراء عملية الإجابة عن الأسئلة المنسوبة في المستند أو مجموعة النصوص أو مجموعة من المقاطع.

تشير ميزة "الإجابة عن الأسئلة المُحدَّدة المصدر" (AQA) إلى الإجابة عن أسئلة مستندة إلى سياق معيّن وتقديم مصادر، مع الحدّ من الأوهام.

يوفّر GenerateAnswer العديد من المزايا مقارنةً باستخدام نموذج تعلُّم لغوي كبير غير معدّل، في الحالات التي يكون فيها مطلوبًا استخدام نموذج تقييم الأداء التلقائي (AQA):

  • تم تدريب النموذج الأساسي على عرض الإجابات المستندة إلى السياق المقدَّم فقط.
  • ويحدِّد الإسنادات (أجزاء من السياق المقدَّم التي ساهمت في تقديم الإجابة). تتيح الإسنادات للمستخدم التحقّق من الإجابة.
  • ويقدّر هذا المقياس answerable_probability لزوج (سؤال، سياق) معيّن، ما يمنحك المزيد من الإمكانيات لتغيير سلوك المنتج استنادًا إلى مدى احتمال أن تكون الإجابة المعروضة مستندة إلى الحقائق وصحيحة.

answerable_probability وحلّ مشكلة "لا أعلم"

في بعض الحالات، يكون أفضل ردّ على السؤال هو "لا أعرف". على سبيل المثال، إذا كان السياق المقدّم لا يتضمّن إجابة عن السؤال، يُعدّ السؤال "لا يمكن الإجابة عنه".

يُعدّ نموذج AQA بارعًا في التعرّف على هذه الحالات. ويمكنها حتى أن يميز بين درجات القدرة على الإجابة وعدم القدرة على الإجابة.

في المقابل، تضع GenerateAnswer API سلطة اتخاذ القرار النهائي من خلال ما يلي:

  • محاولة تقديم إجابة مستندة إلى الحقائق في جميع الأوقات، حتى إذا كان من غير المرجّح أن تكون هذه الإجابة مستندة إلى الحقائق وصحيحة
  • عرض قيمة answerable_probability - يشير ذلك إلى تقدير النموذج لاحتمالية أن تكون الإجابة صحيحة.

يمكن أن يرجع انخفاض قيمة answerable_probability إلى سبب واحد أو أكثر من الأسباب التالية:

  • النموذج غير واثق من صحة إجابته.
  • لا يثق النموذج في أنّ إجابته مستندة إلى المقاطع المُقتبسة، وقد تكون الإجابة مستمَدة بدلاً من ذلك من المعرفة العامة. على سبيل المثال: question="1+1=?", passages=["2+2=4”]answer=2, answerable_probability=0.02
  • قدم النموذج معلومات ذات صلة لا توفر إجابة كاملة عن السؤال. مثال: question="Is it available in my size?, passages=["Available in sizes 5-11"]answer="Yes it is available in sizes 5-11", answerable_probability=0.03"
  • لم يتم طرح أي سؤال منظَّم في GenerateAnswerRequest.

بما أنّ انخفاض قيمة answerable_probability يشير إلى أنّه من المرجّح أن تكون قيمة GenerateAnswerResponse.answer خاطئة أو غير مستندة إلى أي أساس، ننصح بشدة بمعالجة الردّ بشكل أكبر من خلال فحص answerable_probability.

عندما تكون قيمة answerable_probability منخفضة، قد يريد بعض العملاء إجراء ما يلي:

  • عرض رسالة مفادها "لم تتمكن من الإجابة عن هذا السؤال" للمستخدم النهائي.
  • الرجوع إلى نموذج لغوي كبير (LLM) للأغراض العامة يجيب عن السؤال استنادًا إلى المعلومات العامة ويعتمد حد هذه الإجراءات وطبيعتها على حالات الاستخدام الفردية. وتكون القيمة answerable_probability <= 0.5 هي الحدّ الأدنى الجيد للبدء.

نصائح مفيدة حول AQA

للاطّلاع على المواصفات الكاملة لواجهة برمجة التطبيقات، يُرجى الاطّلاع على مرجع واجهة برمجة التطبيقات GenerateAnswerRequest.

  • طول الفقرة: يُنصح باستخدام ما يصل إلى 300 رمز لكل فقرة.
  • ترتيب الفقرات:
    • في حال تقديم GenerateAnswerRequest.inline_passages، يجب ترتيب الفقرات تنازليًا حسب مدى صلة كل فقرة بطلب البحث. إذا تم تجاوز حد طول سياق النموذج، سيتم حذف الفقرات الأخيرة (الأقل صلة).
    • في حال تقديم GenerateAnswerRequest.semantic_retriever، سيتم ترتيب النتائج حسب مدى الصلة تلقائيًا.
  • الحدود: نموذج AQA مخصّص للإجابة عن الأسئلة. بالنسبة إلى حالات الاستخدام الأخرى، مثل الكتابة الإبداعية والتلخيص وما إلى ذلك، يُرجى استدعاء نموذج للأغراض العامة من خلال GenerateContent.
    • المحادثة: إذا كان معروفًا أنّ إدخال المستخدم هو سؤال يمكن الإجابة عنه من سياق معيّن، يمكن لميزة "الأسئلة الشائعة عن التطبيق" الإجابة عن طلبات البحث في المحادثة. ولكن إذا كان إدخال المستخدم قد يكون أي نوع من الإدخالات، قد يكون النموذج العام هو الخيار الأفضل.
  • درجة الحرارة:
    • بشكل عام، يُنصَح بأن تكون درجة الحرارة منخفضة نسبيًا (حوالي 0.2) للحصول على مؤشر جودة الهواء (AQA) بشكل دقيق.
    • إذا كان سيناريو الاستخدام يعتمد على النتائج الحتمية، اضبط temperature=0.
user_query = "What is the purpose of Project IDX?"
answer_style = "ABSTRACTIVE" # Or VERBOSE, EXTRACTIVE
MODEL_NAME = "models/aqa"

# Make the request
# corpus_resource_name is a variable set in the "Create a corpus" section.
content = glm.Content(parts=[glm.Part(text=user_query)])
retriever_config = glm.SemanticRetrieverConfig(source=corpus_resource_name, query=content)
req = glm.GenerateAnswerRequest(model=MODEL_NAME,
                                contents=[content],
                                semantic_retriever=retriever_config,
                                answer_style=answer_style)
aqa_response = generative_service_client.generate_answer(req)
print(aqa_response)
# Get the metadata from the first attributed passages for the source
chunk_resource_name = aqa_response.answer.grounding_attributions[0].source_id.semantic_retriever_chunk.chunk
get_chunk_response = retriever_service_client.get_chunk(name=chunk_resource_name)
print(get_chunk_response)

المزيد من الخيارات: تحسين جودة الهواء باستخدام الفقرات المضمّنة

بدلاً من ذلك، يمكنك استخدام نقطة نهاية AQA مباشرةً، بدون استخدام واجهة برمجة التطبيقات Semantic Retriever API من خلال تمرير inline_passages.

user_query = "What is AQA from Google?"
user_query_content = glm.Content(parts=[glm.Part(text=user_query)])
answer_style = "VERBOSE" # or ABSTRACTIVE, EXTRACTIVE
MODEL_NAME = "models/aqa"

# Create the grounding inline passages
grounding_passages = glm.GroundingPassages()
passage_a = glm.Content(parts=[glm.Part(text="Attributed Question and Answering (AQA) refers to answering questions grounded to a given corpus and providing citation")])
grounding_passages.passages.append(glm.GroundingPassage(content=passage_a, id="001"))
passage_b = glm.Content(parts=[glm.Part(text="An LLM is not designed to generate content grounded in a set of passages. Although instructing an LLM to answer questions only based on a set of passages reduces hallucination, hallucination still often occurs when LLMs generate responses unsupported by facts provided by passages")])
grounding_passages.passages.append(glm.GroundingPassage(content=passage_b, id="002"))
passage_c = glm.Content(parts=[glm.Part(text="Hallucination is one of the biggest problems in Large Language Models (LLM) development. Large Language Models (LLMs) could produce responses that are fictitious and incorrect, which significantly impacts the usefulness and trustworthiness of applications built with language models.")])
grounding_passages.passages.append(glm.GroundingPassage(content=passage_c, id="003"))

# Create the request
req = glm.GenerateAnswerRequest(model=MODEL_NAME,
                                contents=[user_query_content],
                                inline_passages=grounding_passages,
                                answer_style=answer_style)
aqa_response = generative_service_client.generate_answer(req)
print(aqa_response)

مشاركة النص

يمكنك اختيار مشاركة مجموعة النصوص مع الآخرين باستخدام واجهة برمجة التطبيقات CreatePermissionRequest.

القيود:

  • هناك دوران للمشاركة: READER وEDITOR.
    • يمكن لـ READER الاستعلام عن النص.
    • يمتلك WRITER أذونات القارئ، ويمكنه أيضًا تعديل المجموعة ومشاركة المحتوى.
  • يمكن أن يكون المجموعة عامًا من خلال منح EVERYONE كـ user_type إذن وصول للقراءة.
# Replace your-email@gmail.com with the email added as a test user in the OAuth Quickstart
shared_user_email = "TODO-your-email@gmail.com" #  @param {type:"string"}
user_type = "USER"
role = "READER"

# Make the request
# corpus_resource_name is a variable set in the "Create a corpus" section.
request = glm.CreatePermissionRequest(
    parent=corpus_resource_name,
    permission=glm.Permission(grantee_type=user_type,
                              email_address=shared_user_email,
                              role=role))
create_permission_response = permission_service_client.create_permission(request)
print(create_permission_response)

حذف مجموعة النصوص

استخدِم DeleteCorpusRequest لحذف مجموعة نصوص مستخدم وجميع Document وChunk المرتبطة بها.

تجدر الإشارة إلى أنّ النصوص غير الفارغة ستؤدي إلى ظهور خطأ بدون تحديد علامة force=True. في حال ضبط force=True، سيتم أيضًا حذف أي Chunk وعناصر مرتبطة بهذا Document.

إذا كان force=False (الإعداد التلقائي) وDocument يحتويان على أي Chunk، سيتم عرض خطأ FAILED_PRECONDITION.

# Set force to False if you don't want to delete non-empty corpora.
req = glm.DeleteCorpusRequest(name=corpus_resource_name, force=True)
delete_corpus_response = retriever_service_client.delete_corpus(req)
print("Successfully deleted corpus: " + corpus_resource_name)

الملخّص والمراجع الإضافية

قدّم هذا الدليل واجهتَي برمجة تطبيقات "أداة الاسترجاع الدلالي" و"الأسئلة والأجوبة المنسوبة" (AQA) الخاصة بواجهة برمجة تطبيقات Generative Language API، وأظهر كيفية استخدامهما لاسترداد المعلومات الدلالية على بياناتك النصية المخصّصة. تجدر الإشارة إلى أنّ واجهة برمجة التطبيقات هذه تعمل أيضًا مع إطار بيانات LlamaIndex. يُرجى الاطّلاع على البرنامج التعليمي لمزيد من المعلومات.

يمكنك أيضًا الرجوع إلى مستندات واجهة برمجة التطبيقات للاطّلاع على مزيد من المعلومات حول الوظائف الأخرى المتاحة.

الملحق: إعداد بروتوكول OAuth باستخدام بيانات اعتماد المستخدم

اتّبِع الخطوات أدناه من التشغيل السريع لبروتوكول OAuth لإعداد مصادقة OAuth.

  1. إعداد شاشة طلب الموافقة المتعلّقة ببروتوكول OAuth

  2. تفويض بيانات الاعتماد لتطبيق كمبيوتر مكتبي لتشغيل ورقة الملاحظات هذه في Colab، يجب أولاً إعادة تسمية ملف بيانات الاعتماد (عادةً client_secret_*.json) إلى client_secret.json فقط. بعد ذلك، حمِّل الملف باستخدام رمز الملف في الشريط الجانبي الأيمن، ثم رمز التحميل، كما هو موضّح في لقطة الشاشة أدناه.

# Replace TODO-your-project-name with the project used in the OAuth Quickstart
project_name = "TODO-your-project-name" #  @param {type:"string"}
# Replace TODO-your-email@gmail.com with the email added as a test user in the OAuth Quickstart
email = "TODO-your-email@gmail.com" #  @param {type:"string"}
# Rename the uploaded file to `client_secret.json` OR
# Change the variable `client_file_name` in the code below.
client_file_name = "client_secret.json"

# IMPORTANT: Follow the instructions from the output - you must copy the command
# to your terminal and copy the output after authentication back here.
!gcloud config set project $project_name
!gcloud config set account $email

# NOTE: The simplified project setup in this tutorial triggers a "Google hasn't verified this app." dialog.
# This is normal, click "Advanced" -> "Go to [app name] (unsafe)"
!gcloud auth application-default login --no-browser --client-id-file=$client_file_name --scopes="https://www.googleapis.com/auth/generative-language.retriever,https://www.googleapis.com/auth/cloud-platform"

اضبط إعدادات مكتبة العملاء وأعِد تشغيل دفتر البيانات بدءًا من إنشاء قاعدة نصوص.

import google.ai.generativelanguage as glm

generative_service_client = glm.GenerativeServiceClient()
retriever_service_client = glm.RetrieverServiceClient()
permission_service_client = glm.PermissionServiceClient()