FR ▾
Obtenir une clé API

Chat OpenAI dans LangChain avec une API sans censure

La classe ChatOpenAI de LangChain fonctionne avec n’importe quel endpoint compatible OpenAI, vous modifiez donc uniquement la base URL, la clé et le nom du modèle. Cette page montre la configuration en Python et Node, puis passe au streaming, aux outils et à un petit agent.

Mis à jour le

Chaîne isométrique d'anneaux liés alimentant des bulles de chat dans un cube serveur, représentant une connexion LangChain à une API

Points clés

  1. ChatOpenAI nécessite trois paramètres : base_url, api_key et model définis sur uncensored.
  2. Le streaming, l'appel d'outils et le mode JSON passent tous par les interfaces LangChain standard.
  3. Plafonnez la concurrence à 8 et gérez le HTTP 429 avec des tentatives pour rester dans les limites.
  4. Une exécution d'agent en dix étapes coûte bien moins d'un centime à $0,15 et $0,50 par 1M de tokens.

La réponse courte : trois paramètres sur ChatOpenAI

Si vous avez recherché chat open ai langchain, vous avez probablement un projet LangChain qui utilise déjà ChatOpenAI et vous souhaitez qu'il communique avec un autre backend. Il s'agit d'un changement de configuration, pas d'une réécriture. L'API de ce site implémente le protocole de complétion de chat OpenAI, donc LangChain le traite comme n'importe quel autre serveur de style OpenAI.

Vous avez besoin de l'URL de base, de votre clé API et de l'ID de modèle uncensored. Installez d'abord les packages :

pip install -U langchain-openai langgraph

Puis créez l'objet modèle :

import os
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="uncensored",
    base_url="https://api.nofilteraichat.com/v1",
    api_key=os.environ["NOFILTER_API_KEY"],
    temperature=0.8,
)

reply = llm.invoke("Write a two-sentence villain monologue for a heist novel.")
print(reply.content)

C'est toute l'intégration. Chaque fonctionnalité LangChain basée sur ChatOpenAI s'exécute désormais sur le modèle sans censure : chaînes, retrieveurs qui appellent le modèle de chat, analyseurs de sortie et agents. Si vous n'avez pas encore de clé, la page clé API explique l'inscription et le crédit d'essai en un clic.

Gardez la clé hors de votre code

Mettez la clé dans une variable d'environnement et lisez-la au démarrage. Sous Linux ou macOS :

export NOFILTER_API_KEY="paste-your-key-here"

Créez un module client partagé pour le projet, par exemple llm.py qui construit le modèle une fois et l'exporte. Chaque chaîne importe ensuite le même objet, et un changement ultérieur de clé, de délai d'attente ou de température se produit à un seul endroit. Cela facilite également le maintien d'une seconde instance plus froide pour les étapes d'outils et d'une plus chaude pour l'écriture créative, toutes deux pointant vers le même endpoint avec des paramètres différents.

Un écueil piège souvent les développeurs : ChatOpenAI lit également OPENAI_API_KEY et OPENAI_API_BASE depuis l'environnement. Si ces variables sont définies pour un autre projet, un objet partiellement configuré peut envoyer votre demande au mauvais serveur. Passer base_url et api_key explicitement, comme ci-dessus, supprime l'ambiguïté.

Vous pouvez confirmer la connexion sans LangChain du tout. L'endpoint models devrait retourner une seule entrée :

curl https://api.nofilteraichat.com/v1/models \
  -H "Authorization: Bearer $NOFILTER_API_KEY"

Si cela fonctionne mais que LangChain échoue, le problème vient de votre environnement Python, pas de la clé. Si les deux échouent avec 401, vérifiez la présence d'un espace ou d'une nouvelle ligne dans la clé. Le guide de démarrage rapide liste le format de demande exact pour comparaison.

Streaming et utilisation des tokens

Les interfaces de chat sont plus agréables lorsque les tokens apparaissent au fur et à mesure de leur génération. LangChain expose cela via .stream(), et le serveur envoie des chunks SSE standards lorsque stream: true est activé en interne.

from langchain_openai import ChatOpenAI
import os

llm = ChatOpenAI(
    model="uncensored",
    base_url="https://api.nofilteraichat.com/v1",
    api_key=os.environ["NOFILTER_API_KEY"],
    stream_usage=True,
)

final = None
for chunk in llm.stream("Describe a rainy harbour town in four sentences."):
    print(chunk.content, end="", flush=True)
    final = chunk if final is None else final + chunk

print()
print(final.usage_metadata)

Avec stream_usage=True, le dernier chunk porte les compteurs de tokens d'entrée et de sortie, que l'API envoie à la fin du flux. Conservez ces nombres. C'est le moyen le moins cher de voir ce qu'un agent coûte réellement, et nous les utilisons dans la section coût ci-dessous.

À retenir : une requête en streaming occupe son slot de concurrence jusqu’à la fin du flux. Si vous abandonnez un flux sans le fermer, ce slot reste occupé plus longtemps que prévu.

Node et TypeScript

Le package JavaScript utilise un nom d'option légèrement différent. L'URL de base va à l'intérieur de configuration :

npm install @langchain/openai @langchain/core
import { ChatOpenAI } from "@langchain/openai";

const llm = new ChatOpenAI({
  model: "uncensored",
  apiKey: process.env.NOFILTER_API_KEY,
  configuration: { baseURL: "https://api.nofilteraichat.com/v1" },
  temperature: 0.8,
});

const res = await llm.invoke("Give me three names for a smuggler's ship.");
console.log(res.content);

Les types TypeScript pour la réponse sont les classes de messages LangChain habituelles, donc le code existant qui lit res.content ou res.usage_metadata continue de fonctionner. Lorsque vous exécutez cela dans une route serveur, créez le modèle une fois au niveau du module plutôt que par requête. Cela évite de créer un nouveau client HTTP pour chaque appel et rend votre concurrence facile à comprendre.

Tout le reste, y compris .stream(), .bindTools() et .withStructuredOutput(), se comporte de la même manière qu'en Python. La température, top_p, les séquences d'arrêt, la graine et les options de pénalité sont transmises au modèle, vous pouvez donc les définir sur le constructeur comme vous le feriez pour n'importe quel autre backend de style OpenAI.

Appel d'outils et petit agent

L'API prend en charge l'appel d'outils : les champs tools et tool_choice, les tool_calls diffusés, et les résultats d'outils retournés en tant que messages role: "tool". L'agent préconstruit de LangGraph utilise exactement cette boucle. Voici un agent avec un outil :

import os
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent

@tool
def roll_dice(sides: int) -> int:
    """Roll a die with the given number of sides."""
    import random
    return random.randint(1, sides)

llm = ChatOpenAI(
    model="uncensored",
    base_url="https://api.nofilteraichat.com/v1",
    api_key=os.environ["NOFILTER_API_KEY"],
)

agent = create_react_agent(llm, [roll_dice])
out = agent.invoke(
    {"messages": [("user", "Roll a twenty-sided die twice and tell me the total.")]}
)
print(out["messages"][-1].content)

L’utilisation d’outils avec des modèles à poids ouverts est moins prévisible que celle d’un modèle phare hébergé, traitez-la donc comme quelque chose à tester. Rédigez les descriptions d’outils en mots simples, gardez les schémas d’arguments petits et définissez temperature à une valeur faible (0,2 à 0,4) pour les étapes d’agent qui doivent produire des arguments valides. Si un appel revient mal formé, LangChain le signale comme un appel d’outil invalide, et un nouvel essai avec une description plus claire le résout généralement.

Maintenez la boucle de l'agent bornée. LangGraph possède une limite de récursion, et vous devez la définir à un nombre que vous pouvez vous permettre. Si un agent peut appeler des outils indéfiniment, un prompt défectueux peut consommer du crédit pendant votre absence. Une limite de 10 à 15 étapes est une valeur par défaut raisonnable pour la plupart des tâches, et vous pouvez la passer dans la configuration lors de l'appel de l'agent.

Sortie structurée

Le mode JSON est disponible via response_format. Dans LangChain, demandez-le avec la méthode du mode JSON et nommez les clés dans votre prompt :

from pydantic import BaseModel
from langchain_openai import ChatOpenAI
import os

class Character(BaseModel):
    name: str
    role: str
    secret: str

llm = ChatOpenAI(
    model="uncensored",
    base_url="https://api.nofilteraichat.com/v1",
    api_key=os.environ["NOFILTER_API_KEY"],
)
structured = llm.with_structured_output(Character, method="json_mode")
print(structured.invoke(
    "Return JSON with keys name, role and secret for a noir detective."
))

Limites de débit, tentatives et coût

Une clé complète permet 8 requêtes simultanées et 300 requêtes par minute. Une clé d'essai permet 2 et 60. Lorsque vous dépassez l'un ou l'autre, l'API répond avec HTTP 429 et un code d'erreur : rate_limited pour les requêtes par minute, concurrency pour trop de requêtes à la fois. Une surcharge temporaire renvoie également 429, avec un en-tête Retry-After: 5.

LangChain vous donne deux boutons pour cela. max_retries sur le modèle retente les appels échoués avec un backoff, et max_concurrency dans la configuration d'exécution plafonne le travail en lot parallèle :

llm = ChatOpenAI(
    model="uncensored",
    base_url="https://api.nofilteraichat.com/v1",
    api_key=os.environ["NOFILTER_API_KEY"],
    max_retries=4,
    timeout=120,
)

answers = llm.batch(
    ["Prompt one", "Prompt two", "Prompt three", "Prompt four"],
    config={"max_concurrency": 6},
)

La définition de max_concurrency à 6 sur une clé complète laisse de la marge pour un deuxième processus. Rappelez-vous que chaque étape d'agent est une demande séparée, et une étape diffusée occupe son slot jusqu'à la fin du flux.

Combien coûte une exécution d'agent

La tarification est de $0,15 par 1M de tokens d'entrée et de $0,50 par 1M de tokens de sortie. Disons qu'une étape d'agent envoie 3 000 tokens d'historique, d'outils et d'instructions, et que le modèle écrit 500 tokens. L'entrée coûte 3 000 × $0,15 / 1 000 000 = $0,00045. La sortie coûte 500 × $0,50 / 1 000 000 = $0,00025. Une étape coûte $0,0007. Une exécution en dix étapes coûte $0,007, et 1 000 de ces exécutions coûtent $7,00.

Les agents renvoient leur historique croissant à chaque étape, donc les tokens d’entrée dominent. Supprimer les anciennes sorties d’outils est l’optimisation la moins coûteuse dont vous disposez. Les requêtes échouées ou refusées ne sont pas facturées. Les détails des recharges et des bonus se trouvent sur la page tarifs.

Problèmes courants

  • 404 sur chaque appel. L'URL de base doit se terminer par /v1 et ne doit pas inclure /chat/completions. LangChain ajoute le chemin lui-même.
  • Modèle introuvable. Le seul ID de modèle est uncensored. Des noms comme gpt-4o ne fonctionneront pas.
  • Erreurs de contexte. La fenêtre est de 100 000 tokens pour le prompt plus la complétion. De longues chaînes de récupération peuvent la dépasser. Résumez ou réduisez avant d'envoyer.
  • Requête trop volumineuse. La limite du corps est de 8 Mo, ce qui est important si vous chargez des documents entiers dans un prompt.
  • Les embeddings échouent. Cette API est uniquement pour le chat textuel. Gardez votre modèle d'embedding sur un autre fournisseur et utilisez cet endpoint pour la génération.

Le même schéma fonctionne pour d'autres frameworks et interfaces de chat ; le guide d'intégration couvre plus de clients. Pour toute chose inhabituelle, la page support est l'endroit où commencer.

Questions et réponses

Puis-je utiliser ChatOpenAI avec une URL de base personnalisée ?

Oui. Transmettez base_url (baseURL dans la configuration sous Node), votre clé et le modèle uncensored. LangChain se moque du serveur qui répond tant qu'il respecte le protocole de chat OpenAI.

Le streaming LangChain fonctionne-t-il avec cette API ?

Oui. L'API diffuse en SSE et envoie l'utilisation à la fin, donc .stream() et astream() fonctionnent, et stream_usage=True vous donne les compteurs de tokens.

Puis-je utiliser les embeddings ou les bases de vecteurs LangChain avec cela ?

Non pour les embeddings, car l'API n'a pas d'endpoint d'embeddings. Utilisez une autre source d'embeddings pour la récupération et envoyez le texte récupéré à cet endpoint pour la génération.

Que se passe-t-il lorsque vous atteignez la limite de débit ?

Vous obtenez un HTTP 429 avec le code rate_limited ou concurrency. Définissez max_retries sur ChatOpenAI et limitez max_concurrency à 8 ou moins sur une clé complète.

Votre clé est à un formulaire de vous

Créez un compte, copiez la clé, modifiez l'URL de base. C'est toute la configuration.

Obtenir une clé API