Créer un chatbot à partir d’une API LLM : tutoriel Python
Les modèles Abliterated sont des grands modèles de langage dont les mécanismes imposant les refus de sécurité ont été supprimés, permettant au modèle de répondre à des questions controversées, pour adultes ou de niche sans déclencher de filtre de contenu. Cette approche donne aux développeurs un contrôle total sur la voix du modèle et sa date de coupure des connaissances, ce qui est particulièrement précieux pour le codage, le jeu de rôle et l'écriture créative où les garde-fous standard pourraient bloquer des sorties utiles.
Mis à jour

Points clés
- L'API est sans état, donc votre code gère l'historique de la conversation et l'envoie à chaque requête.
- Le streaming, l'appel de fonctions et le mode JSON utilisent tous les paramètres OpenAI standards.
- Réduisez ou résumez l'historique avant d'approcher la fenêtre de 100 000 tokens.
- 1 000 chats de 2 000 tokens d'entrée et 400 tokens de sortie coûtent environ 0,50 $.
L'idée centrale : un chatbot est une boucle et une liste
Un modèle de langage ne se souvient de rien entre les requêtes. Chaque appel à POST /v1/chat/completions est indépendant. Ce qui semble être de la mémoire est votre programme qui renvoie les messages précédents, chacun marqué avec un rôle : system pour les instructions persistantes, user pour ce que l'utilisateur a tapé, assistant pour les réponses précédentes du modèle.
L'architecture est donc réduite. Gardez une liste. Ajoutez le message utilisateur. Envoyez la liste. Ajoutez la réponse. Répétez. Tout le reste de ce tutoriel, du streaming aux outils, est une variation de cette boucle.
L'API ici est compatible OpenAI, donc vous utilisez le package openai standard. Définissez l'URL de base sur https://api.abliterated.cc/v1, utilisez votre clé et définissez le modèle sur uncensored. Obtenez une clé depuis la page des clés API ; le crédit d'essai de $0,50 est suffisant pour plusieurs centaines de courts messages de test.
Étape 1 : un chatbot console fonctionnel
Installez le SDK avec pip install openai et exécutez ceci.
from openai import OpenAI
client = OpenAI(
base_url="https://api.abliterated.cc/v1",
api_key="YOUR_KEY",
)
messages = [
{"role": "system", "content": "You are a concise, friendly support assistant for a bike shop."}
]
while True:
text = input("you: ")
if text.strip() in {"quit", "exit"}:
break
messages.append({"role": "user", "content": text})
resp = client.chat.completions.create(
model="uncensored",
messages=messages,
temperature=0.7,
)
answer = resp.choices[0].message.content
messages.append({"role": "assistant", "content": answer})
print("bot:", answer)
C'est un chatbot complet. Le message système définit sa tâche, la liste porte la mémoire, et temperature contrôle la variété des réponses. Réduisez-le vers 0,2 pour les bots de support factuel, augmentez-le vers 1,0 pour les créatifs.
Rédiger un prompt système qui définit la tâche
Le message système est l'endroit le moins cher pour améliorer un chatbot. Gardez-le court et spécifique. Nommez le rôle, le public, la longueur et le ton des réponses, et ce qu'il faut faire lorsque le bot ne sait pas. Un prompt tel que « Vous répondez aux questions pour une boutique de vélos. Répondez en au maximum trois phrases. Si la question concerne le prix d'une réparation, dites qu'un mécanicien doit inspecter le vélo » fait plus qu'une page de vertus générales.
Deux habitudes sont payantes. Premièrement, formulez les règles sous forme d'actions, pas d'attitudes : « posez une question de clarification lorsque la demande est ambiguë » au lieu de « soyez utile ». Deuxièmement, testez avec des entrées hostiles, comme un message vide, un collage très long et une demande sans rapport avec votre produit. Corrigez le prompt en fonction de ce que vous voyez, puis gardez ces entrées dans une liste de régression.
Le message système étant renvoyé à chaque tour, chaque mot qui s'y trouve est facturé à chaque requête. Un prompt de 400 tokens sur 1 000 conversations de 5 tours chacune ajoute 2 000 000 de tokens d'entrée, soit 2 x $0,15 = $0,30. C'est peu, mais cela montre pourquoi les prompts volumineux s'accumulent à grande échelle.
Étape 2 : diffuser la réponse
Attendre une réponse complète semble lent dans une fenêtre de chat. Définissez stream: true et affichez les morceaux à mesure qu'ils arrivent. Le streaming utilise les événements envoyés par le serveur et se termine par un bloc d'utilisation, donc vous pouvez enregistrer les compteurs de tokens.
from openai import OpenAI
client = OpenAI(base_url="https://api.abliterated.cc/v1", api_key="YOUR_KEY")
messages = [{"role": "user", "content": "Explain tire pressure in two sentences."}]
stream = client.chat.completions.create(
model="uncensored",
messages=messages,
stream=True,
)
reply = ""
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
part = chunk.choices[0].delta.content
reply += part
print(part, end="", flush=True)
if getattr(chunk, "usage", None):
print("\ntokens:", chunk.usage.prompt_tokens, chunk.usage.completion_tokens)
N'oubliez pas d'ajouter la réponse reply assemblée à votre historique, sinon le prochain tour n'aura aucune idée de ce que le bot a dit.
Étape 3 : gérer le contexte avant qu'il ne grossisse
La fenêtre de contexte fait 100 000 tokens, partagée entre le prompt et la complétion. La plupart des chatbots n'y arrivent jamais, mais le coût augmente avec l'historique car vous payez pour tout le prompt à chaque tour. Une politique simple maintient les deux sous contrôle :
- Conservez toujours le message système.
- Conservez les 10 à 20 derniers messages tels quels.
- Lorsque la liste dépasse une limite de taille que vous choisissez, telle que 8 000 tokens estimés, envoyez le bloc le plus ancien au modèle avec l'instruction « résumez cette conversation en moins de 150 mots », et remplacez ce bloc par le résumé en tant que message système.
Une estimation approximative d'un token pour quatre caractères anglais suffit pour le déclencheur. Les chiffres d'utilisation dans chaque réponse vous donnent le chiffre exact a posteriori, afin que vous puissiez calibrer la limite.
Si vous tronquez en supprimant les messages les plus anciens, supprimez-les par paires utilisateur et assistant. Une réponse sans question, ou une question sans réponse, perturbe le modèle plus que vous ne l'imagineriez.
Étape 4 : donner des outils au bot
L'appel de fonctions permet au modèle de demander à votre code de faire quelque chose, comme rechercher une commande. Vous décrivez les fonctions avec tools, le modèle répond avec une entrée tool_calls, vous exécutez la fonction, et vous renvoyez le résultat en tant que message role: "tool".
import json
from openai import OpenAI
client = OpenAI(base_url="https://api.abliterated.cc/v1", api_key="YOUR_KEY")
tools = [{
"type": "function",
"function": {
"name": "get_order_status",
"description": "Look up the status of an order by its id",
"parameters": {
"type": "object",
"properties": {"order_id": {"type": "string"}},
"required": ["order_id"],
},
},
}]
def get_order_status(order_id):
return {"order_id": order_id, "status": "shipped"}
messages = [{"role": "user", "content": "Where is order A1042?"}]
resp = client.chat.completions.create(
model="uncensored", messages=messages, tools=tools, tool_choice="auto"
)
msg = resp.choices[0].message
if msg.tool_calls:
messages.append(msg)
for call in msg.tool_calls:
args = json.loads(call.function.arguments)
result = get_order_status(**args)
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": json.dumps(result),
})
final = client.chat.completions.create(
model="uncensored", messages=messages, tools=tools
)
print(final.choices[0].message.content)
Validez toujours les arguments avant d'exécuter quoi que ce soit ayant des effets secondaires. Le modèle propose un appel ; votre code décide s'il doit l'exécuter.
Étape 5 : sortie structurée avec le mode JSON
Lorsque l'étape suivante de votre programme a besoin de données plutôt que de texte, comme trier un message dans une catégorie, utilisez le mode JSON avec response_format. Mentionnez le mot JSON et les clés attendues dans votre prompt également.
curl https://api.abliterated.cc/v1/chat/completions \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "uncensored",
"response_format": {"type": "json_object"},
"messages": [
{"role": "system", "content": "Reply with JSON: {\"intent\": string, \"urgent\": boolean}"},
{"role": "user", "content": "My brakes squeal and I ride tomorrow morning."}
]
}'
Placez toujours json.loads dans un bloc try. Si l'analyse échoue, réessayez une fois avec le texte d'erreur ajouté ; les requêtes échouées ne sont pas facturées.
Erreurs, coûts et notes de déploiement
Gérez les erreurs, les nouvelles tentatives et les limites de débit
Les vrais utilisateurs envoient des requêtes à des moments inattendus et les réseaux peuvent échouer. Encapsulez l'appel dans une gestion d'erreurs pour qu'une mauvaise réponse ne fasse pas planter la conversation.
import time
from openai import OpenAI, APIError, RateLimitError
client = OpenAI(base_url="https://api.abliterated.cc/v1", api_key="YOUR_KEY")
def chat(messages, tries=3):
for attempt in range(tries):
try:
resp = client.chat.completions.create(
model="uncensored", messages=messages, temperature=0.7
)
return resp.choices[0].message.content
except RateLimitError:
time.sleep(2 ** attempt)
except APIError as exc:
if attempt == tries - 1:
raise
time.sleep(1)
return "Sorry, the assistant is busy. Please try again in a moment."
Une clé complète permet 8 requêtes simultanées et 300 requêtes par minute ; la clé d'essai en permet 2 et 60. Si votre bot sert de nombreux utilisateurs à la fois, mettez les requêtes en file d'attente avec une limite de workers inférieure à 8 au lieu de compter sur les réessais. Comme les requêtes échouées ne sont pas facturées, les réessais n'ont aucun coût en tokens. Gardez le nombre de réessais faible pour que les pannes réelles échouent rapidement.
Journalisez également l'en-tête X-Request-Id à chaque tour de conversation. Lorsqu'une réponse semble incorrecte, l'id vous permet de retrouver la requête exacte plus tard.
Coûts et déploiement
Le prix est de 0,15 $ par 1M de tokens d'entrée et de 0,50 $ par 1M de tokens de sortie. Disons qu'un chat de support utilise 2 000 tokens d'entrée au total et 400 tokens de sortie.
- Entrée : 0,002M x $0,15 = $0,0003
- Sortie : 0,0004M x $0,50 = $0,0002
- Une conversation : $0,0005, donc 1 000 conversations coûtent $0,50
Consultez les tarifs actuels et les bonus de rechargement sur la page des tarifs. Pour la production, gardez la clé sur votre serveur, jamais dans le code du navigateur, et surveillez l'en-tête de réponse X-Balance-USD pour vous alerter avant l'épuisement du crédit. Une clé complète permet 8 requêtes simultanées et 300 requêtes par minute, donc mettez les pics en file d'attente au lieu de les envoyer tous en même temps. La documentation liste tous les paramètres pris en charge.
Plus de guides
Questions et réponses
Avez-vous besoin d'un framework pour créer un chatbot ?
Non. Le SDK OpenAI et une liste de messages suffisent pour créer un bot fonctionnel. Ajoutez un framework plus tard uniquement si vous en avez besoin pour ses fonctionnalités supplémentaires.
L'API se souvient-elle des messages précédents ?
Non. Chaque requête est indépendante, votre code doit donc renvoyer l'historique à chaque fois.
Comment empêcher l'historique de devenir trop long ?
Conservez le message système et les tours récents, et résumez les plus anciens en une courte note une fois que la liste dépasse une taille que vous définissez.
Le bot peut-il appeler mes propres fonctions ?
Oui. Transmettez les outils et tool_choice, exécutez la fonction lorsque la réponse contient tool_calls, et renvoyez le résultat en tant que message tool.
Votre clé n'est qu'à un formulaire d'ici
Créez un compte, copiez la clé, modifiez l'URL de base. C'est toute la configuration.