File search

File search (파일 검색)

파일 검색은 Responses API에서 사용할 수 있는 도구예요. 이 도구를 쓰면 미리 업로드한 파일로 구성한 지식 베이스에서 의미 검색(semantic search)과 키워드 검색을 통해 정보를 가져올 수 있어요. 벡터 스토어(vector store)를 만들고 파일을 업로드하면, 이 지식 베이스(vector_stores)에 접근하도록 해서 모델의 타고난 지식을 보강할 수 있어요.

벡터 스토어와 의미 검색이 어떻게 동작하는지 더 알고 싶다면 retrieval 가이드를 참고하세요.

파일 검색은 OpenAI가 관리하는 호스티드 도구예요. 즉 실행을 처리하는 코드를 직접 구현하지 않아도 돼요. 모델이 이 도구를 쓰기로 결정하면 자동으로 호출해서 여러분의 파일에서 정보를 가져와 출력을 돌려줘요.

출처: 문서

본문

사용 방법

Responses API에서 파일 검색을 쓰기 전에, 벡터 스토어에 지식 베이스를 구축하고 파일을 업로드해 두어야 해요.

벡터 스토어 생성과 파일 업로드

벡터 스토어를 만들고 파일을 업로드하려면 다음 단계를 따라요. 예제 파일을 쓰거나 본인 파일을 업로드해도 돼요.

파일을 File API에 업로드

파일 업로드

import fs from "fs";
import OpenAI from "openai";
const openai = new OpenAI();

async function createFile(filePath) {
  let result;
  if (filePath.startsWith("http://") || filePath.startsWith("https://")) {
    // Download the file content from the URL
    const res = await fetch(filePath);
    const buffer = await res.arrayBuffer();
    const file = new File([buffer], fileName);
    result = await openai.files.create({
      file: file,
      purpose: "assistants",
    });
  } else {
    // Handle local file path
    const fileContent = fs.createReadStream(filePath);
    result = await openai.files.create({
      file: fileContent,
      purpose: "assistants",
    });
  }
  return result.id;
}

// Replace with your own file path or URL
const fileId = await createFile(
  "https://cdn.openai.com/API/docs/deep_research_blog.pdf"
);

console.log(fileId);
from io import BytesIO

import requests
from openai import OpenAI

client = OpenAI()


def create_file(client, file_path):
    if file_path.startswith(("http://", "https://")):
        response = requests.get(file_path, timeout=30)
        response.raise_for_status()
        file_content = BytesIO(response.content)
        file_name = file_path.rsplit("/", 1)[-1]
        result = client.files.create(
            file=(file_name, file_content),
            purpose="assistants",
        )
    else:
        with open(file_path, "rb") as file_content:
            result = client.files.create(
                file=file_content,
                purpose="assistants",
            )
    return result.id


file_id = create_file(
    client,
    "https://cdn.openai.com/API/docs/deep_research_blog.pdf",
)
print(file_id)
package main

import (
	"context"
	"fmt"
	"os"

	"github.com/openai/openai-go/v3"
)

func main() {
	file, err := os.Open("customer_policies.txt")
	if err != nil {
		panic(err)
	}
	defer file.Close()

	client := openai.NewClient()
	result, err := client.Files.New(context.Background(), openai.FileNewParams{
		File:    openai.File(file, "customer_policies.txt", "text/plain"),
		Purpose: openai.FilePurposeAssistants,
	})
	if err != nil {
		panic(err)
	}
	fmt.Println(result.ID)
}
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.files.FileCreateParams;
import com.openai.models.files.FilePurpose;
import java.nio.file.Path;

var file =
    client
        .files()
        .create(
            FileCreateParams.builder()
                .file(Path.of(System.getenv("OPENAI_EXAMPLE_FILE_PATH")))
                .purpose(FilePurpose.USER_DATA)
                .build());

System.out.println(file.id());
require "openai"
require "pathname"

client = OpenAI::Client.new
file = Pathname("customer_policies.txt")
uploaded = client.files.create(file: file, purpose: :user_data)
puts(uploaded.id)
벡터 스토어 생성

벡터 스토어 생성

const vectorStore = await openai.vectorStores.create({
  name: "knowledge_base",
});
console.log(vectorStore.id);
vector_store = client.vector_stores.create(name="knowledge_base")
print(vector_store.id)
package main

import (
	"context"
	"fmt"

	"github.com/openai/openai-go/v3"
)

func main() {
	client := openai.NewClient()
	vectorStore, err := client.VectorStores.New(context.Background(), openai.VectorStoreNewParams{
		Name: openai.String("knowledge_base"),
	})
	if err != nil {
		panic(err)
	}
	fmt.Println(vectorStore.ID)
}
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.vectorstores.VectorStoreCreateParams;

var store =
    client
        .vectorStores()
        .create(VectorStoreCreateParams.builder().name("Product docs").build());

System.out.println(store.id());
require "openai"

client = OpenAI::Client.new
store = client.vector_stores.create(name: "Product docs")
puts(store.id)
파일을 벡터 스토어에 추가

벡터 스토어에 파일 추가

// Use vectorStore and fileId from the earlier create and upload steps.
await openai.vectorStores.files.create(vectorStore.id, {
  file_id: fileId,
});
result = client.vector_stores.files.create(
    vector_store_id=vector_store.id,
    file_id=file_id,
)
print(result)
package main

import (
	"context"
	"fmt"

	"github.com/openai/openai-go/v3"
)

func main() {
	client := openai.NewClient()
	file, err := client.VectorStores.Files.New(context.Background(), "<vector_store_id>", openai.VectorStoreFileNewParams{
		FileID: "file_abc123",
	})
	if err != nil {
		panic(err)
	}
	fmt.Println(file.ID)
}
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.vectorstores.files.FileCreateParams;

String vectorStoreId = "<vector_store_id>";

String fileId = "file_abc123";

var file =
    client
        .vectorStores()
        .files()
        .create(vectorStoreId, FileCreateParams.builder().fileId(fileId).build());

System.out.println(file.id());
require "openai"

client = OpenAI::Client.new
file = client.vector_stores.files.create("<vector_store_id>", file_id: "file_abc123")
puts(file.id)
상태 확인

파일이 사용할 준비가 될 때(즉 상태가 completed일 때)까지 이 코드를 실행해요.

상태 확인

// Use vectorStore from the earlier create step.
const result = await openai.vectorStores.files.list(vectorStore.id);
console.log(result);
result = client.vector_stores.files.list(vector_store_id=vector_store.id)
print(result)
package main

import (
	"context"
	"fmt"

	"github.com/openai/openai-go/v3"
)

func main() {
	client := openai.NewClient()
	files, err := client.VectorStores.Files.List(context.Background(), "<vector_store_id>", openai.VectorStoreFileListParams{})
	if err != nil {
		panic(err)
	}
	fmt.Println(files.Data)
}
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;

String vectorStoreId = "<vector_store_id>";

System.out.println(client.vectorStores().files().list(vectorStoreId).data());
require "openai"

client = OpenAI::Client.new
files = client.vector_stores.files.list("<vector_store_id>")
puts(files.data&.map(&:status))

지식 베이스가 준비되면 모델이 사용할 수 있는 도구 목록에 file_search 도구와, 검색할 벡터 스토어 목록을 함께 포함시킬 수 있어요.

File search 도구

import OpenAI from "openai";
const openai = new OpenAI();

const response = await openai.responses.create({
  model: "gpt-6-astra",
  input: "What is deep research by OpenAI?",
  tools: [
    {
      type: "file_search",
      vector_store_ids: ["<vector_store_id>"],
    },
  ],
});
console.log(response);
from openai import OpenAI

client = OpenAI()

response = client.responses.create(
    model="gpt-6-astra",
    input="What is deep research by OpenAI?",
    tools=[{"type": "file_search", "vector_store_ids": ["<vector_store_id>"]}],
)
print(response)
package main

import (
	"context"
	"fmt"

	"github.com/openai/openai-go/v3"
	"github.com/openai/openai-go/v3/responses"
)

func main() {
	client := openai.NewClient()
	response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
		Model: "gpt-6-astra",
		Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("What is deep research by OpenAI?")},
		Tools: []responses.ToolUnionParam{responses.ToolParamOfFileSearch([]string{"<vector_store_id>"})},
	})
	if err != nil {
		panic(err)
	}
	fmt.Println(response)
}
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.responses.ResponseCreateParams;
import java.util.List;

String vectorStoreId = "<vector_store_id>";

ResponseCreateParams params =
    ResponseCreateParams.builder()
        .model("gpt-6-astra")
        .input("What is deep research by OpenAI?")
        .addFileSearchTool(List.of(vectorStoreId))
        .build();

client.responses().create(params).output().stream()
    .flatMap(item -> item.message().stream())
    .flatMap(message -> message.content().stream())
    .flatMap(content -> content.outputText().stream())
    .forEach(text -> System.out.println(text.text()));
using OpenAI.Responses;
#pragma warning disable OPENAI001

string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
string vectorStoreId = "<vector_store_id>";
ResponsesClient client = new(key);

CreateResponseOptions options = new() { Model = "gpt-6-astra" };
options.Tools.Add(
    ResponseTool.CreateFileSearchTool([vectorStoreId])
);
options.InputItems.Add(
    ResponseItem.CreateUserMessageItem("What is deep research by OpenAI?")
);

ResponseResult response = await client.CreateResponseAsync(options);

Console.WriteLine(response.GetOutputText());
require "openai"

openai = OpenAI::Client.new

response = openai.responses.create(
  model: "gpt-6-astra",
  input: "What is deep research by OpenAI?",
  tools: [
    {
      type: "file_search",
      vector_store_ids: ["<vector_store_id>"]
    }
  ]
)

puts(response)

모델이 이 도구를 호출하면 여러 출력이 담긴 응답을 받게 돼요.

  1. file_search_call 출력 항목 — 파일 검색 호출의 id를 담고 있어요.
  2. message 출력 항목 — 모델의 응답과 파일 인용(file citations)을 담고 있어요.

File search 응답

{
  "output": [
    {
      "type": "file_search_call",
      "id": "fs_67c09ccea8c48191ade9367e3ba71515",
      "status": "completed",
      "queries": ["What is deep research?"],
      "search_results": null
    },
    {
      "id": "msg_67c09cd3091c819185af2be5d13d87de",
      "type": "message",
      "role": "assistant",
      "content": [
        {
          "type": "output_text",
          "text": "Deep research is a sophisticated capability that allows for extensive inquiry and synthesis of information across various domains. It is designed to conduct multi-step research tasks, gather data from multiple online sources, and provide comprehensive reports similar to what a research analyst would produce. This functionality is particularly useful in fields requiring detailed and accurate information...",
          "annotations": [
            {
              "type": "file_citation",
              "index": 992,
              "file_id": "file-2dtbBZdjtDKS8eqWxqbgDi",
              "filename": "deep_research_blog.pdf"
            },
            {
              "type": "file_citation",
              "index": 992,
              "file_id": "file-2dtbBZdjtDKS8eqWxqbgDi",
              "filename": "deep_research_blog.pdf"
            },
            {
              "type": "file_citation",
              "index": 1176,
              "file_id": "file-2dtbBZdjtDKS8eqWxqbgDi",
              "filename": "deep_research_blog.pdf"
            },
            {
              "type": "file_citation",
              "index": 1176,
              "file_id": "file-2dtbBZdjtDKS8eqWxqbgDi",
              "filename": "deep_research_blog.pdf"
            }
          ]
        }
      ]
    }
  ]
}

검색 맞춤 설정 (Retrieval customization)

결과 수 제한

Responses API에서 파일 검색 도구를 사용하면 벡터 스토어에서 가져올 결과 수를 맞춤 설정할 수 있어요. 이렇게 하면 토큰 사용량과 지연 시간을 줄이는 데 도움이 되지만, 답변 품질이 떨어질 수 있어요.

결과 수 제한

const response = await openai.responses.create({
  model: "gpt-6-astra",
  input: "What is deep research by OpenAI?",
  tools: [
    {
      type: "file_search",
      vector_store_ids: ["<vector_store_id>"],
      // highlight-start
      max_num_results: 2,
      // highlight-end
    },
  ],
});
console.log(response);
response = client.responses.create(
    model="gpt-6-astra",
    input="What is deep research by OpenAI?",
    tools=[
        {
            "type": "file_search",
            "vector_store_ids": ["<vector_store_id>"],
            # highlight-start
            "max_num_results": 2,
            # highlight-end
        }
    ],
)
print(response)
package main

import (
	"context"
	"fmt"

	"github.com/openai/openai-go/v3"
	"github.com/openai/openai-go/v3/responses"
)

func main() {
	client := openai.NewClient()
	tool := responses.ToolParamOfFileSearch([]string{"<vector_store_id>"})
	tool.OfFileSearch.MaxNumResults = openai.Int(2)
	response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
		Model: "gpt-6-astra",
		Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("What is deep research by OpenAI?")},
		Tools: []responses.ToolUnionParam{tool},
	})
	if err != nil {
		panic(err)
	}
	fmt.Println(response)
}
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.responses.FileSearchTool;
import com.openai.models.responses.ResponseCreateParams;

String vectorStoreId = "<vector_store_id>";

ResponseCreateParams params =
    ResponseCreateParams.builder()
        .model("gpt-6-astra")
        .input("What is deep research by OpenAI?")
        .addTool(
            FileSearchTool.builder().addVectorStoreId(vectorStoreId).maxNumResults(2).build())
        .build();

client.responses().create(params).output().stream()
    .flatMap(item -> item.message().stream())
    .flatMap(message -> message.content().stream())
    .flatMap(content -> content.outputText().stream())
    .forEach(text -> System.out.println(text.text()));
using OpenAI.Responses;
#pragma warning disable OPENAI001

string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
// Replace this illustrative ID with your vector store ID.
string vectorStoreId = "<vector_store_id>";
ResponsesClient client = new(key);

CreateResponseOptions options = new() { Model = "gpt-6-astra" };
options.Tools.Add(
    ResponseTool.CreateFileSearchTool([vectorStoreId], maxResultCount: 2)
);
options.InputItems.Add(
    ResponseItem.CreateUserMessageItem("What is deep research by OpenAI?")
);

ResponseResult response = await client.CreateResponseAsync(options);
Console.WriteLine(response.GetOutputText());
require "openai"

client = OpenAI::Client.new

response = client.responses.create(
  model: "gpt-6-astra",
  input: "What is deep research by OpenAI?",
  tools: [
    {
      type: :file_search,
      vector_store_ids: ["<vector_store_id>"],
      max_num_results: 2
    }
  ]
)

puts(response)

응답에 검색 결과 포함하기

출력 텍스트에서는 파일 참조(annotation)를 볼 수 있지만, 파일 검색 호출은 기본적으로 검색 결과를 돌려주지 않아요.

검색 결과를 응답에 포함하려면 응답을 만들 때 include 파라미터를 사용하면 돼요.

검색 결과 포함

const response = await openai.responses.create({
  model: "gpt-6-astra",
  input: "What is deep research by OpenAI?",
  tools: [
    {
      type: "file_search",
      vector_store_ids: ["<vector_store_id>"],
    },
  ],
  // highlight-start
  include: ["file_search_call.results"],
  // highlight-end
});
console.log(response);
response = client.responses.create(
    model="gpt-6-astra",
    input="What is deep research by OpenAI?",
    tools=[
        {
            "type": "file_search",
            "vector_store_ids": ["<vector_store_id>"],
        }
    ],
    # highlight-start
    include=["file_search_call.results"],
    # highlight-end
)
print(response)
package main

import (
	"context"
	"fmt"

	"github.com/openai/openai-go/v3"
	"github.com/openai/openai-go/v3/responses"
)

func main() {
	client := openai.NewClient()
	response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
		Model:   "gpt-6-astra",
		Input:   responses.ResponseNewParamsInputUnion{OfString: openai.String("What is deep research by OpenAI?")},
		Tools:   []responses.ToolUnionParam{responses.ToolParamOfFileSearch([]string{"<vector_store_id>"})},
		Include: []responses.ResponseIncludable{responses.ResponseIncludableFileSearchCallResults},
	})
	if err != nil {
		panic(err)
	}
	fmt.Println(response)
}
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.responses.ResponseCreateParams;
import com.openai.models.responses.ResponseIncludable;
import java.util.List;

String vectorStoreId = "<vector_store_id>";

ResponseCreateParams params =
    ResponseCreateParams.builder()
        .model("gpt-6-astra")
        .input("What is deep research by OpenAI?")
        .addInclude(ResponseIncludable.of("file_search_call.results"))
        .addFileSearchTool(List.of(vectorStoreId))
        .build();

client.responses().create(params).output().stream()
    .flatMap(item -> item.fileSearchCall().stream())
    .flatMap(call -> call.results().stream())
    .flatMap(List::stream)
    .forEach(System.out::println);
using OpenAI.Responses;
#pragma warning disable OPENAI001

string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
// Replace this illustrative ID with your vector store ID.
string vectorStoreId = "<vector_store_id>";
ResponsesClient client = new(key);

CreateResponseOptions options = new() { Model = "gpt-6-astra" };
options.Tools.Add(ResponseTool.CreateFileSearchTool([vectorStoreId]));
options.IncludedProperties.Add(IncludedResponseProperty.FileSearchCallResults);
options.InputItems.Add(
    ResponseItem.CreateUserMessageItem("What is deep research by OpenAI?")
);

ResponseResult response = await client.CreateResponseAsync(options);
foreach (FileSearchCallResponseItem search in response.OutputItems.OfType<FileSearchCallResponseItem>())
{
    foreach (FileSearchCallResult result in search.Results)
    {
        Console.WriteLine($"{result.Filename}: {result.Text}");
    }
}
require "openai"

client = OpenAI::Client.new

response = client.responses.create(
  model: "gpt-6-astra",
  input: "What is deep research by OpenAI?",
  include: ["file_search_call.results"],
  tools: [
    {
      type: :file_search,
      vector_store_ids: ["<vector_store_id>"]
    }
  ]
)

puts(response)

메타데이터 필터링

파일의 메타데이터를 기준으로 검색 결과를 필터링할 수 있어요. 자세한 내용은 retrieval 가이드를 참고하세요. 거기서 다음을 다뤄요.

메타데이터 필터링

const response = await openai.responses.create({
  model: "gpt-6-astra",
  input: "What is deep research by OpenAI?",
  tools: [
    {
      type: "file_search",
      vector_store_ids: ["<vector_store_id>"],
      // highlight-start
      filters: {
        type: "in",
        key: "category",
        value: ["blog", "announcement"],
      },
      // highlight-end
    },
  ],
});
console.log(response);
response = client.responses.create(
    model="gpt-6-astra",
    input="What is deep research by OpenAI?",
    tools=[
        {
            "type": "file_search",
            "vector_store_ids": ["<vector_store_id>"],
            # highlight-start
            "filters": {
                "type": "in",
                "key": "category",
                "value": ["blog", "announcement"],
            },
            # highlight-end
        }
    ],
)
print(response)
package main

import (
	"context"
	"fmt"

	"github.com/openai/openai-go/v3"
	"github.com/openai/openai-go/v3/responses"
	"github.com/openai/openai-go/v3/shared"
)

func main() {
	client := openai.NewClient()
	tool := responses.ToolParamOfFileSearch([]string{"<vector_store_id>"})
	tool.OfFileSearch.Filters = responses.FileSearchToolFiltersUnionParam{
		OfComparisonFilter: &shared.ComparisonFilterParam{
			Type: shared.ComparisonFilterTypeIn,
			Key:  "category",
			Value: shared.ComparisonFilterValueUnionParam{OfComparisonFilterValueArray: []shared.ComparisonFilterValueArrayItemUnionParam{
				{OfString: openai.String("blog")},
				{OfString: openai.String("announcement")},
			}},
		},
	}
	response, err := client.Responses.New(context.Background(), responses.ResponseNewParams{
		Model: "gpt-6-astra",
		Input: responses.ResponseNewParamsInputUnion{OfString: openai.String("What is deep research by OpenAI?")},
		Tools: []responses.ToolUnionParam{tool},
	})
	if err != nil {
		panic(err)
	}
	fmt.Println(response)
}
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.ComparisonFilter;
import com.openai.models.responses.FileSearchTool;
import com.openai.models.responses.ResponseCreateParams;
import java.util.List;

String vectorStoreId = "<vector_store_id>";

ResponseCreateParams params =
    ResponseCreateParams.builder()
        .model("gpt-6-astra")
        .input("What is deep research by OpenAI?")
        .addTool(
            FileSearchTool.builder()
                .addVectorStoreId(vectorStoreId)
                .filters(
                    ComparisonFilter.builder()
                        .type(ComparisonFilter.Type.IN)
                        .key("category")
                        .valueOfComparisonFilterValueItems(
                            List.of(
                                ComparisonFilter.Value.ComparisonFilterValueItem.ofString(
                                    "blog"),
                                ComparisonFilter.Value.ComparisonFilterValueItem.ofString(
                                    "announcement")))
                        .build())
                .build())
        .build();

client.responses().create(params).output().stream()
    .flatMap(item -> item.message().stream())
    .flatMap(message -> message.content().stream())
    .flatMap(content -> content.outputText().stream())
    .forEach(text -> System.out.println(text.text()));
using OpenAI.Responses;
#pragma warning disable OPENAI001

string key = Environment.GetEnvironmentVariable("OPENAI_API_KEY")!;
// Replace this illustrative ID with your vector store ID.
string vectorStoreId = "<vector_store_id>";
ResponsesClient client = new(key);

BinaryData filters = BinaryData.FromString(
    """
    { "type": "in", "key": "category", "value": ["blog", "announcement"] }
    """
);
CreateResponseOptions options = new() { Model = "gpt-6-astra" };
options.Tools.Add(
    ResponseTool.CreateFileSearchTool([vectorStoreId], filters: filters)
);
options.InputItems.Add(
    ResponseItem.CreateUserMessageItem("What is deep research by OpenAI?")
);

ResponseResult response = await client.CreateResponseAsync(options);
Console.WriteLine(response.GetOutputText());
require "openai"

client = OpenAI::Client.new

response = client.responses.create(
  model: "gpt-6-astra",
  input: "What is deep research by OpenAI?",
  tools: [
    {
      type: :file_search,
      vector_store_ids: ["<vector_store_id>"],
      filters: {
        type: :in,
        key: "category",
        value: ["blog", "announcement"]
      }
    }
  ]
)

puts(response)

지원되는 파일

text/ MIME 타입의 경우 인코딩은 utf-8, utf-16, ascii 중 하나여야 해요.

파일 형식 MIME 타입
.c text/x-c
.cpp text/x-c++
.cs text/x-csharp
.css text/css
.doc application/msword
.docx application/vnd.openxmlformats-officedocument.wordprocessingml.document
.go text/x-golang
.html text/html
.java text/x-java
.js text/javascript
.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
.sh application/x-sh
.tex text/x-tex
.ts application/typescript
.txt text/plain

사용 참고 사항

API 가용성 Rate limits 참고
[Responses](https://developers.openai.com/api/reference/resources/responses)



[Chat Completions](https://developers.openai.com/api/reference/resources/chat)



[Assistants](https://developers.openai.com/api/reference/resources/beta/subresources/assistants)
**Tier 1**

100 RPM

Tier 2 and 3

500 RPM

Tier 4 and 5

1000 RPM

[Pricing](https://developers.openai.com/api/docs/pricing#built-in-tools)

ZDR and data residency

더 알아보기 (Learn more)