中文 ▾
立即开始

ChatGPT 无审查替代方案:两行代码切换

寻找无需重写代码即可采用的 ChatGPT 无审查替代方案?如果你的代码已经使用了 OpenAI SDK,切换只需两行:Base URL 和 API 密钥,加上模型名称。以下是切换前后的代码,以及切换到该服务后行为上的差异。

最后更新于

铁路道岔将轨道引向发光开放站点的示意图,展示两行代码的提供商切换

总结

  1. 更改 base_url 和 api_key,然后将模型设置为 uncensored。基本聊天客户端中无需更改其他内容。
  2. 最近的官方 SDK 也会读取 OPENAI_BASE_URL 和 OPENAI_API_KEY,因此你可以通过环境变量进行切换。
  3. 服务仅支持文本,提供一个模型,上下文窗口为 100,000 token。
  4. 预期会有不同的措辞和限制,因此在上线前请重新运行测试提示词。

切换前后

以下是典型的 OpenAI Python 客户端示例:

import os
from openai import OpenAI

client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])

r = client.chat.completions.create(
    model="your-current-model",
    messages=[{"role": "user", "content": "Draft a tense dialogue between two rivals."}],
)

指向无审查替代方案的相同客户端:

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.chatgptunfiltered.com/v1",
    api_key=os.environ["UNFILTERED_API_KEY"],
)

r = client.chat.completions.create(
    model="uncensored",
    messages=[{"role": "user", "content": "Draft a tense dialogue between two rivals."}],
)

构造函数中修改了两行,调用中的模型字符串也发生了更改。消息格式、响应对象以及你读取 r.choices[0].message.content 的方式保持不变。替代方案是由独立提供商运行的不同模型。它不是 ChatGPT,也不是来自 OpenAI 或其他任何人的官方 API。

仅使用环境变量进行切换

官方 Python 和 Node SDK 的最新版本在创建不带参数的客户端时,会读取 OPENAI_BASE_URL 和 OPENAI_API_KEY。这意味着应用代码可以保持不变:

export OPENAI_BASE_URL="https://api.chatgptunfiltered.com/v1"
export OPENAI_API_KEY="YOUR_KEY"
python app.py

你仍需确保代码传递了 model="uncensored"。如果模型名称在多处被硬编码,请先将其提取到一个配置值中。这个小型重构使得未来任何方向的切换成本同样低廉。

Node 中同样适用此方法:

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.chatgptunfiltered.com/v1",
  apiKey: process.env.UNFILTERED_API_KEY,
});

const r = await client.chat.completions.create({
  model: "uncensored",
  messages: [{ role: "user", content: "Give me five villain names." }],
});
console.log(r.choices[0].message.content);

框架和 Responses 格式

封装 OpenAI 客户端的库通常会暴露 Base URL 设置。在 LangChain 的 OpenAI 聊天包装器中,它看起来像这样:

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="uncensored",
    base_url="https://api.chatgptunfiltered.com/v1",
    api_key="YOUR_KEY",
)
print(llm.invoke("Name three moods for a chase scene.").content)

如果你使用较新的 Responses 格式,POST /v1/responses 和 POST /v1/chat/completions 都受支持。GET /v1/models 列出了该模型,这是检查你的密钥和 URL 是否正确的一种快速方法。

预期差异

区域你会注意到的差异
回答意愿针对合法成人用途,它不会拒绝内容。带过滤的模型会拒绝的提示词通常也会得到回答。
措辞和风格不同的模型,不同的风格。语气、长度和格式习惯将与你之前的模型不匹配。
模型选择一个模型,ID 为 uncensored。无需选择层级。
范围仅支持文本:不支持图像、音频或视频生成,不支持嵌入,不支持微调。
上下文100,000 token,包括提示词和补全。max_tokens 是可选的。
限制完整密钥:8 个并发请求,每分钟 300 次。试用密钥:2 个并发请求,每分钟 60 次。请求体最大 8 MB。
错误HTTP 429 且代码为 rate_limited 或 concurrency;临时过载返回 429 并带有 Retry-After: 5。

支持流式输出、函数调用和 JSON 模式,也支持 temperature、top_p、stop、seed 和惩罚参数。响应头包括 X-Request-Id、X-Balance-USD、X-RateLimit-Limit-Requests 和 X-RateLimit-Limit-Concurrency。文档 包含详细信息。

还有两个差异值得注意。首先,不同的模型计算 token 的方式可能不同,因此相同文本的计数可能与旧提供商报告的不同;请使用响应中的使用量数据,而不是你自己的估算。其次,依赖于厂商托管工具的功能(如内置网页搜索或厂商端的文件存储)不是此服务的一部分。函数调用是指:你定义函数,你的代码执行它们。

针对你自己提示词的对比脚本

与其目测少量输出,不如在循环中将你的提示词集通过新接口运行,并保存所有需要审查的内容。

import csv, json

with open("prompts.json", encoding="utf-8") as f:
    prompts = json.load(f)  # a list of strings

with open("results.csv", "w", newline="", encoding="utf-8") as out:
    w = csv.writer(out)
    w.writerow(["prompt", "reply", "in_tokens", "out_tokens"])
    for p in prompts:
        r = client.chat.completions.create(
            model="uncensored",
            temperature=0.7,
            messages=[{"role": "user", "content": p}],
        )
        w.writerow([p, r.choices[0].message.content, r.usage.prompt_tokens, r.usage.completion_tokens])

打开 CSV 文件,逐列审查。Token 列为你提供相同流量的成本预测:将总和乘以每 1M token $0.15 和 $0.50。试用密钥允许每分钟 60 次请求和同时 2 个请求,因此如果保持循环顺序,几百个提示词集将在几分钟内完成。

简短的迁移清单

  1. 获取密钥。 在 API 密钥页面,使用 Google 或邮箱注册并领取 $0.50 免费试用额度。有效期 7 天,无需绑定银行卡。
  2. 将模型名称和 URL 放入配置。 一个地方,从环境变量读取。
  3. 重新运行你的测试提示词。 使用 20 到 50 个真实示例,包括之前被模型拒绝的示例,并查看结果。
  4. 调整系统提示词。 删除仅用于说服被过滤模型回答的文本。保留描述角色、受众和格式的内容。
  5. 添加 429 处理程序。 等待 5 秒并重试。将并发限制设置为与你的密钥限额匹配。
  6. 查看使用情况。 在实际流量运行时,通过响应中的 X-Balance-USD 监控余额。

一个涵盖步骤 5 的重试辅助函数:

import time
from openai import RateLimitError

def create_with_retry(**kwargs):
    for _ in range(4):
        try:
            return client.chat.completions.create(**kwargs)
        except RateLimitError:
            time.sleep(5)
    raise RuntimeError("rate limited after 4 tries")

保留旧模型的已保存输出几周。如果用户在切换后抱怨某些内容感觉不对劲,你可以将其与旧模型会产生的输出进行比较,并查看差异是来自提示词、模型还是输入。

无风险推出

不要一次性切换所有模型。将提供商选择放在配置后面,以便你可以移动一定比例的流量并在几秒钟内回滚。

import os, random
from openai import OpenAI

old = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
new = OpenAI(base_url="https://api.chatgptunfiltered.com/v1", api_key=os.environ["UNFILTERED_API_KEY"])

SHARE = float(os.environ.get("NEW_SHARE", "0.05"))

def pick():
    if random.random() < SHARE:
        return new, "uncensored"
    return old, os.environ["OLD_MODEL"]

从 5% 开始,观察几天的错误率、429 计数和用户反馈,然后增加。将 NEW_SHARE 设置为 0 以回滚。按用户或功能进行选择比按请求进行选择更好,因为在对话必须保持在同一模型上时,中途切换模型会改变语气。

成本是多少,何时保持现状

价格为每 1M 输入 token $0.15,每 1M 输出 token $0.50,从预付额度中扣除。一次请求输入 1,500 个 token,输出 400 个,成本为 1,500 x $0.15 / 1M = $0.000225,加上 400 x $0.50 / 1M = $0.0002,总计 $0.000425,或每 1,000 次请求 $0.425。对于其他供应商,请查看其当前定价页面;费率会变化,凭记忆进行的比较很快就会过时。充值为整额,从 $20 到 $500,以加密货币支付,从 $50 起有奖金。详情见 定价。

如果你需要图像或嵌入功能,如果你的受众需要严格的内容审核,或者如果特定供应商的模型是硬性要求,那么继续使用你当前的供应商是正确的选择。要了解此类模型的背景,请阅读 了解无审查 ChatGPT 模型。硬性限制永不改变:禁止涉及未成年人的性内容。

同时运行两个提供商也是可以的。许多团队将普通请求路由到一个模型,而将频繁被拒绝的请求路由到另一个模型。由于两者都使用相同的格式,这种路由只需几行代码和一个何时使用哪个模型的规则。

常见问题

我需要修改多少行代码?

客户端设置中的两项:Base URL 和 API 密钥,以及请求中的模型名称。消息格式和响应解析保持不变。

这真的是没有过滤器的 ChatGPT 吗?

不是。它是一个不同的开放权重模型,由独立提供商运行,与 OpenAI 无关。它经过调整,可在合法成人使用中不拒绝内容地回答。

我可以继续使用 LangChain 或其他框架吗?

可以,只要它允许你设置自定义的 OpenAI 兼容接口地址。设置接口地址、密钥和模型 ID uncensored。

切换后我会失去什么?

文本之外的内容:图像、音频、向量嵌入和微调均未提供。你只能获得一个模型,而不是一个菜单。

获取 API 密钥

注册,复制 token,更新你的 Base URL。就这样。

立即开始