Skip to content

Vision: model-কে image পাঠানো

Chat Completions-এ (image_url part) বা Messages-এ (image block) model-কে image পাঠানোর নিয়ম: URL আর base64 দুটো form, size limit, gateway কী translate করে, image input-এর billing, আর model image নেয় কি না কীভাবে যাচাই করবেন।

Markdown-এ দেখুন
এই পাতায়

Vision মানে model-কে একটা image পাঠিয়ে সেটা নিয়ে প্রশ্ন করা: যেমন error-এর screenshot, কোনো diagram, বা whiteboard-এর ছবি। Tokens-এ image আলাদা করে যায় না, সাধারণ chat request-এর ভেতরেই যায়। POST https://tokens.bd/v1/chat/completions-এ যায় image_url content part হিসেবে, আর POST https://tokens.bd/v1/messages-এ image content block হিসেবে। gateway image-টা provider পর্যন্ত পৌঁছে দেয় আর provider যা report করে, সেটাই bill করে। model image পড়তে পারবে কি না, সেটা model-এর ওপর নির্ভর করে।

Tokens-এ আলাদা কোনো image endpoint নেই। image generation, file upload আর Anthropic Files API এখানে চলে না (Models ও usage দেখুন)। এই পেজ শুধু image input নিয়ে।

Model image নেয় কি না যাচাই করুন#

সব model image পড়তে পারে না। /models পেজের model catalog-এ প্রতিটা model-এর context window, দাম আর বর্ণনা আছে, কিন্তু "image support করে" বলে আলাদা কোনো field নেই। জানার উপায়:

  • /models পেজে model-এর বর্ণনা পড়ুন, আর model-টা যারা বানিয়েছে তাদের নিজেদের documentation দেখুন।
  • Model বেছে নেওয়া পেজের vision অংশে কয়েকটা model-এর তালিকা আছে, কোনটা কী নেয় সেই হিসেবে।
  • একটা ছোট test image পাঠিয়ে (নিচের উদাহরণগুলো) জিজ্ঞেস করুন "What is in this image?"। যে model image পড়ে, সে ছবি নিয়েই উত্তর দেবে।

text-only model সব সময় জোরে আওয়াজ করে fail করে না। সেটা provider-এর সিদ্ধান্ত: হয় 400 পাঠাবে (আপনার কাছে আসবে invalid_request হয়ে, errors দেখুন), নয়তো image বাদ দিয়ে শুধু text দেখে উত্তর দেবে। উত্তরে ছবির কোনো ছাপ না থাকলে ধরে নিন, এই model image নেয় না।

Chat Completions: image_url part#

message-এর content-এ string-এর বদলে একটা array দিন। array-র প্রতিটা element হয় text part, নয়তো image_url part। url হবে একটা public https URL, অথবা base64 data URL (data:<media type>;base64,<data>)।

json
{
  "role": "user",
  "content": [
    { "type": "text", "text": "What does this error screenshot say?" },
    {
      "type": "image_url",
      "image_url": { "url": "data:image/png;base64,<BASE64_DATA>", "detail": "auto" }
    }
  ]
}

detail হলো OpenAI-এর optional hint (low, high বা auto; না দিলে auto)। অন্য provider এটা না-ও মানতে পারে। Anthropic-style provider-এর জন্য gateway যখন request translate করে, তখন detail বাদ দিয়ে দেয় (নিচে দেখুন)।

curl https://tokens.bd/v1/chat/completions \
  -H "Authorization: Bearer $TOKENS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek/deepseek-v4.1-flash",
    "max_tokens": 300,
    "messages": [
      {
        "role": "user",
        "content": [
          {"type": "image_url", "image_url": {"url": "https://YOUR-HOST/path/to/image.png"}},
          {"type": "text", "text": "Describe this image in two sentences."}
        ]
      }
    ]
  }'

https://YOUR-HOST/path/to/image.png-এর জায়গায় আপনার নিজের image-এর link বসান। data URL-এর media type ফাইলের সাথে মিলতে হবে (image/png, image/jpeg, image/webp, image/gif)।

URL দেওয়া image কে আনে

https URL দিলে Tokens image download করে না। URL-টা যেমন আছে তেমন forward করে দেয়, আর image আনে provider। তাই link-টা public হতে হবে আর provider সেখানে পৌঁছাতে পারতে হবে। কোনো কোনো provider শুধু base64 data URL নেয়। URL দিলে fail করছে কিন্তু একই image base64-এ চলছে, তাহলে base64-ই ব্যবহার করুন।

Messages: image content block#

/v1/messages-এ image হলো source-ওয়ালা একটা content block। Tokens-এ দুই ধরনের source চলে:

json
{
  "role": "user",
  "content": [
    {
      "type": "image",
      "source": { "type": "base64", "media_type": "image/png", "data": "<BASE64_DATA>" }
    },
    { "type": "text", "text": "What does this error screenshot say?" }
  ]
}
json
{
  "type": "image",
  "source": { "type": "url", "url": "https://YOUR-HOST/path/to/image.png" }
}

data হবে খাঁটি base64 string, শুরুতে data: prefix থাকবে না। Anthropic-এর তৃতীয় source {"type": "file", "file_id": "..."} চলতে হলে তাদের Files API লাগে, যেটা Tokens-এ নেই। তাই image-টাই সরাসরি পাঠান।

curl https://tokens.bd/v1/messages \
  -H "x-api-key: $TOKENS_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "deepseek/deepseek-v4.1-flash",
    "max_tokens": 300,
    "messages": [
      {
        "role": "user",
        "content": [
          {"type": "image", "source": {"type": "url", "url": "https://YOUR-HOST/path/to/image.png"}},
          {"type": "text", "text": "Describe this image in two sentences."}
        ]
      }
    ]
  }'

Anthropic-এর পরামর্শ: যে text দিয়ে image নিয়ে প্রশ্ন করছেন, image রাখুন তার আগে। একাধিক image থাকলে text-এ label দিন ("Image 1:", "Image 2:"), তাহলে পরে নাম ধরে বলা যাবে। conversation-এর আগের image model-এর চোখের সামনেই থাকে, কিন্তু প্রতিটা request-এ সেগুলো আবার পাঠাতে হবে, কারণ API কিছু মনে রাখে না।

Command line থেকে base64#

base64 image এত বড় যে curl -d '...' argument-এ হাতে লেখা যায় না। request-টা একটা file-এ লিখে সেই file পাঠান। macOS আর Linux-এ, jq install থাকলে:

bash
base64 screenshot.png | tr -d '\n' > screenshot.b64

jq -n --rawfile img screenshot.b64 '{
  model: "deepseek/deepseek-v4.1-flash",
  max_tokens: 300,
  messages: [{
    role: "user",
    content: [
      {type: "image_url", image_url: {url: ("data:image/png;base64," + $img)}},
      {type: "text", text: "Describe this image in two sentences."}
    ]
  }]
}' > request.json

curl https://tokens.bd/v1/chat/completions \
  -H "Authorization: Bearer $TOKENS_API_KEY" \
  -H "Content-Type: application/json" \
  -d @request.json

Image নিয়ে gateway কী করে#

native request-এ (provider আপনার request-এর format-ই বোঝে) gateway body forward করে, শুধু model field বদলায় (আর stream করা Chat Completions-এ usage report করার একটা option যোগ করে)। image decode, resize বা যাচাই কিছুই করে না।

কিছু model এমন provider-এর কাছেই পাওয়া যায়, যে অন্য format বোঝে। তখন gateway request translate করে, আর image-এর ক্ষেত্রে হয় এরকম:

আপনার requestProvider যে format বোঝেImage-এর কী হয়
Messages (image block)OpenAI formatBase64 হয়ে যায় data URL, আর URL থাকে URL-ই, user message-এর image_url part হিসেবে। assistant turn-এর image বাদ পড়ে। tool_result-এর ভেতরের image আর image হিসেবে যায় না (সতর্কতাটা দেখুন)।
Chat Completions (image_url part)Anthropic formatdata URL হয়ে যায় base64 image block, অন্য যেকোনো URL হয় URL image block। detail বাদ পড়ে। শুধু user message-এর image যায়।

Tool result-এর ভেতরের image

যে Messages request gateway OpenAI format-এ translate করে, সেখানে tool_result-এর content-এ image block থাকলে পুরোটা text হয়ে যায়, আর image block-টা JSON হিসেবে সেই text-এর ভেতরে লেখা হয়। model কোনো ছবি দেখে না, উল্টে base64 data input token হিসেবে গোনা হয়। আপনার agent যদি tool থেকে screenshot ফেরত দেয়, তাহলে Anthropic format-এ চলে এমন model নিন, অথবা tool-কে দিয়ে image-টার বর্ণনা text-এ ফেরত দেওয়ান।

translation-এর একই নিয়ম আর যেসব field সাথে যায়, সেগুলো Messages পেজে লেখা আছে।

Size limit#

দুটো limit আছে, আর যেটা ছোট সেটাই খাটে।

Tokens: পুরো request body সর্বোচ্চ 10 MB হতে পারে, নইলে gateway 413 request_entity_too_large দেয়। base64 করলে data ফাইলের চেয়ে প্রায় এক-তৃতীয়াংশ বড় হয়ে যায়। তাই এক request-এর সব image মিলিয়ে বড়জোর প্রায় 7 MB-র image file যেতে পারে, আর text এবং আগের turn গুনলে আরও কম। প্রতিটা request পুরো conversation আবার পাঠায়, আগের image-সহ।

Provider: image-এর format, dimension, সংখ্যা আর প্রতিটা image-এর size নিয়ে প্রত্যেক provider-এর নিজস্ব limit আছে। October 2026-এ যেমন দেখা গেছে:

  • Anthropic: JPEG, PNG, GIF (শুধু প্রথম frame) আর WebP; প্রতি image সর্বোচ্চ 8000 x 8000 pixel; প্রতি image 10 MB (base64); 200K-token context window-ওয়ালা model-এ এক request-এ 100টা পর্যন্ত image, বাকি model-এ 600টা। এক request-এ 20টার বেশি image হলে প্রতি image-এর pixel-এর কড়াকড়ি বাড়ে, আর Anthropic প্রতিটা পাশ 2000 px-এর মধ্যে রাখতে বলে। সূত্র: Anthropic-এর vision documentation।
  • OpenAI: PNG, JPEG, WebP আর animation ছাড়া GIF; এক request-এ 1,500টা পর্যন্ত image। সূত্র: OpenAI-এর images ও vision guide। OpenAI-এর 512 MB payload limit Tokens-এর 10 MB-র চেয়ে বড়, তাই আগে Tokens-এর limit-ই লাগে।
  • অন্য maker-রা নিজেদের limit নিজেরা প্রকাশ করে। যে model ব্যবহার করছেন, তার maker-এর documentation দেখে নিন।

বড় ছবি পাঠানোর আগে resize করে নিন। ফোনের ছবি প্রায়ই 4000 pixel চওড়া হয়, আর model সেটা এমনিই ছোট করে নেয়। ফলে upload-এর size আর latency-র দাম দিচ্ছেন, কিন্তু detail বাড়ছে না। screenshot-এর লেখা যেন পড়া যায়, সেদিকে খেয়াল রাখুন: JPEG বেশি জোরে compress করলে ছোট লেখা আর পড়া যায় না।

Image input-এর billing#

provider image-কে input token-এ রূপান্তর করে, আর মোট সংখ্যাটা usage-এ report করে। Tokens সেই input count-কে model-এর input price ধরে bill করে, অন্য যেকোনো input-এর মতোই। মোটামুটি, provider-রা image গোনে patch ধরে: Anthropic-এর documentation অনুযায়ী প্রতি image-এ ceil(width / 28) x ceil(height / 28) token, তবে আগে image ছোট করে একটা সীমায় আনা হয় (standard tier-এ প্রায় 1,568 token, high-resolution tier-এ 4,784 পর্যন্ত)। OpenAI-র documentation-এ patch-based আর tile-based দুই রকম হিসাব আছে, যা model আর detail-এর ওপর নির্ভর করে। অন্যদের হিসাব আলাদা। তাই আপনার model-এর আসল খরচ জানতে একটা test request পাঠিয়ে usage দেখে নিন।

Admission অন্য একটা সংখ্যা ধরে চলে। request forward করার আগে gateway আপনার ব্যালান্স থেকে তার worst-case খরচ reserve করে, আর input অংশের হিসাব ধরে request body-র প্রতি চার character-এ এক token। বড় base64 image মানে অনেক character, তাই কয়েক MB-র image-ওয়ালা request-এর reservation provider-এর শেষ পর্যন্ত যা charge করবে তার চেয়ে অনেক বেশি হতে পারে। আপনার কাছ থেকে আসল usage-ই কাটা হয়, reservation নয়। তবু ব্যালান্স কম থাকলে, বা key-র spend cap-এর কাছাকাছি থাকলে, যে request-এর খরচ আসলে খুবই কম হতো সেটাও insufficient_credits বা monthly_spend_cap_exceeded দিয়ে ফিরিয়ে দেওয়া হতে পারে। image resize করলে খরচও কমে, refusal-ও যায়। reservation নিয়ে বিস্তারিত Chat Completions পেজে আছে।

সমস্যা হলে#

লক্ষণসম্ভাব্য কারণসমাধান
400 invalid_request, message-এ image বা content আছেModel image input নেয় না, অথবা media type-টা সে support করে নাimage নেয় এমন model চেষ্টা করুন; data URL-এর media type ফাইলের সাথে মিলছে কি না দেখুন।
উত্তরে ছবির কোনো উল্লেখ নেইtext-only model-এ provider image বাদ দিয়ে দিয়েছেimage পড়ে এমন model-এ যান।
413 request_entity_too_largeBody 10 MB-র বেশি, সাধারণত base64 image বা image-ভরা লম্বা historyResize বা compress করুন, কম image পাঠান, অথবা পুরোনো turn বাদ দিন।
ব্যালান্স অল্প, তবু 402 insufficient_creditsinput-এর হিসাবে base64-এর character-গুলোও ধরা হয়image resize করুন, অথবা billing থেকে টাকা যোগ করুন।
URL image fail করে, base64 চলেProvider URL আনতে পারেনি, অথবা শুধু base64 নেয়base64 ব্যবহার করুন, নয়তো URL public করুন।
tool screenshot-ওয়ালা Messages request, model কিছুই দেখে নাtranslate হওয়া model-এ tool_result-এর image text হয়ে যায়উপরের সতর্কতাটা দেখুন।

error-এ কী ভুল হয়েছে স্পষ্ট না থাকলে upstream-এর message বদলে একটা সাধারণ message দেওয়া হয়। তখন x-tokens-request-id নিয়ে Support-এ জানান, আর code-গুলোর জন্য errors দেখুন।

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

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

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

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