HI ▾
API कुंजी पाएँ

एलएलएम एपीआई से चैटबॉट बनाएं: पायथन ट्यूटोरियल

Abliterated मॉडल बड़े भाषा मॉडल हैं जिनमें सुरक्षा अस्वीकृति लागू करने वाले तंत्र हटा दिए गए हैं, जिससे मॉडल सामग्री फ़िल्टर पर टकराए बिना विवादास्पद, वयस्क या विशेष प्रश्नों का उत्तर दे सकता है। यह दृष्टिकोण डेवलपर्स को मॉडल की आवाज़ और ज्ञान कटऑफ पर पूर्ण नियंत्रण देता है, जो कोडिंग, रोलप्ले और रचनात्मक लेखन के लिए विशेष रूप से मूल्यवान है जहाँ मानदंड गार्डरेल उपयोगी आउटपुट को ब्लॉक कर सकते हैं।

चैटबॉट संवाद लूप का चित्रण करते हुए, लूप में एक केंद्रीय घन के आसपास चल रहे चैट संदेश ब्लॉक

मुख्य बिंदु

  • API स्टेटलेस है, इसलिए आपका कोड कन्वर्सेशन हिस्ट्री को संभालता है और हर अनुरोध पर उसे भेजता है।
  • स्ट्रीमिंग, फ़ंक्शन कॉलिंग और JSON मोड सभी मानक OpenAI पैरामीटर का उपयोग करते हैं।
  • कॉन्टेक्स्ट विंडो 100,000 टोकन के करीब पहुँचने से पहले हिस्ट्री को ट्रिम या सारांशित करें।
  • 2,000 इनपुट टोकन और 400 आउटपुट टोकन वाले 1,000 चैट्स का खर्च लगभग $0.50 आता है।

मुख्य विचार: एक चैटबॉट एक लूप और एक लिस्ट है

एक भाषा मॉडल अनुरोधों के बीच कुछ भी याद नहीं रखता। POST /v1/chat/completions का प्रत्येक कॉल स्वतंत्र होता है। जो स्मृति जैसा लगता है, वह आपका प्रोग्राम है जो पहले संदेशों को फिर से भेजता है, प्रत्येक को एक भूमिका टैग के साथ: system स्थिर निर्देशों के लिए, user उस व्यक्ति द्वारा टाइप किए गए कंटेंट के लिए, और assistant पहले मॉडल उत्तरों के लिए।

तो पूरा आर्किटेक्चर छोटा है। एक लिस्ट रखें। यूजर मैसेज ऐपेंड करें। लिस्ट भेजें। जवाब ऐपेंड करें। दोहराएं। इस ट्यूटोरियल में स्ट्रीमिंग से लेकर टूल्स तक, हर कुछ उसी लूप का ही एक वेरिएशन है।

यह API OpenAI-संगत है, इसलिए आप नियमित openai पैकेज का उपयोग करते हैं। Base URL को https://api.abliterated.cc/v1 पर सेट करें, अपनी कुंजी का उपयोग करें और मॉडल को uncensored पर सेट करें। API कुंजी पृष्ठ से एक कुंजी प्राप्त करें; $0.50 का मुफ़्त ट्रायल क्रेडिट कई सौ छोटे परीक्षण संदेशों के लिए पर्याप्त है।

स्टेप 1: एक काम करने वाला कंसोल चैटबॉट

SDK को pip install openai के साथ इंस्टॉल करें और इसे चलाएं।

from openai import OpenAI

client = OpenAI(
    base_url="https://api.abliterated.cc/v1",
    api_key="YOUR_KEY",
)

messages = [
    {"role": "system", "content": "You are a concise, friendly support assistant for a bike shop."}
]

while True:
    text = input("you: ")
    if text.strip() in {"quit", "exit"}:
        break
    messages.append({"role": "user", "content": text})
    resp = client.chat.completions.create(
        model="uncensored",
        messages=messages,
        temperature=0.7,
    )
    answer = resp.choices[0].message.content
    messages.append({"role": "assistant", "content": answer})
    print("bot:", answer)

यह एक पूर्ण चैटबॉट है। सिस्टम संदेश उसका काम सेट करता है, सूची स्मृति वहन करती है, और temperature उत्तरों की विविधता को नियंत्रित करता है। तथ्यात्मक सहायता बॉट्स के लिए इसे 0.2 की ओर कम करें, रचनात्मक बॉट्स के लिए इसे 1.0 की ओर बढ़ाएं।

एक सिस्टम प्रॉम्प्ट लिखें जो काम सेट करे

सिस्टम मैसेज एक चैटबॉट को बेहतर बनाने का सबसे सस्ता स्थान है। इसे छोटा और विशिष्ट रखें। रोल, ऑडियंस, जवाबों की लंबाई और टोन, और जब बॉट को न पता हो तो क्या करना है, उसका नाम दें। "आप एक साइकिल की दुकान के सवालों का जवाब देते हैं। अधिकतम तीन वाक्यों में जवाब दें। अगर सवाल मरम्मत की कीमत के बारे में है, तो कहें कि मैकेनिक को साइकिल की जाँच करनी होगी" जैसा प्रॉम्प्ट सामान्य गुणों के एक पेज से अधिक कर सकता है।

दो आदतें फायदेमंद हैं। पहली, नियमों को भावनाओं के बजाय एक्शन के रूप में रखें: "मददगार बनें" के बजाय "अनुरोध अस्पष्ट होने पर एक स्पष्टीकरण वाला सवाल पूछें"। दूसरा, हॉस्टाइल इनपुट्स के साथ टेस्ट करें, जैसे कि एक खाली मैसेज, एक बहुत लंबा पेस्ट और एक अनुरोध जो आपके प्रोडक्ट से बिल्कुल नहीं मेल खाता। जो देखें, उसके आधार पर प्रॉम्प्ट ठीक करें, फिर उन इनपुट्स को एक रिग्रेशन लिस्ट के रूप में रखें।

चूंकि सिस्टम संदेश हर टर्न पर फिर से भेजा जाता है, इसमें हर शब्द हर अनुरोध पर बिल किया जाता है। 1,000 चैट्स के 5 टर्न वाले 400-टोकन प्रॉम्प्ट में 2,000,000 इनपुट टोकन जुड़ते हैं, या 2 x $0.15 = $0.30। यह छोटा है, लेकिन यह दिखाता है कि भारी प्रॉम्प्ट्स वॉल्यूम पर कैसे जुड़ते हैं।

स्टेप 2: जवाब को स्ट्रीम करें

चैट विंडो में पूरे जवाब का इंतज़ार करना धीमा लगता है। stream: true सेट करें और आने पर टुकड़े प्रिंट करें। स्ट्रीम सर्वर-सेंट इवेंट्स का उपयोग करती है और एक यूसेज ब्लॉक के साथ समाप्त होती है, इसलिए आप टोकन काउंट लॉग कर सकते हैं।

from openai import OpenAI

client = OpenAI(base_url="https://api.abliterated.cc/v1", api_key="YOUR_KEY")
messages = [{"role": "user", "content": "Explain tire pressure in two sentences."}]

stream = client.chat.completions.create(
    model="uncensored",
    messages=messages,
    stream=True,
)
reply = ""
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        part = chunk.choices[0].delta.content
        reply += part
        print(part, end="", flush=True)
    if getattr(chunk, "usage", None):
        print("\ntokens:", chunk.usage.prompt_tokens, chunk.usage.completion_tokens)

याद रखें कि असेंबल किए गए reply को अपनी हिस्ट्री में ऐपेंड करें, वरना अगले टर्न को यह नहीं पता होगा कि बॉट ने क्या कहा।

स्टेप 3: कॉन्टेक्स्ट को बढ़ने से पहले प्रबंधित करें

विंडो 100,000 टोकन की है, जो प्रॉम्प्ट और कंप्लीशन के बीच साझा है। ज्यादातर चैटबॉट्स कभी भी इसके करीब नहीं पहुंचते, लेकिन खर्च हिस्ट्री के साथ बढ़ता है क्योंकि आप हर टर्न पर पूरे प्रॉम्प्ट के लिए भुगतान करते हैं। एक सरल पॉलिसी दोनों को नियंत्रित में रखती है:

  • सिस्टम मैसेज हमेशा रखें।
  • आखिरी 10 से 20 मैसेज को ज्यों का त्यों रखें।
  • जब सूची आपकी चुनी हुई आकार सीमा (जैसे 8,000 अनुमानित टोकन) से अधिक हो जाती है, तो सबसे पुराना ब्लॉक मॉडल को "इस बातचीत का सारांश 150 शब्दों से कम में लिखें" निर्देश के साथ भेजें, और उस ब्लॉक को सिस्टम संदेश के रूप में सारांश से बदल दें।

चार अंग्रेजी अक्षरों के लिए एक टोकन का एक मोटा अनुमान ट्रिगर के लिए पर्याप्त है। हर जवाब में यूसेज नंबर आपको बाद में सटीक संख्या देते हैं, ताकि आप लिमिट को कैलिब्रेट कर सकें।

यदि आप सबसे पुराने मैसेज हटाकर छोटा करते हैं, तो उन्हें यूजर और असिस्टेंट के जोड़ों में हटाएं। एक जवाब बिना सवाल के, या एक सवाल बिना जवाब के, मॉडल को आपकी उम्मीद से ज़्यादा भ्रमित करता है।

चरण 4: बॉट को टूल्स दें

टूल कॉलिंग मॉडल को आपके कोड से कुछ करवाने का अनुरोध करने देती है, जैसे ऑर्डर की जाँच करना। आप tools के साथ फ़ंक्शन्स का वर्णन करते हैं, मॉडल tool_calls एंट्री के साथ जवाब देता है, आप फ़ंक्शन चलाते हैं, और परिणाम को role: "tool" संदेश के रूप में भेजते हैं।

import json
from openai import OpenAI

client = OpenAI(base_url="https://api.abliterated.cc/v1", api_key="YOUR_KEY")

tools = [{
    "type": "function",
    "function": {
        "name": "get_order_status",
        "description": "Look up the status of an order by its id",
        "parameters": {
            "type": "object",
            "properties": {"order_id": {"type": "string"}},
            "required": ["order_id"],
        },
    },
}]

def get_order_status(order_id):
    return {"order_id": order_id, "status": "shipped"}

messages = [{"role": "user", "content": "Where is order A1042?"}]
resp = client.chat.completions.create(
    model="uncensored", messages=messages, tools=tools, tool_choice="auto"
)
msg = resp.choices[0].message

if msg.tool_calls:
    messages.append(msg)
    for call in msg.tool_calls:
        args = json.loads(call.function.arguments)
        result = get_order_status(**args)
        messages.append({
            "role": "tool",
            "tool_call_id": call.id,
            "content": json.dumps(result),
        })
    final = client.chat.completions.create(
        model="uncensored", messages=messages, tools=tools
    )
    print(final.choices[0].message.content)

कोई भी साइड इफेक्ट वाला काम शुरू करने से पहले हमेशा तर्कों की जाँच करें। मॉडल एक कॉल का प्रस्ताव रखता है; आपका कोड तय करता है कि उसे निष्पादित करना है या नहीं।

चरण 5: JSON मोड के साथ संरचित आउटपुट

जब आपके प्रोग्राम का अगला चरण पाठ की बजाय डेटा चाहता है, जैसे कि एक संदेश को किसी श्रेणी में वर्गीकृत करना, तो response_format के साथ JSON मोड का उपयोग करें। अपने प्रॉम्प्ट में JSON शब्द और अपेक्षित कुंजियों का भी उल्लेख करें।

curl https://api.abliterated.cc/v1/chat/completions \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "uncensored",
    "response_format": {"type": "json_object"},
    "messages": [
      {"role": "system", "content": "Reply with JSON: {\"intent\": string, \"urgent\": boolean}"},
      {"role": "user", "content": "My brakes squeal and I ride tomorrow morning."}
    ]
  }'

फिर भी json.loads को एक try ब्लॉक में लपेटें। यदि पार्सिंग विफल होती है, तो त्रुटि पाठ को अंत में जोड़कर एक बार फिर से प्रयास करें; विफल अनुरोधों का शुल्क नहीं लिया जाता है।

त्रुटियाँ, लागत और तैनाती के नोट्स

त्रुटियों, पुनः प्रयासों और रेट लिमिट को हैंडल करें

वास्तविक उपयोगकर्ता अजीब समयों में अनुरोध भेजते हैं, और नेटवर्क विफल हो सकते हैं। कॉल को इस तरह रैप करें कि एक खराब प्रतिक्रिया से बातचीत क्रैश न हो।

import time
from openai import OpenAI, APIError, RateLimitError

client = OpenAI(base_url="https://api.abliterated.cc/v1", api_key="YOUR_KEY")

def chat(messages, tries=3):
    for attempt in range(tries):
        try:
            resp = client.chat.completions.create(
                model="uncensored", messages=messages, temperature=0.7
            )
            return resp.choices[0].message.content
        except RateLimitError:
            time.sleep(2 ** attempt)
        except APIError as exc:
            if attempt == tries - 1:
                raise
            time.sleep(1)
    return "Sorry, the assistant is busy. Please try again in a moment."

एक पूर्ण कुंजी 8 समानांतर अनुरोध और प्रति मिनट 300 अनुरोधों की अनुमति देती है; ट्रायल कुंजी 2 और 60 की अनुमति देती है। यदि आपका बॉट एक साथ कई उपयोगकर्ताओं को सेवा देता है, तो रीट्राइ पर निर्भर रहने के बजाय, 8 से कम वर्कर लिमिट के साथ अनुरोधों को कतार में लगाएं। चूंकि विफल अनुरोधों का चार्ज नहीं होता, रीट्राइ की कोई टोकन लागत नहीं है। रीट्राइ की संख्या छोटी रखें ताकि असली विफलता जल्द फेल हो जाए।

प्रत्येक बातचीत के टर्न के साथ X-Request-Id हेडर को लॉग करें। जब एक उत्तर गलत दिखे, तो id आपको बाद में सटीक अनुरोध खोजने में सक्षम बनाती है।

लागत और तैनाती

मूल्य $0.15 प्रति 1M इनपुट टोकन और $0.50 प्रति 1M आउटपुट टोकन है। मान लीजिए कि एक सहायता चैट में कुल 2,000 इनपुट टोकन और 400 आउटपुट टोकन का उपयोग होता है।

  • इनपुट: 0.002M x $0.15 = $0.0003
  • आउटपुट: 0.0004M x $0.50 = $0.0002
  • एक चैट: $0.0005, इसलिए 1,000 चैट्स की लागत $0.50 है

वर्तमान दरें और टॉप-अप बोनस मूल्य सूची पर देखें। उत्पादन के लिए, कुंजी को सर्वर पर रखें, ब्राउज़र कोड में कभी नहीं, और क्रेडिट खत्म होने से पहले चेतावनी पाने के लिए X-Balance-USD रिस्पॉन्स हेडर पर नज़र रखें। एक पूर्ण कुंजी 8 समानांतर अनुरोधों और प्रति मिनट 300 अनुरोधों की अनुमति देती है, इसलिए एक साथ सभी भेजने के बजाय बर्स्ट को क्यू में डालें। दस्तावेज़ में प्रत्येक समर्थित पैरामीटर की सूची है।

प्रश्न और उत्तर

क्या मुझे चैटबॉट बनाने के लिए एक फ्रेमवर्क की आवश्यकता है?

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

क्या API पहले संदेशों को याद रखता है?

नहीं। प्रत्येक अनुरोध स्वतंत्र है, इसलिए आपके कोड को हर बार इतिहास फिर से भेजना होगा।

मैं इतिहास को बहुत लंबा होने से कैसे रोकूं?

सिस्टम संदेश और हालिया टर्न को बनाए रखें, और सूची आपके द्वारा निर्धारित आकार से अधिक होने पर पुराने टर्न को एक छोटे नोट में सारांशित करें।

क्या बॉट मेरे अपने फ़ंक्शन कॉल कर सकता है?

हाँ। टूल्स और tool_choice पास करें, जब उत्तर में tool_calls हों तो फ़ंक्शन चलाएं, और परिणाम को एक tool message के रूप में लौटाएं।

आपकी कुंजी बस एक फ़ॉर्म दूर है

एक खाता बनाएँ, कुंजी कॉपी करें, बेस URL बदलें। सेटअप यही है।