Ir al contenido
Toda la documentación

Código

OpenAI Agents SDK

El Agents SDK funciona con nokeep a través de chat completions. Dale un cliente AsyncOpenAI con la URL base de nokeep y envuelve el modelo en OpenAIChatCompletionsModel.

Revisado el 29 de octubre de 2026

Instalar y conectar

Shell
pip install openai-agents
export NOKEEP_API_KEY="sk-nokeep-test"  # your own key once it connects
agent.py
import os
from openai import AsyncOpenAI
from agents import Agent, OpenAIChatCompletionsModel, set_tracing_disabled

client = AsyncOpenAI(
    base_url="https://nokeep.ai/v1",
    api_key=os.environ["NOKEEP_API_KEY"],
)
set_tracing_disabled(True)  # traces go to OpenAI's dashboard, which a nokeep key can't reach

model = OpenAIChatCompletionsModel(model="deepseek-v4.1-flash-uncensored", openai_client=client)

from agents import Runner

agent = Agent(name="Editor", instructions="You are a blunt editor.", model=model)
result = Runner.run_sync(agent, "Cut this opening line to ten words: ...")
print(result.final_output)

El SDK llama a la Responses API (/v1/responses) salvo que se le indique otra cosa, y nokeep solo tiene chat completions. Envolver el modelo en OpenAIChatCompletionsModel es lo que hace que funcione.

O configúralo una vez para todos los agentes

Python
import os
from openai import AsyncOpenAI
from agents import Agent, set_default_openai_api, set_default_openai_client, set_tracing_disabled

set_default_openai_client(AsyncOpenAI(base_url="https://nokeep.ai/v1", api_key=os.environ["NOKEEP_API_KEY"]), use_for_tracing=False)
set_default_openai_api("chat_completions")
set_tracing_disabled(True)

agent = Agent(name="Editor", instructions="You are a blunt editor.", model="deepseek-v4.1-flash-uncensored")

Luego los agentes reciben el id del modelo como cadena simple. Los traspasos entre agentes funcionan igual.

Herramientas

Python
from agents import Agent, Runner, function_tool

@function_tool
def get_weather(city: str) -> str:
    """Get the weather in a city."""
    return f"18°C and clear in {city}"

agent = Agent(
    name="Weather",
    instructions="Answer questions about the weather.",
    model=model,
    tools=[get_weather],
)
print(Runner.run_sync(agent, "What's the weather in Lisbon?").final_output)

El SDK envía cada herramienta con strict: true y ejecuta el bucle: el modelo pide una herramienta, el SDK la ejecuta y devuelve el resultado hasta que el modelo responde. Consulta Llamadas a herramientas.

Streaming y uso

Python
import asyncio
from agents import Runner
from openai.types.responses import ResponseTextDeltaEvent

async def main():
    result = Runner.run_streamed(agent, "Tell me a story in three lines.")
    async for event in result.stream_events():
        if event.type == "raw_response_event" and isinstance(event.data, ResponseTextDeltaEvent):
            print(event.data.delta, end="", flush=True)
    print("\n", result.context_wrapper.usage)

asyncio.run(main())

El SDK pide el uso en un streaming, así que context_wrapper.usage contiene los conteos de tokens de toda la ejecución, con todas las llamadas al modelo sumadas.

Esfuerzo de razonamiento y otros ajustes

Python
from agents import Agent, ModelSettings
from openai.types.shared import Reasoning

planner = Agent(
    name="Planner",
    instructions="Plan before you answer.",
    model=model,
    model_settings=ModelSettings(
        reasoning=Reasoning(effort="high"),  # sent as reasoning_effort
        max_tokens=4000,
        extra_body={"min_p": 0.05},  # fields ModelSettings has no argument for
    ),
)

El razonamiento cuenta dentro de max_tokens, así que dale espacio a un agente que razona. Consulta Razonamiento.

Advertencias

  • `reasoning_effort` solo acepta los valores propios del modelo. deepseek-v4.1-flash-uncensored acepta none, low, high, max; glm-5.3-flash-uncensored acepta low, high. Los valores minimal, medium y xhigh de otras apps se ejecutan en el nivel más cercano del modelo (medium como high, xhigh como max donde el modelo lo tenga); cualquier otro valor recibe 400 invalid_reasoning_effort. Consulta Razonamiento.
  • GLM elige sus propias herramientas. glm-5.3-flash-uncensored acepta solo tool_choice auto o none. Forzar una herramienta (required o dar el nombre de una función) recibe 400 unsupported_tool_choice. Usa DeepSeek si necesitas forzar una. En el SDK eso es ModelSettings(tool_choice="required"), o un nombre de herramienta.
  • Los campos que un modelo no acepta se descartan, no se rechazan. La llamada responde igual, y el encabezado de respuesta x-nokeep-ignored indica qué se dejó fuera. GLM solo conserva tools, tool_choice y reasoning_effort, así que sus temperature y response_format se descartan. Consulta qué campos acepta cada modelo.
  • Solo chat completions. No existe /v1/responses ni /v1/embeddings; un framework que use cualquiera de los dos debe apuntar a chat completions, y los embeddings necesitan otro proveedor.

Las herramientas alojadas, como la búsqueda web, la búsqueda de archivos y el intérprete de código, se ejecutan en los servidores de OpenAI a través de la Responses API. No funcionan con ninguna otra API, nokeep incluida. Escríbelas como herramientas de función.

Preguntas

¿También necesito una clave de OpenAI?

No. Cada llamada al modelo va a nokeep con tu clave de nokeep. El rastreo se sube al panel de OpenAI; con el rastreo activado y sin clave de OpenAI, el SDK muestra OPENAI_API_KEY is not set, skipping trace export y el agente se ejecuta igual. set_tracing_disabled(True) lo mantiene en silencio.

¿Qué modelo debe usar un agente?

deepseek-v4.1-flash-uncensored: se le puede pedir que llame a una herramienta, lee imágenes y acepta todos los ajustes. glm-5.3-flash-uncensored cuesta menos y funciona para agentes que dejan que el modelo elija sus herramientas.