Làm quen với truy xuất ngữ nghĩa

Xem trên ai.google.dev Dùng thử sổ tay Colab Xem sổ tay trên GitHub

Tổng quan

Các mô hình ngôn ngữ lớn (LLM) có thể học những khả năng mới mà không cần trực tiếp được huấn luyện về những khả năng đó. Tuy nhiên, các LLM được biết đến là "ảo giác" khi được giao nhiệm vụ đưa ra câu trả lời cho những câu hỏi mà các em chưa được đào tạo. Điều này một phần là do các LLM không biết về các sự kiện sau khi được huấn luyện. Cũng rất khó tìm ra nguồn mà các LLM lấy ra câu trả lời của chúng. Đối với các ứng dụng đáng tin cậy và có thể mở rộng, điều quan trọng là một LLM cung cấp câu trả lời có cơ sở dựa trên dữ kiện thực tế và có thể trích dẫn các nguồn thông tin của nó.

Một phương pháp phổ biến mà chúng tôi dùng để khắc phục những hạn chế này là Tạo ra tăng cường truy xuất (RAG), giúp tăng cường câu lệnh được gửi đến một mô hình ngôn ngữ lớn (LLM) với dữ liệu liên quan được truy xuất từ cơ sở kiến thức bên ngoài thông qua cơ chế Truy xuất thông tin (IR). Cơ sở kiến thức có thể là tập hợp tài liệu, cơ sở dữ liệu hoặc API của riêng bạn.

Sổ tay này hướng dẫn bạn quy trình công việc để cải thiện phản hồi của một mô hình ngôn ngữ lớn (LLM) bằng cách củng cố kiến thức của nó với các tập sao lục văn bản bên ngoài và thực hiện việc truy xuất thông tin ngữ nghĩa để trả lời các câu hỏi bằng Trình truy xuất dữ liệu theo ngữ nghĩa và Câu hỏi được phân bổ và Các API trả lời (AQA) của Generative Language API.

Thiết lập

Nhập Generative Language API

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

Xác thực

Semantic Retriever API cho phép bạn thực hiện việc tìm kiếm theo ngữ nghĩa trên dữ liệu của mình. Vì đó là dữ liệu của bạn nên tính năng này cần các biện pháp kiểm soát quyền truy cập nghiêm ngặt hơn so với khoá API. Xác thực bằng OAuth bằng tài khoản dịch vụ hoặc thông qua thông tin đăng nhập người dùng.

Bước bắt đầu nhanh này sử dụng phương pháp xác thực đơn giản dành cho môi trường thử nghiệm và việc thiết lập tài khoản dịch vụ thường dễ bắt đầu hơn. Đối với môi trường phát hành công khai, hãy tìm hiểu về quy trình xác thực và uỷ quyền trước khi chọn thông tin xác thực truy cập phù hợp với ứng dụng.

Thiết lập OAuth bằng tài khoản dịch vụ

Hãy làm theo các bước bên dưới để thiết lập OAuth bằng tài khoản dịch vụ:

  1. Bật Generative Language API.

  1. Tạo Tài khoản dịch vụ bằng cách làm theo tài liệu này.

    • Sau khi tạo tài khoản dịch vụ, hãy tạo một khoá tài khoản dịch vụ.

  1. Tải tệp tài khoản dịch vụ của bạn lên bằng cách sử dụng biểu tượng tệp ở thanh bên trái, sau đó chọn biểu tượng tải lên (như trong ảnh chụp màn hình dưới đây).

    • Đổi tên tệp đã tải lên thành service_account_key.json hoặc thay đổi biến service_account_file_name trong đoạn mã bên dưới.

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'])

Khởi chạy thư viện ứng dụng bằng thông tin xác thực tài khoản dịch vụ.

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)

Tạo khối liệu

Semantic Retriever API cho phép bạn xác định tối đa 5 tập sao lục văn bản tuỳ chỉnh cho mỗi dự án. Bạn có thể chỉ định một trong các trường sau đây khi xác định kho ngữ liệu:

  • name: Tên tài nguyên (mã nhận dạng) Corpus. Chỉ được chứa tối đa 40 ký tự bao gồm chữ và số. Nếu name trống khi tạo, một tên duy nhất sẽ được tạo với độ dài tối đa là 40 ký tự, đi kèm một tiền tố từ display_name và một hậu tố ngẫu nhiên gồm 12 ký tự.
  • display_name: Tên hiển thị mà con người có thể đọc được của Corpus. Chỉ được chứa tối đa 512 ký tự, bao gồm cả chữ và số, dấu cách và dấu gạch ngang.
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
}

Tải tập sao lục được tạo

Sử dụng phương thức GetCorpusRequest để truy cập Corpus bạn đã tạo ở trên theo phương thức lập trình. Giá trị của tham số name tham chiếu đến tên tài nguyên đầy đủ của Corpus và được đặt trong ô ở trên dưới dạng corpus_resource_name. Định dạng hợp lệ là 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)

Tạo một tài liệu

Corpus có thể chứa tối đa 10.000 Document. Bạn có thể chỉ định một trong các trường sau đây khi xác định tài liệu:

  • name: Tên tài nguyên (mã nhận dạng) Document. Chỉ được chứa tối đa 40 ký tự (chỉ chữ và số hoặc dấu gạch ngang). Mã nhận dạng không được bắt đầu hoặc kết thúc bằng dấu gạch ngang. Nếu tên trống khi tạo, một tên duy nhất sẽ được lấy từ display_name cùng với một hậu tố ngẫu nhiên gồm 12 ký tự.
  • display_name: Tên hiển thị mà con người có thể đọc được. Chỉ được chứa tối đa 512 ký tự, bao gồm cả chữ và số, dấu cách và dấu gạch ngang.

Document cũng hỗ trợ tối đa 20 trường custom_metadata do người dùng chỉ định, được chỉ định làm cặp khoá-giá trị. Siêu dữ liệu tuỳ chỉnh có thể là chuỗi, danh sách chuỗi hoặc dạng số. Lưu ý rằng danh sách chuỗi có thể hỗ trợ tối đa 10 giá trị và giá trị số được biểu thị dưới dạng số dấu phẩy động trong 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)

Tải tài liệu đã tạo

Sử dụng phương thức GetDocumentRequest để truy cập theo phương thức lập trình vào tài liệu bạn đã tạo ở trên. Giá trị của tham số name đề cập đến tên tài nguyên đầy đủ của tài liệu và được đặt trong ô ở trên là document_resource_name. Định dạng hợp lệ là 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)

Nhập và Phân đoạn tài liệu

Để cải thiện mức độ liên quan của nội dung mà cơ sở dữ liệu vectơ trả về trong quá trình truy xuất ngữ nghĩa, hãy chia các tài liệu lớn thành các phần nhỏ hơn hoặc các phần nhỏ trong khi nhập tài liệu.

Chunk là một phần con của Document được xem như một đơn vị độc lập nhằm mục đích biểu diễn và lưu trữ vectơ. Một Chunk có thể có tối đa 2.043 mã thông báo. Corpus có thể có tối đa 1 triệu Chunk.

Tương tự như Document, Chunks cũng hỗ trợ tối đa 20 trường custom_metadata do người dùng chỉ định, được chỉ định làm cặp khoá-giá trị. Siêu dữ liệu tuỳ chỉnh có thể là chuỗi, danh sách chuỗi hoặc dạng số. Lưu ý rằng danh sách chuỗi có thể hỗ trợ tối đa 10 giá trị và giá trị số được biểu thị dưới dạng số dấu phẩy động trong API.

Hướng dẫn này sử dụng htmlChunker nguồn mở của Google.

Bạn có thể sử dụng các phân đoạn khác như LangChain hoặc LlamaIndex.

Nhập HTML và phân đoạn qua htmlChunker

!pip install google-labs-html-chunker

from google_labs_html_chunker.html_chunker import HtmlChunker

from urllib.request import urlopen

Tải DOM HTML cho trang web. Ở đây, HTML được đọc trực tiếp, nhưng nó sẽ tốt hơn là nhận HTML sau kết xuất để bao gồm HTML được chèn JavaScript chẳng hạn như 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")

Chia tài liệu văn bản thành các đoạn văn rồi tạo Chunk từ các đoạn văn này. Bước này sẽ tự tạo các đối tượng Chunk và phần tiếp theo sẽ tải các đối tượng đó lên 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)

Tạo hàng loạt đoạn

Tạo nhiều phần theo lô. Bạn có thể chỉ định tối đa 100 phân đoạn cho mỗi yêu cầu hàng loạt.

Sử dụng CreateChunk() để tạo một đoạn dữ liệu.

# 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)

Ngoài ra, bạn có thể tạo các phân đoạn mà không cần sử dụng 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)

Liệt kê Chunk và nhận trạng thái

Sử dụng phương thức ListChunksRequest để lấy tất cả Chunk hiện có dưới dạng danh sách được phân trang với giới hạn kích thước tối đa là 100 Chunk giây trên mỗi trang, được sắp xếp theo thứ tự tăng dần là Chunk.create_time. Nếu bạn không chỉ định giới hạn, hàm sẽ trả về tối đa 10 Chunk.

Cung cấp next_page_token được trả về trong phản hồi ListChunksRequest làm đối số cho yêu cầu tiếp theo để truy xuất trang tiếp theo. Xin lưu ý rằng khi phân trang, tất cả các tham số khác được cung cấp cho ListChunks phải khớp với lệnh gọi đã cung cấp mã thông báo trang.

Tất cả Chunk đều trả về state. Hãy dùng hàm này để kiểm tra trạng thái của Chunks trước khi truy vấn Corpus. Các trạng thái của Chunk bao gồm – UNSPECIFIED, PENDING_PROCESSING, ACTIVEFAILED. Bạn chỉ có thể truy vấn các 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}')

Nhập tài liệu khác

Thêm một Document khác qua htmlChunker và thêm bộ lọc.

# 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)

Truy vấn tập sao lục

Dùng phương thức QueryCorpusRequest để tìm kiếm theo ngữ nghĩa nhằm lấy các đoạn văn có liên quan.

  • results_count: Chỉ định số lượng đoạn văn cần trả về. Tối đa là 100. Nếu không chỉ định, API sẽ trả về tối đa 10 Chunk.
  • metadata_filters: Lọc theo chunk_metadata hoặc document_metadata. Mỗi MetadataFilter cần tương ứng với một khoá duy nhất. Nhiều đối tượng MetadataFilter được kết hợp với nhau bằng các AND logic. Các điều kiện lọc siêu dữ liệu tương tự được kết hợp bằng các OR logic. Một số ví dụ:
(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} }]
  }]

Xin lưu ý rằng chỉ các giá trị số hỗ trợ "AND" cho cùng một khoá. Chuỗi văn bản chỉ hỗ trợ "OR" cho cùng một khoá.

("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)

Câu trả lời cho câu hỏi được phân bổ

Sử dụng phương thức GenerateAnswer để thực hiện câu trả lời cho câu hỏi có phân bổ trên tài liệu, tập sao lục hoặc một nhóm đoạn văn.

Trả lời câu hỏi được phân bổ (AQA) là việc trả lời các câu hỏi căn cứ trên một bối cảnh cụ thể và đưa ra(các) thông tin ghi nhận sự đóng góp, đồng thời giảm thiểu sự ảo tưởng.

GenerateAnswer có một số ưu điểm so với việc sử dụng một mô hình ngôn ngữ lớn (LLM) chưa được điều chỉnh trong trường hợp muốn có AQA:

  • Mô hình cơ bản đã được huấn luyện để chỉ trả về những câu trả lời dựa trên bối cảnh đã cung cấp.
  • Phần này xác định các thông tin ghi nhận sự đóng góp (các phân đoạn trong bối cảnh được cung cấp đã góp phần tạo nên câu trả lời). Thông tin ghi nhận sự đóng góp cho phép người dùng xác minh câu trả lời.
  • Phương pháp này ước tính answerable_probability cho một cặp câu hỏi (câu hỏi, bối cảnh) nhất định, giúp bạn chuyển hướng hoạt động của sản phẩm tuỳ thuộc vào khả năng câu trả lời được trả về là có căn cứ và chính xác.

answerable_probability và vấn đề "Tôi không biết"

Trong một số trường hợp, câu trả lời tốt nhất cho câu hỏi thực tế lại là "Tôi không biết". Ví dụ: Nếu bối cảnh bạn cung cấp không có câu trả lời cho câu hỏi, thì câu hỏi sẽ được coi là "không trả lời được".

Mô hình AQA rất thành thạo trong việc nhận diện những trường hợp như vậy. Điểm chất lượng thậm chí còn có thể phân biệt giữa mức độ có khả năng trả lời và không thể trả lời.

Tuy nhiên, API GenerateAnswer trao quyền đưa ra quyết định cuối cùng cho bạn bằng cách:

  • Luôn cố gắng trả về một câu trả lời có căn cứ, ngay cả khi khả năng cao là câu trả lời đó ít có cơ sở và chính xác.
  • Trả về giá trị answerable_probability – Ước tính của mô hình về xác suất mà câu trả lời là có căn cứ và chính xác.

answerable_probability thấp có thể do một hoặc nhiều yếu tố sau đây giải thích:

  • Mô hình không tự tin rằng câu trả lời của mình là đúng.
  • Mô hình không tự tin rằng câu trả lời có căn cứ trong các đoạn văn được trích dẫn; Thay vào đó, câu trả lời có thể được lấy từ kiến thức thế giới. Ví dụ: question="1+1=?", passages=["2+2=4”]answer=2, answerable_probability=0.02
  • Mô hình này cung cấp thông tin liên quan không trả lời được đầy đủ câu hỏi. Ví dụ: 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"
  • Không có câu hỏi đúng định dạng nào được đặt ra trong GenerateAnswerRequest.

answerable_probability thấp cho biết rằng GenerateAnswerResponse.answer có thể không chính xác hoặc không có căn cứ, bạn nên tiếp tục xử lý phản hồi bằng cách kiểm tra answerable_probability.

Khi answerable_probability thấp, một số ứng dụng có thể muốn:

  • Hiển thị thông báo về trạng thái "không thể trả lời câu hỏi đó" cho người dùng cuối.
  • Quay lại một mô hình ngôn ngữ lớn (LLM) dùng để giải đáp câu hỏi trong tri thức thế giới. Ngưỡng và tính chất của các tính năng dự phòng đó sẽ tuỳ thuộc vào từng trường hợp sử dụng. Giá trị answerable_probability <= 0,5 là ngưỡng khởi đầu phù hợp.

Mẹo hữu ích về AQA

Để biết thông số kỹ thuật đầy đủ của API, hãy tham khảo Tài liệu tham khảo API GenerateAnswerRequest.

  • Độ dài đoạn thông tin: Bạn nên sử dụng tối đa 300 mã thông báo cho mỗi đoạn văn.
  • Sắp xếp thông điệp:
    • Nếu bạn cung cấp GenerateAnswerRequest.inline_passages, các đoạn văn phải được sắp xếp theo thứ tự giảm dần mức độ liên quan đối với cụm từ tìm kiếm. Nếu vượt quá giới hạn độ dài ngữ cảnh của mô hình, thì các đoạn cuối cùng (ít liên quan nhất) sẽ bị bỏ qua.
    • Nếu bạn cung cấp GenerateAnswerRequest.semantic_retriever, thì hệ thống sẽ tự động sắp xếp mức độ liên quan cho bạn.
  • Hạn chế: Mô hình AQA chuyên biệt cho hoạt động trả lời câu hỏi. Đối với các trường hợp sử dụng khác như viết nội dung sáng tạo, tóm tắt nội dung, v.v., vui lòng gọi một mô hình mục đích chung thông qua GenerateContent.
    • Trò chuyện: Nếu hoạt động trò chuyện của người dùng được xác định là một câu hỏi có thể trả lời được từ một ngữ cảnh nhất định, thì AQA có thể trả lời các truy vấn trò chuyện. Tuy nhiên, nếu hoạt động đầu vào của người dùng có thể là bất kỳ loại mục nhập nào thì mô hình đa năng có thể là lựa chọn phù hợp hơn.
  • Nhiệt độ:
    • Nói chung, nhiệt độ tương đối thấp (~ 0,2) để AQA chính xác.
    • Nếu trường hợp sử dụng của bạn phụ thuộc vào đầu ra xác định, thì hãy đặt nhiệt độ=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)

Tùy chọn khác: AQA sử dụng đoạn nội tuyến

Ngoài ra, bạn có thể sử dụng trực tiếp điểm cuối AQA mà không cần sử dụng Semantic Retriever API bằng cách truyền 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)

Chia sẻ tập sao lục

Bạn có thể chọn chia sẻ tập sao lục với người khác bằng cách sử dụng API CreatePermissionRequest.

Giới hạn:

  • Có 2 vai trò để chia sẻ: READEREDITOR.
    • READER có thể truy vấn tập sao lục.
    • WRITER có quyền của người đọc cũng như có thể chỉnh sửa và chia sẻ tập sao lục.
  • Một tập sao lục có thể được công khai bằng cách cấp cho EVERYONE dưới dạng quyền đọc 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)

Xoá tập sao lục

Sử dụng DeleteCorpusRequest để xoá tập sao lục người dùng cũng như tất cả DocumentChunk giây.

Xin lưu ý rằng tập sao lục không trống sẽ gửi lỗi mà không chỉ định cờ force=True. Nếu bạn đặt force=True, mọi Chunk và đối tượng liên quan đến Document này cũng sẽ bị xoá.

Nếu force=False (mặc định) và Document chứa Chunk bất kỳ, thì lỗi FAILED_PRECONDITION sẽ được trả về.

# 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)

Tóm tắt và đọc thêm

Hướng dẫn này giới thiệu về Trình truy xuất dữ liệu theo ngữ nghĩa cũng như Câu hỏi được phân bổ và Các API trả lời (AQA) của Generative Language API và hướng dẫn cách bạn có thể sử dụng API này để truy xuất thông tin ngữ nghĩa trên dữ liệu văn bản tuỳ chỉnh. Xin lưu ý rằng API này cũng hoạt động với khung dữ liệu LlamaIndex. Hãy tham khảo hướng dẫn này để tìm hiểu thêm.

Ngoài ra, hãy tham khảo tài liệu API để tìm hiểu thêm về các chức năng có sẵn khác.

Phụ lục: Thiết lập OAuth bằng thông tin đăng nhập của người dùng

Hãy làm theo các bước bên dưới trong phần Bắt đầu nhanh OAuth để thiết lập phương thức xác thực OAuth.

  1. Định cấu hình màn hình xin phép bằng OAuth.

  2. Uỷ quyền thông tin đăng nhập cho ứng dụng dành cho máy tính. Để chạy sổ tay này trong Colab, trước tiên, hãy đổi tên tệp thông tin xác thực của bạn (thường là client_secret_*.json) thành chỉ client_secret.json. Sau đó, tải tệp lên bằng cách sử dụng biểu tượng tệp ở thanh bên trái, sau đó chọn biểu tượng tải lên, như trong ảnh chụp màn hình dưới đây.

# 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"

Khởi chạy thư viện ứng dụng rồi chạy lại sổ tay từ phần Tạo một tập sao lục.

import google.ai.generativelanguage as glm

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