中文 ▾
获取 API 密钥

LangChain + LLM:连接无审查 API

LangChain 通过其 ChatOpenAI 类连接到任何 OpenAI 兼容接口。设置 base URL、密钥和模型 ID,你的链和智能体即可在此 API 上运行。

已更新

链接块形成链,指向中央发光枢纽,代表 LangChain 管道调用一个 API

要点

  1. 使用 ChatOpenAI,将 base_url 设置为 API 地址,并将模型设置为 uncensored。
  2. 链、流式输出、函数调用和 JSON 输出均通过标准的聊天补全接口进行。
  3. 完整密钥将批处理并发限制在 8,试用密钥限制在 2,以避免 429 错误。
  4. 这是单一托管模型,不是路由器,因此不支持按供应商切换模型。

简短配置

常见的 langchain + llm 问题是,你是否需要为第三方接口进行特殊集成。不需要。LangChain 的 OpenAI 聊天包装器接受自定义 Base URL,且本 API 遵循 OpenAI 聊天补全格式,因此标准类即可使用。安装该包,传入三个值,即可获得一个可嵌入任意链的聊天模型对象。

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 试用额度,足以多次运行本文中的所有示例。模型 ID 始终为 uncensored,请求发送至 POST /v1/chat/completions。

关于网站名称的说明:尽管域名中包含 "router" 一词,但这是由独立供应商运行的单一开放权重模型,并非跨供应商的路由器,也不是任何供应商的官方 API。你在此处不选择模型。你的代码指定一个模型,该模型即会响应。

将密钥移出源代码

硬编码密钥在首次测试时可行,但第一次提交文件时就会成为问题。改为从环境变量读取。LangChain 包装的 OpenAI 客户端库默认查找 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 服务并依赖相同的环境变量,你的显式参数可防止两者冲突。

带有提示词模板的链

大多数实际工作使用提示词模板、模型和通过管道运算符连接的输出解析器。这是 LangChain 表达式语言风格,对于自定义端点无需特殊处理。

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

该模型对合法成人用途无内容拒绝,当你的链生成小说、角色扮演场景或伴侣对话时,这很重要,因为更谨慎的模型可能会拒绝生成。唯一的固定规则是永远不会生成涉及未成年人的性内容。如果你的产品有更严格的规则,请在此基础上构建自己的输入验证。

流式输出与用量

API 支持通过 stream: true 进行服务器发送事件的流式输出,用量在流结束时报告。在 LangChain 中,你调用 .stream() 并迭代数据块。

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)

需要注意的一个细节:一个流式请求会占用你的并发槽位之一,直到流结束。如果你的 UI 打开流但用户未关闭就离开,该槽位将保持忙碌。完整密钥允许 8 个并发请求,因此少量未关闭的流可能会阻塞新请求。当客户端断开连接时,请取消迭代器。

函数调用和代理

支持函数调用:你传入 tools 和可选的 tool_choice,模型回复 tool_calls(也可流式传输),你以 role: "tool" 消息形式返回结果。在 LangChain 中,bind_tools 会为你处理 wire 格式。

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

对于完整的智能体循环,LangChain 的智能体助手或 LangGraph 会为你运行此循环:调用模型、运行请求的工具、附加工具消息、再次调用。工具使用遵循标准 OpenAI 格式,因此适用于任何兼容接口的代码同样适用。与任何开放权重模型一样,请测试你的特定工具模式。保持参数名称简洁,描述简短,工具列表精简,因为长列表会让较弱的模型更容易选错。

使用 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。在临时过载时,你还会收到带有 Retry-After: 5 头的 429 响应。

自行设置批处理并发,并让客户端以退避方式重试:

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,显示你的剩余额度。

Web 应用的异步调用

在 Web 服务器中,你通常不希望使用阻塞调用。每个 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 头(如果有的话),并向用户显示简短的重试消息,而不是堆栈跟踪。

调试技巧:如果链的行为异常,请打印模型收到的确切消息。提示词模板有时会插入额外的空格或省略变量,模型只能回答它收到的内容。LangChain 的 verbose 和 debug 开关,或者如果你已使用 LangSmith 追踪,会显示最终消息列表。

上下文窗口对链的影响

上下文窗口为 100,000 token(提示词和补全合计),max_tokens 是可选的。这对于将许多文档放入单个提示词的检索链,或保留长历史记录的对话记忆来说已经足够大。但如果每次轮次都重新发送完整历史记录而不进行修剪,费用也会很高。

快速计算。一次检索步骤发送 12,000 个输入 token 并返回 800 个,成本为 0.012 x $0.15 + 0.0008 x $0.50 = $0.0018 + $0.0004 = $0.0022。运行 1,000 次,你需支付 $2.20。定价为每 1M 输入 token $0.15,每 1M 输出 token $0.50,无订阅费,因此你只为链实际使用的部分付费。定价页面 有充值选项,快速入门文档 列出了所有支持的参数。提示词不用于训练。

问答

此接口是否需要特殊的 LangChain 包?

不需要。langchain-openai 包即可。将 base URL、密钥和模型 ID uncensored 传入 ChatOpenAI 即可。

它与 LangGraph 和智能体兼容吗?

兼容,只要它们使用标准的 OpenAI 聊天和函数调用格式。支持函数调用、流式 tool_calls 和 role 为 tool 的结果。

我可以在链内部切换模型吗?

不可以。只有一个模型 uncensored,且该服务不是跨供应商的路由器。如果其他步骤需要不同供应商,请使用单独的 LangChain 模型对象。

我该如何处理 429 错误?

降低批处理并发,在存在时遵守 Retry-After 头,并确保完成流已关闭。完整密钥允许 8 个并发请求和每分钟 300 个请求。

我的向量存储是否有可用的嵌入?

不可以。API 仅支持文本,没有嵌入接口,因此你需要单独的嵌入源用于检索。

只差一张表单,即可获得密钥

创建账户,复制密钥,更改基础 URL。这就是全部设置。

获取 API 密钥