ES ▾
Obtener clave de API

API Codex en Python: Uso de un LLM de código

La configuración de codex api python más simple es el paquete openai oficial apuntando a una base URL diferente. Los ejemplos siguientes cubren generación de código, modo JSON, llamadas a funciones y streaming contra este endpoint compatible con OpenAI.

Actualizado

Un cable brillante que se enrosca a través de bloques de código hacia un cubo de servidor, ilustrando llamadas de Python a una API de LLM de código
Un cable brillante que conecta un portátil a un cubo de servidor, ilustrando cómo apuntar un cliente a una URL base de API

Puntos clave

  • Instala el paquete openai, establece base_url en https://api.getcodexapi.com/v1 y el modelo en uncensored.
  • Usa temperatura baja (0 a 0.3) para código y JSON, y más alta para lluvia de ideas.
  • Se admiten llamadas a funciones, modo JSON y streaming; no se admiten incrustaciones.
  • Limita la concurrencia a 8 con una clave completa y reintenta las respuestas 429 después de una breve espera.

Configuración y primera llamada

Este es un servicio independiente compatible con OpenAI, no la API Codex de OpenAI. Su único modelo es de pesos abiertos, solo texto, y maneja el código lo suficientemente bien para tareas de generación, explicación y refactorización que aún debes revisar. Si quieres el contexto primero, la página sobre la API Codex de OpenAI explica cómo se relacionan las dos.

Instala el SDK con pip install openai, crea una clave en la página de clave de API y ejecuta:

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

El crédito de prueba de $0,50 para nuevos usuarios cubre miles de llamadas pequeñas como esta. La temperatura es 0.2 porque el código se beneficia de menos aleatoriedad. Si ves un bloque de código alrededor de la respuesta, elimínalo en el código o pide texto sin formato en el mensaje del sistema. La página de la URL base, URL base de la API Codex, vuelve a listar la dirección exacta.

Prompting para código que se ejecuta

Algunos hábitos mejoran la salida más que cualquier parámetro.

  • Indica el lenguaje y la versión. "Python 3.11, solo biblioteca estándar" elimina muchas suposiciones.
  • Proporciona la firma. Pega la cabecera de la función y una docstring, y pide al modelo que complete el cuerpo.
  • Muestra un ejemplo de entrada y salida. Fija mejor los casos límite que el texto corrido.
  • Pide una sola cosa. Genera la función y luego pide las pruebas en una segunda llamada.
  • Solicita un diff para las ediciones. Las reescrituras de archivo completo consumen tokens de salida, que cuestan más que la entrada.

La ventana de contexto es de 100.000 tokens, y max_tokens es opcional. Para una tarea de código, puedes pegar varios módulos y aún tener espacio para la respuesta. Establecer max_tokens es útil solo como red de seguridad contra una salida descontrolada.

Modo JSON para resultados estructurados

Cuando el código consume la respuesta, usa el modo JSON. Esto hace que la salida sea JSON válido; no impone tu esquema, así que nombra las claves en el prompt y verifícalas.

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

Combina esto con un try/except alrededor de json.loads y un único reintento que envíe el error de análisis de vuelta. En la práctica, eso maneja las raras respuestas malformadas. Usa temperatura 0 para que las ejecuciones repetidas coincidan.

Llamadas a funciones

Con herramientas describes funciones y el modelo decide cuándo llamarlas. Ejecutas la función, luego envías la salida de vuelta con el rol tool. Esta es la base de cada agente de código.

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)

Prueba el código generado como cualquier otra contribución: ejecútalo, lintéalo y mantén un pequeño conjunto de prompts con salidas conocidas como correctas para que notes cuando un cambio en el prompt empeora los resultados. Fija seed y la temperatura mientras comparas versiones.

Notas: mantén las descripciones de herramientas cortas y literales, valida los argumentos antes de ejecutar cualquier cosa y nunca pases la salida del modelo directamente a una shell. Para un bucle, repite la llamada mientras tool_calls esté presente y detente después de un número máximo de pasos. Cada paso reenvía el historial, por lo que una ejecución de diez pasos paga por aproximadamente diez veces el contexto.

Streaming y reintento en 429

Para herramientas interactivas, transmite los tokens a medida que llegan. Los datos de uso se presentan al final del flujo, lo que facilita el registro de costos.

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.")

Los límites detrás de ese bucle de reintento: una clave completa permite 8 peticiones simultáneas y 300 por minuto, y una clave de prueba 2 y 60. Al superar un límite obtienes HTTP 429 con código rate_limited o concurrency. La sobrecarga temporal también da 429 con un encabezado Retry-After: 5. El ejemplo establece max_retries=0 en el cliente para que tu propio bucle controle las esperas. Una petición en streaming mantiene su espacio de concurrencia hasta que termina el flujo, así que siempre consume o cierra el flujo.

Ejecutar muchas peticiones a la vez

Los trabajos por lotes, como generar pruebas para cien funciones, necesitan un límite de concurrencia. Usa un grupo de hilos con un máximo de 8 trabajadores con una clave completa.

Un patrón simple es ThreadPoolExecutor(max_workers=6) alrededor de una función que llama a ask, dejando dos espacios libres para otro trabajo. Con la clave de prueba usa 2 trabajadores. Si pasas un número mayor, la API responderá a las peticiones adicionales con errores concurrency, y tu bucle de reintento pasará tiempo esperando en lugar de trabajar. Para código asíncrono, usa AsyncOpenAI con un asyncio.Semaphore(6) alrededor de cada llamada; esto da el mismo límite sin hilos. Los encabezados de respuesta X-RateLimit-Limit-Requests y X-RateLimit-Limit-Concurrency muestran los límites para tu clave.

Costo de cargas de trabajo de codificación

El precio es $0,15 por 1M de tokens de entrada y $0,50 por 1M de tokens de salida. Digamos que generas pruebas unitarias para 200 funciones. Cada llamada envía 1.500 tokens de entrada y devuelve 700 tokens. Entrada: 200 x 1.500 = 300.000 tokens, o $0,045. Salida: 200 x 700 = 140.000 tokens, o $0,07. Total: $0,115.

Una refactorización de un archivo grande envía 30.000 tokens de entrada y 8.000 de salida: $0,0045 + $0,004 = $0,0085 por ejecución. Las peticiones fallidas o rechazadas no se cobran, y el crédito no caduca. Las recargas comienzan en $20 y se pueden pagar con tarjeta o cripto, con un bono del 5% desde $50, 10% desde $100 y 15% desde $200. Consulta precios y lee la documentación para la lista completa de parámetros.

Preguntas y respuestas

¿Puedo usar el paquete estándar openai de Python?

Sí. Establece base_url en https://api.getcodexapi.com/v1, pasa tu clave y usa el ID de modelo uncensored.

¿Admite llamadas a funciones desde Python?

Sí. Pasa tools y tool_choice, luego devuelve los resultados con el rol tool. También funcionan las tool_calls en streaming.

¿Cómo obtengo una salida estructurada?

Usa response_format con type json_object, nombra las claves en tu prompt y valida el resultado en el código.

¿Hay un cliente asíncrono?

El paquete openai proporciona AsyncOpenAI, que funciona de la misma manera con esta URL base. Mantén la concurrencia en o por debajo de 8 con una clave completa.

Tu clave está a un formulario de distancia

Crea una cuenta, copia la clave, cambia la URL base. Esa es toda la configuración.

Obtener clave de API