> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bettertoken.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# BetterToken API में स्ट्रीमिंग और टूल कॉलिंग

> BetterToken API में स्ट्रीमिंग और टूल कॉलिंग जोड़ें। Chat Completions, Responses और Messages के इवेंट, फ़ंक्शन स्कीमा और नतीजे लौटाने का तरीका देखें।

`stream: true` से स्ट्रीमिंग चालू करें और अपने API के स्कीमा के अनुसार क्लाइंट टूल परिभाषित करें। स्ट्रीमिंग और टूल कॉलिंग का समर्थन मॉडल के अनुसार बदलता है। ऐप में इस्तेमाल करने से पहले अपनी Model ID से छोटा अनुरोध जाँचें।

## आवश्यकताएँ

पहले [SDK के उदाहरणों](/hi/guides/sdk-examples.md) से साधारण टेक्स्ट अनुरोध सफलतापूर्वक चलाएँ। [model plaza](https://bettertoken.ai/pricing) से जाँचे जाने वाले प्रोटोकॉल के लिए सही Model ID कॉपी करें। किन बातों की जाँच करनी है, यह [मॉडल चयन गाइड](/hi/faq/model-calling/model-selection-guide.md) में दिया है।

प्रोजेक्ट के Python वर्चुअल एनवायरनमेंट में `openai` और `anthropic` इंस्टॉल करें, फिर उसी टर्मिनल में प्लेसहोल्डर बदलें:

```bash theme={null}
python -m pip install openai anthropic
export BETTERTOKEN_API_KEY="YOUR_API_KEY"
export BETTERTOKEN_MODEL_ID="YOUR_MODEL_ID"
```

नीचे हर Python कोड ब्लॉक अलग से चल सकता है। 120 सेकंड का टाइमआउट इन छोटे परीक्षणों का उदाहरण है। ऐप का टाइमआउट [टाइमआउट गाइड](/hi/best-practices.md#set-a-generous-timeout) के अनुसार चुनें। `max_tokens` या `max_output_tokens` सेट करने से पहले मॉडल की [आउटपुट टोकन सीमा](/hi/faq/model-calling/max-tokens.md) देखें।

## टेक्स्ट उत्तर स्ट्रीम करें

स्ट्रीमिंग में एक HTTP उत्तर के भीतर सर्वर से भेजे गए इवेंट (SSE) मिलते हैं। हर SSE इवेंट में पूरा वाक्य या आर्ग्युमेंट का पूरा JSON ऑब्जेक्ट होना ज़रूरी नहीं है।

| API | अनुरोध की सेटिंग | टेक्स्ट इवेंट या चंक | उत्तर का अंत |
| - | - | - | - |
| [Chat Completions](/hi/api-reference/chat-completions.md) | `stream: true` | `choices[].delta.content`; टूल के टुकड़ों के लिए `delta.tool_calls` | हर विकल्प में `finish_reason` मिलता है; मूल स्ट्रीम `data: [DONE]` पर समाप्त होती है |
| [Responses](/hi/api-reference/responses.md) | `stream: true` | `response.output_text.delta` जैसे प्रकार वाले इवेंट | `response.completed`; विफलता और अधूरे उत्तर के इवेंट भी संभालें |
| [Messages](/hi/api-reference/messages.md) | `stream: true` | `content_block_delta` में `text_delta`; टूल आर्ग्युमेंट के लिए `input_json_delta` | `message_delta` में रुकने का कारण आता है, फिर `message_stop` मिलता है |

SDK SSE फ़ॉर्मैट को पार्स करता है। ये उदाहरण नया टेक्स्ट और पूरा होने की जानकारी दिखाते हैं। ऐप में त्रुटि वाले इवेंट भी संभालें।

**Chat Completions**

```python theme={null}
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["BETTERTOKEN_API_KEY"],
    base_url="https://bettertoken.ai/v1",
    timeout=120.0,
    max_retries=0,
)
with client.chat.completions.create(
    model=os.environ["BETTERTOKEN_MODEL_ID"],
    messages=[{"role": "user", "content": "Say hello in one sentence."}],
    stream=True,
) as stream:
    for chunk in stream:
        for choice in chunk.choices:
            if choice.delta.content:
                print(choice.delta.content, end="", flush=True)
            if choice.finish_reason:
                print("\nFinish reason:", choice.finish_reason)
```

**Responses**

```python theme={null}
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["BETTERTOKEN_API_KEY"],
    base_url="https://bettertoken.ai/v1",
    timeout=120.0,
    max_retries=0,
)
with client.responses.create(
    model=os.environ["BETTERTOKEN_MODEL_ID"],
    input="Say hello in one sentence.",
    stream=True,
) as stream:
    for event in stream:
        if event.type == "response.output_text.delta":
            print(event.delta, end="", flush=True)
        elif event.type in (
            "response.completed", "response.failed", "response.incomplete", "error"
        ):
            print("\n", event)
```

**Messages**

```python theme={null}
import os
from anthropic import Anthropic

client = Anthropic(
    api_key=os.environ["BETTERTOKEN_API_KEY"],
    base_url="https://bettertoken.ai",
    timeout=120.0,
    max_retries=0,
)
with client.messages.create(
    model=os.environ["BETTERTOKEN_MODEL_ID"],
    max_tokens=256,
    messages=[{"role": "user", "content": "Say hello in one sentence."}],
    stream=True,
) as stream:
    for event in stream:
        if event.type == "content_block_delta" and event.delta.type == "text_delta":
            print(event.delta.text, end="", flush=True)
        elif event.type == "message_delta":
            print("\nStop reason:", event.delta.stop_reason)
```

## हर प्रोटोकॉल के लिए मौसम का टूल परिभाषित करें

मॉडल फ़ंक्शन कॉल का अनुरोध करता है। आपका ऐप आर्ग्युमेंट जाँचता है, फ़ंक्शन चलाता है और नतीजा लौटाता है। उदाहरण में एक `get_weather` फ़ंक्शन है जो `location` आर्ग्युमेंट लेता है और **तय डेमो डेटा लौटाता है, मौजूदा मौसम नहीं**। मौसम की सेवा या अतिरिक्त Key की ज़रूरत नहीं है।

| अनुरोध या उत्तर का फ़ील्ड | Chat Completions | Responses | Messages |
| - | - | - | - |
| प्रॉम्प्ट | `messages` | `input` | `messages` |
| `tools[]` में टूल की घोषणा | `type: "function"`, और `function` के भीतर `name`, `description`, `parameters` | `type: "function"`, और टूल के शीर्ष स्तर पर `name`, `description`, `parameters` | `name`, `description`, `input_schema` |
| लौटाई गई कॉल | `choices[].message.tool_calls[]` | `output[]` में `type: "function_call"` वाला आइटम | `content[]` में `type: "tool_use"` वाला ब्लॉक |
| आर्ग्युमेंट | `function.arguments` में JSON स्ट्रिंग | `arguments` में JSON स्ट्रिंग | `input` में ऑब्जेक्ट |
| नतीजा लौटाना | `role: "tool"`, `tool_call_id`, `content` वाला संदेश | `type: "function_call_output"`, `call_id`, स्ट्रिंग `output` वाला इनपुट आइटम | `type: "tool_result"`, `tool_use_id`, `content` वाला उपयोगकर्ता कंटेंट ब्लॉक |

समर्थन मॉडल और प्रोटोकॉल के अनुसार बदलता है। साधारण टेक्स्ट चलने पर भी अपनी Model ID से यह छोटा टूल अनुरोध जाँचें। टूल की घोषणा से होस्ट की गई खोज या प्रदाता की ओर से चलने वाले दूसरे टूल चालू नहीं होते।

## टूल कॉल चलाएँ और नतीजा लौटाएँ

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

**Chat Completions**

```python theme={null}
import json
import os
from openai import OpenAI

def get_weather(location):
    if not isinstance(location, str) or not location.strip():
        raise ValueError("location must be a non-empty string")
    return {"location": location, "temperature_c": 20, "source": "demo"}

client = OpenAI(
    api_key=os.environ["BETTERTOKEN_API_KEY"],
    base_url="https://bettertoken.ai/v1", timeout=120.0, max_retries=0,
)
model = os.environ["BETTERTOKEN_MODEL_ID"]
schema = {
    "type": "object",
    "properties": {"location": {"type": "string"}},
    "required": ["location"], "additionalProperties": False,
}
tools = [{"type": "function", "function": {
    "name": "get_weather", "description": "Get demonstration weather for a location.",
    "parameters": schema,
}}]
messages = [{"role": "user", "content": "Call get_weather for Paris and report the demo result."}]
first = client.chat.completions.create(model=model, messages=messages, tools=tools)
message = first.choices[0].message
calls = message.tool_calls or []
if not calls:
    print("No tool call returned:", message.content)
else:
    messages.append(message.model_dump(exclude_none=True))
    for call in calls:
        if call.type != "function" or call.function.name != "get_weather":
            raise ValueError("Unexpected tool")
        args = json.loads(call.function.arguments)
        result = get_weather(**args)
        messages.append({
            "role": "tool", "tool_call_id": call.id,
            "content": json.dumps(result),
        })
    final = client.chat.completions.create(model=model, messages=messages, tools=tools)
    print(final.choices[0].message.model_dump(exclude_none=True))
```

**Responses**

```python theme={null}
import json
import os
from openai import OpenAI

def get_weather(location):
    if not isinstance(location, str) or not location.strip():
        raise ValueError("location must be a non-empty string")
    return {"location": location, "temperature_c": 20, "source": "demo"}

client = OpenAI(
    api_key=os.environ["BETTERTOKEN_API_KEY"],
    base_url="https://bettertoken.ai/v1", timeout=120.0, max_retries=0,
)
model = os.environ["BETTERTOKEN_MODEL_ID"]
schema = {
    "type": "object",
    "properties": {"location": {"type": "string"}},
    "required": ["location"], "additionalProperties": False,
}
tools = [{
    "type": "function", "name": "get_weather",
    "description": "Get demonstration weather for a location.", "parameters": schema,
}]
history = [{"role": "user", "content": "Call get_weather for Paris and report the demo result."}]
first = client.responses.create(model=model, input=history, tools=tools)
calls = [item for item in first.output if item.type == "function_call"]
if not calls:
    print("No tool call returned:", first.output)
else:
    history.extend(first.output)
    for call in calls:
        if call.name != "get_weather":
            raise ValueError("Unexpected tool")
        args = json.loads(call.arguments)
        result = get_weather(**args)
        history.append({
            "type": "function_call_output", "call_id": call.call_id,
            "output": json.dumps(result),
        })
    final = client.responses.create(model=model, input=history, tools=tools)
    print(final.output)
```

**Messages**

```python theme={null}
import json
import os
from anthropic import Anthropic

def get_weather(location):
    if not isinstance(location, str) or not location.strip():
        raise ValueError("location must be a non-empty string")
    return {"location": location, "temperature_c": 20, "source": "demo"}

client = Anthropic(
    api_key=os.environ["BETTERTOKEN_API_KEY"],
    base_url="https://bettertoken.ai", timeout=120.0, max_retries=0,
)
model = os.environ["BETTERTOKEN_MODEL_ID"]
schema = {
    "type": "object",
    "properties": {"location": {"type": "string"}},
    "required": ["location"], "additionalProperties": False,
}
tools = [{
    "name": "get_weather", "description": "Get demonstration weather for a location.",
    "input_schema": schema,
}]
messages = [{"role": "user", "content": "Call get_weather for Paris and report the demo result."}]
first = client.messages.create(model=model, max_tokens=1024, messages=messages, tools=tools)
calls = [block for block in first.content if block.type == "tool_use"]
if first.stop_reason == "max_tokens":
    raise RuntimeError("Response truncated; inspect it before executing tools")
if not calls:
    print("No tool call returned:", first.content)
else:
    messages.append({"role": "assistant", "content": first.content})
    results = []
    for call in calls:
        if call.name != "get_weather":
            raise ValueError("Unexpected tool")
        result = get_weather(**call.input)
        results.append({
            "type": "tool_result", "tool_use_id": call.id,
            "content": json.dumps(result),
        })
    messages.append({"role": "user", "content": results})
    final = client.messages.create(model=model, max_tokens=1024, messages=messages, tools=tools)
    print(final.content)
```

टूल के नतीजे जोड़ने से पहले सहायक का पूरा उत्तर सुरक्षित रखें। Responses में सभी `output` आइटम रखें, जिनमें लौटाए गए रीजनिंग आइटम भी शामिल हैं। Messages में कंटेंट ब्लॉक और उनका क्रम बनाए रखें। नई ID बनाने के बजाय लौटाई गई कॉल ID से नतीजे जोड़ें।

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

### क्या टूल के आर्ग्युमेंट आते ही उन्हें चला सकते हैं?

टूल कॉल के इंडेक्स या आइटम ID के अनुसार टुकड़े इकट्ठा करें। पूरे आर्ग्युमेंट मिलने पर उन्हें पार्स और जाँचें। अधूरा JSON पार्स नहीं हो सकता। स्ट्रीमिंग और टूल जोड़ने से पहले ऊपर के बिना स्ट्रीमिंग वाले उदाहरण चलाएँ।

### साधारण टेक्स्ट चलने पर भी टूल क्यों विफल होते हैं?

समर्थन मॉडल और प्रोटोकॉल के अनुसार बदलता है। अपनी Model ID से छोटा टूल अनुरोध जाँचें। टूल का स्कीमा, लौटे हुए आर्ग्युमेंट, नतीजे की ID और संदेशों का क्रम देखें। टाइप के अनुसार JSON की जाँच के लिए [संरचित आउटपुट से जुड़े प्रश्न](/hi/faq/model-calling/structured-json-pydantic.md) देखें।

### स्ट्रीम बीच में टूटने पर क्या फिर से अनुरोध भेजें?

दोबारा भेजने से पहले अनुरोध का रिकॉर्ड जाँचें। कनेक्शन टूटने से पता नहीं चलता कि अनुरोध पूरा हुआ या नहीं। पुनः प्रयास अलग कोशिश है; उसमें पहले से चल चुकी टूल कार्रवाई दोहराई नहीं जानी चाहिए। [त्रुटि और पुनः प्रयास गाइड](/hi/api-reference/errors.md) देखें।

## संबंधित गाइड

* [SDK सेटअप और प्रमाणीकरण](/hi/guides/sdk-examples.md)
* [API संदर्भ का परिचय](/hi/api-reference/introduction.md)
* [आउटपुट टोकन सीमा](/hi/faq/model-calling/max-tokens.md)
* [संरचित JSON और Pydantic](/hi/faq/model-calling/structured-json-pydantic.md)
* [टाइमआउट सेटिंग](/hi/best-practices.md#set-a-generous-timeout)
* [त्रुटियाँ और सीमाएँ](/hi/api-reference/errors.md)

## आधिकारिक संदर्भ

इन संदर्भों में अपस्ट्रीम प्रोटोकॉल के फ़ील्ड परिभाषित हैं। इस्तेमाल से पहले BetterToken की अपनी Model ID से सुविधा जाँचें।

* [OpenAI में फ़ंक्शन कॉलिंग](https://developers.openai.com/api/docs/guides/function-calling)
* [OpenAI में उत्तर की स्ट्रीमिंग](https://developers.openai.com/api/docs/guides/streaming-responses)
* [Anthropic में टूल की परिभाषा](https://platform.claude.com/docs/en/agents-and-tools/tool-use/define-tools)
* [Anthropic में टूल के नतीजे](https://platform.claude.com/docs/en/agents-and-tools/tool-use/handle-tool-calls)
* [Anthropic Messages की स्ट्रीमिंग](https://platform.claude.com/docs/en/build-with-claude/streaming)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.