Xem thêm: mua tài khoản ChatGPT Plus chính hãng giá rẻ với nhiều ưu đãi đặc biệt
Trong hướng dẫn này, bạn sẽ xây dựng một ứng dụng sử dụng các hàm OpenAI cùng với phiên bản mới nhất của Node.js SDK. Ứng dụng chạy trong trình duyệt, do đó bạn chỉ cần một trình soạn thảo mã và, ví dụ, VS Code Live Server để theo dõi cục bộ. Ngoài ra, hãy viết mã của bạn trực tiếp trong trình duyệt thông qua sân chơi mã này tại Scrimba.
Những gì bạn sẽ xây dựng
Ứng dụng của chúng tôi là một tác nhân đơn giản giúp bạn tìm các hoạt động trong khu vực của mình. Nó có quyền truy cập vào hai chức năng getLocation()và getCurrentWeather(), nghĩa là nó có thể xác định vị trí của bạn và thời tiết hiện tại.
Tại thời điểm này, điều quan trọng là phải hiểu rằng OpenAI không thực thi bất kỳ mã nào cho bạn. Nó chỉ cho ứng dụng của bạn biết những hàm nào cần sử dụng trong một tình huống nhất định và sau đó để ứng dụng của bạn gọi chúng.
Khi nhân viên của chúng tôi biết vị trí và thời tiết của bạn, họ sẽ sử dụng kiến thức nội bộ của GPT để gợi ý các hoạt động địa phương phù hợp cho bạn.
Nhập SDK và xác thực với OpenAI
Chúng tôi bắt đầu bằng cách nhập OpenAI SDK vào đầu tệp JavaScript và xác thực bằng khóa API, khóa này được lưu trữ dưới dạng biến môi trường.
import OpenAI from "openai"; const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY, dangerouslyAllowBrowser: true,});Vì chúng tôi đang chạy mã của mình trong môi trường trình duyệt tại Scrimba, chúng tôi cũng cần thiết lập dangerouslyAllowBrowser: trueđể xác nhận rằng chúng tôi hiểu các rủi ro liên quan đến các yêu cầu API phía máy khách. Xin lưu ý rằng bạn nên chuyển các yêu cầu này sang máy chủ Node trong ứng dụng sản xuất.
Tạo hai chức năng của chúng tôi
Tiếp theo, chúng ta sẽ tạo hai hàm. Hàm đầu tiên - getLocation- sử dụng IP API để lấy vị trí của người dùng.
async function getLocation() { const response = await fetch("https://ipapi.co/json/"); const locationData = await response.json(); return locationData;}API IP trả về một loạt dữ liệu về vị trí của bạn, bao gồm vĩ độ và kinh độ, mà chúng ta sẽ sử dụng làm đối số trong hàm thứ hai getCurrentWeather. Nó sử dụng API Open Meteo để lấy dữ liệu thời tiết hiện tại, như sau:
async function getCurrentWeather(latitude, longitude) { const url = `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}&hourly=apparent_temperature`; const response = await fetch(url); const weatherData = await response.json(); return weatherData;}Mô tả các chức năng của chúng tôi cho OpenAI
Để OpenAI hiểu được mục đích của các hàm này, chúng ta cần mô tả chúng bằng một lược đồ cụ thể. Chúng ta sẽ tạo một mảng có tên toolslà chứa một đối tượng cho mỗi hàm. Mỗi đối tượng sẽ có hai khóa: type, function, và functionkhóa có ba khóa con: name, description, và parameters.
const tools = [ { type: "function", function: { name: "getCurrentWeather", description: "Get the current weather in a given location", parameters: { type: "object", properties: { latitude: { type: "string", }, longitude: { type: "string", }, }, required: ["longitude", "latitude"], }, } }, { type: "function", function: { name: "getLocation", description: "Get the user's location based on their IP address", parameters: { type: "object", properties: {}, }, } },];Thiết lập mảng tin nhắn
Chúng ta cũng cần định nghĩa một messagesmảng. Mảng này sẽ theo dõi tất cả các tin nhắn qua lại giữa ứng dụng của chúng ta và OpenAI.
Đối tượng đầu tiên trong mảng phải luôn có thuộc roletính được đặt thành "system", điều này cho OpenAI biết rằng đây là cách chúng ta muốn nó hoạt động.
const messages = [ { role: "system", content: "You are a helpful assistant. Only use the functions you have been provided with.", },];Tạo chức năng tác nhân
Bây giờ chúng ta đã sẵn sàng xây dựng logic của ứng dụng, nằm trong hàm agent. Nó không đồng bộ và chỉ sử dụng một đối số: userInput.
Chúng ta bắt đầu bằng cách đẩy userInputvào mảng messages. Lần này, chúng ta đặt thành role, "user"để OpenAI biết rằng đây là đầu vào từ người dùng.
async function agent(userInput) { messages.push({ role: "user", content: userInput, }); const response = await openai.chat.completions.create({ model: "gpt-4", messages: messages, tools: tools, }); console.log(response);}Tiếp theo, chúng ta sẽ gửi yêu cầu đến điểm cuối hoàn thành trò chuyện thông qua chat.completions.create()phương thức trong Node SDK. Phương thức này lấy một đối tượng cấu hình làm đối số. Trong đó, chúng ta sẽ chỉ định ba thuộc tính:
model- Quyết định mô hình AI nào chúng ta muốn sử dụng (trong trường hợp này là tài khoản Chat GPT-4).messages- Toàn bộ lịch sử tin nhắn giữa người dùng và AI cho đến thời điểm này.tools- Danh sách các công cụ mà mô hình có thể gọi. Hiện tại, chỉ có các hàm được hỗ trợ như một công cụ., chúng ta sẽ sử dụng mảngtoolsđã tạo trước đó.
Chạy ứng dụng của chúng tôi với một đầu vào đơn giản
Hãy thử chạy chương trình agentcó dữ liệu đầu vào yêu cầu phải gọi hàm để đưa ra câu trả lời phù hợp.
agent("Where am I located right now?");Khi chúng ta chạy mã trên, chúng ta thấy phản hồi từ OpenAI được đăng xuất khỏi bảng điều khiển như thế này:
{ id: "chatcmpl-84ojoEJtyGnR6jRHK2Dl4zTtwsa7O", object: "chat.completion", created: 1696159040, model: "gpt-4-0613", choices: [{ index: 0, message: { role: "assistant", content: null, tool_calls: [ id: "call_CBwbo9qoXUn1kTR5pPuv6vR1", type: "function", function: { name: "getLocation", arguments: "{}" } ] }, logprobs: null, finish_reason: "tool_calls" // OpenAI wants us to call a function }], usage: { prompt_tokens: 134, completion_tokens: 6, total_tokens: 140 } system_fingerprint: null}Phản hồi này cho chúng ta biết rằng chúng ta nên gọi một trong các hàm của mình vì nó chứa khóa sau: finish_reason: "tool_calls".
Tên của hàm có thể được tìm thấy trong response.choices[0].message.tool_calls[0].function.namekhóa được đặt thành "getLocation".
Biến phản hồi của OpenAI thành lệnh gọi hàm
Bây giờ chúng ta đã có tên hàm dưới dạng chuỗi, chúng ta sẽ cần dịch nó thành lệnh gọi hàm. Để giúp chúng ta thực hiện việc đó, chúng ta sẽ tập hợp cả hai hàm của mình trong một đối tượng có tên là availableTools:
const availableTools = { getCurrentWeather, getLocation,};Điều này rất tiện lợi vì chúng ta có thể truy cập getLocationhàm thông qua ký hiệu ngoặc và chuỗi chúng ta nhận được từ OpenAI, như thế này: availableTools["getLocation"].
const { finish_reason, message } = response.choices[0]; if (finish_reason === "tool_calls" && message.tool_calls) { const functionName = message.tool_calls[0].function.name; const functionToCall = availableTools[functionName]; const functionArgs = JSON.parse(message.tool_calls[0].function.arguments); const functionArgsArr = Object.values(functionArgs); const functionResponse = await functionToCall.apply(null, functionArgsArr); console.log(functionResponse);}Chúng ta cũng sẽ nắm bắt mọi đối số mà OpenAI muốn chúng ta truyền vào hàm: message.tool_calls[0].function.arguments. Tuy nhiên, chúng ta sẽ không cần bất kỳ đối số nào cho lệnh gọi hàm đầu tiên này.
Nếu chúng ta chạy lại mã với cùng một đầu vào ( "Where am I located right now?"), chúng ta sẽ thấy đó functionResponse là một đối tượng được điền vị trí về nơi người dùng hiện đang ở. Trong trường hợp của tôi, đó là Oslo, Na Uy.
{ip: "193.212.60.170", network: "193.212.60.0/23", version: "IPv4", city: "Oslo", region: "Oslo County", region_code: "03", country: "NO", country_name: "Norway", country_code: "NO", country_code_iso3: "NOR", country_capital: "Oslo", country_tld: ".no", continent_code: "EU", in_eu: false, postal: "0026", latitude: 59.955, longitude: 10.859, timezone: "Europe/Oslo", utc_offset: "+0200", country_calling_code: "+47", currency: "NOK", currency_name: "Krone", languages: "no,nb,nn,se,fi", country_area: 324220, country_population: 5314336, asn: "AS2119", org: "Telenor Norge AS"}Chúng ta sẽ thêm dữ liệu này vào một mục mới trong mảng messages, tại đó chúng ta cũng chỉ định tên của hàm mà chúng ta đã gọi.
messages.push({ role: "function", name: functionName, content: `The result of the last function was this: ${JSON.stringify( functionResponse )} `,});Lưu ý rằng roleđược đặt thành "function". Điều này cho OpenAI biết rằng contenttham số chứa kết quả của lệnh gọi hàm chứ không phải dữ liệu đầu vào từ người dùng.
Tại thời điểm này, chúng ta cần gửi một yêu cầu mới đến OpenAI với messagesmảng đã cập nhật này. Tuy nhiên, chúng ta không muốn mã hóa cứng một lệnh gọi hàm mới, vì tác nhân của chúng ta có thể cần phải qua lại giữa chính nó và GPT nhiều lần cho đến khi tìm thấy câu trả lời cuối cùng cho người dùng.
Có thể giải quyết vấn đề này theo nhiều cách khác nhau, ví dụ như đệ quy, vòng lặp while hoặc vòng lặp for. Chúng ta sẽ sử dụng vòng lặp for cũ để đơn giản hóa.
Tạo vòng lặp
Ở đầu hàm agent, chúng ta sẽ tạo một vòng lặp cho phép chạy toàn bộ quy trình tối đa năm lần.
Nếu chúng ta quay lại finish_reason: "tool_calls"từ GPT, chúng ta sẽ đẩy kết quả của lệnh gọi hàm vào mảng messagesvà nhảy tới lần lặp tiếp theo của vòng lặp, kích hoạt một yêu cầu mới.
Nếu chúng ta quay finish_reason: "stop"lại thì GPT đã tìm thấy câu trả lời phù hợp, vì vậy chúng ta sẽ trả về hàm và hủy vòng lặp.
for (let i = 0; i < 5; i++) { const response = await openai.chat.completions.create({ model: "gpt-4", messages: messages, tools: tools, }); const { finish_reason, message } = response.choices[0]; if (finish_reason === "tool_calls" && message.tool_calls) { const functionName = message.tool_calls[0].function.name; const functionToCall = availableTools[functionName]; const functionArgs = JSON.parse(message.tool_calls[0].function.arguments); const functionArgsArr = Object.values(functionArgs); const functionResponse = await functionToCall.apply(null, functionArgsArr); messages.push({ role: "function", name: functionName, content: ` The result of the last function was this: ${JSON.stringify( functionResponse )} `, }); } else if (finish_reason === "stop") { messages.push(message); return message.content; }}return "The maximum number of iterations has been met without a suitable answer. Please try again with a more specific input.";Nếu chúng ta không thấy a finish_reason: "stop"trong năm lần lặp lại, chúng ta sẽ trả về thông báo cho biết không tìm thấy câu trả lời phù hợp.
Chạy ứng dụng cuối cùng
Lúc này, chúng ta đã sẵn sàng để dùng thử ứng dụng! Tôi sẽ yêu cầu nhân viên gợi ý một số hoạt động dựa trên vị trí của tôi và thời tiết hiện tại.
const response = await agent( "Please suggest some activities based on my location and the current weather.");console.log(response);Đây là những gì chúng ta thấy trong bảng điều khiển (được định dạng để dễ đọc hơn):
Based on your current location in Oslo, Norway and the weather (15°C and snowy),here are some activity suggestions: 1. A visit to the Oslo Winter Park for skiing or snowboarding.2. Enjoy a cosy day at a local café or restaurant.3. Visit one of Oslo's many museums. The Fram Museum or Viking Ship Museum offer interesting insights into Norway’s seafaring history.4. Take a stroll in the snowy streets and enjoy the beautiful winter landscape.5. Enjoy a nice book by the fireplace in a local library.6. Take a fjord sightseeing cruise to enjoy the snowy landscapes. Always remember to bundle up and stay warm. Enjoy your day!Nếu chúng ta xem xét kỹ hơn và đăng xuất response.choices[0].messageở mỗi lần lặp lại của vòng lặp, chúng ta sẽ thấy rằng GPT đã hướng dẫn chúng ta sử dụng cả hai hàm trước khi đưa ra câu trả lời.
Đầu tiên, nó bảo chúng ta gọi getLocationhàm. Sau đó, nó bảo chúng ta gọi getCurrentWeatherhàm với "longitude": "10.859", "latitude": "59.955"các đối số được truyền vào. Đây là dữ liệu mà nó nhận được từ lần gọi hàm đầu tiên mà chúng ta đã thực hiện.
{"role":"assistant","content":null,"tool_calls":[{"id":"call_Cn1KH8mtHQ2AMbyNwNJTweEP","type":"function","function":{"name":"getLocation","arguments":"{}"}}]}{"role":"assistant","content":null,"tool_calls":[{"id":"call_uc1oozJfGTvYEfIzzcsfXfOl","type":"function","function":{"name":"getCurrentWeather","arguments":"{\n\"latitude\": \"10.859\",\n\"longitude\": \"59.955\"\n}"}}]}Bây giờ bạn đã xây dựng được một tác nhân AI sử dụng các hàm OpenAI và Node.js SDK! Nếu bạn đang tìm kiếm một thử thách bổ sung, hãy cân nhắc nâng cao ứng dụng này. Ví dụ, bạn có thể thêm một hàm để lấy thông tin cập nhật về các sự kiện và hoạt động tại vị trí của người dùng.
Chúc bạn viết mã vui vẻ!

Cách đổi Mật khẩu Chat GPT - Hướng dẫn đổi Pass Chat GPT 100% Thành công
Hướng dẫn Cách đăng nhập Chat GPT Nhanh nhất | Có hỗ trợ Miễn phí qua Teamview-Ultraview
Chat GPT Plus là gì? So sánh Chat GPT Plus với Chat GPT Miễn phí
Chat GPT bị giới hạn giải thích vì sao và cách khắc phục
Chat GPT là gì ? Cách đăng Ký Chat GPT Miễn Phí tại Việt Nam