跳至主要内容

OpenAI O1 API 教程:如何连接 OpenAI 的 API

了解如何通过 API 连接 OpenAI O1 模型,并通过理解推理令牌及其控制方式来管理 API 成本。
· 8分钟 阅读

使用 AI 探索

OpenAI 最近发布了备受期待、具备“博士级推理”能力的模型,但它并不是很多人以为的 GPT-5——而是 OpenAI o1 模型。

OpenAI o1 的运行方式标志着计算资源分配的一个重要范式转变,更加重视训练和推理阶段。这种方法让它在复杂推理任务上表现出色,但与同门的 GPT-4o 和 GPT-4o mini 相比也更加缓慢。

尽管如此,GPT-4o 和 GPT-4o mini 仍是需要快速响应、图像处理或函数调用的应用程序的首选。不过,如果您的项目需要更强的推理能力,且能容忍稍长的响应时间,那么 o1 模型是不二之选。

我已经通过 OpenAI 的 API 体验了 o1,在这篇博客中,我将手把手带您完成同样的操作。我会演示如何连接 API、如何管理成本,最后分享一些提示词技巧,帮助您降低开销并获得更优的响应。

如果您在寻找更入门的文章,请查看这篇OpenAI o1 指南。

注:撰写本教程时,o1 模型仍处于测试阶段。但连接 API 的流程保持不变。

OpenAI O1 API 的使用要求与速率限制

首先需要了解的是,目前要通过 API 访问 o1 模型,需达到使用等级 Tier 5。

等级

资格

使用上限

Free

用户需位于允许的地区

$100 / 月

Tier 1

已付 $5

$100 / 月

Tier 2

已付 $50,且首次成功付款已满 7 天

$500 / 月

Tier 3

已付 $100,且首次成功付款已满 7 天

$1,000 / 月

Tier 4

已付 $250,且首次成功付款已满 14 天

$5,000 / 月

Tier 5

已付 $1,000,且首次成功付款已满 30 天

$50,000 / 月

要查看您的使用等级,请前往OpenAI 开发者平台的账户页面,并在Organization 下的Limits 部分查看。

OpenAI 账户的设置菜单

每个使用等级都有相应的速率限制。撰写本文时,Tier 5 的限制如下:

模型

RPM(每分钟请求数)

TPM(每分钟令牌数)

批处理队列上限

gpt-4o

10,000

30,000,000

5,000,000,000

gpt-4o-mini

30,000

150,000,000

15,000,000,000

o1-preview

500

30,000,000

暂不支持

o1-mini

1000

150,000,000

暂不支持

O1 模型在推理阶段耗时较长,这也是其 RPM 限制低于 GPT-4o 系列的原因。请注意,o1 模型目前不支持批处理,这意味着您不能同时将多个请求打包发送给模型。

由于 O1 模型仍然较新,这些要求和速率限制可能在未来几周内发生变化。例如,OpenAI 最初宣布的每周速率限制为 o1-preview 每周 30 条、o1-mini 每周 50 条。但几天后,他们更新为 o1-preview 每周 50 次查询、o1-mini 每天 50 次查询。

OpenAI O1 的推理令牌

我们很快就会进入实操部分,但在此之前,需要先厘清通过 API 使用 o1 的一个核心新概念:推理令牌(reasoning tokens)。理解这一点对看懂您每月的 OpenAI 账单至关重要。

如果您曾在 ChatGPT 界面中使用过 o1-preview,就会看到它在给出答案前会“把思考过程说出来”。

OpenAI o1 “思考出声”并展示其推理过程的示例

当我们通过 API 使用 o1 模型时,它也会经历同样的思考过程。唯一的区别是,与 ChatGPT 界面不同,这些推理对我们不可见,我们只能看到最终答案。

不过,这些推理依然会被标记化(因此称为“推理令牌”),并且如您所料,是计费的。推理令牌按输出令牌计费,而输出令牌的价格是输入令牌的四倍。

稍后我们会学习如何控制令牌数量并管理成本,但现在先专注于连接OpenAI 的 API 来使用 o1 模型。

OpenAI O1 API:如何连接 OpenAI 的 API

本节我们将按步骤介绍如何通过 API 连接到 o1-preview 模型。稍后还会讲解如何连接 o1-mini 模型。

步骤 1:获取 API 凭证

如果您已有有效账户,可在 OpenAI 的API 密钥页面 获取您的机密 API 密钥。

如果您属于某个组织,可能还需要组织 ID 和项目 ID,这有助于团队更高效地管理成本。请与您的团队确认。

无论您是 API 新手还是经验丰富的开发者,遵循API 最佳实践总是明智之举。

步骤 2:导入 openai 库

OpenAI 通过其 Python 库 openai 简化了与 API 的交互。您可以用以下命令安装:

pip install openai

安装后,从 openai 库中导入 OpenAI 类:

from openai import OpenAI

步骤 3:初始化客户端对象

要与 OpenAI 的 API 交互,我们使用机密 API 密钥初始化一个客户端:

client = OpenAI(api_key=’your-api-key’)

如果您属于某个组织,您可能还需要组织 ID 和项目 ID,届时此步骤可能如下所示:

client = OpenAI(
    organization=’your-organization-id’,
    project=’your-project-id’,
    api_key=’your-api-key’
)

步骤 4:发起一次 API 调用

撰写本文时,可用的 o1 模型只有 o-1 preview 和 o1-mini。它们都可以通过 chat.completions 端点使用。下面的代码中,请注意:

  • 我们通过 client.chat.completions.create() 调用端点。
  • 将 ”o1-preview” 作为 model 参数的字符串值。
  • 将提示作为 ”content” 键的值传入。
  • 通过 response.choices[0].message.content 访问最终响应。
response = client.chat.completions.create(
    model="o1-preview",
    messages=[
        {
            "role": "user",
            "content": "Write a Python script that takes a matrix represented as a string with format '[1,2],[3,4],[5,6]' and prints the transpose in the same format."
        }
    ]
)
print(response.choices[0].message.content)
```python
import ast

# Read the input string
s = input()

# Add outer brackets to make it a valid list representation
input_str = '[' + s + ']'

# Safely evaluate the string to a list of lists
matrix = ast.literal_eval(input_str)

# Transpose the matrix
transposed = list(map(list, zip(*matrix)))

# Convert the transposed matrix back to the required string format
transposed_str = ','.join('[' + ','.join(map(str, row)) + ']' for row in transposed)

# Print the result
print(transposed_str)
```

如何查看推理令牌数量

如前所述,底层推理仍然会计入计费令牌。针对上面的代码,以下是令牌使用情况的拆分:

print(response.usage)
CompletionUsage(completion_tokens=1279, prompt_tokens=43, total_tokens=1322, completion_tokens_details={'reasoning_tokens': 1024})

从输出可以看到,推理令牌数为 1024:completion_tokens_details={'reasoning_tokens': 1024}。

模型共生成了 1279 个补全令牌(completion_tokens=1279),其中 1024 个是不可见的推理令牌——占比约 80%!

使用新的 o1 模型后,成本管理变得更复杂了,我们来详细讨论一下。

如何用 OpenAI O1 模型控制成本

在以往的模型中,我们用 max_tokens 参数来控制补全令牌的数量,比较简单:生成的令牌数与可见令牌数总是相同。

但在 o1 模型中,我们需要一个参数来为所有补全令牌设定上限,包括可见的输出令牌和不可见的推理令牌。为此,OpenAI 新增了 max_completion_tokens 参数,同时弃用了 max_tokens,并使其与 o1 模型不兼容。

我们用上一个示例来试试 max_completion_tokens,将其设为 300 看看结果。请注意,要使用这个新参数,如果您使用的 openai 库版本较旧,可能需要进行更新。

response_with_limit = client.chat.completions.create(
    model="o1-preview",
    messages=[
        {
            "role": "user",
            "content": "Write a Python script that takes a matrix represented as a string with format '[1,2],[3,4],[5,6]' and prints the transpose in the same format."
        }
    ],
    max_completion_tokens=300
)
print(response_with_limit.choices[0].message.content)
‎ ‎ ‎ ‎ 

注意我们没有得到任何输出。但我们还在付费吗?答案是是的。

print(response_with_limit.usage)
CompletionUsage(completion_tokens=300, prompt_tokens=43, total_tokens=343, completion_tokens_details=CompletionTokensDetails(reasoning_tokens=300))

如果 o1 模型在得出最终答案前就达到了令牌上限,它会停止推理过程且不返回任何输出。因此,务必将 max_completion_tokens 设为足以保证有输出的数值——否则我们会为推理令牌和输入令牌买单,却得不到任何回报。

您需要根据具体用例来试验 max_completion_tokens 的具体取值,但 OpenAI 建议至少为补全令牌总数预留 25,000 个令牌。

为避免输出被截断(或完全没有输出),如果您的用例涉及大量令牌,还需要留意上下文窗口。o1-preview 和 o-1 mini 的上下文窗口为 128,000 个令牌。但请注意,输出令牌(可见与不可见)在 o1-preview 上限为 32,768,在 o1-mini 上限为 65,536。

当超过上下文窗口时,o1 模型的输出会被截断

来源:OpenAI

OpenAI O1-Mini API:如何连接 OpenAI 的 API

大型的 o1 模型在高级推理上表现强劲,但也很慢。如果您的应用需要更快的响应时间,且愿意在推理性能上略作妥协,那么 o1-mini 可能更适合。

要通过 API 连接 o1-mini 模型,请遵循我们针对 o1-preview 模型的所有步骤——但在 model 参数处改用字符串 ”o1-mini”。

我们将使用与上个示例相同的提示,以便比较令牌用量:

response_mini = client.chat.completions.create(
    model="o1-mini",
    messages=[
        {
            "role": "user",
            "content": "Write a Python script that takes a matrix represented as a string with format '[1,2],[3,4],[5,6]' and prints the transpose in the same format."
        }
    ]
)
print(response_mini.choices[0].message.content)
Certainly! Below is a Python script that takes a matrix represented as a string in the format `'[1,2],[3,4],[5,6]'`, computes its transpose, and prints the transposed matrix in the same string format.

```python
def parse_matrix(matrix_str):
    """
    Parses a matrix string like '[1,2],[3,4],[5,6]' into a list of lists.
    """
    # Split the string by '],[' to separate the rows
    rows = matrix_str.strip().split('],[')
    
    # Clean the first and last elements by removing any leading '[' or trailing ']'
    rows[0] = rows[0].lstrip('[')
    rows[-1] = rows[-1].rstrip(']')
    
    # Convert each row into a list of integers
    matrix = []
    for row in rows:
        # Split each row by ',' and convert each element to integer
        matrix.append([int(num) for num in row.split(',')])
    
    return matrix

def transpose_matrix(matrix):
    """
    Transposes a given matrix (list of lists).
    """
    # Use zip with unpacking to transpose the matrix
    transposed = list(zip(*matrix))
    # Convert each tuple in the transposed matrix back to a list
    transposed = [list(row) for row in transposed]
    return transposed

def matrix_to_string(matrix):
    """
    Converts a list of lists into a string format like '[1,3,5],[2,4,6]'.
    """
    # Convert each row to a string
    row_strings = []
    for row in matrix:
        # Convert each number to string and join with commas
        row_str = ','.join(str(num) for num in row)
        # Enclose the row in brackets
        row_strings.append(f'[{row_str}]')
    
    # Join all rows with commas
    return ','.join(row_strings)

def main():
    # Example input
    input_str = '[1,2],[3,4],[5,6]'
    
    # Parse the input string into a matrix
    matrix = parse_matrix(input_str)
    
    # Compute the transpose of the matrix
    transposed = transpose_matrix(matrix)
    
    # Convert the transposed matrix back to string format
    output_str = matrix_to_string(transposed)
    
    # Print the result
    print(output_str)

if __name__ == "__main__":
    main()
```

### How It Works:

1. **Parsing the Input String:**
    - The `parse_matrix` function takes the input string and splits it into individual rows by looking for the pattern `"],["`.
    - It cleans the first and last rows by removing any leading `[` or trailing `]`.
    - Each row string is then split by `,` to extract individual numbers, which are converted to integers and stored in a nested list.

2. **Transposing the Matrix:**
    - The `transpose_matrix` function uses the `zip` function along with unpacking (`*`) to transpose the matrix. This effectively switches rows with columns.
    - Since `zip` returns tuples, each transposed row is converted back into a list.

3. **Converting Back to String:**
    - The `matrix_to_string` function takes the transposed matrix and converts each row back into a string in the desired format.
    - It joins the elements of each row with commas and encloses them in brackets.
    - Finally, all row strings are joined together with commas to form the final output string.

4. **Main Execution:**
    - The `main` function demonstrates the usage with an example input. You can modify `input_str` to test with different matrices.
    - It prints the transposed matrix in the specified string format.

### Example:

Given the input string:
```
'[1,2],[3,4],[5,6]'
```
The script will output:
```
[1,3,5],[2,4,6]
```

### Handling User Input:

If you'd like the script to accept user input instead of having a hardcoded string, you can modify the `main` function as follows:

```python
def main():
    # Take user input
    input_str = input("Enter the matrix string (e.g., '[1,2],[3,4],[5,6]'): ").strip()
    
    # Parse the input string into a matrix
    matrix = parse_matrix(input_str)
    
    # Compute the transpose of the matrix
    transposed = transpose_matrix(matrix)
    
    # Convert the transposed matrix back to string format
    output_str = matrix_to_string(transposed)
    
    # Print the result
    print(output_str)
```

With this modification, when you run the script, it will prompt you to enter the matrix string:

```
Enter the matrix string (e.g., '[1,2],[3,4],[5,6]'): [1,2],[3,4],[5,6]
[1,3,5],[2,4,6]
```

### Notes:

- **Error Handling:** The current script assumes that the input string is well-formatted. For production code, you might want to add error handling to manage malformed inputs.
- **Non-integer Elements:** If your matrix contains non-integer elements (e.g., floats or strings), you'll need to adjust the parsing logic accordingly.

### Running the Script:

1. **Save the Script:** Save the above code to a file, say `transpose_matrix.py`.
2. **Run the Script:** Open a terminal or command prompt, navigate to the directory containing the script, and execute:

   ```bash
   python transpose_matrix.py
   ```

3. **Provide Input:** If you've modified it to accept user input, enter the matrix string when prompted.

This script provides a straightforward way to transpose a matrix represented as a string and can be easily adapted or extended based on specific requirements.

可见输出相比 o1-preview 要啰嗦得多——我们来对比一下用量:

print(response_mini.usage) # o1-mini
print(response.usage) # o1-preview
CompletionUsage(completion_tokens=1511, prompt_tokens=43, total_tokens=1554, completion_tokens_details=CompletionTokensDetails(reasoning_tokens=256))
CompletionUsage(completion_tokens=1279, prompt_tokens=43, total_tokens=1322, completion_tokens_details={'reasoning_tokens': 1024})

o1-mini 模型的推理量只有 o1 的四分之一(256 vs. 1024 个推理令牌)。然而,由于其答案更冗长,补全令牌总数实际上更大。尽管 o1-mini 比 o1-preview 便宜不少,但这仍不理想。

一种缓解方式是通过提示词工程——我们要求模型避免解释和开场白,只输出答案。

response_mini_2 = client.chat.completions.create(
    model="o1-mini",
    messages=[
        {
            "role": "user",
            "content": "Write a Python script that takes a matrix represented as a string with format '[1,2],[3,4],[5,6]' and prints the transpose in the same format. Limit yourself to the answer and don't add explanations or introductions."
        }
    ]
)
print(response_mini_2.choices[0].message.content)
```python
import ast

def parse_matrix(matrix_str):
    rows = matrix_str.split('],[')
    rows[0] = rows[0].lstrip('[')
    rows[-1] = rows[-1].rstrip(']')
    matrix = [ast.literal_eval(f'[{row}]') for row in rows]
    return matrix

def transpose(matrix):
    return list(zip(*matrix))

def format_matrix(transposed):
    return ','.join([f'[{",".join(map(str, row))}]' for row in transposed])

input_str = '[1,2],[3,4],[5,6]'
matrix = parse_matrix(input_str)
transposed = transpose(matrix)
output_str = format_matrix(transposed)
print(output_str)
```

好多了!补全令牌总数大约减少了三分之二:

print(response_mini_2.usage)
CompletionUsage(completion_tokens=487, prompt_tokens=55, total_tokens=542, completion_tokens_details=CompletionTokensDetails(reasoning_tokens=320))

API 测试版的限制

撰写本教程时,o1 模型仍处于测试阶段。尽管 OpenAI 表示在接下来的几周将推出更多功能和更友好的速率限制,但目前使用测试版 o1 模型会遇到以下限制:

  • 多模态: 仅支持文本;无法处理图像。
  • 消息类型: 仅允许 user 和 assistant 消息;不支持 system 消息。
  • 流式输出: 暂不可用。
  • 工具: 不包含函数调用、工具与响应格式参数。
  • Logprobs: 不支持该参数。
  • 其他设置: temperature、top_p 和 n 固定为 1,presence_penalty 与 frequency_penalty 均为 0。
  • Assistants 与批处理: 这些模型无法与 Assistants API 或 Batch API 搭配使用。

OpenAI O1 API:定价

目前,在高级推理领域 OpenAI 几乎没有竞争对手。因此,价格可能略显偏高,而且如您所见,显著高于 GPT-4o 系列:

模型

价格

o1-preview

$15.00 / 100 万输入令牌

$60.00 / 100 万输出令牌

o1-mini

$3.00 / 100 万输入令牌

$12.00 / 100 万输出令牌

gpt-4o

$5.00 / 100 万输入令牌

$15.00 / 100 万输出令牌

gpt-4o-mini

$0.150 / 100 万输入令牌

$0.600 / 100 万输出令牌

在 O1 模型上的最佳提示实践

o1 模型与我们熟悉的 GPT-4o 或 Claude 3.5 Sonnet 差异显著。由于 o1 模型已在进行思维链推理,它更适合直截了当的提示。使用少样例提示或让模型“逐步思考”反而可能降低其表现。

以下是 OpenAI 开发者建议的一些最佳提示实践:

  • 保持提示简洁清晰: 模型更擅长处理简短直接的指令,无需冗长解释。
  • 避免思维链提示: 这些模型会在内部完成推理,无需要求其“逐步思考”或“解释推理过程”。
  • 使用分隔符提高清晰度: 使用三引号、XML 标签或分节标题等分隔符,清晰划分输入的不同部分。
  • 在检索增强生成(RAG)中限制额外上下文: 在添加上下文或文档时,只包含最相关的信息,以避免让模型的响应变得复杂。

结语

在本文中,我分享了通过 OpenAI 的 API 连接到 o1 模型的分步指南。

如果您的项目需要高级推理能力,并能接受稍长的响应时间,o1 模型是极佳的选择。

对于需要快速响应、图像处理或函数调用的应用,GPT-4o 和 GPT-4o mini 仍是首选。

想要继续学习,推荐以下资源:

FAQs

OpenAI o1 是否提供 API?

是的,OpenAI 提供用于访问 O1 模型的 API。通过该 API,您可以将 o1 模型的能力集成到您的应用中,实现诸如文本生成、语言翻译等任务。上述教程概述了使用该 API 连接到 o1 模型的步骤。

OpenAI 的 o1 API 是免费的吗?

OpenAI 的 o1 并非免费——详见本教程的定价章节。

非 o1-preview 的 o1 版本预计何时发布?

完整版本 o1(非预览版)的发布日期通常由 OpenAI 通过官方渠道公布。请关注 OpenAI 的博客、网站或社交媒体,获取关于 o1 发布时间线的最新更新与公告。

OpenAI o1 模型的定价是多少?

o1-preview 的价格为每 100 万输入令牌 $15.00、每 100 万输出令牌 $60.00;o1-mini 的价格为每 100 万输入令牌 $3.00、每 100 万输出令牌 $12.00。相比之下,gpt-4o 的价格为每 100 万输入令牌 $5.00、每 100 万输出令牌 $15.00;gpt-4o-mini 的价格为每 100 万输入令牌 $0.150、每 100 万输出令牌 $0.600。

OpenAI o1 模型中的推理令牌是什么?

在 o1 模型 中,推理令牌是指模型在内部思考过程中过掉的令牌。尽管推理令牌会消耗计算资源并计入令牌总用量(从而计费),但它们不会作为输出的一部分展示给终端用户。

Alex Olteanu

作者

Alex Olteanu

我是一名编辑和撰稿人,专注于 AI 博客、教程与新闻,确保内容契合成熟的内容策略并遵循 SEO 最佳实践。我编写过关于 Python、统计学、概率和数据可视化的数据科学课程。我的长篇小说曾获奖,业余时间从事影视剧本创作和电影导演。

主题