Comienza a usar la recuperación semántica

Ver en ai.google.dev Prueba un notebook de Colab Ver notebook en GitHub

Descripción general

Los modelos grandes de lenguaje (LLM) pueden aprender nuevas habilidades sin que se les entrene directamente. Sin embargo, se sabe que los LLM "alucinan" cuando se les asigna la tarea de proporcionar respuestas a preguntas con las que no han sido entrenados. Esto se debe, en parte, a que los LLMs no están al tanto de los eventos después del entrenamiento. También es muy difícil rastrear las fuentes de las que los LLM extraen sus respuestas. Para aplicaciones confiables y escalables, es importante que un LLM proporcione respuestas basadas en hechos y que pueda citar sus fuentes de información.

Un enfoque común que se usa para superar estas restricciones es el de generación de aumento de recuperación (RAG), que aumenta la instrucción enviada a un LLM con datos relevantes recuperados de una base de conocimiento externa a través de un mecanismo de recuperación de información (IR). La base de conocimiento puede ser tu propio corpus de documentos, bases de datos o APIs.

Este notebook te guía a través de un flujo de trabajo para mejorar la respuesta de un LLM aumentando su conocimiento con corpus de texto externo y realizando la recuperación semántica de información para responder preguntas con Semantic Retriever y las APIs de Attributed Question & Answering (AQA) de la API de Generative Language.

Configuración

Importa la API de Generative Language

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

Autenticar

La API de Semantic Retriever te permite realizar búsquedas semánticas en tus propios datos. Dado que son tus datos, se necesitan controles de acceso más estrictos que las claves de API. Realiza la autenticación con OAuth con cuentas de servicio o a través de tus credenciales de usuario.

En esta guía de inicio rápido, se usa un enfoque de autenticación simplificado para un entorno de pruebas, y las configuraciones de cuentas de servicio suelen ser más fáciles de comenzar. En el caso de un entorno de producción, obtén información sobre la autenticación y la autorización antes de elegir las credenciales de acceso adecuadas para tu app.

Cómo configurar OAuth con cuentas de servicio

Sigue estos pasos para configurar OAuth con cuentas de servicio:

  1. Habilita la API de Generative Language.

  1. Sigue la documentación para crear la cuenta de servicio.

    • Después de crear la cuenta de servicio, genera una clave de cuenta de servicio.

  1. Para subir el archivo de la cuenta de servicio, usa el ícono de archivo en la barra lateral izquierda y, luego, el ícono de carga, como se muestra en la siguiente captura de pantalla.

    • Cambia el nombre del archivo subido a service_account_key.json o cambia la variable service_account_file_name en el siguiente código.

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

Inicializa la biblioteca cliente con las credenciales de la cuenta de servicio.

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)

Crea un corpus

La API de Semantic Retriever te permite definir hasta 5 corpus de texto personalizados por proyecto. Puedes especificar cualquiera de los siguientes campos cuando definas tus corpus:

  • name: Es el nombre (ID) del recurso Corpus. Solo debe contener un máximo de 40 caracteres alfanuméricos. Si el name está vacío durante la creación, se generará un nombre único con una longitud máxima de 40 caracteres con un prefijo de display_name y un sufijo aleatorio de 12 caracteres.
  • display_name: Es el nombre visible legible por humanos para Corpus. Solo debe contener un máximo de 512 caracteres, incluidos caracteres alfanuméricos, espacios y guiones.
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
}

Obtén el corpus creado

Usa el método GetCorpusRequest para acceder de manera programática al elemento Corpus que creaste antes. El valor del parámetro name hace referencia al nombre de recurso completo de Corpus y se establece en la celda anterior como corpus_resource_name. El formato esperado es 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)

Crea un documento

Un Corpus puede contener hasta 10,000 Document. Puedes especificar cualquiera de los siguientes campos cuando definas tus documentos:

  • name: Es el nombre (ID) del recurso Document. Debe contener solo un máximo de 40 caracteres (solo alfanuméricos o guiones). El ID no puede comenzar ni terminar con un guion. Si el nombre está vacío en el momento de la creación, se derivará un nombre único de display_name junto con un sufijo aleatorio de 12 caracteres.
  • display_name: Es el nombre visible legible por humanos. Solo debe contener un máximo de 512 caracteres, incluidos caracteres alfanuméricos, espacios y guiones.

Los elementos Document también admiten hasta 20 campos custom_metadata especificados por el usuario, especificados como pares clave-valor. Los metadatos personalizados pueden ser cadenas, listas de cadenas o valores numéricos. Ten en cuenta que las listas de cadenas pueden admitir un máximo de 10 valores, y los valores numéricos se representan como números de punto flotante en la 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)

Obtén el documento creado

Usa el método GetDocumentRequest para acceder de forma programática al documento que creaste anteriormente. El valor del parámetro name hace referencia al nombre de recurso completo del documento y se establece en la celda anterior como document_resource_name. El formato esperado es 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)

Cómo transferir y dividir un documento

Para mejorar la relevancia del contenido que muestra la base de datos de vectores durante la recuperación semántica, divide los documentos grandes en partes o fragmentos más pequeños mientras los transfieres.

Un Chunk es una subparte de un Document que se trata como una unidad independiente para fines de representación y almacenamiento de vectores. Un Chunk puede tener un máximo de 2,043 tokens. Un Corpus puede tener un máximo de 1 millón de Chunk.

Al igual que los Document, Chunks también admite hasta 20 campos custom_metadata especificados por el usuario, que se especifican como pares clave-valor. Los metadatos personalizados pueden ser cadenas, listas de cadenas o valores numéricos. Ten en cuenta que las listas de cadenas pueden admitir un máximo de 10 valores y los valores numéricos se representan como números de punto flotante en la API.

En esta guía, se usa HtmlChunker de código abierto de Google.

Otros segmentadores que puedes usar son LangChain o LlamaIndex.

Transferir HTML y fragmentos a través de HtmlChunker

!pip install google-labs-html-chunker

from google_labs_html_chunker.html_chunker import HtmlChunker

from urllib.request import urlopen

Obtén el DOM HTML de un sitio web. Aquí, el código HTML se lee directamente, pero sería mejor que la renderización posterior de HTML incluya HTML insertado en 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")

Divide el documento de texto en pasajes y crea Chunk a partir de ellos. En este paso, se crean los objetos Chunk y, en la siguiente sección, se suben a la API de 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)

Crea fragmentos por lotes

Crea fragmentos por lotes. Puedes especificar un máximo de 100 fragmentos por solicitud por lotes.

Usa CreateChunk() para crear un solo fragmento.

# 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, puedes crear fragmentos sin usar 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)

Genera una lista de Chunk y obtén el estado

Usa el método ListChunksRequest para obtener todos los Chunk disponibles como una lista paginada con un límite de tamaño máximo de 100 Chunk por página, ordenados de forma ascendente por Chunk.create_time. Si no especificas un límite, se devuelven un máximo de 10 Chunk.

Proporciona el next_page_token que se muestra en la respuesta ListChunksRequest como argumento para la siguiente solicitud para recuperar la siguiente página. Ten en cuenta que, cuando se realiza la paginación, todos los demás parámetros proporcionados a ListChunks deben coincidir con la llamada que proporcionó el token de página.

Todos los Chunk muestran un state. Úsalo para verificar el estado de Chunks antes de consultar un Corpus. Los estados Chunk incluyen UNSPECIFIED, PENDING_PROCESSING, ACTIVE y FAILED. Solo puedes consultar ACTIVE Chunks.

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

Cómo transferir otro documento

Agrega otro Document a través de HtmlChunker y agrega 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)

Cómo consultar el corpus

Usa el método QueryCorpusRequest para realizar una búsqueda semántica y obtener pasajes relevantes.

  • results_count: Especifica la cantidad de pasajes que se mostrarán. El máximo es 100. Si no se especifica, la API muestra un máximo de 10 Chunk.
  • metadata_filters: Filtra por chunk_metadata o document_metadata. Cada MetadataFilter debe corresponder a una clave única. Varios objetos MetadataFilter se unen con AND lógicos. Las condiciones de filtro de metadatos similares se unen con OR lógicos. Estos son algunos ejemplos:
(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} }]
  }]

Ten en cuenta que solo los valores numéricos admiten “AND” para la misma clave. Los valores de cadena solo admiten "O" para la misma clave.

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

Búsqueda de respuestas atribuidas

Usa el método GenerateAnswer para ejecutar preguntas atribuidas en tu documento, corpus o un conjunto de pasajes.

La respuesta a preguntas atribuidas (AQA) se refiere a responder preguntas basadas en un contexto determinado y proporcionar atribuciones, a la vez que se minimiza la alucinación.

GenerateAnswer ofrece varias ventajas en comparación con el uso de un LLM no ajustado, en los casos en que se desee la AQA:

  • El modelo subyacente se entrenó para mostrar solo respuestas basadas en el contexto proporcionado.
  • Identifica las atribuciones (segmentos del contexto proporcionado que contribuyeron a la respuesta). Las atribuciones permiten que el usuario verifique la respuesta.
  • Calcula la answerable_probability para un par determinado (pregunta, contexto), lo que te permite desviar el comportamiento del producto según la probabilidad de que la respuesta que se muestra esté fundamentada y sea correcta.

answerable_probability y el problema "No lo sé"

En algunos casos, la mejor respuesta a la pregunta es "No lo sé". Por ejemplo, si el contexto proporcionado no contiene la respuesta a la pregunta, se considera que la pregunta no se puede responder.

El modelo de AQA es muy hábil para reconocer esos casos. Incluso puede distinguir entre grados de capacidad de respuesta y no respuesta.

Sin embargo, la API de GenerateAnswer pone en tus manos el poder final de la toma de decisiones de la siguiente manera:

  • Siempre intentas proporcionar una respuesta fundamentada, incluso cuando es poco probable que sea correcta.
  • Devuelve un valor answerable_probability: La estimación del modelo de la probabilidad de que la respuesta sea fundamentada y correcta.

Un answerable_probability bajo puede explicarse por 1 o más de los siguientes factores:

  • El modelo no está seguro de que su respuesta sea correcta.
  • El modelo no está seguro de que su respuesta se base en los pasajes citados; la respuesta puede provenir del conocimiento general. Por ejemplo: question="1+1=?", passages=["2+2=4”]answer=2, answerable_probability=0.02
  • El modelo proporcionó información relevante que no respondió completamente la pregunta. Ejemplo: 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"
  • No se hizo ninguna pregunta bien formada en GenerateAnswerRequest.

Dado que un answerable_probability bajo indica que GenerateAnswerResponse.answer probablemente sea incorrecto o no tenga base, se recomienda que se siga procesando la respuesta mediante la inspección de answerable_probability.

Cuando answerable_probability es bajo, es posible que algunos clientes deseen hacer lo siguiente:

  • Muestra un mensaje al usuario final que diga "No se pudo responder esa pregunta".
  • Recurre a un LLM de propósito general que responda la pregunta a partir del conocimiento del mundo. El umbral y la naturaleza de esos resguardos dependerán de casos de uso individuales. Un valor de answerable_probability <= 0.5 es un buen umbral inicial.

Sugerencias útiles de AQA

Para obtener las especificaciones completas de la API, consulta la Referencia de la API de GenerateAnswerRequest.

  • Longitud del pasaje: Se recomiendan hasta 300 tokens por pasaje.
  • Orden de pasajes:
  • Limitaciones: El modelo de AQA se especializa en responder preguntas. Para otros casos de uso, como la escritura creativa, la generación de resúmenes, etc., llama a un modelo de uso general a través de GenerateContent.
    • Chat: Si se sabe que la entrada del usuario es una pregunta que se puede responder desde un contexto determinado, la AQA puede responder las consultas por chat. Sin embargo, si la entrada del usuario puede ser de cualquier tipo, un modelo de uso general puede ser una mejor opción.
  • Temperatura:
    • Por lo general, se recomienda una temperatura relativamente baja (~0.2) para obtener una AQA precisa.
    • Si tu caso de uso se basa en resultados deterministas, establece temperature=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)

Más opciones: AQA con pasajes intercalados

Como alternativa, puedes usar el extremo de AQA directamente, sin usar la API de Semantic Retriever, pasando 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)

Compartir el corpus

Puedes compartir el corpus con otras personas mediante la API de CreatePermissionRequest.

Restricciones:

  • Existen 2 roles para compartir: READER y EDITOR.
    • Un READER puede consultar el corpus.
    • Un WRITER tiene los permisos de lector y, además, puede editar y compartir el corpus.
  • Para que un corpus sea público, se debe otorgar EVERYONE como acceso de lectura de user_type.
# Replace [email protected] with the email added as a test user in the OAuth Quickstart
shared_user_email = "[email protected]" #  @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)

Borra el corpus

Usa DeleteCorpusRequest para borrar un corpus de usuarios y todos los Document y Chunk asociados.

Ten en cuenta que los corpus no vacíos arrojarán un error sin especificar una marca force=True. Si configuras force=True, también se borrarán los Chunk y los objetos relacionados con este Document.

Si force=False (el valor predeterminado) y Document contienen Chunk, se mostrará un error 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)

Resumen y lecturas adicionales

En esta guía, se presentaron las APIs de Semantic Retriever y Attributed Question & Answering (AQA) de la API de Generative Language y se mostró cómo puedes usarlas para realizar la recuperación de información semántica en tus datos de texto personalizados. Ten en cuenta que esta API también funciona con el framework de datos de LlamaIndex. Consulta el instructivo para obtener más información.

Consulta también los documentos de la API para obtener más información sobre las otras funciones disponibles.

Apéndice: Configura OAuth con credenciales del usuario

Sigue los pasos que se indican a continuación en la Guía de inicio rápido de OAuth para configurar la autenticación de OAuth.

  1. Configura la pantalla de consentimiento de OAuth.

  2. Autoriza credenciales para una aplicación de escritorio. Para ejecutar este notebook en Colab, primero cambia el nombre del archivo de credenciales (generalmente client_secret_*.json) a client_secret.json. Luego, sube el archivo con el ícono de archivo en la barra lateral izquierda y, luego, con el ícono de carga, como se muestra en la siguiente captura de pantalla.

# Replace TODO-your-project-name with the project used in the OAuth Quickstart
project_name = "TODO-your-project-name" #  @param {type:"string"}
# Replace [email protected] with the email added as a test user in the OAuth Quickstart
email = "[email protected]" #  @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"

Inicializa la biblioteca cliente y vuelve a ejecutar el notebook desde Crea un corpus.

import google.ai.generativelanguage as glm

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