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

العرض على ai.google.dev التنفيذ في Google Colab عرض المصدر على GitHub

نظرة عامة

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

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

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

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

استيراد واجهة برمجة تطبيقات اللغة التوليدية

# 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: اسم المورد (ID) 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 هو 2,043. ويمكن أن يصل الحد الأقصى لطول السمة 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)

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

يمكنك استخدام طريقة 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 العديد من المزايا مقارنةً باستخدام نموذج لغوي كبير (LLM) لم يتم تعديله، وذلك في الحالات التي تكون فيها قيمة 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 هي حد أدنى جيد للبدء.

نصائح مفيدة حول جودة الهواء

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

  • طول الفقرة: يُنصح باستخدام ما يصل إلى 300 رمز مميّز لكل فقرة.
  • ترتيب الفقرات:
    • في حال تقديم GenerateAnswerRequest.inline_passages، يجب ترتيب الفقرات بترتيب تنازلي حسب مدى صلتها بطلب البحث. إذا تم تجاوز حد طول سياق النموذج، سيتم حذف الفقرات الأخيرة (الأقل صلة).
    • إذا قدّمت GenerateAnswerRequest.semantic_retriever، سيتم ترتيب مدى الصلة بموضوع البحث تلقائيًا بالنيابة عنك.
  • القيود: نموذج "جودة الهواء" متخصص في الإجابة عن الأسئلة. بالنسبة إلى حالات الاستخدام الأخرى مثل الكتابة الإبداعية أو التلخيص أو غير ذلك، يُرجى استخدام نموذج للأغراض العامة من خلال GenerateContent.
    • Chat: إذا كان السؤال الذي يُدخله المستخدم معروفًا بأنه سؤال يمكن الإجابة عنه من سياق معيّن، يمكن لـ "جودة الهواء" الرد على طلبات البحث من خلال الدردشة. ولكن إذا كان البيانات التي أدخلها المستخدم هي أي نوع من أنواع الإدخالات، قد يكون نموذج الأغراض العامة خيارًا أفضل.
  • درجة الحرارة:
    • بشكل عام، يُنصَح بأن تكون درجة الحرارة منخفضة نسبيًا (حوالي 0.2) للحصول على مؤشر جودة الهواء (AQA) بشكل دقيق.
    • إذا كانت حالة الاستخدام تعتمد على مخرجات حتمية، يجب ضبط درجة الحرارة=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 لحذف مجموعة المستخدمين وجميع Documents &المرتبطة 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()