Skip to content

OpenAI Agents SDK

OpenAI Agents SDK (Python ও TypeScript) দিয়ে বানানো agent Tokens-এ চালান: Chat Completions model class, model ID-র slash-এর সমস্যা, tracing, tool আর streaming।

যেসব tool-এ কাজ করেOpenAI Agents SDK
Markdown-এ দেখুন
এই পাতায়

OpenAI Agents SDK হলো agent বানানোর জন্য OpenAI-র library। এখানে একটা Agent-এ instructions আর tool দেওয়া থাকে, আর সেটা চালায় একটা Runner। SDK model-এর সাথে কথা বলে OpenAI API দিয়ে, তাই https://tokens.bd/v1 ঠিকানায় সে Tokens-এও পৌঁছাতে পারে। শুধু দুটো default পথে বাধা হয়, দুটোই সহজে ঠিক করা যায়। এক, আলাদা করে না বললে SDK Responses API ডাকে। দুই, model ID-তে slash থাকলে সে সেটাকে provider/model ধরে নেয়। Tokens-এর প্রতিটা model ID-তেই slash আছে, তাই এই পেজে দুটো জিনিসই কীভাবে সাজাতে হয় দেখানো হয়েছে।

Documentation-এর সাথে মিলিয়ে দেখা

এই গাইড OpenAI Agents SDK-র documentation থেকে নেওয়া। October 2026-এ মিলিয়ে দেখা হয়েছে Python package openai-agents 0.23.1 (প্রকাশ 2 October 2026) আর TypeScript package @openai/agents 0.20.0-এর সাথে। code-টা documentation আর SDK-র নিজের উদাহরণের সাথে মিলিয়ে দেখা হয়েছে, Tokens-এর বিরুদ্ধে শুরু থেকে শেষ পর্যন্ত চালিয়ে দেখা হয়নি। SDK দ্রুত বদলায়। তাই আপনার version-এর সাথে কিছু না মিললে official docs দেখে নিন।

যা যা লাগবে#

  • API keys থেকে নেওয়া একটা Tokens key, যেটা TOKENS_API_KEY নামে export করা।
  • /models থেকে একটা model ID, যেমন deepseek/deepseek-v4.1-flash। Agent tool ডাকে, তাই এমন model নিন যেটা tool calling সাপোর্ট করে (Choosing a model)।
  • Python package-এর জন্য Python 3.10 বা তার পরের version। TypeScript package-এ নিজের client দিলে openai package-এর version 7.2 বা তার পরের হতে হবে।
bash
export TOKENS_API_KEY="tok_live_your_key"

কেন default বদলাতে হয়#

SDK-র defaultTokens-এ কী হয়সমাধান
Responses API ব্যবহার করেTokens /v1/responses পাস করে দেয়, কিন্তু সেটা চলে শুধু তখনই যখন model-এর পেছনের provider নিজে এটা সাপোর্ট করে (Responses)। Chat Completions সব model-এ চলে।OpenAIChatCompletionsModel নিন, অথবা set_default_openai_api("chat_completions") দিন।
prefix/name-কে provider prefix ধরে নেয়SDK-র documentation বলছে, অচেনা prefix হলে UserError ওঠে, আর openai/... হলে slash-এর পরের অংশটুকু রেখে বাকিটা ছেঁটে দেওয়া হয়। deepseek/deepseek-v4.1-flash-এর মতো Tokens ID এই নিয়মে আটকে যায়।model object দিন, custom ModelProvider ব্যবহার করুন, অথবা prefix mode বদলে দিন।
Trace OpenAI-তে upload করেTrace চলে OpenAI-র server-এ, আর তার জন্য OpenAI key লাগে। Tokens key দিলে upload-এ 401 হয়, যা আপনার log-এ দেখা যাবে।Tracing বন্ধ করুন।

SDK-র documentation এগুলো রেখেছে "non-OpenAI models" অংশে। যে provider-এ Responses নেই, সেখানে সে Chat Completions ব্যবহার করতে বলে। আর স্পষ্ট বলে, অচেনা prefix pass-through হয় না, UserError ওঠে।

Python: Chat Completions model object ব্যবহার করুন#

শুরুতে এই setup-টাই নিন। Tokens-এর দিকে তাক করা একটা AsyncOpenAI client বানাতে হবে, সেটাকে OpenAIChatCompletionsModel-এ মুড়ে agent-এর হাতে দিতে হবে। Agent model-এর নাম (string) না পেয়ে একটা model object পায়, তাই SDK model ID parse করে না। ফলে slash নিয়ে কোনো সমস্যাই হয় না।

bash
pip install --upgrade openai-agents
agent.py
import asyncio
import os

from openai import AsyncOpenAI
from agents import Agent, OpenAIChatCompletionsModel, Runner, set_tracing_disabled

set_tracing_disabled(True)  # traces would go to OpenAI; see the Tracing section

client = AsyncOpenAI(
    base_url="https://tokens.bd/v1",
    api_key=os.environ["TOKENS_API_KEY"],
)

agent = Agent(
    name="Reviewer",
    instructions="You are a concise senior engineer. Answer in at most three sentences.",
    model=OpenAIChatCompletionsModel(model="deepseek/deepseek-v4.1-flash", openai_client=client),
)


async def main() -> None:
    result = await Runner.run(agent, "When should I use a dataclass instead of a dict?")
    print(result.final_output)


asyncio.run(main())

base_url-এর শেষে /v1 রাখুন। model string-টা Tokens-এ যেমন লেখা তেমনই যায়, তাই সেটা /models-এর কোনো ID-র সাথে বা GET https://tokens.bd/v1/models-এর সাথে হুবহু মিলতে হবে।

Python: এক জায়গা থেকে সব agent-এর model ঠিক করুন#

অনেক agent থাকলে RunConfig-এর ভেতর দিয়ে একটা custom ModelProvider দিন। তাহলে পুরো run-এ একই model setup খাটে, আর Agent object-এ সাধারণ model নামই রাখা যায়। এটা SDK-র নিজের custom_example_provider.py উদাহরণ মেনে লেখা।

provider.py
import asyncio
import os

from openai import AsyncOpenAI
from agents import (
    Agent,
    Model,
    ModelProvider,
    OpenAIChatCompletionsModel,
    RunConfig,
    Runner,
    set_tracing_disabled,
)

set_tracing_disabled(True)

client = AsyncOpenAI(
    base_url="https://tokens.bd/v1",
    api_key=os.environ["TOKENS_API_KEY"],
)


class TokensModelProvider(ModelProvider):
    def get_model(self, model_name: str | None) -> Model:
        # The name arrives untouched, slash included.
        return OpenAIChatCompletionsModel(
            model=model_name or "deepseek/deepseek-v4.1-flash",
            openai_client=client,
        )


agent = Agent(
    name="Assistant",
    instructions="You are a helpful assistant.",
    model="deepseek/deepseek-v4.1-flash",
)


async def main() -> None:
    result = await Runner.run(
        agent,
        "Name two uses for asyncio.Semaphore.",
        run_config=RunConfig(model_provider=TokensModelProvider()),
    )
    print(result.final_output)


asyncio.run(main())

RunConfig শুধু ওই একটা Runner.run call-এর জন্য খাটে। এটা ছাড়া run করলে request চলে OpenAI-র নিজের endpoint-এ, আর OPENAI_API_KEY যা সেট করা আছে সেটাই ব্যবহার হয়।

বিকল্প: global client#

SDK-তে একটা global default-ও আছে। সব agent-ই Tokens ব্যবহার করবে, এমন হলে এটাই সবচেয়ে ছোট setup:

python
import os
from openai import AsyncOpenAI
from agents import set_default_openai_api, set_default_openai_client, set_tracing_disabled

set_default_openai_client(
    AsyncOpenAI(base_url="https://tokens.bd/v1", api_key=os.environ["TOKENS_API_KEY"]),
    use_for_tracing=False,
)
set_default_openai_api("chat_completions")
set_tracing_disabled(True)

এই setup-এও model="deepseek/deepseek-v4.1-flash"-এর মতো সাধারণ string চলে যায় SDK-র default MultiProvider-এর ভেতর দিয়ে, আর সে প্রথম slash-এ ভেঙে ফেলে। Slash-এর আগের অংশটা SDK-র চেনা কোনো provider নয়, তাই default আচরণ হলো UserError: Unknown prefix ছোঁড়া। আর prefix যদি openai হয়, SDK কোনো শব্দ না করে শুধু slash-এর পরের অংশটা পাঠায়। Global setup-এর সাথে model string ব্যবহার করতে চাইলে provider নিজে বানান আর তাকে বলে দিন পুরো ID রেখে দিতে:

python
import os
from agents import MultiProvider, RunConfig

provider = MultiProvider(
    openai_base_url="https://tokens.bd/v1",
    openai_api_key=os.environ["TOKENS_API_KEY"],
    openai_use_responses=False,         # Chat Completions
    openai_prefix_mode="model_id",      # keep a leading "openai/" as part of the id
    unknown_prefix_mode="model_id",     # keep any other "provider/" as part of the id
)

run_config = RunConfig(model_provider=provider)

openai_prefix_mode আর unknown_prefix_mode SDK-তে আছে openrouter/openai/gpt-4.1-mini-র মতো namespace-ওয়ালা ID কোনো OpenAI-compatible backend-এ পাঠানোর জন্য। তবে model object বা ওপরের ModelProvider-এর মতো সহজ পথে এই প্রশ্নটাই ওঠে না, তাই ওগুলোকেই বেছে নিন।

Note

use_for_tracing=False দিলে SDK এই client-এর key (মানে আপনার Tokens key) দিয়ে OpenAI-তে trace upload করা বন্ধ করে। এর default True। এই argument-টার কথা আছে SDK-র source docstring-এ, তার guide পেজগুলোতে নেই। তাই যে version install করছেন তার সাথে মিলিয়ে নিন।

Tracing: বন্ধ করে দিন#

SDK default-ভাবে trace OpenAI-র server-এ upload করে। OpenAI platform key না থাকলে agent ঠিকমতো চললেও log-এ 401 error আসতে থাকে। Documentation-এ tracing বন্ধ করার তিনটে উপায় আছে:

কতটুকু জায়গা জুড়েকীভাবে
পুরো processset_tracing_disabled(True), অথবা environment variable OPENAI_AGENTS_DISABLE_TRACING=1
একটা runRunConfig(tracing_disabled=True)

Tracing চালু রেখে শুধু upload-এর জন্য আলাদা একটা OpenAI key দিতে চাইলে set_tracing_export_api_key(...) আছে। সেই key আনতে হবে platform.openai.com থেকে। ওটা আপনার Tokens key নয়, আর তখন আপনার prompt trace data হয়ে OpenAI-তে চলে যাবে। Prompt গোপন হলে tracing বন্ধই রাখুন।

Tool#

Agent-কে দিন type hint আর docstring-ওয়ালা Python function। এগুলো থেকেই SDK tool-এর schema বানিয়ে নেয়।

tools.py
import asyncio
import os

from openai import AsyncOpenAI
from agents import (
    Agent,
    OpenAIChatCompletionsModel,
    Runner,
    function_tool,
    set_tracing_disabled,
)

set_tracing_disabled(True)

client = AsyncOpenAI(
    base_url="https://tokens.bd/v1",
    api_key=os.environ["TOKENS_API_KEY"],
)


@function_tool
def get_weather(city: str) -> str:
    """Current weather for a city.

    Args:
        city: The city to look up.
    """
    return f"{city}: light rain, 29C"  # replace with a real lookup


agent = Agent(
    name="Weather helper",
    instructions="Use the tool when the user asks about the weather.",
    model=OpenAIChatCompletionsModel(model="deepseek/deepseek-v4.1-flash", openai_client=client),
    tools=[get_weather],
)


async def main() -> None:
    result = await Runner.run(agent, "Do I need an umbrella in Dhaka?")
    print(result.final_output)


asyncio.run(main())

প্রকাশিত package-এ decorator-টার নাম function_tool। SDK-র নতুন documentation একই decorator import করে from agents.decorators import tool দিয়ে, যেটা ওর alias। যে version মিলিয়ে দেখা হয়েছে তাতে দুটোই চলে।

প্রতিটা tool call মানে Tokens-এ আরেকটা request। তাই কয়েক রাউন্ড tool চললে কয়েকটা request খরচ হয়, আর সেগুলো আপনার rate limits-এর হিসাবে পড়ে। Tool calling-এর জন্য এমন model লাগে যেটা তা সাপোর্ট করে (Tool calling)।

SDK-র documentation-এ কিছু tool আছে যেগুলো শুধু Responses API-তে চলে (যেমন ToolSearchTool), আর বলা আছে Chat Completions backend সেগুলো ফিরিয়ে দেয়। Web search বা file search-এর মতো hosted tool চলে OpenAI-র নিজের দিকে, তাই Tokens দিয়ে সেগুলো পাওয়া যায় না।

Output stream করুন#

Runner.run_streamed এমন একটা result দেয় যার ওপর loop চালিয়ে event পাওয়া যায়। SDK-র documentation-এ দেওয়া text streaming-এর loop এটাই:

stream.py
import asyncio
import os

from openai import AsyncOpenAI
from openai.types.responses import ResponseTextDeltaEvent
from agents import Agent, OpenAIChatCompletionsModel, Runner, set_tracing_disabled

set_tracing_disabled(True)

client = AsyncOpenAI(
    base_url="https://tokens.bd/v1",
    api_key=os.environ["TOKENS_API_KEY"],
)

agent = Agent(
    name="Writer",
    instructions="You write short, plain answers.",
    model=OpenAIChatCompletionsModel(model="deepseek/deepseek-v4.1-flash", openai_client=client),
)


async def main() -> None:
    result = Runner.run_streamed(agent, input="Write a haiku about merge conflicts.")
    async for event in result.stream_events():
        if event.type == "raw_response_event" and isinstance(event.data, ResponseTextDeltaEvent):
            print(event.data.delta, end="", flush=True)
    print()


asyncio.run(main())

Stream শেষ না হওয়া পর্যন্ত পড়তে থাকুন। Iterator শেষ না হলে run-ও শেষ হয় না। SDK-র streaming পেজে এই loop দেখানো হয়েছে default setup-এর জন্য। OpenAIChatCompletionsModel-এ একই রকম চলবে কিনা সেটা সেখানে বলা নেই, তাই আপনার model দিয়ে একবার test করে নিন। আরও দেখুন Streaming।

Tokens-এর stream-এ token-এর হিসাব আসে শুধু তখনই, যখন request-এ সেটা চাওয়া হয়। Chat Completions-এ এর জন্য SDK-তে ModelSettings(include_usage=True) field আছে (documentation অনুযায়ী field-টা শুধু Chat Completions-এ পাওয়া যায়)। agents থেকে ModelSettings import করুন আর দিন এভাবে: Agent(..., model_settings=ModelSettings(include_usage=True))।

কোনো provider streaming-এর সময় ভাঙা tool-call-এর টুকরো পাঠালে SDK-র একটা option আছে, MultiProvider-এ openai_buffer_streamed_tool_calls=True, যেটা সেগুলো জমিয়ে রাখে।

TypeScript#

TypeScript package-এর নাম @openai/agents। এর peer dependency হিসেবে zod 4 লাগে, আর নিজের client দিলে openai package-ও (version 7.2 বা তার পরের)।

bash
npm install @openai/agents zod openai
agent.ts
import OpenAI from "openai";
import {
  Agent,
  OpenAIChatCompletionsModel,
  run,
  setTracingDisabled,
  tool,
} from "@openai/agents";
import { z } from "zod";

setTracingDisabled(true);

const client = new OpenAI({
  apiKey: process.env.TOKENS_API_KEY,
  baseURL: "https://tokens.bd/v1",
});

const getWeather = tool({
  name: "get_weather",
  description: "Current weather for a city",
  parameters: z.object({ city: z.string() }),
  async execute({ city }) {
    return `${city}: light rain, 29C`; // replace with a real lookup
  },
});

const agent = new Agent({
  name: "Weather helper",
  instructions: "Use the tool when the user asks about the weather.",
  model: new OpenAIChatCompletionsModel(client, "deepseek/deepseek-v4.1-flash"),
  tools: [getWeather],
});

const result = await run(agent, "Do I need an umbrella in Dhaka?");
console.log(result.finalOutput);

OpenAIChatCompletionsModel-এর একটা instance দিলে ওই agent Chat Completions-এই থাকে, আর model ID parse হয় না। SDK-র নিজের উদাহরণে আরও দুটো পথ আছে: setOpenAIAPI("chat_completions")-এর সাথে setDefaultOpenAIClient(client) দিয়ে global পথ, আর OpenAIProvider({ openAIClient: client }) দিয়ে new Runner({ modelProvider }) পথ। এই পথগুলো slash-ওয়ালা model নাম কীভাবে সামলায়, TypeScript documentation-এ তা বলা নেই। তাই ওপরের model object-টাই ব্যবহার করুন।

Node-এ text stream করতে:

ts
const stream = await run(agent, "Write a haiku about merge conflicts.", { stream: true });
stream.toTextStream({ compatibleWithNodeStreams: true }).pipe(process.stdout);
await stream.completed;

Tracing বন্ধ করা যায় ওপরের মতো setTracingDisabled(true) দিয়ে, অথবা OPENAI_AGENTS_DISABLE_TRACING=1 দিয়ে। এই code চালান server-এ বা CLI-তে, browser bundle-এ নয়। Tokens CORS header পাঠায় না, আর যে-ই dev tools খুলবে সে-ই আপনার key দেখে ফেলবে।

ঠিকমতো চলছে কিনা দেখুন#

python agent.py চালান। Terminal-এ ছোট একটা উত্তর ছাপা হলে বুঝবেন key, base URL আর model ID ঠিক আছে। এরপর Dashboard-এ Usage analytics খুলে request-টা খুঁজুন। Call ফেল করলে আগে cURL দিয়ে endpoint test করুন। সেখানে 200 আসছে অথচ agent-এ ফেল করছে, তাহলে সমস্যা SDK setup-এ, key-তে নয়।

Model বাছাই#

Agent ঘুরতে থাকে: tool ডাকে, result পড়ে, আবার ডাকে। তাই model-কে tool call ভালো সামলাতে হবে আর লম্বা context ধরে রাখতে হবে। কিছু model সাধারণ chat-এ ঠিক উত্তর দেয়, কিন্তু tool-এ ফেল করে। কোন model agent-এর কাজে মানায়, তা Choosing a model-এ আছে, আর /models-এ প্রতিটা model-এর পেজে দেখা যায় তার context window কত আর tool সাপোর্ট করে কিনা। প্রতিটা উত্তরের দৈর্ঘ্যে সীমা দিতে চাইলে ModelSettings-এর মধ্য দিয়ে max_tokens সেট করুন। কয়েক রাউন্ড tool চললে অনেক token যেতে পারে, তাই agent-কে যে key দেবেন তাতে spend cap বসিয়ে দিন (API keys)।

সীমাবদ্ধতা আর যা চলে না#

  • শুধু Responses-এ চলে এমন feature। Hosted tool (web search, file search, code interpreter), previous_response_id আর Responses-only বাকি field Chat Completions পথে পাওয়া যায় না। Strict validation চালু না করলে SDK ওই field-গুলো চুপচাপ বাদ দিয়ে দেয় (OpenAIProvider-এ strict_feature_validation=True, MultiProvider-এ openai_strict_feature_validation=True)।
  • Structured output। SDK json_schema response format পাঠায়। Tokens ID-র পেছনের model সেটা সাপোর্ট না করলে upstream request ফিরিয়ে দেয় 400 (invalid_request) দিয়ে। Structured output সাপোর্ট করে এমন model নিন (Structured output)।
  • Audio আর Realtime। Audio output চাইলে Chat Completions adapter AgentsException("Audio is not currently supported") ছোঁড়ে। Realtime আর voice agent-এর জন্য OpenAI-র নিজের endpoint লাগে, সেগুলো Tokens দিয়ে চলে না।
  • Tracing। Trace যায় OpenAI-তে, Tokens-এ নয়, আর Tokens key দিয়ে সেগুলো upload করা যায় না।
  • finish_reason="length"-এ খালি উত্তর। Model যদি কিছু output না দিয়েই length limit-এ থেমে যায়, adapter ModelBehaviorError ছোঁড়ে। এটা token বা reasoning budget-এর সমস্যা। max_tokens বাড়ান, নয়তো এমন model নিন যার লুকানো reasoning কম।

সমস্যা হলে#

UserError: Unknown prefix: <first part of your model id>। Model-টা agent-কে string হিসেবে দেওয়া হয়েছে, আর SDK-র default provider slash-এর আগের অংশটাকে provider prefix ধরে নিয়েছে। OpenAIChatCompletionsModel object দিন, ওপরের ModelProvider ব্যবহার করুন, নয়তো MultiProvider-এ unknown_prefix_mode="model_id" দিন।

404 model_not_found। হয় ID-তে বানান ভুল, নয়তো SDK শুরুর openai/ কেটে দিয়েছে। Tokens usage log-এর ID-র সাথে আপনি যেটা পাঠাতে চেয়েছিলেন সেটা মিলিয়ে দেখুন, আর GET https://tokens.bd/v1/models-এর সাথেও যাচাই করুন।

/v1/responses থেকে 404 বা 400। SDK এখনও Responses API-তেই আছে। OpenAIChatCompletionsModel ব্যবহার করুন, অথবা set_default_openai_api("chat_completions") দিন।

api.openai.com থেকে 401 error, বা log-এ "incorrect API key", অথচ agent উত্তর দিচ্ছে। এগুলো trace upload-এর error। Tracing বন্ধ করুন।

Tokens থেকে 401 invalid_api_key। TOKENS_API_KEY-এর key ভুল, নয়তো revoke করা। /dashboard/keys-এ গিয়ে নতুন একটা বানান।

402 insufficient_credits, 403 model_not_allowed_on_key, 429 window_exhausted। এগুলো অ্যাকাউন্টের সীমার ব্যাপার, SDK-র সমস্যা নয়। দেখুন Errors আর Troubleshooting। Agent একসাথে অনেক request ছুড়লে 429 concurrency_limit লাগতে পারে। তখন parallelism কমান (Rate limits)।

Error আসে SDK exception হয়ে। SDK OpenAI client-কে মুড়ে রাখে, তাই Tokens-এর error আসে openai exception হিসেবে। e.code আর e.response.headers.get("x-tokens-request-id") পড়ুন, আর support-এর সাথে যোগাযোগের সময় request id-টা দিয়ে দিন।

এই পাতাটা কি কাজে লেগেছে?

এখনো আটকে আছেন? Support ticket খুলুন

আপনার agent set up করতে সাহায্য লাগবে?

Connection tester দিয়ে সংযোগ পরীক্ষা করে নিন, অথবা একটা API key তৈরি করুন।