今天来继续薅赛博活佛cloudflare

Cloudflare workers AI(以下简称cloudflare ai)是 Cloudflare 提供的一个强大且简单的人工智能平台,允许开发者在 Cloudflare 的全球边缘网络上直接调用和运行 AI 模型,无需自己部署 GPU 或机器学习基础设施

一句话总结:

Cloudflare AI API = 免费 + 快速 + 无服务器 + 支持主流模型,适合任何前后端开发者轻松调用

而且你只需要一个 API 调用,就能使用 LLM、大模型、图像生成、音频转文字等功能,碉堡了

常用模型:

模型用途模型 ID 示例
文本对话@cf/meta/llama-2-7b-chat-int8
图像生成@cf/stability/stable-diffusion-xl-base-1.0
语音转文字@cf/openai/whisper
文本嵌入向量@cf/openai/text-embedding-ada-002

当然免费每天是有限度的

类型免费额度(每天)
文本生成10,000 token
图像生成250 步(约10张)
语音转文字10 分钟音频
文本嵌入10,000 token

对于正常人来说一天足够用了

下面我会来介绍如何使用这些模型

最简单的方法就是直接在线使用,直接打开这个地址即可直达:https://playground.ai.cloudflare.com/,包括deepseek等都是免费使用的,但是不支持图像生成等操作

接下来就是如何使用API来在自己的应用上跑

使用API方法如下:打开cloudflare api tokens界面,创建一个API Key(首先要创建并登录cloudflare账号)

https://dash.cloudflare.com/profile/api-tokens

选择workersAI

保持默认即可,账户选择所有或者你的账户都行

API令牌只会显示一次,请妥善保管

此时就直接可以用了

curl --request POST \
  --url https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/ai/run/@cf/meta/llama-2-7b-chat-int8 \
  --header 'Authorization: Bearer <API_TOKEN>' \
  --header 'Content-Type: application/json' \
  --data '{
    "messages": [
      { "role": "user", "content": "你好,介绍一下 Cloudflare Workers AI。" }
    ]
  }'

account id和api token换成自己的即可

如果使用命令行不好看或者没法生成图片,以下还有解决方法

方法一(操作简单)

使用OneAPI,此文不讲安装方法,请自行搜索

修改渠道信息时把key填你的获取的令牌
base_url改为:https://api.cloudflare.com/client/v4/accounts/AccountID/ai,替换AccountID即可,模型选择时注意模型必须是cloudflare AI的,点此查看模型列表或者在文末我有列出

方法二(快速入手,文末我有我自己部署过的,可以直接访问使用,如果自己想在本地操作或者查看使用说明可以继续看)

首先下载一个XAMPP:https://www.apachefriends.org/download.html

下载完安装,一路继续保持默认即可,最后启动

点击右侧的Explorer,在文件夹界面找到htdocs

接下来把以下代码在桌面上保存到同一个文件夹中,然后拖到htdocs里(注意保持文件路径全部英文)

保存为index.html:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Cloudflare AI 应用</title>
    <style>
        body {
            font-family: 'Arial', sans-serif;
            line-height: 1.6;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }
        h1 {
            color: #f48120;
            text-align: center;
        }
        .container {
            background-color: white;
            border-radius: 8px;
            padding: 20px;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
            margin-bottom: 20px;
        }
        textarea {
            width: 100%;
            height: 150px;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
            margin-bottom: 10px;
            resize: vertical;
        }
        button {
            background-color: #f48120;
            color: white;
            border: none;
            padding: 10px 15px;
            border-radius: 4px;
            cursor: pointer;
            font-weight: bold;
        }
        button:hover {
            background-color: #e67300;
        }
        #response {
            white-space: pre-wrap;
            background-color: #f9f9f9;
            border: 1px solid #ddd;
            border-radius: 4px;
            padding: 15px;
            margin-top: 20px;
            min-height: 100px;
        }
        .model-selector {
            margin-bottom: 15px;
        }
        select {
            padding: 8px;
            border-radius: 4px;
            border: 1px solid #ddd;
            width: 100%;
        }
        .loading {
            text-align: center;
            display: none;
        }
        .help-text {
            background-color: #e8f4f8;
            border-left: 4px solid #4a90e2;
            padding: 10px 15px;
            margin: 15px 0;
            font-size: 14px;
        }
        .error {
            color: #d32f2f;
            background-color: #ffebee;
            padding: 10px;
            border-radius: 4px;
            margin-top: 10px;
        }
        footer {
            text-align: center;
            margin-top: 30px;
            color: #666;
            font-size: 14px;
        }
        .api-config {
            margin-top: 20px;
            padding: 15px;
            background-color: #f5f5f5;
            border-radius: 4px;
        }
        .api-config details {
            margin-bottom: 10px;
        }
        .api-config summary {
            cursor: pointer;
            font-weight: bold;
            color: #333;
        }
        .api-config input, .api-config select {
            width: 100%;
            padding: 8px;
            margin-top: 5px;
            margin-bottom: 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
        }
    </style>
</head>
<body>
    <h1>Cloudflare AI 应用</h1>
    
    <div class="container">
        <div class="help-text">
            <p><strong>使用说明:</strong></p>
            <ul>
                <li>文本生成:输入任何问题或指令,AI将生成相应回答</li>
                <li>情感分析:输入一段文本,AI将分析其情感倾向</li>
                <li>图像生成:输入详细的图像描述,AI将生成相应图像</li>
            </ul>
        </div>
        
        <div class="model-selector">
            <label for="model">选择模型:</label>
            <select id="model">
                <option value="@cf/meta/llama-3.1-8b-instruct">Llama 3.1 (8B) - 文本生成</option>
                <option value="@cf/huggingface/distilbert-sst-2-int8">DistilBERT - 情感分析</option>
                <option value="@cf/stabilityai/stable-diffusion-xl-base-1.0">Stable Diffusion XL - 图像生成</option>
            </select>
        </div>
        
        <label for="prompt">输入提示:</label>
        <textarea id="prompt" placeholder="输入您的问题或提示..."></textarea>
        
        <button id="submitBtn">提交请求</button>
        
        <div class="loading" id="loading">
            <p>处理中,请稍候...</p>
        </div>
        
        <div id="response"></div>
        
        <div class="api-config">
            <details>
                <summary>API 配置</summary>
                <div>
                    <label for="account_id">账户 ID:</label>
                    <input type="text" id="account_id" value="改为你的account id">
                    
                    <label for="api_token">API 令牌:</label>
                    <input type="text" id="api_token" value="改为你的api令牌">
                    
                    <label for="use_proxy">使用代理:</label>
                    <select id="use_proxy">
                        <option value="true">是 (推荐,解决CORS问题)</option>
                        <option value="false">否 (直接调用API)</option>
                    </select>
                </div>
            </details>
        </div>
    </div>

    <footer>
        由 Cloudflare AI API 提供支持
    </footer>

    <script>
        // 根据选择的模型更新提示文本
        document.getElementById('model').addEventListener('change', function() {
            const model = this.value;
            const promptElement = document.getElementById('prompt');
            
            if (model.includes('stable-diffusion')) {
                promptElement.placeholder = "输入图像描述,请使用纯英文和提示标签";
            } else if (model.includes('distilbert')) {
                promptElement.placeholder = "输入一段文本进行情感分析,例如:这家餐厅的服务非常好,食物也很美味...";
            } else {
                promptElement.placeholder = "输入您的问题或指令,例如:解释量子计算的基本原理...";
            }
        });
        
        document.getElementById('submitBtn').addEventListener('click', async function() {
            const prompt = document.getElementById('prompt').value;
            const model = document.getElementById('model').value;
            const responseElement = document.getElementById('response');
            const loadingElement = document.getElementById('loading');
            
            // 获取API配置
            const accountId = document.getElementById('account_id').value;
            const apiToken = document.getElementById('api_token').value;
            const useProxy = document.getElementById('use_proxy').value === 'true';
            
            if (!prompt) {
                responseElement.innerHTML = "<div class='error'>请输入提示内容</div>";
                return;
            }
            
            if (!accountId || !apiToken) {
                responseElement.innerHTML = "<div class='error'>请提供有效的账户ID和API令牌</div>";
                return;
            }
            
            responseElement.textContent = "";
            loadingElement.style.display = "block";
            
            try {
                // 准备请求数据
                let requestData = {};
                
                if (model.includes('stable-diffusion')) {
                    requestData = { prompt: prompt };
                } else if (model.includes('distilbert')) {
                    requestData = { text: prompt };
                } else {
                    requestData = { prompt: prompt };
                }
                
                let response;
                
                if (useProxy) {
                    // 使用代理
                    response = await fetch(`proxy.php?model=${encodeURIComponent(model)}&account_id=${encodeURIComponent(accountId)}&api_token=${encodeURIComponent(apiToken)}`, {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json'
                        },
                        body: JSON.stringify(requestData)
                    });
                } else {
                    // 直接调用API
                    response = await fetch(`https://api.cloudflare.com/client/v4/accounts/${accountId}/ai/run/${model}`, {
                        method: 'POST',
                        headers: {
                            'Authorization': `Bearer ${apiToken}`,
                            'Content-Type': 'application/json'
                        },
                        body: JSON.stringify(requestData)
                    });
                }
                
                // 检查是否为图像生成模型
                if (model.includes('stable-diffusion')) {
                    // 克隆响应以避免多次读取同一个流
                    const responseClone = response.clone();
                    
                    try {
                        // 尝试先解析为JSON(如果是代理返回的)
                        const data = await responseClone.json();
                        if (data.success && data.result && data.result.images) {
                            const imgBase64 = data.result.images[0];
                            responseElement.innerHTML = `<img src="data:image/png;base64,${imgBase64}" alt="生成的图像" style="max-width: 100%;">`;
                        } else {
                            responseElement.innerHTML = `<div class='error'>图像生成失败: ${JSON.stringify(data.errors || '未知错误')}</div>`;
                        }
                    } catch (e) {
                        // 如果不是JSON,则尝试作为二进制图像处理
                        try {
                            const imageBlob = await response.blob();
                            const imageUrl = URL.createObjectURL(imageBlob);
                            responseElement.innerHTML = `<img src="${imageUrl}" alt="生成的图像" style="max-width: 100%;">`;
                        } catch (blobError) {
                            responseElement.innerHTML = `<div class='error'>处理图像失败: ${blobError.message}</div>`;
                        }
                    }
                    loadingElement.style.display = "none";
                    return;
                }
                
                const data = await response.json();
                
                if (data.success) {
                    if (model.includes('distilbert')) {
                        // 处理情感分析响应
                        const sentiment = data.result.classifications[0];
                        const isPositive = sentiment.label === "POSITIVE";
                        const confidencePercent = (sentiment.confidence * 100).toFixed(2);
                        
                        responseElement.innerHTML = `
                            <p><strong>情感分析结果:</strong> ${isPositive ? '积极 😊' : '消极 😞'}</p>
                            <p><strong>置信度:</strong> ${confidencePercent}%</p>
                            <p><strong>原始数据:</strong></p>
                            <pre>${JSON.stringify(data.result, null, 2)}</pre>
                        `;
                    } else {
                        // 处理文本生成响应
                        responseElement.textContent = data.result.response;
                    }
                } else {
                    responseElement.innerHTML = `<div class='error'>错误: ${JSON.stringify(data.errors)}</div>`;
                }
            } catch (error) {
                responseElement.innerHTML = `<div class='error'>请求错误: ${error.message}</div>`;
            } finally {
                loadingElement.style.display = "none";
            }
        });
        
        // 初始化时触发一次模型变更事件,设置正确的提示文本
        document.getElementById('model').dispatchEvent(new Event('change'));
    </script>
</body>
</html> 

保存为proxy.php:

<?php
// 设置允许跨域访问
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');

// 如果是OPTIONS请求,直接返回
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    exit(0);
}

// 获取请求参数
$model = isset($_GET['model']) ? $_GET['model'] : '';
$account_id = isset($_GET['account_id']) ? $_GET['account_id'] : '';
$api_token = isset($_GET['api_token']) ? $_GET['api_token'] : '';

// 验证必要参数
if (empty($model) || empty($account_id) || empty($api_token)) {
    http_response_code(400);
    echo json_encode(['success' => false, 'errors' => ['Missing required parameters']]);
    exit;
}

// 获取请求体
$request_body = file_get_contents('php://input');

// 构建请求URL
$url = "https://api.cloudflare.com/client/v4/accounts/{$account_id}/ai/run/{$model}";

// 初始化cURL
$ch = curl_init($url);

// 设置cURL选项
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $request_body);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ' . $api_token,
    'Content-Type: application/json'
]);

// 执行请求
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);

// 检查是否有错误
if (curl_errno($ch)) {
    http_response_code(500);
    echo json_encode(['success' => false, 'errors' => ['cURL error: ' . curl_error($ch)]]);
    exit;
}

// 关闭cURL
curl_close($ch);

// 检查是否为图像响应
if (strpos($content_type, 'image/') === 0) {
    // 如果是图像,直接传递图像数据和内容类型
    header('Content-Type: ' . $content_type);
    http_response_code($http_code);
    echo $response;
} else {
    // 否则作为JSON响应处理
    header('Content-Type: application/json');
    http_response_code($http_code);
    echo $response;
} 

拖进去后在Apache处选择start,变成stop就可以了

然后访问:http://localhost/你的文件夹名/index.html

在底下填入你的account id和api key

account id在账户主页-名称旁三个点-复制账户id

此时选择模型即可使用cloudflare AI,包括图像生成(就是有点差,毕竟是免费的),延迟平均在10-30

图像生成尽量使用英语,或者使用英语标签,标签超市:https://tags.novelai.dev/

我这里只提供了三个基本模型,还有更多模型可以参阅官方文档进行配置

最后注意每天的tokens限额,所有操作消耗的tokens是共通的,在账户主页的AI-workers AI-每日使用量可以看到,消耗还是非常低的,对比openrouter的消耗,workers能用更多而且响应更快

以下是一些可替换模型(在原代码里修改,音转文、翻译模型需要另行配置,在此不做介绍)

对话模型:

  • @cf/deepseek-ai/deepseek-math-7b-instruct
  • @cf/defog/sqlcoder-7b-2
  • @cf/fblgit/una-cybertron-7b-v2-awq
  • @cf/fblgit/una-cybertron-7b-v2-bf16
  • @cf/google/gemma-2b-it-lora
  • @cf/google/gemma-7b-it-lora
  • @cf/meta-llama/llama-2-7b-chat-hf-lora
  • @cf/meta/llama-2-7b-chat-fp16
  • @cf/meta/llama-2-7b-chat-int8
  • @cf/meta/llama-3-8b-instruct
  • @cf/meta/llama-3-8b-instruct-awq
  • @cf/microsoft/phi-2
  • @cf/mistral/mistral-7b-instruct-v0.1
  • @cf/mistral/mistral-7b-instruct-v0.1-vllm
  • @cf/mistral/mistral-7b-instruct-v0.2-lora
  • @cf/openchat/openchat-3.5-0106
  • @cf/qwen/qwen1.5-0.5b-chat
  • @cf/qwen/qwen1.5-1.8b-chat
  • @cf/qwen/qwen1.5-14b-chat-awq
  • @cf/qwen/qwen1.5-7b-chat-awq
  • @cf/thebloke/discolm-german-7b-v1-awq
  • @cf/tiiuae/falcon-7b-instruct
  • @cf/tinyllama/tinyllama-1.1b-chat-v1.0
  • @hf/google/gemma-7b-it
  • @hf/mistral/mistral-7b-instruct-v0.2
  • @hf/nexusflow/starling-lm-7b-beta
  • @hf/nousresearch/hermes-2-pro-mistral-7b
  • @hf/thebloke/codellama-7b-instruct-awq
  • @hf/thebloke/deepseek-coder-6.7b-base-awq
  • @hf/thebloke/deepseek-coder-6.7b-instruct-awq
  • @hf/thebloke/llama-2-13b-chat-awq
  • @hf/thebloke/llamaguard-7b-awq
  • @hf/thebloke/mistral-7b-instruct-v0.1-awq
  • @hf/thebloke/neural-chat-7b-v3-1-awq
  • @hf/thebloke/openhermes-2.5-mistral-7b-awq
  • @hf/thebloke/zephyr-7b-beta-awq

文生图:

  • @cf/bytedance/stable-diffusion-xl-lightning
  • @cf/lykon/dreamshaper-8-lcm
  • @cf/runwayml/stable-diffusion-v1-5-img2img
  • @cf/runwayml/stable-diffusion-v1-5-inpainting
  • @cf/stabilityai/stable-diffusion-xl-base-1.0

音转文:

  • @cf/openai/whisper
  • @cf/openai/whisper-sherpa
  • @cf/openai/whisper-tiny-en

翻译模型:

@cf/meta/m2m100-1.2b

====================================================

最后的最后,我把这个应用直接部署到我的网站了,在这里可以直接使用:https://071400.xyz/cloudflarefree/

这篇文章到这里就结束了,有问题请留言

赞助我

文章参考:https://www.aisharenet.com/cloudflare-workers-ai/