8 मिनट पढ़ें

AI agents के request retries से duplicate API writes रोकें

Idempotency tokens, request fingerprints, atomic claims और हर action से जुड़ी confirmations के जरिए AI agents से होने वाली डुप्लिकेट API writes रोकें।

AI agents के request retries से duplicate API writes रोकें

AI एजेंट लोगों से कहीं तेज़ी से रिट्राई की गलतियां करते हैं। टाइमआउट देखने पर कोई व्यक्ति रुककर ticket queue देख सकता है और समझ सकता है कि क्या हुआ। एजेंट अक्सर exception देखता है, रिट्राई का निर्देश मानता है और पहली रिक्वेस्ट नेटवर्क सीमा के पार कहीं पूरी होने से पहले दूसरी write भेज देता है।

इससे डुप्लिकेट tickets, बार-बार भुगतान प्रयास, डुप्लिकेट user invitations और एक ही बदलाव के दो deployments हो सकते हैं। समाधान एजेंट को सावधान रहने के लिए कहना नहीं है। आपको ऐसा API contract चाहिए जो रिट्राई के दौरान एक इच्छित कार्रवाई की पहचान बनाए रखे, दोबारा इस्तेमाल किए गए identifier के पीछे छिपे बदलावों का पता लगाए और जब परिणाम गंभीर हो तो नई human confirmation मांगे।

रिट्राई सामान्य हैं, डुप्लिकेट प्रभाव ज़रूरी नहीं

टाइमआउट का मतलब यह नहीं कि सर्वर ने कुछ नहीं किया। सर्वर ticket बना चुका हो सकता है और लौटते समय response खो गया हो सकता है। वह अभी भी रिक्वेस्ट process कर रहा हो सकता है। Load balancer ने connection स्वीकार किया हो, लेकिन upstream service ने bytes देखे ही न हों। Socket error से client परिणाम का अनुमान नहीं लगा सकता।

इसीलिए एजेंट को दिया जाने वाला सामान्य निर्देश, «network errors पर retry करें», अधूरा है। यह हर अनिश्चित परिणाम को असफल कार्रवाई मान लेता है। Write endpoints के लिए अनिश्चित परिणाम की तीन स्थितियां हो सकती हैं:

  • सर्वर को रिक्वेस्ट मिली ही नहीं
  • सर्वर ने रिक्वेस्ट स्वीकार कर काम पूरा कर दिया
  • सर्वर ने रिक्वेस्ट स्वीकार कर ली, लेकिन काम अभी पूरा नहीं हुआ

तीनों स्थितियों में वही रिट्राई सुरक्षित होनी चाहिए। यदि पूरी हो चुकी स्थिति में वह दूसरा प्रभाव पैदा करती है, तो endpoint की retry boundary असुरक्षित है।

HTTP आपके लिए यह समस्या हल नहीं करता। RFC 9110 idempotent methods को ऐसे methods के रूप में परिभाषित करता है जिनका इच्छित प्रभाव एक या अधिक समान रिक्वेस्ट के बाद भी वही रहता है। इसमें PUT, DELETE और safe methods शामिल हैं। RFC यह भी कहता है कि communication failure के बाद client idempotent रिक्वेस्ट को रिट्राई कर सकता है। यह उपयोगी है, लेकिन इससे PUT route इस्तेमाल करने वाला हर endpoint सुरक्षित नहीं हो जाता। Server PUT handler में email delivery, credit issuance या deployment trigger जोड़ सकता है और यदि वह इसकी योजना न बनाए तो side effect दोहरा सकता है।

POST के लिए स्पष्ट agreement चाहिए। कई APIs actions के लिए POST इस्तेमाल करती हैं, क्योंकि server resource identifiers देता है या रिक्वेस्ट का अर्थ होता है «यह business operation करें»। एजेंट ऐसी रिक्वेस्ट को तभी रिट्राई कर सकता है जब API यह बताए कि अलग-अलग प्रयासों में एक ही operation की पहचान कैसे होगी।

Transport retries और business retries को अलग रखें। Transport retry में परिणाम अज्ञात रहने के कारण वही operation फिर भेजा जाता है। Business retry तब शुरू होती है जब पहली operation की terminal failure निश्चित हो और नई operation शुरू करनी हो। दोनों को मिलाने पर वही मशहूर incident report बनती है: एजेंट ने सफलतापूर्वक दो बार रिट्राई की।

Idempotency token एक इच्छित कार्रवाई की पहचान करता है

Idempotency token क्लाइंट द्वारा बनाया गया opaque identifier है, जिसका अर्थ है: «इस value वाली सभी requests इसी एक कार्रवाई को करने के प्रयास हैं।» एजेंट इसे पहली रिक्वेस्ट से पहले बनाता है, task state के साथ सुरक्षित रखता है और हर रिट्राई में वही value भेजता है।

Token का संबंध logical action से होना चाहिए, HTTP attempt से नहीं। यदि एजेंट support ticket बनाता है, response खो देता है और नए token के साथ फिर रिक्वेस्ट भेजता है, तो API के पास रिट्राई पहचानने का कोई आधार नहीं होगा। उसे दूसरा ticket बनाना चाहिए, क्योंकि caller ने इसे दूसरी operation बताया है।

Random, high-entropy value इस्तेमाल करें। UUID आम है, लेकिन कोई भी format चलेगा, बशर्ते caller values का अनुमान न लगा सकें और server token को opaque माने। इसे Idempotency-Key header या documented request field में रखें। Header operation identity को business payload से अलग रखता है और middleware के लिए logs तथा tracing में इसे आगे ले जाना आसान बनाता है।

एक व्यावहारिक रिक्वेस्ट ऐसी दिख सकती है:

curl -X POST https://api.example.test/v1/tickets \\
  -H 'Authorization: Bearer $TOKEN' \\
  -H 'Content-Type: application/json' \\
  -H 'Idempotency-Key: 81b59b1a-9e75-4de7-a53b-1bb50969c83c' \\
  -d '{"project":"ops","title":"Rotate staging certificate","priority":"high"}'

पहली स्वीकार की गई कॉल पर server token, request का canonical fingerprint, operation state और अंततः दोबारा लौटाया जाने वाला response दर्ज करता है। बाद की रिक्वेस्ट में वही token और वही fingerprint हो तो server पिछला परिणाम लौटाता है, दूसरा ticket नहीं बनाता।

Client को token रखने के लिए durable जगह चाहिए। केवल current prompt या process memory में token रखने वाला एजेंट restart के बाद operation identity खो देगा। इसे task record, job record या workflow checkpoint के साथ रखें। यदि कोई व्यक्ति उसी text के साथ जानबूझकर दूसरा, अलग ticket बनाने को कहे, तो एजेंट को नया token बनाना होगा, क्योंकि व्यक्ति ने नया इरादा व्यक्त किया है।

Token को mutable task name, timestamp या natural-language request न बनाएं। ये values टकरा सकती हैं, रिट्राई के बीच बदल सकती हैं या logs में जानकारी उजागर कर सकती हैं। Opaque identifiers उबाऊ होते हैं। यही वजह है कि वे काम करते हैं।

Fingerprint बदली हुई रिट्राई पकड़ता है

Token यह बताता है कि caller का दावा है कि दो requests एक operation हैं। Request fingerprint यह जांचता है कि वे वास्तव में एक ही बात कहती हैं या नहीं। दोनों चाहिए।

मान लें एजेंट पहले deployment API से commit a1b2c3 को staging में भेजने को कहता है। टाइमआउट के बाद वह नई task note पढ़ता है और उसी token के साथ commit d4e5f6 भेजकर रिट्राई करता है। यदि server बिना जांच पहली response लौटाता है, तो agent की गलती छिप जाती है। यदि वह दूसरी body execute करता है, तो एक operation identifier को दो अलग deployments की अनुमति मिल जाती है।

रिक्वेस्ट के महत्वपूर्ण हिस्सों को canonical रूप में बदलकर उनका hash बनाएं। अधिकांश APIs में HTTP method, normalized route, authenticated account या tenant और canonical JSON body शामिल होते हैं। जब कुछ headers business effect बदलते हों, तो उन्हें भी शामिल करें। Volatile tracing headers, connection metadata और idempotency header को बाहर रखें।

JSON में सावधानी चाहिए। अलग property order या whitespace वाला equivalent JSON raw byte hash में अलग दिखेगा। Canonical representation object properties को sort करती है, array order बनाए रखती है, तय number format इस्तेमाल करती है और server द्वारा दिए जाने वाले fields हटाती है। इससे बेहतर है कि API defaults लागू करने और unknown fields अस्वीकार करने के बाद validated command object का fingerprint बनाएं। तब fingerprint उस operation से मेल खाता है जिसे server execute करेगा, किसी मनमाने input encoding से नहीं।

उदाहरण के लिए, validation के बाद digest दर्ज करने वाला pseudocode:

command = validate_create_ticket(request.body)
canonical = canonical_json({
  "method": "POST",
  "route": "/v1/tickets",
  "account_id": authenticated_account.id,
  "command": command
})
fingerprint = sha256(canonical)

जब token पहले से मौजूद हो, तो किसी पुराने परिणाम को लौटाने या उसके लिए इंतज़ार करने से पहले fingerprints की तुलना करें। अलग होने पर conflict response के साथ रिक्वेस्ट अस्वीकार करें। Stored operation identifier और state शामिल करें, लेकिन unauthorized caller को protected request details न लौटाएं।

Fingerprint अकेले duplicate detector नहीं है। दो users वैध रूप से एक जैसे tickets दर्ज कर सकते हैं। Payroll service दो कर्मचारियों को समान भुगतान कर सकती है। Payload का hash बनाकर हर match को deduplicate करने से valid work चुपचाप खो सकता है। Deduplication को idempotency token तक सीमित रखें और जहां domain में सचमुच ज़रूरत हो, वहां business-specific uniqueness rules लगाएं।

आधुनिक function जैसे SHA-256 वाले cryptographic hashes accidental collisions को व्यावहारिक रूप से असंभव बनाते हैं। वे caller के इरादे का प्रमाण नहीं देते। Token इरादा बताता है, fingerprint consistency लागू करता है। जो teams दोनों को एक ही समझती हैं, वे अक्सर ऐसा dedupe rule बना देती हैं जिसे legitimate request अस्वीकार होने पर समझाना मुश्किल होता है।

Server को काम शुरू करने से पहले token claim करना चाहिए

यदि idempotency table side effect पूरा होने के बाद ही परिणाम दर्ज करती है, तो race बनी रहती है। दो concurrent retries table check कर सकती हैं, कुछ न देखकर दो tickets बना सकती हैं और फिर result store करने की दौड़ लगा सकती हैं। मैंने इसे flaky agent problem के रूप में छिपा हुआ देखा है, जबकि असली defect missing uniqueness constraint था।

Irreversible work से पहले server को token को atomically claim करना चाहिए। Scope और token पर unique constraint लगाएं, आम तौर पर account identifier और idempotency token का संयोजन। एक transaction में fingerprint और in_progress state वाली row insert करने का प्रयास करें। जो रिक्वेस्ट जीतती है, वही execution की मालिक होती है। बाकी हर रिक्वेस्ट existing row पढ़ती है।

एक सरल table में ये fields हो सकते हैं:

create table idempotency_operations (
  account_id text not null,
  token text not null,
  fingerprint text not null,
  state text not null,
  response_status integer,
  response_body jsonb,
  created_at timestamptz not null,
  primary key (account_id, token)
);

यहां primary key वास्तविक काम करती है। पहले check और बाद में insert करने वाला application code concurrent workers, queue redelivery और अधीर retries के लिए पर्याप्त बड़ा gap छोड़ देता है।

Claim के बाद handler business action करता है और final response operation row में लिखता है। बाद की matching requests को वही saved status और body मिलते हैं। इससे callers को स्थिर उत्तर मिलता है, भले ही original handler सफल हो गया हो लेकिन जवाब देने से पहले connection टूट गया हो।

मुश्किल स्थिति वह है जब किसी रिक्वेस्ट की row उसके पास हो, लेकिन काम के बीच process समाप्त हो जाए। केवल worker timeout होने पर row न हटाएं। कोई दूसरा worker अभी काम पूरा कर रहा हो सकता है या external provider operation स्वीकार कर चुका हो सकता है। Operation को pending या unknown mark करें, जांच के लिए पर्याप्त data रखें और callers को उसका status पूछने दें। Stale records को repair job तभी resolve करे जब उसे downstream system की state समझ में आती हो।

Database और external API के बीच फैलने वाले काम के लिए outbox pattern या provider-side idempotency token इस्तेमाल करें। Database transaction email, payment या cloud deployment को आपके process से बाहर जाने के बाद rollback नहीं कर सकती। एक local transaction में intent और outbox event लिखें, फिर worker को stable downstream operation identifier के साथ event भेजने दें। इससे recovery code के पास replay करने के लिए ठोस चीज़ रहती है और उसे दूसरी action गढ़नी नहीं पड़ती।

Confirmation को exact operation से जोड़ें

एजेंट को क्रेडेंशियल से दूर रखें
बंडल किए गए MCP shim का इस्तेमाल करें, ताकि Claude Code सीधे सीक्रेट के साथ नहीं, Sallyport के जरिए कार्रवाई भेजे।

Human confirmation एक दूसरी समस्या रोकती है: एजेंट के पास कार्रवाई की permission हो सकती है, लेकिन प्रस्तावित action आश्चर्यजनक, बहुत व्यापक या context बदलने के बाद दोहराई गई हो सकती है। सामान्य «allow deployment» button इसे हल नहीं करता। उसी approval के तहत एजेंट एक deployment की जगह दूसरा deployment रख सकता है।

अच्छी confirmation में target, operation, consequence और operation identifier का नाम होना चाहिए। Production deployment के लिए environment, artifact या commit reference, प्रभावित service और rollback की संभावना दिखाएं। Payment के लिए payee, amount, currency और invoice reference दिखाएं। Ticket के लिए destination project और title दिखाएं।

Confirmation record को request fingerprint से जोड़ें और proposal के current न रहने पर उसे expire करें। यदि व्यक्ति की मंज़ूरी के बाद एजेंट body बदलता है, तो fingerprint बदल जाएगा और system को फिर पूछना होगा। बदली हुई रिक्वेस्ट पर पुरानी approval इस्तेमाल करना privilege escalation का शांत रूप है, भले ही किसी का ऐसा इरादा न रहा हो।

हर low-risk retry के लिए व्यक्ति से approval न मांगें। इससे सही idempotency design approval fatigue में बदल जाएगी। पहली approval एक fingerprinted operation को authorize कर सकती है और matching retries उसी approval का इस्तेमाल कर सकती हैं, क्योंकि वे उसका अर्थ नहीं बदल सकतीं। बदले हुए payload के लिए नया निर्णय चाहिए।

कुछ teams «Proceed?» जैसे chat message पर निर्भर करती हैं और reply को approval मान लेती हैं। दबाव में यह विफल होता है, क्योंकि record में अक्सर exact parameters नहीं होते और agent बाद के reply को पहले की रिक्वेस्ट की सहमति समझ सकता है। Confirmation record में operation identifier रखें और write भेजने से पहले executor से उसका सत्यापन कराएं।

एक सरल approval payload binding को स्पष्ट करता है:

{
  "operation_id": "op_3f8c",
  "idempotency_token": "81b59b1a-9e75-4de7-a53b-1bb50969c83c",
  "fingerprint": "e5c7...",
  "expires_at": "2025-06-14T15:30:00Z",
  "approved_by": "user_42"
}

Confirmation को किसी खास command के लिए authorization मानें, commands की किसी category के आसपास मनमाने ढंग से काम करने की permission नहीं। यही अंतर रिट्राई को सुरक्षित रखता है और एजेंट को ऐसी blank approval नहीं देता जिसे वह बाद में फिर इस्तेमाल कर सके।

Ticket systems को business-level duplicate check भी चाहिए

Idempotency tokens duplicate transport attempts रोकते हैं, लेकिन ticket systems में duplication का एक और स्रोत है: एजेंट अलग-अलग operations शुरू कर सकते हैं जो एक ही समस्या का वर्णन करती हैं। Monitoring alert दो बार आ सकता है, दो agent runs एक ही incident channel पढ़ सकते हैं या scheduler crash के बाद original state के बिना task दोहरा सकता है।

Title text के आधार पर deduplicate करके समस्या हल न करें। Ticket titles इतने बदलते हैं कि duplicates छूट जाएंगे और समान titles अलग incidents के लिए हो सकते हैं। इसके बजाय तय करें कि ticket domain में identity का अर्थ क्या है। यह alert event identifier, incident identifier, repository issue reference या service plus alert fingerprint plus incident window जैसा compound value हो सकता है।

इस business identifier को API में स्पष्ट रखें:

{
  "source_event_id": "alert-7c91",
  "project": "operations",
  "title": "Certificate expiry alert",
  "description": "Alert event alert-7c91 crossed its threshold."
}

Ticket service intended scope के भीतर source_event_id की uniqueness लागू कर सकती है। दूसरे agent run को queue में दूसरा item जोड़ने के बजाय existing ticket identifier मिलेगा। यह idempotency से अलग है। दोनों calls के idempotency tokens अलग हो सकते हैं, क्योंकि वे अलग agent processes से आए हैं, फिर भी वे उसी upstream event को दर्शा सकती हैं।

Agents को create करने से पहले तभी search करना चाहिए जब search result में भरोसेमंद stable identity हो। Search-by-title workflow आकर्षक है, क्योंकि इसमें API बदलाव नहीं चाहिए। Indexing में देरी, query ranking बदलने या agent द्वारा title paraphrase करने पर यह टूट जाता है। Uniqueness rule वहीं रखें जहां write होती है और स्पष्ट response लौटाएं कि API ने ticket बनाया या existing ticket फिर इस्तेमाल किया।

Automatic comments और status changes से सावधान रहें। Existing ticket मिलने पर भी operation duplicate comment जोड़ सकती है या resolved incident फिर खोल सकती है। हर meaningful sub-action को अपना identifier दें या write command में पूरी desired state व्यक्त करें। अस्पष्ट «इस ticket को update करें» endpoints को सुरक्षित रूप से रिट्राई करना कठिन है, क्योंकि कोई नहीं बता सकता कि update का कौन सा हिस्सा पहले चल चुका है।

Payment writes में optimism नहीं, outcome query चाहिए

रिट्राई क्रेडेंशियल बाहर रखें
Sallyport HTTP कॉल चलाता है, जबकि API क्रेडेंशियल उसके एन्क्रिप्टेड वॉल्ट में सुरक्षित रहता है।

Payment actions के लिए मानक अधिक कठोर है, क्योंकि duplicate charge ग्राहक को बाद में refund करने पर भी नुकसान पहुंचाता है। Application को payment provider को एक stable idempotency token भेजना चाहिए और provider transaction reference को local operation record के साथ रखना चाहिए।

Client timeout होने पर payment को unknown मानना चाहिए। Provider reference, merchant reference या provider द्वारा उपलब्ध कराए गए idempotency token से lookup करना चाहिए। केवल success response न मिलने के कारण दूसरा payment attempt शुरू नहीं करना चाहिए।

दो operations को लोग अक्सर एक मान लेते हैं: payment intent बनाना और funds capture करना। इनके retry behavior अलग हो सकते हैं। Service token के जरिए एक payment object को सुरक्षित रूप से create या retrieve कर सकती है, फिर checks पास होने के बाद अलग explicit capture action मांग सकती है। Business states को खुलकर model करें, उन्हें ऐसे single endpoint के पीछे न छिपाएं जो हर call में सब कुछ करने की कोशिश करता हो।

Fingerprint बनाने से पहले amounts को canonical तरीके से संभालें। Values को smallest supported currency unit या किसी और exact representation में बदलें। Floating-point display value का hash बनाकर equivalent calculations की भरोसेमंद तुलना की उम्मीद न करें। जहां domain में invoice या order reference हो, payment request में उसे भी रखें, क्योंकि इससे staff को network retries से आगे duplicate intent पहचानने में मदद मिलती है।

Provider की idempotency सुविधा आपकी अपनी API की जिम्मेदारी खत्म नहीं करती। Application को फिर भी दो agent tasks को उसी order के लिए दो अलग provider requests शुरू करने से रोकना होगा। Order की payable state पर uniqueness constraint लगाएं, local operation record रखें और uncertainty के बाद agent को उसी record से जानकारी लेने दें।

Refunds को भी यही सावधानी चाहिए। «Retry refund» का अर्थ वही refund request दोहराना या दूसरा partial refund शुरू करना हो सकता है। हर refund instruction के लिए stable identifier रखें और पहले मांगी गई amount दर्ज करें। दूसरा refund देना हो तो उसे नए identifier वाली नई, स्पष्ट रूप से authorized instruction बनाएं।

Deployments में immutable references और release lock चाहिए

Deployment retry तभी सुरक्षित है जब वह उसी release का नाम ले। main जैसे branch names और latest जैसे mutable tags इस standard पर खरे नहीं उतरते। टाइमआउट के बाद retry में वही नाम अलग code पर जा सकता है और ऐसा लग सकता है कि deployment सफल हुआ, जबकि approver ने उस code को review ही नहीं किया था।

Immutable artifact digest, commit identifier या ऐसा version इस्तेमाल करें जिसे release system बदलने न दे। उसे request fingerprint और confirmation में शामिल करें। यदि agent बदले हुए artifact reference के साथ वही idempotency token भेजता है, तो दूसरी रिक्वेस्ट को updated retry न मानें, conflict के रूप में अस्वीकार करें।

Environment के लिए concurrency rule भी चाहिए। दो अलग operations के token अलग हो सकते हैं और फिर भी conflict कर सकते हैं, क्योंकि दोनों production को target करती हैं। Release lock, optimistic version check या deployment queue इन बदलावों को serialize कर सकती है। Idempotency यह तय नहीं करती कि दो अलग deployments में कौन जीतेगा। वह केवल एक deployment को दो बार चलने से रोकती है।

यह failure sequence देखें। Agent commit a1b2c3 के लिए deployment dep-118 शुरू करता है और deployment controller उसे स्वीकार कर लेता है। Agent response खो देता है, failure मान लेता है और नए commit d4e5f6 के साथ dep-119 शुरू कर देता है। अब दोनों jobs एक ही environment बदलती हैं। Token केवल dep-118 की वास्तविक retry रोकता; release lock या expected-environment-version check दूसरे conflicting plan को रोकता।

Deployment API को operation status resource देना चाहिए, जिसमें queued, running, succeeded, failed, canceled या unknown state हो। टाइमआउट के बाद agents को इसी status पर poll करना चाहिए। Missing response या ऐसे log line से completion का अनुमान नहीं लगाना चाहिए जिसमें operation identifier न हो।

Rollback के लिए अपना operation identifier और approval चाहिए। Rollback को deployment की retry मानने से intent में आया महत्वपूर्ण बदलाव छिप जाता है। Documented safety rule के तहत यह automatic हो सकता है, लेकिन इसका record original release से अलग होना चाहिए।

Agent tools को boundary के पार operation identity बनाए रखनी चाहिए

विवादित राइट को ट्रेस करें
Sessions जर्नल एजेंट रन को उसकी कार्रवाइयों से जोड़ता है और उस रन को तुरंत रद्द करने देता है।

Agent tool interface को unsafe से आसान safe behavior बनाना चाहिए। Agent को ऐसा एक action दें जो stable operation identifier, payload और declared retry mode स्वीकार करे। Result में बताएं कि service ने नया काम बनाया, पिछला result replay किया, operation को progress में पाया या बदली हुई retry अस्वीकार की।

ऐसे tools से बचें जो हर invocation पर चुपचाप नया idempotency token बनाते हैं। Demo में वे सुविधाजनक लगते हैं और पहले वास्तविक timeout में विफल होते हैं। यदि tool token बनाता है, तो उसे token तुरंत लौटाना और ऐसी जगह persist करना होगा जहां बाद का invocation उसे पा सके। अधिकांश systems में token workflow layer के पास होना चाहिए, क्योंकि वही समझती है कि कौन सी calls एक user-requested action का हिस्सा हैं।

Sallyport agent से API credentials बाहर रख सकता है, जबकि agent अपने MCP connection के जरिए intended HTTP action भेजता है। यह separation credential exposure में मदद करता है, लेकिन downstream API को फिर भी idempotency behavior चाहिए। Protected credential अस्पष्ट POST को सुरक्षित retry में नहीं बदलता।

Agent के tool contract में retry rule स्पष्ट रखें:

if response is a known success:
    record operation complete
if response is a timeout or connection failure:
    query operation status using the same token
    retry only with the same token if the API permits it
if response says fingerprint conflict:
    stop and request a new operation or human review
if response is a known business failure:
    do not retry until the task changes

Exponential backoff को state का विकल्प न बनने दें। Backoff service पर दबाव कम करता है, जो महत्वपूर्ण है, लेकिन यह नहीं बताता कि पिछली write सफल हुई या नहीं। Agent को इंतज़ार करने से पहले operation identifier सुरक्षित रखना होगा।

Logs को विवादित write के बाद साबित करना चाहिए कि क्या हुआ

जब कोई customer कहता है कि उससे दो बार charge लिया गया या engineer को दो tickets मिलते हैं, तो आपको चार सवालों के जवाब चाहिए: हर request किस agent run ने भेजी, उसने कौन सा token इस्तेमाल किया, server ने कौन सा fingerprint निकाला और downstream service ने क्या परिणाम लौटाया। सामान्य request logs में अक्सर इनमें से कम-से-कम एक जानकारी नहीं होती।

API द्वारा action स्वीकार करने वाली boundary पर operation record log करें। इसमें authenticated principal, token, fingerprint, request route, operation state transitions, response reference और उपलब्ध होने पर upstream provider reference रखें। Secrets और पूरी sensitive bodies को सामान्य logs से बाहर रखें। Fingerprint से हर private field को हर log system में सेव किए बिना requests की तुलना की जा सकती है।

जब agent को external writes करने का अधिकार हो, तो append-only audit record उपयोगी है। Record में attempted, approved, sent, accepted, completed और replayed को अलग-अलग दिखाएं। ये interchangeable states नहीं हैं। Stored prior response पाने वाली retry को created नहीं, replayed कहना चाहिए, वरना operators उसे दूसरी action गिनेंगे।

Sallyport agent sessions और individual actions को encrypted hash-chained audit log से बने journals में दर्ज करता है और sp audit verify chain को offline verify कर सकता है। इससे पता चल सकता है कि action gateway से क्या गुज़रा। इस evidence को receiving service के idempotency records के साथ मिलाएं, क्योंकि business action execute हुआ या नहीं, यह receiving service तय करती है।

Disputed-write path पर भरोसा करने से पहले उसका test करें। Server को रिक्वेस्ट पूरी करके response drop करने को कहें। एक token की concurrent copies भेजें। Attempts के बीच agent restart करें। बदले payload के साथ token reuse करें। Token claim करने के बाद और completion record करने से पहले worker को बंद करें। जो design केवल clean success responses में टिकता है, उसने duplicate writes की समस्या हल नहीं की है।

सबसे अधिक नुकसान वाले write endpoint से शुरुआत करें। Stable token जोड़ें, किसी भी side effect से पहले उसे atomically claim करें, fingerprint से जोड़ें और unknown outcomes के लिए callers को status lookup दें। फिर agent को यह identifier तब तक साथ रखना सिखाएं जब तक वह साबित न कर सके कि operation terminal state तक पहुंच गई है।

सामान्य प्रश्न

टाइमआउट के बाद AI एजेंट को डुप्लिकेट रिकॉर्ड बनाने से कैसे रोकें?

एजेंट को पहली रिक्वेस्ट भेजने से पहले हर तार्किक ऑपरेशन के लिए एक स्थायी idempotency token दें। सर्वर उस token के लिए पहली पूरी हुई प्रतिक्रिया सेव करे और बाद की रिट्राई में वही लौटाए। टाइमआउट के बाद नया token न बनाएं, क्योंकि इससे रिट्राई एक नया ऑपरेशन बन जाती है।

क्या API idempotency के लिए request hash पर्याप्त है?

नहीं। Request fingerprint यह पता लगा सकता है कि एक ही payload दो बार आया है, लेकिन यह भरोसेमंद तरीके से नहीं बता सकता कि समान payload एक ही इच्छित कार्रवाई है या दो अलग कार्रवाइयां। इरादा तय करने के लिए क्लाइंट से मिला idempotency token इस्तेमाल करें और बदली हुई सामग्री के साथ token दोबारा इस्तेमाल होने पर रोक लगाने के लिए fingerprint रखें।

क्या AI एजेंट POST requests को सुरक्षित रूप से रिट्राई कर सकता है?

तभी, जब endpoint में idempotency contract साफ़ तौर पर दर्ज हो और एजेंट हर रिट्राई में वही token बनाए रखे। HTTP semantics के अनुसार POST अपने-आप idempotent नहीं होता। सुरक्षित एजेंट को सीमित रिट्राई, स्पष्ट टाइमआउट हैंडलिंग और ऑपरेशन का परिणाम पाने का तरीका भी चाहिए।

एक ही idempotency token दो बार मिलने पर API को क्या लौटाना चाहिए?

सर्वर को पहली स्वीकार की गई रिक्वेस्ट के लिए सेव की गई प्रतिक्रिया लौटानी चाहिए, जिसमें मूल resource identifier और status शामिल हों। उसे side effect दोहराना या दूसरा रिकॉर्ड बनाना नहीं चाहिए। अगर मूल रिक्वेस्ट अभी चल रही हो, तो स्पष्ट in-progress response लौटाएं या कॉलर को सेव किए गए परिणाम का इंतज़ार कराएं।

Idempotency tokens डुप्लिकेट card charges को कैसे रोकते हैं?

पूरी खरीदारी के प्रयास के लिए एक idempotency token इस्तेमाल करें और भुगतान प्रदाता को यह तय करने दें कि ग्राहक से शुल्क लिया गया है या नहीं। अनिश्चित नेटवर्क समस्या के बाद अपने payment endpoint पर नया token लेकर दोबारा कोशिश न करें। दूसरा भुगतान करने से पहले सेव किए गए ऑपरेशन या provider transaction से जानकारी लें।

क्या confirmation prompts डुप्लिकेट deployments रोकते हैं?

वे मदद करते हैं, लेकिन authorization की जगह नहीं लेते। Confirmation में व्यक्ति को खास कार्रवाई से जोड़ा जाना चाहिए: target, बदलाव, scope और operation identifier। वरना सामान्य मंज़ूरी अलग सामग्री वाली दोबारा भेजी गई रिक्वेस्ट को अनजाने में मंज़ूरी दे सकती है।

API को idempotency tokens कितने समय तक रखने चाहिए?

Tokens को उतने समय तक रखें, जितने समय में कॉलर वास्तविक रूप से रिक्वेस्ट को रिट्राई या replay कर सकता है। सही अवधि client retry budget और business risk पर निर्भर करती है। जब पुराने replay से नुकसान हो सकता हो, जैसे भुगतान या बाहरी ticket creation में, तो durable business record को अधिक समय तक रखें।

एक ही idempotency token के साथ अलग request body आने पर क्या होता है?

अलग fingerprint वाले दोबारा इस्तेमाल किए गए token को client error मानें और उसे execute करने से इनकार करें। Conflict response लौटाने से एजेंट रुककर अपनी state देखेगा, बजाय इसके कि पुराने operation identifier को चुपचाप नया अर्थ दे दे।

API request टाइम आउट होने के बाद एजेंट को क्या करना चाहिए?

कॉलर को outcome को failed नहीं, unknown मानना चाहिए। उसे उसी token या request identifier से operation-status endpoint पर जानकारी लेनी चाहिए और API अनुमति दे तो उसी identifier के साथ ही रिट्राई करनी चाहिए। नया POST अंधाधुंध भेजना ही डुप्लिकेट tickets और charges पैदा करता है।

क्या PUT और DELETE को अपने-आप सुरक्षित रूप से रिट्राई किया जा सकता है?

सर्वर उन्हें सही तरीके से लागू करे तो PUT और DELETE की HTTP semantics idempotent होती हैं, लेकिन टाइमआउट के बाद भी क्लाइंट को पता नहीं होता कि पहली रिक्वेस्ट का असर हुआ या नहीं। POST को idempotency token से सुरक्षित बनाया जा सकता है और कई business actions के लिए ऐसा स्पष्ट contract ज़रूरी होता है।

Sallyport

Sallyport आपके AI एजेंट के लिए API कॉल और SSH कमांड चलाता है। कुंजियाँ आपके Mac पर एक लोकल वॉल्ट में रहती हैं; आप हर रन को स्वीकृत करते हैं और हर क्रिया एक सीलबंद जर्नल में दर्ज होती है।

© 2026 Sallyport · Apache-2.0 के तहत ओपन सोर्स · Oleg Sotnikov