Hexo 看板娘 AI 切到通义千问
前面已经把 Hexo 看板娘接上了 AI 聊天,这篇继续记录一下怎么把 AI 接口从 Cloudflare Workers AI 切到通义千问,用阿里云函数计算做一层中转,让国内访问更稳定一点。
一开始我用的是 Cloudflare Workers AI。
这个方案本身挺方便,Worker 和 AI 能力都在 Cloudflare 里,写起来也比较简单。
但是实际放到国内访问的时候,还是会遇到一个问题:workers.dev 有时候需要科学上网才能稳定访问,看板娘聊天就可能出现接口请求失败。
所以这次换一个更适合国内博客访问的方案:
1 | 博客前端 -> 阿里云函数计算 -> 通义千问 -> 函数计算 -> 博客前端 |
为什么选通义千问
这次主要看中几个点。
- 国内访问函数计算比较稳定。
- 通义千问可以通过百炼 API 调用。
- 控制台里能看到免费 Token 额度。
- 函数计算可以只做一层很轻的接口转发。
- 后面如果想换模型,主要改后端,不需要大改前端。
博客看板娘这种场景,不需要特别大的模型。
用户问一句,看板娘回一句,内容一般也不会特别长。
所以模型可以先选 qwen-plus。
它的回复质量够用,速度也还可以。
而且百炼 Token Plan 里可以看到通义千问的免费额度,个人博客先跑起来没什么压力。
开通通义千问
通义千问的 API 调用入口在阿里云百炼里,所以先进入百炼控制台:
1 | https://bailian.console.aliyun.com/ |
如果之前没用过,可以按下面步骤走。
- 登录阿里云账号。
- 进入
阿里云百炼。 - 顶部可以看到
模型、应用、订阅、Token Plan、体验、文档、API 参考这些入口。 - 先点
Token Plan。 - 左侧选择
免费额度。 - 在
大语言模型里找到要用的模型,比如qwen-plus。
这里能看到类似这样的额度:
1 | qwen-plus |
这个就是当前模型的免费 Token。
不同模型的免费额度一般是分开的,不是所有模型共用一个池子。
旁边还有一个开关,叫 免费额度用完即停。
这个建议打开。
打开以后,免费额度用完就会停止,不会继续产生额外 Token 费用。
如果只是个人博客聊天,这个开关开着更安心。
创建 API Key
模型要通过接口调用,就需要一个 API Key。
在百炼控制台里可以这样找:
- 进入百炼控制台。
- 找到 API Key 管理入口。
- 创建一个新的 API Key。
- 复制生成的 Key。
这个 Key 只在后端用。
不要写到前端 JS 里。
不要提交到 Git 仓库里。
不要放到公开文章里。
前端如果直接带着 Key 请求模型,别人打开浏览器控制台就能看到。
所以中间必须有一层自己的后端接口。
这次我用的就是阿里云函数计算。
创建函数计算接口
进入阿里云函数计算控制台:
1 | https://fcnext.console.aliyun.com/ |
然后创建一个函数。
我这里的思路是:
- 地域选国内,比如
华东1 杭州。 - 函数名称写成
waifu-ai-chat。 - 运行环境选择 Node.js。
- 创建 HTTP 触发器。
- 请求路径用
/api/waifu-chat。 - 允许
POST和OPTIONS。
函数计算在这里不是做复杂业务。
它只负责几件事:
- 接收前端发来的聊天内容。
- 处理跨域请求。
- 从环境变量里读取百炼 API Key。
- 调用通义千问模型接口。
- 把模型回复整理成
{ reply: '...' }返回给前端。
配置环境变量
函数里不要直接写 API Key。
在函数计算的配置里添加环境变量:
1 | DASHSCOPE_API_KEY=你的百炼 API Key |
其中:
DASHSCOPE_API_KEY是百炼的 API Key。WAIFU_AI_MODEL是当前使用的模型。ALLOWED_ORIGIN是允许访问这个接口的博客域名。
本地调试的时候,也可以临时允许:
1 | http://localhost:4000 |
线上还是尽量只放自己的博客域名。
函数里的核心逻辑
通义千问在百炼里提供了 OpenAI 兼容模式接口。
这样写起来比较直观。
请求地址是:
1 | https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions |
核心请求大概是这样:
1 | const response = await fetch('https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions', { |
返回以后,从结果里取出模型回复:
1 | const data = await response.json(); |
最后返回给前端:
1 | return { |
前端只关心 reply 字段。
所以后端不管是 Cloudflare Workers AI,还是通义千问,只要最后返回结构保持一致,前端改动就很小。
处理跨域和预检请求
浏览器从博客页面请求函数计算接口,会遇到跨域。
所以函数里需要处理 OPTIONS 请求。
大概逻辑是:
1 | if (method === 'OPTIONS') { |
如果不处理这个,前端可能还没真正发出聊天请求,就先被浏览器拦住。
前端切换接口地址
原来前端请求的是 Cloudflare Worker。
这次改成优先请求阿里云函数计算:
1 | const defaultAiChatEndpoint = 'https://你的函数域名/api/waifu-chat'; |
我这里保留了 Cloudflare Worker 作为备用。
也就是说:
- 优先请求阿里云函数计算。
- 如果阿里云接口异常,再尝试 Cloudflare Worker。
- 如果两个都失败,再给用户一个兜底提示。
这样做的好处是,前端体验更稳一点。
如果某一边临时有问题,不至于完全不能聊。
为什么不直接请求通义千问
前端直接请求通义千问看起来好像更简单。
但不建议这样做。
原因主要有两个。
第一,API Key 会暴露。
只要写在前端 JS 里,用户就能通过浏览器看到。
这个 Key 一旦泄露,别人就能拿去消耗你的额度。
第二,前端不好做访问控制。
如果接口直接暴露在浏览器里,很难限制来源,也不好统一处理错误、限流和提示文案。
所以更稳的结构还是:
1 | 前端页面 -> 自己的后端接口 -> 模型服务 |
函数计算刚好可以承担这个轻量后端。
这次踩到的点
这次主要有几个地方要注意。
workers.dev在国内访问不一定稳定,所以 AI 接口换到国内云更合适。- 百炼 API Key 只能放后端,不能放前端。
- 函数计算要处理
OPTIONS,否则跨域预检会失败。 - 前端和后端约定一个简单返回结构,比如
{ reply: '...' }。 - 先在浏览器控制台看接口请求,再去百炼和函数计算看用量。
整个流程跑通以后,前端其实不用关心模型来自哪里。
只要自己的接口稳定返回 reply,看板娘就可以继续在原来的气泡里回答问题。
以上就是我把 Hexo 看板娘 AI 切到通义千问的一些整理,如有错误,欢迎大佬指出。