Aller au contenu
Développement high

Ollama avancé : SDK Python, Structured Output et embeddings

35 min de lecture

logo ollama

Vous savez déjà utiliser Ollama en ligne de commande et en Python. Mais saviez-vous qu'Ollama dispose d'un SDK Python natif avec des fonctionnalités exclusives ? Ce guide vous montre comment exploiter les Structured Outputs (sorties JSON typées), les embeddings pour la recherche sémantique, et comment construire un assistant DevOps complet en local.

  • SDK natif vs LiteLLM : quand utiliser chaque approche
  • Streaming : afficher les réponses en temps réel
  • Structured Output : obtenir du JSON typé avec Pydantic
  • Embeddings : générer des vecteurs pour la recherche sémantique
  • Conversation multi-turn : maintenir le contexte entre les échanges
  • TP fil rouge : construire DevOps Buddy, un assistant DevOps local

Avant de commencer, assurez-vous d'avoir :

  1. Ollama installé (guide d'installation)
  2. Un modèle téléchargé :
Fenêtre de terminal
ollama pull llama3.2:3b
  1. Le SDK Python, avec des versions figées pour que les exemples se comportent à l'identique chez vous :
Fenêtre de terminal
pip install ollama==0.6.2 pydantic==2.12.3

Vérifiez les versions :

Fenêtre de terminal
ollama --version # 0.16.x ou supérieur
pip show ollama # 0.6.x ou supérieur

Les deux bibliothèques parlent au même serveur Ollama, la question n'est donc pas laquelle « marche » mais laquelle vous enferme. Le SDK natif expose l'API d'Ollama telle quelle, y compris les paramètres qui n'ont pas d'équivalent chez les autres fournisseurs. LiteLLM normalise les appels sur le format OpenAI, ce qui rend le code portable au prix du plus petit dénominateur commun. Dans le tableau ci-dessous, la ligne décisive est Structured Output : le SDK natif contraint la génération avec un schéma JSON côté serveur, là où LiteLLM passe par le mécanisme d'appel de fonctions, moins strict.

AspectSDK ollamaLiteLLM
Installationpip install ollamapip install litellm
ScopeOllama uniquement100+ providers (OpenAI, Anthropic...)
Structured Output✅ Natif avec format=Via function calling
Embeddingsembed() intégréembedding()
Pensée (Thinking)think=True
Cas d'usageScripts dédiés OllamaCode portable multi-providers

Recommandation : Utilisez le SDK natif si vous ciblez uniquement Ollama et voulez exploiter ses fonctionnalités spécifiques. Utilisez LiteLLM si vous voulez pouvoir basculer vers d'autres providers.

Tout au long de ce guide, nous construisons DevOps Buddy, un assistant DevOps local qui :

  • Répond aux questions DevOps en streaming
  • Utilise une base de connaissances avec embeddings (mini-RAG)
  • Retourne des commandes structurées avec Pydantic

Créez le répertoire de travail :

Fenêtre de terminal
mkdir -p ~/lab-ollama && cd ~/lab-ollama
python3 -m venv .venv && source .venv/bin/activate
pip install ollama==0.6.2 pydantic==2.12.3

La fonction chat() du SDK est l'équivalent de litellm.completion(), mais avec une API légèrement différente.

Ce premier script sert surtout à découvrir la forme de l'objet de réponse. Regardez la partie « Métadonnées » plutôt que le texte généré : prompt_eval_count et eval_count comptent les tokens en entrée et en sortie, total_duration s'exprime en nanosecondes, d'où la division par 1e9. Ces trois valeurs sont votre seul moyen de mesurer le coût réel d'un appel local, puisqu'aucune facturation ne vient vous le rappeler.

01_chat_basique.py
#!/usr/bin/env python3
"""
TP 01 : Appel basique avec le SDK Ollama natif
Objectif : Comprendre la différence avec litellm
"""
from ollama import chat
# Appel simple avec le SDK natif
response = chat(
model='llama3.2:3b',
messages=[
{'role': 'user', 'content': 'Explique Docker en une phrase pour un débutant.'}
]
)
print("=== Réponse du modèle ===")
print(response.message.content)
print("\n=== Métadonnées ===")
print(f"Modèle utilisé : {response.model}")
print(f"Tokens prompt : {response.prompt_eval_count}")
print(f"Tokens réponse : {response.eval_count}")
print(f"Durée totale : {response.total_duration / 1e9:.2f}s")

Exécutez le script :

Fenêtre de terminal
python 01_chat_basique.py

Sortie attendue :

=== Réponse du modèle ===
Docker est une technologie qui permet de créer des conteneurs virtuels, qui sont
des environnements isolés et sécurisés où les applications peuvent être exécutées
sans nécessiter d'installations supplémentaires sur l'hôte.
=== Métadonnées ===
Modèle utilisé : llama3.2:3b
Tokens prompt : 36
Tokens réponse : 54
Durée totale : 5.88s

Le streaming affiche la réponse mot par mot au fur et à mesure de la génération. C'est essentiel pour une bonne expérience utilisateur.

Avec stream=True, chat() ne renvoie plus un objet mais un générateur : la boucle for consomme les fragments au rythme de la génération. Deux conséquences pratiques. Les métadonnées de fin (eval_count, total_duration) n'arrivent que dans le dernier fragment, pas au début. Et si vous avez besoin du texte complet ensuite, il faut le concaténer vous-même pendant la boucle, comme le fait DevOps Buddy plus bas.

02_streaming.py
#!/usr/bin/env python3
"""
TP 02 : Streaming avec le SDK Ollama
Objectif : Afficher la réponse en temps réel, mot par mot
"""
from ollama import chat
# Streaming : la réponse arrive progressivement
print("=== Réponse en streaming ===")
stream = chat(
model='llama3.2:3b',
messages=[
{'role': 'user', 'content': 'Donne 5 bonnes pratiques Dockerfile, très bref.'}
],
stream=True # Active le streaming
)
# Afficher chaque chunk au fur et à mesure
for chunk in stream:
print(chunk.message.content, end='', flush=True)
print("\n\n=== Fin du streaming ===")

Le paramètre flush=True force l'affichage immédiat de chaque caractère.

C'est la fonctionnalité la plus puissante du SDK Ollama. Au lieu d'obtenir du texte libre, vous obtenez du JSON typé qui correspond exactement à un schéma Pydantic.

Sans schéma, un modèle à qui l'on demande « réponds en JSON » produit un JSON valide la plupart du temps, et du texte accompagné de trois backticks le reste du temps. Ce taux d'échec résiduel suffit à casser un script en production. Avec format=, Ollama contraint le décodage token par token : la sortie ne peut pas dévier du schéma. Les quatre bénéfices ci-dessous découlent tous de cette garantie côté serveur, pas d'une consigne dans le prompt.

  • Parsing fiable : plus besoin de regex ou de parsing manuel
  • Validation automatique : Pydantic vérifie que la réponse est conforme
  • Typage : votre IDE connaît les types des champs
  • Intégration : les données sont directement utilisables dans votre code

Deux appels font tout le travail, et il ne faut pas les confondre. DockerCommand.model_json_schema() convertit la classe Pydantic en schéma JSON transmis au serveur, qui s'en sert pour brider la génération. DockerCommand.model_validate_json() relit la réponse et instancie l'objet Python. Le schéma contraint la forme, pas le contenu : le champ level sera bien une chaîne, mais rien n'empêche le modèle d'y écrire intermédiaire au lieu des trois valeurs attendues. Pour verrouiller aussi les valeurs, déclarez un Literal["debutant", "intermediaire", "avance"] plutôt qu'un str.

03_structured_output.py
#!/usr/bin/env python3
"""
TP 03 : Structured Output avec Pydantic
Objectif : Obtenir des réponses JSON typées et validées automatiquement
Feature : Disponible depuis Ollama 0.5.0+
"""
from ollama import chat
from pydantic import BaseModel
# Définir le schéma de sortie avec Pydantic
class DockerCommand(BaseModel):
"""Une commande Docker expliquée"""
command: str # La commande complète
description: str # Explication en une phrase
example: str # Un exemple concret
level: str # "debutant", "intermediaire", "avance"
# Appeler le modèle avec le schéma
response = chat(
model='llama3.2:3b',
messages=[
{
'role': 'user',
'content': 'Explique la commande docker build'
}
],
format=DockerCommand.model_json_schema() # Forcer le format JSON
)
# Valider et parser la réponse avec Pydantic
result = DockerCommand.model_validate_json(response.message.content)
# Afficher le résultat structuré
print("=== Sortie structurée (Pydantic) ===")
print(f"Commande : {result.command}")
print(f"Description : {result.description}")
print(f"Exemple : {result.example}")
print(f"Niveau : {result.level}")
print("\n=== JSON brut ===")
print(response.message.content)

Sortie attendue :

=== Sortie structurée (Pydantic) ===
Commande : docker build
Description : Crée une image Docker à partir d'un fichier Dockerfile.
Exemple : docker build -t mon-image .
Niveau : debutant
=== JSON brut ===
{"command": "docker build", "description": "Crée une image Docker...", ...}

Un schéma Pydantic peut contenir d'autres schémas : Tutorial référence une liste de Step, et Pydantic génère un schéma JSON imbriqué qu'Ollama sait respecter. Deux options méritent attention dans l'appel. temperature: 0 rend la sortie déterministe, ce qui compte quand on extrait des données plutôt qu'on ne rédige. num_predict: 500 plafonne le nombre de tokens générés : une structure imbriquée coupée en plein milieu produit un JSON invalide et fait échouer la validation, c'est la panne la plus fréquente sur ce type de schéma.

04_structured_avance.py
#!/usr/bin/env python3
"""
TP 04 : Structured Output avancé (listes et objets imbriqués)
Objectif : Extraire plusieurs éléments structurés en une seule requête
"""
from ollama import chat
from pydantic import BaseModel
class Step(BaseModel):
"""Une étape d'un processus"""
number: int
action: str
command: str
class Tutorial(BaseModel):
"""Un tutoriel complet"""
title: str
steps: list[Step]
total_time: str
print("🔧 Définition du schéma Pydantic...")
print("\n📤 Envoi de la requête à Ollama (llama3.2:3b)...")
# Demander un tutoriel structuré
response = chat(
model='llama3.2:3b',
messages=[
{
'role': 'user',
'content': 'Donne un tutoriel Docker en 2 étapes avec titre, steps (number, action, command) et total_time'
}
],
format=Tutorial.model_json_schema(),
options={'temperature': 0, 'num_predict': 500}
)
print("✅ Réponse reçue!")
print(f" Durée: {response.total_duration / 1e9:.2f}s")
# Parser la réponse
tutorial = Tutorial.model_validate_json(response.message.content)
# Afficher le tutoriel formaté
print(f"\n📚 {tutorial.title}")
print(f"⏱️ {tutorial.total_time}")
for step in tutorial.steps:
print(f" {step.number}. {step.action}{step.command}")

Sortie attendue :

📚 Tutoriel Docker en 2 étapes
⏱️ > 30 minutes
1. Créer un nouveau projet Docker → docker run -it ubuntu /bin/bash
2. Créer une image personnalisée → docker build -t mon-image .

Pour maintenir le contexte entre plusieurs échanges, vous devez gérer l'historique des messages.

Le serveur Ollama ne mémorise rien entre deux appels : la mémoire de la conversation, c'est votre liste messages. À chaque tour, vous renvoyez tout l'historique, question et réponse comprises. Cela a un coût qui grandit linéairement, visible dans prompt_eval_count qui augmente à chaque échange jusqu'à saturer la fenêtre de contexte du modèle. Sur un assistant destiné à durer, il faut donc prévoir une troncature de l'historique ou un résumé des tours anciens ; le script ci-dessous, limité à quatre échanges, n'en a pas besoin.

05_conversation.py
#!/usr/bin/env python3
"""
TP 05 : Conversation multi-turn avec historique
Objectif : Maintenir le contexte entre plusieurs échanges
"""
from ollama import chat
# Historique de la conversation
messages = []
# Contexte système
system_message = {
'role': 'system',
'content': '''Tu es DevOps Buddy, un assistant spécialisé DevOps.
Tu réponds de manière concise et technique.
Tu donnes des exemples de commandes quand c'est pertinent.'''
}
messages.append(system_message)
print("🤖 DevOps Buddy initialisé")
print("=" * 50)
def ask(question: str) -> str:
"""Pose une question et met à jour l'historique"""
print(f"\n👤 {question}")
# Ajouter la question à l'historique
messages.append({'role': 'user', 'content': question})
# Appeler le modèle avec tout l'historique
response = chat(
model='llama3.2:3b',
messages=messages,
options={'temperature': 0.3}
)
# Ajouter la réponse à l'historique
assistant_message = response.message.content
messages.append({'role': 'assistant', 'content': assistant_message})
print(f"🤖 {assistant_message}")
return assistant_message
# Simulation d'une conversation
ask("C'est quoi un Pod Kubernetes en une phrase ?")
ask("Et un Deployment, c'est quoi par rapport à un Pod ?")
ask("Donne-moi la commande pour créer un Deployment avec 3 réplicas")
ask("Comment je scale à 5 réplicas maintenant ?")
print("\n" + "=" * 50)
print(f"📊 Total messages dans l'historique : {len(messages)}")

Le modèle se souvient du contexte : la 4e question "Comment je scale à 5 réplicas" fait référence au Deployment mentionné précédemment.

Les embeddings transforment du texte en vecteurs numériques. Deux textes similaires auront des vecteurs proches. C'est la base du RAG.

La fonction embed() renvoie toujours une liste de vecteurs, même pour une seule chaîne en entrée, d'où le response.embeddings[0] répété dans le script. La similarité cosinus mesure l'angle entre deux vecteurs et non leur distance : elle vaut 1 pour deux textes de sens identique et tend vers 0 pour deux textes sans rapport. Ne comparez jamais un score dans l'absolu, seul le classement relatif entre documents a un sens, et ce classement dépend entièrement du modèle utilisé.

06_embeddings.py
#!/usr/bin/env python3
"""
TP 06 : Embeddings avec Ollama
Objectif : Générer des vecteurs pour la recherche sémantique
Feature : Disponible depuis Ollama 0.3+
"""
from ollama import embed
import math
def cosine_similarity(vec1: list[float], vec2: list[float]) -> float:
"""Calcule la similarité cosinus entre deux vecteurs"""
dot_product = sum(a * b for a, b in zip(vec1, vec2))
norm1 = math.sqrt(sum(a ** 2 for a in vec1))
norm2 = math.sqrt(sum(b ** 2 for b in vec2))
return dot_product / (norm1 * norm2)
# Base de connaissances DevOps
documents = [
"Docker est une plateforme de conteneurisation qui permet de packager des applications",
"Kubernetes orchestre les conteneurs à grande échelle dans un cluster",
"Ansible automatise la configuration des serveurs et le déploiement",
"Terraform gère l'infrastructure as code pour le cloud",
"GitLab CI/CD permet l'intégration et le déploiement continus"
]
print("📦 Génération des embeddings pour 5 documents...")
# Générer les embeddings pour chaque document
doc_embeddings = []
for i, doc in enumerate(documents):
response = embed(model='llama3.2:3b', input=doc)
doc_embeddings.append(response.embeddings[0])
print(f" ✅ Doc {i+1} : {len(response.embeddings[0])} dimensions")
print(f"\n📊 Dimension des vecteurs : {len(doc_embeddings[0])}")
# Question de test
query = "Comment déployer des conteneurs en production ?"
print(f"\n🔍 Requête : {query}")
# Générer l'embedding de la requête
query_response = embed(model='llama3.2:3b', input=query)
query_embedding = query_response.embeddings[0]
# Calculer la similarité avec chaque document
print("\n📈 Scores de similarité :")
scores = []
for i, doc_emb in enumerate(doc_embeddings):
score = cosine_similarity(query_embedding, doc_emb)
scores.append((score, documents[i]))
print(f" {score:.4f}{documents[i][:50]}...")
# Trier par score décroissant
scores.sort(reverse=True)
print(f"\n🏆 Document le plus pertinent :")
print(f" Score: {scores[0][0]:.4f}")
print(f" {scores[0][1]}")

Sortie attendue :

📦 Génération des embeddings pour 5 documents...
✅ Doc 1 : 3072 dimensions
✅ Doc 2 : 3072 dimensions
...
📈 Scores de similarité :
0.3004 → Docker est une plateforme de conteneurisation...
0.3473 → Kubernetes orchestre les conteneurs à grande...
...
🏆 Document le plus pertinent :
Score: 0.4581
Ansible automatise la configuration des serveurs et le déploiement

Ce résultat est mauvais, et c'est l'enseignement principal du script : à la question « comment déployer des conteneurs en production », le document Ansible arrive devant Docker et Kubernetes. llama3.2 est un modèle de conversation, ses vecteurs internes ne sont pas entraînés pour la recherche sémantique. Le classement obtenu reflète surtout la proximité lexicale du mot « déploiement ». Reproduisez l'expérience avec nomic-embed-text et l'ordre se corrige : c'est la démonstration qu'un modèle d'embedding dédié n'est pas une optimisation mais une condition de fonctionnement.

Combinons toutes les fonctionnalités dans un assistant DevOps interactif.

Le script est long, lisez-le par blocs plutôt que ligne à ligne. Trois parties portent la logique. find_relevant_context() réalise la récupération : elle compare l'embedding de la question à ceux de la base et renvoie les deux documents les plus proches. chat_with_rag() réalise l'augmentation : elle colle ce contexte devant la question avant de l'envoyer au modèle. Le reste est de l'habillage de terminal.

Deux limites assumées, qui distinguent ce prototype d'un vrai système RAG. Les embeddings sont recalculés à chaque démarrage et vivent en mémoire : aucune persistance, aucune base vectorielle. Et la recherche est linéaire, elle compare la question à tous les documents. Sur six entrées c'est instantané, sur dix mille il faut un index dédié.

07_devops_buddy.py
#!/usr/bin/env python3
"""
TP 07 : DevOps Buddy - Assistant local complet
Objectif : Combiner toutes les fonctionnalités Ollama dans un assistant interactif
Features utilisées : chat, streaming, structured output, embeddings
"""
from ollama import chat, embed
from pydantic import BaseModel
import math
# === Configuration ===
MODEL = 'llama3.2:3b'
SYSTEM_PROMPT = '''Tu es DevOps Buddy, un assistant expert DevOps/DevSecOps.
Tu réponds en français de manière concise et technique.
Tu donnes des exemples de commandes quand c'est pertinent.
Tu structures tes réponses avec des listes à puces.'''
# === Base de connaissances embarquée ===
KNOWLEDGE_BASE = [
{"topic": "docker", "content": "Docker utilise des conteneurs pour isoler les applications. Commandes: docker build, docker run, docker compose"},
{"topic": "kubernetes", "content": "Kubernetes orchestre les conteneurs. Concepts: Pod, Deployment, Service, Ingress. Commandes: kubectl get, kubectl apply"},
{"topic": "ansible", "content": "Ansible automatise la configuration. Concepts: playbook, inventory, role, task. Commande: ansible-playbook"},
{"topic": "terraform", "content": "Terraform gère l'infrastructure as code. Concepts: provider, resource, module, state. Commandes: terraform init, plan, apply"},
{"topic": "gitlab", "content": "GitLab CI/CD pipeline avec .gitlab-ci.yml. Concepts: stages, jobs, artifacts, cache, runners"},
{"topic": "prometheus", "content": "Prometheus collecte les métriques. Concepts: scraping, PromQL, alertmanager, exporters"},
]
# Pré-calculer les embeddings de la base de connaissances
print("🔄 Chargement de la base de connaissances...")
knowledge_embeddings = []
for item in KNOWLEDGE_BASE:
response = embed(model=MODEL, input=item["content"])
knowledge_embeddings.append(response.embeddings[0])
print(f"✅ {len(KNOWLEDGE_BASE)} documents indexés\n")
# === Fonctions utilitaires ===
def cosine_similarity(vec1: list[float], vec2: list[float]) -> float:
dot = sum(a * b for a, b in zip(vec1, vec2))
norm1 = math.sqrt(sum(a ** 2 for a in vec1))
norm2 = math.sqrt(sum(b ** 2 for b in vec2))
return dot / (norm1 * norm2) if norm1 and norm2 else 0
def find_relevant_context(query: str, top_k: int = 2) -> str:
"""Recherche les documents pertinents pour enrichir le contexte"""
query_emb = embed(model=MODEL, input=query).embeddings[0]
scores = []
for i, doc_emb in enumerate(knowledge_embeddings):
score = cosine_similarity(query_emb, doc_emb)
scores.append((score, KNOWLEDGE_BASE[i]))
scores.sort(reverse=True)
top_docs = scores[:top_k]
context = "\n".join([f"- {doc['content']}" for _, doc in top_docs])
return context
# === Schéma pour les commandes structurées ===
class CommandSuggestion(BaseModel):
command: str
description: str
warning: str | None = None
def get_structured_command(query: str) -> CommandSuggestion | None:
"""Obtenir une suggestion de commande structurée"""
try:
response = chat(
model=MODEL,
messages=[
{'role': 'system', 'content': 'Tu suggères des commandes DevOps. Réponds uniquement en JSON.'},
{'role': 'user', 'content': f'Suggère une commande pour: {query}'}
],
format=CommandSuggestion.model_json_schema(),
options={'temperature': 0, 'num_predict': 200}
)
return CommandSuggestion.model_validate_json(response.message.content)
except Exception as e:
print(f"⚠️ Erreur structured output: {e}")
return None
# === Chat avec RAG ===
def chat_with_rag(question: str, history: list) -> str:
"""Répond à une question avec contexte enrichi"""
# Trouver le contexte pertinent
context = find_relevant_context(question)
# Construire le prompt enrichi
augmented_question = f"""Contexte (base de connaissances):
{context}
Question de l'utilisateur: {question}"""
# Ajouter au historique
history.append({'role': 'user', 'content': augmented_question})
# Appeler le modèle avec streaming
response_text = ""
stream = chat(
model=MODEL,
messages=history,
stream=True,
options={'temperature': 0.3}
)
for chunk in stream:
content = chunk.message.content
print(content, end='', flush=True)
response_text += content
print() # Nouvelle ligne après le streaming
# Ajouter la réponse à l'historique
history.append({'role': 'assistant', 'content': response_text})
return response_text
# === Main ===
def main():
print("=" * 60)
print("🤖 DevOps Buddy - Assistant DevOps Local (Ollama)")
print("=" * 60)
print(f"Modèle: {MODEL}")
print("Commandes spéciales:")
print(" /cmd <action> : Obtenir une commande structurée")
print(" /quit : Quitter")
print("-" * 60)
history = [{'role': 'system', 'content': SYSTEM_PROMPT}]
while True:
try:
user_input = input("\n👤 Vous: ").strip()
if not user_input:
continue
if user_input.lower() == '/quit':
print("👋 À bientôt!")
break
if user_input.startswith('/cmd '):
# Mode commande structurée
query = user_input[5:]
print("\n🔧 Recherche de commande...")
result = get_structured_command(query)
if result:
print(f"\n📋 Commande: {result.command}")
print(f"📝 Description: {result.description}")
if result.warning:
print(f"⚠️ Attention: {result.warning}")
else:
print("❌ Impossible de générer la commande")
else:
# Mode conversation avec RAG
print("\n🤖 DevOps Buddy: ", end='')
chat_with_rag(user_input, history)
except EOFError:
print("\n👋 À bientôt!")
break
except KeyboardInterrupt:
print("\n👋 Interruption - À bientôt!")
break
if __name__ == "__main__":
main()

Le démarrage prend quelques secondes, le temps de calculer les six embeddings de la base. L'assistant propose ensuite deux modes qu'il est utile de comparer : une question libre passe par le RAG en streaming, tandis que le préfixe /cmd bascule sur la sortie structurée et affiche une commande, sa description et un avertissement facultatif. La différence se sent à l'usage : le mode conversation affiche les premiers mots presque tout de suite, alors que le mode /cmd reste muet jusqu'à ce que le JSON complet soit généré et validé, puisqu'un JSON partiel serait inutilisable.

Fenêtre de terminal
python 07_devops_buddy.py

Exemple de session :

🔄 Chargement de la base de connaissances...
✅ 6 documents indexés
============================================================
🤖 DevOps Buddy - Assistant DevOps Local (Ollama)
============================================================
Modèle: llama3.2:3b
Commandes spéciales:
/cmd <action> : Obtenir une commande structurée
/quit : Quitter
------------------------------------------------------------
👤 Vous: C'est quoi un Pod ?
🤖 DevOps Buddy: Un Pod est l'unité de base dans Kubernetes...
👤 Vous: /cmd lister les pods kubernetes
🔧 Recherche de commande...
📋 Commande: kubectl get pods
📝 Description: Liste tous les pods dans le namespace courant
⚠️ Attention: Ajoutez -A pour lister tous les namespaces

Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

  1. SDK natif vs LiteLLM : Le SDK ollama offre des fonctionnalités exclusives (structured output, thinking) mais ne supporte que Ollama
  2. format= : Passez un schéma Pydantic pour obtenir du JSON typé
  3. stream=True : Affiche la réponse en temps réel
  4. embed() : Génère des embeddings pour la recherche sémantique
  5. Historique : Passez tous les messages pour maintenir le contexte
  6. options : Contrôlez la température, le nombre de tokens, etc.
  7. RAG local : Combinez embeddings + contexte pour enrichir les réponses

Passez cette liste avant d'aller plus loin : chaque script isole une capacité du SDK, et les suivants s'appuient sur les précédents. Si 03_structured_output.py échoue, inutile de lancer DevOps Buddy, il utilise le même mécanisme.

Ces trois vérifications éliminent la cause la plus fréquente d'échec, un serveur et un SDK qui ne parlent pas de la même version d'API.

  • SDK ollama installé (pip show ollama)
  • Pydantic installé (pip show pydantic)
  • Modèle téléchargé (ollama list)

Exécutez-les dans l'ordre. Le seul qui peut échouer pour une raison de fond est 06_embeddings.py : si les scores sont tous proches les uns des autres, c'est le modèle d'embedding qu'il faut changer, pas le code.

  • 01_chat_basique.py : réponse + métadonnées
  • 02_streaming.py : affichage temps réel
  • 03_structured_output.py : JSON validé par Pydantic
  • 04_structured_avance.py : listes d'objets
  • 05_conversation.py : historique multi-turn
  • 06_embeddings.py : similarité cosinus
  • 07_devops_buddy.py : assistant complet

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn