다음을 통해 공유


Azure OpenAI 도우미 파일 검색 도구(미리 보기)

파일 검색은 독점 제품 정보나 사용자가 제공한 문서 등 모델 외부의 지식으로 도우미를 강화합니다. OpenAI는 자동으로 문서를 구문 분석 및 청크하고, 포함을 만들기 및 저장하며, 벡터 및 키워드 검색을 모두 사용하여 관련 콘텐츠를 쿼리하여 사용자 쿼리에 답변합니다.

Important

  • 파일 검색에는 Azure OpenAI 사용에 대한 토큰 기반 요금 외에 추가 요금이 있습니다.

참고 항목

  • 파일 검색은 도우미당 최대 10,000개의 파일을 수집할 수 있으며, 이는 이전보다 500배 이상 높은 수치입니다. 빠르고 다중 스레드 검색을 통해 병렬 쿼리를 지원하며 향상된 순위 재지정 및 쿼리 다시 쓰기 기능을 제공합니다.
    • 벡터 저장소는 API의 새 개체입니다. 파일이 벡터 저장소에 추가되면 자동으로 구문 분석, 청크 분할, 포함되어 검색할 수 있는 상태가 됩니다. 벡터 저장소는 도우미와 스레드에서 사용할 수 있으므로 파일 관리 및 청구를 간소화합니다.
  • 특정 실행에서 특정 도구(예: 파일 검색, 코드 인터프리터, 함수)를 강제로 사용하는 데 사용할 수 있는 tool_choice 매개 변수에 대한 지원이 추가되었습니다.

파일 검색 지원

지원되는 지역

파일 검색은 도우미를 지원하는 지역에서 사용할 수 있습니다.

API 버전

  • 2024-05-01-preview

지원되는 파일 형식

참고 항목

텍스트/MIME 형식의 경우 인코딩은 utf-8, utf-16 또는 ASCII여야 합니다.

파일 형식 MIME 형식
c. text/x-c
.cs text/x-csharp
.cpp text/x-c++
.doc application/msword
.docx application/vnd.openxmlformats-officedocument.wordprocessingml.document
.html text/html
.java text/x-java
json. application/json
.md text/markdown
.pdf application/pdf
.php text/x-php
.pptx application/vnd.openxmlformats-officedocument.presentationml.presentation
.py text/x-python
.py text/x-script.python
.rb text/x-ruby
.tex text/x-tex
.txt text/plain
.css 텍스트/css
.js text/javascript
sh. application/x-sh
.ts application/typescript
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"}],
)

파일에 액세스하기 위해 파일 검색 도구는 벡터 저장소 개체를 사용합니다. 파일을 업로드하고 해당 파일을 저장할 벡터 저장소를 만듭니다. 벡터 저장소가 만들어지면 모든 콘텐츠가 처리를 완료했는지 확인하기 위해 모든 파일이 in_progress 상태를 벗어날 때까지 상태를 폴링해야 합니다. SDK는 업로드 및 폴링을 위한 도우미를 제공합니다.

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)

새로운 벡터 저장소를 사용하도록 도우미 업데이트

도우미가 파일에 액세스할 수 있도록 하려면 도우미의 tool_resources를 새 vector_store ID로 업데이트합니다.

assistant = client.beta.assistants.update(
  assistant_id=assistant.id,
  tool_resources={"file_search": {"vector_store_ids": [vector_store.id]}},
)

스레드 만들기

스레드에 메시지 첨부 파일로 파일을 첨부할 수도 있습니다. 이렇게 하면 스레드와 연결된 또 다른 vector_store가 만들어집니다. 또는 이 스레드에 이미 연결된 벡터 저장소가 있는 경우 새 파일을 기존 스레드 벡터 저장소에 연결합니다. 이 스레드에서 실행을 만들면 파일 검색 도구는 도우미의 vector_store와 스레드의 vector_store를 모두 쿼리합니다.

# 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)

벡터 저장소는 마지막으로 활성화된 후 7일(벡터 저장소가 실행의 일부였던 마지막 시간으로 정의됨)의 기본 만료 정책이 있는 메시지 첨부 파일을 사용하여 만들어집니다. 이 기본값은 벡터 스토리지 비용을 관리하는 데 도움이 되도록 존재합니다. 언제든지 이러한 만료 정책을 재정의할 수 있습니다.

실행을 만들고 출력을 확인합니다.

실행을 만들고 모델이 파일 검색 도구를 사용하여 사용자의 질문에 대한 응답을 제공하는 것을 관찰합니다.

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()

작동 방식

파일 검색 도구는 파일에서 올바른 데이터를 추출하고 모델의 응답을 강화하는 데 도움이 되는 몇 가지 검색 모범 사례를 즉시 구현합니다. file_search 도구:

  • 사용자 쿼리를 다시 작성하여 검색에 최적화합니다.
  • 복잡한 사용자 쿼리를 병렬로 실행할 수 있는 여러 검색으로 분류합니다.
  • 도우미 및 스레드 벡터 저장소 모두에서 키워드 및 의미 체계 검색을 모두 실행합니다.
  • 최종 응답을 생성하기 전에 검색 결과의 순위를 다시 지정하여 가장 관련성이 높은 항목을 선택합니다.
  • 기본적으로 파일 검색 도구는 다음 설정을 사용합니다.
    • 청크 크기: 토큰 800개
    • 청크 중복: 토큰 400개
    • 포함 모델: 256차원의 text-embedding-3-large
    • 컨텍스트에 추가되는 최대 청크 수: 20

벡터 저장소

벡터 저장소 개체는 파일 검색 도구에 파일을 검색하는 기능을 제공합니다. 벡터 저장소에 파일을 추가하면 키워드 및 의미 체계 검색이 모두 가능한 벡터 데이터베이스에 파일을 자동으로 구문 분석하고, 청크하고, 포함하고, 저장합니다. 각 벡터 저장소에는 최대 10,000개의 파일을 저장할 수 있습니다. 벡터 저장소는 도우미와 스레드 모두에 연결할 수 있습니다. 현재 최대 하나의 벡터 저장소를 도우미에 연결할 수 있으며 최대 하나의 벡터 저장소를 스레드에 연결할 수 있습니다.

벡터 저장소 만들기 및 파일 추가

단일 API 호출로 벡터 저장소를 만들고 여기에 파일을 추가할 수 있습니다.

vector_store = client.beta.vector_stores.create(
  name="Product Documentation",
  file_ids=['file_1', 'file_2', 'file_3', 'file_4', 'file_5']
)

벡터 저장소에 파일을 추가하는 것은 비동기 작업입니다. 작업이 완료되었는지 확인하려면 공식 SDK의 '만들기 및 폴링' 도우미를 사용하는 것이 좋습니다. SDK를 사용하지 않는 경우에는 vector_store 개체를 검색하고 해당 file_counts 속성을 모니터링하여 파일 수집 작업의 결과를 확인할 수 있습니다.

벡터 저장소 파일을 만들어 만들어진 벡터 저장소에 파일을 추가할 수도 있습니다.

file = client.beta.vector_stores.files.create_and_poll(
  vector_store_id="vs_abc123",
  file_id="file-abc123"
)

또는 최대 500개 파일의 일괄 처리를 만들어 벡터 저장소에 여러 파일을 추가할 수 있습니다.

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']
)

마찬가지로, 다음 중 한 가지 방법으로 이러한 파일을 벡터 저장소에서 제거할 수 있습니다.

  • 벡터 저장소 파일 개체 삭제 또는
  • 기본 파일 개체 삭제(조직의 모든 도우미 및 스레드에 걸쳐 모든 vector_store 및 code_interpreter 구성에서 파일을 제거함)

최대 파일 크기는 512MB입니다. 각 파일에는 파일당 5,000,000개 이하의 토큰이 포함되어야 합니다(파일을 첨부할 때 자동으로 컴퓨팅됨).

벡터 저장소 연결

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"]
    }
  }
)

스레드나 도우미가 만들어진 후 올바른 tool_resources로 업데이트하여 벡터 저장소를 연결할 수도 있습니다.

실행을 만들기 전에 벡터 저장소 준비 상태 확인

실행을 만들기 전에 vector_store의 모든 파일이 완전히 처리되었는지 확인하는 것이 좋습니다. 이렇게 하면 벡터 저장소의 모든 데이터를 검색할 수 있습니다. SDK의 폴링 도우미를 사용하거나 vector_store 개체를 수동으로 폴링하여 상태가 완료되었는지 확인하여 벡터 저장소 준비 상태를 확인할 수 있습니다.

대체적으로 스레드의 벡터 저장소에 아직 처리 중인 파일이 포함되어 있는 경우 실행 개체에서 최대 60초의 대기 시간이 있습니다. 이는 실행이 진행되기 전에 사용자가 스레드에 업로드하는 모든 파일을 완전히 검색할 수 있도록 하기 위한 것입니다. 이 대체 대기는 도우미의 벡터 저장소에 적용되지 않습니다.

만료 정책으로 비용 관리

file_search 도구는 vector_stores 개체를 리소스로 사용하며 만들어진 vector_store 개체의 크기에 따라 요금이 청구됩니다. 벡터 저장소 개체의 크기는 파일에서 구문 분석된 모든 청크와 해당 포함의 합계입니다.

이러한 vector_store 개체와 관련된 비용을 관리하는 데 도움이 되도록 vector_store 개체에 만료 정책에 대한 지원을 추가했습니다. vector_store 개체를 만들거나 업데이트할 때 이러한 정책을 설정할 수 있습니다.

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
  }
)

스레드 벡터 저장소에는 기본 만료 정책이 있습니다.

스레드 도우미(예: 스레드의 tool_resources.file_search.vector_stores 또는 메시지의 message.attachments)를 사용하여 만들어진 벡터 저장소에는 마지막으로 활성화된 후 7일이라는 기본 만료 정책이 있습니다(벡터 저장소가 마지막으로 실행의 일부였던 시간으로 정의됨).

벡터 저장소가 만료되면 해당 스레드에서의 실행이 실패합니다. 이 문제를 해결하려면 동일한 파일로 새 vector_store를 다시 만들고 스레드에 다시 연결할 수 있습니다.

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]
    )