initial commit for Azure RAG cookbook (#1272)
Co-authored-by: juston <96567547+justonf@users.noreply.github.com>pull/1328/head
parent
f6ea13ebed
commit
5f552669f7
@ -0,0 +1 @@
|
|||||||
|
|
@ -0,0 +1,50 @@
|
|||||||
|
bin
|
||||||
|
obj
|
||||||
|
csx
|
||||||
|
.vs
|
||||||
|
edge
|
||||||
|
Publish
|
||||||
|
|
||||||
|
*.user
|
||||||
|
*.suo
|
||||||
|
*.cscfg
|
||||||
|
*.Cache
|
||||||
|
project.lock.json
|
||||||
|
|
||||||
|
/packages
|
||||||
|
/TestResults
|
||||||
|
|
||||||
|
/tools/NuGet.exe
|
||||||
|
/App_Data
|
||||||
|
/secrets
|
||||||
|
/data
|
||||||
|
.secrets
|
||||||
|
appsettings.json
|
||||||
|
local.settings.json
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
vector_database_wikipedia_articles_embedded
|
||||||
|
|
||||||
|
# Local python packages
|
||||||
|
.python_packages/
|
||||||
|
|
||||||
|
# Python Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# Azurite artifacts
|
||||||
|
__blobstorage__
|
||||||
|
__queuestorage__
|
||||||
|
__azurite_db*__.json
|
||||||
|
vector_database_wikipedia_articles_embedded
|
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"recommendations": [
|
||||||
|
"ms-azuretools.vscode-azurefunctions"
|
||||||
|
]
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,153 @@
|
|||||||
|
import azure.functions as func
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
from azure.search.documents import SearchClient
|
||||||
|
from azure.search.documents.indexes import SearchIndexClient
|
||||||
|
from azure.core.credentials import AzureKeyCredential
|
||||||
|
from openai import OpenAI
|
||||||
|
import os
|
||||||
|
from azure.search.documents.models import (
|
||||||
|
VectorizedQuery
|
||||||
|
)
|
||||||
|
|
||||||
|
# Initialize the Azure Function App
|
||||||
|
app = func.FunctionApp()
|
||||||
|
|
||||||
|
def generate_embeddings(text):
|
||||||
|
# Check if text is provided
|
||||||
|
if not text:
|
||||||
|
logging.error("No text provided in the query string.")
|
||||||
|
return func.HttpResponse(
|
||||||
|
"Please provide text in the query string.",
|
||||||
|
status_code=400
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Initialize OpenAI client
|
||||||
|
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
|
||||||
|
logging.info("OpenAI client initialized successfully.")
|
||||||
|
|
||||||
|
# Generate embeddings using OpenAI API
|
||||||
|
response = client.embeddings.create(
|
||||||
|
input=text,
|
||||||
|
model=os.getenv("EMBEDDINGS_MODEL")
|
||||||
|
)
|
||||||
|
logging.info("Embeddings created successfully.")
|
||||||
|
|
||||||
|
# Extract the embedding from the response
|
||||||
|
embedding = response.data[0].embedding
|
||||||
|
logging.debug(f"Generated embedding: {embedding}")
|
||||||
|
|
||||||
|
return embedding
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Error generating embeddings: {str(e)}")
|
||||||
|
return func.HttpResponse(
|
||||||
|
f"Error generating embeddings: {str(e)}",
|
||||||
|
status_code=500
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route(route="vector_similarity_search", auth_level=func.AuthLevel.ANONYMOUS)
|
||||||
|
def vector_similarity_search(req: func.HttpRequest) -> func.HttpResponse:
|
||||||
|
logging.info("Received request for vector similarity search.")
|
||||||
|
try:
|
||||||
|
# Parse the request body as JSON
|
||||||
|
req_body = req.get_json()
|
||||||
|
logging.info("Request body parsed successfully.")
|
||||||
|
except ValueError:
|
||||||
|
logging.error("Invalid JSON in request body.")
|
||||||
|
return func.HttpResponse(
|
||||||
|
"Invalid JSON in request body.",
|
||||||
|
status_code=400
|
||||||
|
)
|
||||||
|
|
||||||
|
# Extract parameters from the request body
|
||||||
|
search_service_endpoint = req_body.get('search_service_endpoint')
|
||||||
|
index_name = req_body.get('index_name')
|
||||||
|
query = req_body.get('query')
|
||||||
|
k_nearest_neighbors = req_body.get('k_nearest_neighbors')
|
||||||
|
search_column = req_body.get('search_column')
|
||||||
|
use_hybrid_query = req_body.get('use_hybrid_query')
|
||||||
|
|
||||||
|
logging.info(f"Parsed request parameters: search_service_endpoint={search_service_endpoint}, index_name={index_name}, query={query}, k_nearest_neighbors={k_nearest_neighbors}, search_column={search_column}, use_hybrid_query={use_hybrid_query}")
|
||||||
|
|
||||||
|
# Generate embeddings for the query
|
||||||
|
embeddings = generate_embeddings(query)
|
||||||
|
logging.info(f"Generated embeddings: {embeddings}")
|
||||||
|
|
||||||
|
# Check for required parameters
|
||||||
|
if not (search_service_endpoint and index_name and query):
|
||||||
|
logging.error("Missing required parameters in request body.")
|
||||||
|
return func.HttpResponse(
|
||||||
|
"Please provide search_service_endpoint, index_name, and query in the request body.",
|
||||||
|
status_code=400
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
# Create a vectorized query
|
||||||
|
vector_query = VectorizedQuery(vector=embeddings, k_nearest_neighbors=float(k_nearest_neighbors), fields=search_column)
|
||||||
|
logging.info("Vector query generated successfully.")
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Error generating vector query: {str(e)}")
|
||||||
|
return func.HttpResponse(
|
||||||
|
f"Error generating vector query: {str(e)}",
|
||||||
|
status_code=500
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Initialize the search client
|
||||||
|
search_client = SearchClient(
|
||||||
|
endpoint=search_service_endpoint,
|
||||||
|
index_name=index_name,
|
||||||
|
credential=AzureKeyCredential(os.getenv("SEARCH_SERVICE_API_KEY"))
|
||||||
|
)
|
||||||
|
logging.info("Search client created successfully.")
|
||||||
|
|
||||||
|
# Initialize the index client and get the index schema
|
||||||
|
index_client = SearchIndexClient(endpoint=search_service_endpoint, credential=AzureKeyCredential(os.getenv("SEARCH_SERVICE_API_KEY")))
|
||||||
|
index_schema = index_client.get_index(index_name)
|
||||||
|
for field in index_schema.fields:
|
||||||
|
logging.info(f"Field: {field.name}, Type: {field.type}")
|
||||||
|
# Filter out non-vector fields
|
||||||
|
non_vector_fields = [field.name for field in index_schema.fields if field.type not in ["Edm.ComplexType", "Collection(Edm.ComplexType)","Edm.Vector","Collection(Edm.Single)"]]
|
||||||
|
|
||||||
|
logging.info(f"Non-vector fields in the index: {non_vector_fields}")
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Error creating search client: {str(e)}")
|
||||||
|
return func.HttpResponse(
|
||||||
|
f"Error creating search client: {str(e)}",
|
||||||
|
status_code=500
|
||||||
|
)
|
||||||
|
|
||||||
|
# Determine if hybrid query should be used
|
||||||
|
search_text = query if use_hybrid_query else None
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Perform the search
|
||||||
|
results = search_client.search(
|
||||||
|
search_text=search_text,
|
||||||
|
vector_queries=[vector_query],
|
||||||
|
select=non_vector_fields,
|
||||||
|
top=3
|
||||||
|
)
|
||||||
|
logging.info("Search performed successfully.")
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Error performing search: {str(e)}")
|
||||||
|
return func.HttpResponse(
|
||||||
|
f"Error performing search: {str(e)}",
|
||||||
|
status_code=500
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Extract relevant data from results and put it into a list of dictionaries
|
||||||
|
response_data = [result for result in results]
|
||||||
|
response_data = json.dumps(response_data)
|
||||||
|
logging.info("Search results processed successfully.")
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Error processing search results: {str(e)}")
|
||||||
|
return func.HttpResponse(
|
||||||
|
f"Error processing search results: {str(e)}",
|
||||||
|
status_code=500
|
||||||
|
)
|
||||||
|
|
||||||
|
logging.info("Returning search results.")
|
||||||
|
return func.HttpResponse(response_data, mimetype="application/json")
|
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0",
|
||||||
|
"logging": {
|
||||||
|
"applicationInsights": {
|
||||||
|
"samplingSettings": {
|
||||||
|
"isEnabled": true,
|
||||||
|
"excludedTypes": "Request"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extensionBundle": {
|
||||||
|
"id": "Microsoft.Azure.Functions.ExtensionBundle",
|
||||||
|
"version": "[4.*, 5.0.0)"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
# Do not include azure-functions-worker in this file
|
||||||
|
# The Python Worker is managed by the Azure Functions platform
|
||||||
|
# Manually managing azure-functions-worker may cause unexpected issues
|
||||||
|
|
||||||
|
azure-functions
|
||||||
|
azure-search-documents
|
||||||
|
azure-identity
|
||||||
|
openai
|
||||||
|
azure-mgmt-search
|
||||||
|
pandas
|
||||||
|
azure-mgmt-resource
|
||||||
|
azure-mgmt-storage
|
||||||
|
azure-mgmt-web
|
||||||
|
python-dotenv
|
||||||
|
pyperclip
|
||||||
|
PyPDF2
|
||||||
|
tiktoken
|
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"scriptFile": "__init__.py",
|
||||||
|
"bindings": [
|
||||||
|
{
|
||||||
|
"authLevel": "Anonymous",
|
||||||
|
"type": "httpTrigger",
|
||||||
|
"direction": "in",
|
||||||
|
"name": "req",
|
||||||
|
"methods": [
|
||||||
|
"post"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "http",
|
||||||
|
"direction": "out",
|
||||||
|
"name": "$return"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,333 @@
|
|||||||
|
|
||||||
|
# Batch API
|
||||||
|
|
||||||
|
Learn how to use OpenAI's Batch API to send asynchronous groups of requests with 50% lower costs, a separate pool of significantly higher rate limits, and a clear 24-hour turnaround time. The service is ideal for processing jobs that don't require immediate responses. You can also [explore the API reference directly here](/docs/api-reference/batch).
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
While some uses of the OpenAI Platform require you to send synchronous requests, there are many cases where requests do not need an immediate response or [rate limits](/docs/guides/rate-limits) prevent you from executing a large number of queries quickly. Batch processing jobs are often helpful in use cases like:
|
||||||
|
|
||||||
|
1. running evaluations
|
||||||
|
2. classifying large datasets
|
||||||
|
3. embedding content repositories
|
||||||
|
|
||||||
|
The Batch API offers a straightforward set of endpoints that allow you to collect a set of requests into a single file, kick off a batch processing job to execute these requests, query for the status of that batch while the underlying requests execute, and eventually retrieve the collected results when the batch is complete.
|
||||||
|
|
||||||
|
Compared to using standard endpoints directly, Batch API has:
|
||||||
|
|
||||||
|
1. **Better cost efficiency:** 50% cost discount compared to synchronous APIs
|
||||||
|
2. **Higher rate limits:** [Substantially more headroom](/settings/organization/limits) compared to the synchronous APIs
|
||||||
|
3. **Fast completion times:** Each batch completes within 24 hours (and often more quickly)
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### 1. Preparing Your Batch File
|
||||||
|
|
||||||
|
Batches start with a `.jsonl` file where each line contains the details of an individual request to the API. For now, the available endpoints are `/v1/chat/completions` ([Chat Completions API](/docs/api-reference/chat)) and `/v1/embeddings` ([Embeddings API](/docs/api-reference/embeddings)). For a given input file, the parameters in each line's `body` field are the same as the parameters for the underlying endpoint. Each request must include a unique `custom_id` value, which you can use to reference results after completion. Here's an example of an input file with 2 requests. Note that each input file can only include requests to a single model.
|
||||||
|
|
||||||
|
```jsonl
|
||||||
|
{"custom_id": "request-1", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "gpt-3.5-turbo-0125", "messages": [{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": "Hello world!"}],"max_tokens": 1000}}
|
||||||
|
{"custom_id": "request-2", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "gpt-3.5-turbo-0125", "messages": [{"role": "system", "content": "You are an unhelpful assistant."},{"role": "user", "content": "Hello world!"}],"max_tokens": 1000}}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Uploading Your Batch Input File
|
||||||
|
|
||||||
|
Similar to our [Fine-tuning API](/docs/guides/fine-tuning/), you must first upload your input file so that you can reference it correctly when kicking off batches. Upload your `.jsonl` file using the [Files API](/docs/api-reference/files).
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
title="Upload files for Batch API"
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
from openai import OpenAI
|
||||||
|
client = OpenAI()\n
|
||||||
|
batch_input_file = client.files.create(
|
||||||
|
file=open("batchinput.jsonl", "rb"),
|
||||||
|
purpose="batch"
|
||||||
|
)
|
||||||
|
`.trim(),
|
||||||
|
curl: `
|
||||||
|
curl https://api.openai.com/v1/files \\
|
||||||
|
-H "Authorization: Bearer $OPENAI_API_KEY" \\
|
||||||
|
-F purpose="batch" \\
|
||||||
|
-F file="@batchinput.jsonl"
|
||||||
|
`.trim(),
|
||||||
|
node: `
|
||||||
|
import OpenAI from "openai";\n
|
||||||
|
const openai = new OpenAI();\n
|
||||||
|
async function main() {
|
||||||
|
const file = await openai.files.create({
|
||||||
|
file: fs.createReadStream("batchinput.jsonl"),
|
||||||
|
purpose: "batch",
|
||||||
|
});\n
|
||||||
|
console.log(file);
|
||||||
|
}\n
|
||||||
|
main();
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
### 3. Creating the Batch
|
||||||
|
|
||||||
|
Once you've successfully uploaded your input file, you can use the input File object's ID to create a batch. In this case, let's assume the file ID is `file-abc123`. For now, the completion window can only be set to `24h`. You can also provide custom metadata via an optional `metadata` parameter.
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
title="Create the Batch"
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
batch_input_file_id = batch_input_file.id\n
|
||||||
|
client.batches.create(
|
||||||
|
input_file_id=batch_input_file_id,
|
||||||
|
endpoint="/v1/chat/completions",
|
||||||
|
completion_window="24h",
|
||||||
|
metadata={
|
||||||
|
"description": "nightly eval job"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
`.trim(),
|
||||||
|
curl: `
|
||||||
|
curl https://api.openai.com/v1/batches \\
|
||||||
|
-H "Authorization: Bearer $OPENAI_API_KEY" \\
|
||||||
|
-H "Content-Type: application/json" \\
|
||||||
|
-d '{
|
||||||
|
"input_file_id": "file-abc123",
|
||||||
|
"endpoint": "/v1/chat/completions",
|
||||||
|
"completion_window": "24h"
|
||||||
|
}'
|
||||||
|
`.trim(),
|
||||||
|
node: `
|
||||||
|
import OpenAI from "openai";\n
|
||||||
|
const openai = new OpenAI();\n
|
||||||
|
async function main() {
|
||||||
|
const batch = await openai.batches.create({
|
||||||
|
input_file_id: "file-abc123",
|
||||||
|
endpoint: "/v1/chat/completions",
|
||||||
|
completion_window: "24h"
|
||||||
|
});\n
|
||||||
|
console.log(batch);
|
||||||
|
}\n
|
||||||
|
main();
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
This request will return a [Batch object](/docs/api-reference/batch/object) with metadata about your batch:
|
||||||
|
|
||||||
|
```python
|
||||||
|
{
|
||||||
|
"id": "batch_abc123",
|
||||||
|
"object": "batch",
|
||||||
|
"endpoint": "/v1/chat/completions",
|
||||||
|
"errors": null,
|
||||||
|
"input_file_id": "file-abc123",
|
||||||
|
"completion_window": "24h",
|
||||||
|
"status": "validating",
|
||||||
|
"output_file_id": null,
|
||||||
|
"error_file_id": null,
|
||||||
|
"created_at": 1714508499,
|
||||||
|
"in_progress_at": null,
|
||||||
|
"expires_at": 1714536634,
|
||||||
|
"completed_at": null,
|
||||||
|
"failed_at": null,
|
||||||
|
"expired_at": null,
|
||||||
|
"request_counts": {
|
||||||
|
"total": 0,
|
||||||
|
"completed": 0,
|
||||||
|
"failed": 0
|
||||||
|
},
|
||||||
|
"metadata": null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Checking the Status of a Batch
|
||||||
|
|
||||||
|
You can check the status of a batch at any time, which will also return a Batch object.
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
title="Check the status of a batch"
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
from openai import OpenAI
|
||||||
|
client = OpenAI()\n
|
||||||
|
client.batches.retrieve("batch_abc123")
|
||||||
|
`.trim(),
|
||||||
|
curl: `
|
||||||
|
curl https://api.openai.com/v1/batches/batch_abc123 \\
|
||||||
|
-H "Authorization: Bearer $OPENAI_API_KEY" \\
|
||||||
|
-H "Content-Type: application/json" \\
|
||||||
|
`.trim(),
|
||||||
|
node: `
|
||||||
|
import OpenAI from "openai";\n
|
||||||
|
const openai = new OpenAI();\n
|
||||||
|
async function main() {
|
||||||
|
const batch = await openai.batches.retrieve("batch_abc123");\n
|
||||||
|
console.log(batch);
|
||||||
|
}\n
|
||||||
|
main();
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
The status of a given Batch object can be any of the following:
|
||||||
|
|
||||||
|
| Status | Description |
|
||||||
|
| ------------- | ------------------------------------------------------------------------------ |
|
||||||
|
| `validating` | the input file is being validated before the batch can begin |
|
||||||
|
| `failed` | the input file has failed the validation process |
|
||||||
|
| `in_progress` | the input file was successfully validated and the batch is currently being run |
|
||||||
|
| `finalizing` | the batch has completed and the results are being prepared |
|
||||||
|
| `completed` | the batch has been completed and the results are ready |
|
||||||
|
| `expired` | the batch was not able to be completed within the 24-hour time window |
|
||||||
|
| `cancelling` | the batch is being cancelled (may take up to 10 minutes) |
|
||||||
|
| `cancelled` | the batch was cancelled |
|
||||||
|
|
||||||
|
### 5. Retrieving the Results
|
||||||
|
|
||||||
|
Once the batch is complete, you can download the output by making a request against the [Files API](/docs/api-reference/files) via the `output_file_id` field from the Batch object and writing it to a file on your machine, in this case `batch_output.jsonl`
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
title="Retrieving the batch results"
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
from openai import OpenAI
|
||||||
|
client = OpenAI()\n
|
||||||
|
content = client.files.content("file-xyz123")
|
||||||
|
`.trim(),
|
||||||
|
curl: `
|
||||||
|
curl https://api.openai.com/v1/files/file-xyz123/content \\
|
||||||
|
-H "Authorization: Bearer $OPENAI_API_KEY" > batch_output.jsonl
|
||||||
|
`.trim(),
|
||||||
|
node: `
|
||||||
|
import OpenAI from "openai";\n
|
||||||
|
const openai = new OpenAI();\n
|
||||||
|
async function main() {
|
||||||
|
const file = await openai.files.content("file-xyz123");\n
|
||||||
|
console.log(file);
|
||||||
|
}\n
|
||||||
|
main();
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
The output `.jsonl` file will have one response line for every successful request line in the input file. Any failed requests in the batch will have their error information written to an error file that can be found via the batch's `error_file_id`.
|
||||||
|
|
||||||
|
|
||||||
|
Note that the output line order may not match the input line order. Instead of
|
||||||
|
relying on order to process your results, use the custom_id field which will be
|
||||||
|
present in each line of your output file and allow you to map requests in your input
|
||||||
|
to results in your output.
|
||||||
|
|
||||||
|
|
||||||
|
```jsonl
|
||||||
|
{"id": "batch_req_123", "custom_id": "request-2", "response": {"status_code": 200, "request_id": "req_123", "body": {"id": "chatcmpl-123", "object": "chat.completion", "created": 1711652795, "model": "gpt-3.5-turbo-0125", "choices": [{"index": 0, "message": {"role": "assistant", "content": "Hello."}, "logprobs": null, "finish_reason": "stop"}], "usage": {"prompt_tokens": 22, "completion_tokens": 2, "total_tokens": 24}, "system_fingerprint": "fp_123"}}, "error": null}
|
||||||
|
{"id": "batch_req_456", "custom_id": "request-1", "response": {"status_code": 200, "request_id": "req_789", "body": {"id": "chatcmpl-abc", "object": "chat.completion", "created": 1711652789, "model": "gpt-3.5-turbo-0125", "choices": [{"index": 0, "message": {"role": "assistant", "content": "Hello! How can I assist you today?"}, "logprobs": null, "finish_reason": "stop"}], "usage": {"prompt_tokens": 20, "completion_tokens": 9, "total_tokens": 29}, "system_fingerprint": "fp_3ba"}}, "error": null}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6. Cancelling a Batch
|
||||||
|
|
||||||
|
If necessary, you can cancel an ongoing batch. The batch's status will change to `cancelling` until in-flight requests are complete (up to 10 minutes), after which the status will change to `cancelled`.
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
title="Cancelling a batch"
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
from openai import OpenAI
|
||||||
|
client = OpenAI()\n
|
||||||
|
client.batches.cancel("batch_abc123")
|
||||||
|
`.trim(),
|
||||||
|
curl: `
|
||||||
|
curl https://api.openai.com/v1/batches/batch_abc123/cancel \\
|
||||||
|
-H "Authorization: Bearer $OPENAI_API_KEY" \\
|
||||||
|
-H "Content-Type: application/json" \\
|
||||||
|
-X POST
|
||||||
|
`.trim(),
|
||||||
|
node: `
|
||||||
|
import OpenAI from "openai";\n
|
||||||
|
const openai = new OpenAI();\n
|
||||||
|
async function main() {
|
||||||
|
const batch = await openai.batches.cancel("batch_abc123");\n
|
||||||
|
console.log(batch);
|
||||||
|
}\n
|
||||||
|
main();
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
### 7. Getting a List of All Batches
|
||||||
|
|
||||||
|
At any time, you can see all your batches. For users with many batches, you can use the `limit` and `after` parameters to paginate your results.
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
title="Getting a list of all batches"
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
from openai import OpenAI
|
||||||
|
client = OpenAI()\n
|
||||||
|
client.batches.list(limit=10)
|
||||||
|
`.trim(),
|
||||||
|
curl: `
|
||||||
|
curl https://api.openai.com/v1/batches?limit=10 \\
|
||||||
|
-H "Authorization: Bearer $OPENAI_API_KEY" \\
|
||||||
|
-H "Content-Type: application/json"
|
||||||
|
`.trim(),
|
||||||
|
node: `
|
||||||
|
import OpenAI from "openai";\n
|
||||||
|
const openai = new OpenAI();\n
|
||||||
|
async function main() {
|
||||||
|
const list = await openai.batches.list();\n
|
||||||
|
for await (const batch of list) {
|
||||||
|
console.log(batch);
|
||||||
|
}
|
||||||
|
}\n
|
||||||
|
main();
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
## Model Availability
|
||||||
|
|
||||||
|
The Batch API can currently be used to execute queries against the following models. The Batch API supports text and vision inputs in the same format as the endpoints for these models:
|
||||||
|
|
||||||
|
- `gpt-4o`
|
||||||
|
- `gpt-4-turbo`
|
||||||
|
- `gpt-4`
|
||||||
|
- `gpt-4-32k`
|
||||||
|
- `gpt-3.5-turbo`
|
||||||
|
- `gpt-3.5-turbo-16k`
|
||||||
|
- `gpt-4-turbo-preview`
|
||||||
|
- `gpt-4-vision-preview`
|
||||||
|
- `gpt-4-turbo-2024-04-09`
|
||||||
|
- `gpt-4-0314`
|
||||||
|
- `gpt-4-32k-0314`
|
||||||
|
- `gpt-4-32k-0613`
|
||||||
|
- `gpt-3.5-turbo-0301`
|
||||||
|
- `gpt-3.5-turbo-16k-0613`
|
||||||
|
- `gpt-3.5-turbo-1106`
|
||||||
|
- `gpt-3.5-turbo-0613`
|
||||||
|
- `text-embedding-3-large`
|
||||||
|
- `text-embedding-3-small`
|
||||||
|
- `text-embedding-ada-002`
|
||||||
|
|
||||||
|
The Batch API also supports [fine-tuned models](/docs/guides/fine-tuning/what-models-can-be-fine-tuned).
|
||||||
|
|
||||||
|
## Rate Limits
|
||||||
|
|
||||||
|
Batch API rate limits are separate from existing per-model rate limits. The Batch API has two new types of rate limits:
|
||||||
|
|
||||||
|
1. **Per-batch limits:** A single batch may include up to 50,000 requests, and a batch input file can be up to 100 MB in size. Note that `/v1/embeddings` batches are also restricted to a maximum of 50,000 embedding inputs across all requests in the batch.
|
||||||
|
2. **Enqueued prompt tokens per model:** Each model has a maximum number of enqueued prompt tokens allowed for batch processing. You can find these limits on the [Platform Settings page](/settings/organization/limits).
|
||||||
|
|
||||||
|
There are no limits for output tokens or number of submitted requests for the Batch API today. Because Batch API rate limits are a new, separate pool, **using the Batch API will not consume tokens from your standard per-model rate limits**, thereby offering you a convenient way to increase the number of requests and processed tokens you can use when querying our API.
|
||||||
|
|
||||||
|
## Batch Expiration
|
||||||
|
|
||||||
|
Batches that do not complete in time eventually move to an `expired` state; unfinished requests within that batch are cancelled, and any responses to completed requests are made available via the batch's output file. You will be charged for tokens consumed from any completed requests.
|
||||||
|
|
||||||
|
## Other Resources
|
||||||
|
|
||||||
|
For more concrete examples, visit **[the OpenAI Cookbook](https://cookbook.openai.com/examples/batch_processing)**, which contains sample code for use cases like classification, sentiment analysis, and summary generation.
|
@ -0,0 +1,393 @@
|
|||||||
|
|
||||||
|
# Changelog
|
||||||
|
|
||||||
|
Keep track of changes to the OpenAI API. You can also track changes via our [public OpenAPI specification](https://github.com/openai/openai-openapi) which is used to generate our SDKs, documentation, and more. This changelog is maintained in a best effort fashion and may not reflect all changes
|
||||||
|
being made.
|
||||||
|
|
||||||
|
### Jun 6th, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
<MarkdownLink
|
||||||
|
href="/docs/guides/function-calling/parallel-function-calling"
|
||||||
|
useSpan
|
||||||
|
>
|
||||||
|
Parallel function calling
|
||||||
|
{" "}
|
||||||
|
can be disabled in Chat Completions and the Assistants API by passing{" "}
|
||||||
|
parallel_tool_calls=false.
|
||||||
|
|
||||||
|
-
|
||||||
|
|
||||||
|
.NET SDK
|
||||||
|
{" "}
|
||||||
|
launched in Beta.
|
||||||
|
|
||||||
|
|
||||||
|
### Jun 3rd, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
Added support for{" "}
|
||||||
|
<MarkdownLink
|
||||||
|
href="/docs/assistants/tools/file-search/customizing-file-search-settings"
|
||||||
|
useSpan
|
||||||
|
>
|
||||||
|
file search customizations
|
||||||
|
|
||||||
|
.
|
||||||
|
|
||||||
|
|
||||||
|
### May 15th, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
Added support for{" "}
|
||||||
|
|
||||||
|
archiving projects
|
||||||
|
|
||||||
|
. Only organization owners can access this functionality.
|
||||||
|
|
||||||
|
-
|
||||||
|
Added support for{" "}
|
||||||
|
|
||||||
|
setting cost limits
|
||||||
|
{" "}
|
||||||
|
on a per-project basis for pay as you go customers.
|
||||||
|
|
||||||
|
|
||||||
|
### May 13th, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
Released{" "}
|
||||||
|
|
||||||
|
GPT-4o
|
||||||
|
{" "}
|
||||||
|
in the API. GPT-4o is our fastest and most affordable flagship model.
|
||||||
|
|
||||||
|
|
||||||
|
### May 9th, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
Added support for{" "}
|
||||||
|
<MarkdownLink
|
||||||
|
href="/docs/assistants/how-it-works/creating-image-input-content"
|
||||||
|
useSpan
|
||||||
|
>
|
||||||
|
image inputs to the Assistants API.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### May 7th, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
Added support for{" "}
|
||||||
|
|
||||||
|
fine-tuned models to the Batch API
|
||||||
|
|
||||||
|
.
|
||||||
|
|
||||||
|
|
||||||
|
### May 6th, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
Added{" "}
|
||||||
|
<MarkdownLink
|
||||||
|
href="/docs/api-reference/chat/create#chat-create-stream_options"
|
||||||
|
useSpan
|
||||||
|
>
|
||||||
|
{'`stream_options: {"include_usage": true}`'}
|
||||||
|
{" "}
|
||||||
|
parameter to the Chat Completions and Completions APIs. Setting this gives
|
||||||
|
developers access to usage stats when using streaming.
|
||||||
|
|
||||||
|
|
||||||
|
### May 2nd, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
Added{" "}
|
||||||
|
|
||||||
|
{"a new endpoint"}
|
||||||
|
{" "}
|
||||||
|
to delete a message from a thread in the Assistants API.
|
||||||
|
|
||||||
|
|
||||||
|
### Apr 29th, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
Added a new{" "}
|
||||||
|
<MarkdownLink
|
||||||
|
href="/docs/guides/function-calling/function-calling-behavior"
|
||||||
|
useSpan
|
||||||
|
>
|
||||||
|
function calling option `tool_choice: "required"`
|
||||||
|
{" "}
|
||||||
|
to the Chat Completions and Assistants APIs.
|
||||||
|
|
||||||
|
-
|
||||||
|
Added a{" "}
|
||||||
|
|
||||||
|
guide for the Batch API
|
||||||
|
{" "}
|
||||||
|
and Batch API support for{" "}
|
||||||
|
|
||||||
|
embeddings models
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Apr 17th, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
Introduced a{" "}
|
||||||
|
|
||||||
|
series of updates to the Assistants API
|
||||||
|
|
||||||
|
, including a new file search tool allowing up to 10,000 files per assistant, new token
|
||||||
|
controls, and support for tool choice.
|
||||||
|
|
||||||
|
|
||||||
|
### Apr 16th, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
Introduced{" "}
|
||||||
|
|
||||||
|
project based hierarchy
|
||||||
|
{" "}
|
||||||
|
for organizing work by projects, including the ability to create{" "}
|
||||||
|
API keys {" "}
|
||||||
|
and manage rate and cost limits on a per-project basis (cost limits available only
|
||||||
|
for Enterprise customers).
|
||||||
|
|
||||||
|
|
||||||
|
### Apr 15th, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
Released{" "}
|
||||||
|
|
||||||
|
Batch API
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Apr 9th, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
Released{" "}
|
||||||
|
|
||||||
|
GPT-4 Turbo with Vision
|
||||||
|
{" "}
|
||||||
|
in general availability in the API
|
||||||
|
|
||||||
|
|
||||||
|
### Apr 4th, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
Added support for{" "}
|
||||||
|
|
||||||
|
seed
|
||||||
|
{" "}
|
||||||
|
in the fine-tuning API
|
||||||
|
|
||||||
|
-
|
||||||
|
Added support for{" "}
|
||||||
|
|
||||||
|
checkpoints
|
||||||
|
{" "}
|
||||||
|
in the fine-tuning API
|
||||||
|
|
||||||
|
-
|
||||||
|
Added support for{" "}
|
||||||
|
<MarkdownLink
|
||||||
|
href="/docs/api-reference/runs/createRun#runs-createrun-additional_messages"
|
||||||
|
useSpan
|
||||||
|
>
|
||||||
|
adding Messages when creating a Run
|
||||||
|
{" "}
|
||||||
|
in the Assistants API
|
||||||
|
|
||||||
|
|
||||||
|
### Apr 1st, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
Added support for{" "}
|
||||||
|
<MarkdownLink
|
||||||
|
href="/docs/api-reference/messages/listMessages#messages-listmessages-run_id"
|
||||||
|
useSpan
|
||||||
|
>
|
||||||
|
filtering Messages by run_id
|
||||||
|
{" "}
|
||||||
|
in the Assistants API
|
||||||
|
|
||||||
|
|
||||||
|
### Mar 29th, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
Added support for{" "}
|
||||||
|
<MarkdownLink
|
||||||
|
href="/docs/api-reference/runs/createRun#runs-createrun-temperature"
|
||||||
|
useSpan
|
||||||
|
>
|
||||||
|
temperature
|
||||||
|
{" "}
|
||||||
|
and{" "}
|
||||||
|
<MarkdownLink
|
||||||
|
href="/docs/api-reference/messages/createMessage#messages-createmessage-role"
|
||||||
|
useSpan
|
||||||
|
>
|
||||||
|
assistant message creation
|
||||||
|
{" "}
|
||||||
|
in the Assistants API
|
||||||
|
|
||||||
|
|
||||||
|
### Mar 14th, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
Added support for{" "}
|
||||||
|
|
||||||
|
streaming
|
||||||
|
{" "}
|
||||||
|
in the Assistants API
|
||||||
|
|
||||||
|
|
||||||
|
### Feb 9th, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
Added
|
||||||
|
|
||||||
|
{" "}
|
||||||
|
timestamp_granularities parameter
|
||||||
|
to the Audio API
|
||||||
|
|
||||||
|
|
||||||
|
### Feb 1st, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
Released
|
||||||
|
|
||||||
|
{" "}
|
||||||
|
gpt-3.5-turbo-0125, an updated GPT-3.5 Turbo model
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Jan 25th, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
Released
|
||||||
|
|
||||||
|
{" "}
|
||||||
|
embedding V3 models and an updated GPT-4 Turbo preview
|
||||||
|
|
||||||
|
|
||||||
|
-
|
||||||
|
Added
|
||||||
|
<MarkdownLink
|
||||||
|
href="/docs/api-reference/embeddings/create#embeddings-create-dimensions"
|
||||||
|
useSpan
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
|
dimensions parameter
|
||||||
|
to the Embeddings API
|
||||||
|
|
||||||
|
|
||||||
|
### Dec 20th, 2023
|
||||||
|
|
||||||
|
-
|
||||||
|
Added
|
||||||
|
<MarkdownLink
|
||||||
|
href="/docs/api-reference/runs/createRun#runs-createrun-additional_instructions"
|
||||||
|
useSpan
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
|
additional_instructions parameter
|
||||||
|
to run creation in the Assistants API
|
||||||
|
|
||||||
|
|
||||||
|
### Dec 15th, 2023
|
||||||
|
|
||||||
|
-
|
||||||
|
Added
|
||||||
|
|
||||||
|
{" "}
|
||||||
|
logprobs and
|
||||||
|
top_logprobs
|
||||||
|
parameters
|
||||||
|
to the Chat Completions API
|
||||||
|
|
||||||
|
|
||||||
|
### Dec 14th, 2023
|
||||||
|
|
||||||
|
-
|
||||||
|
Changed{" "}
|
||||||
|
|
||||||
|
function parameters
|
||||||
|
{" "}
|
||||||
|
argument on a tool call to be optional
|
||||||
|
|
||||||
|
|
||||||
|
### Nov 30th, 2023
|
||||||
|
|
||||||
|
-
|
||||||
|
Released{" "}
|
||||||
|
|
||||||
|
OpenAI Deno SDK
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Nov 6th, 2023
|
||||||
|
|
||||||
|
-
|
||||||
|
Released{" "}
|
||||||
|
|
||||||
|
GPT-4 Turbo Preview
|
||||||
|
|
||||||
|
,
|
||||||
|
updated GPT-3.5 Turbo
|
||||||
|
,
|
||||||
|
GPT-4 Turbo with Vision
|
||||||
|
,
|
||||||
|
Assistants API
|
||||||
|
,
|
||||||
|
DALL·E 3 in the API
|
||||||
|
, and
|
||||||
|
text-to-speech API
|
||||||
|
|
||||||
|
|
||||||
|
-
|
||||||
|
Deprecated the Chat Completions functions{" "}
|
||||||
|
parameter{" "}
|
||||||
|
|
||||||
|
in favor of
|
||||||
|
tools
|
||||||
|
{" "}
|
||||||
|
|
||||||
|
-
|
||||||
|
Released{" "}
|
||||||
|
|
||||||
|
OpenAI Python SDK V1.0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Oct 16th, 2023
|
||||||
|
|
||||||
|
-
|
||||||
|
Added
|
||||||
|
<MarkdownLink
|
||||||
|
href="/docs/api-reference/embeddings/create#embeddings-create-encoding_format"
|
||||||
|
useSpan
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
|
encoding_format parameter
|
||||||
|
to the Embeddings API
|
||||||
|
|
||||||
|
-
|
||||||
|
Added max_tokens to the{" "}
|
||||||
|
|
||||||
|
Moderation models
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Oct 6th, 2023
|
||||||
|
|
||||||
|
-
|
||||||
|
Added{" "}
|
||||||
|
|
||||||
|
function calling support
|
||||||
|
{" "}
|
||||||
|
to the Fine-tuning API
|
||||||
|
|
@ -0,0 +1,118 @@
|
|||||||
|
|
||||||
|
Curl is a popular command line tool used by developers to send HTTP requests to API's. It requires minimal set up time but is less capable than a fully featured programming language like Python or JavaScript.
|
||||||
|
|
||||||
|
## Step 1: Set up curl
|
||||||
|
|
||||||
|
|
||||||
|
Many operating systems ship curl by default. You can check if you have curl installed by opening your Terminal or Command line, then entering the command:
|
||||||
|
|
||||||
|
`curl https://platform.openai.com`
|
||||||
|
|
||||||
|
If curl is set up and you are connected to the internet, it will send a HTTP request to fetch the contents of "platform.openai.com".
|
||||||
|
|
||||||
|
If you get an error that curl is not found, you can install it by following the instructions on the [curl homepage](https://everything.curl.dev/get).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Step 2: Set up your API key
|
||||||
|
|
||||||
|
Now that we have curl working, the next step is to set up an API key in your Terminal or Command line. You can optionally skip this step and just include your API key in your request as is talked about in Step 3.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1. **Open Terminal**: You can find it in the Applications folder or search for it using Spotlight (Command + Space).
|
||||||
|
2. **Edit bash profile**: Use the command `nano ~/.bash_profile` or `nano ~/.zshrc` (for newer MacOS versions) to open the profile file in a text editor.
|
||||||
|
|
||||||
|
3. **Add environment variable**: In the editor, add the line below, replacing `your-api-key-here` with your actual API key:
|
||||||
|
|
||||||
|
```
|
||||||
|
export OPENAI_API_KEY='your-api-key-here'
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Save and exit**: Press Ctrl+O to write the changes, followed by Ctrl+X to close the editor.
|
||||||
|
|
||||||
|
5. **Load your profile**: Use the command `source ~/.bash_profile` or `source ~/.zshrc` to load the updated profile.
|
||||||
|
|
||||||
|
6. **Verification**: Verify the setup by typing `echo $OPENAI_API_KEY` in the terminal. It should display your API key.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1. **Open Command Prompt**: You can find it by searching "cmd" in the start menu.
|
||||||
|
|
||||||
|
2. **Set environment variable in the current session**: To set the environment variable in the current session, use the command below, replacing `your-api-key-here` with your actual API key:
|
||||||
|
|
||||||
|
```
|
||||||
|
setx OPENAI_API_KEY "your-api-key-here"
|
||||||
|
```
|
||||||
|
|
||||||
|
This command will set the OPENAI_API_KEY environment variable for the current session.
|
||||||
|
|
||||||
|
3. **Permanent setup**: To make the setup permanent, add the variable through the system properties as follows:
|
||||||
|
|
||||||
|
- Right-click on 'This PC' or 'My Computer' and select 'Properties'.
|
||||||
|
- Click on 'Advanced system settings'.
|
||||||
|
- Click the 'Environment Variables' button.
|
||||||
|
- In the 'System variables' section, click 'New...' and enter OPENAI_API_KEY as the variable name and your API key as the variable value.
|
||||||
|
|
||||||
|
4. **Verification**: To verify the setup, reopen the command prompt and type the command below. It should display your API key:
|
||||||
|
|
||||||
|
```
|
||||||
|
echo %OPENAI_API_KEY%
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Step 3: Sending your first API request
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Once you have an API key set up, the final step is to send your first API request. To do so, a sample request to the [Chat Completions](/docs/api-reference/chat/create), [Embeddings](/docs/api-reference/embeddings/create), and [Images](/docs/api-reference/images/create) API are included below. Because the API key was set in Step 2, it should be automatically referenced via `$OPENAI_API_KEY` in your terminal or command line. You can also manually replace `$OPENAI_API_KEY` with your API key but be sure to keep the curl command hidden if it includes your API key.
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
defaultLanguage="ChatCompletions"
|
||||||
|
code={{
|
||||||
|
ChatCompletions: `
|
||||||
|
curl https://api.openai.com/v1/chat/completions \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "Authorization: Bearer $OPENAI_API_KEY" \
|
||||||
|
-d '{
|
||||||
|
"model": "gpt-3.5-turbo",
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"role": "system",
|
||||||
|
"content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": "Compose a poem that explains the concept of recursion in programming."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}'
|
||||||
|
`.trim(),
|
||||||
|
Embeddings: `
|
||||||
|
curl https://api.openai.com/v1/embeddings \
|
||||||
|
-H "Authorization: Bearer $OPENAI_API_KEY" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"input": "The food was delicious and the waiter...",
|
||||||
|
"model": "text-embedding-ada-002"
|
||||||
|
}'
|
||||||
|
`.trim(),
|
||||||
|
Images: `
|
||||||
|
curl https://api.openai.com/v1/images/generations \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "Authorization: Bearer $OPENAI_API_KEY" \
|
||||||
|
-d '{
|
||||||
|
"prompt": "A cute baby sea otter",
|
||||||
|
"n": 2,
|
||||||
|
"size": "1024x1024"
|
||||||
|
}'
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
The [Chat Completions](/docs/api-reference/chat/create) example highlights just one area of strength for our models: creative ability. Explaining recursion (the programming topic) in a well formatted poem is something both the best developers and best poets would struggle with. In this case, `gpt-3.5-turbo` does it effortlessly.
|
||||||
|
|
||||||
|
|
@ -0,0 +1,162 @@
|
|||||||
|
# Deprecations
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
As we launch safer and more capable models, we regularly retire older models. Software relying on OpenAI models may need occasional updates to keep working. Impacted customers will always be notified by email and in our documentation along with [blog posts](https://openai.com/blog) for larger changes.
|
||||||
|
|
||||||
|
This page lists all API deprecations, along with recommended replacements.
|
||||||
|
|
||||||
|
## Deprecation vs Legacy
|
||||||
|
|
||||||
|
We use the term "deprecation" to refer to the process of retiring a model or endpoint. When we announce that a model or endpoint is being deprecated, it immediately becomes deprecated. All deprecated models and endpoints will also have a shut down date. At the time of the shut down, the model or endpoint will no longer be accessible.
|
||||||
|
|
||||||
|
We use the term "legacy" to refer to models and endpoints that will no longer receive updates. We tag endpoints and models as legacy to signal to developers where we are moving as a platform and that they should likely migrate to newer models or endpoints. You can expect that a legacy model or endpoint will be deprecated at some point in the future.
|
||||||
|
|
||||||
|
## Incremental model updates
|
||||||
|
|
||||||
|
As [announced](https://openai.com/blog/introducing-chatgpt-and-whisper-apis#:~:text=Chat%20guide.-,ChatGPT%20upgrades,-We%20are%20constantly) in March 2023, we regularly release new versions of `gpt-4` and `gpt-3.5-turbo`.
|
||||||
|
|
||||||
|
Each model version is dated with either `-MMDD` or a `YYYY-MM-DD` suffix; e.g., `gpt-4-0613` or `gpt-4o-2024-05-13`. The undated model name, e.g., `gpt-4o`, will typically point to the latest version dated version. Users of undated model names will be notified by email typically 2 weeks before any change takes place.
|
||||||
|
|
||||||
|
## Migrating to replacements
|
||||||
|
|
||||||
|
Once a model is deprecated, be sure to migrate all usage to a suitable replacement before the shutdown date. Requests to models past the shutdown date will fail.
|
||||||
|
|
||||||
|
To help measure the performance of replacement models on your tasks, we have open-sourced [Evals](https://github.com/openai/evals), a Python framework for evaluating language models.
|
||||||
|
|
||||||
|
If new models perform worse on your tasks, let us know by submitting a [pull request](https://github.com/openai/evals/pulls) to our Evals repo with examples of the task.
|
||||||
|
|
||||||
|
## Deprecation history
|
||||||
|
|
||||||
|
All deprecations are listed below, with the most recent announcements at the top.
|
||||||
|
|
||||||
|
### 2024-06-06: GPT-4-32K and Vision Preview models
|
||||||
|
|
||||||
|
On June 6th, 2024, we notified developers using `gpt-4-32k` and `gpt-4-vision-preview` of their upcoming deprecations in one year and six months respectively. As of June 17, 2024, only existing users of these models will be able to continue using them.
|
||||||
|
|
||||||
|
| Shutdown date | Deprecated model | Deprecated model price | Recommended replacement |
|
||||||
|
| ------------- | --------------------------- | -------------------------------------------------- | ----------------------- |
|
||||||
|
| 2025-06-06 | `gpt-4-32k` | $60.00 / 1M input tokens + $120 / 1M output tokens | `gpt-4o` |
|
||||||
|
| 2025-06-06 | `gpt-4-32k-0613` | $60.00 / 1M input tokens + $120 / 1M output tokens | `gpt-4o` |
|
||||||
|
| 2025-06-06 | `gpt-4-32k-0314` | $60.00 / 1M input tokens + $120 / 1M output tokens | `gpt-4o` |
|
||||||
|
| 2024-12-06 | `gpt-4-vision-preview` | $10.00 / 1M input tokens + $30 / 1M output tokens | `gpt-4o` |
|
||||||
|
| 2024-12-06 | `gpt-4-1106-vision-preview` | $10.00 / 1M input tokens + $30 / 1M output tokens | `gpt-4o` |
|
||||||
|
|
||||||
|
### 2023-11-06: Chat model updates
|
||||||
|
|
||||||
|
On November 6th, 2023, we [announced](https://openai.com/blog/new-models-and-developer-products-announced-at-devday) the release of an updated GPT-3.5-Turbo model (which now comes by default with 16k context) along with deprecation of `gpt-3.5-turbo-0613` and ` gpt-3.5-turbo-16k-0613`. As of June 17, 2024, only existing users of these models will be able to continue using them.
|
||||||
|
|
||||||
|
| Shutdown date | Deprecated model | Deprecated model price | Recommended replacement |
|
||||||
|
| ------------- | ------------------------ | -------------------------------------------------- | ----------------------- |
|
||||||
|
| 2024-09-13 | `gpt-3.5-turbo-0613` | $1.50 / 1M input tokens + $2.00 / 1M output tokens | `gpt-3.5-turbo` |
|
||||||
|
| 2024-09-13 | `gpt-3.5-turbo-16k-0613` | $3.00 / 1M input tokens + $4.00 / 1M output tokens | `gpt-3.5-turbo` |
|
||||||
|
|
||||||
|
Fine-tuned models created from these base models are not effected by this deprecation, but you will no longer be able to create new fine-tuned versions with these models.
|
||||||
|
|
||||||
|
### 2023-08-22: Fine-tunes endpoint
|
||||||
|
|
||||||
|
On August 22nd, 2023, we [announced](https://openai.com/blog/gpt-3-5-turbo-fine-tuning-and-api-updates) the new fine-tuning API (`/v1/fine_tuning/jobs`) and that the original `/v1/fine-tunes` API along with legacy models (including those fine-tuned with the `/v1/fine-tunes` API) will be shut down on January 04, 2024. This means that models fine-tuned using the `/v1/fine-tunes` API will no longer be accessible and you would have to fine-tune new models with the updated endpoint and associated base models.
|
||||||
|
|
||||||
|
#### Fine-tunes endpoint
|
||||||
|
|
||||||
|
| Shutdown date | System | Recommended replacement |
|
||||||
|
| ------------- | ---------------- | ----------------------- |
|
||||||
|
| 2024-01-04 | `/v1/fine-tunes` | `/v1/fine_tuning/jobs` |
|
||||||
|
|
||||||
|
### 2023-07-06: GPT and embeddings
|
||||||
|
|
||||||
|
On July 06, 2023, we [announced](https://openai.com/blog/gpt-4-api-general-availability) the upcoming retirements of older GPT-3 and GPT-3.5 models served via the completions endpoint. We also announced the upcoming retirement of our first-generation text embedding models. They will be shut down on January 04, 2024.
|
||||||
|
|
||||||
|
#### InstructGPT models
|
||||||
|
|
||||||
|
| Shutdown date | Deprecated model | Deprecated model price | Recommended replacement |
|
||||||
|
| ------------- | ------------------ | ---------------------- | ------------------------ |
|
||||||
|
| 2024-01-04 | `text-ada-001` | $0.40 / 1M tokens | `gpt-3.5-turbo-instruct` |
|
||||||
|
| 2024-01-04 | `text-babbage-001` | $0.50 / 1M tokens | `gpt-3.5-turbo-instruct` |
|
||||||
|
| 2024-01-04 | `text-curie-001` | $2.00 / 1M tokens | `gpt-3.5-turbo-instruct` |
|
||||||
|
| 2024-01-04 | `text-davinci-001` | $20.00 / 1M tokens | `gpt-3.5-turbo-instruct` |
|
||||||
|
| 2024-01-04 | `text-davinci-002` | $20.00 / 1M tokens | `gpt-3.5-turbo-instruct` |
|
||||||
|
| 2024-01-04 | `text-davinci-003` | $20.00 / 1M tokens | `gpt-3.5-turbo-instruct` |
|
||||||
|
|
||||||
|
Pricing for the replacement `gpt-3.5-turbo-instruct` model can be found on the [pricing page](https://openai.com/pricing).
|
||||||
|
|
||||||
|
#### Base GPT models
|
||||||
|
|
||||||
|
| Shutdown date | Deprecated model | Deprecated model price | Recommended replacement |
|
||||||
|
| ------------- | ------------------ | ---------------------- | ------------------------ |
|
||||||
|
| 2024-01-04 | `ada` | $0.40 / 1M tokens | `babbage-002` |
|
||||||
|
| 2024-01-04 | `babbage` | $0.50 / 1M tokens | `babbage-002` |
|
||||||
|
| 2024-01-04 | `curie` | $2.00 / 1M tokens | `davinci-002` |
|
||||||
|
| 2024-01-04 | `davinci` | $20.00 / 1M tokens | `davinci-002` |
|
||||||
|
| 2024-01-04 | `code-davinci-002` | --- | `gpt-3.5-turbo-instruct` |
|
||||||
|
|
||||||
|
Pricing for the replacement `babbage-002` and `davinci-002` models can be found on the [pricing page](https://openai.com/pricing).
|
||||||
|
|
||||||
|
#### Edit models & endpoint
|
||||||
|
|
||||||
|
| Shutdown date | Model / system | Recommended replacement |
|
||||||
|
| ------------- | ----------------------- | ----------------------- |
|
||||||
|
| 2024-01-04 | `text-davinci-edit-001` | `gpt-4o` |
|
||||||
|
| 2024-01-04 | `code-davinci-edit-001` | `gpt-4o` |
|
||||||
|
| 2024-01-04 | `/v1/edits` | `/v1/chat/completions` |
|
||||||
|
|
||||||
|
#### Fine-tuning GPT models
|
||||||
|
|
||||||
|
| Shutdown date | Deprecated model | Training price | Usage price | Recommended replacement |
|
||||||
|
| ------------- | ---------------- | ------------------ | ------------------- | ---------------------------------------- |
|
||||||
|
| 2024-01-04 | `ada` | $0.40 / 1M tokens | $1.60 / 1M tokens | `babbage-002` |
|
||||||
|
| 2024-01-04 | `babbage` | $0.60 / 1M tokens | $2.40 / 1M tokens | `babbage-002` |
|
||||||
|
| 2024-01-04 | `curie` | $3.00 / 1M tokens | $12.00 / 1M tokens | `davinci-002` |
|
||||||
|
| 2024-01-04 | `davinci` | $30.00 / 1M tokens | $120.00 / 1K tokens | `davinci-002`, `gpt-3.5-turbo`, `gpt-4o` |
|
||||||
|
|
||||||
|
#### First-generation text embedding models
|
||||||
|
|
||||||
|
| Shutdown date | Deprecated model | Deprecated model price | Recommended replacement |
|
||||||
|
| ------------- | ------------------------------- | ---------------------- | ------------------------ |
|
||||||
|
| 2024-01-04 | `text-similarity-ada-001` | $4.00 / 1M tokens | `text-embedding-3-small` |
|
||||||
|
| 2024-01-04 | `text-search-ada-doc-001` | $4.00 / 1M tokens | `text-embedding-3-small` |
|
||||||
|
| 2024-01-04 | `text-search-ada-query-001` | $4.00 / 1M tokens | `text-embedding-3-small` |
|
||||||
|
| 2024-01-04 | `code-search-ada-code-001` | $4.00 / 1M tokens | `text-embedding-3-small` |
|
||||||
|
| 2024-01-04 | `code-search-ada-text-001` | $4.00 / 1M tokens | `text-embedding-3-small` |
|
||||||
|
| 2024-01-04 | `text-similarity-babbage-001` | $5.00 / 1M tokens | `text-embedding-3-small` |
|
||||||
|
| 2024-01-04 | `text-search-babbage-doc-001` | $5.00 / 1M tokens | `text-embedding-3-small` |
|
||||||
|
| 2024-01-04 | `text-search-babbage-query-001` | $5.00 / 1M tokens | `text-embedding-3-small` |
|
||||||
|
| 2024-01-04 | `code-search-babbage-code-001` | $5.00 / 1M tokens | `text-embedding-3-small` |
|
||||||
|
| 2024-01-04 | `code-search-babbage-text-001` | $5.00 / 1M tokens | `text-embedding-3-small` |
|
||||||
|
| 2024-01-04 | `text-similarity-curie-001` | $20.00 / 1M tokens | `text-embedding-3-small` |
|
||||||
|
| 2024-01-04 | `text-search-curie-doc-001` | $20.00 / 1M tokens | `text-embedding-3-small` |
|
||||||
|
| 2024-01-04 | `text-search-curie-query-001` | $20.00 / 1M tokens | `text-embedding-3-small` |
|
||||||
|
| 2024-01-04 | `text-similarity-davinci-001` | $200.00 / 1M tokens | `text-embedding-3-small` |
|
||||||
|
| 2024-01-04 | `text-search-davinci-doc-001` | $200.00 / 1M tokens | `text-embedding-3-small` |
|
||||||
|
| 2024-01-04 | `text-search-davinci-query-001` | $200.00 / 1M tokens | `text-embedding-3-small` |
|
||||||
|
|
||||||
|
### 2023-06-13: Updated chat models
|
||||||
|
|
||||||
|
On June 13, 2023, we announced new chat model versions in the [Function calling and other API updates](https://openai.com/blog/function-calling-and-other-api-updates) blog post. The three original versions will be retired in June 2024 at the earliest. As of January 10, 2024, only existing users of these models will be able to continue using them.
|
||||||
|
|
||||||
|
| Shutdown date | Legacy model | Legacy model price | Recommended replacement |
|
||||||
|
| ---------------------- | ------------ | ---------------------------------------------------- | ----------------------- |
|
||||||
|
| at earliest 2024-06-13 | `gpt-4-0314` | $30.00 / 1M input tokens + $60.00 / 1M output tokens | `gpt-4o` |
|
||||||
|
|
||||||
|
| Shutdown date | Deprecated model | Deprecated model price | Recommended replacement |
|
||||||
|
| ------------- | -------------------- | ----------------------------------------------------- | ----------------------- |
|
||||||
|
| 2024-09-13 | `gpt-3.5-turbo-0301` | $15.00 / 1M input tokens + $20.00 / 1M output tokens | `gpt-3.5-turbo` |
|
||||||
|
| 2025-06-06 | `gpt-4-32k-0314` | $60.00 / 1M input tokens + $120.00 / 1M output tokens | `gpt-4o` |
|
||||||
|
|
||||||
|
### 2023-03-20: Codex models
|
||||||
|
|
||||||
|
| Shutdown date | Deprecated model | Recommended replacement |
|
||||||
|
| ------------- | ------------------ | ----------------------- |
|
||||||
|
| 2023-03-23 | `code-davinci-002` | `gpt-4o` |
|
||||||
|
| 2023-03-23 | `code-davinci-001` | `gpt-4o` |
|
||||||
|
| 2023-03-23 | `code-cushman-002` | `gpt-4o` |
|
||||||
|
| 2023-03-23 | `code-cushman-001` | `gpt-4o` |
|
||||||
|
|
||||||
|
### 2022-06-03: Legacy endpoints
|
||||||
|
|
||||||
|
| Shutdown date | System | Recommended replacement |
|
||||||
|
| ------------- | --------------------- | ----------------------------------------------------------------------------------------------------- |
|
||||||
|
| 2022-12-03 | `/v1/engines` | [/v1/models](https://platform.openai.com/docs/api-reference/models/list) |
|
||||||
|
| 2022-12-03 | `/v1/search` | [View transition guide](https://help.openai.com/en/articles/6272952-search-transition-guide) |
|
||||||
|
| 2022-12-03 | `/v1/classifications` | [View transition guide](https://help.openai.com/en/articles/6272941-classifications-transition-guide) |
|
||||||
|
| 2022-12-03 | `/v1/answers` | [View transition guide](https://help.openai.com/en/articles/6233728-answers-transition-guide) |
|
@ -0,0 +1,122 @@
|
|||||||
|
|
||||||
|
Runs are asynchronous, which means you'll want to monitor their `status` by polling the Run object until a
|
||||||
|
[terminal status](https://platform.openai.com/docs/assistants/how-it-works/runs-and-run-steps) is reached. For convenience, the 'create and poll' SDK helpers assist both in
|
||||||
|
creating the run and then polling for its completion. Once the Run completes, you can list the
|
||||||
|
Messages added to the Thread by the Assistant. Finally, you would retrieve all the `tool_outputs` from
|
||||||
|
`required_action` and submit them at the same time to the 'submit tool outputs and poll' helper.
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
run = client.beta.threads.runs.create_and_poll(
|
||||||
|
thread_id=thread.id,
|
||||||
|
assistant_id=assistant.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
if run.status == 'completed':
|
||||||
|
messages = client.beta.threads.messages.list(
|
||||||
|
thread_id=thread.id
|
||||||
|
)
|
||||||
|
print(messages)
|
||||||
|
else:
|
||||||
|
print(run.status)
|
||||||
|
|
||||||
|
# Define the list to store tool outputs
|
||||||
|
tool_outputs = []
|
||||||
|
|
||||||
|
# Loop through each tool in the required action section
|
||||||
|
for tool in run.required_action.submit_tool_outputs.tool_calls:
|
||||||
|
if tool.function.name == "get_current_temperature":
|
||||||
|
tool_outputs.append({
|
||||||
|
"tool_call_id": tool.id,
|
||||||
|
"output": "57"
|
||||||
|
})
|
||||||
|
elif tool.function.name == "get_rain_probability":
|
||||||
|
tool_outputs.append({
|
||||||
|
"tool_call_id": tool.id,
|
||||||
|
"output": "0.06"
|
||||||
|
})
|
||||||
|
|
||||||
|
# Submit all tool outputs at once after collecting them in a list
|
||||||
|
if tool_outputs:
|
||||||
|
try:
|
||||||
|
run = client.beta.threads.runs.submit_tool_outputs_and_poll(
|
||||||
|
thread_id=thread.id,
|
||||||
|
run_id=run.id,
|
||||||
|
tool_outputs=tool_outputs
|
||||||
|
)
|
||||||
|
print("Tool outputs submitted successfully.")
|
||||||
|
except Exception as e:
|
||||||
|
print("Failed to submit tool outputs:", e)
|
||||||
|
else:
|
||||||
|
print("No tool outputs to submit.")
|
||||||
|
|
||||||
|
if run.status == 'completed':
|
||||||
|
messages = client.beta.threads.messages.list(
|
||||||
|
thread_id=thread.id
|
||||||
|
)
|
||||||
|
print(messages)
|
||||||
|
else:
|
||||||
|
print(run.status)
|
||||||
|
`.trim(),
|
||||||
|
"node.js": `
|
||||||
|
const handleRequiresAction = async (run) => {
|
||||||
|
// Check if there are tools that require outputs
|
||||||
|
if (
|
||||||
|
run.required_action &&
|
||||||
|
run.required_action.submit_tool_outputs &&
|
||||||
|
run.required_action.submit_tool_outputs.tool_calls
|
||||||
|
) {
|
||||||
|
// Loop through each tool in the required action section
|
||||||
|
const toolOutputs = run.required_action.submit_tool_outputs.tool_calls.map(
|
||||||
|
(tool) => {
|
||||||
|
if (tool.function.name === "getCurrentTemperature") {
|
||||||
|
return {
|
||||||
|
tool_call_id: tool.id,
|
||||||
|
output: "57",
|
||||||
|
};
|
||||||
|
} else if (tool.function.name === "getRainProbability") {
|
||||||
|
return {
|
||||||
|
tool_call_id: tool.id,
|
||||||
|
output: "0.06",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);\n
|
||||||
|
// Submit all tool outputs at once after collecting them in a list
|
||||||
|
if (toolOutputs.length > 0) {
|
||||||
|
run = await client.beta.threads.runs.submitToolOutputsAndPoll(
|
||||||
|
thread.id,
|
||||||
|
run.id,
|
||||||
|
{ tool_outputs: toolOutputs },
|
||||||
|
);
|
||||||
|
console.log("Tool outputs submitted successfully.");
|
||||||
|
} else {
|
||||||
|
console.log("No tool outputs to submit.");
|
||||||
|
}\n
|
||||||
|
// Check status after submitting tool outputs
|
||||||
|
return handleRunStatus(run);
|
||||||
|
}
|
||||||
|
};\n
|
||||||
|
const handleRunStatus = async (run) => {
|
||||||
|
// Check if the run is completed
|
||||||
|
if (run.status === "completed") {
|
||||||
|
let messages = await client.beta.threads.messages.list(thread.id);
|
||||||
|
console.log(messages.data);
|
||||||
|
return messages.data;
|
||||||
|
} else if (run.status === "requires_action") {
|
||||||
|
console.log(run.status);
|
||||||
|
return await handleRequiresAction(run);
|
||||||
|
} else {
|
||||||
|
console.error("Run did not complete:", run);
|
||||||
|
}
|
||||||
|
};\n
|
||||||
|
// Create and poll run
|
||||||
|
let run = await client.beta.threads.runs.createAndPoll(thread.id, {
|
||||||
|
assistant_id: assistant.id,
|
||||||
|
});\n
|
||||||
|
handleRunStatus(run);
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
@ -0,0 +1,124 @@
|
|||||||
|
|
||||||
|
For the streaming case, we create an EventHandler class to handle events in the response stream and submit all tool outputs at once with the “submit tool outputs stream” helper in the Python and Node SDKs.
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
from typing_extensions import override
|
||||||
|
from openai import AssistantEventHandler
|
||||||
|
|
||||||
|
class EventHandler(AssistantEventHandler):
|
||||||
|
@override
|
||||||
|
def on_event(self, event):
|
||||||
|
# Retrieve events that are denoted with 'requires_action'
|
||||||
|
# since these will have our tool_calls
|
||||||
|
if event.event == 'thread.run.requires_action':
|
||||||
|
run_id = event.data.id # Retrieve the run ID from the event data
|
||||||
|
self.handle_requires_action(event.data, run_id)
|
||||||
|
|
||||||
|
def handle_requires_action(self, data, run_id):
|
||||||
|
tool_outputs = []
|
||||||
|
|
||||||
|
for tool in data.required_action.submit_tool_outputs.tool_calls:
|
||||||
|
if tool.function.name == "get_current_temperature":
|
||||||
|
tool_outputs.append({"tool_call_id": tool.id, "output": "57"})
|
||||||
|
elif tool.function.name == "get_rain_probability":
|
||||||
|
tool_outputs.append({"tool_call_id": tool.id, "output": "0.06"})
|
||||||
|
|
||||||
|
# Submit all tool_outputs at the same time
|
||||||
|
self.submit_tool_outputs(tool_outputs, run_id)
|
||||||
|
|
||||||
|
def submit_tool_outputs(self, tool_outputs, run_id):
|
||||||
|
# Use the submit_tool_outputs_stream helper
|
||||||
|
with client.beta.threads.runs.submit_tool_outputs_stream(
|
||||||
|
thread_id=self.current_run.thread_id,
|
||||||
|
run_id=self.current_run.id,
|
||||||
|
tool_outputs=tool_outputs,
|
||||||
|
event_handler=EventHandler(),
|
||||||
|
) as stream:
|
||||||
|
for text in stream.text_deltas:
|
||||||
|
print(text, end="", flush=True)
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
with client.beta.threads.runs.stream(
|
||||||
|
thread_id=thread.id,
|
||||||
|
assistant_id=assistant.id,
|
||||||
|
event_handler=EventHandler()
|
||||||
|
) as stream:
|
||||||
|
stream.until_done()
|
||||||
|
`.trim(),
|
||||||
|
"node.js": `
|
||||||
|
class EventHandler extends EventEmitter {
|
||||||
|
constructor(client) {
|
||||||
|
super();
|
||||||
|
this.client = client;
|
||||||
|
}\n
|
||||||
|
async onEvent(event) {
|
||||||
|
try {
|
||||||
|
console.log(event);
|
||||||
|
// Retrieve events that are denoted with 'requires_action'
|
||||||
|
// since these will have our tool_calls
|
||||||
|
if (event.event === "thread.run.requires_action") {
|
||||||
|
await this.handleRequiresAction(
|
||||||
|
event.data,
|
||||||
|
event.data.id,
|
||||||
|
event.data.thread_id,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error handling event:", error);
|
||||||
|
}
|
||||||
|
}\n
|
||||||
|
async handleRequiresAction(data, runId, threadId) {
|
||||||
|
try {
|
||||||
|
const toolOutputs =
|
||||||
|
data.required_action.submit_tool_outputs.tool_calls.map((toolCall) => {
|
||||||
|
if (toolCall.function.name === "getCurrentTemperature") {
|
||||||
|
return {
|
||||||
|
tool_call_id: toolCall.id,
|
||||||
|
output: "57",
|
||||||
|
};
|
||||||
|
} else if (toolCall.function.name === "getRainProbability") {
|
||||||
|
return {
|
||||||
|
tool_call_id: toolCall.id,
|
||||||
|
output: "0.06",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Submit all the tool outputs at the same time
|
||||||
|
await this.submitToolOutputs(toolOutputs, runId, threadId);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error processing required action:", error);
|
||||||
|
}
|
||||||
|
}\n
|
||||||
|
async submitToolOutputs(toolOutputs, runId, threadId) {
|
||||||
|
try {
|
||||||
|
// Use the submitToolOutputsStream helper
|
||||||
|
const stream = this.client.beta.threads.runs.submitToolOutputsStream(
|
||||||
|
threadId,
|
||||||
|
runId,
|
||||||
|
{ tool_outputs: toolOutputs },
|
||||||
|
);
|
||||||
|
for await (const event of stream) {
|
||||||
|
this.emit("event", event);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error submitting tool outputs:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}\n
|
||||||
|
const eventHandler = new EventHandler(client);
|
||||||
|
eventHandler.on("event", eventHandler.onEvent.bind(eventHandler));\n
|
||||||
|
const stream = await client.beta.threads.runs.stream(
|
||||||
|
threadId,
|
||||||
|
{ assistant_id: assistantId },
|
||||||
|
eventHandler,
|
||||||
|
);\n
|
||||||
|
for await (const event of stream) {
|
||||||
|
eventHandler.emit("event", event);
|
||||||
|
}
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
@ -0,0 +1,252 @@
|
|||||||
|
|
||||||
|
|
||||||
|
# Function calling
|
||||||
|
|
||||||
|
Learn how to connect large language models to external tools.
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
In an API call, you can describe functions and have the model intelligently choose to output a JSON object containing arguments to call one or many functions. The Chat Completions API does not call the function; instead, the model generates JSON that you can use to call the function in your code.
|
||||||
|
|
||||||
|
The latest models (`gpt-4o`, `gpt-4-turbo`, and `gpt-3.5-turbo`) have been trained to both detect when a function should to be called (depending on the input) and to respond with JSON that adheres to the function signature more closely than previous models. With this capability also comes potential risks. We strongly recommend building in user confirmation flows before taking actions that impact the world on behalf of users (sending an email, posting something online, making a purchase, etc).
|
||||||
|
|
||||||
|
|
||||||
|
This guide is focused on function calling with the Chat Completions API, for details
|
||||||
|
on function calling in the Assistants API, please see the{" "}
|
||||||
|
Assistants Tools page.
|
||||||
|
|
||||||
|
|
||||||
|
### Common use cases
|
||||||
|
|
||||||
|
Function calling allows you to more reliably get structured data back from the model. For example, you can:
|
||||||
|
|
||||||
|
- Create assistants that answer questions by calling external APIs
|
||||||
|
- e.g. define functions like `send_email(to: string, body: string)`, or `get_current_weather(location: string, unit: 'celsius' | 'fahrenheit')`
|
||||||
|
- Convert natural language into API calls
|
||||||
|
- e.g. convert "Who are my top customers?" to `get_customers(min_revenue: int, created_before: string, limit: int)` and call your internal API
|
||||||
|
- Extract structured data from text
|
||||||
|
- e.g. define a function called `extract_data(name: string, birthday: string)`, or `sql_query(query: string)`
|
||||||
|
|
||||||
|
...and much more!
|
||||||
|
|
||||||
|
The basic sequence of steps for function calling is as follows:
|
||||||
|
|
||||||
|
1. Call the model with the user query and a set of functions defined in the [functions parameter](/docs/api-reference/chat/create#chat/create-functions).
|
||||||
|
2. The model can choose to call one or more functions; if so, the content will be a stringified JSON object adhering to your custom schema (note: the model may hallucinate parameters).
|
||||||
|
3. Parse the string into JSON in your code, and call your function with the provided arguments if they exist.
|
||||||
|
4. Call the model again by appending the function response as a new message, and let the model summarize the results back to the user.
|
||||||
|
|
||||||
|
### Supported models
|
||||||
|
|
||||||
|
Not all model versions are trained with function calling data. Function calling is supported with the following models: `gpt-4o`, `gpt-4o-2024-05-13`, `gpt-4-turbo`, `gpt-4-turbo-2024-04-09`, `gpt-4-turbo-preview`, `gpt-4-0125-preview`, `gpt-4-1106-preview`, `gpt-4`, `gpt-4-0613`, `gpt-3.5-turbo`, `gpt-3.5-turbo-0125`, `gpt-3.5-turbo-1106`, and `gpt-3.5-turbo-0613`.
|
||||||
|
|
||||||
|
In addition, parallel function calls is supported on the following models: `gpt-4o`, `gpt-4o-2024-05-13`, `gpt-4-turbo`, `gpt-4-turbo-2024-04-09`, `gpt-4-turbo-preview`, `gpt-4-0125-preview`, `gpt-4-1106-preview`, `gpt-3.5-turbo-0125`, and `gpt-3.5-turbo-1106`.
|
||||||
|
|
||||||
|
## Function calling behavior
|
||||||
|
|
||||||
|
The default behavior for [`tool_choice`](/docs/api-reference/chat/create#chat-create-tool_choice) is `tool_choice: "auto"`. This lets the model decide whether to call functions and, if so, which functions to call.
|
||||||
|
|
||||||
|
We offer three ways to customize the default behavior depending on your use case:
|
||||||
|
|
||||||
|
1. To force the model to always call one or more functions, you can set `tool_choice: "required"`. The model will then select which function(s) to call.
|
||||||
|
2. To force the model to call only one specific function, you can set `tool_choice: {"type": "function", "function": {"name": "my_function"}}`.
|
||||||
|
3. To disable function calling and force the model to only generate a user-facing message, you can set `tool_choice: "none"`.
|
||||||
|
|
||||||
|
## Parallel function calling
|
||||||
|
|
||||||
|
Parallel function calling is the model's ability to perform multiple function calls together, allowing the effects and results of these function calls to be resolved in parallel. This is especially useful if functions take a long time, and reduces round trips with the API. For example, the model may call functions to get the weather in 3 different locations at the same time, which will result in a message with 3 function calls in the `tool_calls` array, each with an `id`. To respond to these function calls, add 3 new messages to the conversation, each containing the result of one function call, with a `tool_call_id` referencing the `id` from `tool_calls`.
|
||||||
|
|
||||||
|
Parallel function calling can be disabled by passing `parallel_tool_calls: false` in the request. The model will only call one function at a time when parallel function calling is disabled.
|
||||||
|
|
||||||
|
In this example, we define a single function `get_current_weather`. The model calls the function multiple times, and after sending the function response back to the model, we let it decide the next step. It responded with a user-facing message which was telling the user the temperature in San Francisco, Tokyo, and Paris. Depending on the query, it may choose to call a function again.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
from openai import OpenAI
|
||||||
|
import json\n
|
||||||
|
client = OpenAI()\n
|
||||||
|
# Example dummy function hard coded to return the same weather
|
||||||
|
# In production, this could be your backend API or an external API
|
||||||
|
def get_current_weather(location, unit="fahrenheit"):
|
||||||
|
"""Get the current weather in a given location"""
|
||||||
|
if "tokyo" in location.lower():
|
||||||
|
return json.dumps({"location": "Tokyo", "temperature": "10", "unit": unit})
|
||||||
|
elif "san francisco" in location.lower():
|
||||||
|
return json.dumps({"location": "San Francisco", "temperature": "72", "unit": unit})
|
||||||
|
elif "paris" in location.lower():
|
||||||
|
return json.dumps({"location": "Paris", "temperature": "22", "unit": unit})
|
||||||
|
else:
|
||||||
|
return json.dumps({"location": location, "temperature": "unknown"})\n
|
||||||
|
def run_conversation():
|
||||||
|
# Step 1: send the conversation and available functions to the model
|
||||||
|
messages = [{"role": "user", "content": "What's the weather like in San Francisco, Tokyo, and Paris?"}]
|
||||||
|
tools = [
|
||||||
|
{
|
||||||
|
"type": "function",
|
||||||
|
"function": {
|
||||||
|
"name": "get_current_weather",
|
||||||
|
"description": "Get the current weather in a given location",
|
||||||
|
"parameters": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"location": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The city and state, e.g. San Francisco, CA",
|
||||||
|
},
|
||||||
|
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
|
||||||
|
},
|
||||||
|
"required": ["location"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
response = client.chat.completions.create(
|
||||||
|
model="gpt-4o",
|
||||||
|
messages=messages,
|
||||||
|
tools=tools,
|
||||||
|
tool_choice="auto", # auto is default, but we'll be explicit
|
||||||
|
)
|
||||||
|
response_message = response.choices[0].message
|
||||||
|
tool_calls = response_message.tool_calls
|
||||||
|
# Step 2: check if the model wanted to call a function
|
||||||
|
if tool_calls:
|
||||||
|
# Step 3: call the function
|
||||||
|
# Note: the JSON response may not always be valid; be sure to handle errors
|
||||||
|
available_functions = {
|
||||||
|
"get_current_weather": get_current_weather,
|
||||||
|
} # only one function in this example, but you can have multiple
|
||||||
|
messages.append(response_message) # extend conversation with assistant's reply
|
||||||
|
# Step 4: send the info for each function call and function response to the model
|
||||||
|
for tool_call in tool_calls:
|
||||||
|
function_name = tool_call.function.name
|
||||||
|
function_to_call = available_functions[function_name]
|
||||||
|
function_args = json.loads(tool_call.function.arguments)
|
||||||
|
function_response = function_to_call(
|
||||||
|
location=function_args.get("location"),
|
||||||
|
unit=function_args.get("unit"),
|
||||||
|
)
|
||||||
|
messages.append(
|
||||||
|
{
|
||||||
|
"tool_call_id": tool_call.id,
|
||||||
|
"role": "tool",
|
||||||
|
"name": function_name,
|
||||||
|
"content": function_response,
|
||||||
|
}
|
||||||
|
) # extend conversation with function response
|
||||||
|
second_response = client.chat.completions.create(
|
||||||
|
model="gpt-4o",
|
||||||
|
messages=messages,
|
||||||
|
) # get a new response from the model where it can see the function response
|
||||||
|
return second_response
|
||||||
|
print(run_conversation())
|
||||||
|
`.trim(),
|
||||||
|
"node.js": `
|
||||||
|
const openai = new OpenAI();
|
||||||
|
\n
|
||||||
|
// Example dummy function hard coded to return the same weather
|
||||||
|
// In production, this could be your backend API or an external API
|
||||||
|
function getCurrentWeather(location, unit = "fahrenheit") {
|
||||||
|
if (location.toLowerCase().includes("tokyo")) {
|
||||||
|
return JSON.stringify({ location: "Tokyo", temperature: "10", unit: "celsius" });
|
||||||
|
} else if (location.toLowerCase().includes("san francisco")) {
|
||||||
|
return JSON.stringify({ location: "San Francisco", temperature: "72", unit: "fahrenheit" });
|
||||||
|
} else if (location.toLowerCase().includes("paris")) {
|
||||||
|
return JSON.stringify({ location: "Paris", temperature: "22", unit: "fahrenheit" });
|
||||||
|
} else {
|
||||||
|
return JSON.stringify({ location, temperature: "unknown" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\n
|
||||||
|
async function runConversation() {
|
||||||
|
// Step 1: send the conversation and available functions to the model
|
||||||
|
const messages = [
|
||||||
|
{ role: "user", content: "What's the weather like in San Francisco, Tokyo, and Paris?" },
|
||||||
|
];
|
||||||
|
const tools = [
|
||||||
|
{
|
||||||
|
type: "function",
|
||||||
|
function: {
|
||||||
|
name: "get_current_weather",
|
||||||
|
description: "Get the current weather in a given location",
|
||||||
|
parameters: {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
location: {
|
||||||
|
type: "string",
|
||||||
|
description: "The city and state, e.g. San Francisco, CA",
|
||||||
|
},
|
||||||
|
unit: { type: "string", enum: ["celsius", "fahrenheit"] },
|
||||||
|
},
|
||||||
|
required: ["location"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
\n
|
||||||
|
const response = await openai.chat.completions.create({
|
||||||
|
model: "gpt-4o",
|
||||||
|
messages: messages,
|
||||||
|
tools: tools,
|
||||||
|
tool_choice: "auto", // auto is default, but we'll be explicit
|
||||||
|
});
|
||||||
|
const responseMessage = response.choices[0].message;\n
|
||||||
|
// Step 2: check if the model wanted to call a function
|
||||||
|
const toolCalls = responseMessage.tool_calls;
|
||||||
|
if (responseMessage.tool_calls) {
|
||||||
|
// Step 3: call the function
|
||||||
|
// Note: the JSON response may not always be valid; be sure to handle errors
|
||||||
|
const availableFunctions = {
|
||||||
|
get_current_weather: getCurrentWeather,
|
||||||
|
}; // only one function in this example, but you can have multiple
|
||||||
|
messages.push(responseMessage); // extend conversation with assistant's reply
|
||||||
|
for (const toolCall of toolCalls) {
|
||||||
|
const functionName = toolCall.function.name;
|
||||||
|
const functionToCall = availableFunctions[functionName];
|
||||||
|
const functionArgs = JSON.parse(toolCall.function.arguments);
|
||||||
|
const functionResponse = functionToCall(
|
||||||
|
functionArgs.location,
|
||||||
|
functionArgs.unit
|
||||||
|
);
|
||||||
|
messages.push({
|
||||||
|
tool_call_id: toolCall.id,
|
||||||
|
role: "tool",
|
||||||
|
name: functionName,
|
||||||
|
content: functionResponse,
|
||||||
|
}); // extend conversation with function response
|
||||||
|
}
|
||||||
|
const secondResponse = await openai.chat.completions.create({
|
||||||
|
model: "gpt-4o",
|
||||||
|
messages: messages,
|
||||||
|
}); // get a new response from the model where it can see the function response
|
||||||
|
return secondResponse.choices;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\n
|
||||||
|
runConversation().then(console.log).catch(console.error);
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
You can find more examples of function calling in the OpenAI Cookbook:
|
||||||
|
|
||||||
|
<a
|
||||||
|
href="https://cookbook.openai.com/examples/how_to_call_functions_with_chat_models"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
} color="green" title="Function calling" className="mt-6">
|
||||||
|
Learn from more examples demonstrating function calling
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Tokens
|
||||||
|
|
||||||
|
Under the hood, functions are injected into the system message in a syntax the model has been trained on. This means functions count against the model's context limit and are billed as input tokens. If running into context limits, we suggest limiting the number of functions or the length of documentation you provide for function parameters.
|
||||||
|
|
||||||
|
It is also possible to use [fine-tuning](/docs/guides/fine-tuning/fine-tuning-examples) to reduce the number of tokens used if you have many functions defined.
|
@ -0,0 +1,95 @@
|
|||||||
|
### Using in-memory image data
|
||||||
|
|
||||||
|
The Node.js examples in the guide above use the `fs` module to read image data from disk. In some cases, you may have your image data in memory instead. Here's an example API call that uses image data stored in a Node.js `Buffer` object:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
|
||||||
|
const openai = new OpenAI();
|
||||||
|
|
||||||
|
// This is the Buffer object that contains your image data
|
||||||
|
const buffer = [your image data];
|
||||||
|
|
||||||
|
// Set a `name` that ends with .png so that the API knows it's a PNG image
|
||||||
|
buffer.name = "image.png";
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const image = await openai.images.createVariation({ model: "dall-e-2", image: buffer, n: 1, size: "1024x1024" });
|
||||||
|
console.log(image.data);
|
||||||
|
}
|
||||||
|
main();
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Working with TypeScript
|
||||||
|
|
||||||
|
If you're using TypeScript, you may encounter some quirks with image file arguments. Here's an example of working around the type mismatch by explicitly casting the argument:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
|
||||||
|
const openai = new OpenAI();
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
// Cast the ReadStream to `any` to appease the TypeScript compiler
|
||||||
|
const image = await openai.images.createVariation({
|
||||||
|
image: fs.createReadStream("image.png") as any,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(image.data);
|
||||||
|
}
|
||||||
|
main();
|
||||||
|
```
|
||||||
|
|
||||||
|
And here's a similar example for in-memory image data:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
|
||||||
|
const openai = new OpenAI();
|
||||||
|
|
||||||
|
// This is the Buffer object that contains your image data
|
||||||
|
const buffer: Buffer = [your image data];
|
||||||
|
|
||||||
|
// Cast the buffer to `any` so that we can set the `name` property
|
||||||
|
const file: any = buffer;
|
||||||
|
|
||||||
|
// Set a `name` that ends with .png so that the API knows it's a PNG image
|
||||||
|
file.name = "image.png";
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const image = await openai.images.createVariation({
|
||||||
|
file,
|
||||||
|
1,
|
||||||
|
"1024x1024"
|
||||||
|
});
|
||||||
|
console.log(image.data);
|
||||||
|
}
|
||||||
|
main();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error handling
|
||||||
|
|
||||||
|
API requests can potentially return errors due to invalid inputs, rate limits, or other issues. These errors can be handled with a `try...catch` statement, and the error details can be found in either `error.response` or `error.message`:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
|
||||||
|
const openai = new OpenAI();
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
try {
|
||||||
|
const image = await openai.images.createVariation({
|
||||||
|
image: fs.createReadStream("image.png"),
|
||||||
|
n: 1,
|
||||||
|
size: "1024x1024",
|
||||||
|
});
|
||||||
|
console.log(image.data);
|
||||||
|
} catch (error) {
|
||||||
|
if (error.response) {
|
||||||
|
console.log(error.response.status);
|
||||||
|
console.log(error.response.data);
|
||||||
|
} else {
|
||||||
|
console.log(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
|
```
|
@ -0,0 +1,69 @@
|
|||||||
|
### Using in-memory image data
|
||||||
|
|
||||||
|
The Python examples in the guide above use the `open` function to read image data from disk. In some cases, you may have your image data in memory instead. Here's an example API call that uses image data stored in a `BytesIO` object:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from io import BytesIO
|
||||||
|
from openai import OpenAI
|
||||||
|
client = OpenAI()
|
||||||
|
|
||||||
|
# This is the BytesIO object that contains your image data
|
||||||
|
byte_stream: BytesIO = [your image data]
|
||||||
|
byte_array = byte_stream.getvalue()
|
||||||
|
response = client.images.create_variation(
|
||||||
|
image=byte_array,
|
||||||
|
n=1,
|
||||||
|
model="dall-e-2",
|
||||||
|
size="1024x1024"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Operating on image data
|
||||||
|
|
||||||
|
It may be useful to perform operations on images before passing them to the API. Here's an example that uses `PIL` to resize an image:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from io import BytesIO
|
||||||
|
from PIL import Image
|
||||||
|
from openai import OpenAI
|
||||||
|
client = OpenAI()
|
||||||
|
|
||||||
|
# Read the image file from disk and resize it
|
||||||
|
image = Image.open("image.png")
|
||||||
|
width, height = 256, 256
|
||||||
|
image = image.resize((width, height))
|
||||||
|
|
||||||
|
# Convert the image to a BytesIO object
|
||||||
|
byte_stream = BytesIO()
|
||||||
|
image.save(byte_stream, format='PNG')
|
||||||
|
byte_array = byte_stream.getvalue()
|
||||||
|
|
||||||
|
response = client.images.create_variation(
|
||||||
|
image=byte_array,
|
||||||
|
n=1,
|
||||||
|
model="dall-e-2",
|
||||||
|
size="1024x1024"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error handling
|
||||||
|
|
||||||
|
API requests can potentially return errors due to invalid inputs, rate limits, or other issues. These errors can be handled with a `try...except` statement, and the error details can be found in `e.error`:
|
||||||
|
|
||||||
|
```python
|
||||||
|
import openai
|
||||||
|
from openai import OpenAI
|
||||||
|
client = OpenAI()
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = client.images.create_variation(
|
||||||
|
image=open("image_edit_mask.png", "rb"),
|
||||||
|
n=1,
|
||||||
|
model="dall-e-2",
|
||||||
|
size="1024x1024"
|
||||||
|
)
|
||||||
|
print(response.data[0].url)
|
||||||
|
except openai.OpenAIError as e:
|
||||||
|
print(e.http_status)
|
||||||
|
print(e.error)
|
||||||
|
```
|
@ -0,0 +1,71 @@
|
|||||||
|
|
||||||
|
# Developer quickstart
|
||||||
|
|
||||||
|
## Get up and running with the OpenAI API
|
||||||
|
|
||||||
|
|
||||||
|
Looking for ChatGPT? Head to chatgpt.com.
|
||||||
|
|
||||||
|
|
||||||
|
The OpenAI API provides a simple interface for developers to create an intelligence layer in their applications, powered by OpenAI's state of the art models. The Chat Completions endpoint powers ChatGPT and provides a simple way to take text as input and use a model like GPT-4o to generate an output.
|
||||||
|
|
||||||
|
|
||||||
|
<IconItem
|
||||||
|
icon={}
|
||||||
|
color="green"
|
||||||
|
title="Want to jump straight to the code?"
|
||||||
|
className="mt-6"
|
||||||
|
>
|
||||||
|
Skip the quickstart and dive into the API reference.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
This quickstart is designed to help get your local development environment set up and send your first API request. If you are an experienced developer or want to just dive into using the OpenAI API, the [API reference](/docs/api-reference) of [GPT guide](/docs/guides/text-generation) are a great place to start. Throughout this quickstart, you will learn:
|
||||||
|
|
||||||
|
- How to set up your development environment
|
||||||
|
- How to install the latest SDKs
|
||||||
|
- Some of the basic concepts of the OpenAI API
|
||||||
|
- How to send your first API request
|
||||||
|
|
||||||
|
If you run into any challenges or have questions getting started, please join our [developer forum](https://community.openai.com).
|
||||||
|
|
||||||
|
## Account setup
|
||||||
|
|
||||||
|
First, create an [OpenAI account](/signup) or [sign in](/login). Next, navigate to the [API key page](/account/api-keys) and "Create new secret key", optionally naming the key. Make sure to save this somewhere safe and do not share it with anyone.
|
||||||
|
|
||||||
|
## Quickstart language selection
|
||||||
|
|
||||||
|
Select the tool or language you want to get started using the OpenAI API with.
|
||||||
|
|
||||||
|
<ContentSwitcher
|
||||||
|
options={[
|
||||||
|
{
|
||||||
|
value: "curl",
|
||||||
|
label: "curl",
|
||||||
|
content: ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "python",
|
||||||
|
label: "Python",
|
||||||
|
content: ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "node",
|
||||||
|
label: "Node.js",
|
||||||
|
content: ,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
initialValue="python"
|
||||||
|
/>
|
||||||
|
|
||||||
|
## Next steps
|
||||||
|
|
||||||
|
Now that you have made you first OpenAI API request, it is time to explore what else is possible:
|
||||||
|
|
||||||
|
- For more detailed information on our models and the API, see our [text generation guide](/docs/guides/text-generation).
|
||||||
|
- Visit the [OpenAI Cookbook](https://cookbook.openai.com/) for in-depth example API use-cases, as well as code snippets for common tasks.
|
||||||
|
- Wondering what OpenAI's models are capable of? Check out our library of [example prompts](/examples).
|
||||||
|
- Want to try the API without writing any code? Start experimenting in the [Playground](/playground).
|
||||||
|
- Keep our [usage policies](https://openai.com/policies/usage-policies) in mind as you start building.
|
@ -0,0 +1,75 @@
|
|||||||
|
|
||||||
|
# Actions in GPTs
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
Learn how to build a GPT action that intelligently calls your API.
|
||||||
|
|
||||||
|
### What is a GPT?
|
||||||
|
|
||||||
|
[GPTs](https://openai.com/blog/introducing-gpts) provide the ability to deeply customize ChatGPT for specific use cases along with custom capabilities. You can create a GPT that:
|
||||||
|
|
||||||
|
- Has custom instructions which determine the way the GPT interacts with users
|
||||||
|
- Includes tools like browsing, DALL·E, and Code Interpreter
|
||||||
|
- Comes with preset starter prompts for new and returning users
|
||||||
|
- Has custom actions which allow you to connect the GPT to APIs
|
||||||
|
|
||||||
|
And more! If you want to explore what is possible, check out the deep dive on GPTs from OpenAI Developer Day 2023:
|
||||||
|
|
||||||
|
<iframe
|
||||||
|
width="100%"
|
||||||
|
height="315"
|
||||||
|
src="https://www.youtube-nocookie.com/embed/pq34V_V5j18?si=q4ZPUe-dS8Ii8YX0"
|
||||||
|
title="YouTube video player"
|
||||||
|
frameBorder="0"
|
||||||
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||||
|
allowFullScreen
|
||||||
|
>
|
||||||
|
|
||||||
|
### What is an action in a GPT?
|
||||||
|
|
||||||
|
In addition to using our built-in capabilities (browsing, DALL·E, and Code Interpreter), you can also define custom actions by making one or more APIs available to the GPT. Actions allow GPTs to integrate external data or interact with the real-world, such as connecting GPTs to databases, plugging them into your emails, or making them your shopping assistant, all through APIs.
|
||||||
|
|
||||||
|
The design of actions builds upon insights from our plugins beta, granting developers greater control over the model and how their APIs are called. Actions are defined using the [OpenAPI specification](https://swagger.io/specification/), which is a standard for describing APIs.
|
||||||
|
|
||||||
|
### GPT action flow
|
||||||
|
|
||||||
|
To build a GPT with an action, it is important to understand the end-to-end flow.
|
||||||
|
|
||||||
|
1. Create a GPT in the ChatGPT UI
|
||||||
|
|
||||||
|
- Manually configure or use the GPT builder to create a GPT
|
||||||
|
- Identify the API(s) you want to use
|
||||||
|
|
||||||
|
2. Go to the "Configure" tab in the GPT editor and select "Create new action"
|
||||||
|
|
||||||
|
- You will be presented with 3 main options: selecting the authentication schema for the action, inputting the schema itself, and setting the privacy policy URL
|
||||||
|
- The Schema follows the OpenAPI specification format (not to be confused with OpenAI) to define how the GPT can access an external API
|
||||||
|
|
||||||
|
3. Fill in the details for the schema, authentication, and privacy policy.
|
||||||
|
|
||||||
|
- When selecting an authentication method, you will have 3 options, "None", "API Key", and "OAuth", we will explore these in depth later on
|
||||||
|
- For the schema, you can take an existing OpenAPI specification you have for your API or create a new one. If you have already published an OpenAPI specification online, you can import it via the "Import from URL" button
|
||||||
|
- The privacy policy URL is displayed to the user when they open a GPT and select the drop down in the top left corner showing the name of the GPT
|
||||||
|
|
||||||
|
4. Determine the visibility of your GPT
|
||||||
|
- By default, GPTs are not accessible to everyone
|
||||||
|
- When you go to save a GPT, you will have the option to "Publish to" a certain audience: "Only me", "Anyone with a link", or "Everyone"
|
||||||
|
- Each of these visibility options comes with different constraints and requirements. For example the naming of a GPT has more restrictions if you share it with someone else
|
||||||
|
5. User(s) engage with your GPT
|
||||||
|
- Depending on the visibility of your GPT, users might try it via a link you shared, or find it in the GPT store
|
||||||
|
- If OAuth is required, users will be prompted to login during the session
|
||||||
|
- Behind the scenes, the GPT injects the information on how you configured the GPT (including any available actions, tools, or instructions) into the context of the model
|
||||||
|
- Each time a user makes a request, the model sees the available tools, actions, and instructions which determine how the GPT will respond to the request
|
||||||
|
- If the user request is to check the weather in a specific location and you made a "Check weather" action available, the model will follow the OpenAPI specification you provided to send a request to that API and return the response to the user
|
||||||
|
|
||||||
|
## Next steps
|
||||||
|
|
||||||
|
Now that you know the basics of how a GPT works and where actions can be used, you might want to:
|
||||||
|
|
||||||
|
- Get started building a [GPT with an action](/docs/actions/getting-started)
|
||||||
|
- Learn how we [built the GPT builder](https://help.openai.com/en/articles/8770868-gpt-builder) itself as a custom GPT with actions
|
||||||
|
- Familiarize yourself with our [GPT polices](https://openai.com/policies/usage-policies#:~:text=or%20educational%20purposes.-,Building%20with%20ChatGPT,-Shared%20GPTs%20allow)
|
||||||
|
- Explore the [differences between GPTs and Assistants](https://help.openai.com/en/articles/8673914-gpts-vs-assistants)
|
||||||
|
- Check out the [GPT data privacy FAQ's](https://help.openai.com/en/articles/8554402-gpts-data-privacy-faqs)
|
||||||
|
- Find answers to [common GPT questions](https://help.openai.com/en/articles/8554407-gpts-faq)
|
@ -0,0 +1,198 @@
|
|||||||
|
|
||||||
|
# Libraries
|
||||||
|
|
||||||
|
## Python library
|
||||||
|
|
||||||
|
We provide a [Python library](https://github.com/openai/openai-python), which you can install by running:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install openai
|
||||||
|
```
|
||||||
|
|
||||||
|
Once installed, you can use the library and your secret key to run the following:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from openai import OpenAI
|
||||||
|
client = OpenAI(
|
||||||
|
# Defaults to os.environ.get("OPENAI_API_KEY")
|
||||||
|
)
|
||||||
|
|
||||||
|
chat_completion = client.chat.completions.create(
|
||||||
|
model="gpt-3.5-turbo",
|
||||||
|
messages=[{"role": "user", "content": "Hello world"}]
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
The bindings also will install a command-line utility you can use as follows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ openai api chat_completions.create -m gpt-3.5-turbo -g user "Hello world"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TypeScript / JavaScript library
|
||||||
|
|
||||||
|
We provide a [TypeScript / JavaScript library](https://github.com/openai/openai-node) with support for Node.js and various [other runtimes](https://deno.land/x/openai). Install it by running:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install --save openai
|
||||||
|
# or
|
||||||
|
yarn add openai
|
||||||
|
```
|
||||||
|
|
||||||
|
Once installed, you can use the library and your secret key to run the following:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
|
||||||
|
const openai = new OpenAI({
|
||||||
|
apiKey: process.env.OPENAI_API_KEY,
|
||||||
|
});
|
||||||
|
|
||||||
|
const chatCompletion = await openai.chat.completions.create({
|
||||||
|
messages: [{ role: "user", content: "Say this is a test" }],
|
||||||
|
model: "gpt-3.5-turbo",
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
.NET library Beta
|
||||||
|
|
||||||
|
|
||||||
|
We provide a [.NET library](https://github.com/openai/openai-dotnet), which you can install by running:
|
||||||
|
|
||||||
|
```
|
||||||
|
dotnet add package OpenAI --prerelease
|
||||||
|
```
|
||||||
|
|
||||||
|
Once installed, you can use the library and your secret key to run the following:
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
using OpenAI.Chat;
|
||||||
|
|
||||||
|
ChatClient client = new("gpt-3.5-turbo", Environment.GetEnvironmentVariable("OPENAI_API_KEY"));
|
||||||
|
|
||||||
|
ChatCompletion chatCompletion = client.CompleteChat(
|
||||||
|
[
|
||||||
|
new UserChatMessage("Say 'this is a test.'"),
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Azure OpenAI libraries
|
||||||
|
|
||||||
|
Microsoft's Azure team maintains libraries that are compatible with both the OpenAI API and Azure OpenAI services. Read the library documentation below to learn how you can use them with the OpenAI API.
|
||||||
|
|
||||||
|
- [Azure OpenAI client library for .NET](https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/openai/Azure.AI.OpenAI)
|
||||||
|
- [Azure OpenAI client library for JavaScript](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/openai/openai)
|
||||||
|
- [Azure OpenAI client library for Java](https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/openai/azure-ai-openai)
|
||||||
|
- [Azure OpenAI client library for Go](https://github.com/Azure/azure-sdk-for-go/tree/main/sdk/ai/azopenai)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Community libraries
|
||||||
|
|
||||||
|
The libraries below are built and maintained by the broader developer community. If you'd like to add a new library here, please follow the instructions in our [help center article](https://help.openai.com/en/articles/6684216-adding-your-api-client-to-the-community-libraries-page) on adding community libraries. You can also [watch our OpenAPI specification](https://github.com/openai/openai-openapi) repository on GitHub to get timely updates on when we make changes to our API.
|
||||||
|
|
||||||
|
Please note that OpenAI does not verify the correctness or security of these projects. **Use them at your own risk!**
|
||||||
|
|
||||||
|
### C# / .NET
|
||||||
|
|
||||||
|
- [Betalgo.OpenAI](https://github.com/betalgo/openai) by [Betalgo](https://github.com/betalgo)
|
||||||
|
- [OpenAI-API-dotnet](https://github.com/OkGoDoIt/OpenAI-API-dotnet) by [OkGoDoIt](https://github.com/OkGoDoIt)
|
||||||
|
- [OpenAI-DotNet](https://github.com/RageAgainstThePixel/OpenAI-DotNet) by [RageAgainstThePixel](https://github.com/RageAgainstThePixel)
|
||||||
|
|
||||||
|
### C++
|
||||||
|
|
||||||
|
- [liboai](https://github.com/D7EAD/liboai) by [D7EAD](https://github.com/D7EAD)
|
||||||
|
|
||||||
|
### Clojure
|
||||||
|
|
||||||
|
- [openai-clojure](https://github.com/wkok/openai-clojure) by [wkok](https://github.com/wkok)
|
||||||
|
|
||||||
|
### Crystal
|
||||||
|
|
||||||
|
- [openai-crystal](https://github.com/sferik/openai-crystal) by [sferik](https://github.com/sferik)
|
||||||
|
|
||||||
|
### Dart/Flutter
|
||||||
|
|
||||||
|
- [openai](https://github.com/anasfik/openai) by [anasfik](https://github.com/anasfik)
|
||||||
|
|
||||||
|
### Delphi
|
||||||
|
|
||||||
|
- [DelphiOpenAI](https://github.com/HemulGM/DelphiOpenAI) by [HemulGM](https://github.com/HemulGM)
|
||||||
|
|
||||||
|
### Elixir
|
||||||
|
|
||||||
|
- [openai.ex](https://github.com/mgallo/openai.ex) by [mgallo](https://github.com/mgallo)
|
||||||
|
|
||||||
|
### Go
|
||||||
|
|
||||||
|
- [go-gpt3](https://github.com/sashabaranov/go-gpt3) by [sashabaranov](https://github.com/sashabaranov)
|
||||||
|
|
||||||
|
### Java
|
||||||
|
|
||||||
|
- [openai-java](https://github.com/TheoKanning/openai-java) by [Theo Kanning](https://github.com/TheoKanning)
|
||||||
|
|
||||||
|
### Julia
|
||||||
|
|
||||||
|
- [OpenAI.jl](https://github.com/rory-linehan/OpenAI.jl) by [rory-linehan](https://github.com/rory-linehan)
|
||||||
|
|
||||||
|
### Kotlin
|
||||||
|
|
||||||
|
- [openai-kotlin](https://github.com/Aallam/openai-kotlin) by [Mouaad Aallam](https://github.com/Aallam)
|
||||||
|
|
||||||
|
### Node.js
|
||||||
|
|
||||||
|
- [openai-api](https://www.npmjs.com/package/openai-api) by [Njerschow](https://github.com/Njerschow)
|
||||||
|
- [openai-api-node](https://www.npmjs.com/package/openai-api-node) by [erlapso](https://github.com/erlapso)
|
||||||
|
- [gpt-x](https://www.npmjs.com/package/gpt-x) by [ceifa](https://github.com/ceifa)
|
||||||
|
- [gpt3](https://www.npmjs.com/package/gpt3) by [poteat](https://github.com/poteat)
|
||||||
|
- [gpts](https://www.npmjs.com/package/gpts) by [thencc](https://github.com/thencc)
|
||||||
|
- [@dalenguyen/openai](https://www.npmjs.com/package/@dalenguyen/openai) by [dalenguyen](https://github.com/dalenguyen)
|
||||||
|
- [tectalic/openai](https://github.com/tectalichq/public-openai-client-js) by [tectalic](https://tectalic.com/)
|
||||||
|
|
||||||
|
### PHP
|
||||||
|
|
||||||
|
- [orhanerday/open-ai](https://packagist.org/packages/orhanerday/open-ai) by [orhanerday](https://github.com/orhanerday)
|
||||||
|
- [tectalic/openai](https://github.com/tectalichq/public-openai-client-php) by [tectalic](https://tectalic.com/)
|
||||||
|
- [openai-php client](https://github.com/openai-php/client) by [openai-php](https://github.com/openai-php)
|
||||||
|
|
||||||
|
### Python
|
||||||
|
|
||||||
|
- [chronology](https://github.com/OthersideAI/chronology) by [OthersideAI](https://www.othersideai.com/)
|
||||||
|
|
||||||
|
### R
|
||||||
|
|
||||||
|
- [rgpt3](https://github.com/ben-aaron188/rgpt3) by [ben-aaron188](https://github.com/ben-aaron188)
|
||||||
|
|
||||||
|
### Ruby
|
||||||
|
|
||||||
|
- [openai](https://github.com/nileshtrivedi/openai/) by [nileshtrivedi](https://github.com/nileshtrivedi)
|
||||||
|
- [ruby-openai](https://github.com/alexrudall/ruby-openai) by [alexrudall](https://github.com/alexrudall)
|
||||||
|
|
||||||
|
### Rust
|
||||||
|
|
||||||
|
- [async-openai](https://github.com/64bit/async-openai) by [64bit](https://github.com/64bit)
|
||||||
|
- [fieri](https://github.com/lbkolev/fieri) by [lbkolev](https://github.com/lbkolev)
|
||||||
|
|
||||||
|
### Scala
|
||||||
|
|
||||||
|
- [openai-scala-client](https://github.com/cequence-io/openai-scala-client) by [cequence-io](https://github.com/cequence-io)
|
||||||
|
|
||||||
|
### Swift
|
||||||
|
|
||||||
|
- [OpenAIKit](https://github.com/dylanshine/openai-kit) by [dylanshine](https://github.com/dylanshine)
|
||||||
|
- [OpenAI](https://github.com/MacPaw/OpenAI/) by [MacPaw](https://github.com/MacPaw)
|
||||||
|
|
||||||
|
### Unity
|
||||||
|
|
||||||
|
- [OpenAi-Api-Unity](https://github.com/hexthedev/OpenAi-Api-Unity) by [hexthedev](https://github.com/hexthedev)
|
||||||
|
- [com.openai.unity](https://github.com/RageAgainstThePixel/com.openai.unity) by [RageAgainstThePixel](https://github.com/RageAgainstThePixel)
|
||||||
|
|
||||||
|
### Unreal Engine
|
||||||
|
|
||||||
|
- [OpenAI-Api-Unreal](https://github.com/KellanM/OpenAI-Api-Unreal) by [KellanM](https://github.com/KellanM)
|
@ -0,0 +1,114 @@
|
|||||||
|
|
||||||
|
# Moderation
|
||||||
|
|
||||||
|
Learn how to build moderation into your AI applications.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The [moderations](/docs/api-reference/moderations) endpoint is a tool you can use to check whether text is potentially harmful. Developers can use it to identify content that might be harmful and take action, for instance by filtering it.
|
||||||
|
|
||||||
|
The models classifies the following categories:
|
||||||
|
|
||||||
|
| Category | Description |
|
||||||
|
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| `hate` | Content that expresses, incites, or promotes hate based on race, gender, ethnicity, religion, nationality, sexual orientation, disability status, or caste. Hateful content aimed at non-protected groups (e.g., chess players) is harassment. |
|
||||||
|
| `hate/threatening` | Hateful content that also includes violence or serious harm towards the targeted group based on race, gender, ethnicity, religion, nationality, sexual orientation, disability status, or caste. |
|
||||||
|
| `harassment` | Content that expresses, incites, or promotes harassing language towards any target. |
|
||||||
|
| `harassment/threatening` | Harassment content that also includes violence or serious harm towards any target. |
|
||||||
|
| `self-harm` | Content that promotes, encourages, or depicts acts of self-harm, such as suicide, cutting, and eating disorders. |
|
||||||
|
| `self-harm/intent` | Content where the speaker expresses that they are engaging or intend to engage in acts of self-harm, such as suicide, cutting, and eating disorders. |
|
||||||
|
| `self-harm/instructions` | Content that encourages performing acts of self-harm, such as suicide, cutting, and eating disorders, or that gives instructions or advice on how to commit such acts. |
|
||||||
|
| `sexual` | Content meant to arouse sexual excitement, such as the description of sexual activity, or that promotes sexual services (excluding sex education and wellness). |
|
||||||
|
| `sexual/minors` | Sexual content that includes an individual who is under 18 years old. |
|
||||||
|
| `violence` | Content that depicts death, violence, or physical injury. |
|
||||||
|
| `violence/graphic` | Content that depicts death, violence, or physical injury in graphic detail. |
|
||||||
|
|
||||||
|
The moderation endpoint is free to use for most developers. For higher accuracy, try splitting long pieces of text into smaller chunks each less than 2,000 characters.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
We are continuously working to improve the accuracy of our classifier. Our support for non-English languages is currently limited.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Quickstart
|
||||||
|
|
||||||
|
To obtain a classification for a piece of text, make a request to the [moderation endpoint](/docs/api-reference/moderations) as demonstrated in the following code snippets:
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
title="Example: Getting moderations"
|
||||||
|
defaultLanguage="curl"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
from openai import OpenAI
|
||||||
|
client = OpenAI()\n
|
||||||
|
response = client.moderations.create(input="Sample text goes here.")\n
|
||||||
|
output = response.results[0]
|
||||||
|
`.trim(),
|
||||||
|
curl: `
|
||||||
|
curl https://api.openai.com/v1/moderations \\
|
||||||
|
-X POST \\
|
||||||
|
-H "Content-Type: application/json" \\
|
||||||
|
-H "Authorization: Bearer $OPENAI_API_KEY" \\
|
||||||
|
-d '{"input": "Sample text goes here"}'
|
||||||
|
`.trim(),
|
||||||
|
node: `
|
||||||
|
import OpenAI from "openai";\n
|
||||||
|
const openai = new OpenAI();\n
|
||||||
|
async function main() {
|
||||||
|
const moderation = await openai.moderations.create({ input: "Sample text goes here." });\n
|
||||||
|
console.log(moderation);
|
||||||
|
}
|
||||||
|
main();
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
Below is an example output of the endpoint. It returns the following fields:
|
||||||
|
|
||||||
|
- `flagged`: Set to `true` if the model classifies the content as potentially harmful, `false` otherwise.
|
||||||
|
- `categories`: Contains a dictionary of per-category violation flags. For each category, the value is `true` if the model flags the corresponding category as violated, `false` otherwise.
|
||||||
|
- `category_scores`: Contains a dictionary of per-category raw scores output by the model, denoting the model's confidence that the input violates the OpenAI's policy for the category. The value is between 0 and 1, where higher values denote higher confidence. The scores should not be interpreted as probabilities.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "modr-XXXXX",
|
||||||
|
"model": "text-moderation-007",
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"flagged": true,
|
||||||
|
"categories": {
|
||||||
|
"sexual": false,
|
||||||
|
"hate": false,
|
||||||
|
"harassment": false,
|
||||||
|
"self-harm": false,
|
||||||
|
"sexual/minors": false,
|
||||||
|
"hate/threatening": false,
|
||||||
|
"violence/graphic": false,
|
||||||
|
"self-harm/intent": false,
|
||||||
|
"self-harm/instructions": false,
|
||||||
|
"harassment/threatening": true,
|
||||||
|
"violence": true
|
||||||
|
},
|
||||||
|
"category_scores": {
|
||||||
|
"sexual": 1.2282071e-6,
|
||||||
|
"hate": 0.010696256,
|
||||||
|
"harassment": 0.29842457,
|
||||||
|
"self-harm": 1.5236925e-8,
|
||||||
|
"sexual/minors": 5.7246268e-8,
|
||||||
|
"hate/threatening": 0.0060676364,
|
||||||
|
"violence/graphic": 4.435014e-6,
|
||||||
|
"self-harm/intent": 8.098441e-10,
|
||||||
|
"self-harm/instructions": 2.8498655e-11,
|
||||||
|
"harassment/threatening": 0.63055265,
|
||||||
|
"violence": 0.99011886
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
We plan to continuously upgrade the moderation endpoint's underlying model. Therefore,
|
||||||
|
custom policies that rely on `category_scores` may need recalibration over time.
|
||||||
|
|
@ -0,0 +1,128 @@
|
|||||||
|
|
||||||
|
Node.js is a popular JavaScript framework that is commonly used for web development. OpenAI provides a custom [Node.js / TypeScript library](https://github.com/openai/openai-node) which makes working with the OpenAI API in JavaScript simple and efficient.
|
||||||
|
|
||||||
|
## Step 1: Setting up Node
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
To use the OpenAI Node.js library, you will need to ensure you have Node.js installed.
|
||||||
|
|
||||||
|
To download Node.js, head to the [official Node website](https://nodejs.org/en/download) and download the most recent version marked "LTS" (Long Term Support). If you are installing Node.js for the first time, you can follow the [official Node.js usage guide](https://nodejs.org/api/synopsis.html#usage) to get started.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Once you have Node.js installed, the OpenAI Node.js library can be installed. From the terminal / command line, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm install --save openai
|
||||||
|
# or
|
||||||
|
yarn add openai
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Step 2: Set up your API key
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The main advantage to making your API key accessible for all projects is that our SDK will automatically detect it and use it without having to write any code.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1. **Open Terminal**: You can find it in the Applications folder or search for it using Spotlight (Command + Space).
|
||||||
|
2. **Edit bash profile**: Use the command `nano ~/.bash_profile` or `nano ~/.zshrc` (for newer MacOS versions) to open the profile file in a text editor.
|
||||||
|
|
||||||
|
3. **Add Environment Variable**: In the editor, ensure you have set your API key as shown below, replacing `your-api-key-here` with your actual API key:
|
||||||
|
|
||||||
|
```
|
||||||
|
export OPENAI_API_KEY='your-api-key-here'
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Save and exit**: Press Ctrl+O to write the changes, followed by Ctrl+X to close the editor.
|
||||||
|
|
||||||
|
5. **Load your profile**: Use the command `source ~/.bash_profile` or `source ~/.zshrc` to load the updated profile.
|
||||||
|
|
||||||
|
6. **Verification**: Verify the setup by typing `echo $OPENAI_API_KEY` in the terminal. It should display your API key.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1. **Open command prompt**: You can find it by searching "cmd" in the start menu.
|
||||||
|
|
||||||
|
2. **Set environment variable in the current session**: To set the environment variable in the current session, use the command below, replacing `your-api-key-here` with your actual API key:
|
||||||
|
|
||||||
|
```
|
||||||
|
setx OPENAI_API_KEY "your-api-key-here"
|
||||||
|
```
|
||||||
|
|
||||||
|
This command will set the OPENAI_API_KEY environment variable for the current session.
|
||||||
|
|
||||||
|
3. **Permanent setup**: To make the setup permanent, add the variable through the system properties as follows:
|
||||||
|
|
||||||
|
- Right-click on 'This PC' or 'My Computer' and select 'Properties'.
|
||||||
|
- Click on 'Advanced system settings'.
|
||||||
|
- Click the 'Environment Variables' button.
|
||||||
|
- In the 'System variables' section, click 'New...' and enter OPENAI_API_KEY as the variable name and your API key as the variable value.
|
||||||
|
|
||||||
|
4. **Verification**: To verify the setup, reopen the command prompt and type the command below. It should display your API key:
|
||||||
|
`echo %OPENAI_API_KEY%`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Step 3: Sending your first API request
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
After you have Node.js configured and set up an API key, the final step is to send a request to the OpenAI API using the Node.js library. To do this, create a file named `openai-test.js` using the terminal or an IDE.
|
||||||
|
|
||||||
|
Inside the file, copy and paste one of the examples below:
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
defaultLanguage="ChatCompletions"
|
||||||
|
code={{
|
||||||
|
ChatCompletions: `
|
||||||
|
import OpenAI from "openai";\n
|
||||||
|
const openai = new OpenAI();\n
|
||||||
|
async function main() {
|
||||||
|
const completion = await openai.chat.completions.create({
|
||||||
|
messages: [{ role: "system", content: "You are a helpful assistant." }],
|
||||||
|
model: "gpt-3.5-turbo",
|
||||||
|
});\n
|
||||||
|
console.log(completion.choices[0]);
|
||||||
|
}\n
|
||||||
|
main();
|
||||||
|
`.trim(),
|
||||||
|
Embeddings: `
|
||||||
|
import OpenAI from "openai";\n
|
||||||
|
const openai = new OpenAI();\n
|
||||||
|
async function main() {
|
||||||
|
const embedding = await openai.embeddings.create({
|
||||||
|
model: "text-embedding-ada-002",
|
||||||
|
input: "The quick brown fox jumped over the lazy dog",
|
||||||
|
});\n
|
||||||
|
console.log(embedding);
|
||||||
|
}\n
|
||||||
|
main();
|
||||||
|
`.trim(),
|
||||||
|
Images: `
|
||||||
|
import OpenAI from "openai";\n
|
||||||
|
const openai = new OpenAI();\n
|
||||||
|
async function main() {
|
||||||
|
const image = await openai.images.generate({ prompt: "A cute baby sea otter" });\n
|
||||||
|
console.log(image.data);
|
||||||
|
}
|
||||||
|
main();
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
To run the code, enter `node openai-test.js` into the terminal / command line.
|
||||||
|
|
||||||
|
The [Chat Completions](/docs/api-reference/chat/create) example highlights just one area of strength for our models: creative ability. Explaining recursion (the programming topic) in a well formatted poem is something both the best developers and best poets would struggle with. In this case, `gpt-3.5-turbo` does it effortlessly.
|
||||||
|
|
||||||
|
|
@ -0,0 +1,85 @@
|
|||||||
|
|
||||||
|
You can use the 'create and stream' helpers in the Python and Node SDKs to create a run and stream the response.
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
title="Create and Stream a Run"
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
from typing_extensions import override
|
||||||
|
from openai import AssistantEventHandler
|
||||||
|
|
||||||
|
# First, we create a EventHandler class to define
|
||||||
|
# how we want to handle the events in the response stream.
|
||||||
|
|
||||||
|
class EventHandler(AssistantEventHandler):
|
||||||
|
@override
|
||||||
|
def on_text_created(self, text) -> None:
|
||||||
|
print(f"\\nassistant > ", end="", flush=True)
|
||||||
|
|
||||||
|
@override
|
||||||
|
def on_text_delta(self, delta, snapshot):
|
||||||
|
print(delta.value, end="", flush=True)
|
||||||
|
|
||||||
|
def on_tool_call_created(self, tool_call):
|
||||||
|
print(f"\\nassistant > {tool_call.type}\\n", flush=True)
|
||||||
|
|
||||||
|
def on_tool_call_delta(self, delta, snapshot):
|
||||||
|
if delta.type == 'code_interpreter':
|
||||||
|
if delta.code_interpreter.input:
|
||||||
|
print(delta.code_interpreter.input, end="", flush=True)
|
||||||
|
if delta.code_interpreter.outputs:
|
||||||
|
print(f"\\n\\noutput >", flush=True)
|
||||||
|
for output in delta.code_interpreter.outputs:
|
||||||
|
if output.type == "logs":
|
||||||
|
print(f"\\n{output.logs}", flush=True)
|
||||||
|
|
||||||
|
# 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()
|
||||||
|
`.trim(),
|
||||||
|
"node.js": `
|
||||||
|
// We use the stream SDK helper to create a run with
|
||||||
|
// streaming. The SDK provides helpful event listeners to handle
|
||||||
|
// the streamed response.
|
||||||
|
|
||||||
|
const run = openai.beta.threads.runs.stream(thread.id, {
|
||||||
|
assistant_id: assistant.id
|
||||||
|
})
|
||||||
|
.on('textCreated', (text) => process.stdout.write('\\nassistant > '))
|
||||||
|
.on('textDelta', (textDelta, snapshot) => process.stdout.write(textDelta.value))
|
||||||
|
.on('toolCallCreated', (toolCall) => process.stdout.write(\`\\nassistant > $\{toolCall.type\}\\n\\n\`))
|
||||||
|
.on('toolCallDelta', (toolCallDelta, snapshot) => {
|
||||||
|
if (toolCallDelta.type === 'code_interpreter') {
|
||||||
|
if (toolCallDelta.code_interpreter.input) {
|
||||||
|
process.stdout.write(toolCallDelta.code_interpreter.input);
|
||||||
|
}
|
||||||
|
if (toolCallDelta.code_interpreter.outputs) {
|
||||||
|
process.stdout.write("\\noutput >\\n");
|
||||||
|
toolCallDelta.code_interpreter.outputs.forEach(output => {
|
||||||
|
if (output.type === "logs") {
|
||||||
|
process.stdout.write(\`\\n$\{output.logs\}\\n\`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
See the full list of Assistants streaming events in our API reference [here](/docs/api-reference/assistants-streaming/events). You can also see a list of SDK event listeners for these events in the [Python](https://github.com/openai/openai-python/blob/main/helpers.md#assistant-events) & [Node](https://github.com/openai/openai-node/blob/master/helpers.md#assistant-events) repository documentation.
|
||||||
|
|
||||||
|
### Next
|
||||||
|
|
||||||
|
1. Dive deeper into [How Assistants work](/docs/assistants/how-it-works)
|
||||||
|
2. Learn more about [Tools](/docs/assistants/tools)
|
||||||
|
3. Explore the [Assistants playground](/playground?mode=assistant)
|
@ -0,0 +1,78 @@
|
|||||||
|
|
||||||
|
Runs are asynchronous, which means you'll want to monitor their `status` by polling the Run object until a [terminal status](/docs/assistants/how-it-works/runs-and-run-steps) is reached. For convenience, the 'create and poll' SDK helpers assist both in creating the run and then polling for its completion.
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
title="Create a Run"
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
run = client.beta.threads.runs.create_and_poll(
|
||||||
|
thread_id=thread.id,
|
||||||
|
assistant_id=assistant.id,
|
||||||
|
instructions="Please address the user as Jane Doe. The user has a premium account."
|
||||||
|
)
|
||||||
|
`.trim(),
|
||||||
|
"node.js": `
|
||||||
|
let run = await openai.beta.threads.runs.createAndPoll(
|
||||||
|
thread.id,
|
||||||
|
{
|
||||||
|
assistant_id: assistant.id,
|
||||||
|
instructions: "Please address the user as Jane Doe. The user has a premium account."
|
||||||
|
}
|
||||||
|
);
|
||||||
|
`.trim(),
|
||||||
|
curl: `
|
||||||
|
curl https://api.openai.com/v1/threads/thread_abc123/runs \\
|
||||||
|
-H "Authorization: Bearer $OPENAI_API_KEY" \\
|
||||||
|
-H "Content-Type: application/json" \\
|
||||||
|
-H "OpenAI-Beta: assistants=v2" \\
|
||||||
|
-d '{
|
||||||
|
"assistant_id": "asst_abc123",
|
||||||
|
"instructions": "Please address the user as Jane Doe. The user has a premium account."
|
||||||
|
}'
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
Once the Run completes, you can [list the Messages](/docs/api-reference/messages/listMessages) added to the Thread by the Assistant.
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
if run.status == 'completed':
|
||||||
|
messages = client.beta.threads.messages.list(
|
||||||
|
thread_id=thread.id
|
||||||
|
)
|
||||||
|
print(messages)
|
||||||
|
else:
|
||||||
|
print(run.status)
|
||||||
|
`.trim(),
|
||||||
|
"node.js": `
|
||||||
|
if (run.status === 'completed') {
|
||||||
|
const messages = await openai.beta.threads.messages.list(
|
||||||
|
run.thread_id
|
||||||
|
);
|
||||||
|
for (const message of messages.data.reverse()) {
|
||||||
|
console.log(\`$\{message.role\} > $\{message.content[0].text.value\}\`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log(run.status);
|
||||||
|
}
|
||||||
|
`.trim(),
|
||||||
|
curl: `
|
||||||
|
curl https://api.openai.com/v1/threads/thread_abc123/messages \\
|
||||||
|
-H "Content-Type: application/json" \\
|
||||||
|
-H "Authorization: Bearer $OPENAI_API_KEY" \\
|
||||||
|
-H "OpenAI-Beta: assistants=v2"
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
You may also want to list the [Run Steps](/docs/api-reference/runs/listRunSteps) of this Run if you'd like to look at any tool calls made during this Run.
|
||||||
|
|
||||||
|
### Next
|
||||||
|
|
||||||
|
1. Dive deeper into [How Assistants work](/docs/assistants/how-it-works)
|
||||||
|
2. Learn more about [Tools](/docs/assistants/tools)
|
||||||
|
3. Explore the [Assistants playground](/playground?mode=assistant)
|
@ -0,0 +1,79 @@
|
|||||||
|
|
||||||
|
# Release notes
|
||||||
|
|
||||||
|
Keep track of updates to OpenAI GPTs. You can also view all of the broader [ChatGPT releases](https://help.openai.com/en/articles/6825453-chatgpt-release-notes) which is used to share new features and capabilities. This page is maintained in a best effort fashion and may not reflect all changes
|
||||||
|
being made.
|
||||||
|
|
||||||
|
### May 13th, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
Actions can{" "}
|
||||||
|
|
||||||
|
return
|
||||||
|
{" "}
|
||||||
|
of up to 10 files per request to be integrated into the conversation
|
||||||
|
|
||||||
|
|
||||||
|
### April 8th, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
Files created by Code Interpreter can now be{" "}
|
||||||
|
|
||||||
|
included
|
||||||
|
{" "}
|
||||||
|
in POST requests
|
||||||
|
|
||||||
|
|
||||||
|
### Mar 18th, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
GPT Builders can view and restore previous versions of their GPTs
|
||||||
|
|
||||||
|
|
||||||
|
### Mar 15th, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
POST requests can{" "}
|
||||||
|
|
||||||
|
include up to ten files
|
||||||
|
{" "}
|
||||||
|
(including DALL-E generated images) from the conversation
|
||||||
|
|
||||||
|
|
||||||
|
### Feb 22nd, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
Users can now rate GPTs, which provides feedback for builders and signal for other
|
||||||
|
users in the Store
|
||||||
|
|
||||||
|
-
|
||||||
|
Users can now leave private feedback for Builders if/when they opt in
|
||||||
|
|
||||||
|
-
|
||||||
|
Every GPT now has an About page with information about the GPT including Rating,
|
||||||
|
Category, Conversation Count, Starter Prompts, and more
|
||||||
|
|
||||||
|
-
|
||||||
|
Builders can now link their social profiles from Twitter, LinkedIn, and GitHub to
|
||||||
|
their GPT
|
||||||
|
|
||||||
|
|
||||||
|
### Jan 10th, 2024
|
||||||
|
|
||||||
|
-
|
||||||
|
The{" "}
|
||||||
|
|
||||||
|
GPT Store
|
||||||
|
{" "}
|
||||||
|
launched publicly, with categories and various leaderboards
|
||||||
|
|
||||||
|
|
||||||
|
### Nov 6th, 2023
|
||||||
|
|
||||||
|
-
|
||||||
|
|
||||||
|
GPTs
|
||||||
|
{" "}
|
||||||
|
allow users to customize ChatGPT for various use cases and share these with other
|
||||||
|
users
|
||||||
|
|
@ -0,0 +1,353 @@
|
|||||||
|
|
||||||
|
|
||||||
|
# Speech to text
|
||||||
|
|
||||||
|
Learn how to turn audio into text
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
The Audio API provides two speech to text endpoints, `transcriptions` and `translations`, based on our state-of-the-art open source large-v2 [Whisper model](https://openai.com/blog/whisper/). They can be used to:
|
||||||
|
|
||||||
|
- Transcribe audio into whatever language the audio is in.
|
||||||
|
- Translate and transcribe the audio into english.
|
||||||
|
|
||||||
|
File uploads are currently limited to 25 MB and the following input file types are supported: `mp3`, `mp4`, `mpeg`, `mpga`, `m4a`, `wav`, and `webm`.
|
||||||
|
|
||||||
|
## Quickstart
|
||||||
|
|
||||||
|
### Transcriptions
|
||||||
|
|
||||||
|
The transcriptions API takes as input the audio file you want to transcribe and the desired output file format for the transcription of the audio. We currently support multiple input and output file formats.
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
title="Transcribe audio"
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
from openai import OpenAI
|
||||||
|
client = OpenAI()\n
|
||||||
|
audio_file= open("/path/to/file/audio.mp3", "rb")
|
||||||
|
transcription = client.audio.transcriptions.create(
|
||||||
|
model="whisper-1",
|
||||||
|
file=audio_file
|
||||||
|
)
|
||||||
|
print(transcription.text)
|
||||||
|
`.trim(),
|
||||||
|
node: `
|
||||||
|
import OpenAI from "openai";\n
|
||||||
|
const openai = new OpenAI();\n
|
||||||
|
async function main() {
|
||||||
|
const transcription = await openai.audio.transcriptions.create({
|
||||||
|
file: fs.createReadStream("/path/to/file/audio.mp3"),
|
||||||
|
model: "whisper-1",
|
||||||
|
});\n
|
||||||
|
console.log(transcription.text);
|
||||||
|
}
|
||||||
|
main();
|
||||||
|
`.trim(),
|
||||||
|
curl: `
|
||||||
|
curl --request POST \\
|
||||||
|
--url https://api.openai.com/v1/audio/transcriptions \\
|
||||||
|
--header "Authorization: Bearer $OPENAI_API_KEY" \\
|
||||||
|
--header 'Content-Type: multipart/form-data' \\
|
||||||
|
--form file=@/path/to/file/audio.mp3 \\
|
||||||
|
--form model=whisper-1
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
By default, the response type will be json with the raw text included.
|
||||||
|
|
||||||
|
```example-content
|
||||||
|
{
|
||||||
|
"text": "Imagine the wildest idea that you've ever had, and you're curious about how it might scale to something that's a 100, a 1,000 times bigger.
|
||||||
|
....
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The Audio API also allows you to set additional parameters in a request. For example, if you want to set the `response_format` as `text`, your request would look like the following:
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
title="Additional options"
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
from openai import OpenAI
|
||||||
|
client = OpenAI()\n
|
||||||
|
audio_file = open("/path/to/file/speech.mp3", "rb")
|
||||||
|
transcription = client.audio.transcriptions.create(
|
||||||
|
model="whisper-1",
|
||||||
|
file=audio_file,
|
||||||
|
response_format="text"
|
||||||
|
)
|
||||||
|
print(transcription.text)
|
||||||
|
`.trim(),
|
||||||
|
node: `
|
||||||
|
import OpenAI from "openai";\n
|
||||||
|
const openai = new OpenAI();\n
|
||||||
|
async function main() {
|
||||||
|
const transcription = await openai.audio.transcriptions.create({
|
||||||
|
file: fs.createReadStream("/path/to/file/speech.mp3"),
|
||||||
|
model: "whisper-1",
|
||||||
|
response_format: "text",
|
||||||
|
});\n
|
||||||
|
console.log(transcription.text);
|
||||||
|
}
|
||||||
|
main();
|
||||||
|
`.trim(),
|
||||||
|
curl: `
|
||||||
|
curl --request POST \\
|
||||||
|
--url https://api.openai.com/v1/audio/transcriptions \\
|
||||||
|
--header "Authorization: Bearer $OPENAI_API_KEY" \\
|
||||||
|
--header 'Content-Type: multipart/form-data' \\
|
||||||
|
--form file=@/path/to/file/speech.mp3 \\
|
||||||
|
--form model=whisper-1 \\
|
||||||
|
--form response_format=text
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
The [API Reference](/docs/api-reference/audio) includes the full list of available parameters.
|
||||||
|
|
||||||
|
### Translations
|
||||||
|
|
||||||
|
The translations API takes as input the audio file in any of the supported languages and transcribes, if necessary, the audio into English. This differs from our /Transcriptions endpoint since the output is not in the original input language and is instead translated to English text.
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
title="Translate audio"
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
from openai import OpenAI
|
||||||
|
client = OpenAI()\n
|
||||||
|
audio_file= open("/path/to/file/german.mp3", "rb")
|
||||||
|
translation = client.audio.translations.create(
|
||||||
|
model="whisper-1",
|
||||||
|
file=audio_file
|
||||||
|
)
|
||||||
|
print(translation.text)
|
||||||
|
`.trim(),
|
||||||
|
node: `
|
||||||
|
import OpenAI from "openai";\n
|
||||||
|
const openai = new OpenAI();\n
|
||||||
|
async function main() {
|
||||||
|
const translation = await openai.audio.translations.create({
|
||||||
|
file: fs.createReadStream("/path/to/file/german.mp3"),
|
||||||
|
model: "whisper-1",
|
||||||
|
});\n
|
||||||
|
console.log(translation.text);
|
||||||
|
}
|
||||||
|
main();
|
||||||
|
`.trim(),
|
||||||
|
curl: `
|
||||||
|
curl --request POST \\
|
||||||
|
--url https://api.openai.com/v1/audio/translations \\
|
||||||
|
--header "Authorization: Bearer $OPENAI_API_KEY" \\
|
||||||
|
--header 'Content-Type: multipart/form-data' \\
|
||||||
|
--form file=@/path/to/file/german.mp3 \\
|
||||||
|
--form model=whisper-1
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
In this case, the inputted audio was german and the outputted text looks like:
|
||||||
|
|
||||||
|
```example-content
|
||||||
|
Hello, my name is Wolfgang and I come from Germany. Where are you heading today?
|
||||||
|
```
|
||||||
|
|
||||||
|
We only support translation into English at this time.
|
||||||
|
|
||||||
|
## Supported languages
|
||||||
|
|
||||||
|
We currently [support the following languages](https://github.com/openai/whisper#available-models-and-languages) through both the `transcriptions` and `translations` endpoint:
|
||||||
|
|
||||||
|
Afrikaans, Arabic, Armenian, Azerbaijani, Belarusian, Bosnian, Bulgarian, Catalan, Chinese, Croatian, Czech, Danish, Dutch, English, Estonian, Finnish, French, Galician, German, Greek, Hebrew, Hindi, Hungarian, Icelandic, Indonesian, Italian, Japanese, Kannada, Kazakh, Korean, Latvian, Lithuanian, Macedonian, Malay, Marathi, Maori, Nepali, Norwegian, Persian, Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovenian, Spanish, Swahili, Swedish, Tagalog, Tamil, Thai, Turkish, Ukrainian, Urdu, Vietnamese, and Welsh.
|
||||||
|
|
||||||
|
While the underlying model was trained on 98 languages, we only list the languages that exceeded <50% [word error rate](https://en.wikipedia.org/wiki/Word_error_rate) (WER) which is an industry standard benchmark for speech to text model accuracy. The model will return results for languages not listed above but the quality will be low.
|
||||||
|
|
||||||
|
## Timestamps
|
||||||
|
|
||||||
|
By default, the Whisper API will output a transcript of the provided audio in text. The [`timestamp_granularities[]` parameter](/docs/api-reference/audio/createTranscription#audio-createtranscription-timestamp_granularities) enables a more structured and timestamped json output format, with timestamps at the segment, word level, or both. This enables word-level precision for transcripts and video edits, which allows for the removal of specific frames tied to individual words.
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
title="Timestamp options"
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
from openai import OpenAI
|
||||||
|
client = OpenAI()\n
|
||||||
|
audio_file = open("speech.mp3", "rb")
|
||||||
|
transcript = client.audio.transcriptions.create(
|
||||||
|
file=audio_file,
|
||||||
|
model="whisper-1",
|
||||||
|
response_format="verbose_json",
|
||||||
|
timestamp_granularities=["word"]
|
||||||
|
)\n
|
||||||
|
print(transcript.words)
|
||||||
|
`.trim(),
|
||||||
|
node: `
|
||||||
|
import OpenAI from "openai";\n
|
||||||
|
const openai = new OpenAI();\n
|
||||||
|
async function main() {
|
||||||
|
const transcription = await openai.audio.transcriptions.create({
|
||||||
|
file: fs.createReadStream("audio.mp3"),
|
||||||
|
model: "whisper-1",
|
||||||
|
response_format: "verbose_json",
|
||||||
|
timestamp_granularities: ["word"]
|
||||||
|
});\n
|
||||||
|
console.log(transcription.text);
|
||||||
|
}
|
||||||
|
main();
|
||||||
|
`.trim(),
|
||||||
|
curl: `
|
||||||
|
curl https://api.openai.com/v1/audio/transcriptions \\
|
||||||
|
-H "Authorization: Bearer $OPENAI_API_KEY" \\
|
||||||
|
-H "Content-Type: multipart/form-data" \\
|
||||||
|
-F file="@/path/to/file/audio.mp3" \\
|
||||||
|
-F "timestamp_granularities[]=word" \\
|
||||||
|
-F model="whisper-1" \\
|
||||||
|
-F response_format="verbose_json"
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
## Longer inputs
|
||||||
|
|
||||||
|
By default, the Whisper API only supports files that are less than 25 MB. If you have an audio file that is longer than that, you will need to break it up into chunks of 25 MB's or less or used a compressed audio format. To get the best performance, we suggest that you avoid breaking the audio up mid-sentence as this may cause some context to be lost.
|
||||||
|
|
||||||
|
One way to handle this is to use the [PyDub open source Python package](https://github.com/jiaaro/pydub) to split the audio:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from pydub import AudioSegment
|
||||||
|
|
||||||
|
song = AudioSegment.from_mp3("good_morning.mp3")
|
||||||
|
|
||||||
|
# PyDub handles time in milliseconds
|
||||||
|
ten_minutes = 10 * 60 * 1000
|
||||||
|
|
||||||
|
first_10_minutes = song[:ten_minutes]
|
||||||
|
|
||||||
|
first_10_minutes.export("good_morning_10.mp3", format="mp3")
|
||||||
|
```
|
||||||
|
|
||||||
|
_OpenAI makes no guarantees about the usability or security of 3rd party software like PyDub._
|
||||||
|
|
||||||
|
## Prompting
|
||||||
|
|
||||||
|
You can use a [prompt](/docs/api-reference/audio/createTranscription#audio/createTranscription-prompt) to improve the quality of the transcripts generated by the Whisper API. The model will try to match the style of the prompt, so it will be more likely to use capitalization and punctuation if the prompt does too. However, the current prompting system is much more limited than our other language models and only provides limited control over the generated audio. Here are some examples of how prompting can help in different scenarios:
|
||||||
|
|
||||||
|
1. Prompts can be very helpful for correcting specific words or acronyms that the model may misrecognize in the audio. For example, the following prompt improves the transcription of the words DALL·E and GPT-3, which were previously written as "GDP 3" and "DALI": "The transcript is about OpenAI which makes technology like DALL·E, GPT-3, and ChatGPT with the hope of one day building an AGI system that benefits all of humanity"
|
||||||
|
2. To preserve the context of a file that was split into segments, you can prompt the model with the transcript of the preceding segment. This will make the transcript more accurate, as the model will use the relevant information from the previous audio. The model will only consider the final 224 tokens of the prompt and ignore anything earlier. For multilingual inputs, Whisper uses a custom tokenizer. For English only inputs, it uses the standard GPT-2 tokenizer which are both accessible through the open source [Whisper Python package](https://github.com/openai/whisper/blob/main/whisper/tokenizer.py#L361).
|
||||||
|
3. Sometimes the model might skip punctuation in the transcript. You can avoid this by using a simple prompt that includes punctuation: "Hello, welcome to my lecture."
|
||||||
|
4. The model may also leave out common filler words in the audio. If you want to keep the filler words in your transcript, you can use a prompt that contains them: "Umm, let me think like, hmm... Okay, here's what I'm, like, thinking."
|
||||||
|
5. Some languages can be written in different ways, such as simplified or traditional Chinese. The model might not always use the writing style that you want for your transcript by default. You can improve this by using a prompt in your preferred writing style.
|
||||||
|
|
||||||
|
## Improving reliability
|
||||||
|
|
||||||
|
As we explored in the prompting section, one of the most common challenges faced when using Whisper is the model often does not recognize uncommon words or acronyms. To address this, we have highlighted different techniques which improve the reliability of Whisper in these cases:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The first method involves using the optional prompt parameter to pass a dictionary of the correct spellings.
|
||||||
|
|
||||||
|
Since it wasn't trained using instruction-following techniques, Whisper operates more like a base GPT model. It's important to keep in mind that Whisper only considers the first 244 tokens of the prompt.
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
title="Prompt parameter"
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
from openai import OpenAI
|
||||||
|
client = OpenAI()\n
|
||||||
|
audio_file = open("/path/to/file/speech.mp3", "rb")
|
||||||
|
transcription = client.audio.transcriptions.create(
|
||||||
|
model="whisper-1",
|
||||||
|
file=audio_file,
|
||||||
|
response_format="text",
|
||||||
|
prompt="ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array, OrbitalLink Seven, DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K., Q.U.A.R.T.Z., F.L.I.N.T."
|
||||||
|
)
|
||||||
|
print(transcription.text)
|
||||||
|
`.trim(),
|
||||||
|
node: `
|
||||||
|
import OpenAI from "openai";\n
|
||||||
|
const openai = new OpenAI();\n
|
||||||
|
async function main() {
|
||||||
|
const transcription = await openai.audio.transcriptions.create({
|
||||||
|
file: fs.createReadStream("/path/to/file/speech.mp3"),
|
||||||
|
model: "whisper-1",
|
||||||
|
response_format: "text",
|
||||||
|
prompt:"ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array, OrbitalLink Seven, DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K., Q.U.A.R.T.Z., F.L.I.N.T.",
|
||||||
|
});\n
|
||||||
|
console.log(transcription.text);
|
||||||
|
}
|
||||||
|
main();
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
While it will increase reliability, this technique is limited to only 244 characters so your list of SKUs would need to be relatively small in order for this to be a scalable solution.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The second method involves a post-processing step using GPT-4 or GPT-3.5-Turbo.
|
||||||
|
|
||||||
|
We start by providing instructions for GPT-4 through the `system_prompt` variable. Similar to what we did with the prompt parameter earlier, we can define our company and product names.
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
title="Post-processing"
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
system_prompt = "You are a helpful assistant for the company ZyntriQix. Your task is to correct any spelling discrepancies in the transcribed text. Make sure that the names of the following products are spelled correctly: ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array, OrbitalLink Seven, DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K., Q.U.A.R.T.Z., F.L.I.N.T. Only add necessary punctuation such as periods, commas, and capitalization, and use only the context provided."\n
|
||||||
|
def generate_corrected_transcript(temperature, system_prompt, audio_file):
|
||||||
|
response = client.chat.completions.create(
|
||||||
|
model="gpt-4o",
|
||||||
|
temperature=temperature,
|
||||||
|
messages=[
|
||||||
|
{
|
||||||
|
"role": "system",
|
||||||
|
"content": system_prompt
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": transcribe(audio_file, "")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
return completion.choices[0].message.content\n
|
||||||
|
corrected_text = generate_corrected_transcript(0, system_prompt, fake_company_filepath)
|
||||||
|
`.trim(),
|
||||||
|
node: `
|
||||||
|
const systemPrompt = "You are a helpful assistant for the company ZyntriQix. Your task is to correct any spelling discrepancies in the transcribed text. Make sure that the names of the following products are spelled correctly: ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array, OrbitalLink Seven, DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K., Q.U.A.R.T.Z., F.L.I.N.T. Only add necessary punctuation such as periods, commas, and capitalization, and use only the context provided.";\n
|
||||||
|
async function generateCorrectedTranscript(temperature, systemPrompt, audioFile) {
|
||||||
|
const transcript = await transcribe(audioFile);
|
||||||
|
const completion = await openai.chat.completions.create({
|
||||||
|
model: "gpt-4o",
|
||||||
|
temperature: temperature,
|
||||||
|
messages: [
|
||||||
|
{
|
||||||
|
role: "system",
|
||||||
|
content: systemPrompt
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: "user",
|
||||||
|
content: transcript
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
return completion.choices[0].message.content;
|
||||||
|
}\n
|
||||||
|
const fakeCompanyFilepath = "path/to/audio/file";
|
||||||
|
generateCorrectedTranscript(0, systemPrompt, fakeCompanyFilepath)
|
||||||
|
.then(correctedText => console.log(correctedText))
|
||||||
|
.catch(error => console.error(error));
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
If you try this on your own audio file, you can see that GPT-4 manages to correct many misspellings in the transcript. Due to its larger context window, this method might be more scalable than using Whisper's prompt parameter and is more reliable since GPT-4 can be instructed and guided in ways that aren't possible with Whisper given the lack of instruction following.
|
||||||
|
|
||||||
|
|
@ -0,0 +1,195 @@
|
|||||||
|
|
||||||
|
# Supported countries and territories
|
||||||
|
|
||||||
|
We provide below a list of the countries and territories in which we currently support access to our API services.
|
||||||
|
|
||||||
|
Accessing or offering access to our services outside of the countries and territories listed below may result in your account being blocked or suspended.
|
||||||
|
|
||||||
|
- Albania
|
||||||
|
- Algeria
|
||||||
|
- Afghanistan
|
||||||
|
- Andorra
|
||||||
|
- Angola
|
||||||
|
- Antigua and Barbuda
|
||||||
|
- Argentina
|
||||||
|
- Armenia
|
||||||
|
- Australia
|
||||||
|
- Austria
|
||||||
|
- Azerbaijan
|
||||||
|
- Bahamas
|
||||||
|
- Bahrain
|
||||||
|
- Bangladesh
|
||||||
|
- Barbados
|
||||||
|
- Belgium
|
||||||
|
- Belize
|
||||||
|
- Benin
|
||||||
|
- Bhutan
|
||||||
|
- Bolivia
|
||||||
|
- Bosnia and Herzegovina
|
||||||
|
- Botswana
|
||||||
|
- Brazil
|
||||||
|
- Brunei
|
||||||
|
- Bulgaria
|
||||||
|
- Burkina Faso
|
||||||
|
- Burundi
|
||||||
|
- Cabo Verde
|
||||||
|
- Cambodia
|
||||||
|
- Cameroon
|
||||||
|
- Canada
|
||||||
|
- Central African Republic
|
||||||
|
- Chad
|
||||||
|
- Chile
|
||||||
|
- Colombia
|
||||||
|
- Comoros
|
||||||
|
- Congo (Brazzaville)
|
||||||
|
- Congo (DRC)
|
||||||
|
- Costa Rica
|
||||||
|
- Côte d'Ivoire
|
||||||
|
- Croatia
|
||||||
|
- Cyprus
|
||||||
|
- Czechia (Czech Republic)
|
||||||
|
- Denmark
|
||||||
|
- Djibouti
|
||||||
|
- Dominica
|
||||||
|
- Dominican Republic
|
||||||
|
- Ecuador
|
||||||
|
- Egypt
|
||||||
|
- El Salvador
|
||||||
|
- Equatorial Guinea
|
||||||
|
- Eritrea
|
||||||
|
- Estonia
|
||||||
|
- Eswatini (Swaziland)
|
||||||
|
- Ethiopia
|
||||||
|
- Fiji
|
||||||
|
- Finland
|
||||||
|
- France
|
||||||
|
- Gabon
|
||||||
|
- Gambia
|
||||||
|
- Georgia
|
||||||
|
- Germany
|
||||||
|
- Ghana
|
||||||
|
- Greece
|
||||||
|
- Grenada
|
||||||
|
- Guatemala
|
||||||
|
- Guinea
|
||||||
|
- Guinea-Bissau
|
||||||
|
- Guyana
|
||||||
|
- Haiti
|
||||||
|
- Holy See (Vatican City)
|
||||||
|
- Honduras
|
||||||
|
- Hungary
|
||||||
|
- Iceland
|
||||||
|
- India
|
||||||
|
- Indonesia
|
||||||
|
- Iraq
|
||||||
|
- Ireland
|
||||||
|
- Israel
|
||||||
|
- Italy
|
||||||
|
- Jamaica
|
||||||
|
- Japan
|
||||||
|
- Jordan
|
||||||
|
- Kazakhstan
|
||||||
|
- Kenya
|
||||||
|
- Kiribati
|
||||||
|
- Kuwait
|
||||||
|
- Kyrgyzstan
|
||||||
|
- Laos
|
||||||
|
- Latvia
|
||||||
|
- Lebanon
|
||||||
|
- Lesotho
|
||||||
|
- Liberia
|
||||||
|
- Libya
|
||||||
|
- Liechtenstein
|
||||||
|
- Lithuania
|
||||||
|
- Luxembourg
|
||||||
|
- Madagascar
|
||||||
|
- Malawi
|
||||||
|
- Malaysia
|
||||||
|
- Maldives
|
||||||
|
- Mali
|
||||||
|
- Malta
|
||||||
|
- Marshall Islands
|
||||||
|
- Mauritania
|
||||||
|
- Mauritius
|
||||||
|
- Mexico
|
||||||
|
- Micronesia
|
||||||
|
- Moldova
|
||||||
|
- Monaco
|
||||||
|
- Mongolia
|
||||||
|
- Montenegro
|
||||||
|
- Morocco
|
||||||
|
- Mozambique
|
||||||
|
- Myanmar
|
||||||
|
- Namibia
|
||||||
|
- Nauru
|
||||||
|
- Nepal
|
||||||
|
- Netherlands
|
||||||
|
- New Zealand
|
||||||
|
- Nicaragua
|
||||||
|
- Niger
|
||||||
|
- Nigeria
|
||||||
|
- North Macedonia
|
||||||
|
- Norway
|
||||||
|
- Oman
|
||||||
|
- Pakistan
|
||||||
|
- Palau
|
||||||
|
- Palestine
|
||||||
|
- Panama
|
||||||
|
- Papua New Guinea
|
||||||
|
- Paraguay
|
||||||
|
- Peru
|
||||||
|
- Philippines
|
||||||
|
- Poland
|
||||||
|
- Portugal
|
||||||
|
- Qatar
|
||||||
|
- Romania
|
||||||
|
- Rwanda
|
||||||
|
- Saint Kitts and Nevis
|
||||||
|
- Saint Lucia
|
||||||
|
- Saint Vincent and the Grenadines
|
||||||
|
- Samoa
|
||||||
|
- San Marino
|
||||||
|
- Sao Tome and Principe
|
||||||
|
- Saudi Arabia
|
||||||
|
- Senegal
|
||||||
|
- Serbia
|
||||||
|
- Seychelles
|
||||||
|
- Sierra Leone
|
||||||
|
- Singapore
|
||||||
|
- Slovakia
|
||||||
|
- Slovenia
|
||||||
|
- Solomon Islands
|
||||||
|
- Somalia
|
||||||
|
- South Africa
|
||||||
|
- South Korea
|
||||||
|
- South Sudan
|
||||||
|
- Spain
|
||||||
|
- Sri Lanka
|
||||||
|
- Suriname
|
||||||
|
- Sweden
|
||||||
|
- Switzerland
|
||||||
|
- Sudan
|
||||||
|
- Taiwan
|
||||||
|
- Tajikistan
|
||||||
|
- Tanzania
|
||||||
|
- Thailand
|
||||||
|
- Timor-Leste (East Timor)
|
||||||
|
- Togo
|
||||||
|
- Tonga
|
||||||
|
- Trinidad and Tobago
|
||||||
|
- Tunisia
|
||||||
|
- Turkey
|
||||||
|
- Turkmenistan
|
||||||
|
- Tuvalu
|
||||||
|
- Uganda
|
||||||
|
- Ukraine (with certain exceptions)
|
||||||
|
- United Arab Emirates
|
||||||
|
- United Kingdom
|
||||||
|
- United States of America
|
||||||
|
- Uruguay
|
||||||
|
- Uzbekistan
|
||||||
|
- Vanuatu
|
||||||
|
- Vietnam
|
||||||
|
- Yemen
|
||||||
|
- Zambia
|
||||||
|
- Zimbabwe
|
@ -0,0 +1,157 @@
|
|||||||
|
|
||||||
|
# Text to speech
|
||||||
|
|
||||||
|
Learn how to turn text into lifelike spoken audio
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
The Audio API provides a [`speech`](/docs/api-reference/audio/createSpeech) endpoint based on our [TTS (text-to-speech) model](/docs/models/tts). It comes with 6 built-in voices and can be used to:
|
||||||
|
|
||||||
|
- Narrate a written blog post
|
||||||
|
- Produce spoken audio in multiple languages
|
||||||
|
- Give real time audio output using streaming
|
||||||
|
|
||||||
|
Here is an example of the `alloy` voice:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Please note that our{" "}
|
||||||
|
usage policies require you to
|
||||||
|
provide a clear disclosure to end users that the TTS voice they are hearing is
|
||||||
|
AI-generated and not a human voice.
|
||||||
|
|
||||||
|
|
||||||
|
## Quick start
|
||||||
|
|
||||||
|
The `speech` endpoint takes in three key inputs: the [model](/docs/api-reference/audio/createSpeech#audio-createspeech-model), the [text](/docs/api-reference/audio/createSpeech#audio-createspeech-input) that should be turned into audio, and the [voice](/docs/api-reference/audio/createSpeech#audio-createspeech-voice) to be used for the audio generation. A simple request would look like the following:
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
title="Generate spoken audio from input text"
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
from pathlib import Path
|
||||||
|
from openai import OpenAI
|
||||||
|
client = OpenAI()\n
|
||||||
|
speech_file_path = Path(__file__).parent / "speech.mp3"
|
||||||
|
response = client.audio.speech.create(
|
||||||
|
model="tts-1",
|
||||||
|
voice="alloy",
|
||||||
|
input="Today is a wonderful day to build something people love!"
|
||||||
|
)\n
|
||||||
|
response.stream_to_file(speech_file_path)
|
||||||
|
`.trim(),
|
||||||
|
curl: `
|
||||||
|
curl https://api.openai.com/v1/audio/speech \\
|
||||||
|
-H "Authorization: Bearer $OPENAI_API_KEY" \\
|
||||||
|
-H "Content-Type: application/json" \\
|
||||||
|
-d '{
|
||||||
|
"model": "tts-1",
|
||||||
|
"input": "Today is a wonderful day to build something people love!",
|
||||||
|
"voice": "alloy"
|
||||||
|
}' \\
|
||||||
|
--output speech.mp3
|
||||||
|
`.trim(),
|
||||||
|
node: `
|
||||||
|
import OpenAI from "openai";\n
|
||||||
|
const openai = new OpenAI();\n
|
||||||
|
const speechFile = path.resolve("./speech.mp3");\n
|
||||||
|
async function main() {
|
||||||
|
const mp3 = await openai.audio.speech.create({
|
||||||
|
model: "tts-1",
|
||||||
|
voice: "alloy",
|
||||||
|
input: "Today is a wonderful day to build something people love!",
|
||||||
|
});
|
||||||
|
console.log(speechFile);
|
||||||
|
const buffer = Buffer.from(await mp3.arrayBuffer());
|
||||||
|
await fs.promises.writeFile(speechFile, buffer);
|
||||||
|
}
|
||||||
|
main();
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
By default, the endpoint will output a MP3 file of the spoken audio but it can also be configured to output any of our [supported formats](/docs/guides/text-to-speech/supported-output-formats).
|
||||||
|
|
||||||
|
## Audio quality
|
||||||
|
|
||||||
|
For real-time applications, the standard `tts-1` model provides the lowest latency but at a lower quality than the `tts-1-hd` model. Due to the way the audio is generated, `tts-1` is likely to generate content that has more static in certain situations than `tts-1-hd`. In some cases, the audio may not have noticeable differences depending on your listening device and the individual person.
|
||||||
|
|
||||||
|
## Voice options
|
||||||
|
|
||||||
|
Experiment with different voices (`alloy`, `echo`, `fable`, `onyx`, `nova`, and `shimmer`) to find one that matches your desired tone and audience. The current voices are optimized for English.
|
||||||
|
|
||||||
|
### Alloy
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Echo
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Fable
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Onyx
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Nova
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Shimmer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Supported output formats
|
||||||
|
|
||||||
|
The default response format is "mp3", but other formats like "opus", "aac", "flac", and "pcm" are available.
|
||||||
|
|
||||||
|
- **Opus**: For internet streaming and communication, low latency.
|
||||||
|
- **AAC**: For digital audio compression, preferred by YouTube, Android, iOS.
|
||||||
|
- **FLAC**: For lossless audio compression, favored by audio enthusiasts for archiving.
|
||||||
|
- **WAV**: Uncompressed WAV audio, suitable for low-latency applications to avoid decoding overhead.
|
||||||
|
- **PCM**: Similar to WAV but containing the raw samples in 24kHz (16-bit signed, low-endian), without the header.
|
||||||
|
|
||||||
|
## Supported languages
|
||||||
|
|
||||||
|
The TTS model generally follows the Whisper model in terms of language support. Whisper [supports the following languages](https://github.com/openai/whisper#available-models-and-languages) and performs well despite the current voices being optimized for English:
|
||||||
|
|
||||||
|
Afrikaans, Arabic, Armenian, Azerbaijani, Belarusian, Bosnian, Bulgarian, Catalan, Chinese, Croatian, Czech, Danish, Dutch, English, Estonian, Finnish, French, Galician, German, Greek, Hebrew, Hindi, Hungarian, Icelandic, Indonesian, Italian, Japanese, Kannada, Kazakh, Korean, Latvian, Lithuanian, Macedonian, Malay, Marathi, Maori, Nepali, Norwegian, Persian, Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovenian, Spanish, Swahili, Swedish, Tagalog, Tamil, Thai, Turkish, Ukrainian, Urdu, Vietnamese, and Welsh.
|
||||||
|
|
||||||
|
You can generate spoken audio in these languages by providing the input text in the language of your choice.
|
||||||
|
|
||||||
|
## Streaming real time audio
|
||||||
|
|
||||||
|
The Speech API provides support for real time audio streaming using [chunk transfer encoding](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding). This means that the audio is able to be played before the full file has been generated and made accessible.
|
||||||
|
|
||||||
|
```python
|
||||||
|
from openai import OpenAI
|
||||||
|
|
||||||
|
client = OpenAI()
|
||||||
|
|
||||||
|
response = client.audio.speech.create(
|
||||||
|
model="tts-1",
|
||||||
|
voice="alloy",
|
||||||
|
input="Hello world! This is a streaming test.",
|
||||||
|
)
|
||||||
|
|
||||||
|
response.stream_to_file("output.mp3")
|
||||||
|
```
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
|
||||||
|
### How can I control the emotional range of the generated audio?
|
||||||
|
|
||||||
|
There is no direct mechanism to control the emotional output of the audio generated. Certain factors may influence the output audio like capitalization or grammar but our internal tests with these have yielded mixed results.
|
||||||
|
|
||||||
|
### Can I create a custom copy of my own voice?
|
||||||
|
|
||||||
|
No, this is not something we support.
|
||||||
|
|
||||||
|
### Do I own the outputted audio files?
|
||||||
|
|
||||||
|
Yes, like with all outputs from our API, the person who created them owns the output. You are still required to inform end users that they are hearing audio generated by AI and not a real person talking to them.
|
@ -0,0 +1,20 @@
|
|||||||
|
#### Tier 5 rate limits
|
||||||
|
|
||||||
|
This is a high level summary and there are per-model exceptions to these limits (e.g. some legacy models or models with larger context windows have different rate limits). To view the exact rate limits per model for your account, visit the [limits](/account/rate-limits) section of your account settings.
|
||||||
|
|
||||||
|
| Model | RPM | TPM | Batch Queue Limit |
|
||||||
|
| ------------------------ | ----------- | ---------- | ----------------- |
|
||||||
|
| `gpt-4o` | 10,000 | 12,000,000 | 1,800,000,000 |
|
||||||
|
| `gpt-4-turbo` | 10,000 | 2,000,000 | 300,000,000 |
|
||||||
|
| `gpt-4` | 10,000 | 300,000 | 45,000,000 |
|
||||||
|
| `gpt-3.5-turbo` | 10,000 | 2,000,000 | 300,000,000 |
|
||||||
|
| `text-embedding-3-large` | 10,000 | 10,000,000 | 4,000,000,000 |
|
||||||
|
| `text-embedding-3-small` | 10,000 | 10,000,000 | 4,000,000,000 |
|
||||||
|
| `text-embedding-ada-002` | 10,000 | 10,000,000 | 4,000,000,000 |
|
||||||
|
| `whisper-1` | 500 | - | - |
|
||||||
|
| `tts-1` | 500 | - | - |
|
||||||
|
| `tts-1-hd` | 20 | - | - |
|
||||||
|
| `dall-e-2` | 500 img/min | - | - |
|
||||||
|
| `dall-e-3` | 75 img/min | - | - |
|
||||||
|
|
||||||
|
If you need higher rate limits than this, you can request an increase in the [limits](/account/rate-limits) section of your account settings.
|
@ -0,0 +1,18 @@
|
|||||||
|
#### Tier 4 rate limits
|
||||||
|
|
||||||
|
This is a high level summary and there are per-model exceptions to these limits (e.g. some legacy models or models with larger context windows have different rate limits). To view the exact rate limits per model for your account, visit the [limits](/account/rate-limits) section of your account settings.
|
||||||
|
|
||||||
|
| Model | RPM | TPM | Batch Queue Limit |
|
||||||
|
| ------------------------ | ----------- | --------- | ----------------- |
|
||||||
|
| `gpt-4o` | 10,000 | 800,000 | 80,000,000 |
|
||||||
|
| `gpt-4-turbo` | 10,000 | 800,000 | 80,000,000 |
|
||||||
|
| `gpt-4` | 10,000 | 300,000 | 30,000,000 |
|
||||||
|
| `gpt-3.5-turbo` | 10,000 | 1,000,000 | 100,000,000 |
|
||||||
|
| `text-embedding-3-large` | 10,000 | 5,000,000 | 500,000,000 |
|
||||||
|
| `text-embedding-3-small` | 10,000 | 5,000,000 | 500,000,000 |
|
||||||
|
| `text-embedding-ada-002` | 10,000 | 5,000,000 | 500,000,000 |
|
||||||
|
| `whisper-1` | 100 | - | - |
|
||||||
|
| `tts-1` | 100 | - | - |
|
||||||
|
| `tts-1-hd` | 10 | - | - |
|
||||||
|
| `dall-e-2` | 100 img/min | - | - |
|
||||||
|
| `dall-e-3` | 15 img/min | - | - |
|
@ -0,0 +1,14 @@
|
|||||||
|
#### Free tier rate limits
|
||||||
|
|
||||||
|
This is a high level summary and there are per-model exceptions to these limits (e.g. some legacy models or models with larger context windows have different rate limits). To view the exact rate limits per model for your account, visit the [limits](/account/rate-limits) section of your account settings.
|
||||||
|
|
||||||
|
| Model | RPM | RPD | TPM | Batch Queue Limit |
|
||||||
|
| ------------------------ | --------- | --- | --------- | ----------------- |
|
||||||
|
| `gpt-3.5-turbo` | 3 | 200 | 40,000 | 200,000 |
|
||||||
|
| `text-embedding-3-large` | 3,000 | 200 | 1,000,000 | 3,000,000 |
|
||||||
|
| `text-embedding-3-small` | 3,000 | 200 | 1,000,000 | 3,000,000 |
|
||||||
|
| `text-embedding-ada-002` | 3,000 | 200 | 1,000,000 | 3,000,000 |
|
||||||
|
| `whisper-1` | 3 | 200 | - | - |
|
||||||
|
| `tts-1` | 3 | 200 | - | - |
|
||||||
|
| `dall-e-2` | 5 img/min | - | - | - |
|
||||||
|
| `dall-e-3` | 1 img/min | - | - | - |
|
@ -0,0 +1,18 @@
|
|||||||
|
#### Tier 1 rate limits
|
||||||
|
|
||||||
|
This is a high level summary and there are per-model exceptions to these limits (e.g. some legacy models or models with larger context windows have different rate limits). To view the exact rate limits per model for your account, visit the [limits](/account/rate-limits) section of your account settings.
|
||||||
|
|
||||||
|
| Model | RPM | RPD | TPM | Batch Queue Limit |
|
||||||
|
| ------------------------ | --------- | ------ | --------- | ----------------- |
|
||||||
|
| `gpt-4o` | 500 | - | 30,000 | 90,000 |
|
||||||
|
| `gpt-4-turbo` | 500 | - | 30,000 | 90,000 |
|
||||||
|
| `gpt-4` | 500 | 10,000 | 10,000 | 100,000 |
|
||||||
|
| `gpt-3.5-turbo` | 3,500 | 10,000 | 60,000 | 200,000 |
|
||||||
|
| `text-embedding-3-large` | 3,000 | - | 1,000,000 | 3,000,000 |
|
||||||
|
| `text-embedding-3-small` | 3,000 | - | 1,000,000 | 3,000,000 |
|
||||||
|
| `text-embedding-ada-002` | 3,000 | - | 1,000,000 | 3,000,000 |
|
||||||
|
| `whisper-1` | 50 | - | - | - |
|
||||||
|
| `tts-1` | 50 | - | - | - |
|
||||||
|
| `tts-1-hd` | 3 | - | - | - |
|
||||||
|
| `dall-e-2` | 5 img/min | - | - | - |
|
||||||
|
| `dall-e-3` | 5 img/min | - | - | - |
|
@ -0,0 +1,18 @@
|
|||||||
|
#### Tier 3 rate limits
|
||||||
|
|
||||||
|
This is a high level summary and there are per-model exceptions to these limits (e.g. some legacy models or models with larger context windows have different rate limits). To view the exact rate limits per model for your account, visit the [limits](/account/rate-limits) section of your account settings.
|
||||||
|
|
||||||
|
| Model | RPM | TPM | Batch Queue Limit |
|
||||||
|
| ------------------------ | ----------- | --------- | ----------------- |
|
||||||
|
| `gpt-4o` | 5,000 | 600,000 | 40,000,000 |
|
||||||
|
| `gpt-4-turbo` | 5,000 | 600,000 | 40,000,000 |
|
||||||
|
| `gpt-4` | 5,000 | 80,000 | 5,000,000 |
|
||||||
|
| `gpt-3.5-turbo` | 3,500 | 160,000 | 10,000,000 |
|
||||||
|
| `text-embedding-3-large` | 5,000 | 5,000,000 | 100,000,000 |
|
||||||
|
| `text-embedding-3-small` | 5,000 | 5,000,000 | 100,000,000 |
|
||||||
|
| `text-embedding-ada-002` | 5,000 | 5,000,000 | 100,000,000 |
|
||||||
|
| `whisper-1` | 100 | - | - |
|
||||||
|
| `tts-1` | 100 | - | - |
|
||||||
|
| `tts-1-hd` | 7 | - | - |
|
||||||
|
| `dall-e-2` | 100 img/min | - | - |
|
||||||
|
| `dall-e-3` | 7 img/min | - | - |
|
@ -0,0 +1,18 @@
|
|||||||
|
#### Tier 2 rate limits
|
||||||
|
|
||||||
|
This is a high level summary and there are per-model exceptions to these limits (e.g. some legacy models or models with larger context windows have different rate limits). To view the exact rate limits per model for your account, visit the [limits](/account/rate-limits) section of your account settings.
|
||||||
|
|
||||||
|
| Model | RPM | TPM | Batch Queue Limit |
|
||||||
|
| ------------------------ | ---------- | --------- | ----------------- |
|
||||||
|
| `gpt-4o` | 5,000 | 450,000 | 1,350,000 |
|
||||||
|
| `gpt-4-turbo` | 5,000 | 450,000 | 1,350,000 |
|
||||||
|
| `gpt-4` | 5,000 | 40,000 | 200,000 |
|
||||||
|
| `gpt-3.5-turbo` | 3,500 | 80,000 | 400,000 |
|
||||||
|
| `text-embedding-3-large` | 5,000 | 1,000,000 | 20,000,000 |
|
||||||
|
| `text-embedding-3-small` | 5,000 | 1,000,000 | 20,000,000 |
|
||||||
|
| `text-embedding-ada-002` | 5,000 | 1,000,000 | 20,000,000 |
|
||||||
|
| `whisper-1` | 50 | - | - |
|
||||||
|
| `tts-1` | 50 | - | - |
|
||||||
|
| `tts-1-hd` | 5 | - | - |
|
||||||
|
| `dall-e-2` | 50 img/min | - | - |
|
||||||
|
| `dall-e-3` | 7 img/min | - | - |
|
@ -0,0 +1,358 @@
|
|||||||
|
|
||||||
|
|
||||||
|
Code Interpreter Beta
|
||||||
|
|
||||||
|
|
||||||
|
Code Interpreter allows Assistants to write and run Python code in a sandboxed execution environment. This tool can process files with diverse data and formatting, and generate files with data and images of graphs. Code Interpreter allows your Assistant to run code iteratively to solve challenging code and math problems. When your Assistant writes code that fails to run, it can iterate on this code by attempting to run different code until the code execution succeeds.
|
||||||
|
|
||||||
|
See a quickstart of how to get started with Code Interpreter [here](/docs/assistants/overview/step-1-create-an-assistant?context=with-streaming).
|
||||||
|
|
||||||
|
## How it works
|
||||||
|
|
||||||
|
Code Interpreter is charged at $0.03 per session. If your Assistant calls Code Interpreter simultaneously in two different threads (e.g., one thread per end-user), two Code Interpreter sessions are created. Each session is active by default for one hour, which means that you only pay for one session per if users interact with Code Interpreter in the same thread for up to one hour.
|
||||||
|
|
||||||
|
### Enabling Code Interpreter
|
||||||
|
|
||||||
|
Pass `code_interpreter` in the `tools` parameter of the Assistant object to enable Code Interpreter:
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
assistant = client.beta.assistants.create(
|
||||||
|
instructions="You are a personal math tutor. When asked a math question, write and run code to answer the question.",
|
||||||
|
model="gpt-4o",
|
||||||
|
tools=[{"type": "code_interpreter"}]
|
||||||
|
)
|
||||||
|
`.trim(),
|
||||||
|
"node.js": `
|
||||||
|
const assistant = await openai.beta.assistants.create({
|
||||||
|
instructions: "You are a personal math tutor. When asked a math question, write and run code to answer the question.",
|
||||||
|
model: "gpt-4o",
|
||||||
|
tools: [{"type": "code_interpreter"}]
|
||||||
|
});
|
||||||
|
`.trim(),
|
||||||
|
curl: `
|
||||||
|
curl https://api.openai.com/v1/assistants \\
|
||||||
|
-u :$OPENAI_API_KEY \\
|
||||||
|
-H 'Content-Type: application/json' \\
|
||||||
|
-H 'OpenAI-Beta: assistants=v2' \\
|
||||||
|
-d '{
|
||||||
|
"instructions": "You are a personal math tutor. When asked a math question, write and run code to answer the question.",
|
||||||
|
"tools": [
|
||||||
|
{ "type": "code_interpreter" }
|
||||||
|
],
|
||||||
|
"model": "gpt-4o"
|
||||||
|
}'
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
The model then decides when to invoke Code Interpreter in a Run based on the nature of the user request. This behavior can be promoted by prompting in the Assistant's `instructions` (e.g., “write code to solve this problem”).
|
||||||
|
|
||||||
|
### Passing files to Code Interpreter
|
||||||
|
|
||||||
|
Files that are passed at the Assistant level are accessible by all Runs with this Assistant:
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
# Upload a file with an "assistants" purpose
|
||||||
|
file = client.files.create(
|
||||||
|
file=open("mydata.csv", "rb"),
|
||||||
|
purpose='assistants'
|
||||||
|
)\n
|
||||||
|
# Create an assistant using the file ID
|
||||||
|
assistant = client.beta.assistants.create(
|
||||||
|
instructions="You are a personal math tutor. When asked a math question, write and run code to answer the question.",
|
||||||
|
model="gpt-4o",
|
||||||
|
tools=[{"type": "code_interpreter"}],
|
||||||
|
tool_resources={
|
||||||
|
"code_interpreter": {
|
||||||
|
"file_ids": [file.id]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
`.trim(),
|
||||||
|
"node.js": `
|
||||||
|
// Upload a file with an "assistants" purpose
|
||||||
|
const file = await openai.files.create({
|
||||||
|
file: fs.createReadStream("mydata.csv"),
|
||||||
|
purpose: "assistants",
|
||||||
|
});\n
|
||||||
|
// Create an assistant using the file ID
|
||||||
|
const assistant = await openai.beta.assistants.create({
|
||||||
|
instructions: "You are a personal math tutor. When asked a math question, write and run code to answer the question.",
|
||||||
|
model: "gpt-4o",
|
||||||
|
tools: [{"type": "code_interpreter"}],
|
||||||
|
tool_resources: {
|
||||||
|
"code_interpreter": {
|
||||||
|
"file_ids": [file.id]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
`.trim(),
|
||||||
|
curl: `
|
||||||
|
# Upload a file with an "assistants" purpose
|
||||||
|
curl https://api.openai.com/v1/files \\
|
||||||
|
-H "Authorization: Bearer $OPENAI_API_KEY" \\
|
||||||
|
-F purpose="assistants" \\
|
||||||
|
-F file="@/path/to/mydata.csv"\n
|
||||||
|
# Create an assistant using the file ID
|
||||||
|
curl https://api.openai.com/v1/assistants \\
|
||||||
|
-u :$OPENAI_API_KEY \\
|
||||||
|
-H 'Content-Type: application/json' \\
|
||||||
|
-H 'OpenAI-Beta: assistants=v2' \\
|
||||||
|
-d '{
|
||||||
|
"instructions": "You are a personal math tutor. When asked a math question, write and run code to answer the question.",
|
||||||
|
"tools": [{"type": "code_interpreter"}],
|
||||||
|
"model": "gpt-4o",
|
||||||
|
"tool_resources": {
|
||||||
|
"code_interpreter": {
|
||||||
|
"file_ids": ["file-BK7bzQj3FfZFXr7DbL6xJwfo"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
Files can also be passed at the Thread level. These files are only accessible in the specific Thread. Upload the File using the [File upload](/docs/api-reference/files/create) endpoint and then pass the File ID as part of the Message creation request:
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
thread = client.beta.threads.create(
|
||||||
|
messages=[
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": "I need to solve the equation \`3x + 11 = 14\`. Can you help me?",
|
||||||
|
"attachments": [
|
||||||
|
{
|
||||||
|
"file_id": file.id,
|
||||||
|
"tools": [{"type": "code_interpreter"}]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
`.trim(),
|
||||||
|
"node.js": `
|
||||||
|
const thread = await openai.beta.threads.create({
|
||||||
|
messages: [
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": "I need to solve the equation \`3x + 11 = 14\`. Can you help me?",
|
||||||
|
"attachments": [
|
||||||
|
{
|
||||||
|
file_id: file.id,
|
||||||
|
tools: [{type: "code_interpreter"}]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
`.trim(),
|
||||||
|
curl: `
|
||||||
|
curl https://api.openai.com/v1/threads/thread_abc123/messages \\
|
||||||
|
-u :$OPENAI_API_KEY \\
|
||||||
|
-H 'Content-Type: application/json' \\
|
||||||
|
-H 'OpenAI-Beta: assistants=v2' \\
|
||||||
|
-d '{
|
||||||
|
"role": "user",
|
||||||
|
"content": "I need to solve the equation \`3x + 11 = 14\`. Can you help me?",
|
||||||
|
"attachments": [
|
||||||
|
{
|
||||||
|
"file_id": "file-ACq8OjcLQm2eIG0BvRM4z5qX",
|
||||||
|
"tools": [{"type": "code_interpreter"}]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}'
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
Files have a maximum size of 512 MB. Code Interpreter supports a variety of file formats including `.csv`, `.pdf`, `.json` and many more. More details on the file extensions (and their corresponding MIME-types) supported can be found in the [Supported files](/docs/assistants/tools/code-interpreter/supported-files) section below.
|
||||||
|
|
||||||
|
### Reading images and files generated by Code Interpreter
|
||||||
|
|
||||||
|
Code Interpreter in the API also outputs files, such as generating image diagrams, CSVs, and PDFs. There are two types of files that are generated:
|
||||||
|
|
||||||
|
1. Images
|
||||||
|
2. Data files (e.g. a `csv` file with data generated by the Assistant)
|
||||||
|
|
||||||
|
When Code Interpreter generates an image, you can look up and download this file in the `file_id` field of the Assistant Message response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "msg_abc123",
|
||||||
|
"object": "thread.message",
|
||||||
|
"created_at": 1698964262,
|
||||||
|
"thread_id": "thread_abc123",
|
||||||
|
"role": "assistant",
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"type": "image_file",
|
||||||
|
"image_file": {
|
||||||
|
"file_id": "file-abc123"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
# ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The file content can then be downloaded by passing the file ID to the Files API:
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
from openai import OpenAI\n
|
||||||
|
client = OpenAI()\n
|
||||||
|
image_data = client.files.content("file-abc123")
|
||||||
|
image_data_bytes = image_data.read()\n
|
||||||
|
with open("./my-image.png", "wb") as file:
|
||||||
|
file.write(image_data_bytes)
|
||||||
|
`.trim(),
|
||||||
|
"node.js": `
|
||||||
|
import OpenAI from "openai";\n
|
||||||
|
const openai = new OpenAI();\n
|
||||||
|
async function main() {
|
||||||
|
const response = await openai.files.content("file-abc123");\n
|
||||||
|
// Extract the binary data from the Response object
|
||||||
|
const image_data = await response.arrayBuffer();\n
|
||||||
|
// Convert the binary data to a Buffer
|
||||||
|
const image_data_buffer = Buffer.from(image_data);\n
|
||||||
|
// Save the image to a specific location
|
||||||
|
fs.writeFileSync("./my-image.png", image_data_buffer);
|
||||||
|
}\n
|
||||||
|
main();
|
||||||
|
`.trim(),
|
||||||
|
curl: `
|
||||||
|
curl https://api.openai.com/v1/files/file-abc123/content \\
|
||||||
|
-H "Authorization: Bearer $OPENAI_API_KEY" \\
|
||||||
|
--output image.png
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
When Code Interpreter references a file path (e.g., ”Download this csv file”), file paths are listed as annotations. You can convert these annotations into links to download the file:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "msg_abc123",
|
||||||
|
"object": "thread.message",
|
||||||
|
"created_at": 1699073585,
|
||||||
|
"thread_id": "thread_abc123",
|
||||||
|
"role": "assistant",
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"type": "text",
|
||||||
|
"text": {
|
||||||
|
"value": "The rows of the CSV file have been shuffled and saved to a new CSV file. You can download the shuffled CSV file from the following link:\n\n[Download Shuffled CSV File](sandbox:/mnt/data/shuffled_file.csv)",
|
||||||
|
"annotations": [
|
||||||
|
{
|
||||||
|
"type": "file_path",
|
||||||
|
"text": "sandbox:/mnt/data/shuffled_file.csv",
|
||||||
|
"start_index": 167,
|
||||||
|
"end_index": 202,
|
||||||
|
"file_path": {
|
||||||
|
"file_id": "file-abc123"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### Input and output logs of Code Interpreter
|
||||||
|
|
||||||
|
By listing the steps of a Run that called Code Interpreter, you can inspect the code `input` and `outputs` logs of Code Interpreter:
|
||||||
|
|
||||||
|
<CodeSample
|
||||||
|
defaultLanguage="python"
|
||||||
|
code={{
|
||||||
|
python: `
|
||||||
|
run_steps = client.beta.threads.runs.steps.list(
|
||||||
|
thread_id=thread.id,
|
||||||
|
run_id=run.id
|
||||||
|
)
|
||||||
|
`.trim(),
|
||||||
|
"node.js": `
|
||||||
|
const runSteps = await openai.beta.threads.runs.steps.list(
|
||||||
|
thread.id,
|
||||||
|
run.id
|
||||||
|
);
|
||||||
|
`.trim(),
|
||||||
|
curl: `
|
||||||
|
curl https://api.openai.com/v1/threads/thread_abc123/runs/RUN_ID/steps \\
|
||||||
|
-H "Authorization: Bearer $OPENAI_API_KEY" \\
|
||||||
|
-H "OpenAI-Beta: assistants=v2" \\
|
||||||
|
`.trim(),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
{
|
||||||
|
"object": "list",
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"id": "step_abc123",
|
||||||
|
"object": "thread.run.step",
|
||||||
|
"type": "tool_calls",
|
||||||
|
"run_id": "run_abc123",
|
||||||
|
"thread_id": "thread_abc123",
|
||||||
|
"status": "completed",
|
||||||
|
"step_details": {
|
||||||
|
"type": "tool_calls",
|
||||||
|
"tool_calls": [
|
||||||
|
{
|
||||||
|
"type": "code",
|
||||||
|
"code": {
|
||||||
|
"input": "# Calculating 2 + 2\nresult = 2 + 2\nresult",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"type": "logs",
|
||||||
|
"logs": "4"
|
||||||
|
}
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Supported files
|
||||||
|
|
||||||
|
_For `text/` MIME types, the encoding must be one of `utf-8`, `utf-16`, or `ascii`._
|
||||||
|
|
||||||
|
| File format | MIME type |
|
||||||
|
| ----------- | --------------------------------------------------------------------------- |
|
||||||
|
| `.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` | `text/css` |
|
||||||
|
| `.js` | `text/javascript` |
|
||||||
|
| `.sh` | `application/x-sh` |
|
||||||
|
| `.ts` | `application/typescript` |
|
||||||
|
| `.csv` | `application/csv` |
|
||||||
|
| `.jpeg` | `image/jpeg` |
|
||||||
|
| `.jpg` | `image/jpeg` |
|
||||||
|
| `.gif` | `image/gif` |
|
||||||
|
| `.png` | `image/png` |
|
||||||
|
| `.tar` | `application/x-tar` |
|
||||||
|
| `.xlsx` | `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` |
|
||||||
|
| `.xml` | `application/xml or "text/xml"` |
|
||||||
|
| `.zip` | `application/zip` |
|
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
What's new in v2? Beta
|
||||||
|
|
||||||
|
|
||||||
|
## April 2024
|
||||||
|
|
||||||
|
We are announcing a variety of new features and improvements to the Assistants API and moving our Beta to a new API version, `OpenAI-Beta: assistants=v2`. Here's what's new:
|
||||||
|
|
||||||
|
- We're launching an [improved retrieval tool called `file_search`](/docs/assistants/tools/file-search), which can ingest up to 10,000 files per assistant - 500x more than before. It is faster, supports parallel queries through multi-threaded searches, and features enhanced reranking and query rewriting.
|
||||||
|
- Alongside `file_search`, we're introducing [`vector_store` objects](/docs/assistants/tools/file-search/vector-stores) in the API. Once a file is added to a vector store, it's automatically parsed, chunked, and embedded, made ready to be searched. Vector stores can be used across assistants and threads, simplifying file management and billing.
|
||||||
|
- You can now [control the maximum number of tokens](/docs/assistants/how-it-works/context-window-management) a run uses in the Assistants API, allowing you to manage token usage costs. You can also set limits on the number of previous / recent messages used in each run.
|
||||||
|
- We've added support for the [`tool_choice` parameter](/docs/api-reference/runs/object#runs/object-tool_choice) which can be used to force the use of a specific tool (like `file_search`, `code_interpreter`, or a `function`) in a particular run.
|
||||||
|
- You can now [create messages with the role `assistant`](/docs/api-reference/messages/createMessage#messages-createmessage-role) to create custom conversation histories in Threads.
|
||||||
|
- Assistant and Run objects now support popular model configuration parameters like [`temperature`](/docs/api-reference/assistants/createAssistant#assistants-createassistant-temperature), [`response_format` (JSON mode)](/docs/api-reference/assistants/createAssistant#assistants-createassistant-response_format), and [`top_p`](/docs/api-reference/assistants/createAssistant#assistants-createassistant-top_p).
|
||||||
|
- You can now use [fine-tuned models](/docs/guides/fine-tuning) in the Assistants API. At the moment, only fine-tuned versions of `gpt-3.5-turbo-0125` are supported.
|
||||||
|
- Assistants API now supports [streaming](/docs/assistants/overview/step-4-create-a-run?context=with-streaming).
|
||||||
|
- We've added several streaming and polling helpers to our [Node](https://github.com/openai/openai-node/blob/master/helpers.md) and [Python](https://github.com/openai/openai-python/blob/main/helpers.md) SDKs.
|
||||||
|
|
||||||
|
See our [migration guide](/docs/assistants/migration) to learn more about how to migrate your tool usage to the latest version of the Assistants API.
|
Binary file not shown.
After Width: | Height: | Size: 163 KiB |
Binary file not shown.
After Width: | Height: | Size: 191 KiB |
Loading…
Reference in New Issue