เริ่มต้นใช้งานการดึงข้อมูลความหมาย

ดูใน ai.google.dev ลองใช้ Colab Notebook ดูสมุดบันทึกใน GitHub

ภาพรวม

โมเดลภาษาขนาดใหญ่ (LLM) เรียนรู้ความสามารถใหม่ๆ ได้โดยไม่ต้องได้รับการฝึกโดยตรง แต่ LLM เป็นที่รู้กันว่า "ความไม่สมเหตุสมผล" เมื่อมอบหมายให้ตอบคำถามที่ยังไม่ได้รับการฝึกอบรม ทั้งนี้ส่วนหนึ่งเป็นเพราะ LLM ไม่ทราบถึงเหตุการณ์หลังจากการฝึก นอกจากนี้ การติดตามแหล่งที่มาของ LLM ที่ใช้คำตอบก็ทำได้ยากมากเช่นกัน สำหรับแอปพลิเคชันที่เชื่อถือได้และรองรับการปรับขนาด สิ่งสำคัญคือ LLM จะต้องให้คำตอบที่มีข้อเท็จจริงรองรับและสามารถอ้างอิงแหล่งข้อมูลของตนได้

แนวทางทั่วไปที่ใช้เพื่อเอาชนะข้อจำกัดเหล่านี้เรียกว่า Retrieval Augmented Generation (RAG) ซึ่งเสริมพรอมต์ที่ส่งไปยัง LLM ด้วยข้อมูลที่เกี่ยวข้องซึ่งดึงมาจากฐานความรู้ภายนอกผ่านกลไกการดึงข้อมูล (IR) ฐานความรู้อาจเป็นคลังเอกสาร ฐานข้อมูล หรือ API ของคุณเองก็ได้

สมุดบันทึกนี้จะแนะนำเวิร์กโฟลว์ในการปรับปรุงคำตอบของ LLM ด้วยการเพิ่มความรู้ด้วยคลังข้อความภายนอก และดึงข้อมูลเชิงอรรถศาสตร์เพื่อตอบคำถามโดยใช้ Semantic Retriever และคำถามที่มีการระบุแหล่งที่มา Answering (AQA) API ของ 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 ให้คุณค้นหาตามความหมายในข้อมูลของคุณเอง เนื่องจากข้อมูลของคุณ จึงจะต้องมีการควบคุมการเข้าถึงที่เข้มงวดกว่าคีย์ 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 จะมี Document ได้สูงสุด 10,000 รายการ คุณสามารถระบุฟิลด์ใดฟิลด์หนึ่งต่อไปนี้ขณะกำหนดเอกสารได้

  • name: ชื่อทรัพยากร (รหัส) ของ Document ต้องมีอักขระไม่เกิน 40 ตัว (ตัวอักษรและตัวเลขหรือเครื่องหมายขีดกลางเท่านั้น) รหัสต้องไม่ขึ้นต้นหรือลงท้ายด้วย ขีดกลาง หากชื่อว่างเปล่าเมื่อสร้างขึ้น ชื่อที่ไม่ซ้ำกันจะดึงมาจาก display_name พร้อมคำต่อท้ายแบบสุ่ม 12 อักขระ
  • display_name: ชื่อที่แสดงที่ผู้ใช้อ่านได้ ต้องมีอักขระไม่เกิน 512 ตัว ซึ่งรวมถึงตัวอักษรและตัวเลข การเว้นวรรค และเครื่องหมายขีดกลาง

Document ยังรองรับช่อง custom_metadata ที่ผู้ใช้ระบุได้สูงสุด 20 ช่อง ซึ่งระบุเป็นคู่คีย์-ค่า ข้อมูลเมตาที่กำหนดเองอาจเป็นสตริง รายการสตริง หรือตัวเลข โปรดทราบว่ารายการของสตริงรองรับค่าได้สูงสุด 10 ค่า และค่าตัวเลขจะแสดงเป็นเลขทศนิยมใน API

# 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 มีจำนวนได้สูงสุด 1 ล้านChunk วินาที

Chunks ยังรองรับช่อง custom_metadata ที่ผู้ใช้ระบุสูงสุด 20 ช่อง ซึ่งระบุเป็นคู่คีย์-ค่า เช่นเดียวกับ Document ข้อมูลเมตาที่กำหนดเองอาจเป็นสตริง รายการสตริง หรือตัวเลข โปรดทราบว่ารายการของสตริงรองรับค่าได้สูงสุด 10 ค่า และค่าตัวเลขจะแสดงเป็นเลขทศนิยมใน API

คู่มือนี้ใช้ 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 จากน้อยไปมาก หากคุณไม่ระบุขีดจำกัด ระบบจะแสดงผล Chunk สูงสุด 10 รายการ

ระบุ next_page_token ที่แสดงผลในการตอบกลับ ListChunksRequest เป็นอาร์กิวเมนต์ของคำขอถัดไปเพื่อดึงหน้าถัดไป โปรดทราบว่าเมื่อใส่เลขหน้า พารามิเตอร์อื่นๆ ทั้งหมดที่ให้กับ ListChunks ต้องตรงกับการเรียกใช้ที่ให้โทเค็นของหน้าเว็บ

Chunk ทั้งหมดจะแสดงผล state ใช้เพื่อตรวจสอบสถานะของ Chunks ก่อนค้นหา Corpus Chunk รัฐ ได้แก่ UNSPECIFIED, PENDING_PROCESSING, ACTIVE และ FAILED คุณค้นหาChunkได้ ACTIVE รายการเท่านั้น

# 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 รายการ หากไม่ระบุ API จะแสดงผลสูงสุด 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} }]
  }]

โปรดทราบว่าเฉพาะค่าตัวเลขเท่านั้นที่รองรับ "AND" สำหรับคีย์เดียวกัน สตริง ค่าจะรองรับเฉพาะ "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 ที่ต่ำอาจอธิบายได้จากปัจจัยต่อไปนี้อย่างน้อย 1 ข้อ

  • โมเดลไม่มั่นใจว่าคำตอบถูกต้อง
  • โมเดลไม่มั่นใจว่าคำตอบมีพื้นฐานมาจากข้อความที่อ้างอิง คำตอบอาจได้มาจากความรู้ทางโลก เช่น 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.answer มีแนวโน้มที่จะไม่ถูกต้องหรือไม่สมเหตุสมผล จึงขอแนะนำอย่างยิ่งให้ประมวลผลการตอบกลับเพิ่มเติมโดยตรวจสอบ answerable_probability

เมื่อ answerable_probability อยู่ในช่วงราคาต่ำ ลูกค้าบางรายอาจต้องการทำสิ่งต่อไปนี้

  • แสดงข้อความให้มีผลว่า "ตอบคําถามนั้นไม่ได้" ต่อผู้ใช้ปลายทาง
  • กลับไปใช้ LLM ที่มีวัตถุประสงค์ทั่วไปซึ่งตอบคำถามจากความรู้ทั่วโลก เกณฑ์และลักษณะของวิดีโอสำรองดังกล่าวจะขึ้นอยู่กับกรณีการใช้งานแต่ละรายการ ค่า answerable_probability <= 0.5 ถือเป็นเกณฑ์เริ่มต้นที่ดี

เคล็ดลับที่เป็นประโยชน์เกี่ยวกับ AQA

โปรดดูข้อมูลจำเพาะทั้งหมดของ API ในGenerateAnswerRequestข้อมูลอ้างอิง API

  • ความยาวของข้อความ: แนะนำให้มีโทเค็นสูงสุดไม่เกิน 300 รายการต่อข้อความ
  • การจัดเรียงข้อความ
    • หากระบุ GenerateAnswerRequest.inline_passages ข้อความควรจัดเรียงตามความเกี่ยวข้องกับคำค้นหาจากมากไปน้อย หากเกินขีดจำกัดความยาวบริบทของโมเดล ระบบจะละเว้นข้อความสุดท้าย (เกี่ยวข้องน้อยที่สุด)
    • หากคุณระบุ GenerateAnswerRequest.semantic_retriever ระบบจะจัดเรียงความเกี่ยวข้องให้คุณโดยอัตโนมัติ
  • ข้อจำกัด: โมเดล AQA ออกแบบมาเพื่อการตอบคำถามโดยเฉพาะ สำหรับกรณีการใช้งานอื่นๆ เช่น การเขียนเชิงสร้างสรรค์ การสรุป ฯลฯ โปรดเรียกใช้รูปแบบที่มีวัตถุประสงค์ทั่วไปผ่าน GenerateContent
    • แชท: หากทราบว่าข้อมูลจากผู้ใช้เป็นคำถามที่อาจตอบได้ในบางบริบท AQA จะตอบคำค้นหาของแชทได้ แต่หากข้อมูลจากผู้ใช้อาจเป็นรายการประเภทใดก็ได้ รูปแบบที่มีวัตถุประสงค์ทั่วไปก็อาจเป็นทางเลือกที่ดีกว่า
  • อุณหภูมิ
    • โดยทั่วไปแล้ว เราขอแนะนำให้ใช้อุณหภูมิที่ค่อนข้างต่ำ (~0.2) เพื่อให้ AQA แม่นยำ
    • หาก Use Case ของคุณใช้เอาต์พุตเชิงกำหนด ให้ตั้งอุณหภูมิเป็น 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 ที่ใช้ข้อความในบรรทัด

หรือคุณจะใช้ปลายทาง 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 API

ข้อจำกัด:

  • การแชร์มี 2 บทบาท ได้แก่ 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)

สรุปและอ่านเพิ่มเติม

คู่มือนี้ได้แนะนำเกี่ยวกับรีทรีฟเวอร์เชิงความหมายและคำถามที่มีการระบุแหล่งที่มาและ การตอบ API (AQA) ของ Generative Language API และแสดงวิธีที่คุณสามารถใช้ API ดังกล่าวเพื่อดึงข้อมูลเชิงอรรถศาสตร์จากข้อมูลข้อความที่กำหนดเอง โปรดทราบว่า API นี้ใช้งานได้กับเฟรมเวิร์กข้อมูล LlamaIndex ด้วย ดูข้อมูลเพิ่มเติมได้ในบทแนะนำ

และดูข้อมูลเพิ่มเติมเกี่ยวกับฟังก์ชันอื่นๆ ที่พร้อมใช้งานได้ที่เอกสาร API

ภาคผนวก: ตั้งค่า 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()