FR ▾
Obtenir une clé API

Uncensored VideoAPI Sora 2 : utiliser du texte sans censure pour les pipelines vidéo

Tutoriel IA agentique LangChain avec une API compatible OpenAI

Ce tutoriel LangChain agentic ai connecte LangChain à un endpoint compatible OpenAI, lie deux outils et exécute une boucle d'agent que vous pouvez lire ligne par ligne. Chaque extrait utilise la même base URL et le nom de modèle uncensored.

Mis à jour

Bras robotique en cycle entre des cubes d'outils dans une boucle, illustrant un agent LangChain appelant des outils

Points clés

  • ChatOpenAI fonctionne sans changement : définissez base_url, api_key et model sur uncensored.
  • L'API prend en charge l'appel d'outils, donc bind_tools et l'agent préconstruit fonctionnent tous les deux.
  • Limitez les itérations de boucle et validez les arguments des outils ; les modèles à poids ouverts se trompent parfois dessus.
  • Respectez les 8 requêtes simultanées avec une clé complète lorsque vous exécutez des agents en parallèle.

Ce dont vous avez besoin avant de commencer

Vous avez besoin de Python 3.10 ou plus récent, d'une clé API et de quelques packages. La clé provient de la page Clé API : inscrivez-vous avec Google ou avec e-mail et mot de passe, puis réclamez le crédit d'essai de 0,50 $ en un clic. La clé d'essai permet 2 requêtes simultanées et 60 par minute, ce qui suffit pour tout dans cet article si vous exécutez un agent à la fois.

pip install langchain-openai langchain-core langgraph
export API_KEY="paste-your-key-here"

L'API expose POST /v1/chat/completions et GET /v1/models. LangChain n'a besoin que du premier. Le modèle est un unique modèle à poids ouverts ajusté pour répondre sans refus de contenu pour un usage légal par des adultes ; il est exécuté par un fournisseur indépendant et n'est l'API officielle d'aucun fournisseur de modèle. La documentation liste les en-têtes et les limites si vous les souhaitez à côté de votre éditeur.

Comment les pièces correspondent à l'API

Il est utile de savoir ce que LangChain fait sur le réseau. Un HumanMessage devient un message avec le rôle user. Un AIMessage devient assistant, et lorsqu'il contient des appels d'outils, ceux-ci apparaissent dans le message de l'assistant sous forme de tableau tool_calls. Un ToolMessage devient le rôle tool avec l'ID d'appel correspondant. Le prompt système arrive en premier avec le rôle system.

Cette correspondance est importante pour le débogage. Si un agent se comporte de manière étrange, imprimez la liste des messages avant chaque appel et lisez-la comme une transcription. Vous repérerez généralement le problème en une minute : un résultat d'outil vide, un ID d'appel qui ne correspond pas, ou un historique qui a grandi bien plus que prévu. Le terme agentic peut donner l'impression que c'est de la magie, mais chaque étape est une requête de chat completion ordinaire.

Étape 1 : Connecter ChatOpenAI

L'intégration entière repose sur trois arguments. LangChain génère des requêtes standard au style OpenAI, donc le serveur ne peut pas faire la différence.

import os
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="uncensored",
    base_url="https://api.uncensoredvideo.cc/v1",
    api_key=os.environ["API_KEY"],
    temperature=0.7,
    max_retries=2,
)

print(llm.invoke("Name three beats of a heist scene, one line each.").content)

Si cela affiche trois lignes, la tuyauterie fonctionne. Si vous obtenez une erreur 401, vérifiez la clé. Si vous obtenez une erreur 404, vérifiez que l'URL se termine par /v1 et ne contient pas de chemin supplémentaire. max_retries est une option client, et cela aide avec les réponses temporaires 429 qui incluent Retry-After: 5.

Le streaming fonctionne de la même manière que vous l'utiliseriez avec n'importe quel modèle OpenAI : appelez llm.stream(...) et itérez. Le dernier chunk inclut les informations d'utilisation, vous pouvez donc enregistrer les nombres de tokens par appel.

Étape 2 : Définir les outils

Un agent est une boucle : le modèle lit la conversation, répond ou demande un outil, votre code exécute l'outil, et le résultat retourne au modèle. Les outils ci-dessous sont de simples fonctions Python. Ils sont délibérément ennuyeux, car le but est de voir la mécanique.

from langchain_core.tools import tool

@tool
def word_count(text: str) -> int:
    """Count the words in a piece of text."""
    return len(text.split())

@tool
def spoken_minutes(words: int, words_per_minute: int = 150) -> float:
    """Estimate how many minutes a script takes to read aloud."""
    return round(words / words_per_minute, 2)

tools = [word_count, spoken_minutes]

La docstring et les indications de type deviennent la description et le schéma de l'outil que voit le modèle. Écrivez-les comme si vous briefiez un collègue. Une docstring vague est la raison la plus courante pour laquelle un agent choisit le mauvais outil. Si vous écrivez des scripts pour la vidéo, le même schéma s'applique aux outils qui recherchent des listes de prises de vue ou vérifient un budget de longueur, un sujet couvert sur la page générateur de script Sora 2.

Étape 3 : Exécuter la boucle agent à la main

Les utilitaires préconstruits masquent la boucle. L'écrire une fois vous-même rend chaque bug ultérieur plus facile à trouver.

from langchain_core.messages import HumanMessage, ToolMessage

by_name = {t.name: t for t in tools}
llm_tools = llm.bind_tools(tools)

messages = [HumanMessage(
    "Here is a draft: 'The vault door hums. Nina counts to three, "
    "then cuts the power.' How many words is it, and how long is it read aloud?"
)]

for step in range(6):
    ai = llm_tools.invoke(messages)
    messages.append(ai)
    if not ai.tool_calls:
        break
    for call in ai.tool_calls:
        result = by_name[call["name"]].invoke(call["args"])
        messages.append(ToolMessage(content=str(result), tool_call_id=call["id"]))

print(messages[-1].content)

Trois détails sont importants. La limite range(6) arrête un modèle confus qui bouclerait à l'infini, et il limite aussi vos dépenses. Le tool_call_id doit correspondre à l'appel auquel il répond. Et le modèle peut demander plusieurs outils dans une seule réponse, c'est pourquoi la boucle interne gère une liste.

Sous le capot, la requête porte un tableau tools et la réponse porte tool_calls, avec les résultats retournés comme des messages avec role: "tool". Vous pouvez forcer un outil spécifique avec tool_choice, que LangChain expose comme argument à bind_tools.

Étape 4 : Utilisez l'agent LangGraph préconstruit

Une fois que la boucle manuelle a du sens, l'agent préconstruit économise des lignes. Il prend le même modèle et les mêmes outils.

import os
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent

llm = ChatOpenAI(
    model="uncensored",
    base_url="https://api.uncensoredvideo.cc/v1",
    api_key=os.environ["API_KEY"],
)

agent = create_react_agent(llm, tools)
out = agent.invoke({"messages": [("user", "How long is a 450 word script read aloud?")]})
print(out["messages"][-1].content)

LangChain et LangGraph changent leurs API entre les versions, et certains utilitaires ont été renommés ou déplacés. Si une importation échoue, consultez la documentation LangChain actuelle pour le constructeur d'agent équivalent. La partie connexion, ChatOpenAI avec une URL de base, reste la même.

Choisir entre une boucle et un graphe

La boucle écrite à la main suffit pour les agents qui choisissent parmi quelques outils et s'arrêtent. Elle est facile à lire, facile à journaliser et n'a pas de surprises de framework. Passez à LangGraph lorsque vous avez besoin de branches qui dépendent de l'état : une étape de révision qui renvoie le travail pour un autre passage, une approbation humaine avant qu'un outil risqué ne s'exécute, ou plusieurs sous-agents spécialisés qui se passent des résultats.

Quel que soit votre choix, gardez chaque nœud petit et donnez-lui une seule tâche. Un nœud de planification qui produit une courte liste numérotée au format JSON, un nœud d'exécution qui exécute des outils, et un nœud d'écriture qui produit le texte final sont plus faciles à tester qu'un seul prompt géant. Ils vous permettent également d'utiliser différentes températures : faible pour la planification et l'utilisation d'outils, plus élevée pour l'étape d'écriture. Puisque chaque nœud est un appel de complétion de chat normal, la même clé, URL et nom de modèle servent tous, et le coût est simplement la somme des appels.

Une dernière habitude : imprimez le total des tokens en cours. Les agents qui semblent bon marché dans une démo peuvent dépenser dix fois plus sur une tâche réelle désordonnée, et les chiffres d'utilisation sur chaque réponse rendent cela visible dès la première exécution, avant que cela ne se transforme en surprise sur votre solde.

Mémoire, tests et sortie structurée

La boucle ci-dessus oublie tout lorsque le script se termine. La mémoire la plus simple est la liste des messages elle-même : gardez-la entre les tours de l'utilisateur, ajoutez chaque nouvelle question, et réduisez les messages les plus anciens lorsqu'elle devient longue. Pour les sessions longues, remplacez les anciens messages par un court résumé écrit par le modèle. Parce que l'entrée est facturée par token, un résumé de 500 tokens bat 20 000 tokens d'historique brut à la fois en coût et en concentration.

Tester des agents consiste principalement à vérifier le comportement que vous pouvez observer. Réglez temperature à 0 ou passez un seed fixe, que l'API transmet, afin que les exécutions soient plus reproductibles. Ensuite, écrivez une poignée de questions où vous savez quel outil devrait être appelé, et vérifiez les noms d'outils et les arguments dans la liste des messages, pas le libellé exact de la réponse. Exécutez-les après chaque modification d'un prompt ou d'une description d'outil. Changer une docstring peut changer quel outil le modèle choisit, et un test est le moyen le moins cher de le remarquer.

Journalisez trois choses pour chaque exécution : le nombre d'étapes, les appels d'outils avec leurs arguments, et l'utilisation des tokens. Lorsqu'une exécution échoue, ces trois lignes vous disent si le modèle a mal choisi, si un outil a échoué, ou si la boucle a manqué d'étapes.

Sortie structurée et mode JSON

Les agents ont souvent besoin de retourner des données, pas du texte. L'API prend en charge le mode JSON via response_format: {"type":"json_object"}. Dans LangChain, vous pouvez le demander avec llm.bind(response_format={"type": "json_object"}). Dites au modèle dans le prompt que la réponse doit être un objet JSON et nommez les clés que vous attendez, puis analysez la chaîne et validez-la avec Pydantic. Ne faites pas confiance à l'étape d'analyse pour réussir toujours ; entourez-la d'un retry qui renvoie le texte d'erreur au modèle une fois.

Écueils et comment les corriger

  • Arguments d'outil incorrects. Un modèle à poids ouverts envoie parfois une chaîne là où vous avez déclaré un entier. Validez les arguments, retournez un court message d'erreur de l'outil, et laissez le modèle se corriger à l'étape suivante.
  • Boucles débridées. Limitez toujours les itérations. Enregistrez chaque étape pendant le développement.
  • Agents parallèles. Une clé complète permet 8 requêtes simultanées. Si vous exécutez un lot, définissez config={"max_concurrency": 4} sur llm.batch pour laisser de la marge. Dépasser la limite renvoie 429 avec le code concurrency ; dépasser 300 requêtes par minute renvoie rate_limited.
  • Streaming plus outils. Une requête en streaming occupe son slot de concurrence jusqu'à la fin du streaming, donc ne démarrez pas de nouveaux appels depuis un gestionnaire de streaming sur une clé d'essai.
  • Historique croissant. Chaque étape renvoie la liste complète des messages. La fenêtre de contexte est de 100 000 tokens, mais vous payez pour l'entrée à chaque appel.

Combien coûte une exécution d'agent

Prenons un agent modeste qui effectue 4 appels au modèle pour terminer une tâche, avec un prompt moyen de 3 000 tokens et 200 tokens de sortie par appel. Entrée : 4 x 3 000 = 12 000 tokens, ce qui représente 12 000 x $0,15 / 1 000 000 = $0,0018. Sortie : 4 x 200 = 800 tokens, ce qui représente $0,0004. Une exécution coûte $0,0022, donc 1 000 exécutions coûtent $2,20. Le crédit d'essai de $0,50 couvre environ 227 de ces exécutions. Les requêtes échouées ou refusées ne sont pas facturées, et le crédit n'expire jamais. Voir les tarifs pour les montants de rechargement et les bonus. Ce site accepte uniquement la crypto, USDT sur TRC20 ou USDC sur Base.

Questions et réponses

LangChain a-t-il besoin d'une intégration spéciale pour cette API ?

Non. La classe ChatOpenAI de langchain-openai accepte un base_url, donc vous le pointez vers l'API et utilisez le modèle uncensored. Aucun wrapper personnalisé n'est requis.

L'API prend-elle en charge l'appel d'outils pour les agents ?

Oui. Elle accepte les outils et tool_choice, renvoie tool_calls (même en streaming) et récupère les résultats sous forme de messages avec role tool.

Pourquoi mon agent s'arrête-t-il avec une erreur 429 ?

Vous avez atteint soit la limite de débit de requêtes, soit la limite de concurrence. Une clé complète permet 8 requêtes simultanées et 300 par minute. Réduisez max_concurrency ou attendez la période Retry-After.

Puis-je utiliser LangGraph au lieu de la boucle simple ?

Oui. L'agent préconstruit de LangGraph utilise le même objet ChatOpenAI et la même liste d'outils, donc le code de connexion ne change pas.

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.

Obtenir une clé API