# LangChain ও LiteLLM

> LangChain (Python ও JavaScript) থেকে ChatOpenAI আর custom base URL দিয়ে, এবং LiteLLM থেকে SDK বা proxy হিসেবে openai/ model prefix দিয়ে Tokens ব্যবহার করুন।

LangChain আর LiteLLM, দুটোতেই এমন একটা OpenAI client আছে যাতে custom base URL দেওয়া যায়, আর Tokens-এর এটুকুই দরকার। এই পেজে প্রথমে Python ও JavaScript-এ LangChain-এর `ChatOpenAI` setup দেখানো হয়েছে, তারপর LiteLLM, Python SDK হিসেবে এবং proxy হিসেবে।

সব উদাহরণে ধরে নেওয়া হয়েছে আপনার key export করা আছে:

```bash
export TOKENS_API_KEY="tok_live_your_key"
```

## LangChain Python: base_url দিয়ে ChatOpenAI

```bash
pip install --upgrade langchain-openai
```

```python title="chain.py"
import os
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="deepseek/deepseek-v4.1-flash",
    base_url="https://tokens.bd/v1",
    api_key=os.environ["TOKENS_API_KEY"],
    temperature=0.2,
    max_tokens=500,
    timeout=120,
    max_retries=2,
)

reply = llm.invoke([
    ("system", "You are a precise SQL reviewer."),
    ("human", "Is SELECT * in a view a problem? Two sentences."),
])
print(reply.content)
print(reply.usage_metadata)
```

`model`-এ দিতে হবে Tokens-এর model ID, [/models](/models) বা `GET /v1/models`-এ যেভাবে লেখা আছে ঠিক সেভাবে। LangChain ওটা না বদলেই পাঠিয়ে দেয়।

### Streaming

```python
llm = ChatOpenAI(
    model="deepseek/deepseek-v4.1-flash",
    base_url="https://tokens.bd/v1",
    api_key=os.environ["TOKENS_API_KEY"],
    stream_usage=True,  # sets stream_options.include_usage so you get token counts
)

for chunk in llm.stream("Give me three naming tips for Python modules."):
    print(chunk.content, end="", flush=True)
```

`stream_usage=True` না দিলে Tokens-এর stream করা response-এ usage-এর কোনো তথ্য থাকে না। দেখুন [Streaming](/docs/streaming)।

### Tool আর chain

`bind_tools`, `with_structured_output` আর LCEL chain সবই চলে, কারণ এগুলো শুধু OpenAI chat format-এর ওপর নির্ভর করে। তবে tool calling আর structured output-এর জন্য model-কে সেগুলো সাপোর্ট করতেই হবে। কোনো model-এর ওপর কিছু দাঁড় করানোর আগে [/models](/models)-এ তার পেজটা দেখে নিন, আর পড়ুন [Tool calling](/docs/tool-calling)।

```python
from langchain_core.tools import tool

@tool
def get_weather(city: str) -> str:
    """Current weather for a city."""
    return f"{city}: light rain, 29C"

llm_with_tools = llm.bind_tools([get_weather])
msg = llm_with_tools.invoke("Do I need an umbrella in Dhaka?")
print(msg.tool_calls)
```

## LangChain JS: configuration.baseURL দিয়ে ChatOpenAI

```bash
npm install @langchain/openai @langchain/core
```

JavaScript-এ base URL বসে `configuration`-এর ভেতরে। ওটা সরাসরি নিচের OpenAI client-এ চলে যায়।

```ts title="chain.ts"
import { ChatOpenAI } from "@langchain/openai";

const llm = new ChatOpenAI({
  model: "deepseek/deepseek-v4.1-flash",
  apiKey: process.env.TOKENS_API_KEY,
  configuration: { baseURL: "https://tokens.bd/v1" },
  temperature: 0.2,
  maxTokens: 500,
  streamUsage: true,
});

const reply = await llm.invoke("Explain debouncing vs throttling in two sentences.");
console.log(reply.content);

for await (const chunk of await llm.stream("List three uses for a WeakMap.")) {
  process.stdout.write(String(chunk.content));
}
```

LangChain-এর code চালান server-এ বা CLI-তে, browser bundle-এ নয়। Tokens CORS header পাঠায় না, আর যে-ই dev tools খুলবে সে-ই আপনার key দেখে ফেলবে।

## LiteLLM: api_base-এর সাথে openai/ prefix

LiteLLM model-এর নামের prefix দেখে request কোথায় যাবে ঠিক করে। `openai/` মানে হলো, আপনি `api_base`-এ যে ঠিকানা দেবেন সেখানে ওর generic OpenAI-compatible client ব্যবহার হবে। LiteLLM শুধু প্রথম `openai/`-টা কেটে নেয়, তাই Tokens-এর model ID (যার নিজস্ব `provider/` অংশ আছে) যেমন আছে তেমনই চলে যায়।

### LiteLLM Python SDK

```bash
pip install --upgrade litellm
```

```python title="litellm_example.py"
import os
import litellm

response = litellm.completion(
    model="openai/deepseek/deepseek-v4.1-flash",  # "openai/" + Tokens model ID
    api_base="https://tokens.bd/v1",
    api_key=os.environ["TOKENS_API_KEY"],
    messages=[{"role": "user", "content": "One tip for faster pytest runs?"}],
    max_tokens=200,
)
print(response.choices[0].message.content)
```

`api_base`-এ `/v1` রাখুন। LiteLLM-এ 404 আসার সবচেয়ে বড় কারণ এটা বাদ দেওয়া।

### LiteLLM proxy config

আপনার team যদি LiteLLM proxy চালায়, তাহলে Tokens-এর model `model_list`-এ যোগ করুন আর key রাখুন environment-এ:

```yaml title="config.yaml"
model_list:
  - model_name: deepseek-v4.1-flash # the name your apps will request
    litellm_params:
      model: openai/deepseek/deepseek-v4.1-flash
      api_base: https://tokens.bd/v1
      api_key: os.environ/TOKENS_API_KEY
```

```bash
litellm --config config.yaml
```

এরপর proxy-র client-রা `deepseek-v4.1-flash` চাইবে, আর LiteLLM সেই request Tokens-এ পাঠিয়ে দেবে। কয়েকটা কথা জেনে রাখুন:

- খরচ, plan window আর rate limit খাটে প্রতিটি Tokens অ্যাকাউন্টের ওপর, proxy-র user ধরে নয়। একটা Tokens key-র পেছনে যত জনই থাকুক, সবাই সেই অ্যাকাউন্টের প্রতি মিনিটের আর concurrency-র সীমা ভাগাভাগি করে ([Rate limits](/docs/rate-limits))।
- আলাদা app-এর জন্য আলাদা সীমা চাইলে আলাদা Tokens key বানান, প্রতিটিতে মাসিক spend cap আর allowed-models list দিন ([API keys](/docs/api-keys)), আর প্রতি `model_list` entry-তে একটা করে key ব্যবহার করুন।
- LiteLLM-এর নিজের cost tracking Tokens-এর দাম জানে না। সঠিক হিসাবের জন্য Dashboard-এর usage পেজ বা `GET /v1/tokens/usage` দেখুন।

## কিছু fail করলে

LangChain আর LiteLLM, দুটোই OpenAI SDK-র error মুড়ে দেয়। তাই HTTP status আর Tokens-এর `error.code` (যেমন `invalid_api_key`, `model_not_found`, `insufficient_credits`, `window_exhausted`) exception message-এর মধ্যেই থাকে। কোন code-এর কী সমাধান, তা [Troubleshooting](/docs/troubleshooting) গাইডে আছে। ticket খোলার সময় `x-tokens-request-id` response header দিন। সেটা পেতে ওই call-টা একবার [cURL](/docs/curl) আর `-i` দিয়ে চালিয়ে দেখুন।

---
Page: https://tokens.bd/bn/docs/langchain
