Cách sử dụng Grok API với JavaScript

Grok API cho phép ứng dụng JavaScript kết nối trực tiếp với các mô hình Grok để tạo nội dung, phân tích dữ liệu, hỗ trợ lập trình, xây dựng chatbot và nhiều tính năng AI khác. Thay vì chỉ sử dụng Grok thông qua giao diện trò chuyện, bạn có thể đưa khả năng xử lý của Grok vào website, máy chủ Node.js hoặc các hệ thống backend của riêng mình.

Điểm quan trọng khi tích hợp là hiểu đúng cách API hoạt động: ứng dụng gửi yêu cầu đến máy chủ xAI, truyền API key để xác thực, chỉ định model và nội dung cần xử lý, sau đó nhận kết quả từ API để tiếp tục xử lý trong JavaScript.

Bài viết này hướng dẫn theo hướng thực tế, từ khâu chuẩn bị API key, cài đặt thư viện, gửi yêu cầu đầu tiên cho đến cách tổ chức mã nguồn an toàn. Các phần nâng cao như hội thoại nhiều lượt, xử lý lỗi, streaming, tích hợp frontend và tối ưu ứng dụng sẽ được trình bày ở các đợt tiếp theo.

Cách sử dụng Grok API với JavaScript
Cách sử dụng Grok API với JavaScript

Grok API hoạt động như thế nào khi dùng JavaScript?

Về bản chất, Grok API là một giao diện lập trình giúp ứng dụng của bạn gửi dữ liệu đến hệ thống AI và nhận kết quả trả về. JavaScript đóng vai trò là lớp trung gian thực hiện việc tạo request, truyền dữ liệu và xử lý response.

Một luồng xử lý thông thường có thể hình dung như sau:

  1. Người dùng nhập yêu cầu vào ứng dụng.
  2. JavaScript nhận nội dung từ người dùng.
  3. Ứng dụng gửi request đến API của xAI.
  4. API xác thực API key và xử lý yêu cầu bằng model được chỉ định.
  5. Grok tạo kết quả.
  6. JavaScript nhận response và hiển thị hoặc xử lý kết quả.

API hiện cung cấp endpoint inference tại https://api.x.ai và sử dụng cơ chế xác thực bằng Bearer API key. Với việc tạo nội dung văn bản, Responses API là giao diện chính được xAI khuyến nghị sử dụng.

Điều này cũng có nghĩa bạn không cần xây dựng một hệ thống AI riêng từ đầu. Phần ứng dụng của bạn chủ yếu đảm nhiệm giao diện, dữ liệu đầu vào, logic nghiệp vụ và cách sử dụng kết quả trả về.

Cần chuẩn bị gì trước khi lập trình?

Để bắt đầu, bạn cần một tài khoản xAI có quyền sử dụng API, một API key và môi trường JavaScript phù hợp. Nếu xây dựng backend, Node.js là lựa chọn thuận tiện vì API key có thể được lưu trong biến môi trường thay vì đưa trực tiếp vào mã nguồn.

Theo hướng dẫn hiện tại của xAI, API key có thể được tạo từ trang quản lý API key của xAI Console và có thể đưa vào biến môi trường với tên XAI_API_KEY. API sử dụng Bearer token để xác thực request.

Đối với một dự án Node.js, cấu trúc cơ bản có thể bắt đầu đơn giản như sau:

grok-javascript/
├── node_modules/
├── .env
├── .gitignore
├── package.json
└── index.js

Cách tổ chức này giúp tách thông tin cấu hình khỏi phần logic của chương trình. Đặc biệt, file chứa API key không nên được đưa lên GitHub hoặc gửi công khai.

Tạo API key

Sau khi đăng nhập vào xAI Console, bạn tạo một API key dành cho ứng dụng. API key này hoạt động giống như thông tin xác thực để hệ thống xAI biết request đang được gửi từ tài khoản hoặc team nào.

Không nên viết trực tiếp khóa bí mật vào mã nguồn theo kiểu:

const apiKey = "your-api-key";

Cách làm này rất dễ dẫn đến việc API key bị lộ khi mã nguồn được commit lên Git, đưa lên GitHub hoặc chia sẻ cho người khác.

Thay vào đó, có thể lưu khóa trong file .env khi phát triển cục bộ:

XAI_API_KEY=your_api_key

Sau đó đưa file .env vào .gitignore:

.env
node_modules/

Trong môi trường triển khai thực tế, nên sử dụng cơ chế quản lý secret của máy chủ hoặc nền tảng cloud thay vì đưa API key vào source code.

Cài đặt môi trường JavaScript cho Grok API

Nếu sử dụng Node.js, bạn có thể tạo một thư mục mới rồi khởi tạo dự án:

mkdir grok-javascript
cd grok-javascript
npm init -y

Có hai hướng phổ biến để gọi API. Cách thứ nhất là sử dụng thư viện tương thích OpenAI do API của xAI cung cấp. Cách thứ hai là gửi HTTP request trực tiếp bằng fetch.

Đối với người mới, sử dụng SDK giúp mã nguồn dễ đọc và giảm lượng logic HTTP phải tự xử lý. Trong khi đó, gọi REST API trực tiếp bằng fetch lại rất hữu ích khi bạn muốn hiểu rõ request thực sự được gửi đi như thế nào.

Sử dụng thư viện OpenAI-compatible

xAI cung cấp API tương thích với giao diện OpenAI, vì vậy trong JavaScript có thể sử dụng package openai và cấu hình baseURL trỏ tới API của xAI. Tài liệu chính thức của xAI hiện minh họa cách này với Responses API.

Cài package:

npm install openai

Nếu muốn đọc API key từ file .env, có thể cài thêm thư viện dotenv:

npm install dotenv

Sau đó file index.js có thể bắt đầu bằng phần cấu hình:

import "dotenv/config";
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.XAI_API_KEY,
  baseURL: "https://api.x.ai/v1"
});

Ở đây, apiKey lấy từ biến môi trường thay vì viết trực tiếp vào chương trình. Tham số baseURL chuyển request từ endpoint mặc định của thư viện sang endpoint API của xAI.

Gửi yêu cầu Grok đầu tiên bằng JavaScript

Sau khi cấu hình client, bước tiếp theo là gửi một yêu cầu tới Responses API. Với cách tiếp cận hiện tại, request sử dụng model, nội dung đầu vào và nhận response từ API. Tài liệu xAI đang sử dụng grok-4.7 trong các ví dụ JavaScript và Responses API.

Một ví dụ tối giản:

import "dotenv/config";
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.XAI_API_KEY,
  baseURL: "https://api.x.ai/v1"
});

const response = await client.responses.create({
  model: "grok-4.7",
  input: "Hãy giải thích JavaScript async/await cho người mới."
});

console.log(response.output_text);

Đoạn chương trình trên thực hiện một chuỗi thao tác khá ngắn nhưng quan trọng. Đầu tiên, JavaScript tạo client với API key. Sau đó chương trình gọi phương thức responses.create(), chỉ định model và truyền câu hỏi vào thuộc tính input.

Khi API xử lý xong, kết quả được lưu trong biến response. Với SDK được sử dụng trong ví dụ, response.output_text là cách thuận tiện để lấy phần văn bản mà Grok tạo ra.

Chạy chương trình bằng Node.js:

node index.js

Nếu API key hợp lệ, tài khoản có quyền sử dụng API và request được cấu hình đúng, chương trình sẽ nhận được câu trả lời từ model.

Hiểu rõ phần input trước khi xây dựng ứng dụng lớn

Một lỗi thường gặp khi mới tích hợp AI là xem input đơn giản như một chuỗi văn bản rồi sau đó khó mở rộng khi ứng dụng bắt đầu có nhiều loại dữ liệu.

Responses API hỗ trợ truyền input dưới dạng chuỗi hoặc cấu trúc nhiều message. Cách truyền nhiều message phù hợp hơn khi ứng dụng cần phân biệt vai trò hệ thống và người dùng.

Ví dụ:

const response = await client.responses.create({
  model: "grok-4.7",
  input: [
    {
      role: "system",
      content: "Bạn là trợ lý hỗ trợ lập trình JavaScript."
    },
    {
      role: "user",
      content: "Giải thích Promise trong JavaScript bằng một ví dụ đơn giản."
    }
  ]
});

console.log(response.output_text);

Cách tổ chức này có lợi khi bạn muốn thiết lập một quy tắc chung cho model rồi nhận nhiều yêu cầu khác nhau từ người dùng. Thay vì lặp lại cùng một chỉ dẫn trong từng câu hỏi, phần thiết lập vai trò có thể được tách riêng.

Gọi Grok API trực tiếp bằng fetch

Nếu không muốn phụ thuộc vào SDK, JavaScript hiện đại trong Node.js có thể sử dụng fetch để gửi HTTP request trực tiếp. Cách này giúp bạn hiểu rõ hơn cấu trúc của API và cũng hữu ích khi muốn tích hợp vào những môi trường không sử dụng SDK.

Ví dụ cơ bản:

const response = await fetch("https://api.x.ai/v1/responses", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": `Bearer ${process.env.XAI_API_KEY}`
  },
  body: JSON.stringify({
    model: "grok-4.7",
    input: "Hãy giải thích REST API là gì."
  })
});

const data = await response.json();

console.log(data.output_text);

Ở đây, method được đặt thành POST vì ứng dụng đang gửi dữ liệu lên API. Header Content-Type thông báo rằng phần body sử dụng JSON, còn Authorization chứa API key dưới dạng Bearer token.

Endpoint /v1/responses là endpoint dùng để tạo response. API reference của xAI xác định trường input là dữ liệu bắt buộc trong request và response có thể được sử dụng tiếp thông qua response ID.

Khi nào nên dùng SDK và khi nào nên dùng fetch?

Phương pháp Phù hợp với Ưu điểm
SDK OpenAI-compatible Ứng dụng Node.js cần phát triển nhanh Mã ngắn, dễ tổ chức và thuận tiện khi mở rộng
fetch Ứng dụng cần kiểm soát HTTP request trực tiếp Không phụ thuộc nhiều vào SDK, dễ nhìn thấy cấu trúc API

Nếu mục tiêu là xây dựng một ứng dụng JavaScript lâu dài, SDK thường là lựa chọn thuận tiện hơn. Nếu mục tiêu là học cách API hoạt động hoặc cần kiểm soát request ở mức thấp, fetch là cách tiếp cận đáng hiểu rõ.

Không nên gọi Grok API trực tiếp từ trình duyệt

Đây là vấn đề quan trọng nhất khi đưa Grok vào website.

Nếu bạn đặt API key trực tiếp trong JavaScript chạy trên trình duyệt, người dùng có thể mở DevTools, xem source, kiểm tra network request hoặc tìm khóa bí mật trong bundle. Khi đó API key có nguy cơ bị người khác sử dụng trái phép.

Ví dụ sau không nên triển khai trên frontend:

const client = new OpenAI({
  apiKey: "your-secret-api-key",
  baseURL: "https://api.x.ai/v1"
});

Cách an toàn hơn là tạo một backend trung gian. Trình duyệt chỉ gửi nội dung tới server của bạn, server giữ API key và thay mặt frontend gọi Grok API.

Mô hình kiến trúc nên là:

Trình duyệt
    ↓
Backend JavaScript của bạn
    ↓
Grok API
    ↓
Backend nhận kết quả
    ↓
Trình duyệt hiển thị kết quả

Nhờ vậy, API key chỉ tồn tại ở phía server. Đây cũng là nền tảng cần thiết nếu sau này bạn muốn bổ sung giới hạn request, kiểm tra người dùng, ghi log, kiểm soát chi phí hoặc lọc dữ liệu trước khi gửi tới Grok.

Xây dựng backend JavaScript để kết nối Grok

Khi đã hiểu cách gửi request cơ bản, bước hợp lý tiếp theo là đưa phần gọi Grok API vào backend. Đây là kiến trúc phù hợp hơn cho website vì API key được giữ ở phía máy chủ, còn trình duyệt chỉ giao tiếp với server của bạn.

Với Node.js, bạn có thể sử dụng một framework như Express để tạo API riêng. Luồng xử lý khi đó sẽ trở thành:

Frontend
    ↓
POST /api/grok
    ↓
Node.js / Express
    ↓
Grok API
    ↓
Node.js nhận kết quả
    ↓
Frontend

Ví dụ, cài Express:

npm install express

Nếu sử dụng cú pháp import, có thể khai báo kiểu module trong package.json:

{
  "type": "module"
}

Backend cơ bản có thể được xây dựng như sau:

import "dotenv/config";
import express from "express";
import OpenAI from "openai";

const app = express();

app.use(express.json());

const client = new OpenAI({
  apiKey: process.env.XAI_API_KEY,
  baseURL: "https://api.x.ai/v1"
});

app.post("/api/grok", async (req, res) => {
  try {
    const { message } = req.body;

    if (!message) {
      return res.status(400).json({
        error: "Vui lòng nhập nội dung cần gửi."
      });
    }

    const response = await client.responses.create({
      model: "grok-4.7",
      input: message
    });

    res.json({
      answer: response.output_text
    });
  } catch (error) {
    console.error(error);

    res.status(500).json({
      error: "Không thể xử lý yêu cầu."
    });
  }
});

app.listen(3000, () => {
  console.log("Server đang chạy tại cổng 3000");
});

Backend này tạo một endpoint /api/grok. Frontend gửi nội dung trong thuộc tính message, server nhận dữ liệu rồi gọi Grok API. Sau khi có kết quả, server chỉ trả phần câu trả lời cần thiết về cho trình duyệt.

Kết nối giao diện JavaScript với backend

Sau khi backend hoạt động, frontend có thể sử dụng fetch để gửi câu hỏi đến server của bạn. Điểm quan trọng là frontend không cần biết API key của xAI.

Ví dụ:

async function askGrok(message) {
  const response = await fetch("/api/grok", {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      message
    })
  });

  const data = await response.json();

  if (!response.ok) {
    throw new Error(data.error || "Có lỗi xảy ra.");
  }

  return data.answer;
}

Sau đó có thể gọi hàm:

const answer = await askGrok(
  "Hãy giải thích sự khác nhau giữa let và const trong JavaScript."
);

console.log(answer);

Cách triển khai này tạo ra ranh giới rõ ràng giữa giao diện và dịch vụ AI. Frontend chịu trách nhiệm nhận thao tác của người dùng, còn backend chịu trách nhiệm xác thực, gọi API và kiểm soát dữ liệu.

Ví dụ với một ô nhập câu hỏi

Trong một chatbot đơn giản, JavaScript phía trình duyệt có thể lấy nội dung từ ô nhập rồi gửi đến backend:

const form = document.querySelector("#chat-form");
const input = document.querySelector("#message");
const output = document.querySelector("#answer");

form.addEventListener("submit", async (event) => {
  event.preventDefault();

  const message = input.value.trim();

  if (!message) {
    return;
  }

  output.textContent = "Đang xử lý...";

  try {
    const answer = await askGrok(message);
    output.textContent = answer;
  } catch (error) {
    output.textContent = error.message;
  }
});

Đây mới chỉ là phần giao tiếp cơ bản. Khi xây dựng chatbot thực tế, bạn cần xử lý thêm trạng thái đang gửi, khóa nút submit trong lúc chờ phản hồi, hiển thị lỗi rõ ràng và quản lý lịch sử hội thoại.

Xử lý lỗi khi gọi Grok API

Không nên giả định mọi request đều thành công. Một ứng dụng thực tế có thể gặp lỗi do API key không hợp lệ, request sai cấu trúc, model không khả dụng, vượt giới hạn sử dụng, lỗi mạng hoặc dịch vụ tạm thời gặp sự cố.

Vì vậy, backend nên kiểm tra cả trạng thái HTTP và lỗi phát sinh từ SDK.

app.post("/api/grok", async (req, res) => {
  try {
    const { message } = req.body;

    if (typeof message !== "string" || !message.trim()) {
      return res.status(400).json({
        error: "Nội dung yêu cầu không hợp lệ."
      });
    }

    const response = await client.responses.create({
      model: "grok-4.7",
      input: message.trim()
    });

    return res.json({
      answer: response.output_text
    });
  } catch (error) {
    console.error("Grok API error:", error);

    return res.status(500).json({
      error: "Máy chủ không thể xử lý yêu cầu."
    });
  }
});

Thông báo lỗi nội bộ không nên được trả nguyên trạng cho người dùng trong mọi trường hợp. Log phía server có thể chứa thông tin kỹ thuật để developer kiểm tra, trong khi frontend chỉ cần nhận thông báo đủ rõ để xử lý giao diện.

Phân biệt lỗi đầu vào và lỗi từ dịch vụ

Hai nhóm lỗi này nên được xử lý khác nhau. Nếu người dùng gửi nội dung rỗng, đó là lỗi đầu vào và server có thể trả về HTTP 400. Nếu server gặp lỗi khi gọi dịch vụ AI, có thể trả về lỗi phía máy chủ và ghi thông tin chi tiết vào log.

Tình huống Cách xử lý
Không có nội dung Trả HTTP 400 và yêu cầu nhập lại
Dữ liệu không đúng kiểu Từ chối request trước khi gọi API
API key không hợp lệ Ghi log phía server, không công khai khóa
API tạm thời lỗi Thông báo lỗi phù hợp và có thể thử lại
Request quá nhiều Kiểm soát tần suất và thông báo người dùng

Gửi hội thoại nhiều lượt cho Grok

Một chatbot thực tế không chỉ gửi từng câu hỏi độc lập. Người dùng thường hỏi tiếp dựa trên câu trả lời trước đó. Nếu mỗi request chỉ chứa câu hỏi mới, model có thể không biết ngữ cảnh mà người dùng đang đề cập.

Cách đơn giản là ứng dụng tự quản lý lịch sử hội thoại và gửi phần ngữ cảnh cần thiết trong request tiếp theo.

Ví dụ một lịch sử có thể được tổ chức như sau:

const conversation = [
  {
    role: "user",
    content: "Tôi đang học JavaScript."
  },
  {
    role: "assistant",
    content: "Bạn muốn học phần nào của JavaScript?"
  },
  {
    role: "user",
    content: "Tôi muốn hiểu Promise."
  }
];

Sau đó truyền lịch sử phù hợp vào request. Tùy API và cách bạn thiết kế ứng dụng, phần lịch sử có thể được lưu trong session, database hoặc một hệ thống quản lý hội thoại riêng.

Không nên lưu toàn bộ lịch sử vô thời hạn một cách máy móc. Khi cuộc trò chuyện dài, lượng dữ liệu gửi đi cũng tăng, khiến request trở nên nặng hơn và có thể làm tăng chi phí xử lý.

Chỉ giữ lại ngữ cảnh cần thiết

Một cách tốt hơn là xác định những thông tin thực sự cần thiết cho câu hỏi hiện tại. Ví dụ, nếu người dùng đã nói tên dự án, ngôn ngữ lập trình và mục tiêu ở những lượt trước, các thông tin đó có thể được giữ lại trong ngữ cảnh thay vì gửi toàn bộ cuộc trò chuyện dài hàng trăm lượt.

Với chatbot lớn, backend có thể áp dụng chiến lược như:

  • Giữ một số lượt hội thoại gần nhất.
  • Tóm tắt các phần hội thoại cũ.
  • Lưu thông tin quan trọng của phiên làm việc riêng biệt.
  • Chỉ gửi dữ liệu liên quan đến câu hỏi hiện tại.

Đây là điểm khác biệt giữa một demo API và một ứng dụng AI có khả năng vận hành lâu dài.

Thiết lập hướng dẫn cố định cho Grok

Trong nhiều ứng dụng, bạn không muốn model trả lời theo cách hoàn toàn tùy ý. Chẳng hạn, một website hỗ trợ lập trình có thể muốn Grok luôn giải thích bằng tiếng Việt, ưu tiên ví dụ thực tế và tránh trả lời quá dài.

Thay vì lặp lại những yêu cầu này trong từng câu hỏi, bạn có thể thiết lập chỉ dẫn ở cấp độ phù hợp trong request.

const response = await client.responses.create({
  model: "grok-4.7",
  instructions:
    "Bạn là trợ lý lập trình. Trả lời bằng tiếng Việt, giải thích dễ hiểu và ưu tiên ví dụ thực tế.",
  input: "Giải thích event loop trong JavaScript."
});

console.log(response.output_text);

Cách tách instructions khỏi nội dung người dùng giúp kiến trúc ứng dụng rõ ràng hơn. Phần hướng dẫn định hình hành vi chung của trợ lý, trong khi input chứa yêu cầu cụ thể của từng lượt.

Kiểm soát dữ liệu trước khi gửi lên API

Không nên chuyển mọi dữ liệu từ frontend đến Grok mà không kiểm tra. Backend nên xác thực dữ liệu trước khi gọi API.

Ví dụ, bạn có thể giới hạn độ dài nội dung:

const MAX_LENGTH = 10000;

if (message.length > MAX_LENGTH) {
  return res.status(400).json({
    error: "Nội dung vượt quá giới hạn cho phép."
  });
}

Việc giới hạn kích thước request không chỉ giúp tránh dữ liệu bất thường mà còn hạn chế việc người dùng vô tình gửi một lượng nội dung rất lớn lên dịch vụ AI.

Ngoài độ dài, ứng dụng thực tế nên cân nhắc giới hạn số request trong một khoảng thời gian, xác thực người dùng và ghi nhận mức sử dụng. Nếu endpoint AI được công khai mà không có các lớp kiểm soát này, người khác có thể lợi dụng server của bạn để tạo ra lượng request lớn.

Hiển thị câu trả lời theo thời gian thực với streaming

Với những câu trả lời dài, việc chờ toàn bộ nội dung được tạo xong rồi mới hiển thị có thể khiến người dùng cảm giác ứng dụng phản hồi chậm. Streaming giải quyết vấn đề này bằng cách cho phép ứng dụng nhận kết quả từng phần và cập nhật giao diện ngay khi dữ liệu được trả về.

Thay vì luồng xử lý:

Người dùng gửi câu hỏi
        ↓
Chờ Grok tạo toàn bộ câu trả lời
        ↓
Nhận toàn bộ kết quả
        ↓
Hiển thị

Streaming tạo ra luồng:

Người dùng gửi câu hỏi
        ↓
Grok bắt đầu tạo kết quả
        ↓
Nhận từng phần dữ liệu
        ↓
Cập nhật giao diện liên tục
        ↓
Kết thúc khi hoàn thành

Responses API hỗ trợ streaming thông qua tùy chọn stream: true. Khi đó ứng dụng có thể xử lý các sự kiện được gửi trong quá trình model tạo kết quả thay vì đợi toàn bộ response hoàn thành.

Ví dụ ở phía Node.js:

const stream = await client.responses.create({
  model: "grok-4.7",
  input: "Giải thích chi tiết cách hoạt động của JavaScript Event Loop.",
  stream: true
});

for await (const event of stream) {
  console.log(event);
}

Trong ứng dụng thực tế, backend thường không cần gửi nguyên event object về frontend. Thay vào đó, server có thể lọc những sự kiện chứa phần văn bản mới rồi chuyển chúng tới trình duyệt bằng một cơ chế streaming phù hợp.

Streaming có lợi gì cho chatbot?

Ưu điểm lớn nhất là cải thiện cảm nhận về tốc độ. Người dùng có thể bắt đầu đọc phần đầu câu trả lời trong khi Grok vẫn đang tạo phần còn lại.

Điều này đặc biệt hữu ích với:

  • Chatbot hỏi đáp.
  • Công cụ viết nội dung.
  • Trợ lý lập trình.
  • Ứng dụng phân tích văn bản dài.
  • Các hệ thống cần phản hồi liên tục.

Tuy nhiên, streaming cũng làm kiến trúc frontend và backend phức tạp hơn. Bạn cần xử lý kết nối đang mở, dữ liệu đến từng phần, trạng thái hoàn tất và trường hợp kết nối bị ngắt giữa chừng.

Quản lý timeout và retry đúng cách

Một request đến dịch vụ AI không nên được xem là chắc chắn thành công. Kết nối mạng có thể chậm, server có thể tạm thời gặp vấn đề hoặc dịch vụ có thể trả về lỗi do giới hạn sử dụng.

Ứng dụng nên có cơ chế xử lý timeout thay vì giữ một request mở vô thời hạn.

Ví dụ sử dụng AbortController với fetch:

const controller = new AbortController();

const timeout = setTimeout(() => {
  controller.abort();
}, 30000);

try {
  const response = await fetch("https://api.x.ai/v1/responses", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Authorization": `Bearer ${process.env.XAI_API_KEY}`
    },
    body: JSON.stringify({
      model: "grok-4.7",
      input: "Giải thích Promise trong JavaScript."
    }),
    signal: controller.signal
  });

  const data = await response.json();

  console.log(data);
} catch (error) {
  console.error("Request failed:", error);
} finally {
  clearTimeout(timeout);
}

Retry cũng cần được sử dụng có kiểm soát. Không nên cứ gặp bất kỳ lỗi nào là gửi lại request nhiều lần vì điều đó có thể làm tăng tải và phát sinh thêm chi phí.

Thông thường, retry phù hợp hơn với những lỗi tạm thời. Có thể áp dụng thời gian chờ tăng dần giữa các lần thử thay vì gửi lại liên tục.

Bảo vệ endpoint JavaScript gọi Grok

Giữ API key ở backend chưa đủ để biến một endpoint AI thành hệ thống an toàn. Nếu endpoint /api/grok được mở công khai mà không có giới hạn, bất kỳ ai biết URL cũng có thể gửi request đến server của bạn.

Một backend thực tế nên cân nhắc nhiều lớp bảo vệ.

  • Xác thực người dùng trước khi cho phép gọi AI.
  • Giới hạn số request trong một khoảng thời gian.
  • Giới hạn kích thước dữ liệu đầu vào.
  • Kiểm tra kiểu dữ liệu nhận được.
  • Không trả thông tin bí mật trong thông báo lỗi.
  • Ghi log những request bất thường.
  • Giữ API key trong biến môi trường hoặc hệ thống quản lý secret.

Ví dụ, có thể giới hạn độ dài câu hỏi trước khi gọi model:

function validateMessage(message) {
  if (typeof message !== "string") {
    return false;
  }

  const value = message.trim();

  return value.length > 0 && value.length <= 10000;
}

Trong endpoint:

app.post("/api/grok", async (req, res) => {
  const { message } = req.body;

  if (!validateMessage(message)) {
    return res.status(400).json({
      error: "Nội dung không hợp lệ."
    });
  }

  try {
    const response = await client.responses.create({
      model: "grok-4.7",
      input: message.trim()
    });

    return res.json({
      answer: response.output_text
    });
  } catch (error) {
    console.error(error);

    return res.status(500).json({
      error: "Không thể tạo câu trả lời."
    });
  }
});

Đây chỉ là lớp kiểm tra cơ bản. Với website có lượng truy cập lớn, nên bổ sung rate limiting và hệ thống xác thực phù hợp với kiến trúc của ứng dụng.

Tối ưu chi phí khi sử dụng Grok API

Khi tích hợp AI vào website, chi phí không chỉ phụ thuộc vào số người dùng mà còn phụ thuộc vào lượng dữ liệu được gửi và lượng nội dung model tạo ra.

Một lỗi phổ biến là gửi toàn bộ lịch sử hội thoại trong mọi request. Khi cuộc trò chuyện càng dài, lượng dữ liệu gửi lên càng lớn. Vì vậy, ứng dụng nên kiểm soát context một cách có chủ đích.

Một số biện pháp thực tế gồm:

  • Chỉ gửi lịch sử thực sự cần thiết.
  • Giới hạn độ dài input.
  • Không yêu cầu model tạo câu trả lời dài nếu không cần thiết.
  • Chọn model phù hợp với độ phức tạp của tác vụ.
  • Không gọi API nhiều lần cho cùng một thao tác nếu có thể tái sử dụng kết quả.
  • Thiết lập giới hạn sử dụng cho từng tài khoản.

Ví dụ, một tính năng chỉ cần phân loại câu hỏi đơn giản không nhất thiết phải được thiết kế giống một hệ thống phân tích chuyên sâu. Chọn model dựa trên yêu cầu thực tế sẽ giúp cân bằng giữa chất lượng, tốc độ và chi phí.

Thiết kế một module JavaScript riêng cho Grok

Khi dự án lớn dần, không nên đặt toàn bộ logic gọi API trực tiếp trong file xử lý route. Tách phần giao tiếp với Grok thành một module riêng sẽ giúp mã nguồn dễ bảo trì hơn.

Ví dụ có thể tổ chức:

src/
├── server.js
├── routes/
│   └── grok.js
├── services/
│   └── grok.js
└── utils/
    └── validation.js

File dịch vụ có thể đảm nhiệm việc tạo client và gửi request:

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.XAI_API_KEY,
  baseURL: "https://api.x.ai/v1"
});

export async function generateText(input) {
  const response = await client.responses.create({
    model: "grok-4.7",
    input
  });

  return response.output_text;
}

Route chỉ cần gọi service:

import express from "express";
import { generateText } from "../services/grok.js";

const router = express.Router();

router.post("/", async (req, res) => {
  try {
    const { message } = req.body;

    if (!message) {
      return res.status(400).json({
        error: "Vui lòng nhập nội dung."
      });
    }

    const answer = await generateText(message);

    return res.json({ answer });
  } catch (error) {
    console.error(error);

    return res.status(500).json({
      error: "Không thể xử lý yêu cầu."
    });
  }
});

export default router;

Kiểu tổ chức này đặc biệt hữu ích khi ứng dụng có nhiều tính năng AI. Bạn có thể xây dựng thêm các service riêng cho tạo nội dung, phân tích văn bản, chatbot hoặc những tác vụ khác mà không khiến file server trở nên quá lớn.

Những lỗi thường gặp khi tích hợp Grok API

Đưa API key vào frontend

Đây là lỗi nghiêm trọng nhất. API key phải được bảo vệ ở phía server. Frontend chỉ nên gọi backend của chính ứng dụng.

Không kiểm tra response

Việc gọi API và ngay lập tức đọc dữ liệu mà không xử lý lỗi có thể khiến ứng dụng gặp lỗi khó xác định. Backend nên có một lớp xử lý exception và phản hồi phù hợp.

Gửi toàn bộ dữ liệu người dùng

Không phải dữ liệu nào trong trình duyệt cũng cần được chuyển tới model. Chỉ nên gửi phần cần thiết cho tác vụ đang thực hiện.

Không giới hạn request

Một endpoint công khai không có rate limit có thể bị lạm dụng. Khi đó chi phí API và tài nguyên server có thể tăng nhanh.

Phụ thuộc vào một cấu trúc response cố định

Khi tích hợp API, nên dựa trên tài liệu chính thức và SDK/API version đang sử dụng thay vì tự giả định cấu trúc dữ liệu. Điều này giúp giảm nguy cơ mã nguồn bị hỏng khi API được cập nhật.

Cấu trúc hoàn chỉnh nên hướng tới

Với một ứng dụng JavaScript nghiêm túc, kiến trúc có thể được tổ chức theo hướng:

Người dùng
   ↓
Giao diện JavaScript
   ↓
API backend của website
   ↓
Xác thực + kiểm tra dữ liệu
   ↓
Grok service
   ↓
Grok API
   ↓
Xử lý response
   ↓
Frontend hiển thị kết quả

Cách tổ chức này có ưu điểm là từng thành phần có nhiệm vụ rõ ràng. Frontend không quản lý secret, route không phải chứa toàn bộ logic AI, còn service chịu trách nhiệm giao tiếp với Grok.

Kết luận

Sử dụng Grok API với JavaScript không chỉ đơn giản là gửi một request rồi lấy về một chuỗi văn bản. Để xây dựng ứng dụng có thể sử dụng thực tế, bạn cần quan tâm đồng thời đến cách xác thực, cấu trúc request, quản lý hội thoại, xử lý lỗi, streaming, bảo vệ API key và kiểm soát mức sử dụng.

Với Node.js, cách tiếp cận hợp lý là giữ API key ở backend, sử dụng SDK hoặc fetch để giao tiếp với API, tạo một lớp service riêng cho Grok và để frontend chỉ giao tiếp với API của chính website. Khi ứng dụng phát triển, có thể bổ sung xác thực người dùng, rate limiting, logging, streaming và các chiến lược tối ưu context.

Nếu chỉ cần thử nghiệm, một request đơn giản với responses.create() đã đủ để bắt đầu. Nhưng nếu mục tiêu là xây dựng chatbot hoặc tính năng AI cho website, nên thiết kế kiến trúc ngay từ đầu theo hướng tách frontend, backend và lớp giao tiếp với Grok. Điều này giúp ứng dụng an toàn hơn, dễ mở rộng hơn và thuận tiện bảo trì về sau.

  • ★★★★★ ★★★★★
  • 0 Bình luận
CEO Bùi Tấn Lực | Founder Web Mới
Bùi Tấn Lực
Tìm hiểu về CEO Bùi Tấn Lực, Founder Web Mới với nhiều năm kinh nghiệm trong lĩnh vực phát triển website, SEO và chia sẻ kiến thức công nghệ
Đánh giá
Chia sẻ nội dung đánh giá của bạn về Cách sử dụng Grok API với JavaScript
Email, Điện thoại của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *
Đánh giá của bạn
Tên *
Email
Số điện thoại *
Bình luận, Hỏi đáp
Yêu Cầu Báo Giá
Gửi trang web mẫu cần làm theo, chúng tôi sẽ báo giá đến bạn từ Email (tanlucit09@gmail.com - Bùi Tấn Lực) hoặc Zalo (Lực IT - 0398259259) !