Premiers pas avec la récupération sémantique

Afficher sur ai.google.dev Essayer un notebook Colab Afficher le notebook sur GitHub

Présentation

Les grands modèles de langage (LLM, Large Language Model) peuvent apprendre de nouvelles capacités sans y être directement entraînés. Cependant, les LLM "hallucinent" lorsqu’ils sont chargés de répondre à des questions sur lesquelles ils n’ont pas été formés. Cela est en partie dû au fait que les LLM ne tiennent pas compte des événements après l'entraînement. Il est également très difficile de tracer les sources à partir desquelles les LLM extraient leurs réponses. Pour des applications fiables et évolutives, il est important qu'un LLM fournisse des réponses fondées sur des faits et puisse citer ses sources d'informations.

Une approche courante utilisée pour surmonter ces contraintes est la génération augmentée de récupération (RAG, Retrieval Augmented Generation), qui étend la requête envoyée à un LLM avec des données pertinentes extraites d'une base de connaissances externe grâce à un mécanisme de récupération d'informations (IR). Elle peut être constituée de vos propres corpus de documents, de bases de données ou d'API.

Ce notebook vous guide tout au long d'un workflow permettant d'améliorer la réponse d'un LLM en renforçant ses connaissances avec des corpus textuels externes et en effectuant des récupérations d'informations sémantiques pour répondre à des questions à l'aide du récupérateur sémantique et de la question et de l'attribut API Answering (AQA) de l'API Generative Language.

Configuration

Importer l'API Generative Language

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

Authentifier

L'API Semantic Retriever vous permet d'effectuer une recherche sémantique sur vos propres données. Étant donné qu'il s'agit de vos données, des contrôles d'accès plus stricts sont nécessaires que les clés API. Authentifiez-vous avec OAuth via des comptes de service ou vos identifiants utilisateur.

Ce guide de démarrage rapide utilise une approche d'authentification simplifiée destinée à un environnement de test. Les configurations de compte de service sont généralement plus faciles à démarrer. Pour un environnement de production, découvrez l'authentification et l'autorisation avant de choisir les identifiants d'accès adaptés à votre application.

Configurer OAuth à l'aide de comptes de service

Suivez les étapes ci-dessous pour configurer OAuth à l'aide de comptes de service:

  1. Activez l'API Generative Language.

  1. Créez le compte de service en suivant les instructions de la documentation.

    • Après avoir créé le compte de service, générez une clé de compte de service.

  1. Importez le fichier de votre compte de service en cliquant sur l'icône de fichier dans la barre latérale gauche, puis sur l'icône d'importation, comme illustré dans la capture d'écran ci-dessous.

    • Renommez le fichier importé en service_account_key.json ou modifiez la variable service_account_file_name dans le code ci-dessous.

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

Initialisez la bibliothèque cliente à l'aide des identifiants du compte de service.

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)

Créer un corpus

L'API Semantic Retriever vous permet de définir jusqu'à cinq corpus de texte personnalisés par projet. Vous pouvez spécifier l'un des champs suivants lorsque vous définissez vos corpus:

  • name: nom de la ressource (ID) Corpus. Ne doit pas dépasser 40 caractères alphanumériques. Si le champ name est vide lors de la création, un nom unique est généré, d'une longueur maximale de 40 caractères, avec un préfixe issu de display_name et un suffixe aléatoire de 12 caractères.
  • display_name: nom lisible à afficher de Corpus. Le nom ne doit pas comporter plus de 512 caractères, y compris les caractères alphanumériques, les espaces et les tirets.
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
}

Obtenir le corpus créé

Utilisez la méthode GetCorpusRequest pour accéder par programmation au Corpus que vous avez créé ci-dessus. La valeur du paramètre name fait référence au nom complet de la ressource Corpus et est définie sur corpus_resource_name dans la cellule ci-dessus. Le format attendu est 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)

Créer un document

Un Corpus peut contenir jusqu'à 10 000 éléments Document. Vous pouvez spécifier l'un des champs suivants lors de la définition de vos documents:

  • name: nom de la ressource (ID) Document. Ne doit pas dépasser 40 caractères (caractères alphanumériques ou tirets uniquement). L'ID ne peut pas commencer ni se terminer par tiret. Si le nom est vide lors de la création, un nom unique sera dérivé de display_name ainsi qu'un suffixe aléatoire de 12 caractères.
  • display_name: nom lisible à afficher. Le nom ne doit pas comporter plus de 512 caractères, y compris les caractères alphanumériques, les espaces et les tirets.

Les Document acceptent également jusqu'à 20 champs custom_metadata spécifiés par l'utilisateur, spécifiés sous forme de paires clé/valeur. Les métadonnées personnalisées peuvent être des chaînes, des listes de chaînes ou des valeurs numériques. Notez que les listes de chaînes peuvent accepter jusqu'à 10 valeurs et que les valeurs numériques sont représentées par des nombres à virgule flottante dans l'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)

Obtenir le document créé

Utilisez la méthode GetDocumentRequest pour accéder par programmation au document que vous avez créé ci-dessus. La valeur du paramètre name fait référence au nom complet de la ressource du document et est définie dans la cellule ci-dessus en tant que document_resource_name. Le format attendu est 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)

Ingestion et Fragmenter un document

Pour améliorer la pertinence du contenu renvoyé par la base de données vectorielle lors de la récupération sémantique, décomposez les documents volumineux en fragments plus petits ou morceaux lors de l'ingestion du document.

Un Chunk est une sous-partie d'une Document traitée comme une unité indépendante à des fins de représentation vectorielle et de stockage. Un Chunk ne peut pas comporter plus de 2 043 jetons. Un élément Corpus ne peut pas comporter plus d'un million d'instances Chunk.

Comme pour les Document, Chunks accepte également jusqu'à 20 champs custom_metadata spécifiés par l'utilisateur, spécifiés sous forme de paires clé/valeur. Les métadonnées personnalisées peuvent être des chaînes, des listes de chaînes ou des valeurs numériques. Notez que les listes de chaînes peuvent accepter jusqu'à 10 valeurs et que les valeurs numériques sont représentées par des nombres à virgule flottante dans l'API.

Ce guide utilise l'outil Open Source HTMLChunker de Google.

Vous pouvez également utiliser LangChain ou LlamaIndex.

Ingérer du code HTML et un bloc via HTMLChunker

!pip install google-labs-html-chunker

from google_labs_html_chunker.html_chunker import HtmlChunker

from urllib.request import urlopen

Obtenir le DOM HTML pour un site Web Ici, le code HTML est lu directement, mais il Mieux vaut inclure du code HTML injecté en JavaScript dans la fonction HTML post-rendu comme 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")

Divisez le document texte en plusieurs passages et créez des Chunk à partir de ces passages. Cette étape permet de créer les objets Chunk eux-mêmes. La section suivante les importe dans l'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)

Créer des fragments par lot

Créez des fragments par lots. Vous pouvez spécifier un maximum de 100 segments par requête de lot.

Utilisez CreateChunk() pour créer un seul fragment.

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

Vous pouvez également créer des fragments sans utiliser 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)

Répertorier les éléments Chunk et obtenir l'état

Utilisez la méthode ListChunksRequest pour obtenir toutes les Chunk disponibles sous forme de liste paginée avec une limite maximale de 100 Chunk par page, triées par ordre croissant de Chunk.create_time. Si vous ne spécifiez pas de limite, 10 Chunk au maximum sont renvoyés.

Fournissez le next_page_token renvoyé dans la réponse ListChunksRequest en tant qu'argument à la requête suivante pour récupérer la page suivante. Notez que lors de la pagination, tous les autres paramètres fournis à ListChunks doivent correspondre à l'appel qui a fourni le jeton de page.

Toutes les Chunk renvoient un state. Utilisez-le pour vérifier l'état de Chunks avant d'interroger un Corpus. Les états de Chunk incluent UNSPECIFIED, PENDING_PROCESSING, ACTIVE et FAILED. Vous ne pouvez interroger que ACTIVE instances 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}')

Ingérer un autre document

Ajoutez un autre élément Document via HTMLChunker, ainsi que des filtres.

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

Interroger le corpus

Utilisez la méthode QueryCorpusRequest pour effectuer une recherche sémantique et obtenir des passages pertinents.

  • results_count: spécifiez le nombre de passages à renvoyer. La valeur maximale est 100. Si aucune valeur n'est spécifiée, l'API renvoie un maximum de 10 valeurs Chunk.
  • metadata_filters: filtrer par chunk_metadata ou document_metadata. Chaque MetadataFilter doit correspondre à une clé unique. Plusieurs objets MetadataFilter sont joints par des AND logiques. Les conditions de filtre de métadonnées similaires sont jointes par des OR logiques. Voici quelques exemples :
(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} }]
  }]

Notez que seules les valeurs numériques sont compatibles avec l'opérateur "AND" pour la même clé. Chaîne Les valeurs ne sont compatibles qu'avec des "OR" pour la même clé.

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

Système de questions-réponses attribuée

Utilisez la méthode GenerateAnswer pour effectuer une réponse aux questions attribuées sur votre document, votre corpus ou un ensemble de passages.

L'attribution de réponses aux questions (AQA) consiste à répondre à des questions fondées sur un contexte donné et à fournir des mentions, tout en minimisant les hallucinations.

GenerateAnswer offre plusieurs avantages par rapport à l'utilisation d'un LLM non réglé, dans les cas où l'AQA est souhaité:

  • Le modèle sous-jacent a été entraîné pour ne renvoyer que des réponses basées sur le contexte fourni.
  • Il identifie les attributions (segments du contexte fourni qui ont contribué à la réponse). Les attributions permettent à l'utilisateur de vérifier la réponse.
  • Il estime le answerable_probability pour une paire donnée (question, contexte), ce qui vous permet de détourner le comportement du produit en fonction de la probabilité que la réponse renvoyée soit fondée et correcte.

answerable_probability et le problème "Je ne sais pas"

Dans certains cas, la meilleure réponse à la question est de faire « Je ne sais pas ». Par exemple, si le contexte fourni ne contient pas la réponse à la question, celle-ci est considérée comme étant « sans réponse ».

Le modèle AQA est très efficace pour reconnaître de tels cas. Elle peut même faire la distinction entre les degrés de réponse et d'absence de réponse.

Cependant, l'API GenerateAnswer vous permet de prendre la décision finale en:

  • Tentez toujours de renvoyer une réponse fondée sur le terrain, même lorsqu'il est relativement peu probable qu'elle soit fondée et correcte.
  • Renvoi d'une valeur answerable_probability : estimation de la probabilité que la réponse soit fondée et correcte.

Un answerable_probability faible peut s'expliquer par un ou plusieurs des facteurs suivants:

  • Le modèle n'est pas certain que sa réponse soit correcte.
  • Le modèle n'est pas certain que sa réponse se fonde sur les passages cités. La réponse vient peut-être plutôt de la connaissance du monde. Par exemple: question="1+1=?", passages=["2+2=4”]answer=2, answerable_probability=0.02
  • Le modèle a fourni des informations pertinentes qui n'ont pas complètement répondu à la question. Exemple: 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"
  • Aucune question bien formulée n'a été posée dans GenerateAnswerRequest.

Étant donné qu'une valeur answerable_probability faible indique que "GenerateAnswerResponse.answer" est probablement incorrect ou non ancré, nous vous recommandons vivement de traiter la réponse plus en détail en inspectant answerable_probability.

Lorsque la valeur de answerable_probability est faible, certains clients peuvent souhaiter:

  • Afficher le message "Impossible de répondre à cette question" à l'utilisateur final.
  • Reposez-vous sur un LLM à usage général qui répond à la question à partir de la connaissance du monde. Le seuil et la nature de ces alternatives dépendent des cas d'utilisation individuels. Une valeur answerable_probability <= 0,5 constitue un bon seuil de départ.

Conseils utiles pour l'AQA

Pour connaître toutes les spécifications de l'API, consultez la documentation de référence de l'API GenerateAnswerRequest.

  • Longueur du passage: jusqu'à 300 jetons par passage sont recommandés.
  • Tri des passages: <ph type="x-smartling-placeholder">
      </ph>
    • Si vous fournissez GenerateAnswerRequest.inline_passages, les passages doivent être triés par ordre décroissant de pertinence par rapport à la requête. Si la limite de longueur de contexte du modèle est dépassée, les derniers passages (les moins pertinents) sont omis.
    • Si vous fournissez GenerateAnswerRequest.semantic_retriever, le tri en fonction de la pertinence est effectué automatiquement.
  • Limites: le modèle AQA est spécialisé dans la réponse à des questions. Pour les autres cas d'utilisation tels que l'écriture créative, la synthèse, etc., veuillez appeler un modèle à usage général via GenerateContent.
    • Chat: s'il s'agit d'une question à laquelle l'utilisateur peut répondre dans un contexte donné, l'AQA peut répondre aux questions de chat. Toutefois, si l'entrée utilisateur peut être de n'importe quel type, un modèle à usage général peut être un meilleur choix.
  • Température: <ph type="x-smartling-placeholder">
      </ph>
    • En règle générale, une température relativement faible (environ 0,2) est recommandée pour une AQA précise.
    • Si votre cas d'utilisation repose sur des sorties déterministes, définissez la température sur "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)

Autres options: AQA avec des passages intégrés

Vous pouvez également utiliser directement le point de terminaison AQA, sans utiliser l'API Semantic Retriever, en transmettant 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)

Partager le corpus

Vous pouvez choisir de partager le corpus avec d'autres personnes à l'aide de l'API CreatePermissionRequest.

Contraintes:

  • Il existe deux rôles pour le partage: READER et EDITOR.
    • Un READER peut interroger le corpus.
    • Un WRITER dispose des autorisations du lecteur et peut en outre modifier et partager le corpus.
  • Un corpus peut être public en accordant à EVERYONE un accès en lecture 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)

Supprimer le corpus

Utilisez DeleteCorpusRequest pour supprimer un corpus d'utilisateurs et tous les Document associés et Chunk s

Notez que les corpus non vides génèrent une erreur sans spécifier d'indicateur force=True. Si vous définissez force=True, tous les Chunk et tous les objets associés à cette Document seront également supprimés.

Si force=False (valeur par défaut) et que Document contient des Chunk, une erreur FAILED_PRECONDITION est renvoyée.

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

Résumé et autres documents

Ce guide a présenté le récupérateur sémantique et les questions/réponses attribuées de l'API de langage génératif, et comment les utiliser pour récupérer des informations sémantiques sur vos données textuelles personnalisées. Notez que cette API fonctionne également avec le framework de données LlamaIndex. Pour en savoir plus, consultez le tutoriel.

Reportez-vous également à la documentation de l'API pour en savoir plus sur les autres fonctionnalités disponibles.

Annexe: Configurer OAuth avec des identifiants utilisateur

Suivez les étapes du guide de démarrage rapide OAuth ci-dessous pour configurer l'authentification OAuth.

  1. Configurer l'écran de consentement OAuth

  2. Autoriser des identifiants pour une application de bureau Pour exécuter ce notebook dans Colab, renommez d'abord votre fichier d'identifiants (généralement client_secret_*.json) en client_secret.json. Importez ensuite le fichier en cliquant sur l'icône de fichier dans la barre latérale gauche, puis sur l'icône d'importation, comme illustré dans la capture d'écran ci-dessous.

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

Initialisez la bibliothèque cliente, puis exécutez à nouveau le notebook en commençant par Créer un corpus.

import google.ai.generativelanguage as glm

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