Poin utama
- Gunakan ChatOpenAI dengan base_url diatur ke URL dasar API dan model diatur ke uncensored.
- Rantai, streaming, pemanggilan fungsi, dan output JSON semuanya melalui rute penyelesaian chat standar.
- Batasi konkurensi batch di 8 untuk kunci penuh, atau 2 untuk kunci uji coba, untuk menghindari error 429.
- Ini adalah satu model yang di-hosting, bukan router, jadi tidak ada penggantian model per vendor.
Pengaturan singkat
Pertanyaan umum langchain + llm adalah apakah Anda memerlukan integrasi khusus untuk endpoint pihak ketiga. Anda tidak memerlukannya. Wrapper chat OpenAI LangChain menerima URL dasar kustom, dan API ini mengikuti format penyelesaian chat OpenAI, sehingga kelas standar berfungsi. Instal paketnya, masukkan tiga nilai, dan Anda memiliki objek model chat yang dapat dimasukkan ke dalam rantai apa pun.
pip install -U langchain-openai langchain-core
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="uncensored",
base_url="https://api.nsfwllmrouter.com/v1",
api_key="YOUR_API_KEY",
temperature=0.7,
)
print(llm.invoke("Give me one sentence about LangChain.").content)
Dapatkan kunci dari halaman kunci API. Pengguna baru dapat mengklaim kredit uji coba senilai $0,50 di sana dengan satu klik setelah masuk, yang cukup untuk menjalankan semuanya di artikel ini berkali-kali. ID model selalu uncensored, dan permintaan dikirim ke POST /v1/chat/completions.
Sebuah catatan tentang nama situs: meskipun ada kata "router" dalam domain, ini adalah model bobot terbuka tunggal yang dijalankan oleh penyedia independen, bukan router antar vendor dan bukan API resmi vendor mana pun. Anda tidak memilih di antara model di sini. Kode Anda menamai satu model, dan itulah yang menjawab.
Jauhkan kunci dari sumber
Mengodekan kunci secara langsung berfungsi untuk pengujian pertama dan menjadi masalah saat Anda mengompilasi file untuk pertama kalinya. Bacalah dari lingkungan. Perpustakaan klien OpenAI yang dibungkus LangChain mencari OPENAI_API_KEY dan OPENAI_BASE_URL secara default, sehingga Anda dapat mengaturnya di shell Anda dan membuat model dengan lebih sedikit argumen.
export OPENAI_API_KEY="YOUR_API_KEY"
export OPENAI_BASE_URL="https://api.nsfwllmrouter.com/v1"
import os
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="uncensored",
base_url=os.environ.get("OPENAI_BASE_URL", "https://api.nsfwllmrouter.com/v1"),
api_key=os.environ["OPENAI_API_KEY"],
)
Memasukkan base URL secara eksplisit, seperti di atas, memiliki satu keunggulan. Jika proyek lain di mesin yang sama menggunakan layanan OpenAI asli dan bergantung pada variabel lingkungan yang sama, argumen eksplisit Anda mencegah keduanya bertabrakan.
Rantai pertama dengan template prompt
Sebagian besar pekerjaan nyata menggunakan template prompt, model, dan parser output yang digabungkan dengan operator pipa. Ini adalah gaya Bahasa Ekspresi LangChain, dan tidak memerlukan apa pun khusus untuk endpoint kustom.
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="uncensored",
base_url="https://api.nsfwllmrouter.com/v1",
api_key="YOUR_API_KEY",
)
prompt = ChatPromptTemplate.from_messages([
("system", "You write short story openings in the style the user asks for."),
("human", "Genre: {genre}\nSetting: {setting}\nWrite three sentences."),
])
chain = prompt | llm | StrOutputParser()
print(chain.invoke({"genre": "noir mystery", "setting": "a rainy harbor town"}))
Model ini tidak memiliki penolakan konten untuk penggunaan dewasa yang sah, yang penting ketika rantai Anda menghasilkan fiksi, adegan roleplay, atau dialog teman yang akan ditolak oleh model yang lebih hati-hati. Satu aturan tetapnya adalah bahwa konten seksual yang melibatkan anak di bawah umur tidak pernah dihasilkan. Bangun validasi input Anda sendiri di atas itu jika produk Anda memiliki aturan yang lebih ketat.
Streaming dan penggunaan
API mendukung streaming melalui peristiwa yang dikirim server dengan stream: true, dan penggunaan dilaporkan di akhir stream. Di LangChain, Anda memanggil .stream() dan mengiterasi potongan-potongan.
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="uncensored",
base_url="https://api.nsfwllmrouter.com/v1",
api_key="YOUR_API_KEY",
)
for chunk in llm.stream("Write a four-line poem about debugging at night."):
print(chunk.content, end="", flush=True)
Satu hal yang perlu diingat: permintaan streaming menempati salah satu slot konkurensi Anda hingga stream berakhir. Jika UI Anda membuka stream dan pengguna pergi tanpa menutupnya, slot itu tetap sibuk. Pada kunci penuh Anda memiliki 8 permintaan paralel, sehingga beberapa stream yang dibiarkan terbengkalai dapat memblokir yang baru. Batalkan iterator saat klien terputus.
Pemanggilan alat dan agen
Pemanggilan alat didukung: Anda meneruskan tools dan opsional tool_choice, model membalas dengan tool_calls (yang juga dapat di-streaming), dan Anda mengirim hasil kembali sebagai pesan dengan role: "tool". Di LangChain, bind_tools menangani format kabel untuk Anda.
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
@tool
def word_count(text: str) -> int:
'Count the words in a piece of text.'
return len(text.split())
llm = ChatOpenAI(
model="uncensored",
base_url="https://api.nsfwllmrouter.com/v1",
api_key="YOUR_API_KEY",
)
llm_with_tools = llm.bind_tools([word_count])
msg = llm_with_tools.invoke("How many words are in: the quick brown fox?")
for call in msg.tool_calls:
print(call["name"], call["args"], word_count.invoke(call["args"]))
Untuk loop agen penuh, bantuan agen LangChain atau LangGraph menjalankan siklus ini untuk Anda: panggil model, jalankan alat yang diminta, lampirkan pesan alat, panggil lagi. Penggunaan alat mengikuti bentuk OpenAI standar, sehingga kode yang sama yang akan Anda tulis untuk endpoint kompatibel apa pun berfungsi. Seperti halnya model bobot terbuka apa pun, uji skema alat spesifik Anda. Pertahankan nama argumen yang sederhana, deskripsi singkat, dan daftar alat kecil, karena daftar panjang memberi model yang lebih lemah lebih banyak ruang untuk memilih yang salah.
Output terstruktur dengan mode JSON
Mode JSON tersedia melalui response_format: {"type": "json_object"}. Di LangChain Anda dapat meneruskannya sebagai argumen model dan menguraikan hasilnya sendiri, yang memberi Anda kendali atas validasi dan percobaan ulang.
import json
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="uncensored",
base_url="https://api.nsfwllmrouter.com/v1",
api_key="YOUR_API_KEY",
model_kwargs={"response_format": {"type": "json_object"}},
)
msg = llm.invoke(
"Return a JSON object with keys title and tags (a list of three strings) "
"for an article about hiking."
)
data = json.loads(msg.content)
print(data["title"], data["tags"])
Katakan kata "JSON" dalam prompt dan jelaskan kunci yang Anda inginkan. Mode JSON membuat output valid JSON, tetapi tidak menjamin skema Anda yang tepat, jadi periksa kunci setelah penguraian dan coba lagi jika gagal. Karena permintaan yang gagal tidak dikenakan biaya, loop retry untuk output yang terstruktur salah memakan biaya sedikit.
Konkurensi, retry, dan batas laju
LangChain memudahkan Anda untuk menyebarkan pekerjaan dengan .batch(), dan di situlah kebanyakan orang mencapai batas laju pertama mereka. Kunci penuh mengizinkan 8 permintaan paralel dan 300 permintaan per menit. Kunci uji coba mengizinkan 2 permintaan paralel dan 60 per menit. Lewati batas dan API membalas dengan HTTP 429. Kode error adalah rate_limited saat Anda melebihi permintaan per menit, dan concurrency saat terlalu banyak permintaan berjalan bersamaan. Saat kelebihan beban sementara Anda juga mendapatkan 429 dengan header Retry-After: 5.
Atur konkurensi batch Anda sendiri, dan biarkan klien mencoba lagi dengan backoff:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="uncensored",
base_url="https://api.nsfwllmrouter.com/v1",
api_key="YOUR_API_KEY",
max_retries=4,
timeout=120,
)
inputs = [f"Summarize idea number {i} in one line." for i in range(40)]
results = llm.batch(inputs, config={"max_concurrency": 6})
print(len(results))
Tetap di 6 pada kunci penuh memberikan ruang untuk permintaan lain dari akun yang sama. Pada kunci uji coba gunakan 2. Jika Anda masih melihat error concurrency, carilah streaming yang tidak pernah selesai, karena setiap streaming memegang slot. Setiap respons membawa X-Request-Id, yang merupakan nilai yang dikutip jika Anda menghubungi dukungan, dan X-Balance-USD, yang menunjukkan sisa kredit Anda.
Panggilan async untuk aplikasi web
Di dalam server web Anda jarang menginginkan panggilan blokir. Setiap model chat LangChain memiliki kembaran asinkron dari metodenya, bernama ainvoke, astream dan abatch, dan mereka bekerja terhadap endpoint ini sama seperti versi sinkronnya.
import asyncio
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="uncensored",
base_url="https://api.nsfwllmrouter.com/v1",
api_key="YOUR_API_KEY",
)
async def main():
async for chunk in llm.astream("Describe a quiet harbor at dawn in two sentences."):
print(chunk.content, end="", flush=True)
asyncio.run(main())
Dalam layanan asinkron, jaga jumlah panggilan yang sedang berjalan dengan semafor yang ukurannya disesuaikan dengan kunci Anda, misalnya 8 pada kunci penuh. Itu menjaga satu endpoint sibuk dari aplikasi Anda sendiri tidak memenuhi setiap slot dan membuat yang lain kelaparan. Tangani pengecualian di sekitar panggilan, log header X-Request-Id saat Anda memilikinya, dan tampilkan pesan percobaan ulang singkat kepada pengguna alih-alih jejak tumpukan.
Tips debugging: jika rantai berperilaku aneh, cetak pesan tepat yang diterima model. Template prompt terkadang menyisipkan spasi ekstra atau kehilangan variabel, dan model hanya dapat menjawab apa yang dikirim kepadanya. Sakelar verbose dan debug LangChain, atau pelacakan LangSmith jika Anda sudah menggunakannya, menampilkan daftar pesan akhir.
Apa arti jendela konteks untuk rantai
Jendela konteks adalah 100.000 token untuk prompt dan penyelesaian bersama-sama, dan max_tokens adalah opsional. Itu cukup besar untuk rantai pengambilan yang memasukkan banyak dokumen ke dalam satu prompt, atau untuk memori percakapan yang menyimpan riwayat panjang. Itu juga cukup besar untuk menjadi mahal jika Anda mengirim ulang seluruh riwayat setiap giliran tanpa memangkasnya.
Perhitungan cepat. Langkah pengambilan yang mengirim 12.000 token input dan mendapatkan 800 kembali biayanya 0,012 x $0,15 + 0,0008 x $0,50 = $0,0018 + $0,0004 = $0,0022. Jalankan itu 1.000 kali dan Anda membayar $2,20. Penetapan harga adalah $0,15 per 1M token input dan $0,50 per 1M token output, tanpa langganan, sehingga Anda hanya membayar untuk apa yang sebenarnya digunakan rantai. Halaman penetapan harga memiliki opsi isi saldo, dan dokumen pengenalan cepat mencantumkan setiap parameter yang didukung. Prompt tidak digunakan untuk pelatihan.
