作者开发stillworks,每隔数小时向75个免费LLM端点发送真实POST请求并公开结果,当前仅20个无需API Key即可访问,解决了免费LLM列表"发出去就过时"的问题。
我用过所有免费的 LLM 端点列表,每一份都只在被人写下的那一天是准确的。在那之后,它就是一张截图。某个端点悄悄地加了密钥要求,或者模型 ID 变了,或者提供商开始对匿名流量返回 402,但列表里仍然写着"免费,无需密钥"——因为没有人重新跑过它。
所以我做了一个无聊的版本。stillworks 按计划向它追踪的每个端点发送真实的聊天补全请求,并发布返回的结果——包括失败的情况,和成功的一起并列发布。
开篇声明:这是我自己做的。刚上线两天,MIT 许可,仓库在 bon5co/stillworks。我发出来是因为测量本身才是有趣的部分,而不是因为它已经做完了。
不是 HEAD 请求。不是 /v1/models 列表。而是一个真实的 POST /chat/completions 请求,带 {"role":"user","content":"hello"},而且对于免密钥的那一批,完全不携带 Authorization 请求头。如果补全返回了,这一行就是绿色的并标上时间。如果返回 402,那也会被发布出来。
以下是 2026-08-05 01:30 UTC 的状态:
最新一轮探测中,有 20 个在不带 Authorization 请求头的情况下成功响应。另外 55 个需要免费层密钥,并在同一张表中被标注为需要密钥。
在过去一周的免密钥探测中:194 次尝试中有 146 次成功。
这 20 个中只有 5 个在每一次检查中都成功响应。
有 6 个成功响应次数不到一半。llm7 上的 gpt-oss:20b 在最近 19 次检查中只成功了 9 次。某个目录会把它标为"可用"。
最后一个数字就是全部的论据。"可用"不是布尔值,而把一个布尔值渲染出来的列表,是在轻微地对你撒谎。
页面是一张表。而我真正用的是这个:
curl -s https://stillworks.supercapybara.com/api/llm/up
它返回成功响应的免密钥端点,并按排序——首先按过去一周每个端点的响应比例,其次按延迟。这意味着 models[0] 是首选,其余的是你的备选。每个条目都携带下一次调用所需的全部信息:
{
"model": "minimax-m2.7",
"provider": "llm7",
"openai_base_url": "https://api.llm7.io/v1",
"auth": "none",
"latency_ms": 3862,
"answered": "18/18",
"last_ok": "2026-08-05T01:07:40Z",
"proved": ["tools", "json_schema", "json_object"],
"claimed_unproved": [],
"failed": []
}
遍历这个列表才是预期用法,而不是某种变通方案:
import json, urllib.request
from openai import OpenAI
shelf = json.load(urllib.request.urlopen(
"https://stillworks.supercapybara.com/api/llm/up"))
for endpoint in shelf["models"]: # already ranked, best first
client = OpenAI(base_url=endpoint["openai_base_url"], api_key="not-needed")
try:
reply = client.chat.completions.create(
model=endpoint["model"],
messages=[{"role": "user", "content": "hello"}],
)
except Exception:
continue # your IP hit its quota — next
print(endpoint["model"], reply.choices[0].message.content)
break
你需要那个循环,因为下一节会讲到它的局限性。
还有一个 ?format=env,如果你更想粘贴三行到一个项目里:
# stillworks: verified keyless 22 min ago
OPENAI_BASE_URL=https://text.pollinations.ai/openai
OPENAI_API_KEY=not-needed
OPENAI_MODEL=openai-fast
能力标志是我最有看法的一部分,因为这是我读过的每一个注册表都在敷衍了事的环节。四种状态,它们不能被压缩成两种:
两个真实的行说明了这个区分为什么值得:
pollinations / openai-fast — 39 次纯聊天补全全部成功,295 毫秒,是板上最可靠的免密钥行。该提供商声称支持工具调用。我们的工具探测返回了 402 Payment Required。所以 tools 被放在 claimed_unproved 里,而不是 proved 里——也不是 failed 里——我们没有证伪这个特性,我们只是没能看到它。
ovh-anonymous / Qwen3Guard-Gen-8B — 6 次聊天补全全部成功,464 毫秒。全部四个能力探测都直接失败了:feature 'response_format with provided format' is not currently supported。这些进入 failed。一个行可以是一个完全健康的聊天端点,同时对于结构化输出是一条死路。
20 个免密钥模型中,有 8 个有工具被真正证明可用。如果你用 ?feature=tools,vision 过滤,只会得到真正通过调用演示过的模型——未被探测的模型被排除而不是被乐观地包含,这是保守的方向,偶尔也是令人烦恼的方向。
这一节不是我附加上去的免责声明。这是我认为这个项目有任何价值的原因。
免密钥配额通常是按 IP 计算的。从我们的地址验证通过不等于从你的地址验证通过。一个对我们的服务器成功响应的端点,可能在第一次调用时对你返回 402 或 429。我们无法测量你的配额,也不假装可以。这就是为什么 API 返回一个排序后的列表而不是单个赢家——备选方案才是关键。
标记为 auth: "bearer" 的行是用我们自己的免费层密钥探测的。这证明了该端点响应了我们的账户。它没有说明你的注册表的免费层包含什么,也没有说明该提供商是否仍在发放账户。
这些是别人的免费服务。它们中的任何一个都可以在任何两次探测之间添加密钥要求或消失。时间戳存在就是因为答案会衰减。
它很小,也很新。75 个模型,两天的历史,一个探测 IP。履历必须积累到一定程度,"39/39 成功"才有意义,而目前一些行的分母只有 5。
这就是全部的说辞,我不打算再包装它了。如果你想要一个绿色的勾表示"在线",很多页面会给你一个。而这一个给你的是"最近 19 次尝试中成功 9 次,22 分钟前最后验证,来自我们的 IP,这里是导致另外 10 次失败的那个失败"——然后让你自己去检查那个可用的,而不是信任它。
网站:https://stillworks.supercapybara.com 仓库(MIT):https://github.com/bon5co/stillworks
添加端点只需要对 apps/audit/seed.go 提交一个 PR,写上基础 URL、聊天路径,以及是否需要密钥。探测器在下一个周期验证它,并发布实际发生的结果,包括什么都没发生。
技术栈是 Go、Postgres 和 templ,没有 JavaScript 框架——表的过滤和排序都在服务端,客户端脚本只做增强。提供商密钥存在于环境变量中,只在探测时发出;它们从不会被渲染、记录、写进数据库,或由 API 返回,而且有一个测试会在响应中出现密钥时失败。
欢迎告诉我缺少了哪些端点,或者哪些数字你无法从你自己的 IP 复现。第二个会更有用。