未知数据源 2024年06月25日
申请了谷歌的 GCP 后,不知道怎么用 Sonnet?[转 Linux.do]
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

2024-06-25 13:19 广东


原贴 :https://linux.do/t/topic/118702  

GCP 部分

    点这里打开Google Cloud Shell

    执行以下命令
    Google cloud shell执行

    gcloud auth application-default login
    image

    点击链接并完成授权
    这里出现一段链接,鼠标点击一下这个链接,打开之后一路允许,随后出现下面这个界面,点一下Copy复制下面的验证码

    返回Cloud Shell,粘贴验证码并确认
    回去刚刚的界面鼠标右键粘贴,然后回车确认

    [验证文件(密钥)] 的保存位置
    接着提示验证文件保存在了这个位置

    查看验证文件内容
    使用cat空格加这个路径进行查看,比如我这里是

    cat /tmp/tmp.ABCD/application_default_credentials.json

    从里面复制出三个值保留备用,project_id就是项目ID这个也要用到


Cloudflare 部分

    创建Cloudflare Workers
    随后直接进入cloudflare 创建 Workers (是Worker不是Page请注意)

    随后一路继续,随后点击这里的编辑按钮

    进去之后根据上一节中的信息替换下面脚本中的内容,直接全部覆盖worker.js里面的内容

    编辑Worker脚本

脚本内容

const MODEL = 'claude-3-5-sonnet@20240620'const PROJECT_ID = '项目ID'const CLIENT_ID = '填写'const CLIENT_SECRET = '填写'const REFRESH_TOKEN = '填写'// 相当于密码的功能,接口密钥 const API_KEY = 'sk-pass' const TOKEN_URL = 'https://www.googleapis.com/oauth2/v4/token'; let accessToken = ''; let tokenExpiry = 0; // 获取 access_token async function getAccessToken() { if (Date.now() / 1000 < tokenExpiry - 60) { return accessToken; } const response = await fetch(TOKEN_URL, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ client_id: CLIENT_ID, client_secret: CLIENT_SECRET, refresh_token: REFRESH_TOKEN, grant_type: 'refresh_token' }) }); const data = await response.json(); accessToken = data.access_token; tokenExpiry = Date.now() / 1000 + data.expires_in; return accessToken; } // 选择区域 function getLocation() { const currentSeconds = new Date().getSeconds(); return currentSeconds < 30 ? 'europe-west1' : 'us-east5'; } // 构建 API URL function constructApiUrl(location) { return `https://${location}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${location}/publishers/anthropic/models/${MODEL}:streamRawPredict`; } // 处理请求 async function handleRequest(request) { if (request.method === 'OPTIONS') { return handleOptions(); } // 检查x-api-key const apiKey = request.headers.get('x-api-key'); if (apiKey !== API_KEY) { const errorResponse = new Response(JSON.stringify({ type: "error", error: { type: "permission_error", message: "Your API key does not have permission to use the specified resource." } }), { status: 403, headers: { 'Content-Type': 'application/json' } }); errorResponse.headers.set('Access-Control-Allow-Origin', '*'); errorResponse.headers.set('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, DELETE, HEAD'); errorResponse.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization, x-api-key, anthropic-version, model'); return errorResponse; } const accessToken = await getAccessToken(); const location = getLocation(); const apiUrl = constructApiUrl(location); let requestBody = await request.json(); // 删除原始请求中的"anthropic_version"字段(如果存在) if (requestBody.anthropic_version) { delete requestBody.anthropic_version; } // 删除原始请求中的"model"字段(如果存在) if (requestBody.model) { delete requestBody.model; } // 添加新的"anthropic_version"字段 requestBody.anthropic_version = "vertex-2023-10-16"; const modifiedHeaders = new Headers(request.headers); modifiedHeaders.set('Authorization', `Bearer ${accessToken}`); modifiedHeaders.set('Content-Type', 'application/json; charset=utf-8'); modifiedHeaders.delete('anthropic-version'); const modifiedRequest = new Request(apiUrl, { headers: modifiedHeaders, method: request.method, body: JSON.stringify(requestBody), redirect: 'follow' }); const response = await fetch(modifiedRequest); const modifiedResponse = new Response(response.body, { status: response.status, statusText: response.statusText, headers: response.headers }); modifiedResponse.headers.set('Access-Control-Allow-Origin', '*'); modifiedResponse.headers.set('Access-Control-Allow-Methods', 'POST, GET, OPTIONS'); modifiedResponse.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization, x-api-key, anthropic-version, model'); return modifiedResponse; } function handleOptions() { const headers = new Headers(); headers.set('Access-Control-Allow-Origin', '*'); headers.set('Access-Control-Allow-Methods', 'POST, GET, OPTIONS'); headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization, x-api-key, anthropic-version, model'); return new Response(null, { status: 204, headers: headers }); } export default { async fetch(request) { return handleRequest(request); } }

    部署Worker
    随后重击 Deploy 部署到
    部署之后可以测试一下结果,注意最后的API格式遵循原版Anthropic格式
    文档:Create a Message - Anthropic 21


备注:

有效性测试方法:

{"messages":[{"role":"user","content":"hello world!"}],"stream":false,"model":"claude-3-opus-20240229","max_tokens":4000,"temperature":0.5,"top_p":1,"top_k":5}

workers的地址

域名绑定:

NextChat 15配置,注意密码和worker.js中一致,图片中因为我改了密码所以和脚本里面的不一样,然后模型选择claude系列中任意模型即可(有3.5就选3.5,没有选3 Sonnet):

效果:


API测试地址,可直接填入NextChat中使用
(建议使用网页版 41):https://claude.jgk-blog.tech 47 (终端地址) 密码:sk-key

感谢 @eggacheb 大佬的反馈,可无需修改oneapi/newapi程序,直接加入现有oneapi/newapi渠道中



阅读原文

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

相关文章