vertex ai有个模型广场,里面有70+模型可以调用,注册google cloud送90天的150美元免费额度。可以白嫖里面的ai模型。










记得先要创建一个项目,然后把开通service account,获取json文件的key,忘记的可以看这个教程点击打开链接
我们以google自己的gemini为例,把他作为代理部署在cloudflare的worker上,其他的模型大同小异,直接把相关的url参数修改一下就好了。

cloudflare的worker代码:
// 配置变量
const API_KEY ="你设定的key";
const PROJECT_ID = '';
const CLIENT_EMAIL = '';
const PRIVATE_KEY ="";
const API_ENDPOINT="us-central1-aiplatform.googleapis.com"
const LOCATION_ID="us-central1"
addEventListener("fetch", (event) => {
event.respondWith(handleRequest(event.request));
});
async function handleRequest(request) {
let headers = new Headers({
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
});
if (request.method === "OPTIONS") {
return new Response(null, { headers });
} else if (request.method === "GET") {
return new Response("404 Not Found", { status: 404 });
// return createErrorResponse(405, "invalid_request_error", "GET method is not allowed");
}
const apiKey = request.headers.get("x-api-key");
if (!API_KEY || API_KEY !== apiKey) {
return createErrorResponse(401, "authentication_error", "invalid x-api-key");
}
const signedJWT = await createSignedJWT(CLIENT_EMAIL, PRIVATE_KEY)
const [token, err] = await exchangeJwtForAccessToken(signedJWT)
if (token === null) {
console.log(`Invalid jwt token: ${err}`)
return createErrorResponse(500, "api_error", "invalid authentication credentials");
}
try {
return handleMessagesEndpoint(request, token);
} catch (error) {
console.error(error);
return createErrorResponse(500, "api_error", "An unexpected error occurred");
}
}
async function handleMessagesEndpoint(request, api_token) {
let payload;
try {
payload = await request.json();
} catch (err) {
return createErrorResponse(400, "invalid_request_error", "The request body is not valid JSON.");
}
const stream = payload.stream || false;
const model = payload.model;
const url = `https://${API_ENDPOINT}/v1/projects/${PROJECT_ID}/locations/${LOCATION_ID}/publishers/google/models/${model}:streamGenerateContent`;
delete payload.model;
delete payload.stream;
let response, contentType
try {
response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${api_token}`
},
body: JSON.stringify(payload)
});
contentType = response.headers.get("Content-Type") || "application/json";
} catch (error) {
return createErrorResponse(500, "api_error", "Server Error");
}
if (stream && contentType.startsWith('text/event-stream')) {
if (!(response.body instanceof ReadableStream)) {
return createErrorResponse(500, "api_error", "Server Error");
}
const encoder = new TextEncoder();
const decoder = new TextDecoder("utf-8");
let buffer = '';
let { readable, writable } = new TransformStream({
transform(chunk, controller) {
let decoded = decoder.decode(chunk, { stream: true });
buffer += decoded
let eventList = buffer.split(/\r\n\r\n|\r\r|\n\n/g);
if (eventList.length === 0) return;
buffer = eventList.pop();
for (let event of eventList) {
controller.enqueue(encoder.encode(`${event}\n\n`));
}
},
});
response.body.pipeTo(writable);
return new Response(readable, {
status: response.status,
headers: {
"Content-Type": response.headers.get("Content-Type") || "text/event-stream",
"Access-Control-Allow-Origin": "*",
},
});
} else {
try {
let data = await response.text();
return new Response(data, {
status: response.status,
headers: {
"Content-Type": contentType,
"Access-Control-Allow-Origin": "*",
},
});
} catch (error) {
return createErrorResponse(500, "api_error", "Server Error");
}
}
}
function createErrorResponse(status, errorType, message) {
const errorObject = { type: "error", error: { type: errorType, message: message } };
return new Response(JSON.stringify(errorObject), {
status: status,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
},
});
}
async function createSignedJWT(email, pkey) {
pkey = pkey.replace(/-----BEGIN PRIVATE KEY-----|-----END PRIVATE KEY-----|\r|\n|\\n/g, "");
let cryptoKey = await crypto.subtle.importKey(
"pkcs8",
str2ab(atob(pkey)),
{
name: "RSASSA-PKCS1-v1_5",
hash: { name: "SHA-256" },
},
false,
["sign"]
);
const authUrl = "https://www.googleapis.com/oauth2/v4/token";
const issued = Math.floor(Date.now() / 1000);
const expires = issued + 600;
const header = {
alg: "RS256",
typ: "JWT",
};
const payload = {
iss: email,
aud: authUrl,
iat: issued,
exp: expires,
scope: "https://www.googleapis.com/auth/cloud-platform",
};
const encodedHeader = urlSafeBase64Encode(JSON.stringify(header));
const encodedPayload = urlSafeBase64Encode(JSON.stringify(payload));
const unsignedToken = `${encodedHeader}.${encodedPayload}`;
const signature = await crypto.subtle.sign(
"RSASSA-PKCS1-v1_5",
cryptoKey,
str2ab(unsignedToken)
);
const encodedSignature = urlSafeBase64Encode(signature);
return `${unsignedToken}.${encodedSignature}`;
}
async function exchangeJwtForAccessToken(signed_jwt) {
const auth_url = "https://www.googleapis.com/oauth2/v4/token";
const params = {
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
assertion: signed_jwt,
};
const r = await fetch(auth_url, {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: Object.entries(params)
.map(([k, v]) => k + "=" + v)
.join("&"),
}).then((res) => res.json());
if (r.access_token) {
return [r.access_token, ""];
}
return [null, JSON.stringify(r)];
}
function str2ab(str) {
const buffer = new ArrayBuffer(str.length);
let bufferView = new Uint8Array(buffer);
for (let i = 0; i < str.length; i++) {
bufferView[i] = str.charCodeAt(i);
}
return buffer;
}
function urlSafeBase64Encode(data) {
let base64 = typeof data === "string" ? btoa(encodeURIComponent(data).replace(/%([0-9A-F]{2})/g, (match, p1) => String.fromCharCode(parseInt("0x" + p1)))) : btoa(String.fromCharCode(...new Uint8Array(data)));
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
}部署worker后记得要绑定自己的独立域名,cloudflare的免费子域名国内访问不了

最后就可以访问了
<script type="text/javascript">
fetch('https://worker绑定的自己的域名/',{body: JSON.stringify({
model: 'gemini-1.5-pro-001',
"contents": [
{
"role": "user",
"parts": [
{"text":"hello"}
]
}
],
"generationConfig": {
"maxOutputTokens": 8192,
"temperature": 1,
"topP": 0.95,
},
"safetySettings": [
{
"category": "HARM_CATEGORY_HATE_SPEECH",
"threshold": "BLOCK_MEDIUM_AND_ABOVE"
},
{
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
"threshold": "BLOCK_MEDIUM_AND_ABOVE"
},
{
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
"threshold": "BLOCK_MEDIUM_AND_ABOVE"
},
{
"category": "HARM_CATEGORY_HARASSMENT",
"threshold": "BLOCK_MEDIUM_AND_ABOVE"
}
],
}),
method: 'POST',
headers: {
'content-type': 'application/json',
'x-api-key':'自己设定的key'
}}) // 替换为实际的 JSON URL
.then(response => response.json())
.then(data => {
// 遍历 JSON 数据并提取 text 字段
data.forEach(item => {
item.candidates.forEach(candidate => {
candidate.content.parts.forEach(part => {
if (part.text) {
console.log(part.text);
}
});
});
});
})
.catch(error => console.error('Error fetching the JSON:', error));
</script>
php<?php
$url = 'https://自己绑定worker的域名/';
$apiKey = '你设定的key';
$data = [
'model' => 'gemini-1.5-pro-001',
'contents' => [
[
'role' => 'user',
'parts' => [
['text' => 'hello']
]
]
],
'generationConfig' => [
'maxOutputTokens' => 8192,
'temperature' => 1,
'topP' => 0.95,
],
'safetySettings' => [
[
'category' => 'HARM_CATEGORY_HATE_SPEECH',
'threshold' => 'BLOCK_MEDIUM_AND_ABOVE'
],
[
'category' => 'HARM_CATEGORY_DANGEROUS_CONTENT',
'threshold' => 'BLOCK_MEDIUM_AND_ABOVE'
],
[
'category' => 'HARM_CATEGORY_SEXUALLY_EXPLICIT',
'threshold' => 'BLOCK_MEDIUM_AND_ABOVE'
],
[
'category' => 'HARM_CATEGORY_HARASSMENT',
'threshold' => 'BLOCK_MEDIUM_AND_ABOVE'
]
]
];
$jsonData = json_encode($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'x-api-key: ' . $apiKey
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
} else {
$responseData = json_decode($response, true);
foreach ($responseData as $item) {
foreach ($item['candidates'] as $candidate) {
foreach ($candidate['content']['parts'] as $part) {
if (isset($part['text'])) {
echo $part['text'] . "\n";
}
}
}
}
}
curl_close($ch);
?> 网友回复


