Начало работы с семантическим поиском

Посмотреть на ai.google.dev Запустить в Google Colab Посмотреть исходный код на GitHub

Обзор

Модели большого языка (LLM) могут изучать новые способности без непосредственного обучения им. Однако известно, что студенты LLM «галлюцинируют», когда им поручено дать ответы на вопросы, которым они не обучены. Частично это связано с тем, что LLM не знают о событиях после обучения. Также очень сложно отследить источники, из которых LLM черпают свои ответы. Для надежных и масштабируемых приложений важно, чтобы LLM предоставлял ответы, основанные на фактах, и мог ссылаться на свои источники информации.

Общий подход, используемый для преодоления этих ограничений, называется расширенной генерацией поиска (RAG), который дополняет приглашение, отправленное в LLM, соответствующими данными, полученными из внешней базы знаний с помощью механизма поиска информации (IR). Базой знаний может быть ваш собственный набор документов, баз данных или API.

В этом блокноте описан рабочий процесс, позволяющий улучшить реакцию LLM, дополняя его знания внешними текстовыми корпусами и выполняя поиск семантической информации для ответов на вопросы с помощью API-интерфейсов Semantic Retriever и API-интерфейсов «Атрибутивные вопросы и ответы» (AQA) API генеративного языка .

Настраивать

Импортируйте API генеративного языка.

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

Аутентификация

API Semantic Retriever позволяет выполнять семантический поиск по вашим собственным данным. Поскольку это ваши данные , для них требуется более строгий контроль доступа, чем для ключей API. Аутентификация с помощью OAuth с помощью учетных записей служб или учетных данных пользователя .

В этом кратком руководстве используется упрощенный подход к аутентификации, предназначенный для среды тестирования, и настройку учетной записи службы обычно проще начать. В производственной среде узнайте об аутентификации и авторизации, прежде чем выбирать учетные данные доступа , подходящие для вашего приложения.

Настройка OAuth с использованием сервисных учетных записей

Выполните следующие действия, чтобы настроить OAuth с использованием сервисных учетных записей:

  1. Включите API генеративного языка .

  1. Создайте учетную запись службы, следуя документации .

    • После создания учетной записи службы сгенерируйте ключ учетной записи службы.

  1. Загрузите файл своей учетной записи службы, используя значок файла на левой боковой панели, а затем значок загрузки, как показано на снимке экрана ниже.

    • Переименуйте загруженный файл в service_account_key.json или измените переменную service_account_file_name в приведенном ниже коде.

pip install -U google-auth-oauthlib
service_account_file_name = 'service_account_key.json'

from google.oauth2 import service_account

credentials = service_account.Credentials.from_service_account_file(service_account_file_name)

scoped_credentials = credentials.with_scopes(
    ['https://www.googleapis.com/auth/cloud-platform', 'https://www.googleapis.com/auth/generative-language.retriever'])

Инициализируйте клиентскую библиотеку, используя учетные данные учетной записи службы.

import google.ai.generativelanguage as glm
generative_service_client = glm.GenerativeServiceClient(credentials=scoped_credentials)
retriever_service_client = glm.RetrieverServiceClient(credentials=scoped_credentials)
permission_service_client = glm.PermissionServiceClient(credentials=scoped_credentials)

Создать корпус

API Semantic Retriever позволяет вам определить до 5 пользовательских текстовых корпусов для каждого проекта. При определении корпуса можно указать любое из следующих полей:

  • name : имя (идентификатор) ресурса Corpus . Должно содержать не более 40 буквенно-цифровых символов. Если при создании name пустое, будет создано уникальное имя длиной не более 40 символов с префиксом из display_name и случайным суффиксом из 12 символов.
  • display_name : удобочитаемое отображаемое имя Corpus . Должно содержать не более 512 символов, включая буквы, цифры, пробелы и тире.
example_corpus = glm.Corpus(display_name="Google for Developers Blog")
create_corpus_request = glm.CreateCorpusRequest(corpus=example_corpus)

# Make the request
create_corpus_response = retriever_service_client.create_corpus(create_corpus_request)

# Set the `corpus_resource_name` for subsequent sections.
corpus_resource_name = create_corpus_response.name
print(create_corpus_response)
name: "corpora/google-for-developers-blog-dqrtz8rs0jg"
display_name: "Google for Developers Blog"
create_time {
  seconds: 1713497533
  nanos: 587977000
}
update_time {
  seconds: 1713497533
  nanos: 587977000
}

Получить созданный корпус

Используйте метод GetCorpusRequest для программного доступа Corpus созданному вами выше. Значение параметра name относится к полному имени ресурса Corpus и задается в ячейке выше как corpus_resource_name . Ожидаемый формат: corpora/corpus-123 .

get_corpus_request = glm.GetCorpusRequest(name=corpus_resource_name)

# Make the request
get_corpus_response = retriever_service_client.get_corpus(get_corpus_request)

# Print the response
print(get_corpus_response)

Создать документ

Corpus может содержать до 10 000 Document s. При определении документов вы можете указать любое из следующих полей:

  • name : Имя ресурса Document (ID). Должно содержать не более 40 символов (только буквенно-цифровых или тире). Идентификатор не может начинаться или заканчиваться тире. Если при создании имя пустое, уникальное имя будет получено из display_name вместе со случайным суффиксом из 12 символов.
  • display_name : отображаемое имя, читаемое человеком. Должно содержать не более 512 символов, включая буквы, цифры, пробелы и тире.

Document также поддерживают до 20 пользовательских полей custom_metadata , заданных как пары ключ-значение. Пользовательские метаданные могут быть строками, списками строк или числовыми. Обратите внимание, что списки строк могут поддерживать максимум 10 значений, а числовые значения представлены в API как числа с плавающей запятой.

# Create a document with a custom display name.
example_document = glm.Document(display_name="Introducing Project IDX, An Experiment to Improve Full-stack, Multiplatform App Development")

# Add metadata.
# Metadata also supports numeric values not specified here
document_metadata = [
    glm.CustomMetadata(key="url", string_value="https://developers.googleblog.com/2023/08/introducing-project-idx-experiment-to-improve-full-stack-multiplatform-app-development.html")]
example_document.custom_metadata.extend(document_metadata)

# Make the request
# corpus_resource_name is a variable set in the "Create a corpus" section.
create_document_request = glm.CreateDocumentRequest(parent=corpus_resource_name, document=example_document)
create_document_response = retriever_service_client.create_document(create_document_request)

# Set the `document_resource_name` for subsequent sections.
document_resource_name = create_document_response.name
print(create_document_response)

Получить созданный документ

Используйте метод GetDocumentRequest для программного доступа к документу, созданному вами выше. Значение параметра name относится к полному имени ресурса документа и задается в ячейке выше как document_resource_name . Ожидаемый формат: corpora/corpus-123/documents/document-123 .

get_document_request = glm.GetDocumentRequest(name=document_resource_name)

# Make the request
# document_resource_name is a variable set in the "Create a document" section.
get_document_response = retriever_service_client.get_document(get_document_request)

# Print the response
print(get_document_response)

Вставить и разбить документ

Чтобы повысить релевантность содержимого, возвращаемого векторной базой данных во время семантического поиска, разбивайте большие документы на более мелкие части или фрагменты во время приема документа.

Chunk — это часть Document , которая рассматривается как независимая единица для целей векторного представления и хранения. Chunk может содержать максимум 2043 токена. Corpus может содержать максимум 1 миллион Chunk s.

Подобно Document , Chunks также поддерживает до 20 пользовательских полей custom_metadata , заданных как пары ключ-значение. Пользовательские метаданные могут быть строками, списками строк или числовыми. Обратите внимание, что списки строк могут поддерживать максимум 10 значений, а числовые значения представлены в API как числа с плавающей запятой.

В этом руководстве используется HtmlChunker с открытым исходным кодом Google.

Другие чанкеры, которые вы можете использовать, включают LangChain или LlamaIndex .

Прием HTML и чанка через HtmlChunker

!pip install google-labs-html-chunker

from google_labs_html_chunker.html_chunker import HtmlChunker

from urllib.request import urlopen

Получите HTML DOM для веб-сайта. Здесь HTML читается напрямую, но было бы лучше, чтобы пост-рендеринг HTML включал HTML-код, внедренный Javascript, например document.documentElement.innerHTML .

with(urlopen("https://developers.googleblog.com/2023/08/introducing-project-idx-experiment-to-improve-full-stack-multiplatform-app-development.html")) as f:
  html = f.read().decode("utf-8")

Разбейте текстовый документ на отрывки и создайте Chunk из этих отрывков. На этом этапе создаются сами объекты Chunk , а в следующем разделе они загружаются в 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)

Пакетное создание фрагментов

Создавайте фрагменты партиями. Вы можете указать максимум 100 фрагментов для каждого пакетного запроса.

Используйте CreateChunk() для создания одного фрагмента.

# Option 1: Use HtmlChunker in the section above.
# `chunks` is the variable set from the section above.
create_chunk_requests = []
for chunk in chunks:
  create_chunk_requests.append(glm.CreateChunkRequest(parent=document_resource_name, chunk=chunk))

# Make the request
request = glm.BatchCreateChunksRequest(parent=document_resource_name, requests=create_chunk_requests)
response = retriever_service_client.batch_create_chunks(request)
print(response)

Альтернативно вы можете создавать фрагменты без использования HtmlChunker.

# Add up to 100 CreateChunk requests per batch request.
# document_resource_name is a variable set in the "Create a document" section.
chunks = []
chunk_1 = glm.Chunk(data={'string_value': "Chunks support user specified metadata."})
chunk_1.custom_metadata.append(glm.CustomMetadata(key="section",
                                                  string_value="Custom metadata filters"))
chunk_2 = glm.Chunk(data={'string_value': "The maximum number of metadata supported is 20"})
chunk_2.custom_metadata.append(glm.CustomMetadata(key = "num_keys",
                                                  numeric_value = 20))
chunks = [chunk_1, chunk_2]
create_chunk_requests = []
for chunk in chunks:
  create_chunk_requests.append(glm.CreateChunkRequest(parent=document_resource_name, chunk=chunk))

# Make the request
request = glm.BatchCreateChunksRequest(parent=document_resource_name, requests=create_chunk_requests)
response = retriever_service_client.batch_create_chunks(request)
print(response)

Получение списка Chunk и получение состояния

Используйте метод ListChunksRequest , чтобы получить все доступные Chunk в виде постраничного списка с максимальным размером 100 Chunk на странице, отсортированного в порядке возрастания Chunk.create_time . Если вы не укажете ограничение, возвращается максимум 10 Chunk .

Предоставьте next_page_token , возвращенный в ответе ListChunksRequest в качестве аргумента для следующего запроса на получение следующей страницы. Обратите внимание, что при разбивке на страницы все остальные параметры, предоставляемые ListChunks должны соответствовать вызову, который предоставил токен страницы.

Все Chunk возвращают state . Используйте это, чтобы проверить состояние Chunks перед запросом Corpus . Состояния Chunk включают UNSPECIFIED , PENDING_PROCESSING , ACTIVE и FAILED . Вы можете запрашивать только ACTIVE Chunk .

# Make the request
request = glm.ListChunksRequest(parent=document_resource_name)
list_chunks_response = retriever_service_client.list_chunks(request)
for index, chunks in enumerate(list_chunks_response.chunks):
  print(f'\nChunk # {index + 1}')
  print(f'Resource Name: {chunks.name}')
  # Only ACTIVE chunks can be queried.
  print(f'State: {glm.Chunk.State(chunks.state).name}')

Вставить еще один документ

Добавьте еще один Document через HtmlChunker и добавьте фильтры.

# Create a document with a custom display name.
example_document = glm.Document(display_name="How it’s Made: Interacting with Gemini through multimodal prompting")

# Add document metadata.
# Metadata also supports numeric values not specified here
document_metadata = [
    glm.CustomMetadata(key="url", string_value="https://developers.googleblog.com/2023/12/how-its-made-gemini-multimodal-prompting.html")]
example_document.custom_metadata.extend(document_metadata)

# Make the CreateDocument request
# corpus_resource_name is a variable set in the "Create a corpus" section.
create_document_request = glm.CreateDocumentRequest(parent=corpus_resource_name, document=example_document)
create_document_response = retriever_service_client.create_document(create_document_request)

# Set the `document_resource_name` for subsequent sections.
document_resource_name = create_document_response.name
print(create_document_response)

# Chunks - add another webpage from Google for Developers
with(urlopen("https://developers.googleblog.com/2023/12/how-its-made-gemini-multimodal-prompting.html")) as f:
  html = f.read().decode("utf-8")

# Chunk the file using HtmlChunker
chunker = HtmlChunker(
    max_words_per_aggregate_passage=100,
    greedily_aggregate_sibling_nodes=False,
)
passages = chunker.chunk(html)

# Create `Chunk` entities.
chunks = []
for passage in passages:
    chunk = glm.Chunk(data={'string_value': passage})
    chunk.custom_metadata.append(glm.CustomMetadata(key="tags",
                                                    string_list_value=glm.StringList(
                                                        values=["Google For Developers", "Gemini API", "Blog", "Announcement"])))
    chunk.custom_metadata.append(glm.CustomMetadata(key="chunking_strategy",
                                                    string_value="no_aggregate_sibling_nodes"))
    chunk.custom_metadata.append(glm.CustomMetadata(key = "publish_date",
                                                    numeric_value = 20231206))
    chunks.append(chunk)

# Make the request
create_chunk_requests = []
for chunk in chunks:
  create_chunk_requests.append(glm.CreateChunkRequest(parent=document_resource_name, chunk=chunk))
request = glm.BatchCreateChunksRequest(parent=document_resource_name, requests=create_chunk_requests)
response = retriever_service_client.batch_create_chunks(request)
print(response)

Запросить корпус

Используйте метод QueryCorpusRequest для выполнения семантического поиска и получения соответствующих отрывков.

  • results_count : укажите количество возвращаемых отрывков. Максимум — 100. Если не указано, API возвращает максимум 10 Chunk s.
  • metadata_filters : Фильтровать по chunk_metadata или document_metadata . Каждый MetadataFilter должен соответствовать уникальному ключу. Несколько объектов MetadataFilter соединяются логическими операторами AND . Похожие условия фильтра метаданных объединяются логическими операторами OR . Некоторые примеры:
(year >= 2020 OR year < 2010) AND (genre = drama OR genre = action)

metadata_filter = [
  {
    key = "document.custom_metadata.year"
    conditions = [
      {int_value = 2020, operation = GREATER_EQUAL},
      {int_value = 2010, operation = LESS}]
  },
  {
    key = "document.custom_metadata.genre"
    conditions = [
      {string_value = "drama", operation = EQUAL},
      {string_value = "action", operation = EQUAL} }]
  }]

Обратите внимание, что только числовые значения поддерживают операторы «И» для одного и того же ключа. Строковые значения поддерживают только операторы «ИЛИ» для одного и того же ключа.

("Google for Developers" in tags) and (20230314 > publish_date)

metadata_filter = [
 {
    key = "chunk.custom_metadata.tags"
    conditions = [
    {string_value = 'Google for Developers', operation = INCLUDES},
  },
  {
    key = "chunk.custom_metadata.publish_date"
    conditions = [
    {numeric_value = 20230314, operation = GREATER_EQUAL}]
  }]
user_query = "What is the purpose of Project IDX?"
results_count = 5

# Add metadata filters for both chunk and document.
chunk_metadata_filter = glm.MetadataFilter(key='chunk.custom_metadata.tags',
                                           conditions=[glm.Condition(
                                              string_value='Google For Developers',
                                              operation=glm.Condition.Operator.INCLUDES)])

# Make the request
# corpus_resource_name is a variable set in the "Create a corpus" section.
request = glm.QueryCorpusRequest(name=corpus_resource_name,
                                 query=user_query,
                                 results_count=results_count,
                                 metadata_filters=[chunk_metadata_filter])
query_corpus_response = retriever_service_client.query_corpus(request)
print(query_corpus_response)

Приписанный вопрос-ответ

Используйте метод GenerateAnswer для выполнения атрибутированных вопросов-ответов для вашего документа, корпуса или набора отрывков.

Атрибутированный вопрос-ответ (AQA) означает ответы на вопросы, основанные на данном контексте, и предоставление объяснений, сводя при этом к минимуму галлюцинации.

GenerateAnswer дает несколько преимуществ по сравнению с использованием ненастроенного LLM в тех случаях, когда требуется AQA:

  • Базовая модель обучена возвращать только ответы, основанные на предоставленном контексте.
  • Он определяет атрибуции (сегменты предоставленного контекста, которые способствовали ответу). Атрибуция позволяет пользователю проверить ответ.
  • Он оценивает answerable_probability для данной пары (вопрос, контекст), что дополнительно позволяет вам изменять поведение продукта в зависимости от того, насколько вероятно, что возвращенный ответ будет обоснованным и правильным.

answerable_probability и проблема «я не знаю»

В некоторых случаях лучший ответ на вопрос – это «Я не знаю». Например, если предоставленный контекст не содержит ответа на вопрос, то вопрос считается «без ответа».

Модель AQA хорошо справляется с распознаванием таких случаев. Он даже может различать степени ответственности и отсутствия ответственности.

Однако API GenerateAnswer передает вам право принятия окончательных решений посредством:

  • Всегда старайтесь дать обоснованный ответ, даже если маловероятно, что этот ответ будет обоснованным и правильным.
  • Возврат значения answerable_probability — оценка модели вероятности того, что ответ обоснован и правилен.

Низкая answerable_probability может быть объяснена одним или несколькими из следующих факторов:

  • Модель не уверена в правильности своего ответа.
  • Модель не уверена, что ее ответ основан на цитируемых отрывках; Вместо этого ответ может быть получен из мировых знаний. Например: question="1+1=?", passages=["2+2=4”]answer=2, answerable_probability=0.02
  • Модель предоставила соответствующую информацию, которая не полностью ответила на вопрос. Пример: question="Is it available in my size?, passages=["Available in sizes 5-11"]answer="Yes it is available in sizes 5-11", answerable_probability=0.03"
  • В GenerateAnswerRequest не было задано ни одного правильно сформулированного вопроса.

Поскольку низкое значение answerable_probability указывает на то, что GenerateAnswerResponse.ответ, скорее всего, неверен или необоснован, настоятельно рекомендуется продолжить обработку ответа, проверив answerable_probability .

Когда answerable_probability низкая, некоторые клиенты могут захотеть:

  • Отображение сообщения о том, что «не удалось ответить на этот вопрос» конечному пользователю.
  • Вернитесь к программе LLM общего назначения, которая отвечает на вопросы мировых знаний. Пороговое значение и характер таких откатов будут зависеть от индивидуальных случаев использования. Значение answerable_probability <= 0,5 является хорошим стартовым порогом.

Полезные советы AQA

Полные спецификации API см. в справочнике по API GenerateAnswerRequest .

  • Длина прохода : рекомендуется использовать до 300 жетонов за проход.
  • Сортировка проходов :
    • Если вы предоставляете GenerateAnswerRequest.inline_passages , отрывки должны быть отсортированы в порядке убывания релевантности запросу. Если предел длины контекста модели превышен, последние (наименее релевантные) отрывки будут опущены.
    • Если вы предоставите GenerateAnswerRequest.semantic_retriever , сортировка по релевантности будет выполняться автоматически.
  • Ограничения : Модель AQA предназначена для ответов на вопросы. Для других случаев использования, таких как творческое письмо, обобщение и т. д., вызовите модель общего назначения через GenerateContent.
    • Чат : если известно, что вводимые пользователем данные представляют собой вопрос, на который можно ответить в определенном контексте, то AQA может отвечать на запросы чата. Но если пользовательский ввод может быть любым типом ввода, то модель общего назначения может быть лучшим выбором.
  • Температура :
    • Как правило, для точного AQA рекомендуется относительно низкая температура (~0,2).
    • Если ваш вариант использования основан на детерминированных выходных данных, установите температуру = 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)

Дополнительные параметры: AQA с использованием встроенных проходов

Альтернативно вы можете использовать конечную точку AQA напрямую, без использования API Semantic Retriever, передав 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)

Поделитесь корпусом

Вы можете поделиться корпусом с другими, используя API CreatePermissionRequest .

Ограничения:

  • Есть 2 роли для обмена: READER и EDITOR .
    • READER может запросить корпус.
    • WRITER имеет права чтения и, кроме того, может редактировать и публиковать корпус.
  • Корпус может быть общедоступным, если предоставить EVERYONE доступ на чтение в качестве user_type .
# Replace your-email@gmail.com with the email added as a test user in the OAuth Quickstart
shared_user_email = "TODO-your-email@gmail.com" #  @param {type:"string"}
user_type = "USER"
role = "READER"

# Make the request
# corpus_resource_name is a variable set in the "Create a corpus" section.
request = glm.CreatePermissionRequest(
    parent=corpus_resource_name,
    permission=glm.Permission(grantee_type=user_type,
                              email_address=shared_user_email,
                              role=role))
create_permission_response = permission_service_client.create_permission(request)
print(create_permission_response)

Удалить корпус

Используйте DeleteCorpusRequest , чтобы удалить корпус пользователя и все связанные с ним Document и Chunk .

Обратите внимание, что непустые корпуса выдадут ошибку без указания флага force=True . Если вы установите force=True , любые Chunk и объекты, связанные с этим Document также будут удалены.

Если force=False (по умолчанию) и Document содержит какие-либо Chunk , будет возвращена ошибка FAILED_PRECONDITION .

# Set force to False if you don't want to delete non-empty corpora.
req = glm.DeleteCorpusRequest(name=corpus_resource_name, force=True)
delete_corpus_response = retriever_service_client.delete_corpus(req)
print("Successfully deleted corpus: " + corpus_resource_name)

Резюме и дальнейшее чтение

В этом руководстве представлены API-интерфейсы семантического извлечения и атрибутированных вопросов и ответов (AQA) API генеративного языка, а также показано, как их можно использовать для извлечения семантической информации по вашим пользовательским текстовым данным. Обратите внимание, что этот API также работает с платформой данных LlamaIndex . Обратитесь к руководству , чтобы узнать больше.

Также обратитесь к документации API , чтобы узнать больше о других доступных функциях.

Приложение. Настройка OAuth с учетными данными пользователя

Следуйте инструкциям, приведенным ниже в кратком руководстве по OAuth , чтобы настроить аутентификацию OAuth.

  1. Настройте экран согласия OAuth .

  2. Авторизуйте учетные данные для настольного приложения . Чтобы запустить этот блокнот в Colab, сначала переименуйте свой файл учетных данных (обычно client_secret_*.json ) в client_secret.json . Затем загрузите файл, используя значок файла на левой боковой панели, а затем значок загрузки, как показано на снимке экрана ниже.

# Replace TODO-your-project-name with the project used in the OAuth Quickstart
project_name = "TODO-your-project-name" #  @param {type:"string"}
# Replace TODO-your-email@gmail.com with the email added as a test user in the OAuth Quickstart
email = "TODO-your-email@gmail.com" #  @param {type:"string"}
# Rename the uploaded file to `client_secret.json` OR
# Change the variable `client_file_name` in the code below.
client_file_name = "client_secret.json"

# IMPORTANT: Follow the instructions from the output - you must copy the command
# to your terminal and copy the output after authentication back here.
!gcloud config set project $project_name
!gcloud config set account $email

# NOTE: The simplified project setup in this tutorial triggers a "Google hasn't verified this app." dialog.
# This is normal, click "Advanced" -> "Go to [app name] (unsafe)"
!gcloud auth application-default login --no-browser --client-id-file=$client_file_name --scopes="https://www.googleapis.com/auth/generative-language.retriever,https://www.googleapis.com/auth/cloud-platform"

Инициализируйте клиентскую библиотеку и перезапустите блокнот, начиная с создания корпуса .

import google.ai.generativelanguage as glm

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