GuidesOneMux

Node.js OpenAI SDK ऐप्लिकेशन्स का माइग्रेशन: Base URL, स्ट्रीमिंग, और स्ट्रक्चर्ड आउटपुट्स

Node.js डेवलपर्स के लिए OpenAI SDK ऐप्लिकेशन्स माइग्रेट करने हेतु एक तकनीकी गाइड: कस्टम base URLs कॉन्फ़िगर करना, ऑथेंटिकेशन मैनेज करना, स्ट्रीमिंग स्ट्रक्चर्ड आउटपुट्स हैंडल करना और API एरर्स का विश्लेषण करना।

इस पृष्ठ पर

Introduction

आधिकारिक openai SDK का उपयोग करने वाले किसी मौजूदा Node.js एप्लिकेशन को माइग्रेट करने के लिए आपके बिज़नेस लॉजिक को दोबारा लिखने की आवश्यकता नहीं होती है। चूँकि कई यूनिफ़ाइड मॉडल प्रोवाइडर्स OpenAI REST स्पेसिफिकेशन्स का सख्ती से पालन करते हैं, इसलिए किसी मौजूदा एप्लिकेशन को OneMux जैसे OpenAI-कंपैटिबल रूटिंग लेयर के माध्यम से चलाने के लिए केवल आपके क्लाइंट इनिशियलाइज़ेशन पैरामीटर्स को अपडेट करना पड़ता है।

हालाँकि, प्रोडक्शन पाइपलाइन्स अक्सर एडवांस्ड फीचर्स पर निर्भर करती हैं: डेटा एक्सट्रैक्शन के लिए स्ट्रिक्ट स्कीमा अनुपालन, टोकन-दर-टोकन स्ट्रीमिंग, और मजबूत एरर रिकवरी। यह गाइड बताती है कि Node.js OpenAI SDK को कैसे रीकॉन्फ़िगर करें, स्ट्रक्चर्ड JSON schema एक्सट्रैक्शन कैसे निष्पादित करें, स्ट्रीमिंग रिस्पॉन्स को विश्वसनीयता से कैसे संभालें, और एक्ज़ीक्यूशन एरर्स का डायग्नोसिस कैसे करें।


Step 1: Base URL and Authentication Configuration

आधिकारिक OpenAI Node.js SDK (openai v4+) सीधे OpenAI क्लास कन्स्ट्रक्टर के भीतर कॉन्फ़िगरेशन ओवरराइड्स स्वीकार करता है। अपने ट्रांसपोर्ट लेयर को OpenAI-कंपैटिबल एंडपॉइंट पर माइग्रेट करने के लिए, baseURL प्रॉपर्टी कॉन्फ़िगर करें और अपनी API key सेट करें।

SDK Client Initialization

import OpenAI from "openai";

// Initialize the client pointing to an OpenAI-compatible gateway
const client = new OpenAI({
  apiKey: process.env.ONEMUX_API_KEY,
  baseURL: "https://api.onemux.net/v1",
});

Migration Prerequisites

  1. Environment Variables: सुनिश्चित करें कि आप अपने .env कॉन्फ़िगरेशन में प्रोवाइडर कीज़ को अलग रखते हैं (उदाहरण के लिए, ONEMUX_API_KEY बनाम OPENAI_API_KEY)।
  2. Path Suffix: OpenAI का SDK अपने आप baseURL में /chat/completions जैसे रूट पाथ जोड़ देता है। हमेशा सुनिश्चित करें कि आपके baseURL में /v1 सफिक्स शामिल हो (जैसे, https://api.onemux.net/v1), जब तक कि आपका गेटवे रूट रूटिंग को खुद हैंडल न करता हो।
  3. SDK Version: पुष्टि करें कि आप openai वर्ज़न ^4.0.0 या उससे उच्चतर चला रहे हैं, क्योंकि पुराने v3 वर्ज़न एक अलग कॉन्फ़िगरेशन स्ट्रक्चर (Configuration क्लास) का उपयोग करते थे।

सपोर्टेड रूटिंग नियमों की समीक्षा करने और API क्रेडेंशियल्स के साथ शुरुआत करने के लिए, OneMux Quickstart पर जाएँ।


Step 2: Structured Extraction with Strict JSON Schema

स्ट्रक्चर्ड आउटपुट्स मॉडल्स को दिए गए JSON Schema के बिल्कुल अनुरूप आउटपुट लौटाने के लिए बाध्य करते हैं। स्ट्रक्चर्ड आउटपुट्स पर OpenAI के डॉक्यूमेंटेशन के अनुसार, "strict": true सेट करने पर निम्नलिखित आवश्यक है:

  • सभी ऑब्जेक्ट फ़ील्ड्स required ऐरे में सूचीबद्ध होने चाहिए।
  • सभी ऑब्जेक्ट स्कीमा पर additionalProperties: false स्पष्ट रूप से परिभाषित होना चाहिए।
  • वैकल्पिक (optional) फ़ील्ड्स को null के साथ यूनियन टाइप्स के रूप में मॉडल किया जाना चाहिए (उदा. ["string", "null"])।

Standard Structured Completion Implementation

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.ONEMUX_API_KEY,
  baseURL: "https://api.onemux.net/v1",
});

// Define strict JSON Schema for invoice extraction
const invoiceExtractionSchema = {
  type: "object",
  properties: {
    vendorName: { type: "string" },
    invoiceId: { type: "string" },
    totalAmount: { type: "number" },
    currency: { type: "string" },
    items: {
      type: "array",
      items: {
        type: "object",
        properties: {
          description: { type: "string" },
          quantity: { type: "number" },
          unitPrice: { type: "number" },
        },
        required: ["description", "quantity", "unitPrice"],
        additionalProperties: false,
      },
    },
  },
  required: ["vendorName", "invoiceId", "totalAmount", "currency", "items"],
  additionalProperties: false,
} as const;

async function extractInvoice(rawDocumentText: string) {
  const response = await client.chat.completions.create({
    model: "gpt-4o",
    messages: [
      {
        role: "system",
        content: "Extract normalized invoice records from the provided unstructured input.",
      },
      {
        role: "user",
        content: rawDocumentText,
      },
    ],
    response_format: {
      type: "json_schema",
      json_schema: {
        name: "invoice_extraction",
        strict: true,
        schema: invoiceExtractionSchema,
      },
    },
  });

  const choice = response.choices[0];

  // Check for safety or policy refusals
  if (choice.message.refusal) {
    throw new Error(`Model refused extraction: ${choice.message.refusal}`);
  }

  const rawJson = choice.message.content;
  if (!rawJson) {
    throw new Error("Received empty response payload");
  }

  return JSON.parse(rawJson);
}

डाउनस्ट्रीम गेटवे के साथ कम्पैटिबिलिटी इस बात पर निर्भर करती है कि अंतर्निहित प्रोवाइडर एंडपॉइंट strict: true के साथ json_schema मोड को सपोर्ट करता है या नहीं। विभिन्न प्लेटफ़ॉर्म्स पर मॉडल की क्षमताओं के विवरण के लिए, OneMux Models catalog देखें।


Step 3: Handling Streaming with Structured Outputs

जब response_format के साथ stream: true सक्षम किया जाता है, तो मॉडल JSON पेलोड के आंशिक स्ट्रिंग फ़्रैग्मेंट्स को स्ट्रीम करता है। सामान्य टेक्स्ट चैट के विपरीत, अलग-अलग चंक्स को JSON.parse() से पार्स नहीं किया जा सकता क्योंकि वे अपूर्ण JSON टोकन्स का प्रतिनिधित्व करते हैं।

Accumulating Streamed JSON Chunks

स्ट्रक्चर्ड आउटपुट्स को सही ढंग से स्ट्रीम करने के लिए, स्ट्रीम पूरा होने तक डेल्टा फ़्रैग्मेंट्स को इकट्ठा करें, या इनकमिंग चंक्स को एक इंक्रीमेंटल JSON स्ट्रीम पार्सर के माध्यम से पाइप करें।

async function streamInvoiceExtraction(rawDocumentText: string) {
  const stream = await client.chat.completions.create({
    model: "gpt-4o",
    stream: true,
    messages: [
      {
        role: "system",
        content: "Extract normalized invoice records from the provided text.",
      },
      {
        role: "user",
        content: rawDocumentText,
      },
    ],
    response_format: {
      type: "json_schema",
      json_schema: {
        name: "invoice_extraction",
        strict: true,
        schema: invoiceExtractionSchema,
      },
    },
  });

  let accumulatedJson = "";
  let refusalReason: string | null = null;

  for await (const chunk of stream) {
    const delta = chunk.choices[0]?.delta;

    if (delta?.refusal) {
      refusalReason = (refusalReason || "") + delta.refusal;
    }

    if (delta?.content) {
      accumulatedJson += delta.content;
      // Emit partial events or log progress if building a reactive UI
    }
  }

  if (refusalReason) {
    throw new Error(`Extraction was refused during stream: ${refusalReason}`);
  }

  try {
    return JSON.parse(accumulatedJson);
  } catch (err) {
    throw new Error(`Failed to parse streamed JSON payload: ${accumulatedJson}`);
  }
}

यदि आपकी पाइपलाइन केवल यूज़र इंटरफ़ेस में टाइम-टू-फर्स्ट-बाइट (TTFB) को कम करने के लिए स्ट्रीमिंग का उपयोग करती है, तो सत्यापित करें कि डाउनस्ट्रीम एंडपॉइंट आपके नेटवर्क प्रॉक्सी के माध्यम से निरंतर Server-Sent Events (SSE) का समर्थन करता है।


Step 4: Error Diagnosis and Troubleshooting

SDK कॉल्स को कस्टम baseURL पर माइग्रेट करते समय, एरर डायग्नोसिस को नेटवर्क प्रॉक्सी विफलताओं, स्कीमा गलत कॉन्फ़िगरेशन, रेट लिमिट्स और मॉडल रिफ़्यूज़ल्स के बीच अंतर करना चाहिए।

Common Errors and Resolution Strategies

Error Code / TypeRoot CauseDiagnosis & Fix
401 Unauthorizedअमान्य या गायब API keyपुष्टि करें कि आपकी apiKey में टारगेट गेटवे द्वारा मान्यता प्राप्त एक मान्य क्रेडेंशियल शामिल है (उदा., ONEMUX_API_KEY जांचें)।
400 BadRequestErrorस्कीमा उल्लंघन (strict: true)असमर्थित JSON स्कीमा कीवर्ड्स के लिए एरर मैसेज की जांच करें (उदा., additionalProperties: false का गायब होना या required में फ़ील्ड्स का न होना)।
404 NotFoundगलत पाथ या मॉडल IDसुनिश्चित करें कि baseURL का अंत /v1 से होता है। पुष्टि करें कि अनुरोधित मॉडल प्रोवाइडर की सक्रिय मॉडल सूची में मौजूद है।
429 RateLimitErrorकॉनक्रेन्सी या खर्च की सीमा पार होनाएक्सपोनेंशियल बैकऑफ़ लागू करें। अपने प्रोवाइडर डैशबोर्ड के माध्यम से कोटा लिमिट्स पर नज़र रखें।
Refusal (Choice body)मॉडल सुरक्षा गार्डरेल्स ट्रिगर होनामॉडल ने स्पष्ट रूप से अस्वीकृति (refusal) उत्पन्न की। content में देखने के बजाय choice.message.refusal की जांच करें।

Structured Error Handling Wrapper

import OpenAI from "openai";

async function safeExtractWrapper(fn: () => Promise<any>) {
  try {
    return await fn();
  } catch (error: any) {
    if (error instanceof OpenAI.APIError) {
      console.error(`OpenAI API Error: status=${error.status}, type=${error.type}`);
      console.error(`Message: ${error.message}`);

      if (error.status === 400) {
        console.error("Verify that your schema complies strictly with JSON Schema constraints.");
      } else if (error.status === 401) {
        console.error("Authentication failed: Check your bearer token and proxy baseURL.");
      } else if (error.status === 429) {
        console.warn("Rate limit reached. Queue request for delayed retry.");
      }
    } else {
      console.error("Unexpected application error:", error);
    }
    throw error;
  }
}

Step 5: Consolidating Providers via OneMux

OneMux के माध्यम से OpenAI SDK अनुरोधों को रूट करने से थर्ड-पार्टी लाइब्रेरीज़ या कस्टम प्रोटोकॉल एडेप्टर की आवश्यकता के बिना मल्टी-मॉडल संचालन सरल हो जाता है।

  • यूनिफ़ाइड एंडपॉइंट: मानक OpenAI SDK सिमेंटिक्स का उपयोग करके विभिन्न मॉडल्स में रूट करते हुए एकल क्लाइंट इंटरफ़ेस बनाए रखें।
  • खर्च प्रबंधन और विजिबिलिटी: कई प्रोवाइडर्स के इनवॉइस प्रबंधित किए बिना बिलिंग को केंद्रीकृत करें, प्रति-मॉडल उपयोग की समीक्षा करें, और खर्च के नियम निर्धारित करें।
  • लचीला Pay-as-You-Go: लचीले क्रेडिट टॉप-अप के माध्यम से अपने खाते को फंड करें, जिससे सेवाओं में अप्रत्याशित रुकावट से बचा जा सके।

वर्तमान उपयोग दरों को देखने और मॉडल्स में रूटिंग विकल्पों की तुलना करने के लिए, OneMux Pricing Guide देखें और OneMux Documentation में तकनीकी विवरण पढ़ें।


Sources

सामान्य प्रश्न

क्या मैं कस्टम बेस URL का उपयोग करते समय OpenAI SDK के साथ Zod का उपयोग कर सकता हूँ?

हाँ। यदि आपका गेटवे `/chat/completions` स्ट्रक्चर्ड आउटपुट्स स्पेक को पूरी तरह से लागू करता है, तो `client.beta.chat.completions.parse()` और `zodResponseFormat()` जैसे हेल्पर मेथड्स Zod स्कीमा को आवश्यक स्ट्रिक्ट JSON Schema पेलोड में ट्रांसलेट करके निर्बाध रूप से काम करते हैं।

'strict: true' का उपयोग करते समय मॉडल 400 एरर क्यों देता है?

OpenAI स्ट्रक्चर्ड आउटपुट इंजन के लिए यह आवश्यक है कि प्रत्येक ऑब्जेक्ट परिभाषा में स्पष्ट रूप से `additionalProperties: false` शामिल हो और हर घोषित प्रॉपर्टी को `required` ऐरे के भीतर सूचीबद्ध किया गया हो। यदि `required` में कोई भी की गायब है, या यदि असमर्थित JSON Schema कीवर्ड मौजूद हैं, तो API अनुरोध को 400 वैलिडेशन एरर के साथ अस्वीकार कर देता है।

क्या baseURL बदलने से SDK टेलीमेट्री या टाइमआउट्स पर असर पड़ता है?

`baseURL` को ओवरराइड करने से सभी HTTP ट्रांसपोर्ट नए URL पर रीडायरेक्ट हो जाते हैं। टाइमआउट और रीट्राई विकल्प (जैसे कि OpenAI कन्स्ट्रक्टर में `maxRetries` या `timeout`) क्लाइंट साइड पर पहले की तरह ही काम करते रहते हैं।

संबंधित लेख

Guides

विश्वसनीय JSON निष्कर्षण के लिए GPT 6.1 Terra लागत और संदर्भ गाइड

OneMux के माध्यम से JSON Schema validation के साथ structured extraction के लिए GPT 6.1 Terra workload की लागत का अनुमान लगाना और context, retries तथा output tokens को सीमित करना सीखें।

Guides

GPT-5.6 Terra मूल्य कटौती: सस्ते इनपुट टोकन आपकी टोकन रणनीति कैसे बदलते हैं

OpenAI ने GPT-5.6 Terra और Luna इनपुट मूल्य घटाए हैं। देखें कि कम लागत वाले टोकन प्रॉम्प्ट कम्प्रेशन, API खर्च और रूटिंग को कैसे प्रभावित करते हैं—और OneMux एक्सेस को कैसे सरल बनाता है।

Guides

ईकॉमर्स सपोर्ट के लिए GPT-5.6 Sol: नवीनतम LLM API का उपयोग कैसे करें

जानें कैसे GPT-5.6 Sol, OpenAI का नवीनतम LLM, OneMux के यूनिफाइड API के साथ आपके ईकॉमर्स सपोर्ट को बदल सकता है। मूल्य निर्धारण, एकीकरण और व्यावहारिक उपयोग के मामलों का अन्वेषण करें।

Guides

OpenAI ने GPT-5.6 Sol की रेट लिमिट्स को ढीला किया: इंडी हैकर्स के लिए AI API एक्सेस की अहम जानकारी

OpenAI ने हाल ही में GPT-5.6 Sol पर रेट लिमिट्स को ढीला किया है। लेकिन इसे अनलिमिटेड न कहें। जानें कैसे इंडी हैकर्स OneMux के ज़रिए GPT-5.6 Luna का उपयोग करके लचीला और किफ़ायती AI API एक्सेस पा सकते हैं।