Krótka odpowiedź: trzy ustawienia w ChatOpenAI
Jeśli szukałeś chat open ai langchain, prawdopodobnie masz projekt LangChain, który już używa ChatOpenAI i chcesz, aby rozmawiał z innym backendem. To zmiana konfiguracji, a nie przepisania. API na tej stronie obsługuje protokół uzupełnień czatu OpenAI, więc LangChain traktuje go jako dowolny inny serwer w stylu OpenAI.
Potrzebujesz Base URL, swojego klucza API i identyfikatora modelu uncensored. Najpierw zainstaluj pakiety:
pip install -U langchain-openai langgraphNastępnie stwórz obiekt modelu:
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)To cała integracja. Każda funkcja LangChain oparta na ChatOpenAI działa teraz na modelu bez cenzury: łańcuchy, retrievery wywołujące model czatu, parsery wyjścia i agenci. Jeśli nie masz jeszcze klucza API, strona klucz API wyjaśnia sposób rejestracji i jednorazowy kredyt próbny.
Trzymaj klucz z dala od kodu
Umieść klucz w zmiennej środowiskowej i odczytuj go przy starcie. W Linux lub macOS:
export NOFILTER_API_KEY="paste-your-key-here"Stwórz jeden wspólny moduł klienta dla projektu, na przykład llm.py, który buduje model raz i go eksportuje. Każdy łańcuch importuje ten sam obiekt, a późniejsza zmiana klucza, timeoutu lub temperatury następuje w jednym miejscu. Ułatwia to też utrzymanie drugiej, zimniejszej instancji dla kroków narzędzi i cieplejszej do pisania kreatywnego, obu wskazujących na ten sam endpoint z różnymi ustawieniami.
Jedna pułapka łapie wielu ludzi: ChatOpenAI odczytuje też OPENAI_API_KEY i OPENAI_API_BASE ze środowiska. Jeśli te zmienne są ustawione dla innego projektu, półskonfigurowany obiekt może wysłać twoje zapytanie na zły serwer. Jawne przekazanie base_url i api_key, jak wyżej, usuwa niejednoznaczność.
Możesz potwierdzić połączenie bez LangChain w ogóle. Endpoint modeli powinien zwrócić pojedynczy wpis:
curl https://api.nofilteraichat.com/v1/models \
-H "Authorization: Bearer $NOFILTER_API_KEY"Jeśli to działa, ale LangChain zawodzi, problem jest w twoim środowisku Python, a nie w kluczu. Jeśli oba zawiodą z 401, sprawdź przypadkową spację lub znak nowej linii w kluczu. quickstart zawiera dokładny format żądania do porównania.
Strumieniowanie i użycie tokenów
Interfejsy czatu działają lepiej, gdy tokeny pojawiają się w miarę ich generowania. LangChain udostępnia to przez .stream(), a serwer wysyła standardowe fragmenty SSE, gdy stream: true jest ustawione pod spodem.
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)Dzięki stream_usage=True ostatni fragment zawiera liczbę tokenów wejściowych i wyjściowych, które API wysyła na końcu strumienia. Zapisz te liczby. To najtańszy sposób na sprawdzenie, ile naprawdę kosztuje agent, i używamy ich w sekcji kosztów poniżej.
Jedna rzecz do zapamiętania: zapytanie strumieniowe zajmuje swój slot współbieżności do momentu zakończenia strumienia. Jeśli porzucisz strumień bez jego zamknięcia, ten slot pozostanie zajęty dłużej, niż się spodziewasz.
Node i TypeScript
Pakiet JavaScript używa nieco innej nazwy opcji. Base URL znajduje się wewnątrz 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);Typy TypeScript dla odpowiedzi to zwykłe klasy komunikatów LangChain, więc istniejący kod, który czyta res.content lub res.usage_metadata, nadal działa. Gdy uruchamiasz to wewnątrz trasy serwera, zbuduj model raz w zakresie modułu, a nie dla każdego zapytania. Zapobiega to tworzeniu nowego klienta HTTP dla każdego wywołania i utrzymuje przejrzystość współbieżności.
Wszystko inne, w tym .stream(), .bindTools() i .withStructuredOutput(), działa tak samo jak w Pythonie. Temperatura, top_p, sekwencje stop, seed i opcje kar są przekazywane do modelu, więc możesz je ustawić w konstruktorze tak, jak w przypadku dowolnego innego backendu w stylu OpenAI.
Wywoływanie narzędzi i mały agent
API obsługuje wywoływanie narzędzi: pola tools i tool_choice, strumieniowane tool_calls i wyniki narzędzi zwracane jako wiadomości role: "tool". Gotowy agent LangGraph używa dokładnie tej pętli. Oto agent z jednym narzędziem:
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)Używanie narzędzi z modelami o otwartych wagach jest mniej przewidywalne niż z flagowym modelem hostowanym, więc traktuj to jako coś do przetestowania. Napisz opisy narzędzi prostymi słowami, trzymaj schematy argumentów małe i ustaw temperature nisko (0,2 do 0,4) dla kroków agenta, które muszą wyprodukować poprawne argumenty. Jeśli wywołanie zwróci się niepoprawnie, LangChain zgłasza to jako nieprawidłowe wywołanie narzędzia, a ponowne wywołanie z wyraźniejszym opisem zwykle to naprawia.
Utrzymuj pętlę agenta w granicach. LangGraph ma limit rekurencji i powinieneś ustawić go na liczbę, którą możesz sobie pozwolić. Jeśli agent może wywoływać narzędzia w nieskończoność, zły prompt może spalić kredyt, gdy jesteś poza klawiaturą. Limit 10 do 15 kroków to rozsądny domyślny wybór dla większości zadań, i możesz go przekazać w konfiguracji przy wywołaniu agenta.
Wynik strukturalny
Tryb JSON jest dostępny przez response_format. W LangChain poproś o to metodą trybu JSON i nazwij klucze w swoim 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."
))Limity zapytań, ponawianie i koszty
Pełny klucz pozwala na 8 równoległych zapytań i 300 zapytań na minutę. Klucz próbny pozwala na 2 i 60. Gdy przekroczysz którykolwiek z tych limitów, API odpowiada kodem HTTP 429 i kodem błędu: rate_limited dla zapytań na minutę, concurrency dla zbyt dużej liczby naraz. Tymczasowe przeciążenie również zwraca 429, z nagłówkiem Retry-After: 5.
LangChain daje ci dwa suwaki dla tego. max_retries w modelu ponawia nieudane wywołania z backoff, a max_concurrency w konfiguracji uruchomienia ogranicza równoległą pracę wsadową:
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},
)Ustawienie max_concurrency na 6 dla pełnego klucza zostawia margines dla drugiego procesu. Pamiętaj, że każdy krok agenta to osobne zapytanie, a strumieniowany krok zajmuje swój slot do końca strumienia.
Ile kosztuje uruchomienie agenta
Ceny to $0,15 za 1M tokenów wejściowych i $0,50 za 1M tokenów wyjściowych. Załóżmy, że krok agenta wysyła 3000 tokenów historii, narzędzi i instrukcji, a model pisze 500 tokenów. Wejście kosztuje 3000 × $0,15 / 1 000 000 = $0,00045. Wyjście kosztuje 500 × $0,50 / 1 000 000 = $0,00025. Jeden krok to $0,0007. Uruchomienie na 10 kroków to $0,007, a 1000 takich uruchomień kosztuje $7,00.
Agenci ponownie wysyłają swoją rosnącą historię na każdym kroku, więc tokeny wejściowe dominują. Przycinanie starego wyniku narzędzia to najtańsza optymalizacja, jaką masz. Nieudalne lub odrzucone żądania nie są rozliczane. Szczegóły doładowań i bonusów znajdziesz na stronie z cenami.
Typowe problemy
- 404 przy każdym wywołaniu. Podstawowy URL musi kończyć się na
/v1i nie może zawierać/chat/completions. LangChain dodaje tę ścieżkę samodzielnie. - Model nie znaleziony. Jedynym identyfikatorem modelu jest
uncensored. Nazwy takie jak gpt-4o nie zadziałają. - Błędy okna kontekstu. Okno ma 100 000 tokenów dla promptu plus uzupełnienia. Długie łańcuchy pobierania mogą go przekroczyć. Podsumuj lub przytnij przed wysłaniem.
- Zapytanie za duże. Limit ciała to 8 MB, co ma znaczenie, jeśli wciskasz całe dokumenty do promptu.
- Embeddingi zawiodą. To API to tylko czat tekstowy. Trzymaj swój model embeddingów u innego dostawcy i używaj tego endpointa do generowania.
Ten sam schemat działa dla innych frameworków i interfejsów czatu; przewodnik integracji obejmuje więcej klientów. W przypadku nietypowych przypadków strona wsparcia jest miejscem, od którego warto zacząć.
