Tìm hiểu cách chuyển đổi ứng dụng Node.js OpenAI SDK hiện có sang một gateway tương thích OpenAI như OneMux, xử lý streaming, chẩn đoán lỗi và xây dựng quy trình phân loại hỗ trợ khách hàng có con người phê duyệt.
Việc chuyển đổi một ứng dụng Node.js sẵn có từ các endpoint trực tiếp của OpenAI sang một proxy hoặc unified gateway tương thích OpenAI không đòi hỏi bạn phải viết lại toàn bộ logic cốt lõi. Do thư viện openai chính thức cho Node.js cung cấp cấu hình ở cấp độ client cho network origins và headers, bạn hoàn toàn có thể chuyển hướng lưu lượng, theo dõi mức độ sử dụng và tận dụng cơ chế định tuyến thay thế mà không cần đổi SDK.
Tuy nhiên, việc định tuyến qua proxy hoặc gateway sẽ phát sinh một số vấn đề thực tế: quản lý authentication headers, xử lý các sự kiện streaming qua HTTP, chẩn đoán lỗi ở lớp edge, và đảm bảo kết quả từ mô hình tự hành luôn nằm dưới sự giám sát của con người. Trong quy trình phân loại hỗ trợ khách hàng (customer support triage)—nơi mô hình AI tiếp nhận ticket, phân loại độ khẩn cấp, soạn thảo phản hồi và đề xuất hành động xử lý—việc bắt buộc có sự kiểm duyệt của con người trước khi thực thi logic nghiệp vụ là vô cùng quan trọng.
Hướng dẫn này minh họa cách cấu hình lại Node.js OpenAI SDK cho một gateway tương thích OpenAI như OneMux, stream các đề xuất phân loại và áp dụng cơ chế phê duyệt thủ công trước khi thực hiện các tác vụ quan trọng.
Quy trình phân loại hỗ trợ khách hàng tự động bao gồm việc đọc ticket gửi đến, đánh giá cảm xúc người dùng, xác định mức độ khẩn cấp và đề xuất các bước tiếp theo (chẳng hạn như soạn phản hồi, gắn tag hoặc cấp khoản bồi hoàn một phần). Như được phác thảo trong OpenAI Agents Guide, các kiến trúc agent có tác động trực tiếp đến thế giới thực sẽ vận hành tốt nhất khi vòng lặp điều phối (orchestration loop) nằm trực tiếp trong mã nguồn ứng dụng, nơi bạn có thể duy trì các rào chắn an toàn (guardrails) và điểm kiểm duyệt.
Thay vì trao toàn quyền thực thi cho mô hình, pipeline phân loại được tách thành hai giai đoạn rõ rệt:
Incoming Ticket ──> Node.js Service ──> OneMux Gateway ──> Model Inference
│
▼
Ticket Updated <── Support Agent <── Review Queue <── Proposed Actions
(Execution) (Approves) (Intercepted) & Draft Stream
Gói npm openai chính thức cho phép bạn trỏ request tới bất kỳ endpoint nào tương thích bằng cách chỉnh sửa thuộc tính baseURL. Bạn có thể tham khảo danh sách mô hình hiện có trên OneMux model catalog để lựa chọn mô hình completion phù hợp.
Trước tiên, hãy cài đặt gói chính thức:
npm install openai
Để kết nối tới OneMux, hãy cấu hình instance client với API key của OneMux và base URL https://api.onemux.net/v1:
import OpenAI from 'openai';
// Initialize the OpenAI client pointing to the OneMux gateway
const client = new OpenAI({
apiKey: process.env.ONEMUX_API_KEY,
baseURL: 'https://api.onemux.net/v1',
});
Khi định tuyến qua gateway, các kịch bản lỗi xác thực có đôi chút khác biệt. Nếu API key bị thiếu, không hợp lệ hoặc tài khoản không đủ số dư trên nền tảng, client sẽ nhận về AuthenticationError (HTTP 401). Trước khi chạy các tác vụ phân loại trên môi trường production, hãy kiểm tra kỹ thông tin xác thực của bạn bằng cách tham khảo OneMux quickstart guide.
Nhân viên hỗ trợ sẽ làm việc hiệu quả hơn khi nhìn thấy nội dung bản thảo phân loại xuất hiện tuần tự thay vì phải chờ toàn bộ payload hoàn tất. Khi gọi chat.completions.create với tùy chọn stream: true, SDK sẽ trả về một luồng async iterable cung cấp các Server-Sent Events (SSE).
Đoạn mã sau triển khai stream phản hồi dự thảo ra standard output (hoặc dashboard nội bộ của nhân viên) đồng thời ghi nhận các tool calls có cấu trúc phục vụ phân loại ticket:
import OpenAI from 'openai';
const client = new OpenAI({
apiKey: process.env.ONEMUX_API_KEY,
baseURL: 'https://api.onemux.net/v1',
});
interface TriageProposal {
draftResponse: string;
category?: string;
priority?: 'low' | 'medium' | 'high' | 'urgent';
suggestedRefundAmount?: number;
}
export async function triageTicketStream(
ticketId: string,
customerMessage: string
): Promise<TriageProposal> {
const tools: OpenAI.ChatCompletionTool[] = [
{
type: 'function',
function: {
name: 'propose_ticket_action',
description: 'Propose triage tags, priority updates, or billing adjustments.',
parameters: {
type: 'object',
properties: {
category: {
type: 'string',
enum: ['billing', 'technical_bug', 'account_access', 'general'],
},
priority: {
type: 'string',
enum: ['low', 'medium', 'high', 'urgent'],
},
suggestedRefundAmount: {
type: 'number',
description: 'Refund amount in USD if the user experienced downtime.',
},
},
required: ['category', 'priority'],
},
},
},
];
const stream = await client.chat.completions.create({
model: 'gpt-4o',
stream: true,
tools,
messages: [
{
role: 'system',
content:
'You are a support triage assistant. Analyze the ticket, stream a helpful draft reply for the customer, and call propose_ticket_action with triage metadata.',
},
{
role: 'user',
content: customerMessage,
},
],
});
let draftResponse = '';
let toolCallArguments = '';
let toolName = '';
for await (const chunk of stream) {
const delta = chunk.choices[0]?.delta;
// Stream conversational draft chunks
if (delta?.content) {
draftResponse += delta.content;
process.stdout.write(delta.content);
}
// Accumulate tool call chunks
if (delta?.tool_calls) {
for (const toolCall of delta.tool_calls) {
if (toolCall.function?.name) {
toolName = toolCall.function.name;
}
if (toolCall.function?.arguments) {
toolCallArguments += toolCall.function.arguments;
}
}
}
}
let parsedAction = {};
if (toolName === 'propose_ticket_action' && toolCallArguments) {
try {
parsedAction = JSON.parse(toolCallArguments);
} catch (err) {
console.error('Failed to parse tool call JSON payload:', err);
}
}
return {
draftResponse,
...parsedAction,
};
}
Việc để tool calls tự động thực thi có thể dẫn đến những lệnh hoàn tiền không được kiểm chứng hoặc nâng cấp mức độ ưu tiên sai lệch. Ứng dụng phải lưu trữ TriageProposal đã tạo ở trạng thái trung gian—chẳng hạn như một bản ghi cơ sở dữ liệu có trạng thái PENDING_APPROVAL—thay vì thực thi hành động ngay lập tức.
interface PendingReviewTicket {
ticketId: string;
status: 'PENDING_APPROVAL' | 'APPROVED' | 'REJECTED';
proposal: TriageProposal;
}
// Step 1: Queue the proposal for human verification
async function queueForHumanReview(ticketId: string, proposal: TriageProposal) {
console.log(`[Review Queue] Storing proposal for ticket ${ticketId}:`, proposal);
// Persistence logic: await db.triageReviews.create({ ticketId, proposal, status: 'PENDING_APPROVAL' });
}
// Step 2: Human operator action handler
async function handleHumanDecision(
reviewId: string,
decision: 'APPROVE' | 'REJECT',
modifiedProposal?: Partial<TriageProposal>
) {
if (decision === 'REJECT') {
console.log(`Review ${reviewId} rejected by operator.`);
return;
}
// Execute business logic only after approval
console.log(`Review ${reviewId} approved. Executing refund and priority assignment...`);
// e.g., await paymentGateway.issueRefund(modifiedProposal.suggestedRefundAmount);
}
Sự phân tách này đảm bảo rằng ngay cả khi mô hình phân loại nhầm một câu hỏi thông thường thành khẩn cấp hoặc đề xuất mức tín dụng không thỏa đáng, nhân viên vận hành vẫn kịp thời ngăn chặn hành động đó trước khi nó được thực thi.
Khi sử dụng gateway tương thích OpenAI như OneMux, sự cố có thể bắt nguồn từ ba vị trí: mã ứng dụng cục bộ, proxy gateway hoặc nhà cung cấp mô hình downstream. Việc kiểm tra instance APIError chuẩn từ openai SDK sẽ giúp cô lập nguyên nhân gốc rễ:
import OpenAI from 'openai';
try {
await triageTicketStream('ticket-101', 'System is down since morning!');
} catch (error) {
if (error instanceof OpenAI.APIError) {
console.error(`Status Code: ${error.status}`);
console.error(`Error Message: ${error.message}`);
console.error(`Error Code: ${error.code}`);
console.error(`Error Type: ${error.type}`);
switch (error.status) {
case 401:
console.error('Check your OneMux API key in environment variables.');
break;
case 402:
console.error('Account balance exhausted. Top up credits in the dashboard.');
break;
case 429:
console.error('Rate limit reached or concurrent request ceiling exceeded.');
break;
case 502:
case 504:
console.error('Upstream model provider timeout or network disruption via gateway.');
break;
default:
console.error('Unhandled API exception.');
}
} else {
console.error('Non-API runtime error:', error);
}
}
| Mã HTTP | Nguyên nhân gốc rễ chính | Hướng xử lý khuyến nghị |
|---|---|---|
| 401 Unauthorized | Thiếu hoặc sai OneMux API key. | Kiểm tra cấu hình ONEMUX_API_KEY và việc chuyển tiếp header. |
| 402 Payment Required | Số dư tài khoản đã hết. | Kiểm tra mức sử dụng và nạp thêm tiền qua OneMux pricing. |
| 429 Too Many Requests | Chạm ngưỡng rate limit hoặc giới hạn đồng thời. | Triển khai cơ chế exponential backoff hoặc yêu cầu nâng hạn mức từ nhà cung cấp. |
| 500 Internal Error | Mô hình upstream gặp sự cố hoặc ngoại lệ chưa xử lý tại gateway. | Kiểm tra trạng thái hoạt động của gateway và thử lại request. |
| 502 / 504 Bad Gateway | Gateway không thể kết nối tới nhà cung cấp upstream. | Thiết lập định tuyến dự phòng (fallback) hoặc kiểm tra tính sẵn sàng của mô hình qua OneMux documentation. |
Mặc dù OneMux cung cấp khả năng tương thích thay thế trực tiếp (drop-in) cho các endpoint chat completion tiêu chuẩn của OpenAI (/v1/chat/completions), bạn cần lưu ý một số giới hạn sau:
OpenAI-Organization, OpenAI-Project) có thể bị bỏ qua hoặc được ánh xạ khác đi qua các lớp proxy. Hãy đảm bảo auth token của bạn được truyền qua header chuẩn Bearer authorization.Việc chuyển đổi một ứng dụng Node.js OpenAI SDK sẵn có sang gateway tương thích OpenAI diễn ra rất liền mạch: chỉ cần cập nhật baseURL, cung cấp API key tương ứng của gateway và điều chỉnh cơ chế ghi log lỗi để theo dõi các mã trạng thái đặc thù của gateway. Bằng cách tách biệt đề xuất của mô hình khỏi các tác động phụ thực tế thông qua một cổng phê duyệt, pipeline phân loại hỗ trợ khách hàng của bạn vừa duy trì được tốc độ vận hành cao vừa ngăn ngừa được các hành động ngoài ý muốn.
Có. Vì OneMux cung cấp REST API tương thích hoàn toàn với OpenAI, bạn chỉ cần cấu hình `baseURL` trỏ về `https://api.onemux.net/v1` và truyền API key OneMux vào hàm khởi tạo client. Các phương thức hiện tại như `client.chat.completions.create` sẽ hoạt động hoàn toàn tương tự.
Trong một request streaming, các chunk sẽ trả về từng delta. Khi mô hình xuất văn bản, `delta.content` sẽ chứa nội dung văn bản được stream. Khi mô hình gọi một hàm hoặc tool, `delta.tool_calls` sẽ stream tên và các đoạn chuỗi JSON tăng dần trong `function.arguments`, những đoạn này cần được gom lại và parse sau khi stream kết thúc.
Các mô hình AI có thể đọc sai ngữ điệu của khách hàng hoặc đưa ra chính sách không chính xác (hallucination). Việc đặt một cổng phê duyệt ở cấp ứng dụng giữa các đề xuất của mô hình (như hoàn tiền, thay đổi trạng thái thanh toán hoặc đóng ticket ưu tiên) và quá trình thực thi giúp ngăn chặn các sai sót tự động ảnh hưởng đến người dùng cuối.
Lỗi 502 hoặc 504 thường báo hiệu gateway đã gặp sự cố quá thời gian chờ (timeout) hoặc mất kết nối khi gọi tới nhà cung cấp mô hình upstream. Bạn nên triển khai cơ chế retry với exponential backoff kết hợp jitter, hoặc chuyển hướng sang một mô hình dự phòng (fallback) thứ hai nếu hệ thống đòi hỏi tính sẵn sàng cao.
Guides
Hướng dẫn kỹ thuật dành cho lập trình viên Node.js khi di chuyển ứng dụng dùng OpenAI SDK: cấu hình base URL tùy chỉnh, quản lý xác thực, xử lý structured outputs dạng streaming và chẩn đoán lỗi API.
Guides
Tìm hiểu cách GPT-5.6 Sol phù hợp với tự động hóa hỗ trợ khách hàng, giá của nó và cách truy cập thông qua API tương thích OpenAI hợp nhất của OneMux.
Guides
Khám phá tại sao GPT-5.6 Terra là mô hình lý tưởng cho hỗ trợ khách hàng, cân bằng giữa chi phí, tốc độ và độ chính xác. So sánh với các mô hình khác và tìm hiểu cách OneMux đơn giản hóa việc truy cập.
Guides
Mẫu LangGraph thực tiễn để phân loại yêu cầu hỗ trợ khách hàng: định tuyến yêu cầu, gọi công cụ tra cứu, tạm dừng hoàn tiền để chờ người duyệt và giới hạn quá trình thực thi của đồ thị.