Краткий ответ: три настройки в ChatOpenAI
Если вы искали chat open ai langchain, вероятно, у вас уже есть проект LangChain, использующий ChatOpenAI, и вы хотите подключить его к другому бэкенду. Это изменение конфигурации, а не переписывание кода. API на этом сайте использует протокол chat completions от OpenAI, поэтому LangChain воспринимает его как любой другой сервер в стиле OpenAI.
Вам нужны базовый URL, ваш API-ключ и идентификатор модели uncensored. Сначала установите пакеты:
pip install -U langchain-openai langgraphЗатем создайте объект модели:
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)Это вся интеграция. Каждая функция LangChain, построенная на ChatOpenAI, теперь работает с моделью uncensored: цепочки, ретриверы, вызывающие чат-модель, парсеры вывода и агенты. Если у вас ещё нет ключа, на странице API-ключа описаны регистрация и получение пробного баланса в один клик.
Не храните ключ в коде
Сохраните ключ в переменной окружения и прочитайте его при запуске. В Linux или на macOS:
export NOFILTER_API_KEY="paste-your-key-here"Создайте один общий модуль клиента для проекта, например llm.py, который создаёт модель один раз и экспортирует её. Каждая цепочка импортирует один и тот же объект, и последующее изменение ключа, тайм-аута или температуры происходит в одном месте. Это также упрощает поддержание второго, более «холодного» экземпляра для шагов с инструментами и более «горячего» для творческого письма, оба указывающие на один и тот же эндпоинт с разными настройками.
Одна ловушка подстерегает многих: ChatOpenAI также читает OPENAI_API_KEY и OPENAI_API_BASE из окружения. Если эти переменные установлены для другого проекта, частично настроенный объект может отправить ваш запрос на неверный сервер. Явное указание base_url и api_key, как показано выше, устраняет неоднозначность.
Вы можете проверить соединение без LangChain вообще. Эндпоинт моделей должен вернуть одну запись:
curl https://api.nofilteraichat.com/v1/models \
-H "Authorization: Bearer $NOFILTER_API_KEY"Если это работает, но LangChain не работает, проблема в вашей Python-среде, а не в ключе. Если оба запроса возвращают ошибку 401, проверьте наличие лишнего пробела или символа новой строки в ключе. Быстрый старт содержит точный формат запроса для сравнения.
Потоковая передача и использование токенов
Чат-интерфейсы лучше воспринимаются, когда токены появляются по мере генерации. LangChain предоставляет доступ к этому через .stream(), а сервер отправляет стандартные фрагменты SSE, когда под капотом выставлен stream: true.
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)С параметром stream_usage=True последний фрагмент содержит количество входных и выходных токенов, которые API отправляет в конце потока. Запоминайте эти числа. Это самый дешёвый способ узнать реальную стоимость работы агента, и мы используем их в разделе стоимости ниже.
Одна вещь, о которой следует помнить: потоковый запрос удерживает слот параллельных запросов до завершения потока. Если вы оставите поток без закрытия, этот слот будет занят дольше, чем вы ожидаете.
Node и TypeScript
Пакет JavaScript использует немного другое имя параметра. Базовый URL находится внутри configuration:
npm install @langchain/openai @langchain/coreimport { 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);Типы TypeScript для ответа — это обычные классы сообщений LangChain, поэтому существующий код, читающий res.content или res.usage_metadata, продолжает работать. При запуске этого кода внутри маршрута сервера создавайте модель один раз в области видимости модуля, а не для каждого запроса. Это позволяет избежать создания нового HTTP-клиента для каждого вызова и упрощает понимание параллелизма.
Всё остальное, включая .stream(), .bindTools() и .withStructuredOutput(), ведёт себя так же, как в Python. Температура, top_p, стоп-последовательности, seed и параметры штрафов передаются модели, поэтому вы можете установить их в конструкторе, как и для любого другого бэкенда в стиле OpenAI.
Вызов инструментов и небольшой агент
API поддерживает вызов инструментов: поля tools и tool_choice, потоковые tool_calls и результаты инструментов, возвращаемые как сообщения с role: "tool". Предварительно созданный агент LangGraph использует именно этот цикл. Вот агент с одним инструментом:
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)Использование инструментов с моделями с открытыми весами менее предсказуемо, чем с флагманской хостинговой моделью, поэтому относитесь к этому как к чему-то, что нужно протестировать. Пишите описания инструментов простыми словами, держите JSON-схемы аргументов небольшими и устанавливайте temperature низким (0,2–0,4) для шагов агента, которые должны генерировать корректные аргументы. Если вызов возвращается в неверном формате, LangChain отображает его как неверный вызов инструмента, и повторная попытка с более чётким описанием обычно исправляет ситуацию.
Ограничьте цикл агента. LangGraph имеет лимит рекурсии, и вы должны установить его на число, которое можете себе позволить. Если агент может бесконечно вызывать инструменты, плохой промпт может быстро исчерпать баланс, пока вы отключились от клавиатуры. Лимит в 10–15 шагов — разумное значение по умолчанию для большинства задач, и вы можете передать его в конфигурации при вызове агента.
Структурированный вывод
JSON-режим доступен через response_format. В LangChain запросите его с помощью метода для JSON-режима и укажите имена ключей в вашем промпте:
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."
))Лимиты запросов, повторные попытки и стоимость
Полный ключ позволяет 8 параллельных запросов и 300 запросов в минуту. Пробный ключ позволяет 2 и 60. При превышении любого из них API отвечает кодом HTTP 429 и кодом ошибки: rate_limited для запросов в минуту, concurrency для одновременных запросов. Временная перегрузка также возвращает 429 с заголовком Retry-After: 5.
LangChain предоставляет два параметра для этого. max_retries на модели повторяет неудачные вызовы с экспоненциальной задержкой (backoff), а max_concurrency в конфигурации выполнения ограничивает параллельную пакетную работу:
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},
)Установка max_concurrency на 6 для полного ключа оставляет запас мощности для второго процесса. Помните, что каждый шаг агента — это отдельный запрос, а потоковый шаг занимает свой слот до завершения потока.
Сколько стоит запуск агента
Цены составляют $0,15 за 1M входных токенов и $0,50 за 1M выходных токенов. Предположим, шаг агента отправляет 3000 токенов истории, инструментов и инструкций, а модель генерирует 500 токенов. Входные данные стоят 3000 × $0,15 / 1 000 000 = $0,00045. Выходные данные стоят 500 × $0,50 / 1 000 000 = $0,00025. Один шаг стоит $0,0007. Запуск из десяти шагов стоит $0,007, а 1000 таких запусков стоят $7,00.
Агенты отправляют свою растущую историю на каждом шаге, поэтому входные токены доминируют. Удаление старых результатов инструментов — самая дешёвая оптимизация, которую вы можете сделать. Неудачные или отклонённые запросы не оплачиваются. Подробности о пополнении и бонусах на странице тарифов.
Распространённые проблемы
- 404 при каждом вызове. Базовый URL должен заканчиваться на
/v1и не должен включать/chat/completions. LangChain добавляет путь самостоятельно. - Модель не найдена. Единственный идентификатор модели —
uncensored. Имена вроде gpt-4o не сработают. - Ошибки контекста. Окно составляет 100 000 токенов для промпта и ответа. Длинные цепочки извлечения могут его превысить. Кратко изложите или сократите данные перед отправкой.
- Запрос слишком большой. Лимит тела составляет 8 МБ, что важно, если вы вставляете целые документы в промпт.
- Сбой эмбеддингов. Этот API предназначен только для текстового чата. Оставьте модель эмбеддингов у другого провайдера и используйте этот эндпоинт для генерации.
Та же схема работает для других фреймворков и интерфейсов чата; раздел руководство по интеграции охватывает больше клиентов. Для любых нестандартных случаев начните со страницы поддержки.
