> This is a page from the ElevenLabs documentation. For a complete page index, fetch https://elevenlabs.io/docs/llms.txt. For the full documentation in a single file, fetch https://elevenlabs.io/docs/llms-full.txt.

# अपना मॉडल इंटीग्रेट करें

> **Note**
>
> Custom LLM आपको बाहरी endpoint के ज़रिए अपनी बातचीत को अपने LLM से कनेक्ट करने देता है।
> ElevenLabs [नेटिव रूप से इंटीग्रेट किए गए LLMs](/docs/hi/eleven-agents/customization/llm) को भी सपोर्ट करता है।

**Custom LLMs** से आप अपनी OpenAI API key इस्तेमाल कर सकते हैं या पूरी तरह कस्टम LLM सर्वर चला सकते हैं।

## परिचय

डिफ़ॉल्ट रूप से, हम OpenAI जैसे लोकप्रिय मॉडलों के लिए अपने आंतरिक क्रेडेंशियल्स इस्तेमाल करते हैं। कस्टम LLM सर्वर इस्तेमाल करने के लिए, उसे नीचे दिए गए OpenAI-compatible request/response structures में से किसी एक के अनुरूप होना चाहिए:

* [Chat Completions API](https://platform.openai.com/docs/api-reference/chat/create) (`/v1/chat/completions`)
* [Responses API](https://platform.openai.com/docs/api-reference/responses/create) (`/v1/responses`)

> **Info**
>
> Responses API, OpenAI का नया API फ़ॉर्मैट है जो अतिरिक्त सुविधाओं को सपोर्ट करता है। कस्टम LLM इंटीग्रेशन के लिए दोनों API फ़ॉर्मैट पूरी तरह समर्थित हैं।

नीचे दिए गए गाइड दोनों उपयोग मामलों को कवर करते हैं:

1. **अपनी OpenAI key इस्तेमाल करें**: हमारे प्लेटफ़ॉर्म के साथ अपनी OpenAI API key इस्तेमाल करें।
2. **कस्टम LLM सर्वर**: अपना LLM सर्वर implementation होस्ट और कनेक्ट करें।

आप जानेंगे कि कैसे:

* अपनी OpenAI API key को ElevenLabs में स्टोर करें
* ऐसा सर्वर होस्ट करें जो OpenAI के [Chat Completions](https://platform.openai.com/docs/api-reference/chat/create) या [Responses](https://platform.openai.com/docs/api-reference/responses/create) endpoint की नकल करता हो
* ElevenLabs को अपने कस्टम endpoint पर भेजें
* ज़रूरत के अनुसार अपने LLM को अतिरिक्त parameters भेजें

## रीजनिंग सारांश

आपके endpoint को अंतिम उत्तर से अलग रीजनिंग लौटानी होगी। ElevenLabs अंतिम उत्तर से रीजनिंग जनरेट नहीं करता।

समर्थित endpoint से रीजनिंग मांगने के लिए, एजेंट की LLM सेटिंग्स में **Reasoning summary** चालू करें या API के ज़रिए `enable_reasoning_summary` सेट करें।

### रीजनिंग लौटाएं

अपने endpoint से मेल खाने वाला फ़ॉर्मैट इस्तेमाल करें:

#### Chat Completions API

हर response delta के `reasoning` या `reasoning_content` फ़ील्ड में रीजनिंग स्ट्रीम करें।

Gemini-compatible endpoints के लिए, ElevenLabs
`google.thinking_config.include_thoughts` के साथ thoughts मांगता है और
`extra_content.google.thought` से चिह्नित कंटेंट पढ़ता है।

#### Responses API

`reasoning` output item लौटाएं, जिसमें सारांश टेक्स्ट उसके `summary` फ़ील्ड में हो।

रीजनिंग effort कॉन्फ़िगर होने और Reasoning summary चालू होने पर, ElevenLabs रिक्वेस्ट में
`reasoning.summary` को `auto` पर सेट करता है।

स्टोरेज, डिलीवरी और सीमाओं के लिए [रीजनिंग सारांश](/docs/hi/eleven-agents/customization/llm#reasoning-summary) देखें।

## अपनी OpenAI key इस्तेमाल करना

कस्टम OpenAI key इंटीग्रेट करने के लिए, ElevenLabs डैशबोर्ड में अपने एजेंट की सेटिंग्स को अपने कस्टम LLM सर्वर पर पॉइंट करने के लिए अपडेट करें और अपनी `OPENAI_API_KEY` वाला एक सीक्रेट बनाएं:

ElevenLabs डैशबोर्ड में अपनी Agent settings में, दाईं ओर "LLM" ड्रॉपडाउन मेनू से "Custom LLM" चुनें।

![सीक्रेट जोड़ें](/docs/_fern-img/83c62b81ef04860b9d884e28e1b4ac7bbceaa6e481e72e15ae82a76ec9bbad8e.webp)

"LLM" के नीचे वाले फ़ील्ड पर क्लिक करें और नीचे स्क्रॉल करके "Custom LLM" चुनें।

अपने कस्टम LLM सर्वर का server URL और Model ID दर्ज करें।

![URL दर्ज करें](/docs/_fern-img/85ed8154868096a5c8de4c5e1c09d83c861069ea098c7643a960cac1736b67cb.webp)

"API key" के नीचे ड्रॉपडाउन पर क्लिक करें और "Create new secret" चुनें। key का नाम `OPENAI_API_KEY` रखें, उसे "value" फ़ील्ड में जोड़ें और "Add secret" पर क्लिक करें।

LLM modal बंद करने के लिए "x" बटन पर क्लिक करें और बदलाव सेव करने के लिए "Publish" पर क्लिक करें।

## कस्टम LLM सर्वर

कस्टम LLM सर्वर लाने के लिए, OpenAI की शैली का इस्तेमाल करके एक compatible server endpoint सेट अप करें। आप Chat Completions API (`/v1/chat/completions`) या Responses API (`/v1/responses`) में से कोई भी implement कर सकते हैं।

दोनों endpoints को `Content-Type: text/event-stream` के साथ SSE (Server-Sent Events) फ़ॉर्मैट में responses लौटाने होंगे।

#### Chat Completions API

Chat Completions API, `/v1/chat/completions` endpoint इस्तेमाल करता है।

हर chunk का फ़ॉर्मैट `data: {json}\n\n` होना चाहिए और stream का अंत `data: [DONE]\n\n` से होना चाहिए।

यहां एक उदाहरण server implementation दिया गया है:

```python
import json
import os
import fastapi
from fastapi.responses import StreamingResponse
from openai import AsyncOpenAI
import uvicorn
import logging
from dotenv import load_dotenv
from pydantic import BaseModel
from typing import List, Optional

# Load environment variables from .env file
load_dotenv()

# Retrieve API key from environment
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
if not OPENAI_API_KEY:
    raise ValueError("OPENAI_API_KEY not found in environment variables")

app = fastapi.FastAPI()
oai_client = AsyncOpenAI(api_key=OPENAI_API_KEY)

class Message(BaseModel):
    role: str
    content: str

class ChatCompletionRequest(BaseModel):
    messages: List[Message]
    model: str
    temperature: Optional[float] = 0.7
    max_tokens: Optional[int] = None
    stream: Optional[bool] = False
    user_id: Optional[str] = None

@app.post("/v1/chat/completions")
async def create_chat_completion(request: ChatCompletionRequest) -> StreamingResponse:
    oai_request = request.dict(exclude_none=True)
    if "user_id" in oai_request:
        oai_request["user"] = oai_request.pop("user_id")

    chat_completion_coroutine = await oai_client.chat.completions.create(**oai_request)

    async def event_stream():
        try:
            async for chunk in chat_completion_coroutine:
                # Convert the ChatCompletionChunk to a dictionary before JSON serialization
                chunk_dict = chunk.model_dump()
                yield f"data: {json.dumps(chunk_dict)}\n\n"
            yield "data: [DONE]\n\n"
        except Exception as e:
            logging.error("An error occurred: %s", str(e))
            yield f"data: {json.dumps({'error': 'Internal error occurred!'})}\n\n"

    return StreamingResponse(event_stream(), media_type="text/event-stream")

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8013)
```

#### Responses API

Responses API, `/v1/responses` endpoint इस्तेमाल करता है।

हर chunk का फ़ॉर्मैट `event: {type}\ndata: {json}\n\n` होना चाहिए और stream का अंत `data: [DONE]\n\n` से होना चाहिए। कम से कम ये events ज़रूरी हैं:

* `response.output_text.delta` - टेक्स्ट कंटेंट स्ट्रीम करने के लिए
* `response.completed` - पूरा होने का संकेत देने के लिए

**`server.py`**

```python title="server.py"
import json
import os
import fastapi
from fastapi.responses import StreamingResponse
from openai import AsyncOpenAI
import uvicorn
import logging
from dotenv import load_dotenv
from pydantic import BaseModel
from typing import List, Optional

load_dotenv()

OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
if not OPENAI_API_KEY:
    raise ValueError("OPENAI_API_KEY not found in environment variables")

app = fastapi.FastAPI()
oai_client = AsyncOpenAI(api_key=OPENAI_API_KEY)

class InputMessage(BaseModel):
    role: str
    content: str

class ResponseCreateRequest(BaseModel):
    model: str
    input: List[InputMessage]
    instructions: Optional[str] = None
    temperature: Optional[float] = 0.7
    max_output_tokens: Optional[int] = None
    stream: Optional[bool] = False

@app.post("/v1/responses")
async def create_response(request: ResponseCreateRequest) -> StreamingResponse:
    input_messages = [{"role": msg.role, "content": msg.content} for msg in request.input]

    response_stream = await oai_client.responses.create(
        model=request.model,
        input=input_messages,
        instructions=request.instructions,
        temperature=request.temperature,
        max_output_tokens=request.max_output_tokens,
        stream=True
    )

    async def event_stream():
        try:
            async for event in response_stream:
                if event.type == "response.output_text.delta":
                    yield f"event: response.output_text.delta\ndata: {json.dumps({'type': 'response.output_text.delta', 'delta': event.delta})}\n\n"
                elif event.type == "response.completed":
                    yield f"event: response.completed\ndata: {json.dumps({'type': 'response.completed', 'response': {'id': event.response.id, 'status': 'completed'}})}\n\n"

            yield "data: [DONE]\n\n"

        except Exception as e:
            logging.error("An error occurred: %s", str(e))
            yield f"event: error\ndata: {json.dumps({'type': 'error', 'error': {'message': str(e)}})}\n\n"

    return StreamingResponse(event_stream(), media_type="text/event-stream")

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8013)

```

**`server.ts`**

```typescript title="server.ts"
import express, { Request, Response } from "express";
import OpenAI from "openai";

const app = express();
app.use(express.json());

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

interface InputMessage {
  role: string;
  content: string;
}

interface ResponseCreateRequest {
  model: string;
  input: InputMessage[];
  instructions?: string;
  temperature?: number;
  max_output_tokens?: number;
  stream?: boolean;
}

app.post("/v1/responses", async (req: Request, res: Response) => {
  const request = req.body as ResponseCreateRequest;

  res.setHeader("Content-Type", "text/event-stream");
  res.setHeader("Cache-Control", "no-cache");
  res.setHeader("Connection", "keep-alive");

  try {
    const stream = await openai.responses.create({
      model: request.model,
      input: request.input,
      instructions: request.instructions,
      temperature: request.temperature ?? 0.7,
      max_output_tokens: request.max_output_tokens,
      stream: true,
    });

    for await (const event of stream) {
      if (event.type === "response.output_text.delta") {
        res.write(
          `event: response.output_text.delta\ndata: ${JSON.stringify({ type: "response.output_text.delta", delta: event.delta })}\n\n`
        );
      } else if (event.type === "response.completed") {
        res.write(
          `event: response.completed\ndata: ${JSON.stringify({ type: "response.completed", response: { id: event.response.id, status: "completed" } })}\n\n`
        );
      }
    }

    res.write("data: [DONE]\n\n");
    res.end();
  } catch (error) {
    console.error("An error occurred:", error);
    res.write(
      `event: error\ndata: ${JSON.stringify({ type: "error", error: { message: String(error) } })}\n\n`
    );
    res.end();
  }
});

app.listen(8013, () => console.log("Server running on port 8013"));
```

यह कोड या अपना सर्वर कोड चलाएं।

![](/docs/_fern-img/8032697eeac9a62bb084feb13ab05294df2fee44f14a97897f0b7c10ffee813c.webp)

### अपने सर्वर के लिए सार्वजनिक URL सेट करना

अपने सर्वर को एक्सेस करने योग्य बनाने के लिए, ngrok जैसे tunneling tool से सार्वजनिक URL बनाएं:

```shell
ngrok http --url=<Your url>.ngrok.app 8013
```

![](/docs/_fern-img/16d139cc2889d46e026c8aa7578fcdcd8d228dbe0f4df245091ea6de2ceb345a.webp)

### ElevenLabs CustomLLM कॉन्फ़िगर करना

अब ElevenLabs डैशबोर्ड में अपने एजेंट की सेटिंग्स को अपने कस्टम LLM सर्वर पर पॉइंट करने के लिए अपडेट करें।

![](/docs/_fern-img/d57d81e44dffb7e6f581a4eed449d887f6c365b8ceb4f4f0174bd7e2ffd62537.webp)

अपने server URL को ngrok endpoint पर सेट करें और "Limit token usage" को 5000 पर सेट करें।

अब आप अपने LLM सर्वर के साथ एजेंट से इंटरैक्ट करना शुरू कर सकते हैं।

## धीमी प्रोसेसिंग वाले LLM के लिए ऑप्टिमाइज़ करना

अगर आपके कस्टम LLM का प्रोसेसिंग समय धीमा है (शायद एजेंटिक रीजनिंग या प्री-प्रोसेसिंग की ज़रूरतों के कारण), तो आप अपने स्ट्रीमिंग रिस्पॉन्स में **बफ़र शब्द** लागू करके बातचीत के प्रवाह को बेहतर बना सकते हैं। यह तकनीक आपके LLM के पूरा रिस्पॉन्स जनरेट करने के दौरान बोलने की प्राकृतिक लय बनाए रखने में मदद करती है।

### बफ़र शब्द

जब आपके LLM को पूरा रिस्पॉन्स प्रोसेस करने के लिए ज़्यादा समय चाहिए हो, तो `"... "` (एलिप्सिस के बाद एक स्पेस) पर खत्म होने वाला शुरुआती रिस्पॉन्स लौटाएं। इससे टेक्स्ट टू स्पीच सिस्टम बातचीत को सहज और सक्रिय रखते हुए प्राकृतिक प्रवाह बनाए रख पाता है।
इससे ऐसे प्राकृतिक विराम बनते हैं, जो बाद के उस कॉन्टेंट में सहजता से जुड़ते हैं जिस पर LLM ज़्यादा देर तक विचार कर सकता है। अतिरिक्त स्पेस ज़रूरी है, ताकि बाद का कॉन्टेंट `"..."` से न जुड़ जाए, क्योंकि इससे ऑडियो में विकृति आ सकती है।

### इम्प्लीमेंटेशन

बफ़र शब्द लागू करने के लिए अपने कस्टम LLM सर्वर को इस तरह बदलें:

**`server.py`**

```python title="server.py"
@app.post("/v1/chat/completions")
async def create_chat_completion(request: ChatCompletionRequest) -> StreamingResponse:
    oai_request = request.dict(exclude_none=True)
    if "user_id" in oai_request:
        oai_request["user"] = oai_request.pop("user_id")

    async def event_stream():
        try:
            # Send initial buffer chunk while processing
            initial_chunk = {
                "id": "chatcmpl-buffer",
                "object": "chat.completion.chunk",
                "created": 1234567890,
                "model": request.model,
                "choices": [{
                    "delta": {"content": "Let me think about that... "},
                    "index": 0,
                    "finish_reason": None
                }]
            }
            yield f"data: {json.dumps(initial_chunk)}\n\n"

            # Process the actual LLM response
            chat_completion_coroutine = await oai_client.chat.completions.create(**oai_request)

            async for chunk in chat_completion_coroutine:
                chunk_dict = chunk.model_dump()
                yield f"data: {json.dumps(chunk_dict)}\n\n"
            yield "data: [DONE]\n\n"

        except Exception as e:
            logging.error("An error occurred: %s", str(e))
            yield f"data: {json.dumps({'error': 'Internal error occurred!'})}\n\n"

    return StreamingResponse(event_stream(), media_type="text/event-stream")

```

**`server.ts`**

```typescript title="server.ts"
app.post("/v1/chat/completions", async (req: Request, res: Response) => {
  const request = req.body as ChatCompletionRequest;
  const oaiRequest = { ...request };

  if (oaiRequest.user_id) {
    oaiRequest.user = oaiRequest.user_id;
    delete oaiRequest.user_id;
  }

  res.setHeader("Content-Type", "text/event-stream");
  res.setHeader("Cache-Control", "no-cache");
  res.setHeader("Connection", "keep-alive");

  try {
    // Send initial buffer chunk while processing
    const initialChunk = {
      id: "chatcmpl-buffer",
      object: "chat.completion.chunk",
      created: Math.floor(Date.now() / 1000),
      model: request.model,
      choices: [
        {
          delta: { content: "Let me think about that... " },
          index: 0,
          finish_reason: null,
        },
      ],
    };
    res.write(`data: ${JSON.stringify(initialChunk)}\n\n`);

    // Process the actual LLM response
    const stream = await openai.chat.completions.create({
      ...oaiRequest,
      stream: true,
    });

    for await (const chunk of stream) {
      res.write(`data: ${JSON.stringify(chunk)}\n\n`);
    }

    res.write("data: [DONE]\n\n");
    res.end();
  } catch (error) {
    console.error("An error occurred:", error);
    res.write(`data: ${JSON.stringify({ error: "Internal error occurred!" })}\n\n`);
    res.end();
  }
});
```

## सिस्टम टूल्स इंटीग्रेशन

आपका कस्टम LLM बातचीत के प्रवाह और स्थिति को नियंत्रित करने के लिए [सिस्टम टूल्स](/docs/hi/eleven-agents/customization/tools/system-tools) ट्रिगर कर सकता है। आपके एजेंट में कॉन्फ़िगर होने पर ये टूल्स आपके चैट कंप्लीशन अनुरोधों के `tools` पैरामीटर में अपने-आप शामिल हो जाते हैं।

### सिस्टम टूल्स कैसे काम करते हैं

1. **LLM का निर्णय**: आपका कस्टम LLM बातचीत के संदर्भ के आधार पर तय करता है कि इन टूल्स को कब कॉल करना है
2. **टूल रिस्पॉन्स**: LLM स्टैंडर्ड OpenAI फ़ॉर्मेट में फ़ंक्शन कॉल के साथ रिस्पॉन्ड करता है
3. **बैकएंड प्रोसेसिंग**: ElevenLabs टूल कॉल्स को प्रोसेस करता है और बातचीत की स्थिति अपडेट करता है

सिस्टम टूल्स के बारे में ज़्यादा जानकारी के लिए, [हमारी गाइड](/docs/hi/eleven-agents/customization/tools/system-tools) देखें

### उपलब्ध सिस्टम टूल्स

#### कॉल समाप्त करें

**उद्देश्य**: उचित स्थितियां पूरी होने पर बातचीत को अपने-आप समाप्त करना।

**ट्रिगर की स्थितियां**: LLM को इस टूल को कॉल करना चाहिए जब:

* मुख्य काम पूरा हो गया हो और यूज़र संतुष्ट हो
* आपसी सहमति से बातचीत अपने स्वाभाविक निष्कर्ष पर पहुंच गई हो
* यूज़र साफ़ तौर पर बातचीत समाप्त करने की इच्छा जताए

**पैरामीटर**:

* `reason` (string, आवश्यक): कॉल समाप्त करने का कारण
* `message` (string, वैकल्पिक): कॉल समाप्त करने से पहले यूज़र को भेजने के लिए विदाई संदेश

**फ़ंक्शन कॉल फ़ॉर्मेट**:

```json
{
  "type": "function",
  "function": {
    "name": "end_call",
    "arguments": "{\"reason\": \"Task completed successfully\", \"message\": \"Thank you for using our service. Have a great day!\"}"
  }
}
```

**इम्प्लीमेंटेशन**: अपने एजेंट की सेटिंग्स में सिस्टम टूल के रूप में कॉन्फ़िगर करें। LLM को इस फ़ंक्शन को कॉल करने के समय के बारे में विस्तृत निर्देश मिलेंगे।

और जानें: [कॉल समाप्त करने का टूल](/docs/hi/eleven-agents/customization/tools/system-tools/end-call)

#### भाषा पहचान

**उद्देश्य**: बातचीत के दौरान यूज़र की पहचानी गई भाषा पर अपने-आप स्विच करना।

**ट्रिगर की स्थितियां**: LLM को इस टूल को कॉल करना चाहिए जब:

* यूज़र मौजूदा बातचीत की भाषा से अलग भाषा में बोलता हो
* यूज़र साफ़ तौर पर भाषा बदलने का अनुरोध करे
* बातचीत के लिए कई भाषाओं के सपोर्ट की ज़रूरत हो

**पैरामीटर**:

* `reason` (string, आवश्यक): भाषा बदलने का कारण
* `language` (string, आवश्यक): जिस भाषा को स्विच करना है उसका भाषा कोड (समर्थित भाषाओं की सूची में होना चाहिए)

**फ़ंक्शन कॉल फ़ॉर्मेट**:

```json
{
  "type": "function",
  "function": {
    "name": "language_detection",
    "arguments": "{\"reason\": \"User requested Spanish\", \"language\": \"es\"}"
  }
}
```

**इम्प्लीमेंटेशन**: एजेंट की सेटिंग्स में समर्थित भाषाएं कॉन्फ़िगर करें और भाषा पहचान सिस्टम टूल जोड़ें। एजेंट पहचानी गई भाषाओं के अनुसार वॉइस और रिस्पॉन्स अपने-आप बदल देगा।

और जानें: [भाषा पहचान टूल](/docs/hi/eleven-agents/customization/tools/system-tools/language-detection)

#### एजेंट ट्रांसफ़र

**उद्देश्य**: यूज़र की ज़रूरतों के आधार पर विशेषज्ञ AI एजेंट्स के बीच बातचीत ट्रांसफ़र करना।

**ट्रिगर की स्थितियां**: LLM को इस टूल को कॉल करना चाहिए जब:

* यूज़र के अनुरोध के लिए विशेषज्ञ जानकारी या अलग एजेंट क्षमताओं की ज़रूरत हो
* मौजूदा एजेंट क्वेरी को पर्याप्त रूप से संभाल न सके
* बातचीत का प्रवाह किसी दूसरे तरह के एजेंट की ज़रूरत दिखाए

**पैरामीटर**:

* `reason` (string, वैकल्पिक): एजेंट ट्रांसफ़र का कारण
* `agent_number` (integer, आवश्यक): जिस एजेंट को ट्रांसफ़र करना है उसका शून्य से शुरू होने वाला नंबर (कॉन्फ़िगर किए गए ट्रांसफ़र नियमों के आधार पर)

**फ़ंक्शन कॉल फ़ॉर्मेट**:

```json
{
  "type": "function",
  "function": {
    "name": "transfer_to_agent",
    "arguments": "{\"reason\": \"User needs billing support\", \"agent_number\": 0}"
  }
}
```

**इम्प्लीमेंटेशन**: स्थितियों को खास एजेंट ID से मैप करने वाले ट्रांसफ़र नियम तय करें। कॉन्फ़िगर करें कि मौजूदा एजेंट किन एजेंट्स को ट्रांसफ़र कर सकता है। ट्रांसफ़र कॉन्फ़िगरेशन में एजेंट्स को शून्य से शुरू होने वाले नंबरों से संदर्भित किया जाता है।

और जानें: [एजेंट ट्रांसफ़र टूल](/docs/hi/eleven-agents/customization/tools/system-tools/agent-transfer)

#### मानव को ट्रांसफ़र करें

**उद्देश्य**: जब AI सहायता पर्याप्त न हो, तो बातचीत को सहजता से मानव ऑपरेटर को सौंपना।

**ट्रिगर की स्थितियां**: LLM को इस टूल को कॉल करना चाहिए जब:

* जटिल समस्याओं के लिए मानवीय निर्णय की ज़रूरत हो
* यूज़र साफ़ तौर पर मानव सहायता मांगे
* खास अनुरोध के लिए AI अपनी क्षमताओं की सीमा तक पहुंच जाए
* एस्केलेशन प्रोटोकॉल ट्रिगर हो जाएं

**पैरामीटर**:

* `reason` (string, वैकल्पिक): ट्रांसफ़र का कारण
* `transfer_number` (string, आवश्यक): जिस फ़ोन नंबर पर ट्रांसफ़र करना है (कॉन्फ़िगर किए गए नंबरों से मेल खाना चाहिए)
* `client_message` (string, आवश्यक): ट्रांसफ़र की प्रतीक्षा के दौरान क्लाइंट को पढ़कर सुनाया जाने वाला संदेश
* `agent_message` (string, आवश्यक): कॉल रिसीव करने वाले मानव ऑपरेटर के लिए संदेश

**फ़ंक्शन कॉल फ़ॉर्मेट**:

```json
{
  "type": "function",
  "function": {
    "name": "transfer_to_number",
    "arguments": "{\"reason\": \"Complex billing issue\", \"transfer_number\": \"+15551234567\", \"client_message\": \"I'm transferring you to a billing specialist who can help with your account.\", \"agent_message\": \"Customer has a complex billing dispute about order #12345 from last month.\"}"
  }
}
```

**इम्प्लीमेंटेशन**: ट्रांसफ़र फ़ोन नंबर और स्थितियां कॉन्फ़िगर करें। ग्राहक और कॉल रिसीव करने वाले मानव ऑपरेटर, दोनों के लिए संदेश तय करें। यह Twilio और SIP ट्रंकिंग, दोनों के साथ काम करता है।

और जानें: [मानव को ट्रांसफ़र करने का टूल](/docs/hi/eleven-agents/customization/tools/system-tools/transfer-to-number)

#### टर्न छोड़ें

**उद्देश्य**: एजेंट को बिना बोले रुकने और यूज़र के इनपुट की प्रतीक्षा करने देना।

**ट्रिगर की स्थितियां**: LLM को इस टूल को कॉल करना चाहिए जब:

* यूज़र संकेत दे कि उसे एक पल चाहिए ("Give me a second", "Let me think")
* यूज़र बातचीत के प्रवाह में विराम का अनुरोध करे
* एजेंट को पता चले कि यूज़र को जानकारी समझने के लिए समय चाहिए

**पैरामीटर**:

* `reason` (string, वैकल्पिक): विराम की ज़रूरत का कारण बताने वाला मुक्त-रूप कारण

**फ़ंक्शन कॉल फ़ॉर्मेट**:

```json
{
  "type": "function",
  "function": {
    "name": "skip_turn",
    "arguments": "{\"reason\": \"User requested time to think\"}"
  }
}
```

**इम्प्लीमेंटेशन**: किसी अतिरिक्त कॉन्फ़िगरेशन की ज़रूरत नहीं है। यह टूल एजेंट को केवल तब तक चुप रहने का संकेत देता है, जब तक यूज़र दोबारा न बोले।

और जानें: [टर्न छोड़ने का टूल](/docs/hi/eleven-agents/customization/tools/system-tools/skip-turn)

#### वॉइसमेल पहचान

**Parameters**:

* `reason` (string, आवश्यक): voicemail detect होने का कारण (जैसे, "automated greeting detected", "no human response")

**Function call format**:

```json
{
  "type": "function",
  "function": {
    "name": "voicemail_detection",
    "arguments": "{\"reason\": \"Automated greeting detected with request to leave message\"}"
  }
}
```

और जानें: [वॉइसमेल पहचान टूल](/docs/hi/eleven-agents/customization/tools/system-tools/voicemail-detection)

### सिस्टम टूल्स के साथ उदाहरण अनुरोध

सिस्टम टूल्स कॉन्फ़िगर होने पर, आपके कस्टम LLM को ऐसे अनुरोध मिलेंगे जिनमें स्टैंडर्ड OpenAI फ़ॉर्मेट में टूल्स शामिल होते हैं:

```json
{
  "messages": [
    {
      "role": "system",
      "content": "You are a helpful assistant. You have access to system tools for managing conversations."
    },
    {
      "role": "user",
      "content": "I think we're done here, thanks for your help!"
    }
  ],
  "model": "your-custom-model",
  "temperature": 0.7,
  "max_tokens": 1000,
  "stream": true,
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "end_call",
        "description": "Call this function to end the current conversation when the main task has been completed...",
        "parameters": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "description": "The reason for the tool call."
            },
            "message": {
              "type": "string",
              "description": "A farewell message to send to the user along right before ending the call."
            }
          },
          "required": ["reason"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "language_detection",
        "description": "Change the conversation language when the user expresses a language preference explicitly...",
        "parameters": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "description": "The reason for the tool call."
            },
            "language": {
              "type": "string",
              "description": "The language to switch to. Must be one of language codes in tool description."
            }
          },
          "required": ["reason", "language"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "skip_turn",
        "description": "Skip a turn when the user explicitly indicates they need a moment to think...",
        "parameters": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "description": "Optional free-form reason explaining why the pause is needed."
            }
          },
          "required": []
        }
      }
    }
  ]
}
```

> **Note**
>
> सिस्टम टूल्स का इस्तेमाल करने के लिए आपके कस्टम LLM को फ़ंक्शन कॉलिंग सपोर्ट करनी चाहिए। सुनिश्चित करें कि आपका मॉडल
> OpenAI फ़ॉर्मेट में सही फ़ंक्शन कॉल रिस्पॉन्स जनरेट कर सकता है।

# अतिरिक्त सुविधाएं

#### कस्टम LLM पैरामीटर

आप अपने कस्टम LLM इम्प्लीमेंटेशन में अतिरिक्त पैरामीटर पास कर सकते हैं।

#### Python

#### अतिरिक्त पैरामीटर तय करें

अपने कस्टम पैरामीटर वाला एक ऑब्जेक्ट बनाएं:

```python
from elevenlabs.conversational_ai.conversation import Conversation, ConversationInitiationData

extra_body_for_convai = {
    "UUID": "123e4567-e89b-12d3-a456-426614174000",
    "parameter-1": "value-1",
    "parameter-2": "value-2",
}

config = ConversationInitiationData(
    extra_body=extra_body_for_convai,
)
```

#### LLM इम्प्लीमेंटेशन अपडेट करें

अतिरिक्त पैरामीटर संभालने के लिए अपने कस्टम LLM कोड में बदलाव करें:

```python
import json
import os
import fastapi
from fastapi.responses import StreamingResponse
from fastapi import Request
from openai import AsyncOpenAI
import uvicorn
import logging
from dotenv import load_dotenv
from pydantic import BaseModel
from typing import List, Optional

# Load environment variables from .env file
load_dotenv()

# Retrieve API key from environment
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
if not OPENAI_API_KEY:
    raise ValueError("OPENAI_API_KEY not found in environment variables")

app = fastapi.FastAPI()
oai_client = AsyncOpenAI(api_key=OPENAI_API_KEY)

class Message(BaseModel):
    role: str
    content: str

class ChatCompletionRequest(BaseModel):
    messages: List[Message]
    model: str
    temperature: Optional[float] = 0.7
    max_tokens: Optional[int] = None
    stream: Optional[bool] = False
    user_id: Optional[str] = None
    elevenlabs_extra_body: Optional[dict] = None

@app.post("/v1/chat/completions")
async def create_chat_completion(request: ChatCompletionRequest) -> StreamingResponse:
    oai_request = request.dict(exclude_none=True)
    print(oai_request)
    if "user_id" in oai_request:
        oai_request["user"] = oai_request.pop("user_id")

    if "elevenlabs_extra_body" in oai_request:
        oai_request.pop("elevenlabs_extra_body")

    chat_completion_coroutine = await oai_client.chat.completions.create(**oai_request)

    async def event_stream():
        try:
            async for chunk in chat_completion_coroutine:
                chunk_dict = chunk.model_dump()
                yield f"data: {json.dumps(chunk_dict)}\n\n"
            yield "data: [DONE]\n\n"
        except Exception as e:
            logging.error("An error occurred: %s", str(e))
            yield f"data: {json.dumps({'error': 'Internal error occurred!'})}\n\n"

    return StreamingResponse(event_stream(), media_type="text/event-stream")

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8013)
```

### उदाहरण अनुरोध

इस कस्टम मैसेज सेटअप के साथ, आपके LLM को इस फ़ॉर्मेट में अनुरोध मिलेंगे:

```json
{
  "messages": [
    {
      "role": "system",
      "content": "\n  <Redacted>"
    },
    {
      "role": "assistant",
      "content": "Hey I'm currently unavailable."
    },
    {
      "role": "user",
      "content": "Hey, who are you?"
    }
  ],
  "model": "gpt-4o",
  "temperature": 0.5,
  "max_tokens": 5000,
  "stream": true,
  "elevenlabs_extra_body": {
    "UUID": "123e4567-e89b-12d3-a456-426614174000",
    "parameter-1": "value-1",
    "parameter-2": "value-2"
  }
}
```