Strona główna / Artykuły

ReAct od zera: myśl, działanie, pauza, obserwacja bez ramy referencyjnej

Mała pętla ReAct stworzona ręcznie w Groq: myśl, działanie, pauza, obserwacja – najpierw metoda ręczna, potem wywołania narzędzi regex, dzięki czemu ramy agentów LLM nabierają sensu.

Wydawca: REACTAPP.TOP6 min czytania1373 słów

Źródła: The Origins of AI Agents -How ReAct Rewired the Way LLMs Think and Act

Wprowadzenie

Zadaj modelowi mówiącemu prostym językiem pytanie o aktualną cenę akcji Nvidia oraz o to, ile akcji da się kupić za 100 000 dolarów. Bez dodatkowych narzędzi model wymyśla przestarzałą cenę na podstawie danych treningowych, a następnie błędnie dokonuje obliczeń przy niewłaściwych danych wejściowych. Nie posiada wbudowanej funkcji oznaczającej „Nie wiem – sprawdź to”, ponieważ wyszukiwanie informacji nie polega na pojedynczym przetworzeniu danych.

Gdy jakość odpowiedzi wzrosła, modele okazały się przydatne do rozumowania jednorazowego. Samo planowanie nadal nie zapewnia autonomii. Pytania, które definiują agenty, to: co znajduje się poza wiedzą modelu, która akcja ją zdobywa, jak osiągnąć rezultat, jak zmodyfikować plan oraz kiedy przestać. Decyzja → działanie → sprawdzenie → ponowne planowanie to pętla, a nie linia prosta. Ta pętla jest źródłem współczesnych agentów sztucznej inteligencji. Model ReAct (Rozumowanie + Działanie) ustalił ten wzorzec. Początkowe demonstracje nie były aplikacjami LangChain – składały się z modelu językowego, ustrukturyzowanego promptu oraz osoby (a później skryptu), która wykonywała działania i przekazywała informacje zwrotne.

Poznaj ReAct: Rozumowanie + Działanie

Przykład w praktyce, krok po kroku:

from groq import Groq
import re
from dotenv import load_dotenv

_ = load_dotenv()
client = Groq()
message = client.chat.completions.create(
    model="openai/gpt-oss-120b",  # free, fast open-weight model hosted on Groq
    max_tokens=1000,
    messages=[
        {"role": "user", "content": "Hello, GPT!"}
    ],
)
print(message.choices[0].message.content) # Check the client
class Agent:
    def __init__(self, system=""):
        self.system = system
        self.messages = []
        if self.system:
            self.messages.append({"role": "system", "content": system})

    def __call__(self, message):
        self.messages.append({"role": "user", "content": message})
        result = self.execute()
        self.messages.append({"role": "assistant", "content": result})
        return result

    def execute(self):
        response = client.chat.completions.create(
            model="openai/gpt-oss-120b",
            max_tokens=1000,
            messages=self.messages,
        ).choices[0].message.content
        return response
prompt = """
You run in a loop of Thought, Action, PAUSE, Observation.
At the end of the loop you output an Answer
Use Thought to describe your thoughts about the question you have been asked.
Use Action to run one of the actions available to you - then return PAUSE.
Observation will be the result of running those actions.

Your available actions are:

calculate:
e.g. calculate: 4 * 7 / 3
Runs a calculation and returns the number - uses Python so be sure to use floating point syntax if necessary

fish_weight:
e.g. fish_weight: Shark
returns weight of a fish when given the breed

Example session:

Question: How much does a shark weigh?
Thought: I should look the fish weight using fish_weight
Action: fish_weight: Shark
PAUSE

You will be called again with this:

Observation: A Great white shark weights 41000 lbs

You then output:

Answer: A Great white shark weights 41000 lbs
""".strip()
def calculate(expression):
    return eval(expression)

def fish_weight(name):
    if "Shark" in name:
        return("Great white shark weighs 41000 lbs")
    elif "Puffer" in name:
        return("A puffer fish weighs 20 lbs")
    else:
        return("A fish can weight upto 47000 lbs")

known_actions = {
    "calculate": calculate,
    "fish_weight": fish_weight
}
abot = Agent(prompt)
result = abot("How much does a Shark weigh?")
print(result)
result = fish_weight("Shark")
result
next_prompt = "Observation: {}".format(result)
abot(next_prompt)
abot.messages # View the list of messages containing the conversation
# Present a compund query
abot = Agent(prompt)
# New query
question = """I have 2 fishes, a Shark and a puffer fish. \
What is their combined weight"""
abot(question)
next_prompt = "Observation: {}".format(fish_weight("Shark"))
print(next_prompt)
abot(next_prompt)
next_prompt = "Observation: {}".format(fish_weight("Puffer fish"))
print(next_prompt)
abot(next_prompt)
next_prompt = "Observation: {}".format(eval("41000 + 20"))
print(next_prompt)
abot(next_prompt)
## Add loop (automate the reasoning + act process)
action_re = re.compile('^Action: (\w+): (.*)
) # python regular expression to selection action
def query(question, max_turns=5):
    i = 0
    bot = Agent(prompt)
    next_prompt = question
    while i < max_turns:
        i += 1
        result = bot(next_prompt)
        print(result)
        actions = [
            action_re.match(a)
            for a in result.split('\n')
            if action_re.match(a)
        ]
        if actions:
            # There is an action to run
            action, action_input = actions[0].groups()
            if action not in known_actions:
                raise Exception("Unknown action: {}: {}".format(action, action_input))
            print(" -- running {} {}".format(action, action_input))
            observation = known_actions[action](action_input)
            print("Observation:", observation)
            next_prompt = "Observation: {}".format(observation)
        else:
            return
question = """I have 2 fishes, a Shark and a puffer fish. \
What is their combined weight"""
query(question)
  1. Imporuj klienta Groq, funkcję re do dopasowywania wzorów oraz load_dotenv; załaduj plik środowiskowy, aby klucz API nie był zapisany w sposób sztywny.
  2. Stwórz klienta Groq, który odczytuje wartość GROQ_API_KEY z środowiska.
  3. Wyślij proste wiadomość „Hello” do skonfigurowanego modelu w celu potwierdzenia połączenia.
  4. Zbuduj Agenta, który przechowuje instrukcje systemowe oraz rosnącą historię wiadomości: przy każdym wezwaniu dodaje kolejną wypowiedź użytkownika, wysyła pełną historię, dodaje odpowiedź modelu i zwraca tekst.
  • Napisz instrukcję systemową, która wymusza sekwencję Myśl → Działanie → PAUZA → Obserwacja.
  • Zarejestruj narzędzia takie jak calculate() do obliczeń arytmetycznych oraz fish_weight() do małej tabeli referencyjnej w known_actions.
  • Zainstaluj agenta przy użyciu instrukcji systemowej ReAct.
  • Zadaj pytanie „Ile waży rekin?”. Oczekuj proponowanego Działanie: fish_weight: Shark, a nie samego liczby.
  • Ręcznie uruchom fish_weight("Shark") i zapisz wynik (najpierw w trybie ręcznym).
  • Dostarcz z powrotem wartość Obserwacja: …, aby agent mógł odpowiedzieć.
  • Zobacz zawartość abot.messages, aby przejrzeć pełny zapis rozmowy widziany przez model.
  • Rozpocznij nowego agenta z złożonym pytaniem (waga rekina i ryby balonowej). 13–15. Ręcznie podawaj każdą obserwację, w tym łączną sumę w razie potrzeby.
  • Niech agent skomponuje ostateczną odpowiedź, gdy tylko będą dostępne obserwacje.
  • Dodaj regular expression, który automatycznie wykrywa Action: name: input.
  • Zamknij pętlę w funkcji query(): nowy agent, wysłanie pytania, wydrukowanie wyniku, analiza działania, weryfikacja względem known_actions, wykonanie, obserwacja – powtarzaj do uzyskania ostatecznej odpowiedzi lub osiągnięcia limitu rund.
  • Zaprowadź funkcję query() na złożone pytanie i obserwuj proces Thought → Action → Observation → Answer bez konieczności ręcznych kroków.
  • Wniosek

    Agenci zaczynają od pętli, a nie od ram roboczych. Modeli nauczane metodą Chain-of-thought uczyły się rozumować na głos; ReAct strukturyzuje proces myślenia–działania–obserwacji w sposób odpowiadający sposobowi pracy ludzi. Popularne ramy dla agentów przemysłowią tę koncepcję. Budowa pętli ręcznie trwale zmienia odczucia związane z ramami roboczymi. Oryginalny artykuł znajduje się pod adresem https://arxiv.org/abs/2210.03629.

    Lekcja z praktyki przemysłowej polega na tym, że frameworki ukrywają pętlę za elementami typu runner i węzłami narzędzi, ale umowa pozostaje identyczna: model musi emitować akcję możliwą do analizy, środowisko wykonawcze musi uruchamiać tylko dozwolone narzędzia, a obserwacje muszą ponownie trafić do transkrypcji jako wiadomości pierwszej klasy. Jeśli pominie się cokolwiek z tego, otrzymuje się chatbota z efektami ubocznymi, a nie agenta.

    Lekcja z praktyki przemysłowej polega na tym, że frameworki ukrywają pętlę za elementami typu runner i węzłami narzędzi, ale umowa pozostaje identyczna: model musi emitować akcję możliwą do analizy, środowisko wykonawcze musi uruchamiać tylko dozwolone narzędzia, a obserwacje muszą ponownie trafić do transkrypcji jako wiadomości pierwszej klasy. Jeśli pominie się cokolwiek z tego, otrzymuje się chatbota z efektami ubocznymi, a nie agenta.

    Lekcja z praktyki przemysłowej polega na tym, że frameworki ukrywają pętlę za elementami typu runner i węzłami narzędzi, ale umowa pozostaje identyczna: model musi emitować akcję możliwą do analizy, środowisko wykonawcze musi uruchamiać tylko dozwolone narzędzia, a obserwacje muszą ponownie trafić do transkrypcji jako wiadomości pierwszej klasy. Jeśli pominie się cokolwiek z tego, otrzymuje się chatbota z efektami ubocznymi, a nie agenta.

    Lekcja z praktyki przemysłowej polega na tym, że frameworki ukrywają pętlę za elementami typu runner i węzłami narzędzi, ale umowa pozostaje identyczna: model musi emitować akcję możliwą do analizy, środowisko wykonawcze musi uruchamiać tylko dozwolone narzędzia, a obserwacje muszą ponownie trafić do transkrypcji jako wiadomości pierwszej klasy. Jeśli pominie się cokolwiek z tego, otrzymuje się chatbota z efektami ubocznymi, a nie agenta.

    Literatura pokrewna

  • ReAct Agents w LangGraph: Myślenie, Działanie, Obserwacja krok po kroku — Implementacja pętli ReAct poprzez wyraźne węzły grafu z typowanym stanem, wywołaniami narzędzi oraz warunkami zatrzymania, które można przetestować.
  • Wzory promptów dla prac flow w stylu GPT-6 Astra — Strukturyzacja systemu, narzędzi i przykładów tak, aby długie prompty były możliwe do ponownego użycia w różnych interfejsach czatowych i hostach agentów.
  • ) # python regular expression to selection action\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E \u003Cpre\u003E\u003Ccode class=\"language-python\"\u003Edef query(question, max_turns=5):\n i = 0\n bot = Agent(prompt)\n next_prompt = question\n while i < max_turns:\n i += 1\n result = bot(next_prompt)\n print(result)\n actions = [\n action_re.match(a)\n for a in result.split('\\n')\n if action_re.match(a)\n ]\n if actions:\n # There is an action to run\n action, action_input = actions[0].groups()\n if action not in known_actions:\n raise Exception("Unknown action: {}: {}".format(action, action_input))\n print(" -- running {} {}".format(action, action_input))\n observation = known_actions[action](action_input)\n print("Observation:", observation)\n next_prompt = "Observation: {}".format(observation)\n else:\n return\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E \u003Cpre\u003E\u003Ccode class=\"language-text\"\u003Equestion = """I have 2 fishes, a Shark and a puffer fish. \\\nWhat is their combined weight"""\nquery(question)\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E \u003Col\u003E \u003Cli\u003EImporuj klienta Groq, funkcję \u003Ccode\u003Ere\u003C\u002Fcode\u003E do dopasowywania wzorów oraz \u003Ccode\u003Eload_dotenv\u003C\u002Fcode\u003E; załaduj plik środowiskowy, aby klucz API nie był zapisany w sposób sztywny.\u003C\u002Fli\u003E \u003Cli\u003EStwórz klienta Groq, który odczytuje wartość \u003Ccode\u003EGROQ_API_KEY\u003C\u002Fcode\u003E z środowiska.\u003C\u002Fli\u003E \u003Cli\u003EWyślij proste wiadomość „Hello” do skonfigurowanego modelu w celu potwierdzenia połączenia.\u003C\u002Fli\u003E \u003Cli\u003EZbuduj \u003Ccode\u003EAgenta\u003C\u002Fcode\u003E, który przechowuje instrukcje systemowe oraz rosnącą historię wiadomości: przy każdym wezwaniu dodaje kolejną wypowiedź użytkownika, wysyła pełną historię, dodaje odpowiedź modelu i zwraca tekst.\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cli\u003ENapisz instrukcję systemową, która wymusza sekwencję Myśl → Działanie → PAUZA → Obserwacja.\u003C\u002Fli\u003E \u003Cli\u003EZarejestruj narzędzia takie jak \u003Ccode\u003Ecalculate()\u003C\u002Fcode\u003E do obliczeń arytmetycznych oraz \u003Ccode\u003Efish_weight()\u003C\u002Fcode\u003E do małej tabeli referencyjnej w \u003Ccode\u003Eknown_actions\u003C\u002Fcode\u003E.\u003C\u002Fli\u003E \u003Cli\u003EZainstaluj agenta przy użyciu instrukcji systemowej ReAct.\u003C\u002Fli\u003E \u003Cli\u003EZadaj pytanie „Ile waży rekin?”. Oczekuj proponowanego \u003Ccode\u003EDziałanie: fish_weight: Shark\u003C\u002Fcode\u003E, a nie samego liczby.\u003C\u002Fli\u003E \u003Cli\u003ERęcznie uruchom \u003Ccode\u003Efish_weight("Shark")\u003C\u002Fcode\u003E i zapisz wynik (najpierw w trybie ręcznym).\u003C\u002Fli\u003E \u003Cli\u003EDostarcz z powrotem wartość \u003Ccode\u003EObserwacja: …\u003C\u002Fcode\u003E, aby agent mógł odpowiedzieć.\u003C\u002Fli\u003E \u003Cli\u003EZobacz zawartość \u003Ccode\u003Eabot.messages\u003C\u002Fcode\u003E, aby przejrzeć pełny zapis rozmowy widziany przez model.\u003C\u002Fli\u003E \u003Cli\u003ERozpocznij nowego agenta z złożonym pytaniem (waga rekina i ryby balonowej).\n13–15. Ręcznie podawaj każdą obserwację, w tym łączną sumę w razie potrzeby.\u003C\u002Fli\u003E\u003Cli\u003ENiech agent skomponuje ostateczną odpowiedź, gdy tylko będą dostępne obserwacje.\u003C\u002Fli\u003E \u003Cli\u003EDodaj regular expression, który automatycznie wykrywa \u003Ccode\u003EAction: name: input\u003C\u002Fcode\u003E.\u003C\u002Fli\u003E \u003Cli\u003EZamknij pętlę w funkcji \u003Ccode\u003Equery()\u003C\u002Fcode\u003E: nowy agent, wysłanie pytania, wydrukowanie wyniku, analiza działania, weryfikacja względem \u003Ccode\u003Eknown_actions\u003C\u002Fcode\u003E, wykonanie, obserwacja – powtarzaj do uzyskania ostatecznej odpowiedzi lub osiągnięcia limitu rund.\u003C\u002Fli\u003E \u003Cli\u003EZaprowadź funkcję \u003Ccode\u003Equery()\u003C\u002Fcode\u003E na złożone pytanie i obserwuj proces Thought → Action → Observation → Answer bez konieczności ręcznych kroków.\u003C\u002Fli\u003E \u003C\u002Fol\u003E \u003Ch2\u003EWniosek\u003C\u002Fh2\u003E \u003Cp\u003EAgenci zaczynają od pętli, a nie od ram roboczych. Modeli nauczane metodą Chain-of-thought uczyły się rozumować na głos; ReAct strukturyzuje proces myślenia–działania–obserwacji w sposób odpowiadający sposobowi pracy ludzi. Popularne ramy dla agentów przemysłowią tę koncepcję. Budowa pętli ręcznie trwale zmienia odczucia związane z ramami roboczymi. Oryginalny artykuł znajduje się pod adresem https:\u002F\u002Farxiv.org\u002Fabs\u002F2210.03629.\u003C\u002Fp\u003E\u003Cp\u003ELekcja z praktyki przemysłowej polega na tym, że frameworki ukrywają pętlę za elementami typu runner i węzłami narzędzi, ale umowa pozostaje identyczna: model musi emitować akcję możliwą do analizy, środowisko wykonawcze musi uruchamiać tylko dozwolone narzędzia, a obserwacje muszą ponownie trafić do transkrypcji jako wiadomości pierwszej klasy. Jeśli pominie się cokolwiek z tego, otrzymuje się chatbota z efektami ubocznymi, a nie agenta.\u003C\u002Fp\u003E \u003Cp\u003ELekcja z praktyki przemysłowej polega na tym, że frameworki ukrywają pętlę za elementami typu runner i węzłami narzędzi, ale umowa pozostaje identyczna: model musi emitować akcję możliwą do analizy, środowisko wykonawcze musi uruchamiać tylko dozwolone narzędzia, a obserwacje muszą ponownie trafić do transkrypcji jako wiadomości pierwszej klasy. Jeśli pominie się cokolwiek z tego, otrzymuje się chatbota z efektami ubocznymi, a nie agenta.\u003C\u002Fp\u003E\u003Cp\u003ELekcja z praktyki przemysłowej polega na tym, że frameworki ukrywają pętlę za elementami typu runner i węzłami narzędzi, ale umowa pozostaje identyczna: model musi emitować akcję możliwą do analizy, środowisko wykonawcze musi uruchamiać tylko dozwolone narzędzia, a obserwacje muszą ponownie trafić do transkrypcji jako wiadomości pierwszej klasy. Jeśli pominie się cokolwiek z tego, otrzymuje się chatbota z efektami ubocznymi, a nie agenta.\u003C\u002Fp\u003E \u003Cp\u003ELekcja z praktyki przemysłowej polega na tym, że frameworki ukrywają pętlę za elementami typu runner i węzłami narzędzi, ale umowa pozostaje identyczna: model musi emitować akcję możliwą do analizy, środowisko wykonawcze musi uruchamiać tylko dozwolone narzędzia, a obserwacje muszą ponownie trafić do transkrypcji jako wiadomości pierwszej klasy. Jeśli pominie się cokolwiek z tego, otrzymuje się chatbota z efektami ubocznymi, a nie agenta.\u003C\u002Fp\u003E \u003Ch2\u003ELiteratura pokrewna\u003C\u002Fh2\u003E\u003Cul\u003E \u003Cli\u003E\u003Ca href=\"\u002Fpl\u002Fartykuły\u002Fwprowadzenie-do-mcp-od-frAGMENTACJI-do-wspólnych-serwerów-narzędzi\"\u003EWprowadzenie do MCP: od fragmentacji do wspólnych serwerów narzędzi\u003C\u002Fa\u003E — Dlaczego kopiowanie kontekstu nie działa, jak pomocne okazały się wywołania funkcji, dlaczego integracje typu N×M są szkodliwe oraz jak MCP prowadzi do użycia serwerów wielokrotnego użytku typu N+M.\u003C\u002Fli\u003E \u003Cli\u003E\u003Ca href=\"\u002Fpl\u002Fartykuły\u002Fmcp-od-zera-część-3-połączenie-klienta-z-twój-serwerem\"\u003EMCP od zera, część 3: Połączenie klienta z twoim serwerem\u003C\u002Fa\u003E — Stworzenie klienta MCP stdio, który uruchamia hr_server.py, wywołuje funkcję search_employee i zwraca wyniki — bez konieczności ręcznego uruchamiania serwera.\u003C\u002Fli\u003E \u003Cli\u003E\u003Ca href=\"\u002Fpl\u002Fartykuły\u002Fagenty-ai-dla-przyszłych-inżynierów-pamięć-narzędzia-i pętle-kontroli\"\u003EAgenty AI dla przyszłych inżynierów: pamięć, narzędzia i pętle kontrolne\u003C\u002Fa\u003E — Praktyczny przewodnik po elementach budujących agenty — planowanie, narzędzia, pamięć i ocena — bez użycia nadmiernie technicznego żargonu, który zastępuje rzeczywisty projekt.\u003C\u002Fli\u003E \u003C\u002Ful\u003E\u003Cli\u003E\u003Ca href=\"\u002Fpl\u002Fartykuły\u002Freact-agents-w-langgraph-krok-po-kroku-myślenie-działanie-obserwacja\"\u003EReAct Agents w LangGraph: Myślenie, Działanie, Obserwacja krok po kroku\u003C\u002Fa\u003E — Implementacja pętli ReAct poprzez wyraźne węzły grafu z typowanym stanem, wywołaniami narzędzi oraz warunkami zatrzymania, które można przetestować.\u003C\u002Fli\u003E \u003Cli\u003E\u003Ca href=\"\u002Fpl\u002Fartykuły\u002Fwzory-promptów-dla-prac-flow-w-stylu-gpt-6-astra\"\u003EWzory promptów dla prac flow w stylu GPT-6 Astra\u003C\u002Fa\u003E — Strukturyzacja systemu, narzędzi i przykładów tak, aby długie prompty były możliwe do ponownego użycia w różnych interfejsach czatowych i hostach agentów.\u003C\u002Fli\u003E \u003C\u002Ful\u003E","showLangNote":false,"schemaTitle":"ReAct od zera: myśl, działanie, pauza, obserwacja bez ramy referencyjnej","schemaDescription":"Mała pętla ReAct stworzona ręcznie w Groq: myśl, działanie, pauza, obserwacja – najpierw metoda ręczna, potem wywołania narzędzi regex, dzięki czemu ramy agentów LLM nabierają sensu.","contentLanguage":"pl","sources":[{"title":"The Origins of AI Agents -How ReAct Rewired the Way LLMs Think and Act","url":"https:\u002F\u002Fmedium.com\u002F@khanejasamridh\u002Fthe-origins-of-ai-agents-how-react-rewired-the-way-llms-think-and-act-731895739b4f"}],"related":[{"slug":"introduction-to-mcp-from-fragmentation-to-shared-tool-servers","title":"Wprowadzenie do MCP: od fragmentacji do wspólnych serwerów narzędziowych"},{"slug":"mcp-from-scratch-part-3-connect-a-client-to-your-server","title":"MCP od zera, część 3: Połączenie klienta z twoim serwerem"},{"slug":"ai-agents-for-future-engineers-memory-tools-and-control-loops","title":"Agenci AI dla przyszłych inżynierów: pamięć, narzędzia i pętle sterujące"}]}},"actionData":null,"errors":null} ) # python regular expression to selection action
    def query(question, max_turns=5):
        i = 0
        bot = Agent(prompt)
        next_prompt = question
        while i < max_turns:
            i += 1
            result = bot(next_prompt)
            print(result)
            actions = [
                action_re.match(a)
                for a in result.split('\n')
                if action_re.match(a)
            ]
            if actions:
                # There is an action to run
                action, action_input = actions[0].groups()
                if action not in known_actions:
                    raise Exception("Unknown action: {}: {}".format(action, action_input))
                print(" -- running {} {}".format(action, action_input))
                observation = known_actions[action](action_input)
                print("Observation:", observation)
                next_prompt = "Observation: {}".format(observation)
            else:
                return
    
    question = """I have 2 fishes, a Shark and a puffer fish. \
    What is their combined weight"""
    query(question)
    
    1. Imporuj klienta Groq, funkcję re do dopasowywania wzorów oraz load_dotenv; załaduj plik środowiskowy, aby klucz API nie był zapisany w sposób sztywny.
    2. Stwórz klienta Groq, który odczytuje wartość GROQ_API_KEY z środowiska.
    3. Wyślij proste wiadomość „Hello” do skonfigurowanego modelu w celu potwierdzenia połączenia.
    4. Zbuduj Agenta, który przechowuje instrukcje systemowe oraz rosnącą historię wiadomości: przy każdym wezwaniu dodaje kolejną wypowiedź użytkownika, wysyła pełną historię, dodaje odpowiedź modelu i zwraca tekst.
  • Napisz instrukcję systemową, która wymusza sekwencję Myśl → Działanie → PAUZA → Obserwacja.
  • Zarejestruj narzędzia takie jak calculate() do obliczeń arytmetycznych oraz fish_weight() do małej tabeli referencyjnej w known_actions.
  • Zainstaluj agenta przy użyciu instrukcji systemowej ReAct.
  • Zadaj pytanie „Ile waży rekin?”. Oczekuj proponowanego Działanie: fish_weight: Shark, a nie samego liczby.
  • Ręcznie uruchom fish_weight("Shark") i zapisz wynik (najpierw w trybie ręcznym).
  • Dostarcz z powrotem wartość Obserwacja: …, aby agent mógł odpowiedzieć.
  • Zobacz zawartość abot.messages, aby przejrzeć pełny zapis rozmowy widziany przez model.
  • Rozpocznij nowego agenta z złożonym pytaniem (waga rekina i ryby balonowej). 13–15. Ręcznie podawaj każdą obserwację, w tym łączną sumę w razie potrzeby.
  • Niech agent skomponuje ostateczną odpowiedź, gdy tylko będą dostępne obserwacje.
  • Dodaj regular expression, który automatycznie wykrywa Action: name: input.
  • Zamknij pętlę w funkcji query(): nowy agent, wysłanie pytania, wydrukowanie wyniku, analiza działania, weryfikacja względem known_actions, wykonanie, obserwacja – powtarzaj do uzyskania ostatecznej odpowiedzi lub osiągnięcia limitu rund.
  • Zaprowadź funkcję query() na złożone pytanie i obserwuj proces Thought → Action → Observation → Answer bez konieczności ręcznych kroków.
  • Wniosek

    Agenci zaczynają od pętli, a nie od ram roboczych. Modeli nauczane metodą Chain-of-thought uczyły się rozumować na głos; ReAct strukturyzuje proces myślenia–działania–obserwacji w sposób odpowiadający sposobowi pracy ludzi. Popularne ramy dla agentów przemysłowią tę koncepcję. Budowa pętli ręcznie trwale zmienia odczucia związane z ramami roboczymi. Oryginalny artykuł znajduje się pod adresem https://arxiv.org/abs/2210.03629.

    Lekcja z praktyki przemysłowej polega na tym, że frameworki ukrywają pętlę za elementami typu runner i węzłami narzędzi, ale umowa pozostaje identyczna: model musi emitować akcję możliwą do analizy, środowisko wykonawcze musi uruchamiać tylko dozwolone narzędzia, a obserwacje muszą ponownie trafić do transkrypcji jako wiadomości pierwszej klasy. Jeśli pominie się cokolwiek z tego, otrzymuje się chatbota z efektami ubocznymi, a nie agenta.

    Lekcja z praktyki przemysłowej polega na tym, że frameworki ukrywają pętlę za elementami typu runner i węzłami narzędzi, ale umowa pozostaje identyczna: model musi emitować akcję możliwą do analizy, środowisko wykonawcze musi uruchamiać tylko dozwolone narzędzia, a obserwacje muszą ponownie trafić do transkrypcji jako wiadomości pierwszej klasy. Jeśli pominie się cokolwiek z tego, otrzymuje się chatbota z efektami ubocznymi, a nie agenta.

    Lekcja z praktyki przemysłowej polega na tym, że frameworki ukrywają pętlę za elementami typu runner i węzłami narzędzi, ale umowa pozostaje identyczna: model musi emitować akcję możliwą do analizy, środowisko wykonawcze musi uruchamiać tylko dozwolone narzędzia, a obserwacje muszą ponownie trafić do transkrypcji jako wiadomości pierwszej klasy. Jeśli pominie się cokolwiek z tego, otrzymuje się chatbota z efektami ubocznymi, a nie agenta.

    Lekcja z praktyki przemysłowej polega na tym, że frameworki ukrywają pętlę za elementami typu runner i węzłami narzędzi, ale umowa pozostaje identyczna: model musi emitować akcję możliwą do analizy, środowisko wykonawcze musi uruchamiać tylko dozwolone narzędzia, a obserwacje muszą ponownie trafić do transkrypcji jako wiadomości pierwszej klasy. Jeśli pominie się cokolwiek z tego, otrzymuje się chatbota z efektami ubocznymi, a nie agenta.

    Literatura pokrewna

  • ReAct Agents w LangGraph: Myślenie, Działanie, Obserwacja krok po kroku — Implementacja pętli ReAct poprzez wyraźne węzły grafu z typowanym stanem, wywołaniami narzędzi oraz warunkami zatrzymania, które można przetestować.
  • Wzory promptów dla prac flow w stylu GPT-6 Astra — Strukturyzacja systemu, narzędzi i przykładów tak, aby długie prompty były możliwe do ponownego użycia w różnych interfejsach czatowych i hostach agentów.
  • ← Wszystkie artykułyWyślij brief