Aller au contenu
Toute la documentation

Code

SDK OpenAI Agents

Le SDK Agents fonctionne sur nokeep via chat completions. Donnez-lui un AsyncOpenAI avec l’URL de base de nokeep et enveloppez le modèle dans OpenAIChatCompletionsModel.

Vérifié le 29 octobre 2026

Installer et connecter

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)

Le SDK appelle l’API Responses (/v1/responses) sauf indication contraire, et nokeep ne propose que chat completions. Envelopper le modèle dans OpenAIChatCompletionsModel est ce qui le fait fonctionner.

Ou réglez-le une fois pour tous les agents

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

Les agents prennent ensuite l’identifiant du modèle comme simple chaîne. Les transferts entre agents fonctionnent de la même façon.

Outils

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)

Le SDK envoie chaque outil avec strict: true et exécute la boucle : le modèle demande un outil, le SDK l’exécute et renvoie le résultat, jusqu’à ce que le modèle réponde. Voir Appels d’outils.

Flux et consommation

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

Le SDK demande la consommation sur un flux, donc context_wrapper.usage contient les nombres de jetons de toute l’exécution, tous les appels au modèle additionnés.

Effort de raisonnement et autres réglages

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

La réflexion compte dans max_tokens, donc laissez de la place à un agent qui réfléchit. Voir Réflexion.

Pièges

  • `reasoning_effort` n’accepte que les valeurs du modèle. deepseek-v4.1-flash-uncensored accepte none, low, high, max ; glm-5.3-flash-uncensored accepte low, high. Les valeurs minimal, medium et xhigh d’autres applications passent au niveau le plus proche du modèle (medium devient high, xhigh devient max quand le modèle le propose) ; toute autre valeur reçoit 400 invalid_reasoning_effort. Voir Réflexion.
  • GLM choisit lui-même ses outils. glm-5.3-flash-uncensored n’accepte que tool_choice auto ou none. Forcer un outil (required, ou nommer une fonction) reçoit 400 unsupported_tool_choice. Utilisez DeepSeek si vous devez en forcer un. Dans le SDK, cela s’écrit ModelSettings(tool_choice="required"), ou un nom d’outil.
  • Les champs qu’un modèle ne peut pas prendre sont écartés, pas refusés. L’appel répond quand même, et l’en-tête de réponse x-nokeep-ignored nomme ce qui a été laissé de côté. GLM ne garde que tools, tool_choice et reasoning_effort : son temperature et son response_format sont donc écartés. Voir les champs acceptés par chaque modèle.
  • Chat completions uniquement. Il n’y a ni /v1/responses ni /v1/embeddings ; un framework qui utilise l’un des deux par défaut doit être dirigé vers chat completions, et les embeddings demandent un autre fournisseur.

Les outils hébergés, comme la recherche web, la recherche de fichiers et l’interpréteur de code, tournent sur les serveurs d’OpenAI via l’API Responses. Ils ne fonctionnent avec aucune autre API, nokeep compris. Écrivez-les comme des outils de fonction.

Questions

Ai-je aussi besoin d’une clé OpenAI ?

Non. Chaque appel au modèle passe par nokeep avec votre clé nokeep. Le traçage envoie des données au tableau de bord d’OpenAI ; avec le traçage activé et aucune clé OpenAI définie, le SDK affiche OPENAI_API_KEY is not set, skipping trace export et l’agent tourne quand même. set_tracing_disabled(True) garde la sortie silencieuse.

Quel modèle un agent doit-il utiliser ?

deepseek-v4.1-flash-uncensored : il peut être amené à appeler un outil, lit les images et accepte tous les réglages. glm-5.3-flash-uncensored coûte moins cher et convient aux agents qui laissent le modèle choisir ses outils.