Auf ai.google.dev ansehen | Colab-Notebook testen | Notebook auf GitHub ansehen |
Übersicht
Large Language Models (LLMs) können neue Fähigkeiten erlernen, ohne sie direkt damit trainiert zu werden. Es ist jedoch bekannt, dass LLMs „halluzinieren“ wenn sie damit beauftragt wurden, Fragen zu beantworten, für die sie nicht geschult wurden. Das liegt unter anderem daran, dass LLMs nach dem Training keine Ahnung von Ereignissen haben. Außerdem ist es sehr schwierig, die Quellen zu verfolgen, aus denen LLMs ihre Antworten beziehen. Für zuverlässige, skalierbare Anwendungen ist es wichtig, dass ein LLM auf Fakten basierte Antworten gibt und in der Lage ist, seine Informationsquellen zu zitieren.
Ein gängiger Ansatz zur Überwindung dieser Einschränkungen ist Retrieval Augmented Generation (RAG). Dabei wird der an ein LLM gesendete Prompt mit relevanten Daten erweitert, die über einen Informationsabrufmechanismus (Information Retrieval, IR) aus einer externen Wissensdatenbank abgerufen wurden. Die Wissensdatenbank kann Ihre eigene Korpora von Dokumenten, Datenbanken oder APIs sein.
Dieses Notebook führt Sie durch einen Workflow zur Verbesserung der Reaktion eines LLM, indem sein Wissen mit externen Textkorpora erweitert und semantische Informationen abgerufen werden, um Fragen mit dem Semantic Retriever und den zugeordneten Fragen zu beantworten. Answering (AQA) APIs der Generative Language API
Einrichtung
Generative Language API importieren
# Install the Client library (Semantic Retriever is only supported for versions >0.4.0)
pip install -U google.ai.generativelanguage
Authentifizieren
Mit der Semantic Retriever API können Sie eine semantische Suche für Ihre eigenen Daten ausführen. Da es sich um Ihre Daten handelt, sind dafür strengere Zugriffssteuerungen als für API-Schlüssel erforderlich. Authentifizieren Sie sich mit OAuth über Dienstkonten oder über Ihre Nutzeranmeldedaten.
In dieser Kurzanleitung wird ein vereinfachter Authentifizierungsansatz für eine Testumgebung verwendet. Die Einrichtung von Dienstkonten ist in der Regel einfacher. Für eine Produktionsumgebung sollten Sie sich über die Authentifizierung und Autorisierung informieren, bevor Sie die für Ihre Anwendung geeigneten Anmeldedaten auswählen.
OAuth mit Dienstkonten einrichten
Führen Sie die folgenden Schritte aus, um OAuth mithilfe von Dienstkonten einzurichten:
- Aktivieren Sie die Generative Language API.
Erstellen Sie das Dienstkonto gemäß der Dokumentation.
- Generieren Sie nach dem Erstellen des Dienstkontos einen Dienstkontoschlüssel.
Laden Sie Ihre Dienstkontodatei hoch, indem Sie auf das Dateisymbol in der linken Seitenleiste und dann auf das Uploadsymbol klicken, wie im Screenshot unten dargestellt.
- Benennen Sie die hochgeladene Datei in
service_account_key.json
um oder ändern Sie die Variableservice_account_file_name
im Code unten.
- Benennen Sie die hochgeladene Datei in
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'])
Initialisieren Sie die Clientbibliothek mit den Anmeldedaten des Dienstkontos.
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)
Korpus erstellen
Mit der Semantic Retriever API können Sie bis zu fünf benutzerdefinierte Textkorpora pro Projekt definieren. Sie können beim Definieren Ihrer Korpora eines der folgenden Felder angeben:
name
: Der Ressourcenname (ID) vonCorpus
. Darf maximal 40 alphanumerische Zeichen enthalten. Wennname
bei der Erstellung leer ist, wird ein eindeutiger Name mit einer maximalen Länge von 40 Zeichen mit einem Präfix ausdisplay_name
und einem zufälligen Suffix mit 12 Zeichen generiert.display_name
: Der visuell lesbare Anzeigename für dieCorpus
. Darf höchstens 512 Zeichen enthalten, einschließlich alphanumerischer Zeichen, Leerzeichen und Bindestriche.
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 }
Erstellten Korpus abrufen
Verwenden Sie die Methode GetCorpusRequest
, um programmatisch auf die oben erstellte Corpus
zuzugreifen. Der Wert des Parameters name
bezieht sich auf den vollständigen Ressourcennamen der Corpus
und wird in der Zelle darüber als corpus_resource_name
festgelegt. Das erwartete Format ist 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)
Dokument erstellen
Ein Corpus
kann bis zu 10.000 Document
s enthalten. Sie können bei der Definition Ihrer Dokumente eines der folgenden Felder angeben:
name
: Der Ressourcenname (ID) vonDocument
. Darf höchstens 40 Zeichen enthalten (nur alphanumerische Zeichen oder Bindestriche). Die ID darf nicht mit einem Bindestrich. Wenn der Name bei der Erstellung leer ist, wird ein eindeutiger Name abgeleitet ausdisplay_name
und ein zufälliges Suffix mit 12 Zeichen.display_name
: Der für Menschen lesbare Anzeigename. Darf höchstens 512 Zeichen enthalten, einschließlich alphanumerischer Zeichen, Leerzeichen und Bindestriche.
Document
unterstützen außerdem bis zu 20 benutzerdefinierte custom_metadata
-Felder, die als Schlüssel/Wert-Paare angegeben werden. Benutzerdefinierte Metadaten können Strings, Stringlisten oder numerisch sein. Beachten Sie, dass Stringlisten maximal 10 Werte unterstützen können und numerische Werte im API als Gleitkommazahlen dargestellt werden.
# 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)
Erstelltes Dokument abrufen
Verwenden Sie die Methode GetDocumentRequest
, um programmatisch auf das oben erstellte Dokument zuzugreifen. Der Wert des Parameters name
bezieht sich auf den vollständigen Ressourcennamen des Dokuments und wird in der Zelle darüber als document_resource_name
festgelegt. Das erwartete Format ist 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)
Daten aufnehmen und Dokument kopieren
Um die Relevanz der von der Vektordatenbank zurückgegebenen Inhalte beim semantischen Abruf zu verbessern, unterteilen Sie große Dokumente bei der Datenaufnahme in kleinere Teile oder Blöcke.
Eine Chunk
ist ein Unterteil einer Document
, die zum Zweck der Vektordarstellung und Speicherung als unabhängige Einheit behandelt wird. Ein Chunk
kann maximal 2.043 Tokens haben. Ein Corpus
kann maximal 1 Million Chunk
s haben.
Ähnlich wie Document
s unterstützt Chunks
auch bis zu 20 benutzerdefinierte custom_metadata
-Felder, die als Schlüssel/Wert-Paare angegeben werden. Benutzerdefinierte Metadaten können Strings, Stringlisten oder numerisch sein. Beachten Sie, dass Stringlisten maximal 10 Werte unterstützen können und numerische Werte im API als Gleitkommazahlen dargestellt werden.
In diesem Leitfaden wird der Open-Source-HTMLChunker von Google verwendet.
Andere Chunker, die Sie verwenden können, sind zum Beispiel LangChain oder LlamaIndex.
HTML und Block über HTMLChunker aufnehmen
!pip install google-labs-html-chunker
from google_labs_html_chunker.html_chunker import HtmlChunker
from urllib.request import urlopen
HTML-DOM für eine Website abrufen Hier wird der HTML-Code direkt gelesen,
Es ist besser, beim HTML-Post-Rendering mit JavaScript-Injection zu arbeiten.
wie 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")
Teile das Textdokument in Abschnitte auf und erstelle aus diesen Abschnitten Chunk
s. Mit diesem Schritt werden die Chunk
-Objekte selbst erstellt und im nächsten Abschnitt werden sie in die Semantic Retriever API hochgeladen.
# 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)
Erstellen Sie Blöcke im Batch
Erstellen Sie Blöcke in Batches. Sie können maximal 100 Blöcke pro Batchanfrage angeben.
Verwenden Sie CreateChunk()
für die Erstellung eines einzelnen Blocks.
# 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)
Alternativ können Sie Blöcke ohne den HTMLChunker erstellen.
# 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
s auflisten und Status abrufen
Verwenden Sie die Methode ListChunksRequest
, um alle verfügbaren Chunk
s als paginierte Liste mit einer maximalen Größenbeschränkung von 100 Chunk
s pro Seite, sortiert in aufsteigender Reihenfolge von Chunk.create_time
, abzurufen. Wenn Sie kein Limit angeben, werden maximal 10 Chunk
s zurückgegeben.
Geben Sie das in der ListChunksRequest
-Antwort zurückgegebene next_page_token
als Argument für die nächste Anfrage an, um die nächste Seite abzurufen. Beim Paginieren müssen alle anderen für ListChunks
bereitgestellten Parameter mit dem Aufruf übereinstimmen, der das Seitentoken bereitgestellt hat.
Alle Chunk
s geben ein state
zurück. Hiermit können Sie den Status von Chunks
prüfen, bevor Sie Corpus
abfragen. Zu den Chunk
Bundesstaaten gehören UNSPECIFIED
, PENDING_PROCESSING
, ACTIVE
und FAILED
. Du kannst nur ACTIVE
Chunk
s abfragen.
# 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}')
Weiteres Dokument aufnehmen
Fügen Sie über HTMLChunker eine weitere Document
hinzu und fügen Sie Filter hinzu.
# 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)
Korpus abfragen
Mit der Methode QueryCorpusRequest
können Sie eine semantische Suche ausführen, um relevante Abschnitte zu erhalten.
results_count
: Geben Sie die Anzahl der zurückzugebenden Abschnitte an. Der Höchstwert ist 100. Wenn kein Wert angegeben ist, gibt die API maximal 10Chunk
s zurück.metadata_filters
: Nachchunk_metadata
oderdocument_metadata
filtern. JederMetadataFilter
muss einem eindeutigen Schlüssel entsprechen. MehrereMetadataFilter
-Objekte sind durch logischeAND
s verbunden. Ähnliche Metadatenfilterbedingungen werden durch logischeOR
s verbunden. Beispiele:
(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} }]
}]
UND-Zeichen werden für denselben Schlüssel nur durch numerische Werte unterstützt. Zeichenfolge -Werte unterstützen nur OR-Werte für denselben Schlüssel.
("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)
Zugeordnete Fragenbeantwortung
Mit der Methode GenerateAnswer
können Sie eine Zuordnung von Fragen für Ihr Dokument, Ihren Korpus oder mehrere Abschnitte ausführen.
Zugeordnete Question-Answering (AQA) bezieht sich auf die Beantwortung von Fragen, die auf einem bestimmten Kontext basieren, die Zuordnung(en) zur Verfügung stellen und dabei KI-Halluzinationen minimieren.
GenerateAnswer
bietet mehrere Vorteile gegenüber einem nicht abgestimmten LLM, wenn eine AQA gewünscht wird:
- Das zugrunde liegende Modell wurde so trainiert, dass nur Antworten zurückgegeben werden, die auf dem bereitgestellten Kontext basieren.
- Es identifiziert Attributionen (Segmente des bereitgestellten Kontexts, die zur Antwort beigetragen haben). Attributionen ermöglichen es dem Nutzer, die Antwort zu bestätigen.
- Dabei wird die
answerable_probability
für ein bestimmtes (Frage, Kontext)-Paar geschätzt. Dies gibt Ihnen die Möglichkeit, das Produktverhalten abhängig davon umzuleiten, wie wahrscheinlich es ist, dass die zurückgegebene Antwort begründet und korrekt ist.
answerable_probability
und das Problem „Ich weiß nicht“
In einigen Fällen lautet die beste Antwort auf die Frage tatsächlich „Ich weiß nicht“. Wenn der bereitgestellte Kontext beispielsweise keine Antwort auf die Frage enthält, wird die Frage als „nicht beantwortbar“ erachtet.
Das AQA-Modell erkennt solche Fälle sehr gut. Er kann sogar zwischen dem Grad der Antwortbarkeit und dem Unbeantwortungsgrad unterscheiden.
Die GenerateAnswer
API gibt jedoch die endgültige Entscheidungsgewalt in Ihren Händen:
- Immer versuchen, eine fundierte Antwort zurückzugeben, auch wenn es unwahrscheinlich ist, dass diese Antwort begründet und richtig ist.
- Rückgabe eines Werts
answerable_probability
: Die Schätzung des Modells für die Wahrscheinlichkeit, dass die Antwort begründet und richtig ist.
Ein niedriger answerable_probability
kann durch einen oder mehrere der folgenden Faktoren erklärt werden:
- Das Modell ist nicht davon überzeugt, dass seine Antwort richtig ist.
- Das Modell ist nicht sicher, ob seine Antwort auf den zitierten Textabschnitten fußt. Die Antwort kann sich stattdessen aus dem Weltwissen ergeben. Beispiel:
question="1+1=?", passages=["2+2=4”]
→answer=2, answerable_probability=0.02
- Das Modell lieferte relevante Informationen, die die Frage nicht vollständig beantworten. Beispiel:
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"
- In GenerateAnswerRequest wurde keine korrekt formulierte Frage gestellt.
Da ein niedriger answerable_probability
-Wert darauf hindeutet, dass die GenerateAnswerResponse.answer wahrscheinlich falsch oder grundlos ist, wird dringend empfohlen, die Antwort durch Prüfen von answerable_probability
weiter zu verarbeiten.
Wenn answerable_probability
niedrig ist, möchten einige Kunden möglicherweise Folgendes tun:
- Nachricht mit dem Hinweis „Diese Frage konnte nicht beantwortet werden“ anzeigen für die Endanwendenden.
- Nutzen Sie ein allgemeines LLM, das die Frage nach dem Weltwissen beantwortet. Der Grenzwert und die Art dieser Fallbacks hängen vom jeweiligen Anwendungsfall ab. Ein Wert von
answerable_probability
<= 0,5 ist ein guter Startgrenzwert.
Hilfreiche Tipps zur AQA
Die vollständigen API-Spezifikationen finden Sie in der GenerateAnswerRequest
API-Referenz.
- Durchgangslänge: Es werden bis zu 300 Tokens pro Passage empfohlen.
- Durchgangssortierung:
<ph type="x-smartling-placeholder">
- </ph>
- Wenn Sie
GenerateAnswerRequest.inline_passages
angeben, sollten die Abschnitte in absteigender Reihenfolge nach Relevanz für die Abfrage sortiert werden. Wenn die Kontextlängenbeschränkung des Modells überschritten wird, werden die letzten (am wenigsten relevanten) Abschnitte weggelassen. - Wenn Sie
GenerateAnswerRequest.semantic_retriever
angeben, erfolgt die Sortierung nach Relevanz automatisch.
- Wenn Sie
- Einschränkungen: Das AQA-Modell ist auf die Beantwortung von Fragen spezialisiert. Für andere Anwendungsfälle wie kreatives Schreiben, Zusammenfassen usw. rufen Sie bitte über GenerateContent ein allgemeines Modell auf.
- Chat: Wenn bekannt ist, dass es sich bei der Nutzereingabe um eine Frage handelt, die in einem bestimmten Kontext beantwortet werden kann, kann das AQA Chatanfragen beantworten. Wenn die Nutzereingabe jedoch eine beliebige Art von Eintrag sein kann, ist ein Allzweckmodell möglicherweise die bessere Wahl.
- Temperatur:
<ph type="x-smartling-placeholder">
- </ph>
- Für eine genaue AQA wird im Allgemeinen eine relativ niedrige Temperatur (~0, 2) empfohlen.
- Wenn Ihr Anwendungsfall auf deterministische Ausgaben beruht, legen Sie Temperatur=0 fest.
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)
Mehr Optionen: AQA mit Inline-Durchgängen
Alternativ können Sie den AQA-Endpunkt direkt und ohne die Semantic Retriever API verwenden, indem Sie inline_passages
übergeben.
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)
Korpus freigeben
Sie können den Korpus über die CreatePermissionRequest
API für andere freigeben.
Einschränkungen:
- Es gibt zwei Rollen für die Freigabe:
READER
undEDITOR
.- Ein
READER
kann den Korpus abfragen. - Ein
WRITER
hat Leseberechtigungen und kann den Korpus zusätzlich bearbeiten und freigeben.
- Ein
- Ein Korpus kann öffentlich sein, wenn Sie
EVERYONE
alsuser_type
Lesezugriff gewähren.
# 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)
Korpus löschen
Verwenden Sie DeleteCorpusRequest
, um einen Nutzerkorpus und alle zugehörigen Document
s und Chunk
Sek.
Beachten Sie, dass nicht leere Korpora einen Fehler ausgeben, ohne ein force=True
-Flag anzugeben. Wenn Sie force=True
festlegen, werden alle Chunk
s und Objekte im Zusammenhang mit dieser Document
ebenfalls gelöscht.
Wenn force=False
(Standardeinstellung) und Document
Chunk
-Werte enthält, wird der Fehler FAILED_PRECONDITION
zurückgegeben.
# 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)
Zusammenfassung und weitere Informationen
In diesem Leitfaden wurden der Semantic Retriever, zugeordnete Fragen und Answering (AQA) der Generative Language API und zeigte, wie Sie damit semantische Informationen zu Ihren benutzerdefinierten Textdaten abrufen können. Die API funktioniert auch mit dem Datenframework LlamaIndex. Weitere Informationen finden Sie in dieser Anleitung.
In der API-Dokumentation finden Sie Informationen zu den anderen verfügbaren Funktionen.
Anhang: OAuth mit Nutzeranmeldedaten einrichten
Folgen Sie der Anleitung unten im OAuth-Schnellstart, um die OAuth-Authentifizierung einzurichten.
Anmeldedaten für eine Desktopanwendung autorisieren Um dieses Notebook in Colab auszuführen, benennen Sie zuerst Ihre Anmeldedatendatei (in der Regel
client_secret_*.json
) inclient_secret.json
um. Laden Sie dann die Datei hoch, indem Sie das Dateisymbol in der linken Seitenleiste und dann das Upload-Symbol verwenden, wie im Screenshot unten dargestellt.
# 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"
Initialisieren Sie die Clientbibliothek und führen Sie das Notebook noch einmal aus, beginnend mit Korpus erstellen.
import google.ai.generativelanguage as glm
generative_service_client = glm.GenerativeServiceClient()
retriever_service_client = glm.RetrieverServiceClient()
permission_service_client = glm.PermissionServiceClient()