~/tools / Faire tourner un LLM local sur votre serveur / Ollama OpenAI Converter

Ollama OpenAI Converter — Convertit les requêtes et réponses de chat entre Ollama /api/chat et /v1/chat/completions

Convertit une requête de chat entre le /api/chat natif d'Ollama et son /v1/chat/completions compatible OpenAI, dans les deux sens, et transforme une réponse de /api/chat en la réponse que renvoie /v1/chat/completions. La conversion suit le code source d'Ollama, et l'outil liste chaque champ qui est renommé, abandonné ou sans équivalent. Rien ne quitte votre navigateur.

Sens

Lu comme une requête compatible OpenAI (/v1/chat/completions).

  • Ollama ne lit pas ces champs et les abandonne : tool_choice

curl

Envoie à Ollama sur localhost:11434. Changez l'adresse si Ollama tourne ailleurs.

curl http://localhost:11434/api/chat -d '{"model":"qwen2.5:7b","messages":[{"role":"system","content":"Answer in one sentence."},{"role":"user","content":"What is the weather in Toronto?"},{"role":"assistant","content":"","tool_calls":[{"id":"call_1","function":{"name":"get_weather","arguments":{"city":"Toronto"}}}]},{"role":"tool","content":"11 degrees, cloudy","tool_name":"get_weather","tool_call_id":"call_1"}],"stream":false,"options":{"stop":["END"],"num_predict":200,"temperature":0.2},"tools":[{"type":"function","function":{"name":"get_weather","description":"Weather for a city","parameters":{"type":"object","properties":{"city":{"type":"string"}},"required":["city"]}}}]}'

Requête Ollama /api/chat

{
  "model": "qwen2.5:7b",
  "messages": [
    {
      "role": "system",
      "content": "Answer in one sentence."
    },
    {
      "role": "user",
      "content": "What is the weather in Toronto?"
    },
    {
      "role": "assistant",
      "content": "",
      "tool_calls": [
        {
          "id": "call_1",
          "function": {
            "name": "get_weather",
            "arguments": {
              "city": "Toronto"
            }
          }
        }
      ]
    },
    {
      "role": "tool",
      "content": "11 degrees, cloudy",
      "tool_name": "get_weather",
      "tool_call_id": "call_1"
    }
  ],
  "stream": false,
  "options": {
    "stop": [
      "END"
    ],
    "num_predict": 200,
    "temperature": 0.2
  },
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Weather for a city",
        "parameters": {
          "type": "object",
          "properties": {
            "city": {
              "type": "string"
            }
          },
          "required": [
            "city"
          ]
        }
      }
    }
  ]
}

Champs convertis

DeVers
tool_choicenon repris
stopoptions.stop
max_tokensoptions.num_predict
temperatureoptions.temperature
streamstream(non défini, donc la valeur par défaut de l'endpoint d'origine)

/api/chat diffuse en streaming par défaut et /v1/chat/completions non. La requête convertie définit toujours stream, afin de se comporter comme l'originale.

L'API compatible OpenAI n'a aucun champ pour la longueur du contexte (num_ctx). La documentation d'Ollama suggère de créer un modèle avec PARAMETER num_ctx dans un Modelfile et de l'appeler par ce nom.

La conversion suit Ollama v0.40.14. Dans les versions antérieures, l'endpoint compatible OpenAI fixait temperature et top_p à 1.0 lorsqu'une requête ne les envoyait pas, et les appels d'outil d'un message assistant avec un tableau content vide étaient rattachés au message précédent.

Conversion d'après le code source d'Ollama (v0.40.14, openai/openai.go) et la page de compatibilité OpenAI, vérifiée avec Ollama 0.40.11 le 2026-11-06. Ollama : compatibilité OpenAI

Tout se passe dans votre navigateur. L'outil ne se connecte à rien.

Ollama répond aux requêtes de chat sur deux endpoints : le /api/chat natif et le /v1/chat/completions compatible OpenAI. Le second n'exécute pas les requêtes lui-même. Dans le code source d'Ollama (openai/openai.go), chaque requête est d'abord convertie en requête /api/chat, puis la réponse est reconvertie. Cet outil fait la même conversion dans votre navigateur. Collez le corps d'une requête ou une réponse, et il détecte de laquelle il s'agit. De la forme OpenAI vers Ollama : max_tokens devient options.num_predict, une seule chaîne stop devient une liste, temperature, top_p, seed et les pénalités passent dans options, response_format devient format ("json", ou le schéma de json_schema.schema), reasoning_effort devient think (none devient false, minimal devient low, xhigh et ultra deviennent max), les arguments des appels d'outil passent d'une chaîne JSON à un objet, et un message d'outil reçoit le nom de la fonction retrouvé à partir de son tool_call_id. Chaque partie d'un tableau content devient un message distinct, et les images doivent être des data URL en base64 d'images JPEG, PNG ou WebP ; les URL d'image sont refusées. Les champs qui ne figurent pas dans le code d'Ollama, comme tool_choice, n, user, logit_bias et max_completion_tokens, sont abandonnés sans erreur. Dans notre test sur Ollama 0.40.11, une requête avec max_completion_tokens 3 a quand même renvoyé une longue réponse, car Ollama ne lit que max_tokens. Dans l'autre sens, les options sans équivalent chez OpenAI, comme num_ctx, top_k et min_p, sont listées au lieu d'être écrites. Pour une réponse, done_reason devient finish_reason (stop devient tool_calls lorsque le modèle a appelé un outil), prompt_eval_count et eval_count deviennent usage, thinking devient reasoning, et les durées sont abandonnées. Ollama écrit l'id sous la forme chatcmpl- suivi d'un nombre aléatoire ; l'outil écrit chatcmpl-0. Nous avons vérifié la conversion en envoyant les deux formes de chaque requête à Ollama 0.40.11 avec le champ de débogage _debug_render_only, qui renvoie le prompt que verrait le modèle, et en comparant les deux prompts, ainsi qu'en comparant les réponses converties avec les vraies réponses de /v1/chat/completions.

Le cœur de cet outil est open source, sous licence MIT. github.com/seigo5555/toolkitbox-lib/src/ollama-openai.ts

Cas d'usage

  • Passer du code écrit pour le SDK OpenAI à l'API native d'Ollama, ou l'inverse, sans deviner les noms de champs
  • Comprendre pourquoi un champ envoyé à /v1/chat/completions n'a aucun effet
  • Voir ce qu'un client qui attend des réponses OpenAI recevra d'Ollama

Utilisation

  1. Collez le corps d'une requête /v1/chat/completions ou /api/chat, ou une réponse /api/chat envoyée avec stream à false.
  2. Laissez le sens sur automatique, ou choisissez-le si l'outil ne peut pas distinguer la forme collée.
  3. Copiez le JSON converti ou la commande curl, et lisez les avertissements et le tableau des champs convertis.

FAQ

Pourquoi la requête convertie définit-elle toujours stream ?

/api/chat diffuse en streaming par défaut et /v1/chat/completions non. Si la requête d'origine ne définissait pas stream, la requête convertie reçoit la valeur par défaut de l'endpoint d'origine, afin que les deux se comportent de la même façon.

Comment définir la longueur du contexte via l'API compatible OpenAI ?

Il n'existe aucun champ pour cela. La documentation d'Ollama suggère de créer un modèle avec PARAMETER num_ctx dans un Modelfile et d'appeler l'API avec le nom de ce modèle. L'outil indique options.num_ctx comme sans équivalent.

Un champ est marqué comme non repris. Ollama rejette-t-il la requête ?

Non. Ollama ne lit pas les champs qui ne figurent pas dans son code et les abandonne. Dans notre test sur Ollama 0.40.11, une requête avec tool_choice, n, user, logit_bias et max_completion_tokens a été acceptée sans erreur, et max_completion_tokens n'a pas limité la longueur de la réponse.

Qu'est-ce qui a changé dans Ollama v0.40.14 ?

Avant v0.40.14, l'endpoint compatible OpenAI fixait temperature et top_p à 1.0 lorsqu'une requête ne les envoyait pas. Depuis v0.40.14, ce sont les valeurs par défaut du modèle qui s'appliquent, comme avec /api/chat. Un message assistant avec un tableau content vide et des appels d'outil était aussi traité différemment : dans notre test sur 0.40.11, ses appels d'outil étaient rattachés au message précédent. L'outil suit v0.40.14.

Pourquoi ne puis-je pas coller une réponse OpenAI ?

Ollama convertit les réponses natives vers la forme OpenAI, jamais l'inverse, il n'y a donc aucune conversion à reproduire. Collez plutôt la réponse de /api/chat.

Mes données sont-elles envoyées quelque part ?

Non. La conversion s'exécute dans votre navigateur. La commande curl n'est que du texte que vous exécutez vous-même.

Articles liés

Voir aussi