Pratique Ollama API : guide de développement client Python et Node.js

Vous tapez ollama run gemma3 dans le terminal, et la première réponse s’affiche. Le modèle local tourne.
La question suivante : peut-on l’intégrer à son propre projet ? Pas de clé API, pas de facturation, tout en local — c’est tentant.
En parcourant la doc, on découvre que l’équipe fournit des SDK Python et JavaScript, et qu’on peut même brancher le SDK OpenAI en changeant deux lignes. Plus simple que prévu.
Mais simple ne veut pas dire sans pièges. Comment accumuler le streaming ? Comment écrire la boucle Agent Loop pour l’appel d’outils ? Comment séparer raisonnement et réponse en mode thinking ? Ce sont des erreurs que j’ai déjà commises.
Cet article comble ces lacunes. Comparaison Python et Node.js, SDK natif et compatibilité OpenAI — un guide client complet.
Si Ollama n’est pas encore installé, commencez par l’intégration de LangChain avec Ollama pour faire tourner un modèle local.
Chapitre 1 : bases de l’API Ollama
Commençons par le fonctionnement de l’API.
Ollama démarre par défaut un service API REST local à l’adresse http://localhost:11434/api. Ouvrez cette URL dans le navigateur : un sobre « Ollama is running » confirme que le service fonctionne.
Principaux endpoints
Deux endpoints clés à retenir :
| Endpoint | Usage | Caractéristiques |
|---|---|---|
/api/chat | Dialogue multi-tours | Accepte un tableau messages, contexte transmissible |
/api/generate | Génération mono-tour | Direct, adapté aux tâches ponctuelles |
Il existe aussi /v1/chat/completions, l’endpoint compatible OpenAI. Si vous avez déjà un projet OpenAI, changez base_url et c’est parti — nous y reviendrons en détail.
Essai avec curl
Testons l’API de la manière la plus brute :
curl http://localhost:11434/api/chat -d '{
"model": "gemma3",
"messages": [
{ "role": "user", "content": "Pourquoi le ciel est-il bleu ?" }
]
}'
Le terminal affiche un flux JSON. Regardez le champ message.content : c’est la réponse du modèle.
Structure de réponse typique :
{
"model": "gemma3",
"created_at": "2026-04-18T01:23:45.678Z",
"message": {
"role": "assistant",
"content": "Le ciel paraît bleu surtout parce que..."
},
"done": true
}
Le champ done est important. En streaming, chaque chunk a done: false ; seul le dernier a done: true. Nous l’utiliserons plus loin.
Réponse en streaming
Par défaut, l’API attend la fin de génération avant de tout renvoyer. Pour un effet « machine à écrire », ajoutez stream: true :
curl http://localhost:11434/api/chat -d '{
"model": "gemma3",
"messages": [{ "role": "user", "content": "Pourquoi le ciel est-il bleu ?" }],
"stream": true
}'
Cette fois, le terminal affiche une ligne JSON par chunk. Il faut les accumuler pour reconstituer la réponse complète.
Gérer ces chunks à la main, c’est fastidieux. D’où l’intérêt des SDK officiels — ils encapsulent ces détails.
Chapitre 2 : SDK Python en pratique
Le SDK Python est maintenu par l’équipe Ollama. Installation simple :
pip install ollama
Compatible Python 3.8+, ce qui est pratique.
Appel de base
L’appel le plus simple tient en quelques lignes :
from ollama import chat
response = chat(
model='gemma3',
messages=[{'role': 'user', 'content': 'Pourquoi le ciel est-il bleu ?'}]
)
print(response.message.content)
chat() est un raccourci du SDK ; en interne, il crée un Client par défaut vers le service Ollama local.
Pour personnaliser la connexion — par exemple Ollama sur une autre machine — créez un Client :
from ollama import Client
client = Client(host='http://192.168.1.100:11434')
response = client.chat(model='gemma3', messages=[...])
Réponse en streaming
Le streaming est central : l’utilisateur voit le texte apparaître progressivement, pas d’un coup après une longue attente.
from ollama import chat
stream = chat(
model='gemma3',
messages=[{'role': 'user', 'content': 'Pourquoi le ciel est-il bleu ?'}],
stream=True,
)
for chunk in stream:
print(chunk['message']['content'], end='', flush=True)
Piège courant : chunk est un dictionnaire, pas un objet. Utilisez chunk['message']['content'], pas chunk.message.content. Je suis tombé dedans au début — l’erreur m’a fait perdre du temps.
Client asynchrone
Pour une architecture async — FastAPI, aiohttp — utilisez le client asynchrone :
import asyncio
from ollama import AsyncClient
async def main():
client = AsyncClient()
# Non-streaming
response = await client.chat(
model='gemma3',
messages=[{'role': 'user', 'content': 'Bonjour'}]
)
print(response.message.content)
# Streaming
stream = await client.chat(
model='gemma3',
messages=[{'role': 'user', 'content': 'Pourquoi le ciel est-il bleu ?'}],
stream=True,
)
async for chunk in stream:
print(chunk['message']['content'], end='', flush=True)
asyncio.run(main())
Le streaming async renvoie un async generator, parcouru avec async for. Même logique que la version synchrone, avec await et async.
Cloud Models
Le SDK Ollama prend aussi en charge les modèles cloud. Certains grands modèles — comme gpt-oss 120B — ne tournent pas en local, mais sont disponibles dans le cloud.
from ollama import chat
response = chat(
model='gpt-oss:120b-cloud',
messages=[{'role': 'user', 'content': 'Bonjour'}]
)
Un nom de modèle avec le suffixe -cloud passe par l’API cloud. Il faut un compte Ollama cloud et une clé API ; la configuration diffère du local — voir la doc officielle.
En pratique, c’est utile : petits modèles en local pour économiser, grands modèles dans le cloud pour éviter le matériel lourd. Un bon compromis.
Chapitre 3 : SDK Node.js en pratique
Le SDK Node.js est tout aussi concis :
npm i ollama
Ce package couvre Node.js et le navigateur. La version navigateur s’importe séparément :
// Node.js
import ollama from 'ollama'
// Navigateur
import ollama from 'ollama/browser'
Appel de base
En Node.js, tout est async par défaut — plus naturel :
import ollama from 'ollama'
const response = await ollama.chat({
model: 'gemma3',
messages: [{ role: 'user', content: 'Pourquoi le ciel est-il bleu ?' }],
})
console.log(response.message.content)
Comparaison avec Python : messages en dictionnaire côté Python, en objet côté Node.js. Les noms de paramètres sont alignés — changer de langage ne change pas les concepts.
Réponse en streaming
Node.js gère le streaming nativement via async generator :
import ollama from 'ollama'
const stream = await ollama.chat({
model: 'gemma3',
messages: [{ role: 'user', content: 'Pourquoi le ciel est-il bleu ?' }],
stream: true,
})
for await (const chunk of stream) {
process.stdout.write(chunk.message.content)
}
Utilisez process.stdout.write plutôt que console.log, car console.log ajoute un saut de ligne — vous ne voulez pas un retour à la ligne à chaque caractère.
Configuration personnalisée
Le SDK accepte host et headers personnalisés :
import ollama from 'ollama'
// Host personnalisé
const client = new ollama.Ollama({ host: 'http://192.168.1.100:11434' })
// Ou configuration globale
ollama.setDefaultHost('http://192.168.1.100:11434')
// Ajouter des headers (ex. authentification)
const stream = await ollama.chat({
model: 'gemma3',
messages: [{ role: 'user', content: 'Bonjour' }],
headers: { Authorization: 'Bearer xxx' },
})
Le paramètre headers est pratique si un proxy d’authentification protège votre instance Ollama.
Annuler une génération en streaming
La méthode abort() interrompt une génération en cours :
import ollama from 'ollama'
const stream = await ollama.chat({
model: 'gemma3',
messages: [{ role: 'user', content: 'Rédige un long article...' }],
stream: true,
})
// L'utilisateur clique sur Arrêter
ollama.abort()
for await (const chunk of stream) {
// La boucle se termine tôt après abort
process.stdout.write(chunk.message.content)
}
Indispensable pour une interface de chat : l’utilisateur peut arrêter la génération à tout moment.
Version navigateur
Usage similaire, avec quelques différences :
import ollama from 'ollama/browser'
// En navigateur, le streaming est obligatoire (CORS sur les grosses réponses JSON)
const stream = await ollama.chat({
model: 'gemma3',
messages: [{ role: 'user', content: 'Bonjour' }],
stream: true,
})
for await (const chunk of stream) {
document.getElementById('output').textContent += chunk.message.content
}
Contrainte navigateur : le mode streaming est obligatoire. Les requêtes non streamées renvoient un gros JSON d’un coup ; les requêtes cross-origin risquent timeout ou blocage. Le streaming envoie des chunks — bien plus fiable.
Logique cohérente : une UI de chat en navigateur a de toute façon besoin d’un affichage progressif.
Chapitre 4 : appel d’outils en pratique
L’appel d’outils est la base des Agents. Ollama permet au modèle d’invoquer vos fonctions, puis de continuer la génération avec le résultat.
Le SDK Python offre un atout : passez directement des fonctions Python comme outils ; le SDK parse docstring et types de paramètres.
Parsing automatique des fonctions Python
def get_weather(city: str) -> str:
"""Obtenir la météo d'une ville
Args:
city: Nom de la ville, ex. Pékin, Shanghai
Returns:
Description météo
"""
# Données simulées
weather_data = {
'Pékin': 'Ensoleillé, 18°C',
'Shanghai': 'Nuageux, 22°C',
'Canton': 'Pluie, 26°C',
}
return weather_data.get(city, f'Données météo introuvables pour {city}')
from ollama import chat
response = chat(
model='qwen3',
messages=[{'role': 'user', 'content': 'Quel temps fait-il à Pékin aujourd\'hui ?'}],
tools=[get_weather],
)
print(response.message.content)
Le SDK convertit la fonction au format outil : nom depuis la fonction, description depuis la docstring, paramètres depuis les annotations. Pas besoin d’écrire le JSON Schema à la main.
Modèle Agent Loop
Ce n’est pas si simple : le modèle peut appeler plusieurs outils, ou enchaîner après un premier appel. Il faut une boucle.
Voici l’Agent Loop :
from ollama import chat
def add(a: int, b: int) -> int:
"""Addition"""
return a + b
def multiply(a: int, b: int) -> int:
"""Multiplication"""
return a * b
tools = [add, multiply]
tool_map = {'add': add, 'multiply': multiply}
messages = [{'role': 'user', 'content': 'Calcule (3 + 5) * 2'}]
while True:
response = chat(model='qwen3', messages=messages, tools=tools)
if response.message.tool_calls:
# Le modèle veut appeler un outil
for call in response.message.tool_calls:
func_name = call.function.name
func_args = call.function.arguments
result = tool_map[func_name](**func_args)
# Ajouter le résultat à l'historique
messages.append({
'role': 'tool',
'content': str(result),
'tool_name': func_name,
})
else:
# Plus d'appel d'outil — terminé
print(response.message.content)
break
La logique :
- Envoyer le message avec les définitions d’outils
- Si le modèle renvoie des
tool_calls, exécuter les fonctions correspondantes - Réinjecter les résultats dans l’historique, rappeler le modèle
- Boucler jusqu’à ce qu’il n’appelle plus d’outils
Ce modèle est incontournable pour un Agent : vous définissez les outils, le modèle décide quand, lesquels et dans quel ordre les appeler.
Mode thinking
Certains modèles — qwen3 par exemple — supportent le mode thinking : le modèle « réfléchit » avant de répondre.
from ollama import chat
stream = chat(
model='qwen3',
messages=[{'role': 'user', 'content': 'Pourquoi le ciel est-il bleu ?'}],
stream=True,
think=True,
)
thinking = ''
content = ''
for chunk in stream:
if chunk.message.thinking:
thinking += chunk.message.thinking
elif chunk.message.content:
content += chunk.message.content
print('=== Raisonnement ===')
print(thinking)
print('=== Réponse finale ===')
print(content)
En mode thinking, chaque chunk contient un champ thinking supplémentaire. Accumulez séparément raisonnement et réponse.
Fonctionnalité intéressante : vous voyez comment le modèle dérive la réponse. Utile pour l’éducation ou le débogage de prompts.
Chapitre 5 : SDK natif vs API compatible OpenAI
Deux options :
- SDK Ollama natif (tout ce qui précède)
- SDK OpenAI, en changeant l’adresse pour pointer vers Ollama
Lequel choisir ? Cela dépend de votre contexte.
Compatibilité OpenAI
Pour un projet OpenAI existant, la migration la moins coûteuse : changer base_url :
from openai import OpenAI
client = OpenAI(
base_url='http://localhost:11434/v1',
api_key='ollama', # Obligatoire mais ignorée
)
response = client.chat.completions.create(
model='gemma3',
messages=[{'role': 'user', 'content': 'Pourquoi le ciel est-il bleu ?'}],
)
print(response.choices[0].message.content)
Le SDK OpenAI ne sait pas qu’Ollama est derrière — il parle à une « API OpenAI ».
Version Node.js identique :
import OpenAI from 'openai'
const client = new OpenAI({
baseURL: 'http://localhost:11434/v1',
apiKey: 'ollama',
})
const completion = await client.chat.completions.create({
model: 'gemma3',
messages: [{ role: 'user', content: 'Pourquoi le ciel est-il bleu ?' }],
})
console.log(completion.choices[0].message.content)
Comparaison des deux approches
| Aspect | SDK natif | Compatible OpenAI |
|---|---|---|
| Installation | pip install ollama | SDK OpenAI déjà installé |
| Appel d’outils | Docstring auto-parsée | JSON Schema manuel |
| Streaming | Chunks en dictionnaire | Format OpenAI standard |
| Cloud Models | Supporté | Non supporté |
| Coût de migration | Nul pour un nouveau projet | Minimal pour un projet existant |
Recommandations
Nouveau projet : SDK natif.
Raisons :
- Appel d’outils plus simple — passez directement des fonctions Python
- Plus de fonctionnalités (Cloud Models, mode thinking)
- Doc et exemples officiels, dépannage plus facile
Migration d’un projet OpenAI existant : compatibilité OpenAI.
Raisons :
- Deux lignes de code suffisent
- Pas de réécriture de logique
- Retour à OpenAI simple par la suite
En résumé : SDK natif pour plus de fonctionnalités, compatibilité OpenAI pour migrer plus vite. À vous de voir.
J’ai testé les deux. L’appel d’outils natif fait gagner du temps — pas de JSON Schema à écrire, une docstring claire suffit. Mais si le projet tourne déjà sur OpenAI, inutile de tout refactoriser pour Ollama.
Conclusion
Quelques points clés :
Appel de base : les SDK Python et Node.js sont bien conçus ; quelques lignes suffisent. Pensez à stream=True pour le streaming.
Appel d’outils : Agent Loop est le modèle central — boucler sur les tool_calls jusqu’à ce que le modèle s’arrête. Le SDK Python accepte des fonctions directement, sans JSON Schema.
Mode thinking : qwen3 et d’autres modèles le supportent ; vous voyez le raisonnement du modèle. Traitez séparément les champs thinking et content dans chaque chunk.
Choix d’approche : nouveau projet → SDK natif ; projet OpenAI existant → changez l’adresse.
Prochaines étapes :
- Si Ollama n’est pas installé, commencez par le premier article de la série pour faire tourner un modèle local
- Choisissez l’approche adaptée (native ou compatible OpenAI) et testez
- La doc officielle évolue — de nouvelles fonctionnalités arrivent régulièrement
Faire tourner un LLM en local devient de plus en plus accessible. Ollama cache la complexité derrière une API simple. Il suffit de savoir l’appeler — le reste, c’est son travail.
Voici le deuxième article de cette série. Le prochain portera sur la personnalisation via Modelfile — comment adapter un modèle à vos besoins.
Développement client Ollama API
Guide complet pour appeler l'API de modèles locaux Ollama avec les SDK Python ou Node.js
⏱️ Estimated time: 45 min
- 1
Step 1: Installer le SDK et tester un appel de base
Côté Python : `pip install ollama`. Côté Node.js : `npm i ollama`.
Après l'installation, testez la connexion avec le code le plus simple :
```python
from ollama import chat
response = chat(model='gemma3', messages=[{'role': 'user', 'content': 'Bonjour'}])
print(response.message.content)
```
Assurez-vous que le service Ollama est démarré (port 11434 par défaut) et que le modèle correspondant est téléchargé. - 2
Step 2: Implémenter la réponse en streaming
Activez le mode streaming pour afficher la sortie caractère par caractère :
```python
from ollama import chat
stream = chat(model='gemma3', messages=[...], stream=True)
for chunk in stream:
print(chunk['message']['content'], end='', flush=True)
```
Attention : chunk est un dictionnaire ; accédez au contenu via `chunk['message']['content']`. - 3
Step 3: Configurer l'appel d'outils (optionnel)
Définissez des fonctions Python comme outils ; le SDK analyse automatiquement docstring et annotations de type :
```python
def get_weather(city: str) -> str:
"""Obtenir la météo d'une ville"""
return f'{city}: Ensoleillé'
response = chat(model='qwen3', messages=[...], tools=[get_weather])
```
Implémentez une boucle Agent Loop pour gérer plusieurs appels d'outils jusqu'à la réponse finale. - 4
Step 4: Choisir entre SDK natif et compatibilité OpenAI
Pour un nouveau projet, le SDK natif est recommandé (Cloud Models, mode thinking, etc.).
Pour un projet OpenAI existant, deux lignes suffisent :
```python
client = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')
```
Coût de migration minimal ; retour à OpenAI possible à tout moment.
FAQ
Quel est le port et l'adresse par défaut de l'API Ollama ?
Quel type renvoie le streaming du SDK Python ?
Quelles limitations du SDK Node.js en environnement navigateur ?
Qu'est-ce que le modèle Agent Loop ?
Comment séparer raisonnement et réponse finale en mode thinking ?
Comment choisir entre SDK natif et compatibilité OpenAI ?
11 min de lecture · Publié le: 18 avr. 2026 · Mis à jour le: 30 juil. 2026
Guide Ollama LLM local
Si vous arrivez depuis la recherche, le plus rapide est de passer à l’article précédent ou suivant de cette série.
Précédent
Appels API Ollama : de curl à l'interface compatible OpenAI SDK
Apprenez les deux façons d'appeler l'API Ollama : l'API REST native (curl) et l'interface compatible OpenAI SDK. Exemples de code complets, gestion du streaming et bonnes pratiques.
Partie 12 sur 18
Suivant
Intégration LangChain + Ollama : guide complet pour développer des applications LLM en local
Méthode complète d'intégration LangChain et Ollama avec exemples de code pour Chat, RAG et Agent, stratégies de bascule OpenAI/Ollama, pour construire des applications LLM de niveau entreprise avec des modèles locaux.
Partie 14 sur 18



Commentaires
Connectez-vous avec GitHub pour laisser un commentaire