Cloudflare 每天一万 AI 积分,cherry Studio 使用教程

苏苏
11
2026-11-13

高尔基说过,生命的意义在于折腾,虽然苏苏已经分享了数十个免费的 AI api 接口了,但是还是决定折腾一下 Cloudflare 的 免费 AI api 接口。直接调用是不行的,所以我们需要一个 worker。


说是一万积分,但是这只是积分,还需要换成token,网上有人大致做了部分的换算关系:

Qwen3.8-27B纯输入 24 万 · 纯输出 3.4 万 · 混合算 8 万

GPT-OSS-20B纯输入 55 万 · 纯输出 36.7 万 · 混合算 47 万

Llama-3.1-8B纯输入 243 万 · 纯输出 28.7 万 · 混合算 70 万

Qwen3-30B-A3B纯输入 216 万 · 纯输出 32.8 万 · 混合算 75 万


确实不算多,也就适合聊聊天,纯粹是为了折腾。


控制台左边 构建 --> 计算 --> Workers 和 Pages --> 创建应用程序


选择【从 Hello World!】 开始,直接点击[部署]。


部署完成后,点击右上角[编辑代码],把下面的代码复制进去,粘贴之后,这个页面的右上角有个[部署]按钮,点击一下。然后可以点击左上角返回了。

const SSE_HEADERS = {
  "Content-Type": "text/event-stream",
  "Cache-Control": "no-cache",
  Connection: "keep-alive",
};
// 完善结束状态的 OpenAI 兼容 SSE 转换器
function toOpenAIStream(aiStream, model) {
  const id = `chatcmpl-${crypto.randomUUID()}`;
  const created = Math.floor(Date.now() / 1000);
  const encoder = new TextEncoder();
  const decoder = new TextDecoder();
  let buffer = "";
  let finished = false;
  return aiStream.pipeThrough(
    new TransformStream({
      transform(chunk, controller) {
        buffer += decoder.decode(chunk, { stream: true });
        const lines = buffer.split("\n");
        buffer = lines.pop() || ""; // 处理 TCP 拆包残留
        for (const line of lines) {
          const trimmed = line.trim();
          if (!trimmed.startsWith("data: ")) continue;
          const data = trimmed.slice(6);
          if (data === "[DONE]") {
            continue; // 原生流如果带了 [DONE],在这里统一拦截,由 flush 阶段接管
          }
          try {
            const parsed = JSON.parse(data);
            // 从原生响应中提取生成的文本片段
            const text = parsed.response ?? "";
            if (text) {
              const chunk = {
                id,
                object: "chat.completion.chunk",
                created,
                model,
                choices: [{ index: 0, delta: { content: text }, finish_reason: null }],
              };
              controller.enqueue(encoder.encode(`data: ${JSON.stringify(chunk)}\n\n`));
            }
          } catch {
            // 跳过非 JSON 帧
          }
        }
      },
      flush(controller) {
        if (finished) return;
        finished = true;
        // 1. 发送带有 finish_reason 的结束数据块
        const finalChunk = {
          id,
          object: "chat.completion.chunk",
          created,
          model,
          choices: [{ index: 0, delta: {}, finish_reason: "stop" }],
        };
        controller.enqueue(encoder.encode(`data: ${JSON.stringify(finalChunk)}\n\n`));
        // 2. 紧随其后发送 OpenAPI 要求的 [DONE] 结束标记
        controller.enqueue(encoder.encode(`data: [DONE]\n\n`));
      },
    })
  );
}
export default {
  async fetch(req, env) {
    const { pathname } = new URL(req.url);
    if (pathname !== "/v1/chat/completions") return new Response("Not Found", { status: 404 });
    if (req.method !== "POST") return new Response("Method Not Allowed", { status: 405 });
    let isStream = false;
    try {
      const body = await req.json();
      const { messages, stream = false, model } = body;
      isStream = stream === true;
      if (!model) {
        return Response.json({ error: { message: "缺少 model 参数" } }, { status: 400 });
      }
      if (!Array.isArray(messages) || messages.length === 0) {
        return Response.json({ error: { message: "messages 必须是非空数组" } }, { status: 400 });
      }
      // 流式分支
      if (isStream) {
        const aiStream = await env.AI.run(model, { messages, stream: true });
        return new Response(toOpenAIStream(aiStream, model), { headers: SSE_HEADERS });
      }
      // 非流式分支
      const out = await env.AI.run(model, { messages });
      return Response.json({
        id: `chatcmpl-${crypto.randomUUID()}`,
        object: "chat.completion",
        created: Math.floor(Date.now() / 1000),
        model,
        choices: [{ index: 0, message: { role: "assistant", content: out.response }, finish_reason: "stop" }],
      });
    } catch (err) {
      if (isStream) {
        return new Response(`data: ${JSON.stringify({ error: { message: err.message } })}\n\ndata: [DONE]\n\n`, { headers: SSE_HEADERS });
      }
      return Response.json({ error: { message: err.message } }, { status: 500 });
    }
  },
};

点击上面的【设置】,在【绑定】那里,点击【添加绑定】,在弹出框的左侧选择[Workers AI],然后点击弹出框右下角的[添加绑定],然后在 [变量名称] 那里输入【AI】,再点击一下【添加绑定】。完成了。


这个时候,点一下右上角的[访问],就可以拿到你 Worker 的地址了,通常为 【https://你的名字.子域.workers.dev/】, 如果打不开请看最后的注意。


cherry Studio 这么填写,先新增个自定义提供商

选择 openAI格式

提供商名称,随意

api 密钥,随便乱写个 123,或者你找ai 改一下代码,加上真正的 密钥

url填写 https://你的名字.子域.workers.dev/v1

可以了。

模型需要手动添加,下面是可以添加的模型:


@cf/meta/llama-3.3-70b-instruct-fp8-fast

@cf/meta/llama-4-scout-17b-16e-instruct

@cf/openai/gpt-oss-120b OpenAI

@cf/google/gemma-4-26b-a4b-it

@cf/zai-org/glm-4.7-flash

@cf/mistralai/mistral-small-3.1-24b-instruct

@cf/deepseek-ai/deepseek-r1-distill-qwen-32b

@cf/qwen/qwen3.8-27b

@cf/meta/llama-3.2-1b-instruct

@cf/openai/whisper-large-v3-turbo


具体的模型,来这里找:https://developers.cloudflare.com/workers-ai/platform/pricing/


注意

最后要说的是,cloudflare 的 Worker 地址,国内是打不开的,需要上手段。或者你去申请一个免费域名【看这里:https://www.138vps.com/freedomain/3338.html】, 托管到 cloudflare,然后给你的 Worker 加个自己的域名,就可以正常访问了。


特别申明: 若无说明,文章均为原创,转载时请注明本文地址,谢谢合作!
下 一 篇: 噢~这是最新的文章了

本站仅为分享信息,绝对不是推荐,所有内容均仅代表个人观点,读者购买风险自担。如果你非要把风险推苏苏头上,不要这么残忍,好吗?
本站保证在法律范围内您的个人信息不经由本站透露给任何第三方。
所有网络产品均无法保证在中国任何地区,任何时间,任何宽带均有相同的访问体验,那种号称某机房绝不抽风的不是骗子就是呵呵.
任何IDC都有倒闭和跑路的可能,备份永远是最佳选择,服务器也是机器,不勤备份是对自己极不负责的表现.

加入新群:494744877

欢迎IDC提交优惠信息或者测试样机,提交信息请Eamil至admin#138vps.com,苏苏不保证一定会进行发布。

但请IDC留意以下内容:
无官方正式首页、无可用联络方式暂不发布;
曾经有过倒闭和跑路经历者重开不到6个月不做发布;
从本日起(2016-07-18)不接受任何形式的免费赞助和VPS馈赠,不接受任何评测报告的投稿,不接受任何付费发布和付费删除评论,所有IDC若有必要提交测试样机,请在7日后自行删除。
公告
欢迎加入qq群:494744877
本站诚换友情链接。在您的网站加上本站的友情链接后发邮件到 admin#138vps.com, 苏苏会自行审核,一周内会上线您的友情链接。
要求:建站一年以上,百度权重1,收录数量不低于一千。
请尽量使用 PayPal 进行交易,PayPal 对资金的保护政策更照顾买家。
年度爆文