尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

OpenRouter与Netlify AI Gateway集成:构建安全可控的AI应用代理层

OpenRouter与Netlify AI Gateway集成:构建安全可控的AI应用代理层 这类工具最值得先看的不是功能列表而是能不能在普通环境里稳定跑起来以及它到底解决了什么具体问题。OpenRouter 和 Netlify 的集成核心是让你能通过一个更稳定、更可控的 Web 服务去调用市面上那些主流的大语言模型比如 GPT、Claude、Llama 等等而不用自己一个个去处理 API 密钥、计费、限流和网络问题。它特别适合两类人一是想快速搭建一个 AI 应用原型但又不想在模型供应商、代理配置上折腾的开发者二是想把 AI 能力集成到现有网站或服务里需要一个统一、可监控的入口的团队。我建议先从最小样例开始确认整个链路能跑通再考虑怎么用到你自己的项目里。下面按实际落地顺序拆一遍。1. 先搞清楚 OpenRouter 和 Netlify AI Gateway 各自管什么很多人一看到“集成”就觉得是同一个东西其实这是两个服务分工很明确。理解错了后面配置和排查都会走弯路。1.1 OpenRouter你的“模型聚合器”你可以把 OpenRouter 想象成一个模型超市。它自己不做模型但它把 OpenAI、Anthropic、Google、Meta 等多家公司的模型 API 都接好了统一成一个接口给你用。它的价值在于统一接口不管后面是 GPT-4 还是 Claude 3你调用 OpenRouter 的 API 格式基本一样。统一计费你只需要给 OpenRouter 充值它会帮你跟各个模型供应商结算。模型发现它提供了一个模型列表和实时价格方便你根据预算和需求切换。但它有个问题你的前端代码比如浏览器里的 JavaScript如果直接调用 OpenRouter 的 API就需要把你的 OpenRouter API 密钥暴露给客户端这是非常不安全的。而且直接调用还可能遇到网络不稳定、需要处理跨域CORS等麻烦。1.2 Netlify AI Gateway你的“安全代理和缓存层”这就是 Netlify 出场的原因。Netlify AI Gateway 是一个服务你可以把它部署在 Netlify 上或者理解成 Netlify 提供的一个功能。它的核心作用有两个隐藏密钥你把 OpenRouter 的 API 密钥配置在 Netlify 的服务端环境变量里。前端只请求你自己的 Netlify 服务地址密钥永远不会暴露给用户。提供额外功能比如请求缓存、频率限制、日志记录、统一的错误处理。你可以把它看作一个专门为 AI API 设计的反向代理或网关。所以集成的流程是你的网站/应用 - Netlify AI Gateway (你的域名) - OpenRouter - 各大模型厂商。1.3 这个组合解决了什么实际问题不是所有项目都需要这个组合。如果你只是自己在本地跑个脚本直接用 OpenRouter 的 API 就行。这个集成的典型使用场景是构建面向公众的 AI 应用比如一个公开的写作助手、翻译工具、聊天机器人网站。你需要隐藏 API 密钥并管理用量。团队内部工具需要一个统一的、带访问控制的 AI 能力入口。需要缓存和降本对于某些不常变化或可重复的提示词Prompt通过 Gateway 缓存结果能显著降低 API 调用成本和提升响应速度。简化前端开发前端只需要对接一个固定的、自己域名的接口不用关心后端换了哪个模型或供应商。2. 动手之前先备齐这三样东西别急着写代码先把这几个账号和资源准备好能避免一大半“卡住”的问题。2.1 一个 OpenRouter 账号和 API 密钥访问 OpenRouter 官网注意使用合规的网络环境进行开发学习注册账号。登录后在控制台找到你的 API 密钥。它通常以sk-or-开头。最重要的一步充点钱。OpenRouter 是预付费模式大部分模型调用都需要账户里有余额。先充个 5-10 美元足够你做大量的测试。很多“模型不可用”或“请求失败”的错误根源就是账户余额为零。2.2 一个 Netlify 账号和一个待部署的项目如果你没有 Netlify 账号去官网注册一个。它有免费套餐对于初期测试和中小型项目完全够用。准备你的项目代码。这不是一个“无代码”配置你需要有一个可以部署的 Web 项目。最简单的是创建一个包含以下文件的文件夹index.html你的前端页面。netlify/functions/ai-gateway.js这是 Netlify Functions无服务器函数的目录和文件我们将在这里配置 AI Gateway。package.json如果你的函数需要依赖比如用 Node.js 写更复杂的逻辑。你的项目可以非常简单就是一个 HTML 页面加一个后端函数。Netlify 的核心部署方式是通过 Git 仓库GitHub, GitLab, Bitbucket连接或者直接拖拽文件夹上传。2.3 理解基本的请求流程和代码结构在脑子里过一遍这个数据流写代码时就不会乱用户在浏览器打开你的index.html点击按钮触发一个 AI 请求。前端 JavaScript 向/api/ai-gateway这个地址是你自己定义的发送一个fetch请求。Netlify 平台接收到对/api/ai-gateway的请求会自动执行netlify/functions/ai-gateway.js这个函数。这个函数内部使用你配置在 Netlify 环境变量中的 OpenRouter API 密钥向 OpenRouter 的官方接口发起请求。拿到 OpenRouter 的响应后再返回给你的前端页面。前端页面将结果显示出来。环境变量是关键你的 OpenRouter API 密钥绝不能写在ai-gateway.js代码文件里然后上传到 Git。必须通过 Netlify 网站后台的 “Environment Variables” 来设置。3. 从零开始部署一个最简单的集成示例我们现在就按最直接的步骤部署一个能跑通的例子。我建议你完全跟着做一遍之后再修改成你需要的样子。3.1 创建本地项目文件在你的电脑上新建一个文件夹例如openrouter-netlify-demo。然后创建以下文件文件 1index.html(前端页面)!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleOpenRouter Netlify 测试/title style body { font-family: sans-serif; max-width: 800px; margin: 2rem auto; padding: 1rem; } textarea, input, button { width: 100%; margin: 0.5rem 0; padding: 0.8rem; box-sizing: border-box; } #output { border: 1px solid #ccc; padding: 1rem; min-height: 100px; white-space: pre-wrap; background: #f9f9f9; } /style /head body h2AI 对话测试 (通过 Netlify Gateway)/h2 input typetext idmodel placeholder输入模型ID例如: openai/gpt-3.5-turbo valueopenai/gpt-3.5-turbo textarea idprompt placeholder输入你的问题... rows4用中文简单介绍一下你自己。/textarea button onclicksendRequest()发送请求/button div h4响应结果/h4 div idoutput等待请求.../div /div script async function sendRequest() { const model document.getElementById(model).value; const prompt document.getElementById(prompt).value; const output document.getElementById(output); output.textContent 请求中...; try { // 关键点这里请求的是我们自己的 Netlify Function 路径 const response await fetch(/.netlify/functions/ai-gateway, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ model, messages: [{ role: user, content: prompt }] }) }); if (!response.ok) { const err await response.text(); throw new Error(HTTP ${response.status}: ${err}); } const data await response.json(); // 解析 OpenRouter 返回的标准格式 if (data.choices data.choices[0] data.choices[0].message) { output.textContent data.choices[0].message.content; } else { output.textContent 响应格式异常: JSON.stringify(data, null, 2); } } catch (error) { output.textContent 请求失败: error.message; console.error(error); } } /script /body /html文件 2netlify/functions/ai-gateway.js(后端网关函数)// 注意这个文件必须放在 netlify/functions/ 目录下 exports.handler async (event, context) { // 1. 只处理 POST 请求 if (event.httpMethod ! POST) { return { statusCode: 405, body: Method Not Allowed }; } try { // 2. 解析前端传来的数据 const requestBody JSON.parse(event.body); const { model, messages } requestBody; if (!model || !messages) { return { statusCode: 400, body: JSON.stringify({ error: 缺少必要参数: model 或 messages }) }; } // 3. 从环境变量读取 OpenRouter API 密钥 // 这个变量需要在 Netlify 网站后台设置名字必须叫 OPENROUTER_API_KEY const apiKey process.env.OPENROUTER_API_KEY; if (!apiKey) { console.error(OPENROUTER_API_KEY 环境变量未设置); return { statusCode: 500, body: JSON.stringify({ error: 服务器配置错误 }) }; } // 4. 构造请求转发给 OpenRouter const openRouterResponse await fetch(https://openrouter.ai/api/v1/chat/completions, { method: POST, headers: { Authorization: Bearer ${apiKey}, Content-Type: application/json, // OpenRouter 要求添加这个头部来标识你的应用可选但推荐 HTTP-Referer: event.headers.referer || https://your-netlify-site.netlify.app, X-Title: Netlify AI Gateway Demo }, body: JSON.stringify({ model: model, // 例如 openai/gpt-3.5-turbo messages: messages // 标准消息格式 }) }); // 5. 获取 OpenRouter 的原始响应 const responseData await openRouterResponse.json(); // 6. 将响应原样返回给前端 return { statusCode: openRouterResponse.status, headers: { Content-Type: application/json }, body: JSON.stringify(responseData) }; } catch (error) { console.error(Gateway 函数内部错误:, error); return { statusCode: 500, body: JSON.stringify({ error: 内部服务器错误, details: error.message }) }; } };文件 3package.json(可选但推荐){ name: openrouter-netlify-demo, version: 1.0.0, description: Demo for OpenRouter with Netlify AI Gateway, dependencies: {} }这个文件不是必须的但有了它Netlify 会更明确地将其识别为一个 Node.js 项目。3.2 在 Netlify 上配置环境和部署登录 Netlify点击 “Add new site” - “Import an existing project”。连接你的 GitHub/GitLab 仓库或者直接选择 “Deploy manually” 拖拽你刚才创建的整个文件夹上传。站点开始构建和部署。稍等片刻Netlify 会给你一个xxx.netlify.app的临时域名。关键配置设置环境变量。在 Netlify 站点管理后台进入 “Site configuration” - “Environment variables”。点击 “Add variable”。Key输入OPENROUTER_API_KEYValue输入你在 OpenRouter 控制台获取的sk-or-xxx密钥。点击 “Save”。注意如果你已经部署了一次修改环境变量后需要点击 “Deploy settings” 里的 “Trigger deploy” 重新部署一次新环境变量才会生效。部署完成后访问你的xxx.netlify.app域名。你应该能看到一个简单的页面。在模型输入框里保持openai/gpt-3.5-turbo这是最便宜且稳定的测试模型在问题框里输入中文或英文问题点击“发送请求”。如果一切正常几秒后你就能在下方看到 AI 的回复。恭喜集成成功了4. 成功之后排查、优化和进阶用法第一次跑通只是开始。在实际项目中你会遇到各种问题也需要考虑如何优化。4.1 请求失败的常见原因和排查顺序如果点击按钮后看到“请求失败”别慌按这个顺序查检查 OpenRouter 账户余额这是最常见的原因。去 OpenRouter 控制台看看余额是否大于 0。即使请求失败也可能因为鉴权预检查而扣一点费用。检查 Netlify 环境变量确认变量名OPENROUTER_API_KEY完全一致没有空格。确认值是正确的没有遗漏字符。确认重新部署了。修改环境变量后必须触发一次新的部署。检查浏览器开发者工具F12打开 “Network” 标签页查看发送到/.netlify/functions/ai-gateway的请求。看状态码500通常是网关函数内部错误检查函数日志400是请求参数错误405是请求方法不对。查看响应体里面通常有更详细的错误信息。检查 Netlify Function 日志在 Netlify 站点后台进入 “Functions” 标签页找到ai-gateway函数。查看每次调用的日志。这里会打印出console.error的内容比如“环境变量未设置”或网络请求的错误。这是最强大的调试工具。检查模型标识符确保你输入的模型 ID 是 OpenRouter 支持的。可以去 OpenRouter 的模型列表页面查看正确的 ID例如anthropic/claude-3-haiku、google/gemini-flash-1.5。检查请求格式OpenRouter 的聊天接口兼容 OpenAI 格式但务必确保messages是一个数组且每个对象包含role和content。4.2 为你的网关函数增加实用功能基础的转发功能有了我们可以把它变得更强大、更实用。功能一添加请求缓存对于相同的问题缓存可以极大提升响应速度并节省费用。修改ai-gateway.jsconst crypto require(crypto); exports.handler async (event, context) { // ... 之前的检查代码 ... // 在转发请求前生成一个请求内容的哈希值作为缓存键 const cacheKey crypto.createHash(md5).update(JSON.stringify({model, messages})).digest(hex); // 这里可以使用 Netlify 内置的缓存或者连接一个外部缓存服务如 Redis // 以下是一个简单的内存缓存示例注意Netlify Function 是无状态的生产环境应用外部缓存 // const cachedResponse await getFromCache(cacheKey); // if (cachedResponse) { return { statusCode: 200, body: cachedResponse }; } // ... 原来的转发请求代码 ... // 在得到 openRouterResponse 后存储到缓存生产环境实现 // await saveToCache(cacheKey, JSON.stringify(responseData), 300); // 缓存5分钟 };生产环境建议使用 Netlify 的 On-demand Builders 或集成 Upstash Redis 等服务来实现跨请求的缓存。功能二添加频率限制和认证防止你的公开接口被滥用。// 简单的基于 IP 的频率限制示例生产环境需更严谨 const rateLimitMap new Map(); // 注意无状态函数中此 map 无效需用外部存储 exports.handler async (event, context) { const clientIp event.headers[client-ip] || event.headers[x-forwarded-for]; const now Date.now(); const windowMs 60 * 1000; // 1分钟 const maxRequests 10; // 最多10次 // 生产环境应从 Redis 等读取计数 // const requestCount await getRequestCount(clientIp, windowMs); // if (requestCount maxRequests) { // return { statusCode: 429, body: 请求过于频繁请稍后再试。 }; // } // await incrementRequestCount(clientIp); // ... 后续处理逻辑 ... };更完善的方案是使用 Netlify 的 Identity 服务来做用户认证只允许注册用户调用。功能三统一错误处理和日志exports.handler async (event, context) { const requestId context.awsRequestId; // 唯一的请求ID const logData { requestId, path: event.path, method: event.httpMethod, clientIp: event.headers[client-ip], timestamp: new Date().toISOString() }; try { // ... 业务逻辑 ... console.log(JSON.stringify({ ...logData, status: success, model })); return { statusCode: 200, headers, body }; } catch (error) { // 捕获未预料的错误 console.error(JSON.stringify({ ...logData, status: error, error: error.message, stack: error.stack })); return { statusCode: 500, body: JSON.stringify({ error: 服务暂时不可用, requestId }) // 给前端返回请求ID便于追踪 }; } };4.3 模型选择与成本控制建议OpenRouter 最大的优势是模型多但选择也多到让人困惑。给几点落地建议测试和开发阶段用openai/gpt-3.5-turbo或google/gemini-flash-1.5。它们速度快、成本极低足够验证逻辑。需要更强推理或创意考虑anthropic/claude-3-haiku性价比高或openai/gpt-4能力最强但贵。需要处理超长上下文关注claude-3-5-sonnet200K或gpt-4-turbo128K。完全开源和私有化可以选择meta-llama/llama-3-70b-instruct等模型但注意其性能可能不如商业模型稳定。成本控制在 OpenRouter 后台设置预算提醒。在 Netlify Gateway 层实现缓存这是最有效的省钱方式。前端设计上对于耗时较长的复杂任务考虑使用流式响应Server-Sent Events 或 WebSocket而不是让用户长时间等待同时避免因超时导致的重复请求。监控用量定期查看 OpenRouter 的用量统计和 Netlify Function 的调用次数与耗时。5. 生产环境部署的注意事项当你的演示项目要变成一个真正的、有人使用的服务时需要考虑以下几点5.1 安全性加固环境变量确保OPENROUTER_API_KEY等所有密钥都保存在 Netlify 环境变量中绝不提交到代码仓库。CORS 设置如果你的前端和 API 不在同一个域名下需要在网关函数返回的 headers 中正确设置 CORS。headers: { Content-Type: application/json, Access-Control-Allow-Origin: https://你的前端域名.com, // 严格指定不要用 * Access-Control-Allow-Methods: POST, OPTIONS, Access-Control-Allow-Headers: Content-Type }输入验证与清理对前端传入的model、messages内容进行严格的验证和清理防止注入攻击。特别是messages中的用户内容如果最终要展示给其他用户需注意防范 XSS。访问控制如前所述使用 Netlify Identity 或自定义的 JWT 令牌来实现 API 访问认证。5.2 性能和可靠性函数超时Netlify Functions 默认有 10 秒的执行超时限制。对于复杂的提示词或慢速模型可能不够。你可以在netlify.toml配置文件中增加超时时间最高可配到 30 秒。[functions] [functions.ai-gateway] timeout 30 # 单位秒冷启动无服务器函数有冷启动延迟。对于要求瞬时响应的应用可以考虑通过设置一个定时器定期“预热”函数或者使用 Netlify 的付费计划获得更好的性能。错误重试在网关函数内可以考虑对 OpenRouter 的请求实现简单的重试逻辑例如对网络错误或 5xx 状态码重试一次提升最终用户体验。监控与告警利用 Netlify 的 Analytics 和 Functions 日志监控调用量、错误率和耗时。可以设置告警当错误率突增时通知你。5.3 替代方案与边界思考OpenRouter Netlify 这个组合很好但它不是唯一解也不适合所有场景。如果你只需要 OpenAI 的模型可以考虑直接使用 OpenAI 官方 API并通过类似方式用 Netlify Function 代理。这样少了一层依赖。如果你的应用流量很大可能需要考虑自建一个更强大的后端服务如 Node.js Express 部署在 VPS 或容器中而不是完全依赖无服务器函数以便更好地管理连接池、内存和持久化缓存。Netlify AI Gateway 的“官方”用法Netlify 自己也推出了一个更集成的 AI Gateway 产品它可以直接代理多个供应商包括 OpenAI、Anthropic并提供统一的仪表盘。如果你的项目完全在 Netlify 生态内也可以直接探索这个方案可能配置更简单。我们本文介绍的是更通用、更可控的“自己实现网关”的模式。这个方案真正落地时最该盯住的不是功能列表而是输入格式、资源占用和失败重试。先从最简单的模型、最小的请求把链路跑通加上缓存和基础监控然后再根据实际需求去迭代功能。这样既能快速验证想法又能保证核心服务的稳定。
返回列表