എല്ലാവരും പ്രോംപ്റ്റിനെക്കുറിച്ച് അമിതമായി ചിന്തിക്കുന്നു. അവർ അഭിവാദ്യങ്ങൾ (greetings) പരിഷ്കരിക്കാനും, ശൈലി (tone) മാറ്റാനും, മോഡൽ ആവശ്യത്തിന് ഊഷ്മളമായി സംസാരിക്കുന്നുണ്ടോ എന്ന് ഉത്കണ്ഠപ്പെടാനും ശ്രമിക്കുന്നു. അത് വെറുമൊരു ശ്രദ്ധതിരിക്കലാണ്. ഒരു AI ഏജന്റ് യഥാർത്ഥ ഉപയോക്താക്കൾക്ക് യഥാർത്ഥ ഇമെയിലുകൾ അയക്കാൻ തുടങ്ങുമ്പോൾ, "Best regards"-ന് പകരം "Cheers" എന്ന് എഴുതുന്നു എന്നതല്ല അപകടം. ഏജന്റിന്റെ തീരുമാനത്തിനും സന്ദേശം ഇൻബോക്സിൽ എത്തുന്നതിനും ഇടയിൽ കൃത്യമായി എന്താണ് സംഭവിച്ചത് എന്ന് നിങ്ങൾക്ക് ഉറപ്പിച്ചു പറയാൻ കഴിയില്ല എന്നതാണ് യഥാർത്ഥ അപകടം. ഞാൻ ആദ്യം നോക്കുന്നത് അതിൻ്റെ അതിർവരമ്പുകളിലാണ് (boundary). അവിടെയാണ് പ്രൊഡക്ഷൻ സിസ്റ്റങ്ങൾ നിശബ്ദമായി പരാജയപ്പെടുന്നത്.

കരാറാണ് (Contract) ബലഹീനത

AI ഡെമോകൾ തെറ്റുകൾ ക്ഷമിക്കുന്നവയാണ്. ഒരു ബ്രൗസർ വിൻഡോയിലെ സുഗമമായ സംഭാഷണം അനേകം അനുമാനങ്ങളുടെ (assumptions) കുഴപ്പങ്ങൾ മറച്ചുവെക്കുന്നു. പ്രൊഡക്ഷനിൽ, യഥാർത്ഥ ബലഹീനത നിലനിൽക്കുന്നത് മൂന്ന് കാര്യങ്ങൾ തമ്മിലുള്ള കരാറിലാണ് (contract): ഏജന്റിന്റെ തീരുമാനം, ആ പ്രവൃത്തി നടപ്പിലാക്കുന്ന ടൂൾ, ഫലം പരിശോധിക്കുന്ന ഘട്ടം. ആ അതിർവരമ്പ് അവ്യക്തമാണെങ്കിൽ, സിസ്റ്റം മികച്ച രീതിയിൽ പ്രവർത്തിച്ചുകൊണ്ടിരിക്കും, പക്ഷേ എപ്പോഴെങ്കിലും അത് പരാജയപ്പെടും. അപ്പോൾ അത് നിശബ്ദമായി പരാജയപ്പെടുകയോ, മുഴുവൻ ഉപഭോക്താക്കൾക്കും ഒരേ സന്ദേശം വീണ്ടും വീണ്ടും അയക്കുകയോ, അല്ലെങ്കിൽ എന്തുകൊണ്ട് എന്ന് വ്യക്തമായ രേഖയില്ലാതെ തെറ്റായ സമയത്ത് സന്ദേശങ്ങൾ അയക്കുകയോ ചെയ്തേക്കാം. പ്രോംപ്റ്റ് ഒരു കവിത പോലെ മനോഹരമായിരിക്കാം. എന്നാൽ അതിനു താഴെയുള്ള ആർക്കിടെക്ചർ (architecture) ഇപ്പോഴും വളരെ ദുർബലമായിരിക്കാം.

ഏജന്റിനെ സ്വതന്ത്രമായി എഴുതാൻ അനുവദിക്കുന്നത് നിർത്തുക

ഏജന്റിന് ഒരു ശൂന്യമായ പേജ് നൽകുക എന്നതാണ് ഏറ്റവും സാധാരണമായ തെറ്റ്. ഒരു ഇമെയിൽ പച്ചരൂപത്തിൽ (raw text) വിവരിക്കാൻ ടീമുകൾ ഏജന്റിനെ അനുവദിക്കുകയും, പിന്നീട് ആ വിവരണത്തിൽ നിന്ന് ഉദ്ദേശ്യം (intent) മനസ്സിലാക്കാൻ ഒരു ഡൗൺസ്ട്രീം ടൂളിനെ വിശ്വസിക്കുകയും ചെയ്യുന്നു. അത് വളരെ ദുർബലമായ രീതിയാണ്. ഒരു LLM യുക്തമായ ഒരു ഉദ്ദേശ്യം നിർദ്ദേശിച്ചേക്കാം, പക്ഷേ നിങ്ങളുടെ ഇൻഫ്രാസ്ട്രക്ചറിന് (infrastructure) സർഗ്ഗാത്മകതയല്ല വേണ്ടത്. അതിന് ഒരു കരാർ (contract) ആണ് വേണ്ടത്. ഒരു മെഷീന് അവ്യക്തതയില്ലാതെ പരിശോധിക്കാൻ കഴിയുന്ന പ്രത്യേക ഫീൽഡുകൾ അതിന് ആവശ്യമാണ്.

ഒരു ഏജന്റ് ഇമെയിൽ അഭ്യർത്ഥന പുറപ്പെടുവിക്കുമ്പോൾ, സിസ്റ്റത്തിന്റെ പ്രവർത്തനത്തിന് (plumbing) കൃത്യമായി എന്താണോ വേണ്ടത് അത് അതിൽ ഉണ്ടായിരിക്കണം:

  • Template version: ഇമെയിൽ ബോഡിയുടെ ഏത് പതിപ്പാണ് ഉപയോഗിക്കുന്നത് എന്ന് അറിയാൻ ഇത് സഹായിക്കുന്നു, അങ്ങനെ ഉപയോക്താവ് എന്താണ് കണ്ടതെന്ന് നിങ്ങൾക്ക് മനസ്സിലാക്കാം.
  • Recipient scope: ഇത് ആർക്കൊക്കെ ലഭിക്കണം എന്നത് ഉപയോക്താക്കളുടെ ID അല്ലെങ്കിൽ സെഗ്മെന്റ് നിയമങ്ങൾ വഴി നിർവചിക്കണം, "ഇപ്പോൾ സൈൻ അപ്പ് ചെയ്ത ഉപയോക്താവ്" എന്നതുപോലെയുള്ള സ്വാഭാവിക ഭാഷയിലൂടെയല്ല.
  • Trace ID: ഏജന്റിൽ തുടങ്ങി എക്സിക്യൂട്ടർ (executor), ഇമെയിൽ പ്രൊവൈഡർ എന്നിവർ വഴി ലോഗുകളിൽ എത്തുന്നതുവരെയുള്ള ഈ അഭ്യർത്ഥനയെ പിന്തുടരാൻ സഹായിക്കുന്ന ഒരു തനതായ ഐഡന്റിഫയർ.
  • Time window: ഈ സന്ദേശം അയക്കാൻ അനുമതിയുള്ള സമയം, അങ്ങനെ പഴയ ഏജന്റ് തീരുമാനങ്ങൾ മണിക്കൂറുകൾക്ക് ശേഷം പാതിരാത്രിയിൽ ഇമെയിലുകൾ അയക്കുന്നത് ഒഴിവാക്കാം.
  • Idempotency: ഏജന്റ് വീണ്ടും ശ്രമിക്കുകയോ നെറ്റ്‌വർക്ക് തകരാറുകൾ സംഭവിക്കുകയോ ചെയ്താൽ ഒരേ സന്ദേശം തന്നെ രണ്ടുതവണ അയക്കുന്നത് തടയുന്ന ഒരു കീ (key).

പച്ചരൂപത്തിലുള്ള ടെക്സ്റ്റ് (Raw text) ഒരു മോശം API ആണ്. അത് അടിയന്തിരതയെക്കുറിച്ചും (urgency), പ്രേക്ഷകരെക്കുറിച്ചും (audience), പ്രവൃത്തിയെക്കുറിച്ചും (action) അവ്യക്തതകൾ ഉണ്ടാക്കുന്നു. പ്രത്യേക ഫീൽഡുകൾ മെഷീൻ റീഡബിൾ (machine-readable), ഓഡിറ്റ് ചെയ്യാവുന്നതും, പരിശോധിക്കാവുന്നതുമാണ്. അവ അവ്യക്തമായ നിർദ്ദേശങ്ങളെ പരിശോധിക്കാവുന്ന കമാൻഡുകളാക്കി മാറ്റുന്നു.

ഗദ്യമല്ല, പ്രവൃത്തികളാണ് പ്രധാനം

ഏജന്റിന് എഴുതാനുള്ള ഒരു തുറന്ന ചുമതല നൽകുന്നതിന് പകരം, അനുവദനീയമായ പ്രവൃത്തികളുടെ ഒരു മെനുവിൽ അതിനെ പരിമിതപ്പെടുത്തുക. ഒരു നിശ്ചിത enum ഉള്ള ഇന്റേണൽ API പോലെ ഇതിനെ കരുതുക. ഏജന്റ് ഒരു സബ്ജക്ട് ലൈൻ തയ്യാറാക്കുകയോ അഭിവാദ്യങ്ങളെക്കുറിച്ച് ചിന്തിക്കുകയോ ചെയ്യുന്നില്ല. പകരം send_review_request അല്ലെങ്കിൽ send_retry_notice പോലുള്ള ഒരു പ്രവൃത്തി തിരഞ്ഞെടുക്കുന്നു. അതിന്റെ സർഗ്ഗാത്മക സ്വാതന്ത്ര്യം അത്രമാത്രമേയുള്ളൂ.

ഒരു ഡെറ്റർമിനിസ്റ്റിക് എക്സിക്യൂട്ടർ (deterministic executor) ആ ആക്ഷൻ കീ എടുക്കുന്നു, വെർഷൻ കൺട്രോളിൽ നിന്ന് ശരിയായ ടെംപ്ലേറ്റ് എടുക്കുന്നു, അത് ശുദ്ധീകരിച്ച ഡാറ്റ ഉപയോഗിച്ച് പൂരിപ്പിക്കുന്നു, വെരിഫൈ ചെയ്ത സ്രോതസ്സിൽ നിന്ന് സ്വീകർത്താക്കളുടെ പട്ടിക പൂരിപ്പിക്കുന്നു, കൂടാതെ അവസാന കമാൻഡ് നിർമ്മിക്കുന്നു. എന്ത് സംഭവിക്കണം എന്ന് ഏജന്റ് തീരുമാനിക്കുന്നു. അത് എങ്ങനെ സംഭവിക്കണം എന്ന് ബോറടിപ്പിക്കുന്നതും പ്രവചിക്കാവുന്നതുമായ കോഡ് തീരുമാനിക്കുന്നു.

ഈ വേർതിരിക്കൽ സിസ്റ്റത്തെ പരിശോധിക്കാൻ എളുപ്പമാക്കുന്നു. ഒരു LLM ഇൻഫറൻസ് (inference) പോലും പ്രവർത്തിപ്പിക്കാതെ തന്നെ, ഒരു പ്രത്യേക ഇൻപുട്ട് send_retry_notice എന്നതിനെ വിശ്വസ്തതയോടെ ട്രിഗർ ചെയ്യുന്നുണ്ടോ എന്ന് നിങ്ങൾക്ക് പരിശോധിക്കാം. നിങ്ങളുടെ യൂണിറ്റ് ടെസ്റ്റുകൾ (unit tests) വേഗതയേറിയതും കൃത്യവുമാകും, കാരണം അവ മോഡൽ ടെമ്പറേച്ചറിനെക്കുറിച്ചല്ല (model temperature), മറിച്ച് മാപ്പിംഗ് ലോജിക്കിനെക്കുറിച്ചാണ് പരിശോധിക്കുന്നത്. നിങ്ങളുടെ ഇന്റഗ്രേഷൻ ടെസ്റ്റുകൾ (integration tests) മോഡൽ നല്ലൊരു ദിവസത്തിലായിരുന്നോ എന്നല്ല, മറിച്ച് എക്സിക്യൂട്ടർ ആക്ഷനെ ഇമെയിൽ സർവീസിലേക്ക് ശരിയായി മാപ്പ് ചെയ്യുന്നുണ്ടോ എന്നതിലാണ് ശ്രദ്ധ കേന്ദ്രീകരിക്കുന്നത്.

അഞ്ച് പാളികളിലായി നിർമ്മിക്കുക

ഒരു ശക്തമായ സിസ്റ്റം ഒരു ഒറ്റ പ്രോംപ്റ്റിൽ നിന്ന് ഉണ്ടാകുന്നതല്ല. അത് പാളികളായിട്ടാണ് നിർമ്മിക്കുന്നത്, ഓരോ പാളിയും ഒരു വ്യക്തമായ ഉത്തരവാദിത്തം നിർവ്വഹിക്കുന്നു.

1. ബാക്കെൻഡ് (backend) ഇവന്റിനെ സുരക്ഷിതമായ ഡാറ്റയായി കുറയ്ക്കുന്നു.
ട്രിഗർ ഒരു വെബ്ഹുക്ക് (webhook), ഡാറ്റാബേസ് മാറ്റം, അല്ലെങ്കിൽ ഒരു ഷെഡ്യൂൾ ചെയ്ത ജോബ് എന്നിവയായാലും, ഈ പാളി ഇൻപുട്ടുകൾ ശുദ്ധീകരിക്കുന്നു (sanitizes), അപ്രതീക്ഷിത ഫീൽഡുകൾ നീക്കം ചെയ്യുന്നു, കൂടാതെ ഏജന്റിന് ആവശ്യമുള്ളത് മാത്രം നൽകുന്നു. ഒരു വെബ്ഹുക്ക് പേലോഡിൽ (payload) ഇരുപത് ഫീൽഡുകൾ ഉണ്ടെങ്കിലും ഏജന്റിന് രണ്ട് ഫീൽഡുകൾ മാത്രമേ ആവശ്യമുള്ളൂ എങ്കിൽ, ആ രണ്ട് ഫീൽഡുകൾ മാത്രം നൽകുക. പരിശോധിക്കപ്പെടാത്ത ഒരു പച്ച യൂസർ ടെക്സ്റ്റും (raw user text) ഡിസിഷൻ ലെയറിൽ (decision layer) എത്താൻ പാടില്ല.

2. ഏജന്റ് നിശ്ചിത സ്കീമയിൽ (schema) നിന്ന് ഒരു പ്രവൃത്തി തിരഞ്ഞെടുക്കുന്നു.
അത് സാഹചര്യം (context) മനസ്സിലാക്കുന്നു, ഒരു തീരുമാനം എടുക്കുന്നു, കൂടാതെ ആവശ്യമായ മെറ്റാഡാറ്റയോടൊപ്പം (metadata) മുൻകൂട്ടി നിശ്ചയിച്ച ആക്ഷൻ കീകളിൽ ഒന്ന് ഔട്ട്പുട്ട് ആയി നൽകുന്നു. അത് ഗദ്യം എഴുതുന്നില്ല. അത് സ്വീകർത്താക്കളെ ഊഹിക്കുന്നില്ല. അടുത്ത പാളിക്ക് ഒരു JSON സ്കീമയ്‌ക്കെതിരെ പരിശോധിക്കാൻ കഴിയുന്ന ഒരു സ്ട്രക്ചേർഡ് പേലോഡ് (structured payload) അത് തിരികെ നൽകുന്നു.

3. The tool validates permissions and required fields.
Does this agent context have the right to trigger send_review_request for this user? Is the recipient scope non-empty and within allowed limits? Is the idempotency key present and unique in your log? Is the trace ID well-formed? Fail here, loudly, before any email service is ever touched.

4. The email service logs the send with a trace ID.
Every message that leaves your system should carry that trace identifier through the provider's API and into your observability stack. If a user complains they received two copies, you should be able to query one ID and see exactly where the duplication originated: a retried agent call, a flaky executor, or a misbehaving callback.

5. The end-to-end test checks the actual inbox for content and effect.
Open the rendered message in a real mailbox. Is the subject line populated correctly? Does the unsubscribe link resolve? Does clicking the primary call-to-action button land on the correct page with the correct user state? A passing unit test means the code ran. Only an inbox test tells you the email actually works for a human.

Evidence Over Guessing

When a test fails in this pipeline, you need four specific pieces of evidence. Accept nothing less.

  1. The original decision from the agent. What action did it choose, and what was the full input context?
  2. The normalized command from the tool. What did the deterministic executor build after applying the template, hydration logic, and validation rules?
  3. The message in the isolated inbox. Not a log of what you think you sent, but the real MIME message, headers and all, captured in a dedicated test mailbox.
  4. The final effect after clicking the link. The resulting page state, database change, or external event that proves the email achieved its purpose.

If one piece is missing, your team will fill the gap with assumptions. They will guess. Guessing in automation is expensive. It burns hours, erodes trust, and turns every incident into a forensic mystery instead of a