Του Hassan Djirdeh (@djirdehh)
Αυτό το άρθρο είναι το πρώτο άρθρο και σεμινάριο που αποστέλλεται στο ενημερωτικό δελτίο frontendfresh.com. Εγγραφείτε στοΕνημερωτικό δελτίο Front-end Freshγια να λαμβάνετε συμβουλές μηχανικής, σεμινάρια και έργα στο front-end που αποστέλλονται στα εισερχόμενά σας σε εβδομαδιαία βάση!
Αυτό το άρθρο είναι το πρώτο email μιας σειράς εκμάθησης 3 έως 4 μερών, όπου θα εργαστούμε για να δημιουργήσουμε το δικό μας προσαρμοσμένο chatbot Q&A. Αυτό θα το πετύχουμε με:
- Δημιουργία διακομιστή Node/Express για αλληλεπίδραση με τα API του OpenAI (σημερινό email).
- Χρησιμοποιώντας το React για τη δημιουργία της διεπαφής χρήστη του chatbot Q&A.
- Τέλος, στη συνέχεια, θα διερευνήσουμε πώς να βελτιστοποιήσουμε την εφαρμογή μας, ώστε το chatbot Q&A να επιστρέφει προσαρμοσμένες πληροφορίες.
Η τελική μας εφαρμογή θα μοιάζει με το εξής:
Σήμερα, θα επικεντρωθούμε αποκλειστικά στη δημιουργία ενός διακομιστή Node.js όπου μπορούμε να αλληλεπιδράσουμε απευθείας με τα API του OpenAI. Αυτός είναι ένας πρόδρομος για τη ρύθμιση της εφαρμογής διεπαφής μας, η οποία στη συνέχεια θα αλληλεπιδρά με το τοπικό API που θα δημιουργήσουμε.
Εάν θέλετε να ακολουθήσετε, θα χρειαστείτε το Node και το NPM εγκατεστημένο στον υπολογιστή σας και ένα κλειδί OpenAI API (θα σας δείξουμε πώς να το αποκτήσετε στην επόμενη ενότητα).
Δημιουργία κλειδιού OpenAI API
Ακολουθήστε αυτά τα βήματα για να δημιουργήσετε ένα κλειδί API με το OpenAI:
- Εγγραφείτε για έναν λογαριασμό μεταβαίνοντας στον ιστότοπο του OpenAI (https://platform.openai.com/).
- Μόλις δημιουργηθεί ένας λογαριασμός, επισκεφτείτε τη σελίδα κλειδιών API στη διεύθυνση https://platform.openai.com/account/api-keys.
- Δημιουργήστε ένα νέο κλειδί κάνοντας κλικ στο κουμπί "Δημιουργία νέου μυστικού κλειδιού".
Όταν δημιουργείται ένα κλειδί API, θα μπορείτε να αντιγράψετε το μυστικό κλειδί και να το χρησιμοποιήσετε όταν ξεκινήσετε την ανάπτυξη.
Σημείωση: Το OpenAI παρέχει επί του παρόντος δωρεάν πιστώσεις 18$ για 3 μήνες, κάτι που είναι υπέροχο, καθώς δεν θα χρειαστεί να παρέχετε τα στοιχεία πληρωμής σας για να αρχίσετε να αλληλεπιδράτε με το API για πρώτη φορά.
Ρύθμιση εφαρμογής Node/Express
Τώρα θα προχωρήσουμε στη δημιουργία ενός νέου καταλόγου για το έργο Node μας και θα το ονομάσουμε custom_chat_gpt
.
mkdir custom_chat_gpt
Θα πλοηγηθούμε στον νέο κατάλογο και θα εκτελέσουμε την ακόλουθη εντολή για να δημιουργήσουμε ένα αρχείο package.json
.
npm init -y
Μόλις δημιουργηθεί κατάλληλα το αρχείο package.json
, θα εγκαταστήσουμε τις τρεις εξαρτήσεις που θα χρειαστούμε προς το παρόν.
npm install dotenv express openai
dotenv
: θα μας επιτρέψει να φορτώσουμε μεταβλητές περιβάλλοντος από ένα αρχείο.env
όταν εργαζόμαστε τοπικά.express
: είναι το πλαίσιο Node.js που θα χρησιμοποιήσουμε για την περιστροφή ενός διακομιστή Node.openai
: είναι η βιβλιοθήκη Node.js για το OpenAI API.
Στη συνέχεια, θα δημιουργήσουμε ένα αρχείο με το όνομα index.js
. Το αρχείο index.js
είναι το μέρος όπου θα δημιουργήσουμε τον διακομιστή Node.js/Express.
Στο αρχείο index.js
, θα:
- Συμπεριλάβετε την ενότητα
express
μεrequire("express")
. - Στη συνέχεια, θα εκτελέσουμε τη συνάρτηση
express()
για να ορίσουμε το στιγμιότυπο Express και να το αντιστοιχίσουμε σε μια σταθερά με την ένδειξηapp
. - Θα καθορίσουμε ένα ενδιάμεσο λογισμικό στην παρουσία μας Express (με
app.use()
) για την ανάλυση των εισερχόμενων αιτημάτων JSON και την τοποθέτηση των αναλυμένων δεδομένων σε ένα σώμαreq
. - Θα καθορίσουμε μια μεταβλητή
port
στην οποία θα δοθεί μια τιμή που προέρχεται από μια μεταβλητή περιβάλλοντοςPORT
ή5000
εάν η μεταβλητή περιβάλλοντοςPORT
δεν έχει οριστεί.
const express = require("express"); const app = express(); app.use(express.json()); const port = process.env.PORT || 5000;
Στη συνέχεια, θα ρυθμίσουμε μια διαδρομή POST
με την ένδειξη /ask
που θα λειτουργεί ως το τελικό σημείο που θα ενεργοποιήσει ο πελάτης μας. Σε αυτήν τη διαδρομή, θα περιμένουμε να υπάρχει μια τιμή prompt
στο σώμα του αιτήματος και αν δεν υπάρχει, θα ρίξουμε ένα σφάλμα. Εάν η τιμή prompt
υπάρχει, απλώς θα επιστρέψουμε μια απάντηση κατάστασης 200
που περιέχει το prompt
σε ένα πεδίο message
.
Τέλος, θα εκτελέσουμε τη συνάρτηση app.listen()
για να ακούει η εφαρμογή μας την τιμή θύρας που έχουμε καθορίσει στη μεταβλητή port
.
const express = require("express"); const app = express(); app.use(express.json()); const port = process.env.PORT || 5000; // POST request endpoint app.post("/ask", async (req, res) => { // getting prompt question from request const prompt = req.body.prompt; try { if (prompt == null) { throw new Error("Uh oh, no prompt was provided"); } // return the result return res.status(200).json({ success: true, message: prompt, }); } catch (error) { console.log(error.message); } }); app.listen(port, () => console.log(`Server is running on port ${port}!!`));
Με αυτή την αλλαγή αποθηκευμένη, θα είναι η κατάλληλη στιγμή να ελέγξουμε ότι οι αλλαγές μας λειτουργούν. Θα τρέξουμε τον διακομιστή με:
node index.js
Με τον διακομιστή μας σε λειτουργία, μπορούμε στη συνέχεια να προσπαθήσουμε να ενεργοποιήσουμε το αίτημα /ask
POST μέσω μιας εντολής CURL
για να επαληθεύσουμε ότι ο διακομιστής μας έχει ρυθμιστεί κατάλληλα.
curl -X POST \ http://localhost:5000/ask \ -H 'Content-Type: application/json' \ -d '{ "prompt": "Hi! This is a test prompt!" }'
Θα λάβουμε επιτυχή απάντηση και θα μας επιστραφεί η προτροπή μας.
Με τον διακομιστή μας να λειτουργεί τώρα όπως προβλέπεται, μπορούμε να προχωρήσουμε στην αλληλεπίδραση του τελικού σημείου /ask
με το τελικό σημείο /completions
του OpenAI.
Αλληλεπίδραση με το τελικό σημείο ολοκλήρωσης του OpenAI
Το OpenAI παρέχει ένα /completions
τελικό σημείο στο API του που παρέχει προτάσεις ολοκλήρωσης για την εισαγωγή κειμένου.
Όταν στέλνουμε ένα αίτημα στο τελικό σημείο /completions
και συμπεριλάβουμε ένα μήνυμα προτροπής ή ένα αρχικό κείμενο, το API θα δημιουργήσει μια συνέχεια αυτού του κειμένου με βάση τα δεδομένα εκπαίδευσης του.
Με αυτό το τελικό σημείο /completions
, μπορούμε να δημιουργήσουμε τη δική μας προσαρμοσμένη έκδοση του ChatGPT (με κάποια προειδοποίηση ότι το ChatGPT πιθανότατα χρησιμοποιεί ένα πιο ισχυρό μοντέλο Machine Learning που δεν είναι διαθέσιμο μέσω του OpenAI API).
Για να αλληλεπιδράσουμε με το OpenAI API, θα χρειαστούμε το μοναδικό κλειδί API που δημιουργήσαμε νωρίτερα μέσω του ιστότοπου OpenAI. Οι ευαίσθητες πληροφορίες, όπως τα κλειδιά API, δεν πρέπει να κωδικοποιούνται απευθείας στον πηγαίο κώδικα της εφαρμογής.
Θα δημιουργήσουμε ένα αρχείο .env
στον ριζικό κατάλογο του έργου μας για την αποθήκευση μεταβλητών περιβάλλοντος που περιέχουν ευαίσθητες πληροφορίες.
custom_chat_gpt .env // ...
Στο αρχείο .env
, θα δημιουργήσουμε μια νέα μεταβλητή περιβάλλοντος με την ετικέτα OPENAI_API_KEY
και θα της δώσουμε την τιμή του κλειδιού OpenAI API.
# your unique API key value goes here OPENAI_API_KEY=sk-############
Στο αρχείο index.js
, θα απαιτήσουμε και θα χρησιμοποιήσουμε τη λειτουργική μονάδα dotenv
για να φορτώσουμε μεταβλητές περιβάλλοντος από το αρχείο .env
στο περιβάλλον process
της εφαρμογής μας. Θα εισαγάγουμε επίσης τις κλάσεις που θα χρειαστούμε από τη βιβλιοθήκη openai
Node.js — τις κλάσεις Configuration
και OpenAIApi
.
// configure dotenv require("dotenv").config(); // import modules from OpenAI library const { Configuration, OpenAIApi } = require("openai"); // ...
Στη συνέχεια, θα χρειαστεί να δημιουργήσουμε ένα αντικείμενο διαμόρφωσης για την αλληλεπίδραση με το OpenAI API. Θα το κάνουμε αυτό εγκαθιστώντας τον κατασκευαστή Configuration()
και περνώντας την τιμή της μεταβλητής περιβάλλοντος OPENAI_API_KEY
στο πεδίο apiKey
.
const configuration = new Configuration({ apiKey: process.env.OPENAI_API_KEY, });
Στη συνέχεια, θα ρυθμίσουμε μια νέα παρουσία της κλάσης OpenAI API όπως η εξής:
const configuration = new Configuration({ apiKey: process.env.OPENAI_API_KEY, }); const openai = new OpenAIApi(configuration);
Μπορούμε τώρα να χρησιμοποιήσουμε τη μεταβλητή openai
που δημιουργήσαμε για να πραγματοποιούμε κλήσεις API και να επεξεργαστούμε απαντήσεις από το OpenAI.
Στη συνάρτηση αιτήματος /ask
POST, θα εκτελέσουμε τη συνάρτηση openai.createCompletion()
που ουσιαστικά ενεργοποιεί μια κλήση στο τελικό σημείο ολοκλήρωσης του OpenAI.
app.post("/ask", async (req, res) => { const prompt = req.body.prompt; try { if (prompt == null) { throw new Error("Uh oh, no prompt was provided"); } // trigger OpenAI completion const response = await openai.createCompletion(); // ... } catch (error) { console.log(error.message); } });
Το τελικό σημείο ολοκλήρωσης OpenAI μας επιτρέπει να μεταβιβάσουμε έναν μεγάλο αριθμό προαιρετικών πεδίων στο αίτημα για να τροποποιήσουμε τον τρόπο με τον οποίο θέλουμε να συμπεριφέρεται η συμπλήρωση του κειμένου μας. Για την περίπτωση χρήσης μας, θα εξετάσουμε μόνο την παροχή τιμών για δύο πεδία — model
και prompt
.
model
: καθορίζει το όνομα του μοντέλου γλώσσας που πρέπει να χρησιμοποιήσει το API για να δημιουργήσει την απάντηση στο αίτημα. Το OpenAI παρέχει πολλά διαφορετικά μοντέλα γλώσσας, το καθένα με τα δυνατά του σημεία και τις δυνατότητές του. Για την περίπτωση χρήσης μας, θα καθορίσουμε ότι θέλουμε να χρησιμοποιήσουμε το μοντέλοtext-davinci-003
που είναι το πιο ικανό μοντέλο GPT-3 του OpenAI.prompt
: είναι η προτροπή για την οποία θέλουμε το OpenAI να δημιουργήσει μια ολοκλήρωση. Εδώ απλώς θα μεταβιβάσουμε την τιμήprompt
που υπάρχει στο σώμα του αιτήματός μας/ask
.
app.post("/ask", async (req, res) => { const prompt = req.body.prompt; try { if (prompt == null) { throw new Error("Uh oh, no prompt was provided"); } // trigger OpenAI completion const response = await openai.createCompletion({ model: "text-davinci-003", prompt, }); // ... } catch (error) { console.log(error.message); } });
Το κείμενο που επιστρέφεται από την απόκριση OpenAI υπάρχει μέσα σε έναν πίνακα choices
που ο ίδιος βρίσκεται μέσα σε ένα αντικείμενο response.data
. Θα προσπαθήσουμε να αποκτήσουμε πρόσβαση στο κείμενο που επιστράφηκε από την πρώτη επιλογή που επιστράφηκε στο API, το οποίο θα έχει την εξής μορφή:
app.post("/ask", async (req, res) => { const prompt = req.body.prompt; try { if (prompt == null) { throw new Error("Uh oh, no prompt was provided"); } const response = await openai.createCompletion({ model: "text-davinci-003", prompt, }); // retrieve the completion text from response const completion = response.data.choices[0].text; // ... } catch (error) { console.log(error.message); } });
Το τελευταίο πράγμα που θα κάνουμε είναι να επιστραφεί αυτή η απάντηση ολοκλήρωσης στην επιτυχή απάντηση του αιτήματός μας /ask
. Με αυτήν την αλλαγή και όλες τις αλλαγές που κάναμε, το αρχείο index.js
μας θα έχει την εξής μορφή.
require("dotenv").config(); const express = require("express"); const { Configuration, OpenAIApi } = require("openai"); const app = express(); app.use(express.json()); const configuration = new Configuration({ apiKey: process.env.OPENAI_API_KEY, }); const openai = new OpenAIApi(configuration); const port = process.env.PORT || 5000; app.post("/ask", async (req, res) => { const prompt = req.body.prompt; try { if (prompt == null) { throw new Error("Uh oh, no prompt was provided"); } const response = await openai.createCompletion({ model: "text-davinci-003", prompt, }); const completion = response.data.choices[0].text; return res.status(200).json({ success: true, message: completion, }); } catch (error) { console.log(error.message); } }); app.listen(port, () => console.log(`Server is running on port ${port}!!`));
Θα αποθηκεύσουμε τις αλλαγές μας και θα επανεκκινήσουμε τον διακομιστή μας. Με τον διακομιστή μας σε λειτουργία, μπορούμε να κάνουμε ορισμένες ερωτήσεις στο API μας όπως "What is the typical weather in Dubai?"
.
curl -X POST \ http://localhost:5000/ask \ -H 'Content-Type: application/json' \ -d '{ "prompt": "What is the typical weather in Dubai?" }'
Αφού περιμένουμε μερικά δευτερόλεπτα, το API μας θα μας επιστρέψει μια έγκυρη απάντηση στην ερώτησή μας!
Αυτό είναι! Καταφέραμε να δημιουργήσουμε ένα απλό API με Node/Express για αλληλεπίδραση με το τελικό σημείο ολοκλήρωσης του OpenAI.
Στο επόμενο εκπαιδευτικό μήνυμα ηλεκτρονικού ταχυδρομείου που θα στείλουμε, θα συνεχίσουμε σε αυτόν τον οδηγό δημιουργώντας μια εφαρμογή React που ενεργοποιεί το αίτημα /ask
όταν υποβάλλεται ένα πεδίο εισαγωγής.
Κλείσιμο σκέψεις
- Μπορείτε να βρείτε τον πηγαίο κώδικα για αυτό το άρθρο στη διεύθυνση github.com/djirdehh/frontend-fresh/articles_source_code.
- Αλληλεπιδράστε με το τελικό σημείο
/completions
και μη διστάσετε να το ζητήσετε όποια προτροπή θέλετε! - Εάν δεν είστε λάτρης της χρήσης
curl
για τη δοκιμή αιτημάτων τοπικά, το Postman είναι ένα δημοφιλές εργαλείο για τη δοκιμή αιτημάτων API μέσω ενός πελάτη. - Διαβάστε περισσότερα για όλα τα διαφορετικά προαιρετικά πεδία που μπορούμε να παρέχουμε στο τελικό σημείο
/completion
του OpenAI στην τεκμηρίωση OpenAI API. - Εγγραφείτε στο https://www.frontendfresh.com/ για περισσότερα σεμινάρια όπως αυτό για να βγάζετε τα εισερχόμενά σας σε εβδομαδιαία βάση!
Δημιουργήστε εφαρμογές με επαναχρησιμοποιήσιμα στοιχεία, όπως και η Lego
Το εργαλείο ανοιχτού κώδικα του Bitβοηθά 250.000+ προγραμματιστές να δημιουργήσουν εφαρμογές με στοιχεία.
Μετατρέψτε οποιαδήποτε διεπαφή χρήστη, δυνατότητα ή σελίδα σε επαναχρησιμοποιήσιμο στοιχείο — και μοιραστείτε το στις εφαρμογές σας. Είναι πιο εύκολο να συνεργαστείτε και να χτίσετε πιο γρήγορα.
Διαχωρίστε τις εφαρμογές σε στοιχεία για να διευκολύνετε την ανάπτυξη εφαρμογών και απολαύστε την καλύτερη εμπειρία για τις ροές εργασίας που θέλετε: