Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Redis

เพิ่มประสิทธิภาพ ลดต้นทุน: Cache OpenAI API Responses ด้วย Upstash Redis

หากเคยใช้ OpenAI API อาจสังเกตว่ามันช่อนิดหน่อย และบางครั้งไม่ตอบสนองเลย โดยเฉพาะ GPT-4 Model มี Latency สูง นอกจากนี้ยังจ่ายเงินต่อทุก Response เหล่านี้เป็นเหตุผลหลีกเลี่ยงการ Serve Responses โดยตรง

เก็บ Responses ไว้ใน Upstash Redis แทน หาก Serve Response เดียวกันให้หลาย Clients จะประหยัดเงินได้มาก และด้วย Global Deployments ผู้ใช้ได้ข้อมูลเร็วที่สุด

บทความนี้แนะนำการ Cache OpenAI API Responses ไป Upstash Redis Database

Features - ฟีเจอร์

สร้าง Web App แสดง History Jokes ให้ Visitors:

  1. Query OpenAI API ทุกวันเพื่อขอ History Joke ตามวันที่ปัจจุบัน
  2. Cache Joke ไว้สำหรับส่งต่อ
  3. แสดง Jokes ทั้งหมด

Technology - เทคโนโลยี

  • Node.js เป็น HTTP Server
  • OpenAI API Generate History Jokes
  • Upstash QStash Trigger Joke Request จาก HTTP Server ไป OpenAI API
  • Upstash Redis เก็บ Joke สำหรับใช้ภายหลัง

Prerequisites - เงื่อนไขก่อนเริ่ม

  • OpenAI Account พร้อม API Access
  • Upstash Account ส่ง Request ไป OpenAI และ Cache Responses ใน Upstash Redis
  • Node.js Installation เรียก OpenAI และ Upstash APIs

Implementation - การทำงาน

Setting Up the Project - ตั้งค่าโปรเจกต์

สร้าง Node.js Project ใหม่ Install Dependencies:

$ mkdir history-jokes & cd history-jokes
$ npm init -y
$ npm i dotenv express axios @upstash/redis @upstash/qstash

Implementing the Server - Implement Server

สร้าง index.js ใส่โค้ด:

require("dotenv").config();
const axios = require("axios");
const express = require("express");
const { Redis } = require("@upstash/redis");
const { Receiver } = require("@upstash/qstash");
const redisClient = new Redis({ url: process.env.UPSTASH_REDIS_URL, token: process.env.UPSTASH_REDIS_TOKEN });
const qstashReceiver = new Receiver({ currentSigningKey: process.env.UPSTASH_QSTASH_CURRENT_SIGNING_KEY, nextSigningKey: process.env.UPSTASH_QSTASH_CURRENT_NEXT_KEY });
const openaiApiClient = axios.create({ baseURL: "https://api.openai.com/v1", headers: { Authorization: "Bearer " + process.env.OPENAI_TOKEN, "Content-Type": "application/json" } });
const server = express();
server.use("/generate", async (request, response, next) => {
  let validRequest = false;
  try { validRequest = await qstashReceiver.verify({ signature: request.headers["upstash-signature"], body: "" }); } catch (e) {}
  if (!validRequest) return response.status(403).end("Forbidden");
  return next();
});
server.post("/generate", async (_request, response) => {
  const today = new Date();
  const month = today.toLocaleString("default", { month: "long" });
  let day = today.toLocaleString("default", { day: "numeric" });
  day = day == 1 ? "1st" : day == 2 ? "2nd" : day == "3" ? "3rd" : day + "th";
  const { data } = await openaiApiClient.post("/chat/completions", { model: "gpt-3.5-turbo", messages: [ { role: "system", content: "You are a comedian that tells short history jokes." }, { role: "user", content: `Please tell me a joke for ${month} the ${day}.` } ] });
  const joke = JSON.stringify({ date: month + " the " + day, text: data.choices[0].message.content });
  await redisClient.lpush("jokes", joke);
  response.end();
});
server.get("/", async (_request, response) => {
  let html = "<h1>History Jokes for Every Day</h1>";
  const jokes = await redisClient.lrange("jokes", 0, -1);
  html += "<ul>" + jokes.map(({ date, text }) => `<li><b>${date}</b><br><pre>${text}</pre></li>`).join("") + "</ul>";
  response.setHeader("Content-Type", "text/html");
  response.end(html);
});
server.listen(3000);

ส่วนสำคัญของโค้ด:

ใช้ redisClient Save/Load Responses ใน Upstash Redis

qstashReceiver Verify Daily Calls จาก Upstash QStash รับรองว่าแค่ QStash เรียก /generate Endpoint

ใช้ Axios สร้าง OpenAI API Client ไม่ต้องส่ง baseUrl และ Authentication Header ทุกครั้ง

สร้าง Express Middleware ใช้ qstashReceiver Verify Requests ไป /generate ใช้ Empty String เป็น body เพราะ QStash Trigger เท่านั้นไม่ส่งค่า

Note: Middleware อนุญาตทั้งหมดถ้า Un-comment // return next() ใช้ Test /generate บน localhost

/generate Endpoint Listen POST Requests สร้างและเก็บ Jokes คำนวณ month และ day สร้าง Prompts 2 อัน: บอก AI เป็น Comedian และขอ History Joke ตามเดือน/วัน เรียก OpenAI API Save Result ใน LIST Upstash Redis

/ Endpoint Listen GET Requests แสดง Jokes โหลด LIST จาก Upstash Redis Format HTML List Elements ส่ง Client

Deployment - การ Deploy

Server Ready สร้าง Cloud Resources และใส่ API Credentials

Creating a Credential File - สร้าง Credential File

สร้าง .env ด้วยเนื้อหา:

OPENAI_TOKEN=""
UPSTASH_REDIS_REST_URL=""
UPSTASH_REDIS_REST_TOKEN=""
UPSTASH_QSTASH_CURRENT_SIGNING_KEY=""
UPSTASH_QSTASH_NEXT_SIGNING_KEY=""

ขั้นตอนต่อไป Fill Strings เหล่านี้

Creating an OpenAI API Token - สร้าง OpenAI API Token

เริ่ม OpenAI API ต้องการ Key เฉพาะ ไม่ต้อง Deploy ไป OpenAI Web Console กด "Create New Secret Key" ตั้งชื่อ กด "Create Secret Key" Copy Key ใส่ .env เป็น OPENAI_TOKEN

Deploying a Recurring Request with QStash - Deploy Recurring Request ด้วย QStash

บอก QStash ให้ส่ง Request ไป /generate วันละครั้ง ใช้ "Request Builder" ใน Upstash Console Figure 1 แสดง Config:

เพิ่มประสิทธิภาพ ลดต้นทุน: Cache OpenAI API Responses ด้วย Upstash Redis

Figure 1: QStash Request Builder

แทนที่ <HOSTNAME> ด้วย Domain ที่ Host Server ต้องมี Publicly Accessible Hostname สำหรับ QStash

Signing Keys QStash ใช้ อยู่ใน Upstash Console Section "Request Builder" กด Grey "Signing Keys" Dropdown Copy Keys ใส่ .env ให้ถูกต้อง

Deploying an Upstash Redis Database - Deploy Upstash Redis Database

สร้าง Upstash Redis Database ไป Upstash Console กด "Create Database" Button

Dialog Config Database Figure 2 แสดงค่าที่ควรใช้:

เพิ่มประสิทธิภาพ ลดต้นทุน: Cache OpenAI API Responses ด้วย Upstash Redis

Figure 2: Upstash Redis Configuration

สร้างเสร็จ Scroll ลง "REST API" Section มี Buttons "UPSTASH_REDIS_REST_URL" และ "UPSTASH_REDIS_REST_TOKEN" กด Copy Credentials ใส่ .env ให้ถูก

Testing the Website - ทดสอบ Website

Test Local Machine Deactivate QStash Validation Middleware Un-comment // return next() ใน index.js

Run Server:

$ node .

เปิด / Route ใน Browser ควรเห็นแค่ "History Jokes for Every Day" เพราะยังไม่มี Jokes Generated

ส่ง POST Request ไป /generate Generate Joke:

$ curl -X POST https://localhost/generate

Refresh Browser ควรเห็น Joke เหมือน Figure 3:

เพิ่มประสิทธิภาพ ลดต้นทุน: Cache OpenAI API Responses ด้วย Upstash Redis

Figure 3: Joke Website

Joke นี้ Cached ใน Upstash Redis แล้ว ไม่มี OpenAI API Requests ตอน User Visit Website ได้ Sub-second Response Times ประหยัดเงินมาก

Summary - สรุป

AI APIs เป็น Tools หลากหลายจะ Transform Internet แต่วันนี้ Slow และ Expensive Caching Vital ตอนใช้ APIs นี้ Upstash Redis คือวิธีง่ายที่สุดเพิ่มใน Stack แค่ไม่กี่คลิก