படங்கள் நிறைந்த agent turns நினைவகத்துக்குள் வைத்திருத்தல்
Production-இல் ஒரு agent turn, ஆறு catalogue scans-இலிருந்து பொருட்களை வெட்டி அவற்றைப் பார்த்துக்கொண்டிருக்கும்போது 952 MB-இல் memory தீர்ந்தது. ஒரே ஒரு leak இல்லை — மூன்று இருந்தன. மாதிரியை அழைக்கும் ஒவ்வொரு முறையும் அந்த turn-இன் படங்கள் முழு அளவில் மீண்டும் அனுப்பப்பட்டன; மாதிரியை அழைக்கப் பயன்படுத்திய நூலகம் turn முடியும் வரை ஒவ்வொரு request-ஐயும் உயிருடன் வைத்திருந்தது; agent framework-இன் tracing ஒவ்வொரு அழைப்பின் உள்ளீடுகளையும், படங்களையும் சேர்த்து, turn முழுவதும் வைத்திருந்தது. மூன்றையும் சரிசெய்தோம்: அனுப்புவதற்கு முன் படங்கள் சுருக்கப்படுகின்றன, ஒவ்வொரு அழைப்பின் படங்களும் அந்த அழைப்பு முடிந்ததும் விடுவிக்கப்படுகின்றன.
Agent படங்களை எப்படிப் பார்க்கிறது
Mythex-இல் நீங்கள் கட்டும்போது, agent உங்கள் project-இன் cloud sandbox-க்குள் வேலை செய்கிறது. அது படங்களைப் பார்க்க முடியும் — நீங்கள் இணைத்த screenshot, ஒரு mockup, project-இல் உள்ள ஒரு கோப்பு, அல்லது அது இப்போதுதான் உருவாக்கிய ஒரு படம் — அவற்றை உரையாடலுடன் மாதிரிக்கு அனுப்புவதன் மூலம்.
ஒரு turn என்பது உங்கள் ஒரு message-க்கு agent செய்யும் அனைத்தும். ஒரு turn-க்குள், agent மாதிரியை பல முறை அழைக்கிறது: சிந்திக்கிறது, ஒரு கருவியை இயக்குகிறது, அதன் முடிவைப் பார்க்கிறது, மீண்டும் சிந்திக்கிறது. ஒவ்வொரு அழைப்பும் இதுவரை உள்ள உரையாடலை அனுப்புகிறது; அதில் அந்த turn-இன் படங்களும் அடங்கும், உரையாக குறியாக்கம் செய்யப்பட்டு (base64, அது சுமார் மூன்றில் ஒரு பங்கு பெரியதாக்கும்).
செயலிழந்த turn ஒரு நியாயமான வேலையைச் செய்துகொண்டிருந்தது. அது ஆறு catalogue scans-ஐ எடுத்தது, ஒவ்வொன்றும் சுமார் 2.4 MB, அவற்றிலிருந்து தனித்தனி பொருட்களை வெட்டியது, வெட்டியவற்றை சரிபார்க்க மீண்டும் மீண்டும் படித்தது. அது பல மாதிரி அழைப்புகள், ஒவ்வொன்றும் பல பெரிய படங்களைச் சுமந்துகொண்டிருந்தன.
காரணம் 1: ஒவ்வொரு அழைப்பும் முழு அளவிலான படங்களை மீண்டும் அனுப்பியது
ஒவ்வொரு மாதிரி அழைப்பும் அதன் request body-ஐ turn-இன் முழு அளவிலான படங்களுடன் மீண்டும் உருவாக்கியது — ஒரு அழைப்புக்கு சுமார் 20 MB base64. Body agent-இன் நினைவகத்தில் ஒரே string ஆக உருவாக்கப்படுவதால், ஒவ்வொரு அழைப்பும் மற்றொரு ~20 MB ஒதுக்கியது.
முழு அளவில் அனுப்புவதால் எந்தப் பயனும் இல்லை. மாதிரி படங்களை தானாகவே நீண்ட பக்கத்தில் சுமார் 1,300 pixels ஆகக் குறைக்கிறது; கூடுதல் pixels நினைவகத்தையும் upload நேரத்தையும் மட்டுமே வீணாக்கின.
தீர்வு: ஒரு முறை சுருக்கு, சிறியதாக அனுப்பு
- 400 KB-க்கு மேலுள்ள படங்கள் அனுப்புவதற்கு முன் நீண்ட பக்கத்தில் அதிகபட்சம் 1,568 pixels உள்ள JPEG ஆக மாற்றப்படுகின்றன. சிறிய படங்கள் அப்படியே செல்கின்றன.
- மாற்றம் ImageMagick பயன்படுத்துகிறது; அது ஒவ்வொரு Mythex sandbox-இலும் உள்ளது, ஒவ்வொரு கோப்புக்கும் ஒரு முறை மட்டும் இயங்குகிறது. ஒவ்வொரு அழைப்பிலும் அதே scans-ஐக் காட்டும் turn சுருக்கிய நகலை மீண்டும் பயன்படுத்துகிறது. அந்த cache கோப்பின் path, அளவு மற்றும் modification நேரத்தால் அடையாளம் காணப்படுகிறது; அதனால் திருத்தப்பட்ட கோப்பு மீண்டும் மாற்றப்படும். அதற்கும் அளவு வரம்பு உண்டு, அதனால் அதுவே நினைவகத்தை நிரப்பும் காரணியாக மாறாது.
- ஒரு மாதிரி அழைப்பில் படங்களுக்கான பட்ஜெட் 16 MB-இலிருந்து 6 MB-ஆகக் குறைகிறது.
அதே ஆறு scans இப்போது ஒரு அழைப்புக்கு 19.7 MB அல்ல, 4.4 MB செலவாகின்றன.
காரணம் 2: மாதிரி client ஒரு request-ஐ ஒருபோதும் விடுவிக்கவில்லை
ஒவ்வொரு request-இன் அளவு ஒரு பகுதி மட்டுமே. நினைவகமும் அழைப்புக்கு அழைப்பு வளர்ந்தது. எங்கள் staging சூழலில், அதே வகை turn ஒரு முழு garbage collection-க்குப் பிறகும் 369 MB நேரடி நினைவகத்தை வைத்திருந்தது — அதாவது அடையமுடியாத எல்லாம் விடுவிக்கப்பட்ட நிலை. Heap sampling அந்த வளர்ச்சி முழுவதும், மாதிரி client நூலகத்தின் request bodies-ஐ குறியாக்கம் செய்யும் பகுதியில் இருப்பதைக் காட்டியது.
காரணம் ஒரு abort listener. நீங்கள் Stop அழுத்தும்போது, turn-இன் abort signal இயங்குகிறது, அதைக் கேட்கும் ஒவ்வொரு request-உம் ரத்து செய்யப்படும். நாங்கள் அந்த ஒரே turn-அளவிலான signal-ஐ ஒவ்வொரு request-க்கும் அனுப்பினோம். மாதிரி நூலகம் கொடுக்கப்பட்ட signal-இல் ஒரு “abort” listener-ஐச் சேர்க்கிறது — ஆனால் அதை ஒருபோதும் அகற்றுவதில்லை.
அதனால் ஒரு turn-இன் ஒவ்வொரு request-உம், turn நீடிக்கும் வரை, turn-இன் signal-இலிருந்து அடையக்கூடியதாக இருந்தது: listener, அது request-இன் controller-ஐ வைத்திருந்தது, அது request-ஐ வைத்திருந்தது, அது படங்களுடன் முழு request body-ஐ வைத்திருந்தது.
தீர்வு: ஒவ்வொரு request-க்கும் ஒரு signal
ஒவ்வொரு request-க்கும் இப்போது அதன் சொந்த signal கிடைக்கிறது. அது request இயங்கும் நேரத்தில் மட்டும் turn-இன் signal-உடன் இணைக்கப்படுகிறது — streamed பதிலுக்கு, கடைசி chunk படிக்கப்படும் வரை — பின்னர் உடனே பிரிக்கப்படுகிறது. Stop இன்னும் நடக்கும் எந்த request-ஐயும் சென்றடைகிறது; ஆனால் turn-இன் signal ஒரு நேரத்தில் ஒரே ஒரு listener-ஐ மட்டுமே வைத்திருக்கிறது.
சோதனைகள் மூன்று பகுதிகளையும் உள்ளடக்குகின்றன:
- 12 அழைப்புகளுக்குப் பிறகு, turn-இன் signal-இல் listeners எதுவும் இல்லை. சரிசெய்வதற்கு முன் 12 இருந்தன.
- தலா 8 MB உள்ள 15 requests-க்கு மேல் நினைவகம் நிலையாக இருக்கிறது. முன்பு அது 128 MB வளர்ந்தது.
- Stream நடுவில் இருக்கும் request-ஐ Stop இன்னும் ரத்து செய்கிறது.
காரணம் 3: tracing ஒவ்வொரு அழைப்பின் உள்ளீடுகளையும் வைத்திருந்தது
Heap snapshot மூன்றாவது வைத்திருப்பவரைக் காட்டியது: ஒரு மாதிரி அழைப்புக்கு சுமார் 6 MB. இது agent framework-இன் event streaming-இலிருந்து வந்தது. அது turn-இல் ஒவ்வொரு மாதிரி அழைப்பையும் turn-இன் குழந்தையாகப் பதிவு செய்கிறது, உள்ளீடுகளுடன், turn முடியும் வரை. ஒவ்வொரு அழைப்பிலும் இணைக்கப்பட்ட ஒவ்வொரு படமும் அதனுடன் நினைவகத்தில் இருந்தது.
தீர்வு: அழைப்பு திரும்பியதும் படங்களை வெறுமையாக்கு
படங்கள் ஒரு குறிப்பிட்ட மாதிரி அழைப்புக்காக உருவாக்கப்பட்ட messages-இல் மட்டுமே இணைக்கப்படுகின்றன. அவை உரையாடலின் சேமிக்கப்பட்ட நிலையில் ஒருபோதும் வைக்கப்படுவதில்லை. ஆகவே ஓர் அழைப்பு திரும்பியதும், அந்த messages-இல் உள்ள படத் தரவை வெறுமையாக்குவது பாதுகாப்பானது. Trace அழைப்பின் உரைப் பதிவை வைத்திருக்கும்; pixels போய்விடும்.
ஒரு விவரம் முக்கியமானது: படங்களை அதே இடத்திலேயே வெறுமையாக்க வேண்டும். Tracer ஒரே படத் தரவை ஒரு message-இல் ஒன்றுக்கு மேற்பட்ட references வழியாக அடையலாம்; புதிய வெற்றுப் பட்டியலை வைத்தால் அசல் — pixels உட்பட — இன்னும் அடையக்கூடியதாக இருக்கும். சேமிக்கப்பட்ட உரையாடல் நிலை ஒருபோதும் மாற்றப்படுவதில்லை.
ஒரு சோதனை, agent-இன் graph-ஐ அதே event streaming கீழ், ஒவ்வொரு அழைப்பிலும் 4 MB படத்துடன் இயக்குகிறது. சரிசெய்யாமல், 16 அழைப்புகளில் நினைவகம் 77 MB வளர்ந்தது. சரிசெய்த பிறகு நினைவகம் நிலையாக இருக்கிறது.
நாங்கள் கற்றது
- நினைவகப் பிரச்சனைகள் அடுக்குகளாக வரலாம். மூன்று தனித்தனி காரணங்கள் ஒவ்வொன்றும் படங்களை நீண்ட நேரம் வைத்திருந்தன; turn நினைவகத்துக்குள் நிற்க மூன்றும் போக வேண்டியிருந்தது.
- நூலகத்திடம் நீங்கள் கொடுக்கும் எதுவும் வைத்திருக்கப்படலாம். ஒரு signal மற்றும் ஒரு trace இரண்டும், அவற்றுக்குக் கொடுத்த அழைப்புகளைவிட நீண்டு வாழ்ந்தன. நினைவகம் அழைப்புக்கு அழைப்பு வளர்ந்தால், அந்த அழைப்பு தொடும் நீண்டகால objects என்னவென்று பாருங்கள்.
- மறுபக்கம் தூக்கி எறியப்போவதை அனுப்ப வேண்டாம். மாதிரி எப்படியும் நிராகரிக்கும் pixels ஒவ்வொரு அழைப்பிலும் எங்களுக்கு நினைவகச் செலவாயின.
- நினைவகத்தை நேரடியாகச் சோதியுங்கள். ஒவ்வொரு சரிசெய்தலும் heap வளர்ச்சியை அல்லது listener எண்ணிக்கையை அளக்கும் ஒரு சோதனையுடன் வந்தது; அதனால் ஒரு பின்னடைவு செயலிழப்பாக அல்ல, ஓர் எண்ணாகத் தெரியும்.
Agent-இன் output தொடர்பான இது குறுகிய காலத்தில் வந்த இரண்டாவது நினைவகக் கதை. முதலாவது ஒரு progress label 41,000 முறை மீண்டும் அனுப்பப்பட்டது. Agent என்ன, அது எப்படி வேலை செய்கிறது என்று தெரிந்துகொள்ள, AI agents வழிகாட்டி மற்றும் chat docs பார்க்கவும்.