Strona główna / Artykuły / Wskazówki praktyczne: Przewodnik po architekturach wielu agentów

Wskazówki praktyczne: Przewodnik po architekturach wielu agentów

Praktyczne wskazówki: Przewodnik terenowy po architekturach wielu agentów – umowy, sprawdzania oraz gotowe miejsca na kod dla zespołów wdrażających ten wzorzec.

3174 słów

To przewodnictwo pokazuje, jak przejść od surowców do gotowego systemu w ramach: Przewodnika terenowego po architekturach wieloagentowych. Skupia się na krokach realizowalnych w praktyce, wyraźnych sprawdzeniach oraz kodzie, który można bez problemu dodać do repozytorium, nie musząc zgadywać intencji twórcy. Na etapie przeglądu należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie wykonać dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu systemu. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nazwij poszczególne elementy, zdefiniuj kryteria sukcesu i odrzuć przypadkowe, częściowe ukończenie zadań.

1. Hierarchiczne systemy wieloagentowe

Gdy przechodzisz przez pierwszy etap Hierarchical Multi-Agent Systems, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Obok wyników funkcjonalnych zapisz czas trwania oraz koszt tokenów lub zapytań. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy przechodzi się od wersji demonstracyjnej do środowisk współdzielonych. Utwórz punkt kontrolny po kosztownych krokach. Program powinien unikać ponownego naliczania opłat za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł.

from fundamental_analysis_tools import evaluate_fundamentals
from langchain.agents import create_agent
from technical_analysis_tools import technical_analysis

agent = create_agent(
    model=llm,
    tools=[technical_analysis, evaluate_fundamentals]
)
Supervisor
├── Technical Analysis Tool
└── Fundamental Analysis Tool
Supervisor
├── Technical Analyst Agent
│   ├── Tool A
│   ├── Tool B
│   └── ...
└── Fundamental Analyst Agent
    ├── Tool C
    ├── Tool D
    └── ...
from langchain.tools import tool
from langgraph_supervisor import create_supervisor

@tool
def get_weather(city: str) -> str:
    """Use this tool to get the weather of a city or location"""
    return f"The weather is sunny in {city}"

weather_expert = create_agent(
    model=llm,
    tools=[get_weather],
    name="weather_expert"
)

technical_analyst_agent = create_agent(
    model=llm,
    tools=[technical_analysis],
    name="technical_analyst"
)

fundamental_analyst_agent = create_agent(
    model=llm,
    tools=[evaluate_fundamentals],
    name="fundamental_analyst"
)

analysis_squad = create_supervisor(
    [technical_analyst_agent, fundamental_analyst_agent],
    model=llm,
    supervisor_name="analysis_supervisor",
    prompt=(
        "You are a team supervisor managing a fundamental analyst and a "
        "technical analyst..."
    )
)

analysis_app = analysis_squad.compile(
    name="fundamental_and_technical_analyst"
)

supervisor_graph = create_supervisor(
    [analysis_app, weather_expert],
    model=llm,
    prompt=(
        "You are a team supervisor managing a fundamental analyst, a "
        "technical analyst and a weather expert..."
    )
)

supervisor = supervisor_graph.compile()

Kiedy należy używać architektury hierarchicznej?

Gdy pracujesz nad etapem „Kiedy należy to użyć”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Przechowuj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury. Ustaw punkty kontrolne po kosztownych krokach. System powinien unikać ponownego naliczania opłat za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł.

2. Wyraźne przepływy pracy z wieloma agentami

Gdy przechodzisz przez etap 2 Explicit Multi Agent, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zdokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponowne, kontrola przez ludzi oraz obsługa wiadomości nieodebranych stanowią część produktu, a nie elementy dodawane później. Ustaw punkty kontrolne po kosztownych krokach. Narzędzie do kontynuacji pracy nie powinno ponownie naliczać opłat za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł. Gdy przechodzisz przez etap 2 Explicit Multi Agent, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzucaj ciche, częściowe ukończenie zadań.

def execute_plan(
    plan: Plan,
    state: State,
) -> Command[
    Literal[
        "fundamental_analysis_agent",
        "technical_analysis_agent",
        "respond",
    ]
]:
    gotos = [
        Send(
            step.action.agent_to_use,
            {"query": step.action.query_to_send},
        )
        for step in plan.steps
    ]

    if not gotos:
        gotos.append(
            Send("respond", {"messages": state["messages"]})
        )

    return Command(goto=gotos)

def router(state: State) -> Command[
    Literal["fundamental_analysis_agent", "technical_analysis_agent", "respond"]
]:
    # Get plan
    query = state['messages'][-1].content
    response = llm_planner.invoke(query) #invoke planner
    return execute_plan(response, state)

Kiedy stosować wyraźne workflow z wieloma agentami

Metoda „Kiedy używać wyraźnej fazy” działa najlepiej, gdy traktuje się ją jako mierzalną powierzchnię. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę o cofnięciu zmian, zanim rozszerzysz zakres pracy. Zapisuj czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy przechodzi się z środowiska demonstracyjnego do współdzielonych środowisk. Utrzymuj stan grafu w prostej formie i z określonym typem danych. Wplecione elementy ukrywają informację o tym, który węzeł zapisał dane do którego pola, i powodują przerwanie kontynuacji po przerwach.

3. Agent Swarm

Faza 3 Agent Swarm działa najlepiej, gdy traktuje się ją jako mierzalną powierzchnię. Zabezpiecz jeden „złoty” zapis, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres działania. Przechowuj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całego grafu. Utrzymuj stan grafu w formie prostych, typizowanych struktur. Wplecione bloki danych ukrywają informację o tym, który węzeł zapisał dane w danym polu, co powoduje przerwanie kontynuacji działania po zakłóceniach.

from langgraph_swarm import (
    create_handoff_tool,
    create_swarm,
)

## We'll have to redefine our all agents to include the handoff tool
weather_expert = create_agent(
    model=llm,
    tools=[
        get_weather,
        create_handoff_tool(
            agent_name="technical_analyst",
            description="Transfer for technical analysis related questions"
        ),
        create_handoff_tool(
            agent_name="fundamental_analyst",
            description="Transfer for fundamental analysis related questions"
        ),
    ],
    name="weather_expert"
)
technical_analyst_agent = ...
fundamental_analyst_agent = ...

swarm_workflow = create_swarm(
    [fundamental_analyst_agent, technical_analyst_agent, weather_expert],
    default_active_agent="weather_expert" #a default agent must be specified.
)

swarm = swarm_workflow.compile()

Kiedy należy używać swarmu?

Metoda „When should you use stage” funkcjonuje najlepiej, gdy jest traktowana jako mierzalna struktura. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres projektu. Zdokumentuj zarówno prawidłowy przebieg działania, jak i ścieżkę przywracania do normalnego stanu. Próby ponownych działań, kontrolne punkty ludzkie oraz obsługa wiadomości nieprzyjętych stanowią część produktu, a nie elementy dodawane później. Utrzymuj stan grafu w prostej formie i z określonym typem danych. Wложone struktury ukrywają informację o tym, który węzeł zapisał dane w danym polu, co powoduje przerwanie kontynuacji działania po zakłóceniach. Metoda „When should you use stage” funkcjonuje najlepiej, gdy jest traktowana jako mierzalna struktura. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres projektu. Traktuj tę fazę jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzucaj ciche, częściowe ukończenie zadań.

4. Systemy wielu agentów typu Blackboard

Dla etapu 4 Blackboard Multi Agent należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy zapisywać czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega nieoczekiwanym rachunkom, gdy ścieżka przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Konieczne jest ludzkie zatwierdzenie dla operacji, które powodują wydatki lub zmiany w danych produkcyjnych. Połączenia realizowane w czasie kompilacji nie gwarantują pełnej kompletności biznesowej.

a. Tablica czarna

Dla etapu tablicy czarnej należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Konfigurację należy przechowywać poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury. Wprowadź ludzką aprobatę dla połączeń, które powodują wydatki lub zmieniają dane produkcyjne. Połączenia ustalane w czasie kompilacji nie równają się pełności funkcjonalności biznesowej.

class Blackboard(TypedDict, total=False):
    query: str

    # Problem frame
    problem_framed: bool
    ticker: str | None
    location: str | None
    wants_technical: bool
    wants_fundamental: bool

    # Specialist panels
    technical: dict | None
    fundamental: dict | None
    environmental: dict | None

    # Integrated solution
    synthesis: str | None

    # Control state
    next_knowledge_source: str | None
    cycles: int

b. Źródła wiedzy

W fazie źródeł wiedzy należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy udokumentować zarówno prawidłowy przebieg procesu, jak i ścieżkę naprawczą. Próby ponownych działań, kontrola przez ludzi oraz obsługa nieudanych transakcji stanowią część produktu, a nie elementy dodawane później. Konieczne jest uzyskanie zatwierdzenia człowieka w przypadkach, gdy dochodzi do wydawania pieniędzy lub zmiany danych produkcyjnych. Połączenia realizowane w czasie kompilacji nie równają się pełnej kompletności rozwiązania biznesowego. W fazie źródeł wiedzy należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Traktuj tę fazę jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Należy nadać nazwy poszczególnym elementom, zdefiniować kryteria sukcesu oraz odrzucić przypadki cichego, częściowego ukończenia zadania.

def can_analyse_technicals(board: Blackboard) -> bool:
    return (
        board.get("ticker") is not None
        and board.get("wants_technical", False)
        and board.get("technical") is None
    )

c. Komponent sterujący

Podczas przechodzenia przez etap c. Komponent sterujący, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Obok wyników funkcjonalnych zapisz czas trwania oraz koszt tokena lub zapytania. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy ścieżka przechodzi z wersji demonstracyjnej do środowisk współdzielonych. Ustal punkty kontrolne po kosztownych krokach. Narzędzie do kontynuacji nie powinno ponownie naliczać opłaty za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł.

def control_component(board: Blackboard) -> dict:
    eligible = [
        source
        for source in KNOWLEDGE_SOURCES #these are subagents
        if source.precondition(board)
    ]
    if not eligible:
        return {"next_knowledge_source": None}
    chosen = max(
        eligible,
        key=lambda source: source.priority,
    )
    return {
        "next_knowledge_source": chosen.name,
        "cycles": board.get("cycles", 0) + 1,
    }
inspect → identify eligible specialists → activate one
       → contribute → inspect again

Egzekucja jest celowo sekwencyjna

Gdy przechodzisz przez etap wykonywania, który jest celowo sekwencyjny, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Przechowuj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury. Ustaw punkty kontrolne po kosztownych krokach. System powrotu nie powinien ponownie naliczać opłat za tę samą wywołanie LLM, gdy operator ponawia próbę z późniejszym węzłem.

Kiedy należy używać architektury typu „blackboard”?

Gdy pracujesz nad etapem „Kiedy należy to użyć”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Dokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponowne, kontrola przez ludzi oraz obsługa wiadomości błędnych stanowią część produktu, a nie elementy dodawane później. Ustalaj punkty kontrolne po kosztownych krokach. System nie powinien ponownie naliczać opłat za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł. Gdy pracujesz nad etapem „Kiedy należy to użyć”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzucaj ciche, częściowe ukończenie zadań.

5. Systemy wielu agentów typu Actor-Critic (adwersarialne)

5-etapowy model Adversarial Multi Stage z aktorem-krytykiem funkcjonuje najlepiej, gdy traktowany jest jako mierzalna struktura. Zanim rozszerzysz zakres, zapisz jeden idealny przykład działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań. Zapisuj czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy przechodzi się z środowiska demonstracyjnego do współdzielonych środowisk. Utrzymuj stan grafu w formie prostych, spójnie skategoryzowanych elementów. Wtórne struktury ukrywają informację o tym, który węzeł zapisał dane w danym polu, i powodują przerwę w kontynuacji działania po zakłóceniach.

actor → critic → judge
  ↑                 |
  └──── revise ─────┘

a. Aktor

Scena „The Actor” funkcjonuje najlepiej, gdy traktowana jest jako mierzalna powierzchnia. Zapisz jeden przykład udanego działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Przechowuj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, aby operatorzy mogli je sprawdzić bez konieczności przeglądania całej struktury. Utrzymuj stan struktury w formie prostych, typizowanych elementów. Wplecione dane ukrywają informację o tym, który węzeł zapisał dany pole, co powoduje przerwę w kontynuacji pracy po zakłóceniach.

def actor(state: AdversarialState) -> dict:
    if state.get("latest_critique") is None:
        prompt = f"Produce a first draft.\n\nTASK: {state['task']}"
    else:
        prompt = (
            "Revise the current draft.\n\n"
            f"TASK:\n{state['task']}\n\n"
            f"CURRENT DRAFT:\n{state['draft']}\n\n"
            f"CRITIQUE:\n{state['latest_critique']}\n\n"
            f"JUDGE'S PRIORITY:\n{state['latest_verdict']['focus']}"
        )

    draft = llm.invoke(prompt).content

    return {
        "draft": draft,
        "round": state.get("round", 0) + 1,
    }

b. Krytyk

Faza krytycznej oceny funkcjonuje najlepiej, gdy jest traktowana jako mierzalna powierzchnia. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres. Zdokumentuj zarówno prawidłowy przebieg działania, jak i ścieżkę przywracania do normalnego stanu. Próby ponownych działań, kontrolne punkty ludzkie oraz obsługa wiadomości nieodebranych stanowią część produktu, a nie elementy dodawane później. Utrzymuj stan grafu w prostej formie i z określonym typem danych. Wplecione struktury ukrywają informację o tym, który węzeł zapisał dane w danym polu, co powoduje przerwanie kontynuacji po przerwach. Faza krytycznej oceny funkcjonuje najlepiej, gdy jest traktowana jako mierzalna powierzchnia. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres. Traktuj tę fazę jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzucaj ciche, częściowe ukończenie zadań.

class Issue(BaseModel):
    severity: Literal["blocking", "major", "minor"]
    description: str

class Critique(BaseModel):
    issues: list[Issue]
    summary: str
def weighted_issue_score(issues: list[dict]) -> int:
    weights = {
        "blocking": 5,
        "major": 2,
        "minor": 1,
    }

    return sum(
        weights[issue["severity"]]
        for issue in issues
    )

c. Sędzia

Na etapie sędziego należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy rejestrować czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy ścieżka przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Konieczne jest ludzkie zatwierdzenie dla operacji, które generują wydatki lub zmieniają dane produkcyjne. Podłączenia realizowane w czasie kompilacji nie gwarantują pełnej kompletności biznesowej.

class Verdict(BaseModel):
    decision: Literal["accept", "revise"]
    reasoning: str
    focus: str

def judge(state: AdversarialState) -> dict:
    verdict = llm.with_structured_output(Verdict).invoke(
        [
            HumanMessage(
                content=(
                    "Evaluate the critic's findings on their merits. "
                    "Accept if only minor issues remain. "
                    "Request revision only for blocking or material problems.\n\n"
                    f"DRAFT:\n{state['draft']}\n\n"
                    f"CRITIQUE:\n{state['latest_critique']}"
                )
            )
        ]
    )

    return {
        "latest_verdict": verdict.model_dump(),
    }

Dlaczego watchdog nadal jest konieczny

Aby zrozumieć, dlaczego watchdog jest niezbędny na danej etapie, należy zdefiniować wejścia, osobę odpowiedzialną za tę etap oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić daną etap od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Konfigurację należy przechowywać oddzielnie od kodu aplikacji. Pliki środowiskowe, magazyny poufnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury. Zatwierdzenie przez człowieka powinno być wymagane przy operacjach, które wiążą się z wydawaniem pieniędzy lub modyfikacją danych produkcyjnych. Połączenia realizowane w czasie kompilacji nie równają się pełnej kompletności biznesowej.

round 1: 12
round 2: 8
round 3: 8
round 4: 9
def watchdog(state: AdversarialState) -> dict:
    round_number = state.get("round", 0)
    scores = state.get("issue_counts", [])

    if round_number >= HARD_ROUND_CAP:
        return {
            "halt_reason": "hard round cap reached",
        }

    if len(scores) >= STALEMATE_WINDOW:
        window = scores[-STALEMATE_WINDOW:]

        if window[-1] >= window[0]:
            return {
                "halt_reason": (
                    f"stalemate detected: {window}"
                ),
            }

    return {}

Zakończenie procesu musi odróżniać sukces od niepowodzenia

Podczas finalizacji należy odróżnić etap sukcesu, określić dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie wykonać ten krok od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy udokumentować zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponownych działań, kontrolne punkty ludzkie oraz obsługa wiadomości błędnych stanowią część produktu, a nie elementy dodawane później. Konieczne jest uzyskanie zatwierdzenia człowieka w przypadkach, gdy dochodzi do wydawania pieniędzy lub zmiany danych produkcyjnych. Podłączenia realizowane w czasie kompilacji nie równają się pełnej kompletności funkcjonalności biznesowej. Podczas finalizacji należy odróżnić etap sukcesu, określić dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie wykonać ten krok od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nazwij poszczególne elementy, zdefiniuj kryteria sukcesu i odrzucaj ciche, częściowe rozwiązania.

Kiedy należy używać architektury adwersarialnej?

Podczas analizy kwestii „Kiedy należy używać” najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zapisz czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega nieoczekiwanym rachunkom, gdy proces przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Ustal punkty kontrolne po kosztownych krokach. Narzędzie do kontynuacji nie powinno ponownie naliczać opłat za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł.

Wybór architektury

Gdy przechodzisz przez etap wyboru architektury, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Trzymaj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury. Ustaw punkty kontrolne po kosztownych krokach. System powrotu nie powinien ponownie naliczać opłat za tę samą wywołanie LLM, gdy operator ponawia próbę z późniejszym węzłem.

Ostateczne uwagi

Gdy przechodzisz przez etap Ostatecznych Uwag, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zdokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponowne, kontrola przez ludzi oraz obsługa wiadomości błędnych stanowią część produktu, a nie elementy dodatkowej optymalizacji. Ustal punkty kontrolne po kosztownych krokach. System powrotu nie powinien ponownie naliczać opłat za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł. Gdy przechodzisz przez etap Ostatecznych Uwag, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzucaj ciche, częściowe ukończenie zadań.

Etap listy kontrolnej operacyjnej funkcjonuje najlepiej, gdy traktowany jest jako mierzalna struktura. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres.

Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowaną sekwencję działań.

Zachowuj strukturę grafu w formie prostych, typizowanych elementów. Wplecione struktury ukrywają informację o tym, który węzeł zapisał dane do którego pola, i utrudniają kontynuację pracy po przerwach.

Gdy budżet na to pozwala, dodaj test wstępny, który sprawdza kluczową ścieżkę działania w środowisku CI przy użyciu przygotowanych danych testowych, a nie rzeczywistych, płatnych API.

Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzucaj ciche, częściowe ukończenie zadań.

Zachowuj strukturę grafu w formie prostych, typizowanych elementów. Wplecione struktury ukrywają informację o tym, który węzeł zapisał dane do którego pola, i utrudniają kontynuację pracy po przerwach.

Zanim wdrożysz tę architekturę, zamroź wersje, utwórz dokładny zapis dla kluczowych etapów realizacji oraz potwierdź kroki odwracania zmian. Środowiska współdzielone wymagają ograniczeń szybkości, weryfikacji przynależności użytkowników oraz wyraźnego właściciela odpowiedzialnego za rotację haseł. Wolimy nudną niezawodność od pomysłowych, jednorazowych demonstracji.

Uwaga dotycząca f6f8c689c406: unikaj przechowywania kluczy dostawcy w repozytorium, ustaw ograniczenie liczby tokenów na sesję oraz przechowuj zapisy obok narzędzi do testowania, aby późniejsze zmiany modeli pozostawały porównywalne.