DEV Community

Rakib Ahasan
Rakib Ahasan

Posted on

AI Agent-এর জন্য API: শূন্য থেকে শুরু, .NET ডেভেলপারের শেখার নোট

এই লেখা কেন

আমি .NET ব্যাকএন্ড ডেভেলপার। এতদিন API বানিয়েছি ফ্রন্টএন্ড বা মোবাইল টিমের জন্য। কিন্তু ইদানীং বারবার শুনছি, "AI Agent আপনার API ব্যবহার করবে।" আমি জানতে চাইলাম, এর মানে কী, আর আমার API-তে কী বদলাতে হবে।

এই লেখা সেই শেখার নোট। কোনো বিশেষজ্ঞের লেখা না, একজন শিক্ষার্থীর গুছিয়ে লেখা সারাংশ, যাতে আপনি একবার পড়েই পুরো বিষয়টা বুঝে ফেলেন।


এক নজরে (TL;DR)

AI Agent মানুষের মতো API ব্যবহার করে না। সে ডকুমেন্টেশন পড়ে না, আন্দাজ করে না, error দেখে নিজে debug করে না, আর খুব দ্রুত retry করে। তাই ৫টা কাজ করতে হয়:

# কাজ সহজ ভাষায়
১ সম্পূর্ণ schema ও description Agent-কে স্পষ্ট করে বলো কী পাঠাতে হবে
২ সব জায়গায় একই নিয়ম একই ধরনের জিনিস একইভাবে লেখো
৩ Structured error ভুল হলে বলে দাও কী ঠিক করতে হবে
৪ Idempotency দুবার call এলেও যেন দুবার কাজ না হয়
৫ সুচিন্তিত operation কম কিন্তু কাজের operation দাও

আগে কিছু শব্দ পরিষ্কার করি

  • AI Agent: এমন একটা প্রোগ্রাম যেখানে LLM নিজে সিদ্ধান্ত নিয়ে বিভিন্ন tool ও API call করে কাজ শেষ করে। যেমন "এই customer-এর জন্য অর্ডার দাও" বললে সে নিজেই ঠিক করে কোন API কোন ক্রমে call করবে।
  • OpenAPI spec: আপনার API-র machine-readable বর্ণনা (Swagger যা দেখায়, তার আসল উৎস)। কোন endpoint আছে, কী পাঠাতে হয়, কী ফেরত আসে।
  • Idempotency: একই request একাধিকবার পাঠালেও ফলাফল একবার পাঠানোর মতোই হওয়া।
  • MCP (Model Context Protocol): AI Agent-কে বাইরের tool ও data-র সাথে যুক্ত করার একটা open protocol। এক ধরনের "AI-র জন্য USB পোর্ট"।

মানুষ ডেভেলপার বনাম AI Agent

বিষয় মানুষ ডেভেলপার AI Agent
ডকুমেন্টেশন পড়ে, বুঝে নেয় মূলত OpenAPI spec ও description-এর উপর নির্ভর করে
অস্পষ্ট ফিল্ড অনুমান করে, জিজ্ঞেস করে ভুল অনুমান করতে পারে
Error পেলে message পড়ে debug করে message-এ নির্দেশনা না থাকলে একই ভুল বারবার করতে পারে
গতি ধীর খুব দ্রুত, ভুলও দ্রুত বাড়ে

এই পার্থক্য থেকেই নিচের ৫টা নিয়ম আসে।


একটা কাল্পনিক উদাহরণ

বোঝার সুবিধার জন্য ধরুন একটা Order API আছে, আর Agent-কে বলা হলো "২টা পণ্যের অর্ডার দাও।" (এটা কল্পনা, বাস্তব ঘটনা না।)

  • Spec-এ quantity-র type লেখা নেই, তাই Agent "2" (string) পাঠাল।
  • Server উত্তর দিল {"error": "Invalid input"}। কোন ফিল্ড ভুল সেটা নেই।
  • Agent একই request আবার পাঠাল। একই উত্তর।

মানুষ হলে ডকুমেন্টেশন খুলত। Agent-এর কাছে শুধু spec আর response। দুটোই অস্পষ্ট হলে সে আটকে যায়। এই ধরনের পরিস্থিতি এড়াতেই নিচের নিয়মগুলো।


১. সম্পূর্ণ Schema ও অর্থবহ Description

নিয়ম: প্রতিটা ফিল্ডে type, format, constraint ও description দিন।

.NET-এ request model-এ attribute দিলে OpenAPI spec-এ সেগুলো আসে:

public record PlaceOrderRequest(
    [property: Description("যে customer অর্ডার করছেন তার ID")]
    Guid CustomerId,

    [property: Description("পণ্যের ID")]
    Guid ProductId,

    [property: Range(1, 1000)]
    [property: Description("পণ্যের সংখ্যা (পূর্ণসংখ্যা, কমপক্ষে ১)")]
    int Quantity);
Enter fullscreen mode Exit fullscreen mode

Endpoint-এর description-ও ভাবুন। "Gets the data" এর চেয়ে "Returns a paginated list of invoices filtered by status and date range" Agent-কে অনেক ভালো সংকেত দেয়।

২. সব জায়গায় একই নিয়ম (Consistency)

Agent একটা endpoint থেকে pattern শিখে বাকিগুলোতে খাটায়। একটায় status pending, আরেকটায় IN_PROGRESS, তৃতীয়টায় done থাকলে সে বিভ্রান্ত হয়।

একটা convention ঠিক করে সব জায়গায় মানুন:

  • নামকরণ (camelCase বা snake_case, দুটোই না)
  • ID-র format (যেমন সবখানে uuid)
  • Pagination-এর ধরন
  • Error-এর কাঠামো
  • Status value-র লিখনরীতি

৩. Structured Error

নিয়ম: Error-কে Agent-এর জন্য নির্দেশনা বানান: কোন ফিল্ড ভুল, কী পেয়েছি, কী কী মান বৈধ।

ASP.NET Core-এ RFC 9457 (Problem Details) built-in আছে। সাথে নিজের ফিল্ড যোগ করা যায়:

return Results.Problem(
    title: "Invalid field value",
    detail: "Field 'status' received invalid value 'processing'.",
    statusCode: StatusCodes.Status400BadRequest,
    extensions: new Dictionary<string, object?>
    {
        ["field"] = "status",
        ["receivedValue"] = "processing",
        ["allowedValues"] = new[] { "pending", "shipped", "delivered", "cancelled" }
    });
Enter fullscreen mode Exit fullscreen mode

ফলাফল JSON:

{
  "title": "Invalid field value",
  "status": 400,
  "detail": "Field 'status' received invalid value 'processing'.",
  "field": "status",
  "receivedValue": "processing",
  "allowedValues": ["pending", "shipped", "delivered", "cancelled"]
}
Enter fullscreen mode Exit fullscreen mode

{"error": "Invalid input"}-এর সাথে তুলনা করুন। এটা পেলে Agent পরের চেষ্টায় ঠিক মান পাঠাতে পারে।

৪. Idempotency

সমস্যা: Network timeout হলে Agent (বা যেকোনো client) retry করে। POST /orders দুবার গেলে দুটো অর্ডার তৈরি হতে পারে।

সমাধান: client একটা Idempotency-Key header পাঠায়। Server সেই key মনে রাখে। একই key আবার এলে নতুন অর্ডার তৈরি না করে আগের ফলাফল ফেরত দেয়।

শেখার জন্য একটা সরল স্কেচ (in-memory, production-এ Redis বা database লাগবে):

var seenKeys = new ConcurrentDictionary<string, bool>();

app.MapPost("/orders", (HttpRequest http, PlaceOrderRequest body) =>
{
    var key = http.Headers["Idempotency-Key"].ToString();

    // TryAdd atomic: একই key দুটো parallel request-এ এলে একটাই সফল হবে
    if (!string.IsNullOrEmpty(key) && !seenKeys.TryAdd(key, true))
        return Results.Conflict("এই key দিয়ে request আগেই এসেছে।");

    // ... অর্ডার তৈরি করুন ...
    return Results.Ok();
});
Enter fullscreen mode Exit fullscreen mode

গুরুত্বপূর্ণ বিষয় দুটো:

  1. Atomic check: "আগে দেখি আছে কিনা, তারপর সেট করি", দুই ধাপে করলে দুটো parallel request-ই পার পেয়ে যেতে পারে। Redis-এ SET NX বা database-এ unique constraint এই কাজ করে।
  2. আসল সিস্টেমে আগের সফল response সংরক্ষণ করে ফেরত দেওয়া উচিত, শুধু Conflict না। এই স্কেচ কেবল ধারণা বোঝানোর জন্য।

৫. সুচিন্তিত Operation, শুধু CRUD না

প্রতিটা endpoint Agent-কে tool হিসেবে দিলে তার সামনে অনেক বিকল্প থাকে, ভুল বাছাইয়ের সম্ভাবনাও বাড়ে। কিছু ভালোভাবে বর্ণনা করা operation বেশি কাজের।

উদাহরণ: অর্ডার দিতে যদি customer খোঁজা → stock দেখা → অর্ডার তৈরি, তিনটা call লাগে, তাহলে একটা PlaceOrder operation বানানো যায়। Agent-কে ধাপগুলো সাজাতে হয় না, মাঝপথে ভুলের জায়গাও কমে।


MCP: Agent-এর জন্য আরেক ধাপ

MCP দিয়ে আপনার operation-গুলো এমনভাবে expose করা যায় যে MCP-সমর্থিত Agent সেগুলো সহজে খুঁজে পায় ও ব্যবহার করে। .NET-এর জন্য official C# SDK আছে। একটা tool দেখতে মোটামুটি এরকম:

[McpServerToolType]
public class OrderTools
{
    [McpServerTool, Description("নির্দিষ্ট customer-এর জন্য নতুন অর্ডার তৈরি করে।")]
    public async Task<string> PlaceOrder(
        [Description("Customer-এর ID")] Guid customerId,
        [Description("পণ্যের ID")] Guid productId,
        [Description("সংখ্যা, কমপক্ষে ১")] int quantity)
    {
        // এখানে আপনার existing application logic কল করুন
        return "created";
    }
}
Enter fullscreen mode Exit fullscreen mode

SDK দ্রুত বদলায়, তাই setup-এর সঠিক কোড official repository থেকে দেখে নিন।

এখানেও ৫ নম্বর নিয়ম খাটে: সব endpoint MCP tool বানাবেন না। শুধু যেগুলো Agent-এর সত্যিই লাগবে।


চেকলিস্ট

  • [ ] OpenAPI spec সম্পূর্ণ: প্রতিটা ফিল্ডে type, format, constraint
  • [ ] Description-এ intent আছে, শুধু input/output না
  • [ ] Error structured: ফিল্ডের নাম ও বৈধ মান সহ
  • [ ] State পরিবর্তনকারী endpoint-এ idempotency
  • [ ] Response ছোট ও focused
  • [ ] যেখানে সম্ভব composite operation
  • [ ] Pagination, naming, status value সব জায়গায় একই
  • [ ] Authentication ও rate limit spec-এ উল্লেখ আছে

নিজে হাতে করে দেখার ছোট কাজ

পড়ে বোঝা আর করে বোঝা আলাদা। ১-২ ঘণ্টায় করা যায়:

  1. একটা ছোট POST /orders endpoint বানান (ইচ্ছা করে type ও error অস্পষ্ট রেখে)।
  2. MCP-সমর্থিত একটা client বা Agent দিয়ে সেটা call করান, আর কোথায় আটকায় দেখুন।
  3. ৫টা নিয়ম একে একে প্রয়োগ করুন, প্রতিবার আচরণ কেমন বদলাল লিখে রাখুন।

আরও পড়ার জন্য

শেষ কথা

API এতদিন ডেভেলপারদের জন্য ডিজাইন হয়েছে। এখন তার কনজিউমার হিসেবে Agent-ও আসছে, যারা আন্দাজ বা debug করে না। যে API-র schema পরিষ্কার, error নির্দেশনামূলক আর retry নিরাপদ, সেটা Agent আর মানুষ, দুজনের জন্যই ভালো।

আপনার API-তে এই ৫টার মধ্যে কোনটা সবচেয়ে আগে করবেন? কমেন্টে জানান।

আগের লেখা: Repository, MediatR, CQRS নিয়ে Production-এর শিক্ষা

Top comments (0)