इस महीने तुमने "AI agents आ गए!" वाली एक दर्जन posts पढ़ी होंगी। Anthropic ने 8 April को Managed Agents ship किया। Google ने ADK launch किया। OpenAI ने अपना Agents SDK push किया। हर pitch deck में "autonomous agents" ऐसे लिखा है जैसे कोई जादू का मंत्र हो। लेकिन तुमने कभी वो actual loop नहीं बनाया जो इन सबको power करता है — Python की वो 50 lines जहाँ एक model एक function call करता है, result पढ़ता है, और decide करता है कि आगे क्या करना है। इसके बिना, हर vendor का demo बराबर impressive लगता है, और तुम real feature को महँगी gift-wrapping से अलग नहीं कर सकते।

"बस Platform Use कर लो" क्यों काम नहीं करता

Obvious move: कोई managed platform चुनो और सब उस पर छोड़ दो। लेकिन problem ये है — तुम understanding outsource कर रहे हो। Anthropic के Managed Agents का charge है $0.08 per session-hour। OpenAI के Agents SDK के अपने abstractions हैं। Google ADK graph-based workflows use करता है। हर platform एक ही core pattern को memory, permissions, और billing के बारे में अलग-अलग opinions में wrap करता है — लेकिन अगर तुम्हें pattern ही नहीं पता, तो evaluate कैसे करोगे कि तुम्हारे use case के लिए कौन सी opinion matter करती है? 2024 MIT Sloan Management Review analysis के हिसाब से enterprise AI projects में agentic AI का pilot-to-production success rate लगभग 5% है। Failure mode framework नहीं है। वो teams हैं जिन्हें समझ नहीं आता कि नीचे क्या चल रहा है।

तो चलो, बनाते हैं।

Recipe: 50 Lines से X-Ray Vision

Step 0: SDK Install करो

27 April 2026 तक, latest Anthropic Python SDK — एक toolkit जो तुम्हारे Python code को Claude के brain से बात करने देता है — v0.97.0 है। एक command:

pip install anthropic

अपनी API key set करो — एक secret password जो Anthropic के servers पर तुम्हारा account identify करता है:

export ANTHROPIC_API_KEY="sk-ant-..."

Step 1: अपने Tools Define करो

Tools वो functions हैं जिन्हें Claude तुमसे run करने को कह सकता है। तुम इन्हें JSON Schema से describe करते हो — एक standardized format जो बताता है "इस function को ये inputs चाहिए, इस shape में।" Claude इन descriptions को restaurant menu की तरह पढ़ता है और order करता है।

Critical insight: names से ज़्यादा descriptions matter करती हैं। Claude decide करता है कि tool कब call करना है description के basis पर। Vague description = unpredictable behavior।

यहाँ एक real tool definition है — weather lookup और calendar creator:

tools = [
    {
        "name": "get_weather",
        "description": "Get current weather for a city. Use when the user asks about weather, temperature, or outdoor conditions.",
        "input_schema": {
            "type": "object",
            "properties": {
                "city": {"type": "string", "description": "City name, e.g. 'New York'"},
                "units": {"type": "string", "enum": ["celsius", "fahrenheit"]}
            },
            "required": ["city"]
        }
    },
    {
        "name": "create_event",
        "description": "Create a calendar event. Use when the user wants to schedule, book, or plan something.",
        "input_schema": {
            "type": "object",
            "properties": {
                "title": {"type": "string"},
                "start": {"type": "string", "format": "date-time"},
                "end": {"type": "string", "format": "date-time"}
            },
            "required": ["title", "start", "end"]
        }
    }
]

ध्यान दो: required behavior control करता है। कोई required field skip करो और देखो Claude values hallucinate करने लगेगा। ज़रूरत से ज़्यादा fields require करो और valid calls block हो जाएँगे।

Step 2: Execution Layer बनाओ

यहाँ तुम्हारा code run होता है। Claude खुद कुछ execute नहीं करता — वो बस एक polite request भेजता है जैसे "please get_weather run करो {city: 'Chicago'} के साथ", और तुम्हारा code actual काम करता है:

def run_tool(name, input_data):
    if name == "get_weather":
        # Production में यहाँ weather API call होगा
        return {"temp": 72, "condition": "sunny", "city": input_data["city"]}
    if name == "create_event":
        return {"event_id": "evt_456", "status": "created", "title": input_data["title"]}
    return {"error": f"Unknown tool: {name}"}

Step 3: The Loop — जहाँ Agency पैदा होती है

यही वो part है जिसे हर platform हज़ारों lines के abstraction में wrap करता है। Agentic loop — वो cycle जहाँ Claude tools call करता है, results पढ़ता है, और अगला move decide करता है — लगभग 20 lines का है:

import json
import anthropic

client = anthropic.Anthropic()
messages = [{"role": "user", "content": "What's the weather in Chicago? If it's nice, schedule a picnic tomorrow at noon."}]

response = client.messages.create(
    model="claude-sonnet-4-20250514", max_tokens=1024,
    tools=tools, messages=messages
)

while response.stop_reason == "tool_use":
    # Claude एक बार में MULTIPLE tools request कर सकता है — सब process करो
    tool_results = []
    for block in response.content:
        if block.type == "tool_use":
            result = run_tool(block.name, block.input)
            tool_results.append({
                "type": "tool_result",
                "tool_use_id": block.id,
                "content": json.dumps(result)
            })

    messages.append({"role": "assistant", "content": response.content})
    messages.append({"role": "user", "content": tool_results})

    response = client.messages.create(
        model="claude-sonnet-4-20250514", max_tokens=1024,
        tools=tools, messages=messages
    )

print(response.content[0].text)

वो prompt दो autonomous tool calls trigger करता है: पहले get_weather (Chicago check करने के लिए), फिर create_event (picnic schedule करने के लिए) — और Claude इन्हें chain करता है बिना तुम्हारे बताए। यही "aha" moment है: model weather result पढ़ता है, decide करता है कि मौसम अच्छा है, और अगला tool खुद call कर देता है।

हर agent platform यही loop है plus memory, permissions, billing, और deployment की opinions ऊपर से चिपकी हुई।

Step 4: Error Handling — Crash मत करो, सिखाओ

जब कोई tool fail हो, loop crash मत करो। Error वापस भेजो is_error: True के साथ ताकि Claude adapt कर सके — different input से retry करे, problem explain करे, या दूसरा approach try करे:

def run_tool_safe(name, input_data):
    try:
        return run_tool(name, input_data), False
    except Exception as e:
        return {"error": str(e)}, True

# Loop के अंदर, tool_results construction replace करो:
result, is_err = run_tool_safe(block.name, block.input)
tool_results.append({
    "type": "tool_result",
    "tool_use_id": block.id,
    "content": json.dumps(result),
    "is_error": is_err
})

Claude error पढ़कर intelligently respond करता है: "मैंने picnic schedule करने की कोशिश की लेकिन calendar सिर्फ business hours में events allow करता है। क्या Saturday morning try करूँ?"

Step 5: Safety Fuse लगाओ

एक runaway loop tokens — छोटे word-chunks जिन्हें Claude process करता है, लगभग एक English word का ¾ हिस्सा — जलाता रहता है जब तक तुम kill नहीं करते। Counter लगाओ:

MAX_ITERATIONS = 10
iteration = 0

while response.stop_reason == "tool_use" and iteration < MAX_ITERATIONS:
    iteration += 1
    # ... same loop body ...

if iteration >= MAX_ITERATIONS:
    print("Loop hit safety limit. Something's probably wrong.")

कोई managed platform तुम्हें नहीं बताएगा कि ये सबसे पहले add करने वाली चीज़ है। वो इसे चुपचाप handle करते हैं — और इसका bill तुम्हें भेजते हैं।

Production में काटने वाले Gotchas

1. "First tool only" bug। Claude एक response में multiple tool_use blocks return कर सकता है — जैसे तीन cities का weather एक साथ check करना। अगर तुम सिर्फ पहला block process करते हो (tutorials में बहुत common है), model confused हो जाता है missing results की वजह से। Symptom: Claude बार-बार वही request repeat करता है। Fix: सारे blocks iterate करो, सारे results एक message में return करो। Official tutorial इसे Ring 2 से Ring 3 progression कहता है।

2. Context window bloat। Context window — Claude एक बार में कितना text "देख" सकता है, जैसे working memory — तेज़ी से भरता है। हर tool call और result accumulate होता है। एक verbose command output एक ही turn में हज़ारों tokens खा सकता है। Agent SDK compaction automatically handle करता है; raw SDK नहीं। Fix: बड़े outputs को वापस feed करने से पहले summarize करो, या relevant parts तक truncate करो।

3. कोई sandboxing नहीं। तुम्हारा run_tool function तुम्हारी permissions के साथ run होता है। अगर Claude कोई file delete करने को कहे और तुम्हारा tool मान ले, file गई — बिना undo के। Momentic के analysis के मुताबिक, उनकी team ने 3 महीने autonomous agent runs करके सीखा: "sandboxing optional नहीं है... चीज़ें जितना तुम सोचते हो उससे कहीं ज़्यादा तेज़ी से हाथ से निकलती हैं।"

4. Missing required fields। अगर तुम्हारी schema कहती है required: ["city"] लेकिन user बोले "मौसम कैसा है?", तो Claude city hallucinate करेगा बजाय पूछने के। Fix: description explicit बनाओ — "अगर user city specify न करे, तो guess करने की बजाय पूछो।"

अब तुम क्या कर सकते हो

तुम्हारे पास एक working agentic loop है। यहाँ से हर vendor announcement सीधे इस पर map होता है। Managed Agents? वो तुम्हारा loop है plus checkpointing, monitoring, और crash recovery — $0.08/session-hour में। OpenAI का Agents SDK vs Google ADK? वही loop, अलग handoff और graph-based opinions।

अगली बार जब कोई platform pitch तुम्हारे सामने आए। Demo पर भरोसा करने की बजाय, पूछो: मेरे loop की कौन सी layer ये replace कर रहा है — और क्या वो layer actually मेरा bottleneck है?