前往 ai.google.dev 查看 | 試用 Colab 筆記本 | 在 GitHub 中查看筆記本 |
總覽
大型語言模型 (LLM) 不需要直接訓練模型,就能學習新能力。不過,LLM 向來是「退休」而是針對他們未經訓練的問題提供回覆。部分原因是 LLM 在完成訓練後不知道相關事件。要掌握大型語言模型的回覆來源,也相當困難。為可靠的可擴充式應用程式,LLM 提供的內容必須以事實為依據,並能引用資訊來源。
用於克服這些限制的常見做法稱為「檢索增強生成」(RAG),透過資訊擷取 (IR) 機制從外部知識庫擷取相關資料,藉此擴增傳送至 LLM 的提示資料。知識庫可以是您自有的文件、資料庫或 API 語料庫。
這份筆記本會逐步引導您使用外部文字語料庫來強化 LLM 的知識,並執行語意資訊擷取作業,透過語意擷取器和歸因問題回答問題,生成式語言 API 的回答 (AQA) API。
設定
匯入生成式語言 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:
按照說明文件建立服務帳戶。
- 建立服務帳戶後,請產生服務帳戶金鑰。
依序點選左側欄中的檔案圖示和上傳圖示 (如下方螢幕截圖所示),即可上傳服務帳戶檔案。
- 將上傳的檔案重新命名為
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
資源名稱 (ID)。最多只能包含 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
:Document
資源名稱 (ID)。最多只能包含 40 個半形字元 (只能使用英數字元或破折號)。ID 的開頭或結尾不得為 。如果建立時沒有名稱,系統會從display_name
,以及 12 個字元的隨機後置字串。display_name
:使用者可理解的顯示名稱。長度上限為 512 個半形字元,包括英數字元、空格和破折號。
Document
也支援最多 20 個使用者指定的 custom_metadata
欄位,並以鍵/值組合的形式指定。自訂中繼資料可以是字串、字串清單或數字。請注意,字串清單最多可以支援 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
最多可以有 2043 個符記。Corpus
的 Chunk
上限為 100 萬個。
與 Document
類似,Chunks
也支援最多 20 個使用者指定的 custom_metadata
欄位,並以鍵/值組合的形式指定。自訂中繼資料可以是字串、字串清單或數字。請注意,字串清單最多可以支援 10 個值,而數字值在 API 中會以浮點數表示。
本指南使用 Google 的開放原始碼 HtmlChunker。
其他可用的切塊器包括 LangChain 或 LlamaIndex。
透過 HtmlChunker 擷取 HTML 和區塊
!pip install google-labs-html-chunker
from google_labs_html_chunker.html_chunker import HtmlChunker
from urllib.request import urlopen
取得網站的 HTML DOM。在這個範例中,系統會直接讀取 HTML,但會
HTML 檔案轉譯後,納入使用 JavaScript 插入的 HTML
例如 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
。
提供 ListChunksRequest
回應中傳回的 next_page_token
做為引數,以便擷取下一個網頁。請注意,進行分頁時,提供至 ListChunks
的所有其他參數都必須與提供網頁權杖的呼叫相符。
所有 Chunk
都會傳回 state
。請在查詢 Corpus
前使用這個項目檢查 Chunks
的狀態。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}')
擷取其他文件
透過 HtmlChunker 新增其他 Document
,並新增篩選器。
# 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) 是指根據特定情境回答問題,並提供出處,同時盡量減少幻覺。
在需要 AQA 的情況下,GenerateAnswer
比使用未調整的 LLM 多了幾項優點:
- 基礎模型經過充分訓練,只會傳回奠基於提供情境的答案。
- 可找出歸因 (提供答案的指定情境片段)。作者資訊可讓使用者確認答案。
- 這項工具會針對特定 (問題、背景資訊) 估算
answerable_probability
,進一步協助您根據傳回答案獲得依據性和正確答案的可能性來劃分產品行為。
answerable_probability
和「我不知道」問題
在某些情況下,最佳解答其實是「我不知道」。舉例來說,如果提供的背景資訊不包含題目的答案,就會視為「無法回答」。
AQA 模型擅於識別這類情況。甚至可區分答對度和不答題程度。
不過,GenerateAnswer
API 可以透過以下方式,讓您最終做出決策權:
- 務必嘗試傳回有基準的答案,即使答案較不太可能取得且正確的基準也是如此。
- 傳回值
answerable_probability
- 模型根據基準化和正確答案的可能性預估值。
下列 1 或多項因素都可能造成 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
偏低時,部分客戶可能會想:
- 顯示「無法回答這個問題」的效果訊息供使用者參考
- 改回使用一般用途的大型語言模型,從世界知識回答問題。這類備用的門檻和性質取決於個人用途。若值為
answerable_probability
<= 0.5,是很好的起始門檻。
AQA 實用訣竅
如需完整的 API 規格,請參閱 GenerateAnswerRequest
API 參考資料。
- 票證長度:建議每個段落最多 300 個符記。
- 段落排序:
- 如果提供
GenerateAnswerRequest.inline_passages
,所有段落應依照查詢的關聯性,由高至低排序。如果模型的結構定義長度超過上限,就會省略最後一個 (關聯性最低) 的段落。 - 如果提供「
GenerateAnswerRequest.semantic_retriever
」,系統會自動為您排序關聯性。
- 如果提供
- 限制:AQA 模型專門用於回答問題。如果是廣告素材撰寫、摘要等其他用途,請透過 GenerateContent 呼叫一般用途模型。
- 即時通訊:如果使用者輸入的問題是可在特定情境下回答的問題,品質確保團隊可以回答即時通訊查詢。但如果使用者輸入內容屬於任何類型,那麼一般用途模型可能就更適合。
- 溫度:
- 一般來說,建議使用相對較低的 (約 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)
更多選項:使用內嵌通道進行品質確保
或者,您也可以藉由傳遞 inline_passages
,直接使用 AQA 端點,而不使用 Semantic Retriever API。
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
,與這個 Document
相關的所有 Chunk
和物件也會一併刪除。
如果 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) 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()