Agenci interaktywni w stylu REPL
Pętle danych wejściowych, historia i wieloturowa konwersacja w agentach terminalowych.
Agenci interaktywni w stylu REPL to bezpłatna lekcja AI Agents na CoddyKit. To lekcja 2 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 Agents, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs AI Agents zawiera 4 lekcji w sumie.
Czym jest agent w stylu REPL?
REPL (Read-Eval-Print Loop) to interaktywna sesja terminala, w której wpisuje się dane, otrzymuje wynik i kontynuuje pracę. Agenty konwersacyjne działające w terminalu funkcjonują dokładnie w ten sposób: użytkownik wpisuje wiadomość, agent odpowiada, a rozmowa trwa do momentu zakończenia przez użytkownika.
Podstawowa pętla REPL
Najprostszy REPL to pętla while True, która odczytuje dane użytkownika za pomocą input(), przetwarza je i wyświetla wynik. Pętla działa bez końca, dopóki użytkownik nie zasygnalizuje zakończenia.
def run_agent_repl(inputs):
print('Agent started. Type /exit to quit.')
conversation_history = []
for user_input in inputs:
user_input = user_input.strip()
if not user_input:
continue
if user_input == '/exit':
print('Goodbye!')
break
conversation_history.append({'role': 'user', 'content': user_input})
agent_reply = f'[Agent reply to: {user_input}]'
conversation_history.append({'role': 'assistant', 'content': agent_reply})
print(f'Agent: {agent_reply}')
run_agent_repl(['Hello agent', 'What can you do?', '/exit'])Elegancka obsługa KeyboardInterrupt
Po naciśnięciu przez użytkownika klawiszy Ctrl+C Python zgłasza wyjątek KeyboardInterrupt. Należy przechwycić go na najwyższym poziomie, aby zamiast śladu stosu wyświetlić przyjazny komunikat pożegnalny.
def run_agent_repl():
print('Agent ready. Press Ctrl+C to exit.')
conversation_history = []
try:
while True:
user_input = input('You: ').strip()
if not user_input:
continue
conversation_history.append({'role': 'user', 'content': user_input})
reply = '[mocked agent response]'
conversation_history.append({'role': 'assistant', 'content': reply})
print(f'Agent: {reply}')
except KeyboardInterrupt:
print('\nSession ended. Goodbye!')
except EOFError:
# Triggered when stdin is closed (piped input ends)
print('\nEnd of input. Exiting.')
if __name__ == '__main__':
import builtins
_demo_inputs = iter(['What agents can you build?', EOFError])
def _fake_input(prompt=''):
val = next(_demo_inputs)
if val is EOFError:
raise EOFError
print(prompt + val)
return val
builtins.input = _fake_input
run_agent_repl()
Zachowywanie historii wieloturowej rozmowy
Aby agent miał pamięć rozmowy, należy przechowywać listę wiadomości i przy każdej turze przekazywać do LLM pełną historię. Rozmowę należy rozpocząć od wiadomości systemowej określającej osobowość agenta.
import openai
client = openai.OpenAI(api_key='YOUR_API_KEY')
def run_chat_repl():
history = [
{'role': 'system', 'content': 'You are a helpful AI assistant.'}
]
print('Chat started. Type /exit to quit.')
try:
while True:
user_input = input('You: ').strip()
if not user_input or user_input == '/exit':
break
history.append({'role': 'user', 'content': user_input})
response = client.chat.completions.create(
model='gpt-4o-mini',
messages=history
)
reply = response.choices[0].message.content
history.append({'role': 'assistant', 'content': reply})
print(f'Agent: {reply}')
except KeyboardInterrupt:
print('\nGoodbye!')readline: historia i edycja danych wejściowych
Moduł readline (Unix/Mac) umożliwia poruszanie się za pomocą klawiszy strzałek po wcześniej wprowadzonych danych, podobnie jak w prawdziwej powłoce. Użytkownicy mogą nacisnąć strzałkę w górę, aby przywołać poprzednie wiadomości.
try:
import readline # available on Unix/Mac, not Windows
# Enable persistent history between sessions
import os
HISTORY_FILE = os.path.expanduser('~/.agent_history')
try:
readline.read_history_file(HISTORY_FILE)
except FileNotFoundError:
pass
import atexit
atexit.register(readline.write_history_file, HISTORY_FILE)
readline.set_history_length(500)
print('History enabled (use up/down arrows)')
except ImportError:
pass # readline not available on Windows
# After this, input() automatically has history supportWbudowane polecenia z ukośnikiem
Należy wyposażyć agenta REPL we wbudowane polecenia z ukośnikiem do typowych operacji: /help, /exit oraz /clear do resetowania rozmowy i /history do wyświetlania poprzednich wiadomości.
def handle_command(cmd: str, history: list) -> bool:
'Returns True if the command was handled, False if it is a regular message'
if cmd == '/exit' or cmd == '/quit':
print('Goodbye!')
raise SystemExit(0)
elif cmd == '/help':
print('Commands: /exit, /clear, /history, /help')
return True
elif cmd == '/clear':
# Keep only the system message
system = history[0] if history and history[0]['role'] == 'system' else None
history.clear()
if system:
history.append(system)
print('[Conversation cleared]')
return True
elif cmd == '/history':
for i, msg in enumerate(history):
if msg['role'] != 'system':
print(f' [{msg["role"]}] {msg["content"][:80]}')
return True
return False # not a command, treat as regular message
if __name__ == '__main__':
demo_history = [
{'role': 'system', 'content': 'You are a helpful agent.'},
{'role': 'user', 'content': 'Hi there'},
{'role': 'assistant', 'content': 'Hello! How can I help?'},
]
handle_command('/help', demo_history)
handle_command('/history', demo_history)
Ograniczanie długości historii rozmowy
Przekazywanie całej historii rozmowy do LLM przy każdej turze powoduje liniowy wzrost liczby tokenów. Aby kontrolować koszty, należy ograniczyć historię do ostatnich N wiadomości, zachowując wiadomość systemową.
def trim_history(history: list, max_turns: int = 10) -> list:
system_messages = [m for m in history if m['role'] == 'system']
non_system = [m for m in history if m['role'] != 'system']
# Keep the last max_turns messages (each turn = 1 user + 1 assistant)
max_messages = max_turns * 2
trimmed = non_system[-max_messages:]
return system_messages + trimmed
# Usage in the REPL loop:
# history.append({'role': 'user', 'content': user_input})
# trimmed = trim_history(history, max_turns=10)
# response = client.chat.completions.create(model='gpt-4o-mini', messages=trimmed)
print('Trimming history prevents token count from growing unboundedly')Wyświetlanie powitalnego banera
Powitalny baner sprawia, że REPL wygląda bardziej profesjonalnie. Należy wyświetlić go raz podczas uruchamiania, podając nazwę agenta, jego wersję i dostępne polecenia. Można użyć prostej grafiki ASCII lub biblioteki rich do dodania kolorów.
def print_banner():
banner = '''
====================================
AI Research Agent v1.0
====================================
Type your question to begin.
Commands: /help /clear /exit
====================================
'''
print(banner)
# Or with rich colors:
# from rich.console import Console
# from rich.panel import Panel
# console = Console()
# console.print(Panel('[bold cyan]AI Research Agent[/] v1.0', subtitle='Type /help for commands'))
print_banner()Wyświetlanie wskaźników pisania
Wywołania LLM mogą trwać kilka sekund. Podczas oczekiwania należy wyświetlić komunikat „thinking...”, aby użytkownicy wiedzieli, że agent przetwarza żądanie. Po nadejściu odpowiedzi należy go usunąć.
import sys
import threading
import time
def thinking_spinner(stop_event: threading.Event):
frames = ['|', '/', '-', '\\']
i = 0
while not stop_event.is_set():
sys.stdout.write(f'\rAgent is thinking... {frames[i % 4]}')
sys.stdout.flush()
time.sleep(0.1)
i += 1
sys.stdout.write('\r' + ' ' * 30 + '\r') # clear the line
sys.stdout.flush()
def call_agent_with_spinner(query: str) -> str:
stop = threading.Event()
spinner = threading.Thread(target=thinking_spinner, args=(stop,))
spinner.start()
# result = agent.run(query) # the actual slow call
time.sleep(1) # simulating work
result = 'The answer is 42.'
stop.set()
spinner.join()
return result
if __name__ == '__main__':
answer = call_agent_with_spinner('What is 6 * 7?')
print(f'\nFinal answer: {answer}')
Zapisywanie sesji do pliku
Należy umożliwić użytkownikom zapisanie rozmowy do pliku po zakończeniu sesji. Jest to przydatne podczas sesji badawczych, gdy potrzebny jest zapis informacji znalezionych przez agenta.
import json
import datetime
import os
def save_session(history: list, directory: str = 'sessions'):
os.makedirs(directory, exist_ok=True)
timestamp = datetime.datetime.now().strftime('%Y%m%d_%H%M%S')
filename = os.path.join(directory, f'session_{timestamp}.json')
with open(filename, 'w') as f:
json.dump({
'saved_at': timestamp,
'messages': history
}, f, indent=2)
print(f'Session saved to {filename}')
# Usage in REPL on /save command:
# save_session(conversation_history)
if __name__ == '__main__':
import tempfile
demo_dir = tempfile.mkdtemp()
demo_history = [
{'role': 'user', 'content': 'Hello'},
{'role': 'assistant', 'content': 'Hi! How can I help?'},
]
save_session(demo_history, directory=demo_dir)
Kompletny szablon agenta REPL
Połączmy wszystkie elementy: gotowy do użycia szablon REPL z zarządzaniem historią, poleceniami z ukośnikiem, obsługą przerwania klawiaturą i zapisywaniem sesji.
def run_repl(agent):
history = [{'role': 'system', 'content': 'You are a helpful AI assistant.'}]
print('Agent ready. Type /help for commands.')
try:
while True:
user_input = input('You: ').strip()
if not user_input:
continue
if user_input.startswith('/'):
handle_command(user_input, history)
continue
history.append({'role': 'user', 'content': user_input})
trimmed = trim_history(history, max_turns=10)
reply = agent.run(trimmed)
history.append({'role': 'assistant', 'content': reply})
print(f'Agent: {reply}')
except KeyboardInterrupt:
print('\nSession ended.')
save_session(history)Sprawdzenie wiedzy: agenty w stylu REPL
Sprawdź swoją wiedzę na temat interaktywnych agentów REPL.
Podsumowanie: interaktywne agenty w stylu REPL
Możesz teraz tworzyć w pełni funkcjonalne interaktywne agenty działające w terminalu:
- Używaj
while True: input()jako głównej pętli odczytu - Przechwytuj
KeyboardInterrupt, aby prawidłowo kończyć działanie po naciśnięciu Ctrl+C - Przechowuj listę
conversation_history, aby zapewnić pamięć wieloturowej rozmowy - Używaj
readlinedo obsługi historii danych wejściowych za pomocą klawiszy strzałek - Implementuj polecenia z ukośnikiem:
/help,/cleari/exit - Ograniczaj historię, aby zapobiec nieograniczonemu wzrostowi liczby tokenów
- Wyświetlaj animację ładowania lub wskaźnik postępu podczas wywołań LLM
Ucz się AI Agents dzięki korepetycjom AI — za darmo
Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.
- Kursy
- 60
- Lekcje
- 239
Często zadawane pytania
Czy lekcja „Agenci interaktywni w stylu REPL” jest bezpłatna?
Tak — pełny tekst „Agenci interaktywni w stylu REPL” 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 Agents, przejdź na CoddyKit PRO. Kurs AI Agents zawiera 4 lekcji w sumie.
Co nauczysz się w „Agenci interaktywni w stylu REPL”?
Pętle danych wejściowych, historia i wieloturowa konwersacja w agentach terminalowych. Ćwiczysz AI Agents 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 Agents?
Nie wymagamy żadnego doświadczenia. AI Agents 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 2 z 4.
Ile czasu zajmuje lekcja „Agenci interaktywni w stylu REPL”?
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 Agents?
Tak. Każda lekcja AI Agents 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
- Tworzenie interfejsów agentów wiersza poleceń
- Agenci interaktywni w stylu REPL
- Parsowanie argumentów i tekst pomocy
- Strumieniowanie wyników w agentach CLI