Passo a Passo da Pesquisa Semântica
Saiba como executar uma pesquisa semântica dos dados usando o OCI Search com o OpenSearch.
Pré-requisitos
Antes de começar, você precisa fazer o seguinte:
- 
Selecione um dos modelos pré-treinados suportados pelo OCI Search com o OpenSearch 
- 
Confirme se o cluster do OpenSearch está na versão 2.11. 
- 
Atualize as definições do cluster para executar a pesquisa semântica. O seguinte exemplo de comando atualiza as configurações aplicáveis: PUT _cluster/settings { "persistent": { "plugins": { "ml_commons": { "only_run_on_ml_node": "false", "model_access_control_enabled": "true", "native_memory_threshold": "99", "rag_pipeline_feature_enabled": "true", "memory_feature_enabled": "true", "allow_registering_model_via_local_file": "true", "allow_registering_model_via_url": "true", "model_auto_redeploy.enable":"true", "model_auto_redeploy.lifetime_retry_times": 10 } } } }
Registrar o Grupo de Modelos
Use grupos de modelos para agrupar modelos logicamente e controlar quem tem acesso a eles. Registre um grupo de modelos usando a operação registrar nas APIs do Grupo de Modelos, conforme mostrado no seguinte exemplo:
POST /_plugins/_ml/model_groups/_register
{
  "name": "general pretrained models",
  "description": "A model group for pretrained models hosted by OCI Search with OpenSearch"
}Anote o model_group_id retornado na resposta:
{
  "model_group_id": "<model_group_ID>",
  "status": "CREATED"
}Registrar e Implantar o Modelo
Você tem as três opções a seguir para pesquisa semântica:
- Opção 1: Registre e implante um modelo pré-treinado hospedado no OCI Search com OpenSearch usando as etapas descritas em Usando um Modelo Pré-treinado OpenSearch. Esta opção é a mais simples de usar, você não precisa configurar nenhuma política adicional do IAM e o payload não é tão complexo quanto o payload da próxima opção.
- Opção 2: Importe, registre e implante um modelo pré-treinado OpenSearch usando as etapas descritas em Modelos Personalizados. Isso inclui fazer upload do arquivo de modelo para um bucket do serviço Object Storage e, em seguida, especificar o URL do serviço Object Storage do arquivo de modelo quando você registra o modelo.
- Opção 3: Você também pode registrar e implantar um modelo de incorporação GenAI remoto, como o cohere.embed-english-v3.0, no seu cluster usando nosso Conector GenAI. Você deve criar um conector primeiro e, em seguida, registrar e implantar o modelo usando o ID do conector, conforme descrito nas etapas a seguir.Observação
 Se você estiver usando o modelo ON-DEMAND, mantenha-se atualizado com as notificações de descontinuação do modelo do serviço GenAI e atualize o conector quando necessário para evitar possíveis interrupções de serviço. Consulte Modelos Básicos Pré-treinados no Serviço Generative AI para obter os modelos de incorporação suportados e selecionar um modelo de incorporação na lista de modelos suportados.Se você estiver usando o modelo DEDICATED, altere o parâmetro servingTypeno exemplo de payload a seguir de ON-DEMAND para DEDICATED.
- model_group_id: Se você concluiu a Etapa 1, este é o valor de model_group_id para a solicitação _register.
- name: O nome do modelo do modelo pré-treinado que você deseja usar.
- version: O número da versão do modelo pré-treinado que você deseja usar.
- model_format: O formato do modelo,- TORCH_SCRIPTou- ONNX.
Registre o modelo usando a operação registrar nas APIs de Modelo, conforme mostrado no seguinte exemplo:
POST /_plugins/_ml/models/_register
{
  "name": "huggingface/sentence-transformers/msmarco-distilbert-base-tas-b",
  "version": "1.0.2",
  "model_group_id": "<model_group_ID>",
  "model_format": "TORCH_SCRIPT"
}Anote o task_id retornado na resposta. Você pode usar o task_id para verificar o status da operação.
Por exemplo, a partir da seguinte resposta:
{
  "task_id": "<task_ID>",
  "status": "CREATED"
}para verificar o status da operação de registro, use task_id com a operação Obter das APIs da Tarefa, conforme mostrado no seguinte exemplo: 
GET /_plugins/_ml/tasks/<task_ID>Quando a operação de registro estiver concluída, o valor state na resposta à operação Obter será COMPLETED, conforme mostrado o seguinte exemplo: 
{
  "model_id": "<embedding_model_ID>",
  "task_type": "REGISTER_MODEL",
  "function_name": "TEXT_EMBEDDING",
  "state": "COMPLETED",
  "worker_node": [
    "f2b_8-mVRVyVqeKqsA7dcQ"
  ],
  "create_time": 1706831015570,
  "last_update_time": 1706831070740,
  "is_async": true
}Anote o valor model_ID retornado na resposta a ser usada quando você implantar o modelo.
Implantar o Modelo
Depois que a operação de registro for concluída para o modelo, você poderá implantar o modelo no cluster usando a operação de implantação das APIs de Modelo, informando o model_ID da resposta da operação Obter na etapa anterior, conforme mostrado no seguinte exemplo: 
POST /_plugins/_ml/models/<embedding_model_ID>/_deploy Anote o task_id retornado na resposta. Você pode usar o task_id para verificar o status da operação.
Por exemplo, a partir da seguinte resposta:
{
  "task_id": "<task_ID>",
  "task_type": "DEPLOY_MODEL",
  "status": "CREATED"
}para verificar o status da operação de registro, use o task_ID com a operação Get das APIs de Tarefas, conforme mostrado no seguinte exemplo: 
GET /_plugins/_ml/tasks/<task_ID>Quando a operação de implantação estiver concluída, o valor status na resposta à operação Obter será COMPLETED.
Criar um Pipeline de Ingestão k-NN
Após a conclusão da operação de implantação, crie um pipeline de ingestão usando o modelo implantado. O pipeline de ingestão usa o modelo implantado para gerar automaticamente os vetores de incorporação para cada documento no momento da ingestão. O processador lida com tudo para a incorporação, então você só precisa mapear adequadamente o campo de texto esperado no documento que está sendo convertido em incorporação. O exemplo a seguir mostra a criação de um pipeline de ingestão:
PUT _ingest/pipeline/<pipeline_name>
{
  "description": "An example neural search pipeline",
  "processors" : [
    {
      "text_embedding": {
        "model_id": "<embedding_model_ID>",
        "field_map": {
           "<text_field_name>": "<embedding_field_name>"
        }
      }
    }
  ]
}Se o pipeline de ingestão tiver sido criado, a seguinte resposta será retornada:
{
  "acknowledged": true
}Criar Índice
Crie um índice usando o pipeline de ingestão criado na etapa anterior. Você pode usar qualquer um dos mecanismos ANN disponíveis no índice. O exemplo a seguir usa o Mecanismo Lucene:
PUT /lucene-index
{
    "settings": {
        "index.knn": true,
        "default_pipeline": "<pipeline_name>"
    },
    "mappings": {
        "properties": {
            "<embedding_field_name>": {
                "type": "knn_vector",
                "dimension": <model_dimension>,
                "method": {
                    "name":"hnsw",
                    "engine":"lucene",
                    "space_type": "l2",
                    "parameters":{
                        "m":512,
                        "ef_construction": 245
                    }
                }
            },
            "<text_field_name>": {
                "type": "text"
            }
        }
    }
    }O campo passage_text do índice de criação corresponde ao campo passage_text no pipeline de ingestão. Isso faz com que o pipeline saiba como criar incorporações e, em seguida, mapeá-las para documentos no momento da ingestão.
Para ajudá-lo a escolher o mecanismo que deseja usar e os parâmetros de configuração disponíveis para esses mecanismos, consulte índice k-NN e Pesquisa k-NN aproximada.
Veja a seguir um exemplo de resposta para uma criação de índice bem-sucedida:
{
        "acknowledged": true,
        "shards_acknowledged": true,
        "index": "lucene-index"
}Ingerir Documentos no Índice
Faça a ingestão de dados no índice, conforme mostrado no seguinte exemplo:
POST /lucene-index/_doc/1
{
  "<text_field_name>": "there are many sharks in the ocean"
}
 
POST /lucene-index/_doc/2
{
  "<text_field_name>": "fishes must love swimming"
}
 
POST /lucene-index/_doc/3
{
  "<text_field_name>": "summers are usually very hot"
}
 
POST /lucene-index/_doc/4
{
  "<text_field_name>": "florida has a nice weather all year round"
}Resposta :
# POST /lucene-index/_doc/1
{
  "_index": "lucene-index",
  "_id": "1",
  "_version": 1,
  "result": "created",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 0,
  "_primary_term": 1
}
# POST /lucene-index/_doc/2
{
  "_index": "lucene-index",
  "_id": "2",
  "_version": 1,
  "result": "created",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 1,
  "_primary_term": 1
}
# POST /lucene-index/_doc/3
{
  "_index": "lucene-index",
  "_id": "3",
  "_version": 1,
  "result": "created",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 2,
  "_primary_term": 1
}
# POST /lucene-index/_doc/4
{
  "_index": "lucene-index",
  "_id": "4",
  "_version": 1,
  "result": "created",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 3,
  "_primary_term": 1
}Execute o seguinte para verificar um dos documentos para garantir que as incorporações sejam geradas corretamente:
GET /lucene-index/_doc/3Resposta :
{
  "_index": "lucene-index",
  "_id": "3",
  "_version": 1,
  "_seq_no": 2,
  "_primary_term": 1,
  "found": true,
  "_source": {
    "<embedding_field_list>": [
      -0.1254959,
      -0.3151774,
      0.03526799,
      0.39322096,
      -0.0475556,
      -0.12378334,
      -0.032554347,
      0.4033895,
      0.050718695,
      -0.3587931,
      0.097042784,
      0.11742551,
      -0.06573639,
      0.14252506,
      -0.466573,
      0.56093556,
      -0.2815812,
      -0.00016521096,
      -0.2858566,Executando a Pesquisa Semântica
Esta seção contém exemplos de diferentes tipos de pesquisas semânticas que você pode executar.
Pesquisa Semântica com Pesquisa Híbrida
Usando o ID do modelo em Registrar e Implantar o Modelo, execute a pesquisa semântica com pesquisa híbrida da seguinte forma:
GET lucene-index/_search
{
  "query": {
    "bool" : {
      "should" : [
        {
          "script_score": {
            "query": {
              "neural": {
                "<embedding_field_name>": {
                  "query_text": "what are temperatures in miami like",
                  "model_id": "<embedding_model_ID>",
                  "k": 2
                }
              }
            },
            "script": {
              "source": "_score * 1.5"
            }
          }
        }
      ]
    }
  },
  "fields": [
    "<text_field_name>"
  ],
  "_source": false
}Resposta :
{
  "took": 343,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 0.032253794,
    "hits": [
      {
        "_index": "lucene-index",
        "_id": "4",
        "_score": 0.032253794,
        "fields": {
          "<text_field_name>": [
            "florida has a nice weather all year round"
          ]
        }
      },
      {
        "_index": "lucene-index",
        "_id": "3",
        "_score": 0.031487543,
        "fields": {
          "<text_field_name>": [
            "summers are usually very hot"
          ]
        }
      }
    ]
  }
}Você pode ver que a pergunta de consulta não menciona Florida, tempo, nem verão, no entanto, o modelo infere o significado semântico de temperaturas e miami para retornar as respostas mais relevantes.
Pesquisa Semântica com Pesquisa Neural
Usando o ID do modelo em Registrar e Implantar o Modelo, execute a pesquisa semântica com pesquisa neural da seguinte forma:
GET /lucene-index/_search
{
  "_source": {
    "excludes": [
      "<embedding_field_name>"
    ]
  },
  "query": {
    "neural": {
      "<embedding_field_name>": {
        "query_text": "good climate",
        "model_id": "<embedding_model_ID>",
        "k": 5
      }
    }
  }
}Resposta :
{
  "took": 36,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 4,
      "relation": "eq"
    },
    "max_score": 0.012060728,
    "hits": [
      {
        "_index": "lucene-index",
        "_id": "4",
        "_score": 0.012060728,
        "_source": {
          "passage_text": "florida has a nice weather all year round"
        }
      },
      {
        "_index": "lucene-index",
        "_id": "1",
        "_score": 0.010120423,
        "_source": {
          "passage_text": "there are many sharks in the ocean"
        }
      },
      {
        "_index": "lucene-index",
        "_id": "3",
        "_score": 0.00985171,
        "_source": {
          "passage_text": "summers are usually very hot"
        }
      },
      {
        "_index": "lucene-index",
        "_id": "2",
        "_score": 0.009575767,
        "_source": {
          "passage_text": "fishes must love swimming"
        }
      }
    ]
  }
}