Strona główna / Artykuły

API Gemini w Pythonie: ten sam bezstanowy pętla z rolami modeli i obiektami chatu.

Wywołanie Gemini z Pythona za pomocą SDK google-genai: zawartość i komponenty, system_instruction, użycie tokenów oraz obiekt chatu, który rejestruje historię na stronie klienta.

Wydawca: REACTAPP.TOP4 min czytania892 słów

Źródła: Part 4 — Call the Gemini API in Python (user / model, same loop)

Po OpenAI i Claude, Gemini od Google jest trzecim dostawcą, który stosuje ten sam schemat: endpoint bez stanu, rozmowa oznaczona rolą oraz pełna historia wysyłana przy każdym połączeniu. Gemini dodaje do tego jeszcze jedną przyjemną cechę w swojej nazwie.

Zmiana nazw, a nie przebudowa

Konstrukcja rozmowy w Gemini jest identyczna jak w OpenAI i Claude, z wyjątkiem dwóch zmian nazw. Rola asystenta nazywa się model. Ta nazwa jest chyba bardziej szczera, ponieważ „asystent” sugeruje określoną osobowość, natomiast model po prostu wskazuje, że tekst pochodzi z modelu. Zajmuje ona to samo miejsce na liście. Prompt systemowy staje się system_instruction i jest przekazywany w obiekcie konfiguracyjnym, a nie na liście wiadomości. To rozwinięcie koncepcji „systemu na boku” z Claude o jeden poziom dalej.

Lista wiadomości jest dostępna pod nazwą contents. Każda z nich zawiera elementy typu parts, ponieważ Gemini obsługuje natywnie tekst, obrazy i dźwięk. W przypadku czatu z prostym tekstem nic z tego nie jest widoczne: wprowadza się ciągi znaków, a jako wynik otrzymuje się resp.text.

Jedno ostrzeżenie dotyczące bibliotek przed pokazaniem kodu. Przez lata Google wydał kilka pakietów w języku Python, a starsze poradniki są pełne przestarzałych importów, takich jak google-generativeai oraz narzędzi z okresu Bard. Obecnym oficjalnym SDK jest google-genai, importowanym za pomocą from google import genai, i to właśnie ono jest tutaj używane.

Ustawienia i jeden ruch

Zainstaluj go za pomocą pip install google-genai, utwórz klucz w Google AI Studio i wyeksportuj go jako GEMINI_API_KEY. Klient pobiera ten klucz z środowiska, więc w kodzie nigdy nie pojawi się on bezpośrednio.

# current official SDK: pip install google-genai
from google import genai
from google.genai import types

client = genai.Client()  # key from env

resp = client.models.generate_content(
    model="gemini-2.5-flash",
    contents="Why does Gemini name the reply "
             "role 'model', not 'assistant'?",
    config=types.GenerateContentConfig(
        system_instruction="Be concise.",
        temperature=0,
    ),
)
print(resp.text)

W odróżnieniu od dwóch poprzednich dostawców, messages został teraz zastąpiony przez contents, a pojedynczy ruch może być zwykłą łańcuchem znaków. Komenda systemowa trafia do GenerateContentConfig. Temperatura ponownie jest standardowym polem konfiguracyjnym, które poprzednie Claude SDK usunęło. Odpowiedź to po prostu resp.text, a liczby tokenów znajdują się w resp.usage_metadata jako prompt_token_count i candidates_token_count – to te same wartości, tylko oznaczone nazwami używanymi przez Google. Zawsze je rejestruj.

Zarządzany cykl historii

Możliwe jest bezpośrednie przeniesienie własnej funkcji ask(): przechowuj wartości user i model w liście, dodawaj każdą wymianę informacji i za każdym razem przekazuj contents=. To działa. Jednak SDK oferuje udogodnienie, którego klienci OpenAI i Anthropic nie mają od razu: obiekt rozmowy, który zajmuje się dodawaniem tych danych.

chat = client.chats.create(
    model="gemini-2.5-flash",
    config=types.GenerateContentConfig(
        system_instruction="Be concise.",
    ),
)

r1 = chat.send_message(
    "Define a context window."
)
print(r1.text)

r2 = chat.send_message(
    "Now for a five-year-old."
)
print(r2.text)

for turn in chat.get_history():
    part = turn.parts[0].text[:40]
    print(turn.role, "->", part)

Odpowiedź na to pytanie pojawia się w kontekście, ponieważ obiekt czatu cicho odtwarza wcześniejszą wymianę wiadomości, dokładnie tak jak zrobiłaby to funkcja napisana ręcznie. Jeśli przejrzysz get_history() na końcu, zobaczysz naprzemienną kolejność ról user i model – to jest ta sama lista, która została wysłana w ostatniej prośbie. Po stronie serwera nic nie jest przechowywane. Obiekt czatu zapisuje to, co piszemy po stronie klienta, więc tokeny wprowadzanych danych nadal gromadzą się przy każdej kolejności, a długie rozmowy są droższe za każdą próbę połączenia.

Jedna rzecz się nie zmieniła: usługa stojąca za SDK nie pamięta nic między poszczególnymi prośbami.

Wygoda ma swoją cenę, a w przypadku frameworków ma to znaczenie później. Zarządzana historia oznacza mniej kodu i mniej błędów, aż do momentu, gdy musisz usunąć stare wpisy, je podsumować lub włączyć pobraane dokumenty do rozmowy. Wtedy zapragniesz z powrotem prostego listy. LangChain znajduje się na tym samym poziomie skali, ale o jeden stopień wyżej. Bądź zaznajomiony zarówno z listą utrzymywaną ręcznie, jak i z zarządzanym obiektem – żaden z nich nie może cię ograniczyć.

Rozpoczynanie pracy z przykładem

pip install -r requirements.txt
export GEMINI_API_KEY="AIza..."
python examples/part04_gemini.py

Skrypt omawia kolejno trzy kwestie: pojedynczą rundę rozmowy, pętlę ręcznego wyliczania tokenów w celu potwierdzenia ich równoważności oraz zarządzany czat z wyświetlaną historią. Liczba tokenów jest rejestrowana po każdej próbie wywołania. Jeśli nie zostanie ustawiony żaden klucz, skrypt natychmiast się zatrzymuje z wyraźną wiadomością. Ponieważ te wywołania są realizowane w czasie rzeczywistym i opłacane, nie należy go uruchamiać w środowisku CI.

Trzy dostawcy, jeden format

Szybkie porównanie wszystkich trzech. OpenAI traktuje pole system jako zwykłą wiadomość i pozostawia historię użytkownikowi. Claude przekształca system w odrębny parametr, wymaga ustawienia max_tokens i również pozostawia historię użytkownikowi. Gemini umieszcza system_instruction w konfiguracji, nazywa asystenta model i przechowuje historię, jeśli na to pozwolisz. Wszystkie trzy opierają się na tej samej pętli bezstanowej: wysyła się pełną rozmowę, otrzymuje się odpowiedź, dodaje ją do historii i robi się to ponownie.

Dlatego właśnie frameworki wielopodawcze mogą pozostać lekkie, a zmiana dostawcy nie musi być przerażająca. Migracja polega na utworzeniu mapy przemiany nazw, a nie na przepisywaniu kodu.