വർഷങ്ങളായി, ആർട്ടിഫിഷ്യൽ ഇന്റലിജൻസ് എഡിറ്ററിൽ നിങ്ങളുടെ കൂടെയിരുന്ന് അടുത്തതായി എന്താണ് വരാൻ പോകുന്നത് എന്ന് ഊഹിക്കുമായിരുന്നു. നിങ്ങൾ ഒരു വരി എഴുതിയാൽ, അത് അടുത്ത വരി നിർദ്ദേശിക്കും. ആർക്കിടെക്ചർ, ഡിബഗ്ഗിംഗ്, സിന്റാക്സ് എന്നിവയുടെ നിയന്ത്രണം ഇപ്പോഴും നിങ്ങളുടെ കൈകളിലായിരുന്നു. ആ രീതി അവസാനിച്ചിരിക്കുന്നു.
നമ്മൾ Intent-Driven Development-ലേക്ക് മാറിക്കൊണ്ടിരിക്കുകയാണ്. നിങ്ങൾ ലൂപ്പുകളും (loops) കണ്ടീഷനലുകളും (conditionals) ടൈപ്പ് ചെയ്യുന്നത് നിർത്തുന്നു. പകരം, നിങ്ങൾക്ക് ആവശ്യമുള്ള ഫലം നിങ്ങൾ വിവരിക്കുന്നു. ഒരു ഏജന്റ് ആ ലക്ഷ്യം ഉൾക്കൊള്ളുകയും, ഘട്ടങ്ങൾ ആസൂത്രണം ചെയ്യുകയും, കോഡ് എഴുതുകയും, ടെസ്റ്റുകൾ പ്രവർത്തിപ്പിക്കുകയും, ഫലം കാണുന്നതിന് മുമ്പ് തന്നെ അതിന്റെ പിശകുകൾ പരിഹരിക്കുകയും ചെയ്യുന്നു. കീബോർഡ് ഇനി പ്രാഥമിക ഉപകരണമല്ല. വ്യക്തമായ ചിന്താഗതിയാണ് പ്രധാനം.
വരിവരിയായി കോഡിംഗ് ചെയ്യുന്നതിന്റെ അന്ത്യം
പഴയ രീതിയിൽ, നിങ്ങളുടെ ഓരോ ഉദ്ദേശ്യത്തെയും ഒരു കമ്പൈലറിന് (compiler) മനസ്സിലാകുന്ന ഒരു പ്രത്യേക ഭാഷയിലേക്ക് മാറ്റാൻ നിങ്ങൾ നിർബന്ധിതരായിരുന്നു. ബിസിനസ്സ് ആവശ്യകതകൾ നിങ്ങളുടെ മനസ്സിലുണ്ടായിരുന്നെങ്കിൽ, നിങ്ങൾ അവയെ ഫംഗ്ഷനുകളായും (functions), ഇംപോർട്ടുകളായും (imports), എറർ ഹാൻഡ്ലിംഗായും (error handling), ടെസ്റ്റ് കേസുകളായും (test cases) നേരിട്ട് വിഭജിക്കണമായിരുന്നു. Intent-Driven Development ആ പരിഭാഷാ ഘട്ടത്തെ ഇല്ലാതാക്കുന്നു.
ഉദാഹരണത്തിന്, നിങ്ങൾക്ക് ഒരു പേയ്മെന്റ് വെബ്ഹുക്ക് (payment webhook) ഇന്റഗ്രേറ്റ് ചെയ്യണമെന്നുണ്ടെന്ന് കരുതുക. മുമ്പ്, നിങ്ങൾ റൂട്ട് ഹാൻഡ്ലർ (route handler) എഴുതുകയും, പേലോഡ് പാഴ്സ് (parse the payload) ചെയ്യുകയും, സിഗ്നേച്ചർ പരിശോധിക്കുകയും (validate the signature), ഒരു ട്രാൻസാക്ഷനുള്ളിൽ ഡാറ്റാബേസ് അപ്ഡേറ്റ് ചെയ്യുകയും, ഒരു രസീത് ഇമെയിൽ ക്യൂ ചെയ്യുകയും ചെയ്യുമായിരുന്നു. ഇപ്പോൾ നിങ്ങൾ ആവശ്യം വിവരിക്കുന്നു: “വരുന്ന Stripe webhook പരിശോധിക്കുക, ഇവന്റ് ഐഡെംപോഡന്റായി (idempotently) രേഖപ്പെടുത്തുക, രസീത് പ്രക്രിയ ആരംഭിക്കുക. ഡാറ്റാബേസ് എഴുതുന്നതിൽ പരാജയപ്പെട്ടാൽ റോളുകൾ ബാക്ക് (Roll back) ചെയ്യുക.” ഏജന്റ് ഹാൻഡ്ലർ എഴുതുന്നു, പാഴ്സിംഗ് സ്ട്രാറ്റജി തിരഞ്ഞെടുക്കുന്നു, റീട്രൈ ലോജിക് (retry logic) ക്രമീകരിക്കുന്നു, കൂടാതെ ടെസ്റ്റുകൾ തയ്യാറാക്കുന്നു. നിങ്ങളുടെ പങ്ക് ഒരു എഴുത്തുകാരനിൽ നിന്ന് ഒരു സംവിധായകനിലേക്കുള്ള മാറ്റമാണ്.
ഏജന്റ് കോഡ് നിർമ്മിക്കുന്നതിൽ മാത്രം ഒതുങ്ങുന്നില്ല എന്നതുകൊണ്ടാണ് ഇത് പ്രവർത്തിക്കുന്നത്. അത് ഒരു ലൂപ്പിലേക്ക് പ്രവേശിക്കുന്നു.
ഏജന്റ് ലൂപ്പിനുള്ളിൽ
പ്രധാന ജോലി ഇനി മനുഷ്യർ ടൈപ്പ് ചെയ്യുന്നതോ മാനുവൽ ഡിബഗ്ഗിംഗോ അല്ല. അത് നിർമ്മാണവും (generation) പരിശോധനയും (validation) തമ്മിലുള്ള ഒരു കൃത്യമായ ചക്രമാണ്. ഏജന്റ് കോഡ് നിർമ്മിക്കുന്നു, നിങ്ങളുടെ ടെസ്റ്റ് സ്യൂട്ടിന് (test suite) അനുസരിച്ച് അത് പ്രവർത്തിപ്പിക്കുന്നു, ഔട്ട്പുട്ട് വായിക്കുന്നു, കൂടാതെ പരാജയങ്ങൾ സ്വയം പരിഹരിക്കുന്നു. ഒരു മിസ്സിംഗ് ഇംപോർട്ട്, ടൈപ്പ് മിസ്മാച്ച്, പരാജയപ്പെട്ട അസർഷൻ (assertion) എന്നിവ ഉണ്ടെങ്കിൽ — ഏജന്റ് സ്റ്റാക്ക് ട്രാസ് (stack trace) കണ്ട് ഫയൽ എഡിറ്റ് ചെയ്യുകയും സ്യൂട്ട് വീണ്ടും പ്രവർത്തിപ്പിക്കുകയും ചെയ്യുന്നു. നിങ്ങൾ ആ ലൂപ്പിലല്ല. ആ ചക്രം മെഷീന്റെ വേഗതയിലാണ് നടക്കുന്നത്.
ആ ലൂപ്പ് തകരാറിലാകുമ്പോഴാണ് നിങ്ങൾ ഇടപെടുന്നത്. ഒരുപക്ഷേ രണ്ട് ഡിപ്പൻഡൻസികൾ (dependencies) തമ്മിലുള്ള സംഘർഷം പരിഹരിക്കാൻ ഏജന്റിന് കഴിഞ്ഞെന്നു വരില്ല, അല്ലെങ്കിൽ യൂണിറ്റ് ടെസ്റ്റുകൾ വിജയിക്കുന്നതും എന്നാൽ ഉയർന്ന തലത്തിലുള്ള ബിസിനസ്സ് നിയമങ്ങൾ ലംഘിക്കുന്നതുമായ കോഡ് അത് നിർമ്മിച്ചേക്കാം. മനുഷ്യന്റെ വിവേചനാധികാരം ഇപ്പോഴും പ്രസക്തമാകുന്ന ഇടങ്ങളാണിവ.
നിങ്ങളുടെ യഥാർത്ഥ ജോലി: Constraint Designer and Edge-Case Hunter
മെഷീൻ ഫംഗ്ഷനുകൾ എഴുതുകയാണെങ്കിൽ, നിങ്ങൾക്ക് എന്ത് ബാക്കിയുണ്ട്? രണ്ട് കാര്യങ്ങൾ, അവ സിന്റാക്സ് ടൈപ്പ് ചെയ്യുന്നതിനേക്കാൾ കഠിനമാണ്.
ഒന്നാമതായി, ഏജന്റിനെ ശരിയായ പാതയിൽ നിലനിർത്തുന്ന കൺസ്ട്രയിന്റുകൾ (constraints) നിങ്ങൾ എഴുതുന്നു. ഏജന്റിന് വിപുലമായ അറിവുണ്ടെങ്കിലും നിങ്ങളുടെ പ്രത്യേക സാഹചര്യത്തെക്കുറിച്ച് (environment) ധാരണയില്ല. നിങ്ങൾ അതിനോട് പറയണം: “ആന്തരിക ബില്ലിംഗ് API മാത്രം ഉപയോഗിക്കുക, ഒരിക്കലും കാർഡ് ടോക്കണുകൾ ലോഗ് ചെയ്യരുത്, കൂടാതെ റെസ്പോൺസ് ലാറ്റൻസി (response latency) ഇരുന്നൂറ് മില്ലിസെക്കൻഡിൽ താഴെയായി നിലനിർത്തുക.” ഈ അതിർവരമ്പുകൾ വെറും പ്രോംപ്റ്റുകൾ മാത്രമല്ല. അവ വിജയവും പരാജയവും നിർണ്ണയിക്കുന്ന സ്പെസിഫിക്കേഷനുകളാണ് (specifications).
രണ്ടാമതായി, ഏജന്റ് പരാജയപ്പെടുന്ന പത്ത് ശതമാനം കേസുകൾ നിങ്ങൾ കണ്ടെത്തുന്നു. സാധാരണ സാഹചര്യങ്ങൾ ഏജന്റുകൾ നന്നായി കൈകാര്യം ചെയ്യുന്നു. എന്നാൽ സൂക്ഷ്മമായ റേസ് കണ്ടീഷനുകൾ (race conditions), അവ്യക്തമായ ബിസിനസ് ലോജിക് എഡ്ജ് കേസുകൾ (edge cases), അവയുടെ ട്രെയിനിംഗ് ഡാറ്റയിൽ അടങ്ങിയിരിക്കുന്ന സുരക്ഷാ അനുമാനങ്ങൾ എന്നിവയിൽ അവ തടസ്സപ്പെടുന്നു. വെബ്ഹുക്ക് ഹാൻഡ്ലറും റീഫണ്ട് ക്രോൺ ജോബും (refund cron job) തമ്മിലുള്ള മത്സരമോ, അല്ലെങ്കിൽ നിർമ്മിച്ച റീട്രൈ ലോജിക് ചാർജുകൾ ഇരട്ടിപ്പിക്കാൻ സാധ്യതയുണ്ടെന്നോ തിരിച്ചറിയുന്നതിലൂടെയാണ് നിങ്ങളുടെ മികവ് തെളിയുന്നത്. മെഷീൻ സാധാരണ പ്രശ്നങ്ങൾ പരിഹരിക്കുന്നു. നിങ്ങൾ അപകടകരമായ അപവാദങ്ങൾ (exceptions) കണ്ടെത്തുന്നു.
കോഡ് റിവ്യൂവിന് പകരം ഒരു വെരിഫിക്കേഷൻ ഹാർനെസ്സ് ഉപയോഗിക്കുക
ഒരു ഏജന്റിന് ഒറ്റരാത്രികൊണ്ട് അമ്പത് ഫയലുകൾ നിർമ്മിക്കാൻ കഴിയുമ്പോൾ, അവ "ശരിയാണോ" എന്ന് നോക്കാൻ വെറുതെ ഒന്ന് കണ്ണോടിച്ചു നോക്കിയാൽ മാത്രം പോരാ. അത്രയും വലിയ അളവിൽ അവ പരിശോധിക്കുന്നത് മനുഷ്യർക്ക് അസാധ്യമാണ്. കോഡ് നിങ്ങളുടെ അടുത്തെത്തുന്നതിന് മുമ്പ് പിശകുകൾ കണ്ടെത്തുന്ന ഒരു ഹാർനെസ്സ് (harness) നിങ്ങൾക്ക് ആവശ്യമാണ്.
ഈ ഹാർനെസ്സ് മൂന്ന് തൂണുകളിൽ അധിഷ്ഠിതമാണ്.
ഡ്യൂറബിൾ എക്സിക്യൂഷൻ (Durable execution). ഏജന്റ് ടാസ്ക്കുകൾ പലപ്പോഴും ഒരു സിംഗിൾ റിക്വസ്റ്റ് ടൈമൗട്ടിനേക്കാൾ കൂടുതൽ സമയം എടുക്കാറുണ്ട്. താൽക്കാലികമായ നെറ്റ്വർക്ക് തകരാർ കാരണം ഒരു ഘട്ടം പരാജയപ്പെട്ടാൽ, ഹാർനെസ്സ് അത് നിർത്തിവെക്കുകയും, വീണ്ടും ശ്രമിക്കുകയും, സ്റ്റേറ്റ് (state) നശിപ്പിക്കാതെ തന്നെ പുനരാരംഭിക്കുകയും ചെയ്യുന്നു. തടസ്സങ്ങൾക്കിടയിലും ജോലി പൂർത്തിയാകുന്നു.
സ്ട്രക്ചേർഡ് ഔട്ട്പുട്ടുകൾ (Structured outputs). ഏജന്റ് കൃത്യമായ ഒരു കോൺഫിഗറേഷൻ ഫയൽ നൽകുമെന്ന് പ്രതീക്ഷിക്കുന്നതിന് പകരം, നിങ്ങൾ മുൻകൂട്ടി നിബന്ധനകൾ നിശ്ചയിക്കുന്നു. JSON Schema പോലുള്ള ടൂളുകൾ ഔട്ട്പുട്ട് ഉടൻ തന്നെ പരിശോധിക്കുന്നു. ഏജന്റ് ഒരു ആവശ്യമായ ഫീൽഡ് വിട്ടുപോവുകയോ തെറ്റായ ഡാറ്റാ ടൈപ്പ് ഉപയോഗിക്കുകയോ ചെയ്താൽ, കോഡ് നിങ്ങളുടെ റെപ്പോസിറ്ററിയിൽ (repository) എത്തുന്നതിന് മുമ്പ് തന്നെ ഹാർനെസ്സ് അത് നിരസിക്കുന്നു.
ഡൈനാമിക് ഗാർഡ്റെയിലുകൾ (Dynamic guardrails). രഹസ്യ വിവരങ്ങൾ (secrets) വായിക്കാനോ പ്രൊഡക്ഷൻ ഡാറ്റാബേസുകളിൽ എഴുതാനോ ഏജന്റിന് സ്വതന്ത്രമായ അനുമതി ഉണ്ടാകരുത്. ഹാർനെസ്സ് പെർമിഷനുകൾ ഡൈനാമിക് ആയി നിയന്ത്രിക്കുന്നു, ഏജന്റിനെ ഒരു സാൻഡ്ബോക്സിൽ (sandbox) പരിമിതപ്പെടുത്തുന്നു, അങ്ങനെ അതിന് നിശ്ചിത ടെസ്റ്റ് ഡാറ്റാബേസുകളിലും ഇന്റേണൽ എൻഡ്പോയിന്റുകളിലും (internal endpoints) മാത്രമേ ഇടപെടാൻ കഴിയൂ. നിങ്ങൾ ഓരോ വരിയും പരിശോധിക്കുകയല്ല. ഏജന്റിന് ചുറ്റുമുള്ള വേലിയെയാണ് നിങ്ങൾ ഓഡിറ്റ് ചെയ്യുന്നത്.
കോഡ് പ്രവർത്തിക്കുന്നുണ്ടെങ്കിലും ഉൽപ്പന്നം പരാജയപ്പെടുമ്പോൾ
ഇതാണ് വൈരുദ്ധ്യം. ടെസ്റ്റിംഗ് ഹാർനസ്സ് (harness) മോശം കോഡിനെ കണ്ടെത്തുന്നു. എന്നാൽ മോശം ഉദ്ദേശ്യങ്ങളെ (intent) കണ്ടെത്താൻ അതിന് കഴിയില്ല.
നിങ്ങളുടെ സ്പെസിഫിക്കേഷൻ (specification) "എല്ലാ പുതിയ ഉപയോക്താക്കൾക്കും ഒരു വെൽക്കം ഇമെയിൽ അയക്കുക" എന്ന് പറയുകയാണെങ്കിൽ, ആ ഇമെയിൽ അയക്കുന്നതിനായി ഏജന്റ് വൃത്തിയുള്ളതും പരിശോധിക്കപ്പെട്ടതുമായ കോഡ് എഴുതും. എന്നാൽ നിങ്ങളുടെ യഥാർത്ഥ ഉദ്ദേശ്യം, "ഉപയോക്താവ് അവരുടെ വിലാസം പരിശോധിക്കുകയും, മാർക്കറ്റിംഗിനായി സമ്മതം നൽകുകയും, അവരുടെ പ്രാദേശിക സമയക്രമത്തിലെ ബിസിനസ്സ് സമയത്ത് സൈൻ അപ്പ് ചെയ്യുകയും ചെയ്താൽ മാത്രം വെൽക്കം ഇമെയിൽ അയക്കുക" എന്നതാണെന്ന് ഏജന്റിന് മനസ്സിലാകില്ല. ആ കോഡ് സാങ്കേതികമായി കുറ്റമറ്റതാകാം, എന്നാൽ വാണിജ്യപരമായി അപകടകരവുമാണ്.
Intent-Driven Development-ലെ യഥാർത്ഥ അപകടം അവ്യക്തമായ സ്പെസിഫിക്കേഷനുകളാണ്. വ്യക്തമല്ലാത്ത ഉദ്ദേശ്യങ്ങൾ തെറ്റായ പ്രശ്നങ്ങൾക്ക് പാഠപുസ്തകത്തിലെപ്പോലെ മനോഹരമായ പരിഹാരം നൽകുന്ന സോഫ്റ്റ്വെയറുകൾ നിർമ്മിക്കുന്നു. അതുകൊണ്ടാണ് നിങ്ങളുടെ സ്പെസിഫിക്കേഷനുകളെ യഥാർത്ഥ ആസ്തികളായി (assets) നിങ്ങൾ കാണേണ്ടത്. അവയ്ക്ക് വേർഷനുകൾ നൽകുക. സ്റ്റേക്ക്ഹോൾഡർമാരുമായി (stakeholders) ചേർന്ന് അവ അവലോകനം ചെയ്യുക. ഏജന്റ് നിർമ്മാണം തുടങ്ങുന്നതിന് മുമ്പ് യഥാർത്ഥ വർക്ക്ഫ്ലോകൾ (workflows) ഉപയോഗിച്ച് അവ ശരിയാണെന്ന് ഉറപ്പുവരുത്തുക. ഒരു ചാറ്റ് ബോക്സിൽ എഴുതുന്ന പ്രോംപ്റ്റ് (prompt) ഒരു സ്പെസിഫിക്കേഷൻ അല്ല. അതൊരു ബാധ്യതയാണ്.
എഞ്ചിനീയറിംഗ് വിധിനിർണ്ണയം ഉയർന്ന തലങ്ങളിലേക്ക് മാറുന്നു
എഞ്ചിനീയറിംഗ് വിധിനിർണ്ണയം (Engineering judgment) ഇല്ലാതാവുകയല്ല. അത് ഉയർന്ന തലങ്ങളിലേക്ക് മാറുകയാണ്.
ഒരു മാപ്പ് എങ്ങനെ ആവർത്തിക്കണം (iterate) എന്നതിലോ അല്ലെങ്കിൽ ഒരു ക്ലാസ് ഹൈരാർക്കി (class hierarchy) എങ്ങനെ ക്രമീകരിക്കണം എന്നതിലോ നിങ്ങൾ ഇനി മാനസിക ഊർജ്ജം ചെലവഴിക്കേണ്ടതില്ല. പകരം, പരാജയപ്പെടുമ്പോൾ സിസ്റ്റം എന്ത് ചെയ്യണം, ഏത് ഡാറ്റ ഒരിക്കലും പുറത്തുവിടരുത്, വിതരണം ചെയ്യപ്പെട്ട സേവനങ്ങളിൽ (distributed services) ഏതൊക്കെ നിയമങ്ങൾ (invariants) പാലിക്കപ്പെടണം എന്നിവയിലാണ് നിങ്ങൾ ശ്രദ്ധ കേന്ദ്രീകരിക്കേണ്ടത്. കോഡിംഗ് എന്ന കല, ആവശ്യകതകൾ (requirements) നിർണ്ണയിക്കുന്ന കലയായി മാറിക്കൊണ്ടിരിക്കുകയാണ്.
ഇതിനർത്ഥം, പണ്ട് നിങ്ങൾ കോഡിന് നൽകിയിരുന്ന അതേ കൃത്യത നിങ്ങളുടെ സ്പെസിഫിക്കേഷനുകൾക്കും ആവശ്യമാണ് എന്നാണ്. നിങ്ങളുടെ നിയന്ത്രണങ്ങൾ (constraints) കൃത്യമായി രേഖപ്പെടുത്തുക. പരാജയപ്പെടാൻ സാധ്യതയുള്ള രീതികൾ (failure modes) വ്യക്തമായി നിർവചിക്കുക. പണ്ട് നിങ്ങൾ ടൈപ്പുകൾ (types) പ്രഖ്യാപിച്ചിരുന്നതുപോലെ തന്നെ ബിസിനസ്സ് നിയമങ്ങളും വ്യക്തമായി പറയുക. ഏജന്റ് അതിന്റെ ഇംപ്ലിമെന്റേഷൻ (implementation) കൈകാര്യം ചെയ്യും. എന്നാൽ ആ ഇംപ്ലിമെന്റേഷൻ നിർമ്മിക്കാൻ യോഗ്യമാണെന്ന് നിങ്ങൾ ഉറപ്പാക്കണം.
നിങ്ങളുടെ ഗുണനിലവാരത്തിന്റെ മാനദണ്ഡം (quality bar) പുൾ റിക്വസ്റ്റിൽ (pull request) നിന്ന് പ്രോംപ്റ്റിലേക്ക് മാറ്റുക. ആദ്യം ഹാർനസ്സ് നിർമ്മിക്കുക. രണ്ടാമതായി സ്പെസിഫിക്കേഷൻ എഴുതുക. പ്രശ്നം ശരിയായി നിർവചിച്ചിട്ടുണ്ടോ എന്നും അതിരുകൾ സുരക്ഷിതമായി നിശ്ചയിച്ചിട്ടുണ്ടോ എന്നും പരിശോധിക്കുന്നതിൽ നിങ്ങൾ ശ്രദ്ധ കേന്ദ്രീകരിക്കുമ്പോൾ, സിന്റാക്സ് (syntax) കൈകാര്യം ചെയ്യാൻ മെഷീനെ അനുവദിക്കുക.
ഈ മാറ്റത്തിന് പിന്നിലെ ആശയങ്ങളെക്കുറിച്ച് കൂടുതൽ ആഴത്തിൽ അറിയാൻ, Intent-Driven Development-നെ കുറിച്ചുള്ള യഥാർത്ഥ ചർച്ച ഇവിടെ ലഭ്യമാണ്. AI-native എഞ്ചിനീയറിംഗുമായി ബന്ധപ്പെട്ട തുടർച്ചയായ സംഭാഷണങ്ങൾക്കായി നിങ്ങൾക്ക് GyaanSetu community-ൽ ചേരാം.
