TH ▾
รับคีย์ API

LangChain + LLM: เชื่อมต่อ API แบบไม่เซ็นเซอร์ แบบไม่เซ็นเซอร์

LangChain เชื่อมต่อกับเอนด์พอยต์ที่เข้ากันได้กับ OpenAI ผ่านคลาส ChatOpenAI ตั้งค่า base URL, คีย์ API และ model ID แล้ว chains และ agents ของคุณจะทำงานบน API นี้

อัปเดต

บล็อกที่เชื่อมโยงกันเป็นลำดับส่งไปยังจุดศูนย์กลางที่เรืองแสง แสดงถึง LangChain pipelines ที่เรียก API เดียวกัน

ประเด็นสำคัญ

  1. ใช้ ChatOpenAI โดยตั้งค่า base_url เป็น API และตั้งค่า model เป็น uncensored
  2. Chains, streaming, การเรียกใช้เครื่องมือ และการส่งออก JSON ล้วนใช้เส้นทาง chat completions มาตรฐาน
  3. จำกัดความพร้อมกันของ batch ไว้ที่ 8 สำหรับคีย์เต็ม หรือ 2 สำหรับคีย์ทดลอง เพื่อหลีกเลี่ยงข้อผิดพลาด 429
  4. นี่คือโมเดลที่โฮสต์แบบเดียว ไม่ใช่ router ดังนั้นจึงไม่มีการสลับโมเดลรายผู้จัดจำหน่าย

การตั้งค่าแบบสั้น

คำถาม langchain + llm ทั่วไปคือว่าคุณต้องการการผสานรวมพิเศษสำหรับเอนด์พอยต์ของบุคคลที่สามหรือไม่ คุณไม่จำเป็นต้องใช้ LangChain's OpenAI chat wrapper ยอมรับ custom base URL และ API นี้ปฏิบัติตามรูปแบบการแชท completions ของ OpenAI ดังนั้นคลาสมาตรฐานจึงใช้งานได้ ติดตั้งแพ็กเกจ ส่งค่าสามค่า และคุณจะมี object โมเดลแชทที่สามารถ drop เข้าไปใน chain ใดๆ ได้

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)

รับคีย์จาก หน้าคีย์ API ผู้ใช้ใหม่สามารถรับ $0.50 ของเครดิตทดลองใช้ที่นั่นด้วยการคลิกหนึ่งครั้งหลังจากการสมัคร ซึ่งเพียงพอที่จะรันทุกอย่างในบทความนี้หลายครั้ง model ID คือ uncensored เสมอ และคำขอไปที่ POST /v1/chat/completions

หมายเหตุเกี่ยวกับชื่อเว็บไซต์: แม้จะมีคำว่า "router" อยู่ในโดเมน นี่คือโมเดล open-weight แบบเดียวที่ให้บริการโดยผู้ให้บริการอิสระ ไม่ใช่ router ระหว่างผู้จัดจำหน่าย และไม่ใช่ API ทางการของผู้จัดจำหน่ายรายใด คุณไม่ได้เลือกระหว่างโมเดลที่นี่ โค้ดของคุณระบุชื่อโมเดลหนึ่งโมเดล และนั่นคือโมเดลที่จะตอบกลับ

เก็บคีย์ออกจากซอร์สโค้ด

การ hardcode คีย์ API ใช้ได้สำหรับการทดสอบครั้งแรก แต่จะกลายเป็นปัญหาเมื่อคุณ commit ไฟล์ครั้งแรก ให้อ่านจาก environment แทน ไลบรารี client ของ OpenAI ที่ LangChain ห่อหุ้มจะมองหา OPENAI_API_KEY และ OPENAI_BASE_URL โดยค่าเริ่มต้น คุณสามารถตั้งค่าใน shell ของคุณและสร้างโมเดลด้วยอาร์กิวเมนต์น้อยลง

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"],
)

การส่ง base URL อย่างชัดเจนดังข้างต้นมีข้อดีอย่างหนึ่ง หากโปรเจกต์อื่นบนเครื่องเดียวกันใช้บริการ OpenAI จริงและพึ่งพาตัวแปร environment เดียวกัน อาร์กิวเมนต์อย่างชัดเจนของคุณจะป้องกันไม่ให้ทั้งสองชนกัน

chain แรกพร้อม prompt template

งานส่วนใหญ่ใช้ prompt template โมเดล และ output parser ที่ต่อกันด้วยตัวดำเนินการ pipe นี่คือสไตล์ LangChain Expression Language และไม่ต้องใช้พิเศษสำหรับเอนด์พอยต์ที่กำหนดเอง

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

โมเดลไม่มีการปฏิเสธเนื้อหาสำหรับการใช้งานผู้ใหญ่ที่ถูกต้องตามกฎหมาย ซึ่งมีความสำคัญเมื่อ chain ของคุณสร้างนิยาย ฉาก roleplay หรือบทสนทนา companion ที่โมเดลระมัดระวังกว่าจะปฏิเสธ กฎเดียวที่ตายตัวคือเนื้อหาทางเพศที่เกี่ยวข้องกับผู้เยาว์จะไม่ถูกสร้างเลย สร้างการตรวจสอบอินพุตของคุณเองเหนือสิ่งนั้นหากผลิตภัณฑ์ของคุณมีกฎที่เข้มงวดกว่า

Streaming และการใช้งาน

API รองรับ streaming ผ่าน server-sent events ด้วย stream: true และ usage จะรายงานที่ท้าย stream ใน LangChain คุณเรียก .stream() และ iterate over chunks

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)

รายละเอียดหนึ่งอย่างที่ต้องจดจำ: การร้องขอแบบ streaming จะใช้ช่องหนึ่งช่องจากช่องความพร้อมใช้งานของคุณจนกว่า stream จะสิ้นสุด หาก UI ของคุณเปิด stream และผู้ใช้เดินจากไปโดยไม่ปิด ช่องนั้นจะยังคงใช้งานอยู่ สำหรับคีย์เต็มคุณมีความพร้อมกัน 8 คำขอพร้อมกัน ดังนั้น stream ที่ทิ้งไว้จำนวนหนึ่งสามารถบล็อกคำขอใหม่ได้ ยกเลิก iterator เมื่อไคลเอนต์ตัดการเชื่อมต่อ

การเรียกใช้ฟังก์ชันและเอเจนต์

รองรับการเรียกใช้ฟังก์ชัน: คุณส่ง tools และ optionally tool_choice โมเดลตอบกลับด้วย tool_calls (ซึ่งสามารถสตรีมได้) และคุณส่งผลลัพธ์กลับเป็นข้อความด้วย role: "tool" ใน LangChain bind_tools จัดการรูปแบบการส่งข้อมูลให้คุณ

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"]))

สำหรับวงจรเอเจนต์แบบเต็ม ตัวช่วย agent ของ LangChain หรือ LangGraph จะรันวงจรนี้ให้คุณ: เรียกโมเดล รันเครื่องมือที่ร้องขอ เพิ่มข้อความเครื่องมือ เรียกอีกครั้ง การใช้งานเครื่องมือปฏิบัติตามรูปแบบมาตรฐานของ OpenAI ดังนั้นโค้ดที่คุณเขียนสำหรับเอนด์พอยต์ที่เข้ากันได้ใดๆ จึงใช้งานได้ เช่นเดียวกับโมเดล open-weight ใดๆ ทดสอบ schema เครื่องมือเฉพาะของคุณของคุณ เก็บชื่ออาร์กิวเมนต์ให้เรียบง่าย คำอธิบายให้สั้น และรายการเครื่องมือให้เล็ก เนื่องจากรายการที่ยาวเกินไปให้โมเดลที่อ่อนแอกว่ามากขึ้นในการเลือกตัวที่ผิด

ผลลัพธ์ที่มีโครงสร้างด้วยโหมด JSON

โหมด JSON มีให้ผ่าน response_format: {"type": "json_object"} ใน LangChain คุณสามารถส่งผ่านเป็นอาร์กิวเมนต์ของโมเดลและแยกวิเคราะห์ผลลัพธ์ด้วยตัวคุณเอง ซึ่งให้คุณควบคุมการตรวจสอบและการลองใหม่

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"])

บอกคำว่า "JSON" ในพรอมต์และอธิบายคีย์ที่คุณต้องการ โหมด JSON ทำให้การส่งออกเป็น JSON ที่ถูกต้อง แต่ไม่รับประกันรูปแบบที่แน่นอนของคุณ ดังนั้นตรวจสอบคีย์หลังจากการแยกวิเคราะห์และลองใหม่เมื่อล้มเหลว เนื่องจากคำขอที่ล้มเหลวไม่มีการเรียกเก็บเงิน วงจรการลองใหม่สำหรับผลลัพธ์ที่มีรูปแบบไม่ถูกต้องจึงมีต้นทุนต่ำ

ความพร้อม การลองใหม่ และขีดจำกัดอัตรา

LangChain ทำให้การกระจายงานด้วย .batch() ง่าย และนั่นคือจุดที่ผู้คนส่วนใหญ่ชนกับขีดจำกัดอัตราแรก คีย์เต็มอนุญาตให้มีความพร้อมกัน 8 คำขอพร้อมกันและ 300 คำขอต่อนาที คีย์ทดลองอนุญาตให้มีความพร้อมกัน 2 คำขอพร้อมกันและ 60 ต่อนาที หากเกิน API จะตอบกลับด้วย HTTP 429 รหัสข้อผิดพลาดคือ rate_limited เมื่อคุณเกินคำขอต่อนาที และ concurrency เมื่อคำขอจำนวนมากทำงานพร้อมกัน ในการโอเวอร์โหลดชั่วคราวคุณยังได้รับ 429 พร้อมส่วนหัว Retry-After: 5

ตั้งค่าความพร้อมของ batch ด้วยตนเอง และให้ไคลเอนต์ลองใหม่ด้วยการถอยหลัง:

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

การตั้งค่าค่าความพร้อมกันที่ 6 สำหรับคีย์เต็มจะเหลือพื้นที่สำหรับคำขออื่นจากบัญชีเดียวกัน สำหรับคีย์ทดลองใช้ให้ใช้ค่า 2 หากยังพบข้อผิดพลาด concurrency ให้ตรวจสอบสตรีมที่ยังไม่เสร็จสิ้น เนื่องจากแต่ละสตรีมจะครอบครองสล็อตหนึ่งสล็อต แต่ละการตอบกลับมี X-Request-Id ซึ่งเป็นค่าที่ต้องระบุเมื่อติดต่อฝ่ายสนับสนุน และ X-Balance-USD ซึ่งแสดงเครดิตคงเหลือของคุณ

การเรียกแบบ Async สำหรับเว็บแอป

ภายในเว็บเซิร์ฟเวอร์คุณมักไม่ต้องการการเรียกแบบ blocking ทุกโมเดลแชทของ LangChain มีฟังก์ชันแบบอะซิงโครนัสคู่กับฟังก์ชันปกติ ได้แก่ ainvoke, astream และ abatch และทำงานกับเอนด์พอยต์นี้เหมือนกับเวอร์ชันแบบซิงโครนัส

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())

ในบริการแบบอะซิงโครนัส ให้ควบคุมจำนวนการเรียกใช้งานที่กำลังดำเนินการอยู่ด้วยเซมาโฟร์ที่มีขนาดตามคีย์ของคุณ เช่น 8 สำหรับคีย์เต็ม สิ่งนี้จะป้องกันเอนด์พอยต์ที่ยุ่งของแอปพลิเคชันคุณจากการครอบครองสล็อตทั้งหมดและทำให้คำขออื่นขาดแคลน สกัดข้อยกเว้นรอบการเรียกใช้งาน บันทึกส่วนหัว X-Request-Id เมื่อมี และแสดงข้อความลองใหม่สั้นๆ ให้ผู้ใช้แทนที่จะแสดง stack trace

เคล็ดลับการดีบัก: หากเชนทำงานผิดปกติ ให้พิมพ์ข้อความที่โมเดลได้รับอย่างแม่นยำ เทมเพลตพรอมต์บางครั้งแทรกช่องว่างเพิ่มเติมหรือละตัวแปร และโมเดลสามารถตอบได้เฉพาะสิ่งที่ได้รับเท่านั้น สวิตช์ verbose และ debug ของ LangChain หรือการติดตาม LangSmith หากคุณใช้งานอยู่แล้ว จะแสดงรายการข้อความสุดท้าย

ความหมายของหน้าต่างบริบทสำหรับเชน

หน้าต่างบริบทมีขนาด 100,000 โทเคนสำหรับพรอมต์และ completion รวมกัน และ max_tokens เป็นตัวเลือก มันมีขนาดใหญ่พอสำหรับ retrieval chains ที่บรรจุเอกสารจำนวนมากลงในพรอมต์เดียว หรือสำหรับหน่วยความจำการสนทนาที่เก็บประวัติระยะยาว มันมีขนาดใหญ่พอจนทำให้เสียเงินหากคุณส่งประวัติเต็มรูปแบบในทุกขั้นตอนโดยไม่มีการตัดทอน

การคำนวณอย่างรวดเร็ว ขั้นตอนการดึงข้อมูลที่ส่ง input tokens จำนวน 12,000 และรับกลับ 800 มีค่าใช้จ่าย 0.012 x $0.15 + 0.0008 x $0.50 = $0.0018 + $0.0004 = $0.0022 หากดำเนินการนั้น 1,000 ครั้ง คุณจะจ่าย $2.20 อัตราค่าบริการอยู่ที่ $0.15 ต่อ input tokens 1 ล้าน และ $0.50 ต่อ output tokens 1 ล้าน โดยไม่มี subscription ดังนั้นคุณจ่ายเฉพาะสิ่งที่ chain ใช้จริง หน้า ราคา มีตัวเลือกการเติมเงิน และเอกสาร เริ่มต้นอย่างรวดเร็ว ระบุรายการพารามิเตอร์ที่รองรับทั้งหมด พรอมต์ไม่ได้ถูกใช้สำหรับการฝึก

ถาม-ตอบ

ฉันต้องการแพ็คเกจ LangChain พิเศษสำหรับเอนด์พอยต์นี้หรือไม่?

ไม่ แพ็คเกจ langchain-openai เพียงพอ ส่ง base URL, คีย์ของคุณและ model ID uncensored ไปยัง ChatOpenAI

มันทำงานกับ LangGraph และ agents ได้หรือไม่?

ใช่ ตราบใดที่พวกเขาใช้รูปแบบแชทและการเรียกใช้เครื่องมือมาตรฐานของ OpenAI การเรียกใช้เครื่องมือ (tool calls), streamed tool_calls และ role tool results รองรับ

ฉันสามารถสลับระหว่างโมเดลภายในเชนได้หรือไม่?

ไม่ มีโมเดลเดียวคือ uncensored และบริการไม่ใช่ตัวกระจายเส้นทางข้ามผู้ให้บริการ ใช้วัตถุโมเดล LangChain แยกหากต้องการผู้ให้บริการอื่นสำหรับขั้นตอนอื่น

ฉันควรจัดการกับข้อผิดพลาด 429 อย่างไร?

ลด concurrency ของ batch, ปฏิบัติตามส่วนหัว Retry-After เมื่อมี และตรวจสอบให้แน่ใจว่าสตรีมที่เสร็จสมบูรณ์ถูกปิด คีย์แบบเต็มอนุญาตให้มีความพร้อมกัน 8 คำขอและ 300 ต่อนาที

embeddings มีให้สำหรับ vector store ของฉันหรือไม่?

ไม่ API เป็นข้อความเท่านั้นและไม่มีเอนด์พอยต์ embeddings ดังนั้นคุณต้องการแหล่ง embeddings แยกสำหรับการดึงข้อมูล

คีย์ของคุณอยู่ห่างแค่แบบฟอร์มเดียว

สร้างบัญชี คัดลอกคีย์ และเปลี่ยน base URL นั่นคือการตั้งค่าทั้งหมด

รับคีย์ API