VI ▾
Lấy khóa API

LangChain + LLM: Kết nối API không kiểm duyệt

LangChain giao tiếp với bất kỳ endpoint tương thích OpenAI nào thông qua lớp ChatOpenAI của nó. Bạn đặt base URL, khóa và model ID, và các chuỗi và agents của bạn chạy trên API này.

Cập nhật

Các khối liên kết tạo thành chuỗi cung cấp cho một trung tâm phát sáng, đại diện cho các pipeline LangChain gọi một API

Điểm chính

  1. Sử dụng ChatOpenAI với base_url được đặt thành API và model được đặt thành uncensored.
  2. Chuỗi, truyền phát, gọi hàm và xuất JSON đều đi qua tuyến hoàn thành chat chuẩn.
  3. Giới hạn độ đồng thời của batch ở mức 8 trên khóa đầy đủ, hoặc 2 trên khóa dùng thử, để tránh lỗi 429.
  4. Đây là một mô hình được lưu trữ, không phải bộ định tuyến, nên không có việc chuyển đổi mô hình theo nhà cung cấp.

Cài đặt ngắn

Câu hỏi langchain + llm thông thường là liệu bạn có cần tích hợp đặc biệt cho endpoint của bên thứ ba không. Bạn không cần. Lớp bao chat OpenAI của LangChain chấp nhận base URL tùy chỉnh, và API này tuân theo định dạng hoàn thành chat của OpenAI, vì vậy lớp tiêu chuẩn hoạt động. Cài đặt gói, truyền ba giá trị, và bạn có một đối tượng mô hình chat mà bạn có thể đưa vào bất kỳ chuỗi nào.

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)

Lấy khóa từ trang khóa API. Người dùng mới có thể nhận $0.50 tín dụng dùng thử chỉ với một cú nhấp chuột sau khi đăng nhập, đủ để chạy mọi thứ trong bài viết này nhiều lần. ID mô hình luôn là uncensored, và yêu cầu được gửi đến POST /v1/chat/completions.

Một lưu ý về tên trang web: bất chấp từ "router" trong tên miền, đây là một mô hình trọng số mở được chạy bởi một nhà cung cấp độc lập, không phải là bộ định tuyến giữa các nhà cung cấp và không phải là API chính thức của bất kỳ nhà cung cấp nào. Bạn không chọn giữa các mô hình ở đây. Mã của bạn đặt tên cho một mô hình, và đó là mô hình sẽ trả lời.

Giữ khóa ra khỏi mã nguồn

Gán cứng khóa hoạt động cho lần kiểm tra đầu tiên và trở thành vấn đề vào lần đầu tiên bạn commit tệp. Hãy đọc nó từ môi trường thay thế. Các thư viện khách hàng OpenAI mà LangChain bao bọc tìm kiếm OPENAI_API_KEY và OPENAI_BASE_URL theo mặc định, vì vậy bạn có thể đặt chúng trong shell của bạn và xây dựng mô hình với ít đối số hơn.

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

Việc truyền base URL rõ ràng, như ở trên, có một lợi thế. Nếu một dự án khác trên cùng máy sử dụng dịch vụ OpenAI thực và dựa vào biến môi trường cùng tên, đối số rõ ràng của bạn ngăn ngừa sự xung đột giữa hai thứ.

Một chuỗi đầu tiên với mẫu prompt

Hầu hết công việc thực tế sử dụng một mẫu prompt, mô hình và trình phân tích đầu ra được nối với nhau bằng toán tử pipe. Đây là phong cách Ngôn ngữ Biểu thức LangChain, và nó không cần gì đặc biệt cho endpoint tùy chỉnh.

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

Mô hình không từ chối nội dung cho việc sử dụng người trưởng thành hợp pháp, điều này quan trọng khi chuỗi của bạn tạo ra truyện, cảnh đóng vai hoặc hội thoại người bạn mà một mô hình thận trọng hơn sẽ từ chối. Quy tắc cố định duy nhất là nội dung tình dục liên quan đến người chưa thành niên không bao giờ được tạo ra. Bạn xây dựng xác thực đầu vào của riêng mình dựa trên điều đó nếu sản phẩm của bạn có quy tắc nghiêm ngặt hơn.

Truyền phát và sử dụng

API hỗ trợ truyền phát qua các sự kiện do máy chủ gửi với stream: true, và việc sử dụng được báo cáo ở cuối stream. Trong LangChain, bạn gọi .stream() và lặp qua các chunk.

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)

Một chi tiết cần ghi nhớ: một yêu cầu truyền phát chiếm một trong các khe đồng thời của bạn cho đến khi stream kết thúc. Nếu giao diện người dùng của bạn mở một stream và người dùng đi mà không đóng nó, khe đó vẫn bận. Trên khóa đầy đủ, bạn có 8 yêu cầu đồng thời, vì vậy một vài stream bị bỏ rơi có thể chặn các yêu cầu mới. Hủy trình lặp khi khách hàng ngắt kết nối.

Gọi công cụ và agent

Gọi hàm được hỗ trợ: bạn truyền tools và tùy chọn tool_choice, mô hình trả lời với tool_calls (cũng có thể được truyền phát), và bạn gửi kết quả lại dưới dạng tin nhắn với role: "tool". Trong LangChain, bind_tools xử lý định dạng dây cho bạn.

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

Đối với vòng lặp agent đầy đủ, các trợ giúp agent của LangChain hoặc LangGraph sẽ tự động chạy chu kỳ này cho bạn: gọi mô hình, chạy công cụ được yêu cầu, đính kèm tin nhắn công cụ, gọi lại. Việc sử dụng công cụ tuân theo định dạng chuẩn của OpenAI, vì vậy cùng mã bạn sẽ viết cho bất kỳ endpoint tương thích nào đều hoạt động. Như với bất kỳ mô hình trọng số mở nào, hãy kiểm tra các lược đồ công cụ cụ thể của bạn. Giữ tên đối số đơn giản, mô tả ngắn gọn và danh sách công cụ nhỏ, vì danh sách dài cung cấp cho các mô hình yếu hơn nhiều không gian hơn để chọn cái sai.

Đầu ra có cấu trúc với chế độ JSON

Chế độ JSON có sẵn thông qua response_format: {"type": "json_object"}. Trong LangChain, bạn có thể truyền nó dưới dạng đối số mô hình và tự phân tích kết quả, điều này cho bạn quyền kiểm soát xác thực và thử lại.

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

Hãy nói từ "JSON" trong prompt và mô tả các khóa bạn muốn. Chế độ JSON làm cho đầu ra là JSON hợp lệ, nhưng nó không đảm bảo lược đồ chính xác của bạn, vì vậy hãy kiểm tra các khóa sau khi phân tích và thử lại khi thất bại. Vì các yêu cầu thất bại không bị tính phí, vòng lặp thử lại cho đầu ra bị lỗi tốn kém rất ít.

Độ đồng thời, thử lại và giới hạn tốc độ

LangChain giúp dễ dàng phân tán công việc với .batch(), và đó là nơi hầu hết mọi người gặp phải giới hạn tốc độ đầu tiên của họ. Khóa đầy đủ cho phép 8 yêu cầu đồng thời và 300 yêu cầu mỗi phút. Khóa dùng thử cho phép 2 yêu cầu đồng thời và 60 yêu cầu mỗi phút. Vượt quá và API trả về HTTP 429. Mã lỗi là rate_limited khi bạn vượt quá yêu cầu mỗi phút, và concurrency khi quá nhiều yêu cầu chạy cùng lúc. Trên quá tải tạm thời, bạn cũng nhận được 429 với tiêu đề Retry-After: 5.

Bạn đặt độ đồng thời của batch của riêng mình, và để khách hàng thử lại với 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))

Giữ ở mức 6 trên khóa đầy đủ để lại khoảng trống cho các yêu cầu khác từ cùng tài khoản. Trên khóa dùng thử hãy sử dụng 2. Nếu bạn vẫn thấy lỗi concurrency, hãy tìm các stream chưa bao giờ kết thúc, vì mỗi stream giữ một khe. Mỗi phản hồi mang theo X-Request-Id, là giá trị để trích dẫn nếu bạn liên hệ hỗ trợ, và X-Balance-USD, hiển thị tín dụng còn lại của bạn.

Gọi không đồng bộ cho ứng dụng web

Bên trong máy chủ web, bạn hiếm khi muốn gọi chặn. Mọi mô hình chat LangChain đều có các phương thức không đồng bộ tương ứng của các phương thức của nó, được đặt tên là ainvoke, astream và abatch, và chúng hoạt động với endpoint này giống như các phiên bản đồng bộ.

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

Trong dịch vụ không đồng bộ, hãy bảo vệ số lượng cuộc gọi đang chạy với một semaphore có kích thước bằng khóa của bạn, ví dụ 8 trên khóa đầy đủ. Điều đó giữ cho một endpoint bận của ứng dụng của bạn không lấp đầy mọi khe và làm đói các khe khác. Bắt các ngoại lệ xung quanh cuộc gọi, ghi lại tiêu đề X-Request-Id khi bạn có nó, và hiển thị cho người dùng một thông báo thử lại ngắn thay vì dấu vết ngăn xếp.

Mẹo gỡ lỗi: nếu một chuỗi hoạt động kỳ lạ, hãy in chính xác các tin nhắn mà mô hình nhận được. Các mẫu prompt đôi khi chèn khoảng trắng bổ sung hoặc bỏ qua một biến, và mô hình chỉ có thể trả lời những gì nó được gửi. Các chế độ verbose và debug của LangChain, hoặc theo dõi LangSmith nếu bạn đã sử dụng nó, hiển thị danh sách tin nhắn cuối cùng.

Cửa sổ ngữ cảnh có ý nghĩa gì đối với chuỗi

Cửa sổ ngữ cảnh là 100,000 token cho prompt và hoàn thành cùng nhau, và max_tokens là tùy chọn. Điều đó đủ lớn cho các chuỗi truy xuất nhồi nhiều tài liệu vào một prompt, hoặc cho bộ nhớ hội thoại giữ lịch sử dài. Nó cũng đủ lớn để trở nên đắt đỏ nếu bạn gửi lại toàn bộ lịch sử mỗi lần mà không cắt giảm.

Một phép tính nhanh. Một bước truy xuất gửi 12.000 token đầu vào và nhận lại 800 tốn 0,012 x $0,15 + 0,0008 x $0,50 = $0,0018 + $0,0004 = $0,0022. Chạy điều đó 1.000 lần và bạn trả $2,20. Giá là $0,15 cho mỗi 1 triệu token đầu vào và $0,50 cho mỗi 1 triệu token đầu ra, không có đăng ký, vì vậy bạn chỉ trả tiền cho những gì chuỗi thực sự sử dụng. trang giá cả có các tùy chọn nạp tiền, và tài liệu bắt đầu nhanh liệt kê mọi tham số được hỗ trợ. Các prompt không được sử dụng để huấn luyện.

Hỏi đáp

Tôi có cần gói LangChain đặc biệt cho endpoint này không?

Không. Gói langchain-openai là đủ. Bạn truyền base URL, khóa của bạn và model ID uncensored vào ChatOpenAI.

Nó có hoạt động với LangGraph và agents không?

Có, miễn là chúng sử dụng định dạng gọi công cụ và gọi hàm chuẩn của OpenAI. Các lệnh gọi công cụ, tool_calls được truyền phát và kết quả vai trò công cụ đều được hỗ trợ.

Tôi có thể chuyển đổi giữa các mô hình trong một chuỗi không?

Không. Chỉ có một mô hình, uncensored, và dịch vụ không phải là bộ định tuyến giữa các nhà cung cấp. Hãy sử dụng một đối tượng mô hình LangChain riêng biệt nếu bạn cần một nhà cung cấp khác cho một bước khác.

Bạn nên làm gì với lỗi 429?

Hãy giảm độ đồng thời của batch, tuân thủ tiêu đề Retry-After khi có, và đảm bảo các stream đã kết thúc được đóng. Khóa đầy đủ cho phép 8 yêu cầu đồng thời và 300 yêu cầu mỗi phút.

Embedding có sẵn cho kho vector của tôi không?

Không. API chỉ hỗ trợ văn bản và không có endpoint embedding, nên bạn cần một nguồn embedding riêng cho truy xuất.

Khóa của bạn chỉ cách một biểu mẫu

Tạo tài khoản, sao chép khóa, thay đổi URL cơ sở. Đó là toàn bộ thiết lập.

Lấy khóa API