中文 ▾
获取 API 密钥

Python 中的 Codex API:调用编码大语言模型

最简单的 codex api python 设置是指向不同 Base URL 的官方 openai 包。以下示例涵盖针对此 OpenAI 兼容接口的代码生成、JSON 模式、函数调用和流式输出。

更新于

一根发光的电缆蜿蜒穿过代码块进入服务器立方体,展示了 Python 对编码 LLM API 的调用
一根连接笔记本电脑和服务器立方体的发光电缆,说明如何将客户端指向 API 基础 URL

要点

  • 安装 openai 包,将 base_url 设置为 https://api.getcodexapi.com/v1,将模型设置为 uncensored。
  • 代码和 JSON 使用低 temperature(0 到 0.3),头脑风暴使用较高的值。
  • 支持函数调用、JSON 模式和流式输出;不支持 embeddings。
  • 完整密钥将并发限制在 8,并在短暂等待后重试 429 响应。

设置和首次调用

这是一个独立的 OpenAI 兼容服务,并非 OpenAI 自己的 Codex API。其单一模型是开放权重模型,仅支持文本,生成的代码足以用于生成、解释和重构任务,但你仍应进行审查。如果你想先了解背景,OpenAI Codex API页面解释了两者之间的关系。

使用 pip install openai 安装 SDK,在 API 密钥页面创建密钥,然后运行:

# pip install openai
from openai import OpenAI

client = OpenAI(base_url="https://api.getcodexapi.com/v1", api_key="YOUR_KEY")

resp = client.chat.completions.create(
    model="uncensored",
    messages=[
        {"role": "system", "content": "You are a senior Python developer. Reply with code only, no commentary."},
        {"role": "user", "content": "Write a function that parses an ISO 8601 date string and returns a datetime."},
    ],
    temperature=0.2,
)
print(resp.choices[0].message.content)

新用户的试用额度 $0.50 足以覆盖数千次此类小调用。Temperature 设为 0.2,因为代码受益于更少的随机性。如果答案周围出现 markdown 围栏,请在代码中剥离它,或在 system message 中要求纯文本。Base URL 页面 Codex API base URL再次列出了确切地址。

提示生成可运行代码

一些习惯比任何参数都能更好地提高输出质量。

  • 声明语言和版本。 "Python 3.11,仅限标准库" 消除了大量猜测。
  • 提供签名。粘贴函数头和 docstring,并要求模型填充函数体。
  • 展示一个输入和输出示例。 这比文字描述更能确定边缘情况。
  • 一次只要求一件事。 生成函数,然后在第二次调用中要求生成测试。
  • 请求 diff 进行编辑。 整个文件重写会消耗输出 token,其成本高于输入。

上下文窗口为 100,000 token,max_tokens 是可选的。对于代码任务,你可以粘贴多个模块,并为回复留出空间。设置 max_tokens 仅作为防止输出失控的安全网。

用于结构化结果的 JSON 模式

当代码消耗答案时,使用 JSON 模式。它使输出成为有效的 JSON;它不强制执行你的 schema,因此在提示词中命名键并检查它们。

import json
from openai import OpenAI

client = OpenAI(base_url="https://api.getcodexapi.com/v1", api_key="YOUR_KEY")

resp = client.chat.completions.create(
    model="uncensored",
    response_format={"type": "json_object"},
    messages=[
        {"role": "system", "content": "Return JSON with keys: name, args (list of strings), returns."},
        {"role": "user", "content": "Describe the signature of: def clamp(x, lo, hi)."},
    ],
    temperature=0,
)
data = json.loads(resp.choices[0].message.content)
print(data["name"], data["args"])

将其与 try/except 包裹的 json.loads 以及一次重试配对,将解析错误发送回去。实际上,这可以处理罕见的格式错误响应。使用温度 0,以便重复运行结果一致。

函数调用

通过工具你描述函数,模型决定何时调用它们。你运行函数,然后使用 tool 角色将输出发回。这是每个编码智能体的基础。

import json
from openai import OpenAI

client = OpenAI(base_url="https://api.getcodexapi.com/v1", api_key="YOUR_KEY")

tools = [{
    "type": "function",
    "function": {
        "name": "run_tests",
        "description": "Run the project's test suite and return the output.",
        "parameters": {
            "type": "object",
            "properties": {"path": {"type": "string"}},
            "required": ["path"],
        },
    },
}]

messages = [{"role": "user", "content": "Run the tests in tests/unit and tell me what failed."}]
first = client.chat.completions.create(model="uncensored", messages=messages, tools=tools, tool_choice="auto")
msg = first.choices[0].message

if msg.tool_calls:
    call = msg.tool_calls[0]
    args = json.loads(call.function.arguments)
    output = "2 passed, 1 failed: test_parse_empty"          # replace with a real runner
    messages.append(msg)
    messages.append({"role": "tool", "tool_call_id": call.id, "content": output})
    final = client.chat.completions.create(model="uncensored", messages=messages, tools=tools)
    print(final.choices[0].message.content)

像对待任何其他贡献一样测试生成的代码:运行它、lint 它,并保持一组带有已知良好输出的提示词,以便在提示词更改导致结果变差时注意到。在比较版本时固定 seed 和 temperature。

注意:保持工具描述简短且字面化,在运行任何内容之前验证参数,并且永远不要将模型输出直接传入 shell。对于循环,只要存在 tool_calls 就重复调用,并在达到最大步骤数后停止。每一步都会重新发送历史记录,因此十步运行大约支付十倍的上下文费用。

流式输出与 429 重试

对于交互式工具,在 token 到达时进行流式输出。使用情况出现在流末尾,这使得成本记录变得容易。

import time
from openai import OpenAI, RateLimitError

client = OpenAI(base_url="https://api.getcodexapi.com/v1", api_key="YOUR_KEY", max_retries=0)

def ask(prompt, tries=4):
    for attempt in range(tries):
        try:
            stream = client.chat.completions.create(
                model="uncensored",
                messages=[{"role": "user", "content": prompt}],
                stream=True,
                stream_options={"include_usage": True},
            )
            text = []
            for chunk in stream:
                if chunk.choices and chunk.choices[0].delta.content:
                    piece = chunk.choices[0].delta.content
                    text.append(piece)
                    print(piece, end="", flush=True)
                if chunk.usage:
                    print("\ntokens:", chunk.usage.prompt_tokens, chunk.usage.completion_tokens)
            return "".join(text)
        except RateLimitError:
            time.sleep(5 * (attempt + 1))
    raise RuntimeError("still rate limited")

ask("Explain Python generators in four sentences.")

该重试循环背后的限制:完整密钥允许 8 个并发请求和每分钟 300 个请求,试用密钥允许 2 个和 60 个。超过限制时,你会收到带有代码 rate_limited 或 concurrency 的 HTTP 429。临时过载也会给出带有 Retry-After: 5 头的 429。示例在客户端设置 max_retries=0,以便由你自己的循环控制等待。流式请求在其流结束之前占用并发槽位,因此请务必消耗或关闭流。

同时运行多个请求

批量作业(例如为一百个函数生成测试)需要并发限制。在完整密钥上使用最多 8 个工作人员的线程池。

一个简单的模式是在调用 ask 的函数周围使用 ThreadPoolExecutor(max_workers=6),为其他工作留出两个槽位。试用密钥使用 2 个工作人员。如果你传递更大的数字,API 将对额外请求返回 concurrency 错误,你的重试循环将花费时间等待而不是工作。对于异步代码,使用 AsyncOpenAI 并在每次调用周围使用 asyncio.Semaphore(6);它在没有线程的情况下提供相同的限制。X-RateLimit-Limit-Requests 和 X-RateLimit-Limit-Concurrency 响应头显示了你密钥的限制。

编码工作负载的成本

价格为每 1M 输入 token $0.15,每 1M 输出 token $0.50。假设你为 200 个函数生成单元测试。每次调用发送 1,500 个输入 token 并返回 700 个 token。输入:200 x 1,500 = 300,000 token,即 $0.045。输出:200 x 700 = 140,000 token,即 $0.07。总计:$0.115。

大型文件的重构发送 30,000 个输入 token 和 8,000 个输出 token:每次运行 $0.0045 + $0.004 = $0.0085。失败或被拒绝的请求不收费,且额度永不过期。充值从 $20 开始,可以通过信用卡或加密货币支付,$50 起赠 5%,$100 起赠 10%,$200 起赠 15%。详见 定价,并阅读 文档 获取完整参数列表。

问答

我可以使用标准的 openai Python 包吗?

可以。将 base_url 设置为 https://api.getcodexapi.com/v1,传入你的密钥并使用模型 ID uncensored。

它支持从 Python 进行函数调用吗?

可以。传入 tools 和 tool_choice,然后使用 tool 角色返回结果。流式输出的 tool_calls 也有效。

如何获取结构化输出?

使用带有 type json_object 的 response_format,在提示词中命名键,并在代码中验证结果。

有异步客户端吗?

openai 包提供了 AsyncOpenAI,使用此 Base URL 时工作方式相同。完整密钥的并发请求保持在 8 或以下。

只差一张表单,即可获得密钥

创建账户,复制密钥,更改基础 URL。这就是全部设置。

获取 API 密钥