~/tools / Rodar um LLM local no seu servidor / Ollama OpenAI Converter

Ollama OpenAI Converter — Converta requisições e respostas de chat entre Ollama /api/chat e /v1/chat/completions

Converte uma requisição de chat entre o /api/chat nativo do Ollama e o seu /v1/chat/completions compatível com a OpenAI, nos dois sentidos, e transforma uma resposta de /api/chat na resposta que /v1/chat/completions retorna. A conversão segue o código-fonte do próprio Ollama, e a ferramenta lista cada campo que é renomeado, descartado ou sem equivalente. Nada sai do seu navegador.

Sentido

Lido como uma requisição compatível com a OpenAI (/v1/chat/completions).

  • O Ollama não lê estes campos e os descarta: tool_choice

curl

Envia ao Ollama em localhost:11434. Mude o endereço se o Ollama rodar em outro lugar.

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"]}}}]}'

Requisição do 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"
          ]
        }
      }
    }
  ]
}

Campos convertidos

DePara
tool_choicenão repassado
stopoptions.stop
max_tokensoptions.num_predict
temperatureoptions.temperature
streamstream(não definido, então vale o padrão do endpoint original)

/api/chat transmite em streaming por padrão e /v1/chat/completions não. A requisição convertida sempre define stream, para que se comporte como a original.

A API compatível com a OpenAI não tem campo para o tamanho do contexto (num_ctx). A documentação do Ollama sugere criar um modelo com PARAMETER num_ctx em um Modelfile e chamá-lo por esse nome.

A conversão segue o Ollama v0.40.14. Nas versões anteriores, o endpoint compatível com a OpenAI definia temperature e top_p como 1.0 quando uma requisição não os enviava, e as chamadas de ferramenta de uma mensagem de assistant com um array content vazio eram anexadas à mensagem anterior.

Conversão a partir do código-fonte do Ollama (v0.40.14, openai/openai.go) e da página de compatibilidade com a OpenAI, verificada com o Ollama 0.40.11 em 2026-11-06. Ollama: compatibilidade com a OpenAI

Tudo é feito no seu navegador. A ferramenta não se conecta a nada.

O Ollama responde a requisições de chat em dois endpoints: o /api/chat nativo e o /v1/chat/completions compatível com a OpenAI. O segundo não executa as requisições por conta própria. No código-fonte do Ollama (openai/openai.go), cada requisição é primeiro convertida em uma requisição de /api/chat, e a resposta é convertida de volta. Esta ferramenta faz a mesma conversão no seu navegador. Cole o corpo de uma requisição ou uma resposta, e ela detecta qual das duas é. Da forma OpenAI para o Ollama: max_tokens vira options.num_predict, uma única string stop vira uma lista, temperature, top_p, seed e as penalidades vão para options, response_format vira format ("json", ou o esquema de json_schema.schema), reasoning_effort vira think (none vira false, minimal vira low, xhigh e ultra viram max), os argumentos das chamadas de ferramenta passam de uma string JSON para um objeto, e uma mensagem de ferramenta recebe o nome da função, buscado a partir do seu tool_call_id. Cada parte de um array content vira uma mensagem própria, e as imagens precisam ser data URLs em base64 de imagens JPEG, PNG ou WebP; URLs de imagem são rejeitadas. Campos que não estão no código do Ollama, como tool_choice, n, user, logit_bias e max_completion_tokens, são descartados sem erro. No nosso teste com o Ollama 0.40.11, uma requisição com max_completion_tokens 3 ainda retornou uma resposta longa, porque o Ollama lê somente max_tokens. No sentido contrário, as opções sem equivalente na OpenAI, como num_ctx, top_k e min_p, são listadas em vez de escritas. Numa resposta, done_reason vira finish_reason (stop vira tool_calls quando o modelo chamou uma ferramenta), prompt_eval_count e eval_count viram usage, thinking vira reasoning, e as durações são descartadas. O Ollama escreve o id como chatcmpl- seguido de um número aleatório; a ferramenta escreve chatcmpl-0. Verificamos a conversão enviando as duas formas de cada requisição ao Ollama 0.40.11 com o campo de depuração _debug_render_only, que retorna o prompt que o modelo veria, e comparando os dois prompts, e comparando as respostas convertidas com as respostas reais de /v1/chat/completions.

A lógica principal desta ferramenta é de código aberto, sob a licença MIT. github.com/seigo5555/toolkitbox-lib/src/ollama-openai.ts

Casos de uso

  • Levar código escrito para o SDK da OpenAI para a API nativa do Ollama, ou o contrário, sem adivinhar os nomes dos campos
  • Descobrir por que um campo que você envia para /v1/chat/completions não tem efeito
  • Ver o que um cliente que espera respostas da OpenAI vai receber do Ollama

Como usar

  1. Cole o corpo de uma requisição de /v1/chat/completions ou /api/chat, ou uma resposta de /api/chat enviada com stream em false.
  2. Deixe o sentido em automático, ou escolha-o se a ferramenta não conseguir distinguir qual forma você colou.
  3. Copie o JSON convertido ou o comando curl, e leia os avisos e a tabela de campos convertidos.

FAQ

Por que a requisição convertida sempre define stream?

/api/chat transmite em streaming por padrão e /v1/chat/completions não. Se a requisição original não definia stream, a convertida recebe o padrão do endpoint original, para que as duas se comportem do mesmo jeito.

Como defino o tamanho do contexto pela API compatível com a OpenAI?

Não há campo para isso. A documentação do Ollama sugere criar um modelo com PARAMETER num_ctx em um Modelfile e chamar a API com o nome desse modelo. A ferramenta lista options.num_ctx como sem equivalente.

Um campo está marcado como não repassado. O Ollama rejeita a requisição?

Não. O Ollama não lê campos que não estão no seu código e os descarta. No nosso teste com o Ollama 0.40.11, uma requisição com tool_choice, n, user, logit_bias e max_completion_tokens foi aceita sem erro, e max_completion_tokens não limitou o tamanho da resposta.

O que mudou no Ollama v0.40.14?

Antes da v0.40.14, o endpoint compatível com a OpenAI definia temperature e top_p como 1.0 quando uma requisição não os enviava. A partir da v0.40.14, valem os padrões do próprio modelo, como em /api/chat. Uma mensagem de assistant com um array content vazio e chamadas de ferramenta também era tratada de outro modo: no nosso teste com a 0.40.11, as chamadas de ferramenta eram anexadas à mensagem anterior. A ferramenta segue a v0.40.14.

Por que não posso colar uma resposta da OpenAI?

O Ollama converte respostas nativas para a forma da OpenAI, nunca o contrário, então não há conversão a copiar. Cole no lugar a resposta de /api/chat.

Meus dados são enviados para algum lugar?

Não. A conversão roda no seu navegador. O comando curl é só texto para você executar.

Artigos relacionados

Relacionados