v1.2 — Ediția 2026. Un curs audio aprofundat despre framework-ul de orchestrare LangChain v1.0. Construiește aplicații AI multi-agent de încredere, cu apelare standardizată a instrumentelor, ieșiri structurate, validare human-in-the-loop și inginerie avansată a contextului.
Explorăm de ce LangChain a evoluat de la un simplu wrapper la un framework complet de orchestrare. Vei învăța istoria dezvoltării aplicațiilor LLM și modul în care lansarea v1.0 standardizează interacțiunile cu modelele.
3m 39s
2
Abstracția Unificată a Agentului
Aprofundăm funcția de bază create_agent care unifică abstracțiile anterioare ale LangChain. Vei învăța cum funcționează bucla ReAct în fundal pentru a gestiona raționamentul modelului și execuția instrumentelor.
3m 53s
3
Standardizarea Haosului
Examinăm modul în care LangChain standardizează interacțiunile cu modelele între diferiți furnizori. Vei învăța cum să inițializezi modele de chat și să comuți fără probleme între OpenAI, Anthropic și Google.
3m 36s
4
Limbajul Universal al LLM-urilor
Analizăm unitatea fundamentală de context din LangChain: Messages. Vei învăța cum să structurezi mesajele System, Human, AI și Tool pentru a construi istorice de conversație robuste.
4m 04s
5
Echiparea Agenților cu Instrumente
Explorăm cum să oferi acțiuni modelelor tale folosind decoratorul @tool. Vei învăța cum type hints și docstrings sunt convertite automat în scheme JSON precise pentru model.
4m 15s
6
Injectarea Contextului în Instrumente
Aprofundăm transmiterea informațiilor de runtime direct către instrumentele tale, fără a le expune LLM-ului. Vei învăța cum să folosești parametrul ToolRuntime pentru configurații sigure, bazate pe dependency injection.
3m 49s
7
Persistența la Nivel de Thread
Abordăm memoria pe termen scurt și modul de menținere a istoricului conversației. Vei învăța cum să atașezi checkpointers agentului tău pentru a permite ca discuțiile să fie întrerupte, reluate și reținute.
4m 08s
8
Comprimarea Contextului cu Middleware
Explorăm cum să previi ca discuțiile lungi să îți blocheze modelul. Vei învăța cum să folosești SummarizationMiddleware pentru a comprima automat mesajele vechi și a economisi tokeni.
4m 02s
9
Formate de Date Garantate
Discutăm despre cum să forțezi modelele de limbaj să returneze structuri de date stricte și predictibile. Vei învăța diferența dintre ProviderStrategy și ToolStrategy pentru generarea modelelor Pydantic.
3m 42s
10
Interceptarea Buclei Agentului
Introducem paradigma middleware, oferindu-ți un control chirurgical asupra execuției agentului tău. Vei învăța cum să folosești hook-uri wrap-style și node-style pentru a intercepta apelurile modelelor.
3m 30s
11
Ingineria Dinamică a Contextului
Aprofundăm ingineria contextului prin generarea dinamică a prompturilor de sistem. Vei învăța cum să folosești middleware pentru a modifica instrucțiunile în funcție de rolul utilizatorului curent și de mediu.
3m 52s
12
AI Sigur cu Guardrails Deterministe
Ne securizăm agenții împotriva scurgerilor de date folosind middleware integrat. Vei învăța cum să aplici PIIMiddleware pentru a redacta automat informațiile sensibile înainte ca acestea să ajungă la model.
4m 08s
13
Pauză pentru Aprobare Umană
Explorăm execuția instrumentelor cu miză mare prin adăugarea unui om în buclă (human-in-the-loop). Vei învăța cum să oprești execuția unui agent pentru a aproba, edita sau respinge acțiuni sensibile.
4m 28s
14
Feedback în Timp Real de la Agent
Aprofundăm streaming-ul pentru a îmbunătăți drastic experiența utilizatorului. Vei învăța cum să interpretezi modurile de stream pentru a afișa live tokenii LLM alături de actualizări personalizate ale execuției instrumentelor.
3m 49s
15
Persistența Cross-Session
Explorăm memoria pe termen lung pentru a construi agenți care își cunosc cu adevărat utilizatorii. Vei învăța cum să folosești LangGraph stores pentru a salva documente JSON în conversații complet diferite.
3m 47s
16
Paradigma Multi-Agent
Explicăm de ce agenții singulari eșuează și introducem arhitectura Subagents. Vei învăța cum un agent supervizor principal coordonează subagenții ca ferestre de context izolate pentru a preveni supraîncărcarea cu tokeni.
4m 06s
17
Agenți Bazați pe Stare
Explorăm modul în care agenții își pot modifica dinamic comportamentul. Vei învăța pattern-ul Handoffs pentru transferul controlului și pattern-ul Skills pentru încărcarea prompturilor specializate la cerere.
3m 50s
18
Fluxuri de Lucru Personalizate și Routere
Ieșim din bucla standard a agentului. Vei învăța cum să folosești LangGraph pentru a construi arhitecturi de rutare personalizate, combinând logica deterministă cu raționamentul agentic nedeterminist.
4m 29s
19
Comunicarea Agent-to-Agent
Explorăm endpoint-ul LangSmith A2A. Vei învăța cum agenții distribuiți, implementați pe servere complet diferite, pot conversa nativ folosind protocolul A2A RPC de la Google.
4m 24s
20
Viitorul este MCP
Privim spre viitor cu Model Context Protocol, care standardizează modul în care agenții accesează instrumente externe. Vei învăța cum să conectezi servere MCP la distanță la agentul tău folosind transporturi standard.
4m 45s
Episoade
1
Era Orchestrării
3m 39s
Explorăm de ce LangChain a evoluat de la un simplu wrapper la un framework complet de orchestrare. Vei învăța istoria dezvoltării aplicațiilor LLM și modul în care lansarea v1.0 standardizează interacțiunile cu modelele.
Salut, sunt Alex de la DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episodul 1 din 20. Este incredibil de ușor să construiești un prototip de agent AI, dar este extrem de greu să faci unul suficient de fiabil pentru a fi dus în producție. Diferența dintre un demo cool făcut în weekend și o aplicație enterprise este uriașă. Soluția pentru a acoperi această diferență este ceea ce numim Era Orchestrării.
Mai întâi, să clarificăm o confuzie foarte des întâlnită. Oamenii confundă adesea LangChain cu un model provider. LangChain nu antrenează, nu face host și nu face serve pentru Large Language Models. Este layer-ul de orchestrare care stă direct deasupra acestor modele. Gândește-te la el ca la centrul de control care gestionează modul în care aplicația ta interacționează cu orice model alegi să folosești.
Pentru a înțelege de ce este necesar un layer de orchestrare, trebuie să ne uităm la cum a evoluat tehnologia. Prin 2022, interacțiunea cu un language model era simplă. Trimiteai un string de text și primeai înapoi un string de text. Niște prompt chains simple erau suficiente ca să-ți faci treaba. Nu aveai nevoie de un framework greoi pentru a gestiona un workflow de bază de tip text-in, text-out. Puteai scrie foarte ușor un script în care output-ul de la promptul A era pur și simplu dat paste în promptul B.
Dar, pe măsură ce trecem prin 2025 și privim spre 2026, peisajul arată complet diferit. Modelele nu mai procesează doar plain text. Ele preiau și generează blocuri multimodale complexe. O singură interacțiune ar putea implica rutarea unui user prompt, declanșarea unui tool call extern, procesarea unei imagini și returnarea unui bloc structurat de date. Un model ar putea returna o cerere pentru un database lookup exact lângă un rezumat text. Dacă codul aplicației tale trebuie să inspecteze manual fiecare răspuns în parte pentru a-și da seama dacă este un string, un tool call sau un fișier imagine, codebase-ul tău va deveni rapid un haos fragil și imposibil de întreținut.
Iată ideea cheie. Să pasezi contextul exact cum trebuie către un model, la momentul potrivit, este mult mai greu decât pur și simplu să alegi cel mai puternic model de pe piață. Poți să faci swap cu cel mai inteligent reasoning engine disponibil, dar dacă primește date dezordonate și nestandardizate, întreaga interacțiune va eșua.
De aceea, LangChain a evoluat de la o simplă chaining library la un layer de orchestrare standardizat pentru release-ul său 1.0. Oferă un format standard de mesaj care funcționează consecvent pe toți marii model providers. În loc să scrii o logică de parsing custom pentru fiecare API diferit, folosești o structură uniformă. Prin standardizarea formatului de mesaj, LangChain se asigură că un tool call de la un provider arată exact la fel în codul tău ca un tool call de la un provider concurent. Definești o secvență în care intră un user message, layer-ul de orchestrare îl normalizează, îl trimite la model, prinde răspunsul multimodal și traduce acel răspuns înapoi într-un format standard pe care aplicația ta chiar îl poate folosi. Scrii logica aplicației o singură dată, iar layer-ul de orchestrare se ocupă de traducere.
Modelul în sine nu mai este întreaga aplicație, este doar reasoning engine-ul, iar layer-ul de orchestrare este cel care determină dacă acel engine chiar îți rezolvă problema de business.
Dacă vrei să ne ajuți să continuăm să facem aceste episoade, poți susține emisiunea căutând DevStoriesEU pe Patreon. Asta e tot pentru acest episod. Mersi că ne-ai ascultat și continuă să construiești!
2
Abstracția Unificată a Agentului
3m 53s
Aprofundăm funcția de bază create_agent care unifică abstracțiile anterioare ale LangChain. Vei învăța cum funcționează bucla ReAct în fundal pentru a gestiona raționamentul modelului și execuția instrumentelor.
Salut, sunt Alex de la DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episodul 2 din 20. Ce-ar fi dacă ai putea înlocui întreaga buclă complexă de raționament cu un singur function call de zece linii? Petreci ore întregi scriind parsere custom și while-loops doar pentru a face un language model să apeleze o funcție în mod fiabil. Unified Agent Abstraction este arhitectura care te scapă de toată bătaia asta de cap.
Pentru a înțelege de ce contează asta, trebuie să clarificăm o confuzie comună legată de versiunile mai vechi ale framework-ului. În versiunea zero point x, developerii trebuiau să navigheze printr-un labirint de clase specifice de agenți. Aveai conversational agents, zero-shot agents și chains custom complexe. Dacă îți faci upgrade la cod, poți uita de toate astea. Unified agent abstraction înlocuiește complet toate acele chains vechi și legacy agents. Oferă un entry point clar și standardizat printr-o funcție numită pur și simplu create agent.
Această funcție există pentru a gestiona ReAct loop-ul. ReAct vine de la Reason and Act. Când un user pune o întrebare complexă, un language model nu poate pur și simplu să execute cod. Trebuie să raționeze asupra problemei, să decidă să ia o acțiune, să genereze un output text care solicită acea acțiune, și apoi să aștepte o observație înainte de a putea raționa din nou. Gestionarea manuală a acestui ciclu este o bătaie de cap. Trebuie să faci parse la textul generat de model, să îl mapezi la o funcție locală, să execuți acea funcție, să formatezi output-ul, să îl trimiți înapoi în model și să evaluezi dacă task-ul este finalizat. Funcția create agent abstractizează întregul proces de orchestrare.
Hai să trecem printr-o implementare simplă folosind un tool de verificare a vremii. Mai întâi, îți definești tool-ul specific, poate o funcție numită get weather care primește numele unui oraș. Apoi, îți inițializezi language model-ul ales. Apoi vine partea de abstractizare. Apelezi funcția create agent și îi pasezi trei argumente. Pasezi language model-ul tău, o listă care conține tool-ul tău get weather, și un system prompt care dictează regulile pentru agent. Acest singur call returnează un obiect agent executabil. În final, invoci acest obiect cu un user query, cerând vremea actuală din Londra.
Iată ideea de bază din execution flow. Când invoci agentul, pornești ReAct loop-ul. Agentul trimite query-ul și descrierile tool-urilor către model. Modelul decide că are nevoie de date în timp real și generează un tool call standardizat. Agent abstraction-ul interceptează automat acest call. Execută tool-ul tău get weather cu argumentul London, preia datele de temperatură rezultate și le pasează înapoi modelului ca o nouă observație. Modelul evaluează aceste date, își dă seama că are răspunsul la user query, și generează un răspuns final.
Nu ai scris niciun loop, și nu ai scris niciun output parser. Ai furnizat doar tool-urile, modelul și instrucțiunile. Puterea unified agent abstraction constă în stabilirea unei limite arhitecturale stricte. Izolează complet mecanica ciclului de raționament, permițându-ți să îți dedici tot efortul de inginerie pentru a rafina calitatea tool-urilor tale și claritatea prompt-urilor.
Asta e tot pentru acest episod. Mersi că m-ai ascultat, și continuă să construiești!
3
Standardizarea Haosului
3m 36s
Examinăm modul în care LangChain standardizează interacțiunile cu modelele între diferiți furnizori. Vei învăța cum să inițializezi modele de chat și să comuți fără probleme între OpenAI, Anthropic și Google.
Salut, sunt Alex de la DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episodul 3 din 20. Providerii diferiți de modele au API-uri extrem de diferite, ceea ce înseamnă că testarea unui model nou te obligă de obicei să rescrii jumătate din aplicație. Ajungi să rămâi blocat cu un singur vendor doar pentru că costul tehnic de schimbare este prea mare. Standardizarea acestui haos este exact subiectul acestui episod.
Înainte să intrăm în mecanica modului în care LangChain rezolvă asta, e util să clarificăm o confuzie comună. Dacă ai lucrat cu primele modele de limbaj, probabil ești familiarizat cu clasele LLM legacy care acceptă un singur string de text brut ca input. Modelele de chat moderne sunt diferite. Ele necesită strict o secvență structurată de mesaje, unde fiecare mesaj are atașat un rol specific, cum ar fi system, human sau AI. Tot ce discutăm acum se aplică acestor modele de chat moderne, nu celor legacy de text completion.
Când construiești o aplicație, hardcodarea unui anumit provider creează un vendor lock-in imediat. Pentru a scăpa de această dependență, LangChain introduce o singură funcție factory numită init chat model. Gândește-te la ea ca la un translator universal pentru inițializarea clienților de AI. În loc să imporți o clasă unică pentru OpenAI, alta pentru Anthropic și încă una pentru Google, te bazezi exclusiv pe această singură funcție.
Iată ideea cheie. Funcția init chat model folosește o sintaxă simplă de string pentru a ști ce să construiască. Pasezi un string formatat cu numele providerului, urmat de două puncte, apoi de versiunea specifică a modelului. Imaginează-ți un agent care rulează în prezent pe GPT-5 de la OpenAI. Inițializezi modelul pur și simplu pasând string-ul openai două puncte gpt-5.
Acum, să presupunem că Anthropic lansează un model nou care gestionează mai bine generarea de cod și vrei să-l testezi. Pentru că ai folosit funcția init chat model, nu te atingi de logica agentului. Nu imporți un pachet client nou. Pur și simplu schimbi acel string de inițializare în anthropic două puncte claude-sonnet-4-6. LangChain rezolvă dinamic string-ul și încarcă clasa de integrare corectă din spate.
Asta rezolvă partea cu modelul în sine, dar providerii au diferențe și la setările de configurare. Un API ar putea aștepta un parametru numit max sampled tokens, în timp ce altul așteaptă max length. Funcția init chat model rezolvă asta acceptând parametri standard. Când inițializezi modelul, poți pasa argumente precum temperature sau max tokens direct funcției.
Dacă setezi temperature la zero virgulă doi și max tokens la o mie, LangChain mapează acești termeni generici la cheile de payload exacte cerute de orice provider ai specificat în string-ul tău. Configurezi modelul o singură dată folosind terminologia standard, iar framework-ul o traduce pentru API-ul de destinație.
Prin separarea codului aplicației de detaliile de implementare specifice vendorului, câștigi agilitate arhitecturală, ceea ce îți permite să evaluezi modele concurente în câteva secunde, nu în zile.
Asta e tot pentru acest episod. Mulțumesc că m-ai ascultat și continuă să construiești!
4
Limbajul Universal al LLM-urilor
4m 04s
Analizăm unitatea fundamentală de context din LangChain: Messages. Vei învăța cum să structurezi mesajele System, Human, AI și Tool pentru a construi istorice de conversație robuste.
Salut, sunt Alex de la DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episodul 4 din 20. Dacă încă pasezi string-uri plain text către modelele tale de limbaj, îți limitezi sever aplicațiile. String-urile simple pierd contextul. Ele nu pot stoca în siguranță referințe către imagini, rezultate ale execuției de tool-uri sau roluri distincte de interacțiune. Pentru a rezolva asta, LangChain folosește obiecte de tip mesaj standardizate, care acționează ca un limbaj universal pentru LLM-uri.
Un mesaj în LangChain este o structură de date care conține un rol specific, un payload și metadata opționale. Diferiți provideri de API gestionează rolurile de conversație și input-urile multimodale în mod diferit în API-urile lor raw. LangChain abstractizează această fricțiune în patru clase distincte.
Prima este SystemMessage. Acest obiect stabilește regulile de background, persona sau constrângerile stricte pentru interacțiune. Urmează HumanMessage, care reprezintă prompt-ul utilizatorului sau fișierele uploadate. Apoi avem AIMessage, care capturează răspunsul generat de model. În final, există ToolMessage. Acest obiect transportă specific rezultatul execuției unei funcții externe înapoi către model, separând curat input-ul raw al utilizatorului de datele factuale generate de sistem.
Orchestrezi conversațiile pasând un array cu aceste obiecte de tip mesaj către model. Poți construi manual acest array pentru a modela output-ul. Mai întâi, creezi o listă și inserezi un SystemMessage, atribuind modelului rolul unui expert în poezie cu formatare strictă. În al doilea rând, adaugi un HumanMessage care cere un haiku despre migrări de baze de date. Iată ideea cheie. Nu trebuie să aștepți ca modelul să genereze următorul răspuns. Poți instanția manual un AIMessage și îl poți injecta în array imediat după prompt-ul uman, conținând o linie de deschidere specifică. Când pasezi tot acest array către model, el interpretează AIMessage-ul injectat de tine ca fiind propriul său comportament din trecut. Va continua fără probleme haiku-ul exact de la punctul tău de plecare, respectând structura pe care i-ai impus-o.
Când primești în cele din urmă un AIMessage înapoi de la model, trebuie să extragi ceea ce a produs de fapt. Developerii confundă frecvent atributul raw content cu payload-ul parsat. Fiecare obiect de tip mesaj are o proprietate content. Totuși, acest atribut raw content reflectă direct orice a returnat providerul LLM specific. În funcție de providerul modelului și de prompt, acesta poate fi un simplu string de text, sau poate fi o listă puternic imbricată de dicționare care conține chunk-uri de text mixte, URL-uri de imagini și identificatori de tool-uri. Parsarea manuală a acestui lucru îți face codul incredibil de fragil.
În loc să citești raw content-ul, ar trebui să folosești proprietatea content blocks. Proprietatea content blocks este reprezentarea strict tipizată și standardizată din LangChain a payload-ului mesajului. Când citești din content blocks, LangChain traduce răspunsul specific providerului într-o listă uniformă de obiecte de tip block. Poți itera prin această listă în siguranță. Mai întâi verifici dacă un block este un text block, și dacă da, extragi payload-ul de text. Apoi verifici dacă este un tool call block, și extragi argumentele. Construirea logicii de parsare în jurul proprietății standardizate content blocks este singura modalitate de a te asigura că aplicația ta rămâne complet decuplată de formatele de răspuns schimbătoare ale providerilor individuali de modele.
Asta e tot pentru acest episod. Mulțumesc pentru audiție și continuă să construiești!
5
Echiparea Agenților cu Instrumente
4m 15s
Explorăm cum să oferi acțiuni modelelor tale folosind decoratorul @tool. Vei învăța cum type hints și docstrings sunt convertite automat în scheme JSON precise pentru model.
Salut, sunt Alex de la DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episodul 5 din 20. Un agent AI fără acces la lumea exterioară este doar un generator de text. Pentru a-l transforma într-un sistem care chiar își face treaba, trebuie să-i dai mâini. Astăzi vorbim despre Împuternicirea Agenților cu Tools, mai exact folosind decoratorul at-tool.
Un tool în LangChain este o punte între motorul de raționament al unui model de limbaj și sistemele tale externe. Dar există o concepție greșită des întâlnită aici. Mulți developeri presupun că modelul de limbaj analizează cumva logica din interiorul funcției lor Python pentru a-și da seama cum să o folosească. Nu face asta. Modelul de limbaj nu vede niciodată codul tău Python. Vede doar o schemă care descrie funcția.
Pentru a crea un tool, scrii o funcție Python standard și plasezi decoratorul at-tool direct deasupra ei. Acest decorator face ceva crucial. Inspectează semnătura funcției, extrage numele funcției, citește type hints pentru fiecare parametru și parsează docstring-ul. Preia toate aceste metadate și le grupează într-un format structurat pe care modelul de limbaj îl poate citi efectiv.
Deoarece modelul citește doar această schemă generată, precizia codului tău este esențială. Să analizăm un scenariu. Să presupunem că scrii o funcție numită search database. Dacă îi dai un docstring slab care spune doar „caută în baza de date” și omiți complet type hints, modelul de limbaj zboară orbește. Nu știe ce fel de bază de date este și nu știe ce argumente să furnizeze. Ar putea încerca să transmită o propoziție conversațională completă ca search query, provocând funcția ta Python să dea crash la execuție.
Iată ideea cheie. Când folosești decoratorul at-tool, trebuie să scrii docstring-urile pentru modelul de limbaj, nu pentru developerul uman. În loc de o descriere vagă, scrii o instrucțiune clară, cum ar fi „caută în baza de date a clienților după adresa de email pentru a extrage istoricul de facturare”.
Apoi, aplici type hints stricte parametrilor tăi de intrare. Specifici că argumentul email trebuie să fie un string. Poți chiar să adaugi o descriere argumentului în sine. Fiecare informație de tip pe care o adaugi oferă modelului de limbaj o limită mai strictă asupra a ceea ce are voie să genereze.
Când îi dai acest tool nou decorat unui agent, agentul citește schema detaliată înainte de a face orice altceva. Când un utilizator întreabă despre o rambursare a unui client, agentul scanează tool-urile disponibile și recunoaște că tool-ul search database este exact ceea ce trebuie, pe baza docstring-ului tău precis. Datorită type hint-ului tău strict, știe exact cum să formateze argumentul. Extrage string-ul de email din prompt-ul utilizatorului, oprește generarea de text și emite un tool call.
LangChain interceptează acel tool call. Preia string-ul de email generat de model, îl transmite în funcția ta Python de la bază și execută codul. Funcția ta comunică cu baza de date, preia istoricul de facturare și returnează datele brute direct către LangChain. LangChain transmite apoi aceste date înapoi agentului ca o observație. Agentul își reia procesul de gândire, dar acum are datele reale pe care tocmai i le-ai furnizat.
Capacitatea modelului de limbaj de a acționa este complet limitată de calitatea semnăturii funcției tale. Tratează docstring-urile și type hints ca pe niște constrângeri inginerești stricte, deoarece, pentru modelul de limbaj, acestea sunt singurele instrucțiuni care există. Asta e tot pentru acest episod. Mulțumesc pentru audiție și continuă să construiești!
6
Injectarea Contextului în Instrumente
3m 49s
Aprofundăm transmiterea informațiilor de runtime direct către instrumentele tale, fără a le expune LLM-ului. Vei învăța cum să folosești parametrul ToolRuntime pentru configurații sigure, bazate pe dependency injection.
Salut, sunt Alex de la DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episodul 6 din 20. Dacă te bazezi pe un model de limbaj pentru a transmite corect un token de autentificare sau o identitate de utilizator către un database tool, te pregătești pentru o breșă masivă de securitate. Modelul nu știe cine este utilizatorul curent și cu siguranță nu ar trebui să te bazezi pe el să ghicească. Ai nevoie de o modalitate de a transmite date sensibile de backend direct către tool-urile tale, ocolind complet modelul. Exact asta rezolvă Injecting Tool Context.
Când construiești un tool, unele argumente sunt menite să fie generate de model, cum ar fi un search string sau un interval de date. Alte argumente sunt strict pentru infrastructura ta de backend. Aici intervine obiectul ToolRuntime. Acesta îți permite să injectezi configurație statică într-un tool exact atunci când se execută.
Ai putea crede că poți pur și simplu să transmiți un dicționar de configurare ca argument normal al tool-ului și să-i spui prompt-ului să-l ignore. Nu face asta. Când definești un parametru numit config sau runtime în funcția tool-ului tău, LangChain le tratează drept cuvinte cheie rezervate. Le ascunde intenționat de tool schema care este trimisă modelului de limbaj. Modelul nu le vede niciodată. Vede doar argumentele pe care este responsabil să le furnizeze. Aceasta înseamnă că modelul nu poate halucina o configurație falsă sau să încerce să treacă peste limitele tale de securitate.
Ia în considerare un scenariu concret. Construiești un tool get account info pentru o aplicație bancară. Tool-ul necesită un user ID pentru a obține înregistrările corecte din baza de date. Dacă modelul furnizează acest ID, un prompt injection inteligent ar putea păcăli modelul să solicite date pentru un client complet diferit. În schimb, proiectezi funcția tool-ului să accepte două argumente. Primul este tipul de cont, pe care modelul îl va furniza. Al doilea este un argument numit runtime.
În codul principal al aplicației, înainte ca tool-ul să fie invocat, populezi acest obiect runtime. Mai exact, folosești proprietatea runtime dot context. Pui user ID-ul real, autentificat, al persoanei care face solicitarea direct în acest context. De asemenea, poți plasa acolo o conexiune activă la baza de date sau o adresă de endpoint regional.
Modelul evaluează solicitarea utilizatorului și decide să apeleze tool-ul get account info. Se uită la schemă, vede că trebuie să furnizeze un tip de cont și generează cuvântul savings. Nu generează nimic altceva. LangChain interceptează acest execution call. Preia tipul de cont din model, îl combină perfect cu runtime context-ul din backend și execută funcția Python. În interiorul funcției, extragi user ID-ul din context și rulezi query-ul de database în siguranță.
Acest mecanism îți oferă un dependency injection securizat. Poți injecta orice are nevoie tool-ul tău pentru a funcționa, despre care modelul nu are de ce să știe. API keys pentru servicii de facturare terțe, file system paths sau tenant identifiers într-o arhitectură multi-tenant, toate își au locul în runtime context.
Iată ideea principală. Ascunderea argumentelor de configurare în spatele runtime context-ului asigură că modelul tău acționează exclusiv ca un logic router, în timp ce codul aplicației tale păstrează controlul absolut, fără compromisuri, asupra accesului la date și a securității execuției.
Îți mulțumesc că ai petrecut câteva minute cu mine. Până data viitoare, numai bine.
7
Persistența la Nivel de Thread
4m 08s
Abordăm memoria pe termen scurt și modul de menținere a istoricului conversației. Vei învăța cum să atașezi checkpointers agentului tău pentru a permite ca discuțiile să fie întrerupte, reluate și reținute.
Salut, sunt Alex de la DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episodul 7 din 20. Fără memorie, fiecare interacțiune cu agentul tău AI pare o scenă din 50 de prime întâlniri. Modelul pornește complet de la zero, uitând tot ce ai discutat cu câteva secunde în urmă. Soluția este Thread-Level Persistence.
Modelele mari de limbaj sunt complet stateless. Ele procesează text și returnează text, fără să rețină absolut nimic între request-uri. Pentru a purta o conversație, un agent are nevoie de o metodă de a stoca și accesa interacțiunile trecute. În contextul unei singure sesiuni active, gestionăm asta prin memoria pe termen scurt, care este administrată ca parte a state-ului agentului și persistată folosind checkpointers.
Lumea crede adesea că memoria în AI este o capacitate internă a modelului, prin care rețeaua neuronală își amintește magic de tine. Nu este așa. Memoria este pur și simplu istoricul mesajelor. Persistența la nivel de thread înseamnă pur și simplu să iei lista curentă de mesaje, să o salvezi într-o bază de date după fiecare pas și să o introduci înapoi în prompt înainte ca modelul să vadă următorul input. Checkpointer-ul gestionează asta automat, așa că nu trebuie să scrii manual logica de stocare și extragere.
În LangGraph, state-ul este salvat per thread. Un thread reprezintă o sesiune continuă. Pentru a activa asta, ai nevoie de un checkpointer. Pentru development și testare, poți folosi In Memory Saver. Când compilezi graph-ul agentului, pasezi acest obiect saver ca argument pentru checkpointer. Această integrare îi spune agentului că, la finalul execuției fiecărui node, trebuie să facă un snapshot al state-ului curent și să-l predea saver-ului. State-ul include orice ai definit în graph-ul tău, ceea ce este de obicei o listă curentă de mesaje.
Hai să ne uităm la un scenariu concret. Compilezi agentul cu un In Memory Saver. Acum, vrei să invoci agentul. În loc să pasezi doar un mesaj de la user, pasezi și un obiect de configurare care conține un thread ID specific. Hai să folosim valoarea de tip string conversation one. Trimiți mesajul, numele meu este Bob. Agentul îl primește, generează un salut politicos și finalizează. În culise, checkpointer-ul salvează state-ul actualizat, care acum conține mesajul ce afirmă că numele tău este Bob, indexat sub conversation one.
Mai târziu, invoci agentul a doua oară. Trimiți un nou mesaj în care întrebi, care este numele meu. Partea crucială este că pasezi exact același obiect de configurare cu thread ID-ul conversation one.
Iată detaliul cheie. Înainte ca agentul să ruteze noua ta întrebare către model, checkpointer-ul interceptează procesul. Caută conversation one în In Memory Saver. Extrage snapshot-ul de state de la runda ta anterioară, încarcă istoricul de mesaje salvat și adaugă noua ta întrebare la final. Modelul de limbaj primește contextul istoric complet, vede mesajul anterior în care te-ai prezentat și răspunde cu succes că numele tău este Bob.
Dacă ai schimba thread ID-ul în conversation two și ai întreba care îți este numele, checkpointer-ul ar căuta acel nou ID, nu ar găsi niciun state existent și ar inițializa o listă de mesaje nouă, goală. Agentul nu ar avea nicio idee cine ești. Thread ID-ul este singura cheie care leagă o secvență de apeluri de model izolate și stateless într-o sesiune coerentă de memorie pe termen scurt.
Checkpointer-ul abstractizează munca repetitivă de gestionare a array-urilor de mesaje și de interogare a bazelor de date, garantând că agentul tău își poate relua munca exact de unde a rămas, atâta timp cât furnizezi thread ID-ul corect.
Mersi că m-ai ascultat — ne auzim data viitoare.
8
Comprimarea Contextului cu Middleware
4m 02s
Explorăm cum să previi ca discuțiile lungi să îți blocheze modelul. Vei învăța cum să folosești SummarizationMiddleware pentru a comprima automat mesajele vechi și a economisi tokeni.
Salut, sunt Alex de la DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episodul 8 din 20. Cu cât o conversație durează mai mult, cu atât un Large Language Model devine mai distras de informațiile învechite. Pierzi din acuratețe, în timp ce plătești costuri mai mari de tokeni pentru fiecare turn. Comprimarea contextului folosind un middleware rezolvă exact această problemă.
Pe măsură ce istoricul de chat crește, ajungi în cele din urmă la limita de context window a modelului tău. Chiar și înainte de a atinge acea limită strictă, dacă îi dai mii de tokeni din conversația veche, performanța va scădea. Soluția este SummarizationMiddleware din LangChain. În loc să taie pur și simplu mesajele vechi, le comprimă într-un singur summary block. Asta păstrează sensul semantic al conversației fără acel overhead masiv de tokeni.
Există o concepție greșită destul de comună despre cum rulează asta. Lumea presupune adesea că agentul principal trebuie să facă el însuși sumarizarea. Nu o face, și chiar nu ar trebui să o facă. Vrei ca agentul tău principal să ruleze pe cel mai inteligent și capabil model al tău, pentru a gestiona logica complexă. Sumarizarea este un task mult mai simplu. Atribui un model mai mic și mai ieftin către SummarizationMiddleware, exclusiv pentru acest job.
Configurarea acestui middleware necesită definirea a doi parametri principali. Primul este trigger-ul. Trigger-ul îi spune middleware-ului când să intervină. Poți seta trigger-ul să se activeze ori de câte ori numărul total de tokeni al conversației atinge 4000. Al doilea parametru este keep condition. Asta îi spune middleware-ului cât context recent să lase complet neatins. Ai putea seta valoarea de keep la 20, ceea ce înseamnă că cele mai recente 20 de mesaje rămân neatinse.
Iată flow-ul logic în practică. User-ul tău discută cu agentul principal. Conversația crește. La următorul turn, istoricul total de mesaje depășește pragul de 4000 de tokeni. Înainte ca agentul principal măcar să vadă noul user input, SummarizationMiddleware interceptează request-ul. Scanează istoricul și identifică tot ce este mai vechi de cele mai recente 20 de mesaje. Ia acel chunk mai vechi din conversație și îl dă modelului tău mai mic, desemnat pentru asta. Să zicem că ai configurat middleware-ul să folosească gpt-4.1-mini.
Acel model mai mic citește mesajele vechi și generează un paragraf concis care rezumă ce s-a discutat. Middleware-ul rescrie apoi array-ul de istoric. Înlocuiește toate acele mesaje vechi, individuale, cu un singur system message care conține noul rezumat. Dacă exista deja un rezumat mai vechi dintr-un ciclu de compresie anterior, middleware-ul îl include în prompt, astfel încât noul rezumat să actualizeze narațiunea curentă.
Pachetul final trimis agentului tău principal este extrem de optimizat. Acesta conține noul mesaj de rezumat, urmat de cele 20 de mesaje recente necomprimate, urmate de cel mai recent user input.
Iată ideea cheie. Agentul principal nu își dă seama niciodată că istoricul a fost comprimat în spate. Primește doar un context window curat și extrem de relevant. Păstrezi sensul semantic pe termen lung al chat-ului, menții modelul concentrat și îți reduci drastic costurile de tokeni la fiecare turn ulterior.
Dacă găsești aceste episoade utile și vrei să susții emisiunea, poți căuta DevStoriesEU pe Patreon. Asta e tot pentru acest episod. Mulțumesc că m-ai ascultat, și continuă să construiești!
9
Formate de Date Garantate
3m 42s
Discutăm despre cum să forțezi modelele de limbaj să returneze structuri de date stricte și predictibile. Vei învăța diferența dintre ProviderStrategy și ToolStrategy pentru generarea modelelor Pydantic.
Salut, sunt Alex de la DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episodul 9 din 20. Să construiești software care se bazează pe parsing de răspunsuri în limbaj natural folosind regular expressions este o bombă cu ceas. Îi ceri unui language model un data object simplu, iar el îți dă date perfecte, doar că adaugă un salut politicos la început și împachetează totul în formatare markdown. Parserul tău dă crash instant. Guaranteed Data Formats sunt soluția ca să rezolvi asta definitiv.
Structured output forțează language model-ul să returneze informațiile exact așa cum se așteaptă aplicația ta. Transformă generarea de text imprevizibilă în software objects de încredere. Gândește-te la un sistem care procesează mesaje inbound de customer support. Un user trimite un paragraf dezordonat, unstructured, în care se plânge de o problemă de login, dar își ascunde numele, adresa de email și numărul de telefon undeva prin text. Ai nevoie de aceste trei date pentru a declanșa un database lookup.
În loc să scrii un prompt complex prin care te rogi de model să-și formateze corect răspunsul, definești un model Pydantic standard. Creezi o clasă numită ContactInfo și definești name, email și phone ca required fields. Apoi, pur și simplu pasezi această schemă Pydantic parametrului response format din configurația language model-ului tău. Nu trebuie să dai exemple sau să scrii custom validation scripts.
Asta e partea care contează. Când furnizezi acea schemă Pydantic, LangChain determină automat cel mai sigur mod de a o aplica. Face asta selectând discret între două execution paths diferite.
Mai întâi, verifică dacă language model-ul ales are un feature oficial de structured output integrat în API-ul său. Dacă are, LangChain face auto-select pe Provider Strategy. Această strategie face push la schema ta direct către provider, folosindu-se de constrângerile lor native, server-side, pentru a garanta output format-ul.
Dar hardware-ul se schimbă și modelele sunt înlocuite. Dacă decizi să folosești un alt model care nu are native structured output, LangChain detectează acest capability gap. Face automat fallback la Tool Strategy. Under the hood, îți traduce schema ContactInfo într-un function signature. Îi spune modelului despre un fake tool care necesită exact un name, un email și un phone number ca să ruleze. Modelul încearcă să apeleze acest tool, și făcând asta, generează exact acele structured arguments de care ai nevoie. Codul aplicației tale nu trebuie să se modifice niciodată pentru a acomoda schimbarea.
Când operațiunea se termină, developerii își caută adesea datele în locul greșit. Ai putea presupune că output-ul este returnat ca raw text pe care încă trebuie să-l parsezi. Nu este raw text. LangChain interceptează payload-ul și instanțiază obiectul Pydantic pentru tine. Plasează acest obiect Python complet validat direct în application state-ul tău. Îl vei găsi capturat în cheia structured response din state dictionary-ul tău. Pur și simplu faci referință la acea cheie și ai imediat obiectul ContactInfo, cu type-safe fields gata de pasat către restul aplicației tale.
Prin mutarea poverii de schema validation de la custom parsing logic către framework layer, integrările tale de language model devin la fel de previzibile ca un API call standard.
Mersi că m-ai ascultat — ne auzim data viitoare.
10
Interceptarea Buclei Agentului
3m 30s
Introducem paradigma middleware, oferindu-ți un control chirurgical asupra execuției agentului tău. Vei învăța cum să folosești hook-uri wrap-style și node-style pentru a intercepta apelurile modelelor.
Salut, sunt Alex de la DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episodul 10 din 20. Dacă agentul tău dă fail silențios în production, adesea este pentru că nu urmărești ce se întâmplă între pașii din reasoning loop-ul său. Modelul dă crash, loop-ul se întrerupe și rămâi uitându-te la un run incomplet. Interceptarea agent loop-ului cu un custom middleware este modul prin care recâștigi controlul.
Când un agent rulează un ciclu ReAct, transferă constant controlul înainte și înapoi către language model. Middleware-ul oferă hook-uri pentru a-ți executa logica exact atunci când ai nevoie în timpul acelui schimb. Există două tipuri principale de hook-uri pe care le vei folosi: node-style hooks și wrap-style hooks. O greșeală comună este să le tratezi ca fiind interschimbabile. Node-style hooks rulează secvențial. Wrap-style hooks chiar încadrează execuția și pot prinde excepții.
Node-style hooks folosesc decoratori numiți before model și after model. Când atașezi un before model hook la o funcție, framework-ul îți rulează complet logica și abia apoi declanșează API-ul de language model. Când modelul răspunde, rulează un after model hook. Aceste hook-uri sunt excelente pentru a face log la prompt-ul exact trimis către API, pentru a injecta context sau pentru a elimina caracterele greșite din output-ul final de text. Dar pentru că rulează strict în secvență, nu oferă nicio protecție împotriva fail-urilor. Dacă API-ul de language model dă timeout, after model hook-ul tău nu se execută niciodată. Eroarea face bubble up și dă crash la întregul agent loop.
Asta e partea care contează. Dacă trebuie să gestionezi instabilitatea, folosești un wrap-style hook. Decoratorul pentru asta este wrap model call. Un wrap hook stă în întregime în jurul execuției modelului. Funcția ta rulează, face niște setup, și apoi cedează explicit controlul către model. Pentru că acel custom code al tău face wrap la network call-ul propriu-zis, poți plasa acea execuție în structuri standard de error handling.
Ia în considerare construirea unui wrap model call middleware pentru a gestiona API rate limits cu un retry loop cu exponential backoff. Scrii o funcție decorată cu wrap model call. În interiorul acestei funcții, creezi un retry loop. Plasezi comanda care cedează controlul modelului în interiorul unui try block. Dacă modelul reușește, prinzi răspunsul, îl returnezi, iar loop-ul se termină. Dacă modelul aruncă o eroare, catch block-ul tău o interceptează. În loc să dea fail agentului, catch block-ul tău declanșează o pauză. Calculezi un delay scurt, aștepți, și apoi lași loop-ul să încerce call-ul din nou, dublând delay-ul de fiecare dată.
Orchestratorul agentului nu vede niciodată fail-urile. Middleware-ul prinde excepțiile, gestionează logica de retry în izolare și transmite fără probleme un răspuns de succes înapoi către ReAct loop-ul principal atunci când, în sfârșit, reușește.
Node-style hooks pregătesc input-urile și formatează output-urile, dar wrap-style hooks protejează execuția. Asta e tot pentru acest episod. Ne auzim data viitoare!
11
Ingineria Dinamică a Contextului
3m 52s
Aprofundăm ingineria contextului prin generarea dinamică a prompturilor de sistem. Vei învăța cum să folosești middleware pentru a modifica instrucțiunile în funcție de rolul utilizatorului curent și de mediu.
Salut, sunt Alex de la DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episodul 11 din 20. Principalul motiv pentru care agentul tău dă greș nu e pentru că modelul din spate e prost. Ci pentru că i-ai dat contextul greșit pentru acest task. Dacă sistemul tău tratează un superuser și un guest exact la fel, aplicația ta e oarbă la realitate. Ca să reparăm asta, folosim Dynamic Context Engineering.
Mai întâi, hai să clarificăm o idee greșită des întâlnită despre cum sunt construite prompt-urile. Contextul dinamic nu este system prompt-ul de bază pe care îl scrii atunci când îți definești inițial agentul în cod. Acel system prompt inițial este complet static. Dynamic Context Engineering este procesul de modificare a acelui prompt din mers, cu doar câteva milisecunde înainte ca modelul să fie apelat efectiv. Context engineering înseamnă să oferi modelului de limbaj exact regulile de care are nevoie pentru un anumit utilizator la un moment dat, și nimic mai mult.
Dacă încerci să înghesui fiecare regulă posibilă într-un singur prompt static masiv - spunându-i modelului cum să acționeze dacă utilizatorul e admin, cum să acționeze dacă e viewer și cum să acționeze dacă e marți - irosești tokeni și derutezi modelul. În schimb, vrei să injectezi dinamic doar regulile care contează în acest moment.
În LangChain, acest lucru este gestionat folosind un decorator specific numit dynamic underscore prompt. Plasezi acest decorator deasupra unei funcții Python pe care o definești tu. Când aplicația ta primește un query și declanșează chain-ul, LangChain face o pauză. Caută orice funcție wrapped cu acest decorator și o execută înainte de a comunica cu modelul.
În interiorul funcției tale decorate, ai nevoie de o modalitate de a ști ce se întâmplă în acel moment. Aici citești din request dot runtime dot context. Acest obiect de context este în esență un dicționar. El conține toate metadatele live transmise în chain atunci când l-ai invocat. Poți pune orice dorești acolo din backend-ul aplicației tale, cum ar fi user ID-uri, session states, feature flags sau niveluri de acces.
Hai să ne uităm la un scenariu concret. Scrii o funcție numită context aware prompt și îi faci wrap cu decoratorul dynamic prompt. În interiorul acestei funcții, citești rolul utilizatorului din runtime context. Verifici rolul. Dacă utilizatorul e admin, funcția ta adaugă un bloc specific de text la system prompt, spunând modelului de limbaj că are permisiune deplină să returneze comenzi distructive. Dacă utilizatorul e viewer, funcția ta adaugă un bloc de text diferit, oferind instrucțiuni stricte conform cărora modelul trebuie să returneze doar rezumate read-only și nu trebuie să sugereze niciodată modificări de configurare.
Acum, extragi o a doua bucată de date din runtime context, și anume starea mediului. Verifici dacă mediul este setat pe production. Dacă este, funcția ta adaugă un avertisment sever de siguranță chiar la finalul system prompt-ului, cerând modelului să își verifice de două ori output-ul pentru siguranță. Dacă mediul este doar de staging, omiți complet să adaugi acel avertisment.
Iată ideea de bază. Funcția ta preia base prompt-ul static, lipește regulile de admin sau viewer, adaugă avertismentul de production dacă e nevoie, și returnează string-ul final. LangChain preia acest string complet asamblat și îl trimite către modelul de limbaj. Modelul de limbaj nu știe niciodată că prompt-ul a fost asamblat din bucăți. El vede doar un set de instrucțiuni extrem de specifice, perfect adaptate. Făcând asta, îți menții system prompt-urile curate, precise și complet relevante pentru request-ul imediat.
Nu mai speri că modelul va ghici ce reguli se aplică, și începi să impui exact regulile necesare pentru starea curentă a aplicației tale.
Aș vrea să îmi iau un moment să îți mulțumesc pentru că ne asculți — ne ajută foarte mult. Să ai o zi grozavă!
12
AI Sigur cu Guardrails Deterministe
4m 08s
Ne securizăm agenții împotriva scurgerilor de date folosind middleware integrat. Vei învăța cum să aplici PIIMiddleware pentru a redacta automat informațiile sensibile înainte ca acestea să ajungă la model.
Salut, sunt Alex de la DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episodul 12 din 20. Un singur chat log care conține un număr de card de credit neredactat poate compromite instantaneu compliance-ul întregii tale aplicații. Nu te poți baza pe un language model să ignore politicos datele sensibile, iar să-i ceri modelului să se autocenzureze este un proces lent și imprevizibil. Aici intervine Safe AI cu Deterministic Guardrails.
Aceste guardrails deterministe sunt verificări hardcoded, bazate pe reguli. Ele se bazează pe pattern-uri și o logică previzibilă, cum ar fi regular expressions sau algoritmi ficși, în loc să ceară unui alt language model să evalueze textul. Pentru că fac bypass la network call-ul către un AI, se execută în milisecunde și nu costă practic nimic. Dacă construiești pentru producție, acest layer determinist este obligatoriu pentru securitate.
În framework, implementezi asta folosind PII Middleware. O greșeală frecventă pe care o fac developerii este să încerce să filtreze informațiile sensibile după aceea, scanând output-ul modelului. Dar, pentru a proteja privacy-ul utilizatorilor, PII Middleware este conceput să intercepteze mesajul raw exact în momentul în care utilizatorul dă send. El procesează textul înainte ca acel model call să fie măcar inițiat. Configurezi explicit acest comportament setând parametrul apply to input pe true.
Hai să trecem printr-un scenariu cu un agent de customer service. Un utilizator stresat trimite un mesaj în care spune că are contul blocat, incluzând adresa de email personală, iar apoi dă paste la tot numărul de șaisprezece cifre al cardului de credit pentru a-și verifica achiziția. Dacă codul tău trimite acel raw string către un third-party AI provider, ai încălcat regulile de bază de data compliance. Ai nevoie de o strategie pentru a neutraliza textul, iar middleware-ul îți oferă trei acțiuni built-in: block, redact și mask.
Dacă folosești strategia block, middleware-ul acționează ca un zid impenetrabil. În momentul în care detectează formatul cardului de credit, aruncă o eroare strictă și oprește complet acel chain. Request-ul este respins instant.
Dacă alegi strategia redact, middleware-ul elimină chirurgical datele specifice și introduce un placeholder curat. Adresa de email personală este complet ștearsă din string și înlocuită cu cuvântul email între paranteze. Language model-ul citește în continuare o propoziție coerentă și înțelege că a fost furnizat un email, dar datele reale au dispărut.
A treia strategie este mask. Mascarea păstrează o porțiune sigură din datele originale. Middleware-ul înlocuiește primele douăsprezece cifre ale cardului de credit cu asteriscuri, lăsând expuse doar ultimele patru numere. Asta este foarte eficient atunci când sistemul tău de backend trebuie să verifice un cont fără să expună toate datele financiare.
Implementarea acestui lucru necesită configurarea middleware-ului înainte ca acel chain să ruleze. Instanțiezi PII Middleware și îi oferi o listă de entități target. În acest caz, specifici email și credit card. Apoi, atribui strategiile alese acelor entități, alegând poate redact pentru email și mask pentru card. În cele din urmă, atașezi această componentă de middleware la chain-ul tău principal, asigurându-te că setezi parametrul apply to input. În momentul în care utilizatorul trimite mesajul, regulile deterministe curăță textul, iar AI-ul primește doar un prompt igienizat.
Iată ideea principală. Cea mai sigură modalitate de a gestiona informațiile personale sensibile în orice arhitectură de generative AI este să garantezi că language model-ul nu le vede niciodată de la bun început. Asta e tot pentru acest episod. Mulțumesc pentru audiție și continuă să construiești!
13
Pauză pentru Aprobare Umană
4m 28s
Explorăm execuția instrumentelor cu miză mare prin adăugarea unui om în buclă (human-in-the-loop). Vei învăța cum să oprești execuția unui agent pentru a aproba, edita sau respinge acțiuni sensibile.
Salut, sunt Alex de la DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episodul 13 din 20. Un agent autonom este incredibil de puternic, până în momentul în care trimite automat un e-mail cu o schiță a datelor tale financiare către clientul greșit. Unele acțiuni sunt pur și simplu prea riscante pentru a fi executate fără să fie verificate de un om. Tocmai de aceea folosim pauza pentru aprobare umană.
Agenții execută automat tools pe baza prompturilor de la utilizator. Acest comportament este ideal pentru citirea datelor, dar este periculos pentru acțiunile distructive sau ireversibile. Avem nevoie de o modalitate de a pune pe pauză execuția, de a întreba un om dacă o acțiune este sigură, și apoi de a relua sau anula.
Înainte de a discuta despre mecanisme, trebuie să clarificăm o cauză comună de eroare. Inginerii configurează uneori interrupts și apoi se întreabă de ce agentul pur și simplu dă crash sau își dă restart. Trebuie să ai un checkpointer activat. Nu poți pune pe pauză un agent dacă nu își poate aminti unde a rămas. Întreaga memorie a agentului și progresul curent trebuie salvate în persistence layer în timp ce așteaptă un răspuns uman. Fără checkpointer nu există pauză.
Cu persistența activă, poți gestiona execuția de tools în siguranță folosind middleware-ul Human In The Loop. Imaginează-ți o configurație în care agentul tău are două tools: un search tool și un delete database tool. Vrei ca agentul să caute liber, dar sub nicio formă nu vrei să dea drop la tabele fără permisiune.
Când configurezi acest middleware, setezi un argument numit interrupt on. Îi pasezi numele specifice ale acelor tools care necesită supraveghere. În scenariul nostru, configurezi interrupt on pentru a urmări doar acel delete database tool. Search tool-ul este ignorat de middleware și se execută imediat de fiecare dată când agentul îl apelează. Totuși, când agentul decide că trebuie să folosească delete database tool-ul, middleware-ul interceptează request-ul. Acesta pune pe pauză graph-ul, salvează starea curentă în checkpointer-ul tău și oprește complet execuția.
Graph-ul este acum suspendat în persistence layer, așteptând intervenția umană. Operatorul uman revizuiește tool call-ul în așteptare și are trei modalități de a răspunde către middleware.
Primul tip de decizie este approve. Omul analizează parametrii generați de agent, este de acord că sunt corecți și trimite o comandă de aprobare. Graph-ul se activează și execută ștergerea exact așa cum a planificat inițial agentul.
Al doilea tip de decizie este reject. Operatorul vede că agentul încearcă să șteargă ținta greșită și trimite o respingere. Tool-ul nu se execută. În schimb, agentul primește o observație care indică faptul că acțiunea a fost blocată de un om. Agentul procesează apoi acest feedback și poate fie să încerce o abordare diferită, fie să ceară clarificări utilizatorului.
Iată ideea principală. A treia opțiune este edit. Uneori, agentul are în mare parte dreptate, dar face o eroare minoră, cum ar fi faptul că targetează mediul de production în loc de mediul de staging. În loc să dea reject complet acțiunii și să forțeze agentul să gândească din nou problema, operatorul poate modifica direct parametrii de input ai tool-ului. Omul schimbă mediul target în staging și trimite call-ul corectat. Agentul își reia execuția și execută acțiunea folosind parametrii modificați, mergând mai departe fără probleme.
Prin utilizarea acestui middleware, îți protejezi sistemul de greșeli periculoase. Pauza pentru aprobare umană nu doar că previne catastrofele, ci îți transformă agentul dintr-o entitate imprevizibilă într-un colaborator supravegheat, care poate gestiona în siguranță operațiuni cu miză mare.
Asta e tot pentru acest episod. Mulțumesc că ai ascultat și spor la construit!
14
Feedback în Timp Real de la Agent
3m 49s
Aprofundăm streaming-ul pentru a îmbunătăți drastic experiența utilizatorului. Vei învăța cum să interpretezi modurile de stream pentru a afișa live tokenii LLM alături de actualizări personalizate ale execuției instrumentelor.
Salut, sunt Alex de la DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episodul 14 din 20. Pe utilizatori nu îi deranjează să aștepte zece secunde pentru un răspuns complex, atâta timp cât le arăți ce face creierul în acele zece secunde. Un ecran gol îți dă senzația unei aplicații defecte. Soluția pentru latența percepută este Real-Time Agent Feedback.
Pentru a repara ecranul gol, LangChain expune un parametru numit stream mode atunci când îți execuți agentul sau graph-ul. Acesta controlează exact ce fel de date trimite agentul înapoi prin conexiune în timp ce rulează. Primul mod pe care trebuie să-l știi este modul messages. Acesta gestionează efectul clasic de typing. Face stream la token-urile brute din language model pe măsură ce sunt generate. Dacă modelul scrie un paragraf, aplicația ta primește chunk-urile de text unul câte unul, permițând UI-ului tău să se actualizeze fluid, în loc să aștepte întregul bloc de text.
Oamenii confundă adesea streaming-ul de token-uri pentru răspunsul final cu streaming-ul pentru intermediate reasoning. Sunt cu totul și cu totul diferite. Dacă agentul tău decide să apeleze un search tool, generarea de token-uri se oprește. Language model-ul așteaptă ca tool-ul să se termine. Dacă acel tool rulează timp de cinci secunde, UI-ul tău îngheață timp de cinci secunde. Modul messages singur nu îi spune utilizatorului ce face agentul de fapt în background. Arată doar ce spune language model-ul.
Pentru a rezolva problema de silent tool, folosești modul custom. Modul custom permite tool-urilor și node-urilor tale interne să emită propriile update-uri de status în timp real direct în stream. Pentru a implementa asta, folosești un utilitar LangChain numit get stream writer. Apelezi această funcție în interiorul codului tool-ului tău. Îți oferă un obiect writer, pe care îl poți folosi pentru a emite custom events înapoi către client în orice moment al execuției tool-ului.
Gândește-te la un tool lent de verificare a vremii. Agentul tău primește un prompt care cere prognoza și decide să apeleze weather tool-ul. În interiorul funcției Python pentru acel tool, preiei stream writer-ul. Pe măsură ce tool-ul începe să interogheze un API remote lent, folosești writer-ul pentru a emite un custom event cu un status precum Acquired data. Frontend-ul tău primește imediat acest custom event și afișează un loading spinner cu acel text. Utilizatorul știe că agentul lucrează. Odată ce API-ul remote returnează datele, tool-ul se termină, iar language model-ul preia controlul. Preia datele meteo brute, formulează un răspuns human-friendly, iar stream-ul de messages repornește, scriind prognoza finală pe ecran.
Iată ideea cheie. Nu trebuie să alegi un singur mod. Poți pasa o listă care conține atât messages, cât și custom parametrului de stream mode. LangChain va intercala automat token-urile din language model și log-urile din custom tool-ul tău într-un singur feed continuu. Frontend-ul tău doar verifică tipul de event pe măsură ce sosește. Dacă este un custom event, actualizezi indicatorul de status. Dacă este un message event, adaugi token-ul la chat bubble. Latența percepută scade la zero, deoarece sistemul comunică mereu cu utilizatorul.
Dacă vrei să ajuți la continuarea acestor episoade, poți susține emisiunea căutând DevStoriesEU pe Patreon. Mulțumesc pentru audiție, happy coding tuturor!
15
Persistența Cross-Session
3m 47s
Explorăm memoria pe termen lung pentru a construi agenți care își cunosc cu adevărat utilizatorii. Vei învăța cum să folosești LangGraph stores pentru a salva documente JSON în conversații complet diferite.
Salut, sunt Alex de la DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episodul 15 din 20. Pentru a construi un asistent cu adevărat personalizat, acesta trebuie să rețină că preferi răspunsurile scurte, chiar dacă i-ai spus asta acum trei săptămâni într-un chat complet diferit. Dacă te bazezi exclusiv pe memoria standard a conversațiilor, acea preferință dispare în momentul în care începi un nou thread. Mecanismul care previne această amnezie este persistența cross-session folosind paradigma Store.
Mulți dezvoltatori confundă checkpointerul cu store-ul. Iată diferența. Un checkpointer gestionează state-ul pe termen scurt. Reține un singur thread de conversație. Când utilizatorul creează un chat nou, checkpointerul pornește de la zero. Store-ul traversează acele limite ale thread-urilor. Permite agenților tăi să persiste și să recupereze informații la nivel global, în toate interacțiunile cu un anumit utilizator.
În esență, memoria pe termen lung din LangChain este doar un key-value store ierarhic. Persistă documente JSON. Ierarhia se bazează pe namespace-uri. Un namespace este o secvență de string-uri care se comportă exact ca un folder path pe computerul tău. Dacă vrei să stochezi date de profil, poți folosi un namespace care conține string-ul users, urmat de identificatorul utilizatorului. În interiorul acelui namespace, stochezi itemi. Fiecare item necesită un string key unic și un dictionary care reprezintă valoarea JSON.
Aici devine interesant. Tool-urile interacționează cu acest store direct prin runtime context. Nu pasezi niciodată manual store-ul prin graph state-ul tău.
Ia în considerare un custom tool numit save user info. Sarcina sa este de a captura o preferință de limbă vorbită. În timpul configurării, îți inițializezi aplicația cu un store backing, cum ar fi un in-memory store pentru testare locală. În logica tool-ului tău, accesezi instanța de store direct din runtime configuration-ul injectat. Extragi identificatorul utilizatorului din contextul curent. Apoi, apelezi metoda put pe store. Oferi namespace tuple-ul care conține cuvântul users și user ID-ul. Definești o cheie, cum ar fi language preference, și în final pasezi JSON dictionary-ul care conține valoarea, poate Spanish.
Store-ul persistă acest document. Săptămâni mai târziu, utilizatorul începe o conversație complet nouă. Thread state-ul este gol. Dar, deoarece agentul are acces la un retrieval tool, poate apela metoda get pe runtime store folosind exact același namespace și aceeași cheie. Extrage documentul JSON, citește preferința și răspunde imediat în spaniolă.
Separarea contextului conversațional pe termen scurt de memoria factuală pe termen lung menține aplicația ușoară. Checkpointerul nu se încarcă cu ani de istoric al utilizatorului, iar state-ul rămâne curat. Store-ul încarcă doar documentele JSON specifice pe care agentul decide în mod explicit să le facă fetch.
Tratarea contextului și a persistenței ca două sisteme complet distincte este singura modalitate de a scala un agent în mod fiabil. Checkpointerul păstrează prezentul, în timp ce store-ul păstrează trecutul.
Asta e tot pentru astăzi. Mulțumesc pentru ascultare — du-te și construiește ceva cool.
16
Paradigma Multi-Agent
4m 06s
Explicăm de ce agenții singulari eșuează și introducem arhitectura Subagents. Vei învăța cum un agent supervizor principal coordonează subagenții ca ferestre de context izolate pentru a preveni supraîncărcarea cu tokeni.
Salut, sunt Alex de la DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episodul 16 din 20. Când agentul tău unic de AI începe să dea greș din cauza propriei liste masive de tools și instrucțiuni care se bat cap în cap, să-i arunci un context window mai mare nu va rezolva problema. E timpul să nu mai construiești un script monolitic și să începi să angajezi o echipă. Exact aici intervine paradigma Multi-Agent.
Construim sisteme multi-agent pentru că agenții unici se lovesc de un zid cognitiv. Dă-i unui agent treizeci de tools, cinci pagini de system prompts și un istoric lung de conversație, și își va pierde concentrarea. Va apela un tool greșit sau va uita constrângerile. Abordarea multi-agent descompune acest proces. Permite dezvoltarea distribuită, unde echipe diferite gestionează agenți diferiți. Permite execuția în paralel. Cel mai important, impune o izolare strictă a contextului.
Astăzi ne concentrăm pe o arhitectură specifică, numită pattern-ul Subagents. Asta implică un agent supervisor principal care deleagă task-uri către subagenți specializați. Lumea confundă adesea un supervisor cu un simplu router. Un router este doar o funcție statică care se uită la un query și îl trimite pe un path fix. Un supervisor este un agent activ, care gândește. El menține acel state al conversației, decide ce subagenți să invoce pe parcursul mai multor turn-uri și sintetizează răspunsurile lor.
Iată ideea cheie. Subagenții oferă o izolare perfectă a contextului. Când acel supervisor îi cere unui subagent să facă ceva, subagentul pornește cu un context window complet curat. Are doar instrucțiunile și acele tools specifice de care are nevoie pentru job-ul său exact. Subagentul ar putea să facă greșeli, să apeleze tools de trei ori și să-și umple propriul scratchpad în timp ce își dă seama de răspuns. Acel supervisor nu vede niciodată această dezordine. Primește doar rezultatul final, curățat. Asta îți protejează agentul principal de context bloat și previne halucinațiile.
Pentru a conecta acel supervisor la subagenți, încapsulezi subagenții ca tools. Există două moduri de a face asta în LangChain. Prima metodă este tool-per-agent. Îi oferi acelui supervisor un tool specific pentru fiecare subagent. Dacă ai cinci subagenți, acel supervisor are cinci tools. A doua metodă este un single-dispatch tool. Aici, acel supervisor primește exact un tool numit ceva de genul delegate task. Acest tool necesită două input-uri: numele agentului target și descrierea task-ului.
Ia în considerare un scenariu single-dispatch. Ai un agent principal, un agent de research și un agent writer. Un user cere un raport de piață complex. Agentul principal decide că are nevoie de date mai întâi. Apelează acel single-dispatch tool, pasând agentul de research ca target și acel market query ca payload. Agentul de research pornește în propriul său context izolat, caută pe web, parsează documente și returnează un paragraf de rezumat. Agentul principal primește acest text. Apoi, agentul principal apelează din nou acel dispatch tool, de data asta având ca target agentul writer, pasând rezumatul de research și instrucțiunile de formatare. Agentul writer redactează raportul final și îl returnează agentului principal, care îl livrează user-ului.
Poți executa aceste subtask-uri diferit, în funcție de nevoile tale. Poți rula subagenții sincron, unde acel supervisor așteaptă ca agentul de research să termine înainte de a face orice altă acțiune. Dacă ai task-uri independente, cum ar fi research-ul a trei competitori diferiți, poți rula subagenții asincron. Acel supervisor face dispatch la toate cele trei task-uri simultan, ele se execută în paralel, iar acel supervisor așteaptă ca toate să returneze un rezultat înainte de a merge mai departe.
Gruparea task-urilor în subagenți nu este doar despre organizarea codului tău, ci este despre a controla strict ceea ce language model-ul este forțat să țină în memorie la un moment dat.
Asta e tot pentru acest episod. Îți mulțumesc că ai ascultat și continuă să construiești!
17
Agenți Bazați pe Stare
3m 50s
Explorăm modul în care agenții își pot modifica dinamic comportamentul. Vei învăța pattern-ul Handoffs pentru transferul controlului și pattern-ul Skills pentru încărcarea prompturilor specializate la cerere.
Salut, sunt Alex de la DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episodul 17 din 20. Nu trebuie să încarci creierul agentului cu fiecare scenariu posibil de la început. Să bagi cincizeci de pagini de instrucțiuni într-un singur system prompt face ca modelul tău să devină confuz, lent și costisitor. Trebuie doar să-l înveți cum să ceară manualul corect atunci când vine momentul. Acesta este mecanismul de bază din spatele agenților State-Driven.
Agenții State-Driven funcționează pe un principiu simplu. Comportamentul agentului se schimbă dinamic în funcție de state-ul curent al aplicației. Gestionăm asta folosind două pattern-uri principale: Skills și Handoffs. Ambele pattern-uri se bazează pe tools pentru a actualiza variabilele de state, care la rândul lor dictează ce se întâmplă mai departe în workflow.
Hai să ne uităm mai întâi la pattern-ul Skills. Acest pattern se referă la dezvăluirea progresivă a cunoștințelor. În loc să-i dai unui agent toate instrucțiunile de la început, îi dai un tool. Când agentul decide că are nevoie de mai multe informații pentru a rezolva o problemă, apelează acest tool. Tool-ul se execută, dar face mai mult decât să returneze un string modelului. Actualizează o variabilă de state specifică din aplicația ta. Layer-ul tău de orchestrare monitorizează acest state. Când detectează schimbarea, injectează dinamic un nou set de instrucțiuni sau capabilități în system prompt-ul agentului pentru următoarea interacțiune.
Ia ca exemplu un agent standard de customer support. Inițial, singura lui sarcină este să-și dea seama ce vrea clientul. Un utilizator întreabă despre un produs defect. Agentul apelează un tool pentru a colecta un ID de garanție. Execuția acestui tool actualizează o variabilă de state pentru a indica faptul că o cerere de garanție este activă. Aplicația citește acest nou state și încarcă dinamic un skill de refund specializat în prompt. Acest skill ar putea include regulile specifice pentru procesarea retururilor și accesul la o bază de date securizată de inventar. Capacitățile agentului au evoluat în mijlocul conversației, determinate în întregime de un state update.
Acum, ce se întâmplă dacă task-ul necesar este prea complex pentru a fi gestionat de agentul inițial, chiar și cu skill-uri noi? Aici intervine pattern-ul de Handoff. Handoff-urile folosesc de asemenea tools pentru a actualiza state-ul, dar în loc să încarce instrucțiuni noi în agentul curent, schimbarea de state transferă controlul către un agent complet diferit. Să revenim la scenariul nostru. Agentul de suport colectează ID-ul garanției, dar în loc să proceseze el însuși refund-ul, apelează un handoff tool. Acest tool actualizează o variabilă de rutare în state, schimbând agentul activ de la bot-ul de triaj la un agent specialist conceput exclusiv pentru retururi de valoare mare. Layer-ul de orchestrare vede această schimbare de state și direcționează următorul pas din workflow către specialist.
Acest punct de tranziție este locul în care lucrurile crapă adesea. Când faci handoff între agenți, noul agent are nevoie de contextul conversației. Mulți developeri încearcă să curețe istoricul pasând pur și simplu mesajele raw ale utilizatorului către noul agent. Nu face asta. Când faci handoff între agenți, trebuie să incluzi mesajul AI care conține acel tool call efectiv care a inițiat handoff-ul, și mesajul de tip Tool rezultat care confirmă că handoff-ul a avut loc. Dacă scoți acel tool call și mesajul Tool din array-ul de mesaje, istoricul conversației se strică. Noul model pierde lanțul logic de evenimente. Nu va ști cum a ajuns acolo și probabil va repeta întrebările la care utilizatorul a răspuns deja. Pasează întotdeauna istoricul de mesaje neîntrerupt.
Iată ideea de bază. State-ul nu este doar un memory store pasiv, ci acel control plane care dictează exact ce este capabil să facă sistemul tău în orice milisecundă.
Asta e tot pentru acest episod. Mulțumesc pentru audiție și continuă să construiești!
18
Fluxuri de Lucru Personalizate și Routere
4m 29s
Ieșim din bucla standard a agentului. Vei învăța cum să folosești LangGraph pentru a construi arhitecturi de rutare personalizate, combinând logica deterministă cu raționamentul agentic nedeterminist.
Salut, sunt Alex de la DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episodul 18 din 20. Uneori nu vrei ca un agent AI să decidă liber ce să facă în continuare. Vrei doar să execute un flowchart strict, determinist. Workflow-urile custom și routerele îți oferă exact acest nivel de control.
Când te bazezi exclusiv pe un agent loop standard, lași language model-ul să-și dea seama singur de fiecare pas. Poate să caute într-o bază de date, să realizeze că are nevoie de mai multe date, să caute din nou și, în cele din urmă, să răspundă. Asta e o abordare puternică, dar e imprevizibilă și adesea lentă. Workflow-urile custom din LangGraph te lasă să ieși din acest loop. Tu ești cel care desenează harta. Poți combina perfect logica deterministă, cum ar fi executarea unor scripturi exacte de data retrieval, cu raționamentul nedeterminist al agentului. Pui language model-ul într-o secvență strictă de evenimente.
Înainte să construim unul, trebuie să clarificăm o confuzie comună între un router și un supervisor. Un supervisor orchestrează activ o conversație multi-turn. Urmărește agenții cum vorbesc, decide cine urmează și gestionează dialogul în timp. Un router nu face asta. Un router este doar un pas de clasificare. Se uită la input, decide pe ce cale ar trebui să o ia workflow-ul, rutează datele și treaba lui e gata. Poate fi stateless sau stateful, dar nu este un manager conversațional.
Să ne uităm la un scenariu concret. Construiești un tool de tip knowledge base multi-sursă. Un utilizator pune o întrebare, iar răspunsul ar putea fi îngropat în pull request-uri pe GitHub, thread-uri pe Slack sau ambele. Nu vrei ca un singur agent să ghicească orbește unde să caute. Vrei un workflow structurat.
Mai întâi, creezi un routing node. Pasezi query-ul utilizatorului către un language model și îi ceri să dea ca output o listă simplă de destinații. Dacă query-ul este despre un bug fix recent, modelul ar putea da ca output cuvintele GitHub și Slack.
Asta e partea care contează. Nu trebuie să alegi o singură cale. Poți rula mai mulți agenți în același timp folosind Send API. În LangGraph, în loc să returneze un singur pas următor din logica ta condițională, funcția ta de routing returnează o listă de comenzi Send. Fiecare comandă asociază un nod destinație cu datele specifice de care are nevoie. Graph-ul vede mai multe comenzi Send și execută automat toate acele noduri țintă în paralel. Asta se numește fanning out.
În timpul fanning out-ului, workflow-ul ajunge la nodurile agentului tău. Într-un workflow custom, invocarea unui agent este simplă. Un agent este pur și simplu un proces runnable, executat în interiorul unei funcții standard de nod. Nodul Slack primește query-ul, rulează un agent Slack dedicat pentru a căuta pe canale, extrage contextul și îl returnează în state-ul general al graph-ului. Nodul GitHub face același lucru simultan pentru repository-urile de cod. Izolarea acestor agenți în interiorul unor noduri specifice asigură că ei fac doar treaba pentru care au fost construiți.
În cele din urmă, toate acele branch-uri paralele trebuie să conveargă. Faci fan in. Creezi un nod sintetizator care așteaptă ca agenții paraleli să termine. Citește state-ul general al graph-ului, preia contextul adunat de pe Slack și contextul adunat de pe GitHub, le pasează pe ambele unui language model final și generează un răspuns unic și curat pentru utilizator.
Adevărata putere a workflow-urilor custom constă în încapsularea naturii imprevizibile a large language models în fiabilitatea previzibilă a routing-ului software standard.
Asta e tot pentru episodul ăsta. Ne auzim data viitoare!
19
Comunicarea Agent-to-Agent
4m 24s
Explorăm endpoint-ul LangSmith A2A. Vei învăța cum agenții distribuiți, implementați pe servere complet diferite, pot conversa nativ folosind protocolul A2A RPC de la Google.
Salut, sunt Alex de la DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episodul 19 din 20. Ce se întâmplă când un agent construit în Python trebuie să comunice nativ cu un agent construit de o echipă complet diferită, care rulează pe un server complet diferit? Dacă te bazezi pe apeluri de funcții interne hardcoded, sistemul tău pică în momentul în care traversează o limită de rețea. Soluția este comunicarea Agent-to-Agent.
Agent-to-Agent, sau A2A, este un protocol de comunicare care permite sisteme multi-agent cu adevărat distribuite. Acesta permite agenților găzduiți pe servere complet diferite să mențină o conversație continuă fără a fi nevoie să partajeze același codebase sau spațiu de memorie local. În loc să încapsulezi totul într-o singură aplicație masivă, rutezi request-urile prin rețea.
Comunicarea se bazează strict pe un format definit de endpoint: slash a2a slash, urmat de ID-ul asistentului. Fiecare agent care participă la această rețea distribuită expune exact acest path de endpoint. Când un agent are nevoie de ajutor de la altul, trimite un request HTTP POST acolo. Payload-ul trimis către acest endpoint este structurat ca un mesaj JSON-RPC standard.
Pentru a menține coerența conversației pe mai multe hop-uri de rețea și servere diferite, protocolul utilizează doi identificatori distincți în payload-ul său. Dezvoltatorii îi confundă uneori pe aceștia doi, așa că le vom defini limitele. Primul este Context ID-ul. Context ID-ul este responsabil pentru continuitatea generală a thread-ului. Reprezintă întregul istoric general al conversației, de la primul prompt până la output-ul final. Al doilea este Task ID-ul. Task ID-ul identifică request-ul sau pasul specific din cadrul acelei singure ture. Context ID-ul se întinde pe întreaga sesiune. Task ID-ul se schimbă de fiecare dată când un agent îi cere celuilalt să efectueze o acțiune nouă.
Ia în considerare un scenariu practic în care Agentul A rulează pe un server care ascultă la portul 2024, iar Agentul B rulează pe un alt server la portul 2025. Agentul A își dă seama că are nevoie ca Agentul B să gestioneze un subtask specific, eventual să verifice inventarul extern. Agentul A pregătește un mesaj JSON-RPC. În interiorul acestui mesaj, include Context ID-ul existent, astfel încât Agentul B să știe cărei conversații în curs îi aparține. Agentul A generează, de asemenea, un Task ID complet nou pentru acest request specific de inventar.
Agentul A trimite acest payload către endpoint-ul A2A pe portul 2025, inserând ID-ul specific de asistent al Agentului B direct în path-ul URL-ului. Agentul B primește request-ul. Citește Context ID-ul pentru a recupera orice state de background necesar, procesează task-ul cerut în parametrii JSON-RPC și calculează rezultatul. Agentul B construiește apoi un răspuns JSON-RPC. Acest răspuns include explicit Task ID-ul exact pe care Agentul A l-a furnizat inițial. Agentul B trimite acest răspuns înapoi către Agentul A pe portul 2024. Agentul A primește rezultatul, face match între Task ID și request-ul său pending, și își continuă propria execuție internă.
Iată ideea cheie. Deoarece protocolul impune JSON-RPC standard și izolează state tracking-ul în identificatori specifici de Context și Task, niciun agent nu trebuie să știe cum funcționează intern celălalt. Nu mențin o conexiune socket deschisă constant. Pur și simplu transmit pe rând mesaje structurate înainte și înapoi peste limitele HTTP standard. Un server pune o întrebare, celălalt răspunde, iar task-ul general progresează.
Când separi thread-ul de conversație pe termen lung de execuția individuală a task-urilor pe termen scurt, poți scala rețelele multi-agent pe diferite servere și framework-uri la nesfârșit. Dacă găsești aceste episoade utile și vrei să susții emisiunea, poți căuta DevStoriesEU pe Patreon. Asta e tot pentru acest episod. Mulțumesc pentru audiție și continuă să construiești!
20
Viitorul este MCP
4m 45s
Privim spre viitor cu Model Context Protocol, care standardizează modul în care agenții accesează instrumente externe. Vei învăța cum să conectezi servere MCP la distanță la agentul tău folosind transporturi standard.
Salut, sunt Alex de la DEV STORIES DOT EU. LangChain v1.0 Orchestration Framework, episodul 20 din 20. De fiecare dată când vrei ca agentul tău să comunice cu o nouă bază de date sau un API, ajungi să scrii un wrapper custom. Codebase-ul tău se umple cu integrări fragile care crapă de fiecare dată când un API extern se modifică. Asta limitează cât de repede îți poți scala aplicațiile. Soluția pentru acest bottleneck de integrare este Model Context Protocol, sau MCP.
Gândește-te la MCP ca la un USB-C pentru agenții AI. Acesta standardizează modul în care tool-urile și contextul sunt expuse către large language models. Înainte de acest protocol, dacă voiai ca agentul tău să facă un query într-o bază de date și să verifice un serviciu meteo, trebuia să scrii funcții Python specifice pentru ambele, să le definești manual acele input schemas și să le faci bind la modelul tău. Cu MCP, serviciul extern în sine oferă o interfață standardizată. Agentul tău pur și simplu se conectează la el și înțelege instant ce tool-uri sunt disponibile, ce argumente cer și cum să le execute.
O confuzie frecventă este că folosirea unui server MCP remote înseamnă că logica agentului tău se mută în rețea. Iată ideea cheie. Agentul tău rămâne complet local. Serverul remote nu îți rulează agentul și nu îi controlează raționamentul. El doar expune o listă de JSON schemas standardizate care reprezintă tool-urile pe care le suportă. Agentul tău local citește acele schemas, decide ce tool să folosească pe baza acelui user prompt și trimite un execution request înapoi către server. Execuția are loc acolo, iar rezultatul raw este returnat agentului tău local.
În LangChain, gestionezi aceste conexiuni folosind MultiServerMCPClient. Această componentă acționează ca un hub central. Permite unui singur agent să se conecteze simultan la mai multe servere MCP diferite, colectând tool-uri de la toate. Clientul gestionează comunicarea din spate folosind diferite transport layers. Cele două transporturi principale pe care le vei configura sunt standard input și output, denumite stdio, și HTTP.
Hai să trecem printr-un scenariu concret. Construiești un agent care trebuie să facă niște calcule complexe folosind un script Python local, în timp ce face fetch la date meteo live de la un serviciu remote. În loc să scrii tool wrappers custom pentru aceste task-uri, configurezi MultiServerMCPClient să le gestioneze pe amândouă.
Mai întâi, îți definești serverul de mate local folosind transportul stdio. Configurezi clientul cu comanda de rulare, cum ar fi executabilul Python din sistem, și calea către scriptul tău de mate. Când clientul se inițializează, pornește acest script ca un background process local. Clientul LangChain și scriptul își pasează mesaje direct prin stream-urile de standard input și standard output.
Apoi, definești serverul meteo folosind transportul HTTP. Pentru asta, furnizezi doar endpoint URL-ul serviciului meteo remote. Acest setup se bazează de obicei pe Server-Sent Events pentru a menține o conexiune persistentă, permițând agentului să ceară acțiuni și să facă stream la răspunsuri pe web.
Odată ce ambele transporturi sunt definite, inițializezi MultiServerMCPClient. Clientul contactează imediat procesul de mate local via stdio și URL-ul meteo remote via HTTP. Le cere ambelor servere să îi predea definițiile de tool-uri. Colectează acele schemas, le dă merge într-o singură listă continuă și le oferă agentului tău LangChain. Din perspectiva agentului, el vede doar o listă unificată de tool-uri disponibile. Nu știe deloc că un tool se execută într-un binary process local, iar celălalt declanșează un HTTP request către un server de la capătul lumii.
Trecerea către protocoale standardizate înseamnă că îți poți petrece timpul construind o logică de agent mai bună, în loc să întreții la nesfârșit API wrappers. Pentru că acesta este episodul final al seriei, te încurajez cu tărie să citești documentația oficială LangChain și să încerci să configurezi hands-on un server MCP local. Dacă ai sugestii de subiecte pe care vrei să le vezi în următoarea noastră serie, vizitează devstories dot eu și lasă-ne un mesaj. Adevărata putere a unui agent nu stă în ceea ce știe, ci la ce se poate conecta seamless.
Asta e tot pentru acest episod. Îți mulțumesc că ai ascultat și continuă să construiești!
Tap to start playing
Browsers block autoplay
Share this episode
Episode
—
Copy this episode in another language:
Acest site nu folosește cookie-uri. Furnizorul nostru de hosting ar putea înregistra adresa ta IP în scopuri de analiză. Află mai multe.