Primeiros passos com a recuperação semântica

Ver em ai.google.dev Testar um bloco do Colab Veja o notebook no GitHub

Visão geral

Os modelos de linguagem grandes (LLMs) podem aprender novas habilidades sem serem treinados diretamente nelas. No entanto, os LLMs podem "alucinar" quando precisam responder a perguntas para as quais não foram treinados. Isso ocorre em parte porque os LLMs não sabem dos eventos após o treinamento. Também é muito difícil rastrear as origens das respostas dos LLMs. Para aplicativos confiáveis e escalonáveis, é importante que um LLM forneça respostas baseadas em fatos e cite as fontes de informações.

Uma abordagem comum usada para superar essas restrições é chamada de geração aumentada de recuperação (RAG, na sigla em inglês), que aumenta o comando enviado a um LLM com dados relevantes extraídos de uma base de conhecimento externa por meio de um mecanismo de recuperação de informações (IR). A base de conhecimento pode ser seu próprio conjunto de documentos, bancos de dados ou APIs.

Este notebook orienta você em um fluxo de trabalho para melhorar a resposta de um LLM aumentando o conhecimento dele com corpora de texto externos e realizando a recuperação de informações semânticas para responder a perguntas usando o Semantic Retriever e as APIs Attributed Question & Answering (AQA) da API de linguagem generativa.

Configuração

Importar a API Generative Language

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

Autenticar

A API Semantic Retriever permite realizar pesquisas semânticas nos seus próprios dados. Como são seus dados, isso exige controles de acesso mais rigorosos do que as chaves de API. Use o OAuth com contas de serviço ou usando suas credenciais de usuário.

Este guia de início rápido usa uma abordagem de autenticação simplificada destinada a um ambiente de teste, e as configurações de conta de serviço geralmente são mais fáceis de começar. Para um ambiente de produção, saiba mais sobre autenticação e autorização antes de escolher as credenciais de acesso adequadas para o app.

Configurar o OAuth usando contas de serviço

Siga as etapas abaixo para configurar o OAuth usando contas de serviço:

  1. Ative a API Generative Language.

  1. Crie a conta de serviço seguindo a documentação.

    • Depois de criar a conta de serviço, gere uma chave de conta de serviço.

  1. Faça o upload do arquivo da conta de serviço usando o ícone de arquivo na barra lateral esquerda e, em seguida, o ícone de upload, conforme mostrado na captura de tela abaixo.

    • Renomeie o arquivo enviado para service_account_key.json ou mude a variável service_account_file_name no código abaixo.

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

Inicializar a biblioteca de cliente usando as credenciais da conta de serviço.

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)

Criar um corpus

A API Semantic Retriever permite definir até cinco corpora de texto personalizados por projeto. É possível especificar um dos seguintes campos ao definir seu corpora:

  • name: o nome do recurso Corpus (ID). Precisa ter no máximo 40 caracteres alfanuméricos. Se o name estiver vazio na criação, um nome exclusivo será gerado com um comprimento máximo de 40 caracteres com um prefixo do display_name e um sufixo aleatório de 12 caracteres.
  • display_name: o nome de exibição legível por humanos da Corpus. Precisa ter no máximo 512 caracteres, incluindo alfanuméricos, espaços e traços.
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
}

Acessar o corpus criado

Use o método GetCorpusRequest para acessar programaticamente o Corpus criado acima. O valor do parâmetro name se refere ao nome completo do recurso do Corpus e é definido na célula acima como corpus_resource_name. O formato esperado é 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)

Criar um documento

Um Corpus pode conter até 10.000 Documents. É possível especificar um dos seguintes campos ao definir seus documentos:

  • name: o nome do recurso Document (ID). Precisa conter no máximo 40 caracteres (apenas alfanuméricos ou traços). O ID não pode começar ou terminar com um traço. Se o nome estiver vazio na criação, um nome exclusivo será derivado de display_name com um sufixo aleatório de 12 caracteres.
  • display_name: o nome de exibição legível por humanos. Precisa conter no máximo 512 caracteres, incluindo caracteres alfanuméricos, espaços e traços.

Documents também oferecem suporte a até 20 campos custom_metadata especificados pelo usuário, definidos como pares de chave-valor. Os metadados personalizados podem ser strings, listas de strings ou numéricos. As listas de strings aceitam no máximo 10 valores, e os valores numéricos são representados como números de ponto flutuante na 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)

Receber o documento criado

Use o método GetDocumentRequest para acessar o documento criado acima de forma programática. O valor do parâmetro name se refere ao nome completo do recurso do documento e é definido na célula acima como document_resource_name. O formato esperado é 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)

Ingerir e dividir um documento

Para melhorar a relevância do conteúdo retornado pelo banco de dados vetorial durante a recuperação semântica, divida documentos grandes em partes menores ou blocos durante a ingestão do documento.

Um Chunk é uma subparte de um Document que é tratado como uma unidade independente para fins de representação e armazenamento de vetores. Uma Chunk pode ter no máximo 2.043 tokens. Um Corpus pode ter no máximo um milhão de Chunks.

Assim como Document, Chunks também aceita até 20 campos custom_metadata especificados pelo usuário, especificados como pares de chave-valor. Os metadados personalizados podem ser strings, listas de strings ou numéricos. As listas de strings aceitam no máximo 10 valores, e os valores numéricos são representados como números de ponto flutuante na API.

Este guia usa o HTMLChunker de código aberto do Google.

Outros chunkers que podem ser usados incluem LangChain ou LlamaIndex.

Fazer a transferência de HTML e de fragmentos com o HtmlChunker

!pip install google-labs-html-chunker

from google_labs_html_chunker.html_chunker import HtmlChunker

from urllib.request import urlopen

Receba o DOM HTML de um site. Aqui, o HTML é lido diretamente, mas seria melhor fazer com que a renderização pós-HTML incluísse HTML injetado por JavaScript, como 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")

Divida o documento de texto em passagens e crie Chunks com base nelas. Esta etapa cria os objetos Chunk, e a próxima seção os envia para a API Semantic Retriever.

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

Criar blocos em lote

Crie blocos em lotes. É possível especificar no máximo 100 blocos por solicitação em lote.

Use CreateChunk() para a criação de um único bloco.

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

Como alternativa, você pode criar blocos sem usar o 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)

Lista Chunks e recebe o estado

Use o método ListChunksRequest para receber todos os Chunks disponíveis como uma lista paginada com um limite de tamanho máximo de 100 Chunks por página, classificados em ordem crescente de Chunk.create_time. Se você não especificar um limite, um máximo de 10 Chunks serão retornados.

Forneça o next_page_token retornado na resposta ListChunksRequest como um argumento para a próxima solicitação a fim de recuperar a próxima página. Ao paginar, todos os outros parâmetros fornecidos para ListChunks precisam corresponder à chamada que forneceu o token da página.

Todos os Chunks retornam um state. Use isso para verificar o estado do Chunks antes de consultar um Corpus. Os estados Chunk incluem UNSPECIFIED, PENDING_PROCESSING, ACTIVE e FAILED. Só é possível consultar Chunks 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}')

Ingerir outro documento

Adicione outro Document usando o HTMLChunker e adicione filtros.

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

Consultar o corpus

Use o método QueryCorpusRequest para fazer uma pesquisa semântica e encontrar trechos relevantes.

  • results_count: especifica o número de passagens a serem retornadas. O máximo é 100. Se não for especificado, a API vai retornar no máximo 10 Chunks.
  • metadata_filters: filtre por chunk_metadata ou document_metadata. Cada MetadataFilter precisa corresponder a uma chave exclusiva. Vários objetos MetadataFilter são unidos por ANDs lógicos. Condições de filtro de metadados semelhantes são combinadas por ORs lógicas. Alguns exemplos:
(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} }]
  }]

Apenas valores numéricos aceitam "AND" para a mesma chave. Os valores de string aceitam apenas "OR"s para a mesma chave.

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

Respostas a perguntas atribuídas

Use o método GenerateAnswer para responder a perguntas atribuídas no seu documento, corpus ou conjunto de passagens.

A resposta a perguntas atribuídas (AQA, na sigla em inglês) se refere a responder a perguntas com base em um determinado contexto e fornecer atribuições, minimizando a alucinação.

O GenerateAnswer oferece várias vantagens em relação ao uso de um LLM não ajustado, nos casos em que a AQA é desejada:

  • O modelo subjacente foi treinado para retornar apenas respostas com base no contexto fornecido.
  • Ele identifica atribuições (segmentos do contexto fornecido que contribuíram para a resposta). As atribuições permitem que o usuário verifique a resposta.
  • Ele estima o answerable_probability para um determinado par (pergunta, contexto), o que permite desviar o comportamento do produto dependendo da probabilidade de a resposta retornada ser fundamentada e correta.

answerable_probability e o problema "Não sei"

Em alguns casos, a melhor resposta para a pergunta é "Não sei". Por exemplo, se o contexto fornecido não contém a resposta, a pergunta é considerada "sem resposta".

O modelo AQA é muito eficiente em reconhecer esses casos. Ela pode até distinguir entre graus de capacidade de resposta e incapacidade de responder.

No entanto, a API GenerateAnswer coloca o poder de decisão final nas suas mãos:

  • Sempre tentar retornar uma resposta fundamentada, mesmo quando essa resposta é relativamente improvável de ser fundamentada e correta.
  • Retorno de um valor answerable_probability: a estimativa do modelo da probabilidade de a resposta estar fundamentada e correta.

Um answerable_probability baixo pode ser explicado por um ou mais dos seguintes fatores:

  • O modelo não tem certeza de que a resposta está correta.
  • O modelo não tem certeza de que a resposta está baseada nas passagens citadas. A resposta pode ser derivada do conhecimento de mundo. Por exemplo: question="1+1=?", passages=["2+2=4”]answer=2, answerable_probability=0.02
  • O modelo forneceu informações relevantes que não responderam completamente à pergunta. Exemplo: 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"
  • Nenhuma pergunta bem escrita foi feita no GenerateAnswerRequest.

Como um answerable_probability baixo indica que o GenerateAnswerResponse.answer provavelmente está errado ou não tem base, é altamente recomendável processar a resposta inspecionando answerable_probability.

Quando o answerable_probability estiver baixo, alguns clientes talvez queiram:

  • Mostre uma mensagem informando que não foi possível responder à pergunta ao usuário final.
  • Use um LLM de uso geral que responda à pergunta com base no conhecimento do mundo. O limite e a natureza desses substitutos dependem dos casos de uso individuais. Um valor de answerable_probability <= 0,5 é um bom limite inicial.

Dicas úteis da AQA

Para conferir as especificações completas da API, consulte a Referência da API do GenerateAnswerRequest.

  • Comprimento da passagem: é recomendado até 300 tokens por passagem.
  • Classificação de passagens:
    • Se você informar GenerateAnswerRequest.inline_passages, os trechos serão classificados em ordem decrescente de relevância para a consulta. Se o limite de comprimento do contexto do modelo for excedido, as últimas passagens (menos relevantes) serão omitidas.
    • Se você fornecer GenerateAnswerRequest.semantic_retriever, a classificação por relevância será feita automaticamente.
  • Limitações: o modelo AQA é especializado em responder a perguntas. Para outros casos de uso, como escrita criativa, resumo etc., chame um modelo de uso geral usando o GenerateContent.
    • Chat: se a entrada do usuário for uma pergunta que pode ser respondida em um determinado contexto, o AQA poderá responder às consultas do chat. No entanto, se a entrada do usuário pode ser de qualquer tipo, um modelo de uso geral pode ser uma opção melhor.
  • Temperatura:
    • Geralmente, uma temperatura relativamente baixa (~0,2) é recomendada para uma AQA precisa.
    • Se o caso de uso depender de saídas determinísticas, defina a temperatura=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)

Mais opções: AQA usando passagens inline

Como alternativa, é possível usar o endpoint AQA diretamente, sem usar a API Semantic Retriever, transmitindo 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)

Compartilhar o corpus

Você pode compartilhar o corpus com outras pessoas usando a API CreatePermissionRequest.

Restrições:

  • Há dois papéis para o compartilhamento: READER e EDITOR.
    • Um READER pode consultar o corpus.
    • Um WRITER tem as permissões de leitor e também pode editar e compartilhar o corpus.
  • Um corpus pode ser público concedendo EVERYONE como acesso de leitura 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)

Excluir o corpus

Use DeleteCorpusRequest para excluir um corpus de usuário e todos os Documents e Chunks associados.

O corpora não vazio vai gerar um erro sem especificar uma flag force=True. Se você definir force=True, todos os Chunks e objetos relacionados a esse Document também serão excluídos.

Se force=False (padrão) e Document contiverem Chunks, um erro FAILED_PRECONDITION será retornado.

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

Resumo e leitura complementar

Este guia apresentou as APIs Semantic Retriever e Attributed Question & Answering (AQA) da API Language Generative e mostrou como você pode usá-las para realizar a recuperação de informações semânticas nos seus dados de texto personalizados. Essa API também funciona com o framework de dados LlamaIndex. Consulte o tutorial para saber mais.

Consulte também os documentos da API para saber mais sobre as outras funcionalidades disponíveis.

Apêndice: configurar o OAuth com credenciais de usuário

Siga as etapas abaixo do Guia de início rápido do OAuth para configurar a autenticação OAuth.

  1. Configure a tela de consentimento OAuth.

  2. Autorizar credenciais para um aplicativo para computador. Para executar este notebook no Colab, renomeie o arquivo de credenciais (normalmente client_secret_*.json) para client_secret.json. Em seguida, faça upload do arquivo usando o ícone de arquivo na barra lateral esquerda e o ícone de upload, conforme mostrado na captura de tela abaixo.

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

Inicialize a biblioteca de cliente e execute novamente o notebook, começando em Criar um corpus.

import google.ai.generativelanguage as glm

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