ดูใน 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 โดยใช้บัญชีบริการ
- เปิดใช้ Generative Language API
สร้างบัญชีบริการโดยทำตามเอกสารประกอบ
- หลังจากสร้างบัญชีบริการแล้ว ให้สร้างคีย์บัญชีบริการ
อัปโหลดไฟล์บัญชีบริการโดยใช้ไอคอนไฟล์ในแถบด้านข้างทางซ้าย จากนั้นคลิกไอคอนอัปโหลดตามที่แสดงในภาพหน้าจอด้านล่าง
- เปลี่ยนชื่อไฟล์ที่อัปโหลดเป็น
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 จะแสดงผลสูงสุด 10Chunk
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
ให้สิทธิ์ข้อมูลเข้าสู่ระบบสำหรับแอปพลิเคชันเดสก์ท็อป หากต้องการเรียกใช้สมุดบันทึกนี้ใน 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()