0Pricing
AI Engineering Academy · Lekcja

Budowanie potoków wieloagentowych za pomocą LangGraph

Użyj LangGraph do zdefiniowania w grafie skierowanym węzłów agentów, krawędzi warunkowych i współdzielonego stanu, umożliwiając złożone przepływy wieloagentowe z pętlami, rozgałęzieniami i punktami kontrolnymi z udziałem człowieka.

Budowanie potoków wieloagentowych za pomocą LangGraph to bezpłatna lekcja AI Engineering Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej AI Engineering Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs AI Engineering Academy zawiera 4 lekcji w sumie.

Czym jest LangGraph?

LangGraph to biblioteka zbudowana na bazie LangChain, która umożliwia definiowanie przepływów pracy wielu agentów jako grafów skierowanych. Węzły grafu reprezentują agentów lub kroki przetwarzania, krawędzie reprezentują przepływ stanu między nimi, a krawędzie warunkowe umożliwiają dynamiczne wyznaczanie trasy na podstawie bieżącego stanu. LangGraph obsługuje mechanizm wykonywania, trwałość stanu oraz punkty kontrolne z udziałem człowieka.

# pip install langgraph
from langgraph.graph import StateGraph, END
from typing import TypedDict, Annotated
import operator

# Define your shared state schema
class AgentState(TypedDict):
    messages: Annotated[list, operator.add]  # append-only list
    research: str
    draft: str
    status: str

Definiowanie stanu w LangGraph

Każdy przepływ pracy LangGraph działa na współdzielonym obiekcie stanu, który wszystkie węzły mogą odczytywać i zapisywać. Stan jest typowanym słownikiem (TypedDict) przenoszącym dane przez graf. Po uruchomieniu węzeł otrzymuje bieżący stan, wykonuje swoją pracę i zwraca słownik aktualizacji do scalenia ze stanem. Ten model współdzielonego stanu umożliwia agentom komunikowanie się bez bezpośredniego powiązania.

from typing import TypedDict

class ResearchState(TypedDict):
    query: str           # input from user
    research_notes: str  # filled by researcher node
    written_draft: str   # filled by writer node
    review_feedback: str # filled by reviewer node
    final_output: str    # filled by synthesizer node
    iteration_count: int # tracks how many revision loops occurred

# Each node returns a PARTIAL update - only the keys it modifies
def researcher_node(state: ResearchState) -> dict:
    notes = do_research(state['query'])
    return {'research_notes': notes}  # only update this key

Tworzenie węzłów agentów

W LangGraph każdy agent jest funkcją węzła, która pobiera bieżący stan, wykonuje wywołanie LLM i uruchamia narzędzia, a następnie zwraca aktualizację stanu. Węzły są funkcjami czystymi — nie przechowują stanu wewnętrznego. Cały stan znajduje się we współdzielonym obiekcie stanu grafu, dzięki czemu przepływ pracy można łatwo przeglądać, wznawiać i debugować.

from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage, HumanMessage

llm = ChatOpenAI(model='gpt-4o')

def researcher_node(state: ResearchState) -> dict:
    messages = [
        SystemMessage(content='You are a research specialist. Find accurate information.'),
        HumanMessage(content=f'Research this topic: {state["query"]}')
    ]
    response = llm.invoke(messages)
    return {'research_notes': response.content}

def writer_node(state: ResearchState) -> dict:
    messages = [
        SystemMessage(content='You are a technical writer. Write clear, engaging prose.'),
        HumanMessage(content=f'Write a draft using these notes:\n{state["research_notes"]}')
    ]
    response = llm.invoke(messages)
    return {'written_draft': response.content}

Budowanie grafu za pomocą StateGraph

Po zdefiniowaniu funkcji węzłów należy połączyć je za pomocą StateGraph. Węzły dodaje się przy użyciu graph.add_node(), krawędzie między nimi — za pomocą graph.add_edge(), punkt wejścia ustawia się przez graph.set_entry_point(), a graf kompiluje do postaci wykonywalnej za pomocą graph.compile(). Skompilowany graf jest obiektem runnable, który przyjmuje stan początkowy i zwraca stan końcowy.

from langgraph.graph import StateGraph, END

# Build the graph
workflow = StateGraph(ResearchState)

# Add nodes
workflow.add_node('researcher', researcher_node)
workflow.add_node('writer', writer_node)
workflow.add_node('reviewer', reviewer_node)

# Add edges (sequential pipeline)
workflow.set_entry_point('researcher')
workflow.add_edge('researcher', 'writer')
workflow.add_edge('writer', 'reviewer')
workflow.add_edge('reviewer', END)

# Compile into an executable
app = workflow.compile()

# Run it
result = app.invoke({'query': 'What is RAG?', 'iteration_count': 0})
print(result['written_draft'])

Krawędzie warunkowe do dynamicznego wyznaczania trasy

Krawędzie warunkowe umożliwiają kierowanie przepływu grafu do różnych węzłów na podstawie bieżącego stanu. Zamiast stałej krawędzi przekazuje się funkcję wyznaczającą trasę, która analizuje stan i zwraca nazwę następnego węzła. Umożliwia to tworzenie pętli poprawek, bramek jakości, etapów zatwierdzania przez człowieka oraz rozgałęzień zależnych od treści wyników agentów.

def should_revise(state: ResearchState) -> str:
    '''Router function: returns the name of the next node.'''
    if state['iteration_count'] >= 3:
        return 'finalize'  # Too many revisions - accept as is
    if 'insufficient' in state.get('review_feedback', '').lower():
        return 'researcher'  # Need more research
    if 'rewrite' in state.get('review_feedback', '').lower():
        return 'writer'  # Needs rewriting
    return 'finalize'  # Looks good

# Add conditional edge from reviewer
workflow.add_conditional_edges(
    'reviewer',                    # from node
    should_revise,                 # routing function
    {
        'researcher': 'researcher', # route name -> node name
        'writer': 'writer',
        'finalize': 'finalizer'
    }
)

Pętle i iteracje w LangGraph

LangGraph natywnie obsługuje pętle — agenta można odwiedzić wielokrotnie. Jest to niezbędne w cyklach poprawek, wzorcach ponawiania po błędzie i iteracyjnym udoskonalaniu. Należy zawsze uwzględnić w stanie warunek zakończenia pętli (taki jak licznik iteracji lub próg wyniku jakości) i egzekwować go w routerze krawędzi warunkowych, aby zapobiec nieskończonym pętlom.

def researcher_node(state: ResearchState) -> dict:
    notes = do_research(state['query'])
    return {
        'research_notes': notes,
        'iteration_count': state['iteration_count'] + 1  # always increment
    }

def should_continue_research(state: ResearchState) -> str:
    # Terminate loop after 3 iterations regardless of quality
    if state['iteration_count'] >= 3:
        return END
    # Continue if research is incomplete
    if len(state.get('research_notes', '')) < 500:
        return 'researcher'  # loop back
    return 'writer'  # proceed to next stage

Równoległe wykonywanie węzłów

LangGraph obsługuje gałęzie równoległe z użyciem RunnableParallel wewnątrz węzła lub przez rozgałęzienie do wielu węzłów. Gdy niezależne podzadania muszą być wykonywane jednocześnie, można utworzyć rozgałęzienie z jednego węzła do wielu węzłów równoległych, a następnie węzeł scalający, który czeka na wszystkie wyniki i łączy je we współdzielonym stanie.

# Fan-out: one node triggers multiple parallel ones
workflow.add_edge('planner', 'researcher_a')
workflow.add_edge('planner', 'researcher_b')
workflow.add_edge('planner', 'researcher_c')

# Fan-in: aggregator waits for all three
workflow.add_edge('researcher_a', 'aggregator')
workflow.add_edge('researcher_b', 'aggregator')
workflow.add_edge('researcher_c', 'aggregator')
workflow.add_edge('aggregator', 'writer')

# Aggregator merges parallel results
def aggregator_node(state: ResearchState) -> dict:
    combined = state.get('notes_a', '') + '\n' + state.get('notes_b', '') + '\n' + state.get('notes_c', '')
    return {'research_notes': combined}

Punkty kontrolne i udział człowieka w pętli

LangGraph obsługuje punkty kontrolne dzięki integracji z mechanizmem zapisywania punktów kontrolnych (SQLite, Redis lub PostgreSQL). Po włączeniu punktów kontrolnych stan grafu jest zapisywany po wykonaniu każdego węzła. Umożliwia to wstrzymywanie, sprawdzanie i wznawianie długotrwałych przepływów pracy. Pozwala także tworzyć wzorce z udziałem człowieka w pętli, w których graf zatrzymuje się przy określonym węźle i czeka na zatwierdzenie lub dane od człowieka przed kontynuowaniem.

from langgraph.checkpoint.sqlite import SqliteSaver

# Use SQLite for persistent checkpoints
checkpointer = SqliteSaver.from_conn_string(':memory:')
app = workflow.compile(checkpointer=checkpointer, interrupt_before=['human_review'])

# First run - pauses at human_review node
thread = {'configurable': {'thread_id': 'my-workflow-1'}}
result = app.invoke({'query': 'Analyze competitors'}, config=thread)
# result.next == 'human_review' -- waiting for human input

# Human provides feedback and resumes
app.update_state(thread, {'review_feedback': 'Good research, proceed with writing'})
final = app.invoke(None, config=thread)  # resume from checkpoint

Strumieniowanie wyników LangGraph

LangGraph obsługuje tryb strumieniowania, który emituje pośrednie aktualizacje stanu po zakończeniu każdego węzła, zamiast czekać na ukończenie całego przepływu pracy. Jest to przydatne w długich potokach, w których chcą Państwo wyświetlać użytkownikowi częściowy postęp. Użyj app.stream(), aby otrzymać iterator migawek stanu z każdego kroku.

# Stream intermediate results as each node completes
for event in app.stream({'query': 'What is RAG?'}):
    for node_name, node_output in event.items():
        print(f'Node completed: {node_name}')
        if 'research_notes' in node_output:
            print('Research done:', node_output['research_notes'][:100])
        if 'written_draft' in node_output:
            print('Draft done:', node_output['written_draft'][:100])

Wizualizacja grafu

LangGraph może rysować graf jako diagram Mermaid, co jest niezwykle pomocne w rozumieniu złożonych przepływów pracy z wieloma węzłami i krawędziami warunkowymi. Wywołaj app.get_graph().draw_mermaid_png(), aby uzyskać obraz PNG, lub app.get_graph().draw_mermaid(), aby otrzymać składnię Mermaid, którą można wkleić do dowolnego generatora Mermaid.

# Visualize the workflow graph
graph_image = app.get_graph().draw_mermaid_png()
with open('workflow.png', 'wb') as f:
    f.write(graph_image)

# Or print Mermaid syntax
print(app.get_graph().draw_mermaid())
# Outputs:
# graph TD
#    __start__ --> researcher
#    researcher --> writer
#    writer --> reviewer
#    reviewer -->|Good| finalize
#    reviewer -->|Needs work| researcher

Kompletny przykład agenta LangGraph

Podsumowując: kompletny potok wieloagentowy LangGraph definiuje stan TypedDict, tworzy funkcje węzłów dla poszczególnych agentów, łączy je za pomocą StateGraph, dodaje krawędzie warunkowe dla pętli poprawek, kompiluje graf z mechanizmem zapisywania punktów kontrolnych i uruchamia go ze stanem początkowym. Daje to solidny, obserwowalny i możliwy do wznowienia przepływ pracy wielu agentów przy minimalnej ilości kodu pomocniczego.

Szybki sprawdzian

Sprawdź, czy rozumieją Państwo potoki wieloagentowe LangGraph omówione w tej lekcji.

Podsumowanie lekcji

W tej lekcji nauczyli się Państwo, że LangGraph przedstawia przepływy pracy wielu agentów jako grafy skierowane, w których węzły są agentami, a krawędzie — przepływem, że krawędzie warunkowe umożliwiają dynamiczne wyznaczanie trasy, pętle i cykle poprawek na podstawie bieżącego stanu oraz że punkty kontrolne pozwalają wstrzymywać i wznawiać długotrwałe przepływy pracy z zatwierdzaniem przez człowieka. W następnej części omówimy pamięć współdzieloną i komunikację między agentami.

Często zadawane pytania

Czy lekcja „Budowanie potoków wieloagentowych za pomocą LangGraph” jest bezpłatna?

Tak — pełny tekst „Budowanie potoków wieloagentowych za pomocą LangGraph” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu AI Engineering Academy, przejdź na CoddyKit PRO. Kurs AI Engineering Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Budowanie potoków wieloagentowych za pomocą LangGraph”?

Użyj LangGraph do zdefiniowania w grafie skierowanym węzłów agentów, krawędzi warunkowych i współdzielonego stanu, umożliwiając złożone przepływy wieloagentowe z pętlami, rozgałęzieniami i punktami k… Ćwiczysz AI Engineering Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć AI Engineering Academy?

Nie wymagamy żadnego doświadczenia. AI Engineering Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Budowanie potoków wieloagentowych za pomocą LangGraph”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji AI Engineering Academy?

Tak. Każda lekcja AI Engineering Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Dlaczego pojedyncze agenty napotykają ograniczenia
  2. Wzorzec orkiestrator–subagent
  3. Budowanie potoków wieloagentowych za pomocą LangGraph
  4. Współdzielona pamięć i komunikacja między agentami
← Powrót do AI Engineering Academy