ES ▾
Obtener clave de API

Chat OpenAI en LangChain con una API sin censura

La clase ChatOpenAI de LangChain funciona con cualquier endpoint compatible con OpenAI, por lo que solo cambias la URL base, la clave y el nombre del modelo. Esta página muestra la configuración en Python y Node, y luego avanza hacia el streaming, las herramientas y un agente pequeño.

Actualizado

Cadena isométrica de anillos conectados que alimentan burbujas de chat en un cubo de servidor, representando una conexión de LangChain a una API

Puntos clave

  1. ChatOpenAI necesita tres configuraciones: base_url, api_key y modelo establecido en uncensored.
  2. El streaming, las llamadas a funciones y el modo JSON pasan por las interfaces estándar de LangChain.
  3. Limita la concurrencia a 8 y maneja HTTP 429 con reintentos para mantenerse dentro de los límites.
  4. Una ejecución de agente de diez pasos cuesta menos de un centavo a $0.15 y $0.50 por 1M de tokens.

La respuesta corta: tres configuraciones en ChatOpenAI

Si buscaste chat open ai langchain, probablemente tengas un proyecto LangChain que ya usa ChatOpenAI y quieres que hable con un backend diferente. Eso es un cambio de configuración, no una reescritura. La API de este sitio habla el protocolo de completación de chat de OpenAI, por lo que LangChain lo trata como cualquier otro servidor de estilo OpenAI.

Necesitas la URL base, tu clave de API y el ID del modelo uncensored. Instala los paquetes primero:

pip install -U langchain-openai langgraph

Luego crea el objeto del modelo:

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)

Esa es toda la integración. Cada función de LangChain basada en ChatOpenAI ahora se ejecuta contra el modelo sin censura: cadenas, recuperadores que llaman al modelo de chat, analizadores de salida y agentes. Si aún no tienes una clave, la página de clave de API explica el registro y el crédito de prueba con un clic.

Mantén la clave fuera de tu código

Coloca la clave en una variable de entorno y léela al inicio. En Linux o macOS:

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

Crea un único módulo de cliente compartido para el proyecto, por ejemplo llm.py que construya el modelo una vez y lo exporte. Cada cadena luego importa el mismo objeto, y un cambio posterior de clave, tiempo de espera o temperatura ocurre en un solo lugar. Esto también facilita mantener una segunda instancia más fría para pasos de herramientas y una más cálida para escritura creativa, ambas apuntando al mismo endpoint con configuraciones diferentes.

Una trampa atrapa a mucha gente: ChatOpenAI también lee OPENAI_API_KEY y OPENAI_API_BASE del entorno. Si esas variables están configuradas para otro proyecto, un objeto parcialmente configurado puede enviar tu petición al servidor equivocado. Pasar base_url y api_key explícitamente, como arriba, elimina la ambigüedad.

Puedes confirmar la conexión sin LangChain en absoluto. El endpoint de modelos debería devolver una única entrada:

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

Si eso funciona pero LangChain falla, el problema está en tu entorno de Python, no en la clave. Si ambas fallan con 401, busca un espacio o salto de línea extraño en la clave. La guía de inicio rápido lista el formato exacto de la petición para comparación.

Streaming y uso de tokens

Las interfaces de chat se sienten mejor cuando los tokens aparecen a medida que se generan. LangChain expone eso a través de .stream(), y el servidor envía fragmentos SSE estándar cuando stream: true está configurado internamente.

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)

Con stream_usage=True el último fragmento lleva los recuentos de tokens de entrada y salida, que la API envía al final del streaming. Guarda esos números. Es la forma más barata de ver cuánto cuesta realmente un agente, y los usamos en la sección de costes a continuación.

Una cosa a recordar: una petición en streaming mantiene su ranura de concurrencia hasta que termina el streaming. Si abandonas un streaming sin cerrarlo, esa ranura permanece ocupada más tiempo del esperado.

Node y TypeScript

El paquete de JavaScript usa un nombre de opción ligeramente diferente. La URL base va dentro 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);

Los tipos de TypeScript para la respuesta son las clases de mensaje habituales de LangChain, por lo que el código existente que lee res.content o res.usage_metadata sigue funcionando. Cuando ejecutes esto dentro de una ruta de servidor, construye el modelo una vez en el ámbito del módulo en lugar de por petición. Eso evita crear un nuevo cliente HTTP para cada llamada y mantiene tu concurrencia fácil de razonar.

Todo lo demás, incluyendo .stream(), .bindTools() y .withStructuredOutput(), se comporta de la misma manera que en Python. Temperatura, top_p, secuencias de parada, semilla y las opciones de penalización se pasan al modelo, por lo que puedes establecerlas en el constructor como lo harías para cualquier otro backend de estilo OpenAI.

Llamadas a funciones y un agente pequeño

La API admite llamadas a funciones: los campos tools y tool_choice, el streaming de tool_calls y los resultados de las herramientas devueltos como mensajes role: "tool". El agente preconstruido de LangGraph usa exactamente ese bucle. Aquí tienes un agente con una herramienta:

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)

El uso de herramientas con modelos de pesos abiertos es menos predecible que con un modelo destacado alojado, así que trátalo como algo que debes probar. Escribe las descripciones de las herramientas en palabras sencillas, mantén los esquemas de argumentos pequeños y establece temperature en un valor bajo (0.2 a 0.4) para los pasos del agente que deben producir argumentos válidos. Si una llamada devuelve un formato incorrecto, LangChain lo muestra como una llamada a herramienta inválida, y un reintento con una descripción más clara suele solucionarlo.

Mantén el bucle del agente acotado. LangGraph tiene un límite de recursión, y debes establecerlo en un número que puedas permitirte. Si un agente puede llamar a herramientas para siempre, un prompt malo puede consumir créditos mientras estás lejos del teclado. Un límite de 10 a 15 pasos es un valor predeterminado sensato para la mayoría de las tareas, y puedes pasarlo en la configuración cuando invoques al agente.

Salida estructurada

El modo JSON está disponible a través de response_format. En LangChain, pídelo con el método de modo JSON y nombra las claves en tu 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."
))

Límites de peticiones, reintentos y coste

Una clave completa permite 8 peticiones simultáneas y 300 peticiones por minuto. Una clave de prueba permite 2 y 60. Cuando excedes cualquiera de estos límites, la API responde con HTTP 429 y un código de error: rate_limited para peticiones por minuto, concurrency para demasiadas a la vez. Una sobrecarga temporal también devuelve 429, con un encabezado Retry-After: 5.

LangChain te da dos perillas para esto. max_retries en el modelo reintenta las llamadas fallidas con retroceso, y max_concurrency en la configuración de ejecución limita el trabajo paralelo por lotes:

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},
)

Establecer max_concurrency en 6 en una clave completa deja margen para un segundo proceso. Recuerda que cada paso de agente es una petición separada, y un paso en streaming ocupa su ranura hasta que termina el streaming.

Cuánto cuesta una ejecución de agente

Los precios son $0.15 por 1M de tokens de entrada y $0.50 por 1M de tokens de salida. Supongamos que un paso de agente envía 3,000 tokens de historial, herramientas e instrucciones, y el modelo genera 500 tokens. La entrada cuesta 3,000 × $0.15 / 1,000,000 = $0.00045. La salida cuesta 500 × $0.50 / 1,000,000 = $0.00025. Un paso cuesta $0.0007. Una ejecución de diez pasos cuesta $0.007, y 1,000 de esas ejecuciones cuestan $7.00.

Los agentes reenvían su historial creciente en cada paso, por lo que los tokens de entrada dominan. Recortar la salida de herramientas antigua es la optimización más barata que tienes. Las peticiones fallidas o rechazadas no se cobran. Los detalles de las recargas y bonificaciones están en la página de precios.

Problemas comunes

  • 404 en cada llamada. La URL base debe terminar en /v1 y no debe incluir /chat/completions. LangChain añade la ruta por sí misma.
  • Modelo no encontrado. El único ID de modelo es uncensored. Nombres como gpt-4o no funcionarán.
  • Errores de contexto. La ventana es de 100.000 tokens para prompt más finalización. Las cadenas de recuperación largas pueden excederla. Resume o recorta antes de enviar.
  • Petición demasiado grande. El límite del cuerpo es 8 MB, lo cual importa si metes documentos enteros en un prompt.
  • Fallo de embeddings. Esta API es solo chat de texto. Mantén tu modelo de embeddings en otro proveedor y usa este endpoint para la generación.

El mismo patrón funciona para otros marcos y interfaces de chat; la guía de integración cubre más clientes. Para cualquier cosa inusual, la página de soporte es el lugar para empezar.

Preguntas y respuestas

¿Puedo usar ChatOpenAI con una URL base personalizada?

Sí. Pasa base_url (baseURL dentro de la configuración en Node), tu clave y el modelo uncensored. LangChain no le importa qué servidor responda mientras siga el protocolo de chat de OpenAI.

¿Funciona el streaming de LangChain con esta API?

Sí. La API hace streaming mediante SSE y envía el uso al final, por lo que .stream() y astream() funcionan, y stream_usage=True te proporciona los recuentos de tokens.

¿Puedo usar embeddings o almacenes vectoriales de LangChain con ello?

No para embeddings, porque la API no tiene un endpoint de embeddings. Usa otra fuente de embeddings para la recuperación y envía el texto recuperado a este endpoint para la generación.

¿Qué ocurre cuando alcanzo el límite de peticiones?

Obtienes HTTP 429 con el código rate_limited o concurrency. Establece max_retries en ChatOpenAI y limita max_concurrency a 8 o menos en una clave completa.

Tu clave está a un formulario de distancia

Crea una cuenta, copia la clave, cambia la URL base. Esa es toda la configuración.

Obtener clave de API