Pesquise seus dados usando similaridade semântica.
A API de Recuperação permite realizar pesquisa semântica nos seus dados, uma técnica que encontra resultados semanticamente semelhantes, mesmo quando correspondem a poucas ou nenhuma palavra-chave. A recuperação é útil por si só, mas se torna especialmente poderosa quando combinada com nossos modelos para sintetizar respostas.
A API de Recuperação usa armazenamentos vetoriais, que funcionam como índices dos seus dados. Este guia explica como realizar pesquisas semânticas e apresenta os armazenamentos vetoriais em detalhes.
1
2
3
4
5require "openai"client = OpenAI::Client.newresults = client.vector_stores.search("vs_123", query: "What is the return policy?")puts(results.data&.first&.content)
Para aprender a usar os resultados com nossos modelos, consulte a seção Síntese de
respostas.
Pesquisa semântica
A pesquisa semântica é uma técnica que usa embeddings vetoriais para encontrar resultados semanticamente relevantes. Isso inclui resultados com poucas ou nenhuma palavra-chave em comum, que as técnicas tradicionais de pesquisa podem deixar de encontrar.
Por exemplo, vamos analisar possíveis resultados para "When did we go to the moon?":
Observe que o resultado mais relevante não contém nenhuma das palavras da consulta de pesquisa. Essa flexibilidade torna a pesquisa semântica uma técnica poderosa para consultar bases de conhecimento de qualquer tamanho.
A pesquisa semântica usa armazenamentos vetoriais, que abordaremos em detalhes mais adiante neste guia. Esta seção se concentra no funcionamento da pesquisa semântica.
Como realizar pesquisas semânticas
Você pode consultar um armazenamento vetorial usando a função search e especificando uma query em linguagem natural. Isso retorna uma lista de resultados, cada um com os trechos relevantes, as pontuações de similaridade e o arquivo de origem.
Consulta de pesquisa
Python
1
2
3const results = await client.vectorStores.search(vector_store.id, { query: "How many woodchucks are allowed per passenger?",});
1
2
3
4results = client.vector_stores.search(vector_store_id=vector_store.id,query="How many woodchucks are allowed per passenger?",)
1
2
3
4
5
6
7
8require "openai"client = OpenAI::Client.newresults = client.vector_stores.search( "vs_123", query: "How many woodchucks are allowed per passenger?")puts(results.data&.first&.content)
Resultados
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42{"object": "vector_store.search_results.page","search_query": "How many woodchucks are allowed per passenger?","data": [ {"file_id": "file-12345","filename": "woodchuck_policy.txt","score": 0.85,"attributes": {"region": "North America","author": "Wildlife Department" },"content": [ {"type": "text","text": "According to the latest regulations, each passenger is allowed to carry up to two woodchucks." }, {"type": "text","text": "Ensure that the woodchucks are properly contained during transport." } ] }, {"file_id": "file-67890","filename": "transport_guidelines.txt","score": 0.75,"attributes": {"region": "North America","author": "Transport Authority" },"content": [ {"type": "text","text": "Passengers must adhere to the guidelines set forth by the Transport Authority regarding the transport of woodchucks." } ] } ],"has_more": false,"next_page": null}
Por padrão, uma resposta contém no máximo 10 resultados, mas você pode definir um limite de até 50 usando o parâmetro max_num_results.
Reescrita de consultas
Certos estilos de consulta produzem resultados melhores, por isso disponibilizamos uma configuração que reescreve suas consultas automaticamente para otimizar o desempenho. Ative esse recurso definindo rewrite_query=true ao executar search.
A consulta reescrita estará disponível no campo search_query do resultado.
Original
Reescrita
Gostaria de saber a altura do prédio principal de escritórios.
altura do prédio principal de escritórios
Quais são as normas de segurança para o transporte de materiais perigosos?
normas de segurança para materiais perigosos
Como faço para registrar uma reclamação sobre um problema no serviço?
processo de registro de reclamações sobre serviços
Filtragem por atributos
A filtragem por atributos ajuda a restringir os resultados aplicando critérios, como limitar as pesquisas a um intervalo de datas específico. Você pode definir e combinar critérios em attribute_filter para selecionar arquivos com base nos atributos deles antes de realizar a pesquisa semântica.
Use filtros de comparação para comparar uma key específica nos attributes de um arquivo com um determinado value, e filtros compostos para combinar vários filtros usando and e or.
Filtro de comparação
1
2
3
4
5{"type": "eq"|"ne"|"gt"|"gte"|"lt"|"lte"|"in"|"nin", // comparison operators"key": "attributes_key", // attributes key"value": "target_value"// value to compare against}
Se os resultados da pesquisa de arquivos não forem relevantes o suficiente, você pode ajustar ranking_options para melhorar a qualidade das respostas. Isso inclui especificar um ranker, como auto ou default-2024-08-21, e definir um score_threshold entre 0.0 e 1.0. Um valor mais alto de score_threshold limitará os resultados aos trechos mais relevantes, embora possa excluir alguns potencialmente úteis. Quando ranking_options.hybrid_search é fornecido, você também pode ajustar hybrid_search.embedding_weight (rrf_embedding_weight) e hybrid_search.text_weight (rrf_text_weight) para controlar como a fusão de classificações recíprocas equilibra as correspondências semânticas de embeddings e as correspondências esparsas de palavras-chave. Aumente o primeiro peso para enfatizar a similaridade semântica e o segundo para enfatizar a sobreposição textual. Garanta que pelo menos um dos pesos seja maior que zero.
Armazenamentos vetoriais
Os armazenamentos vetoriais são os contêineres que viabilizam a pesquisa semântica na API de Recuperação e na ferramenta de pesquisa de arquivos. Quando você adiciona um arquivo a um armazenamento vetorial, ele é automaticamente dividido em trechos, convertido em embeddings e indexado.
Os armazenamentos vetoriais contêm objetos vector_store_file, que têm como base um objeto file.
Tipo de objeto
Descrição
file
Representa o conteúdo enviado pela Files API. É usado com frequência em armazenamentos vetoriais, mas também para ajuste fino e outros casos de uso.
vector_store
Contêiner para arquivos pesquisáveis.
vector_store.file
Tipo invólucro que representa especificamente um file dividido em trechos, convertido em embeddings e associado a um vector_store. Contém o mapa attributes, usado para filtragem.
Preços
A cobrança será baseada no armazenamento total usado em todos os seus armazenamentos vetoriais, determinado pelo tamanho dos trechos processados e dos embeddings correspondentes.
Algumas operações, como create para vector_store.file, são assíncronas e podem levar algum tempo para serem concluídas. Use nossas funções auxiliares, como create_and_poll, para bloquear a execução até a conclusão. Como alternativa, você pode verificar o status. A remoção de arquivos de um armazenamento vetorial tem consistência eventual, e os resultados da pesquisa ainda podem incluir conteúdo de um arquivo removido por um breve período.
Ao criar um lote, você pode fornecer file_ids com attributes e/ou chunking_strategy opcionais, ou usar o array files para passar objetos que incluam um file_id e, opcionalmente, attributes e chunking_strategy para cada arquivo. As duas opções são mutuamente exclusivas, permitindo controlar claramente se todos os arquivos compartilham as mesmas configurações ou se você precisa substituir configurações por arquivo.
Para aumentar a taxa de processamento da ingestão em um único armazenamento vetorial, recomendamos a criação em lote sempre que possível. Os lotes podem incluir até 500 arquivos em uma única requisição, o que geralmente reduz a disputa por recursos e melhora a latência de ponta a ponta em comparação com o envio de várias requisições de criação de arquivos individuais.
Atributos
Cada vector_store.file pode ter um dicionário attributes associado, com valores que podem ser consultados ao realizar uma pesquisa semântica com filtragem por atributos. O dicionário pode ter no máximo 16 chaves, com um limite de 256 caracteres cada.
Criar arquivo no armazenamento vetorial com atributos
Você pode definir uma política de expiração para objetos vector_store com expires_after. Quando um armazenamento vetorial expirar, todos os objetos vector_store.file associados serão excluídos e você deixará de pagar por eles.
Definir política de expiração para o armazenamento vetorial
O tamanho máximo de arquivo é de 512 MB. Cada arquivo deve conter no máximo 5.000.000 de tokens (calculados automaticamente quando você anexa um arquivo).
Divisão em blocos
Por padrão, max_chunk_size_tokens é definido como 800 e chunk_overlap_tokens como 400. Isso significa que cada arquivo é indexado dividindo-se seu conteúdo em blocos de 800 tokens, com uma sobreposição de 400 tokens entre blocos consecutivos.
Você pode ajustar esse comportamento definindo chunking_strategy ao adicionar arquivos ao armazenamento vetorial. A estratégia tem algumas limitações:
max_chunk_size_tokens deve estar entre 100 e 4096, inclusive.
chunk_overlap_tokens deve ser não negativo e não deve exceder max_chunk_size_tokens / 2.
Para tipos MIME text/, a codificação deve ser utf-8, utf-16 ou ascii.
Depois de realizar uma consulta, você pode querer sintetizar uma resposta com base nos resultados. Para isso, você pode usar nossos modelos, fornecendo os resultados e a consulta original para obter uma resposta fundamentada.
Realizar consulta de pesquisa para obter resultados
Python
1
2
3
4
5
6
7
8
9import OpenAI from "openai";const client = new OpenAI();const userQuery = "What is the return policy?";const results = await client.vectorStores.search(vector_store.id, { query: userQuery,});
1
2
3
4
5
6
7
8require "openai"client = OpenAI::Client.newresults = client.vector_stores.search( "vs_123", query: "What is the return policy?")puts(results.data)
Sintetizar uma resposta com base nos resultados
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22const formattedResults = formatResults(results.data);// Join the text content of all resultsconst textSources = results.data .map((result) => result.content.map((c) => c.text).join("\n")) .join("\n");const completion = await client.chat.completions.create({ model: "gpt-6-astra", messages: [ { role: "developer", content: "Produce a concise answer to the query based on the provided sources.", }, { role: "user", content: `Sources: ${formattedResults}\n\nQuery: '${userQuery}'`, }, ],});console.log(completion.choices[0].message.content);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20# Use results and user_query from the preceding search step.formatted_results = format_results(results.data)"\n".join("\n".join(c.text for c in result.content) for result in results.data)completion = client.chat.completions.create(model="gpt-6-astra",messages=[ {"role": "developer","content": "Produce a concise answer to the query based on the provided sources.", }, {"role": "user","content": f"Sources: {formatted_results}\n\nQuery: '{user_query}'", }, ],)print(completion.choices[0].message.content)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46package mainimport ( "context" "fmt" "strings" "github.com/openai/openai-go/v3")func main() { client := openai.NewClient() userQuery := "What is the return policy?" results, err := client.VectorStores.Search(context.Background(), "vs_123", openai.VectorStoreSearchParams{ Query: openai.VectorStoreSearchParamsQueryUnion{OfString: openai.String(userQuery)}, }) if err != nil { panic(err) } completion, err := client.Chat.Completions.New(context.Background(), openai.ChatCompletionNewParams{ Model: "gpt-6-astra", Messages: []openai.ChatCompletionMessageParamUnion{ openai.DeveloperMessage("Produce a concise answer to the query based on the provided sources."), openai.UserMessage(fmt.Sprintf("Sources: %s\n\nQuery: %q", formatResults(results.Data), userQuery)), }, }) if err != nil { panic(err) } fmt.Println(completion.Choices[0].Message.Content)}func formatResults(results []openai.VectorStoreSearchResponse) string { var sources strings.Builder sources.WriteString("<sources>") for _, result := range results { fmt.Fprintf(&sources, "<result file_id=%q file_name=%q>", result.FileID, result.Filename) for _, content := range result.Content { fmt.Fprintf(&sources, "<content>%s</content>", content.Text) } sources.WriteString("</result>") } sources.WriteString("</sources>") return sources.String()}