Ferramenta de pesquisa de ficheiros do Azure OpenAI Assistants (Pré-visualização)
A Pesquisa de Ficheiros aumenta o conhecimento do Assistente externo ao seu modelo, como informações proprietárias do produto ou documentos fornecidos pelos utilizadores. O OpenAI analisa e fragmenta automaticamente os seus documentos, cria e armazena as incorporações e utiliza a pesquisa de vetores e de palavras-chave para obter conteúdo relevante para responder às consultas do utilizador.
Importante
- A pesquisa de ficheiros tem custos adicionais além das taxas baseadas no token de utilização do Azure OpenAI.
Nota
- A pesquisa de arquivos pode ingerir até 10.000 arquivos por assistente - 500 vezes mais do que antes. É rápida, suporta consultas paralelas através de pesquisas multi-thread e apresenta reclassificação e reescrita de consultas melhoradas.
- O arquivo de vetores é um novo objeto da API. Depois de um ficheiro ser adicionado a um arquivo de vetores, é automaticamente analisado, fragmentado e incorporado, ficando pronto para ser pesquisado. Os arquivos de vetores podem ser utilizados entre assistentes e threads, o que simplifica a gestão de ficheiros e a faturação.
- Adicionamos suporte para o
tool_choice
parâmetro que pode ser usado para forçar o uso de uma ferramenta específica (como pesquisa de arquivos, interpretador de código ou uma função) em uma execução específica.
Suporte à pesquisa de ficheiros
Regiões suportadas
A pesquisa de ficheiros está disponível em regiões que suportam Assistentes.
Versão da API
- 2024-05-01-pré-visualização
Tipos de ficheiro suportados
Nota
Para tipos de texto/MIME, a codificação deve ser utf-8, utf-16 ou ASCII.
File format | Tipo de MIME |
---|---|
c. | texto/x-c |
.cs | texto/x-csharp |
.cpp | texto/x-c++ |
.doc | aplicação/msword |
.docx | aplicativo/vnd.openxmlformats-officedocument.wordprocessingml.document |
.html | text/html |
.java | texto/x-java |
.json | application/json |
.md | texto/marcação |
aplicação/pdf | |
.php | texto/x-php |
.pptx | application/vnd.openxmlformats-officedocument.presentationml.presentation |
.py | texto/x-python |
.py | texto/x-script.python |
.rb | texto/x-rubi |
.tex | texto/x-tex |
.txt | text/plain |
.css | texto/css |
.js | texto/javascript |
.sh | aplicação/x-sh |
.ts | aplicação/typescript |
Ativar pesquisa de ficheiros
from openai import AzureOpenAI
client = AzureOpenAI(
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
api_version="2024-05-01-preview",
azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
)
assistant = client.beta.assistants.create(
name="Financial Analyst Assistant",
instructions="You are an expert financial analyst. Use your knowledge base to answer questions about audited financial statements.",
model="gpt-4-turbo",
tools=[{"type": "file_search"}],
)
Carregar ficheiros para pesquisa de ficheiros
Para acessar seus arquivos, a ferramenta de pesquisa de arquivos usa o objeto de armazenamento vetorial. Carregue seus arquivos e crie um repositório vetorial para contê-los. Depois que o repositório vetorial for criado, você deve pesquisar seu status até que todos os arquivos estejam fora do estado para garantir que todo o conteúdo tenha terminado o in_progress
processamento. O SDK fornece auxiliares para upload e sondagem.
from openai import AzureOpenAI
client = AzureOpenAI(
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
api_version="2024-05-01-preview",
azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
)
# Create a vector store called "Financial Statements"
vector_store = client.beta.vector_stores.create(name="Financial Statements")
# Ready the files for upload to OpenAI
file_paths = ["mydirectory/myfile1.pdf", "mydirectory/myfile2.txt"]
file_streams = [open(path, "rb") for path in file_paths]
# Use the upload and poll SDK helper to upload the files, add them to the vector store,
# and poll the status of the file batch for completion.
file_batch = client.beta.vector_stores.file_batches.upload_and_poll(
vector_store_id=vector_store.id, files=file_streams
)
# You can print the status and the file counts of the batch to see the result of this operation.
print(file_batch.status)
print(file_batch.file_counts)
Atualizar o assistente para usar o novo repositório de vetores
Para tornar os ficheiros acessíveis ao seu assistente, atualize os do tool_resources
assistente com o novo vector_store
ID.
assistant = client.beta.assistants.update(
assistant_id=assistant.id,
tool_resources={"file_search": {"vector_store_ids": [vector_store.id]}},
)
Criar um thread
Você também pode anexar arquivos como anexos de mensagem no seu thread. Isso criará outro vector_store
associado ao thread ou, se já houver um repositório de vetores anexado a esse thread, anexará os novos arquivos ao repositório de vetores de thread existente. Quando você cria um Executar neste thread, a ferramenta de pesquisa de arquivos consultará o vector_store
do seu assistente e o vector_store
no thread.
# Upload the user provided file to OpenAI
message_file = client.files.create(
file=open("mydirectory/myfile.pdf", "rb"), purpose="assistants"
)
# Create a thread and attach the file to the message
thread = client.beta.threads.create(
messages=[
{
"role": "user",
"content": "How many company shares were outstanding last quarter?",
# Attach the new file to the message.
"attachments": [
{ "file_id": message_file.id, "tools": [{"type": "file_search"}] }
],
}
]
)
# The thread now has a vector store with that file in its tool resources.
print(thread.tool_resources.file_search)
Os repositórios de vetores são criados usando anexos de mensagens que têm uma política de expiração padrão de sete dias após terem sido ativos pela última vez (definidos como a última vez que o repositório de vetores fez parte de uma execução). Esse padrão existe para ajudá-lo a gerenciar seus custos de armazenamento vetorial. Você pode substituir essas políticas de expiração a qualquer momento.
Crie uma execução e verifique a saída
Crie uma Execução e observe que o modelo usa a ferramenta de pesquisa de arquivos para fornecer uma resposta à pergunta do usuário.
from typing_extensions import override
from openai import AssistantEventHandler, OpenAI
client = OpenAI()
class EventHandler(AssistantEventHandler):
@override
def on_text_created(self, text) -> None:
print(f"\nassistant > ", end="", flush=True)
@override
def on_tool_call_created(self, tool_call):
print(f"\nassistant > {tool_call.type}\n", flush=True)
@override
def on_message_done(self, message) -> None:
# print a citation to the file searched
message_content = message.content[0].text
annotations = message_content.annotations
citations = []
for index, annotation in enumerate(annotations):
message_content.value = message_content.value.replace(
annotation.text, f"[{index}]"
)
if file_citation := getattr(annotation, "file_citation", None):
cited_file = client.files.retrieve(file_citation.file_id)
citations.append(f"[{index}] {cited_file.filename}")
print(message_content.value)
print("\n".join(citations))
# Then, we use the stream SDK helper
# with the EventHandler class to create the Run
# and stream the response.
with client.beta.threads.runs.stream(
thread_id=thread.id,
assistant_id=assistant.id,
instructions="Please address the user as Jane Doe. The user has a premium account.",
event_handler=EventHandler(),
) as stream:
stream.until_done()
Como funciona
A ferramenta de pesquisa de arquivos implementa várias práticas recomendadas de recuperação prontas para uso para ajudá-lo a extrair os dados certos de seus arquivos e aumentar as respostas do modelo. A ferramenta file_search:
- Reescreve as consultas do usuário para otimizá-las para pesquisa.
- Divide consultas complexas de usuários em várias pesquisas que podem ser executadas em paralelo.
- Executa pesquisas semânticas e de palavras-chave em repositórios de vetores de assistente e thread.
- Reclassifica os resultados da pesquisa para escolher os mais relevantes antes de gerar a resposta final.
- Por padrão, a ferramenta de pesquisa de arquivos usa as seguintes configurações:
- Tamanho do bloco: 800 tokens
- Sobreposição de blocos: 400 tokens
- Modelo de incorporação: text-embedding-3-large em 256 dimensões
- Número máximo de partes adicionadas ao contexto: 20
Repositórios vetoriais
Os objetos de armazenamento vetorial dão à ferramenta de pesquisa de arquivos a capacidade de pesquisar seus arquivos. Adicionar um arquivo a um repositório vetorial analisa, fragmenta, incorpora e armazena automaticamente o arquivo em um banco de dados vetorial capaz de pesquisa semântica e de palavras-chave. Cada armazenamento vetorial pode armazenar até 10.000 arquivos. Os armazenamentos vetoriais podem ser anexados a Assistentes e Threads. Atualmente, você pode anexar no máximo um repositório de vetores a um assistente e, no máximo, um armazenamento de vetores a um thread.
Criação de repositórios vetoriais e adição de arquivos
Você pode criar um repositório vetorial e adicionar arquivos a ele em uma única chamada de API:
vector_store = client.beta.vector_stores.create(
name="Product Documentation",
file_ids=['file_1', 'file_2', 'file_3', 'file_4', 'file_5']
)
Adicionar arquivos a repositórios vetoriais é uma operação assíncrona. Para garantir que a operação seja concluída, recomendamos que você use os auxiliares de 'criar e pesquisar' em nossos SDKs oficiais. Se você não estiver usando os SDKs, poderá recuperar o vector_store
objeto e monitorar sua file_counts
propriedade para ver o resultado da operação de ingestão de arquivos.
Os ficheiros também podem ser adicionados a um arquivo de vetores depois deste ser criado.
file = client.beta.vector_stores.files.create_and_poll(
vector_store_id="vs_abc123",
file_id="file-abc123"
)
Como alternativa, você pode adicionar vários arquivos a um repositório vetorial criando lotes de até 500 arquivos.
batch = client.beta.vector_stores.file_batches.create_and_poll(
vector_store_id="vs_abc123",
file_ids=['file_1', 'file_2', 'file_3', 'file_4', 'file_5']
)
Da mesma forma, estes ficheiros podem ser removidos de um arquivo de vetores ao:
- Eliminar o objeto de ficheiro do arquivo de vetores.
- Eliminar o objeto de ficheiro subjacente (que remove o ficheiro de todas as configurações de vetor_store e code_interpreter em todos os assistentes e threads na sua organização).
O tamanho máximo do ficheiro é de 512 MB. Cada ficheiro não deve conter mais de 5 000 000 tokens por ficheiro (calculado automaticamente quando anexa um ficheiro).
Anexando repositórios vetoriais
Você pode anexar armazenamentos de vetores ao seu Assistente ou Thread usando o parâmetro tool_resources.
assistant = client.beta.assistants.create(
instructions="You are a helpful product support assistant and you answer questions based on the files provided to you.",
model="gpt-4-turbo",
tools=[{"type": "file_search"}],
tool_resources={
"file_search": {
"vector_store_ids": ["vs_1"]
}
}
)
thread = client.beta.threads.create(
messages=[ { "role": "user", "content": "How do I cancel my subscription?"} ],
tool_resources={
"file_search": {
"vector_store_ids": ["vs_2"]
}
}
)
Você também pode anexar um repositório de vetores a Threads ou Assistentes depois que eles forem criados, atualizando-os com o direito tool_resources
.
Garantindo a prontidão do armazenamento vetorial antes de criar execuções
É altamente recomendável que você garanta que todos os arquivos em um vetor_store sejam totalmente processados antes de criar uma execução. Isso garante que todos os dados em seu armazenamento de vetores sejam pesquisáveis. Você pode verificar a prontidão do armazenamento de vetores usando os auxiliares de sondagem nos SDKs ou sondando manualmente o vector_store
objeto para garantir que o status seja concluído.
Como fallback, há uma espera máxima de 60 segundos no objeto run quando o armazenamento vetorial do thread contém arquivos que ainda estão sendo processados. Isso é para garantir que todos os arquivos que seus usuários carregam em um thread sejam totalmente pesquisáveis antes que a execução prossiga. Essa espera de fallback não se aplica ao armazenamento de vetores do assistente.
Gerenciando custos com políticas de expiração
A file_search
ferramenta usa o vector_stores
objeto como seu recurso e você será cobrado com base no tamanho dos vetor_store objetos criados. O tamanho do objeto de armazenamento de vetor é a soma de todos os blocos analisados de seus arquivos e suas incorporações correspondentes.
Para ajudá-lo a gerenciar os custos associados a esses objetos vetor_store, adicionamos suporte para políticas de expiração no vector_store
objeto. Você pode definir essas políticas ao criar ou atualizar o vector_store
objeto.
vector_store = client.beta.vector_stores.create_and_poll(
name="Product Documentation",
file_ids=['file_1', 'file_2', 'file_3', 'file_4', 'file_5'],
expires_after={
"anchor": "last_active_at",
"days": 7
}
)
Os repositórios de vetores de thread têm políticas de expiração padrão
Os repositórios de vetores criados usando auxiliares de thread (como tool_resources.file_search.vector_stores
em Threads ou message.attachments
em Mensagens) têm uma política de expiração padrão de sete dias após terem sido ativos pela última vez (definidos como a última vez que o repositório de vetores fez parte de uma execução).
Quando um repositório vetorial expira, as execuções nesse thread falharão. Para corrigir isso, você pode recriar um novo vetor_store com os mesmos arquivos e reanexá-lo ao thread.
all_files = list(client.beta.vector_stores.files.list("vs_expired"))
vector_store = client.beta.vector_stores.create(name="rag-store")
client.beta.threads.update(
"thread_abc123",
tool_resources={"file_search": {"vector_store_ids": [vector_store.id]}},
)
for file_batch in chunked(all_files, 100):
client.beta.vector_stores.file_batches.create_and_poll(
vector_store_id=vector_store.id, file_ids=[file.id for file in file_batch]
)