Robię małego asystenta GPT na swoim komputerze

Najpierw wyjaśnienie, co dokładnie zrobiłem. Kazałem czatowi GPT-4 napisać malutki programik w języku Python. Bardzo mnie to bawi, bo ja nie znam się w ogóle na kodowaniu. Zero. Null. Próbowałem słuchać jakichś wykładów na temat kodowania, ale usypiają mnie perfekcyjnie wręcz. Zamiast tego chcę się pobawić praktycznie, ale na poziomie nieznanym edukatorom i edukatorkom. Do tej pory nie było ludzi, którzy programowali nie wiedząc, jak to się robi. Dzięki czatowi GPT-4 to jest możliwe. Na samym końcu wpisu podaję cenę tej zabawy – ile mnie to kosztowało i czemu warto. Kod podaję również na samym dole.

Źródło ilustracji: GPT-4

Programik ten najpierw zagląda do pliku tekstowego, w którym mam przygotowaną długą i starannie opracowaną instrukcję rozmowy z czatem GPT. W następnym kroku programik/skrypt łączy się z czatem GPT4 bezpośrednio (API), bez wchodzenia na stronę internetową.

GPT, Bard i tego typu produkty, nie mogą zupełnie zastąpić umiejętności programowania. Raz dostaniemy dobrą odpowiedź, innym razem coś będzie wymagało poprawki a czasem efekt będzie bardzo zły. Ja ponieważ nie umiem programować muszę polegać na maszynie w dużo większym stopniu niż programiści i programistki. Muszę też dłużej planować pisanie moich poleceń – upewniać się, że to, o co proszę ma sens.

Nie obyło się problemów, ale po ok 50 minutach otrzymałem wstępnie działający skrypt. Samo otwarcie skryptu kosztuje mnie jednak 4 centy i tyle jest odejmowane od mojego konta, które wcześniej musiałem zasilić. Dwa włączenia skryptu i krótka rozmowa z czatem w sumie kosztowały 11 centów.

Dodałem działające następujące funkcjonalności do skryptu:
1. Na początku ładuje i wysyła jako polecenie treść z pliku .txt
2. Czat odpowiada na tej podstawie kreatywnie.
3. Ja odpowiadam czatowi a koniec mojej odpowiedzi oznacza komenda #Respond
4. Na koniec konwersacji piszę #Over_and_Out i wtedy skrypt zapisuje całą rozmowę do kolejnego pliku .txt

Chciałem, bym pracując z czatem GPT-4 mógł ręcznie uzupełniać zawartość tego pliku tekstowego, tak by jego treść odzwierciedlała postęp mojej pracy na dany temat. Wtedy czat automatycznie będzie od razu wiedział, na jakim etapie jesteśmy. Teraz jednak widzę, że trzeba będzie pójść na całość i wszystko zautomatyzować. Co by mi to dało?

– Czatowi zdarza się zapominać treści rozmów. Stare rozmowy z czatem są też kasowane po jakimś czasie. Teraz mi to nie grozi.
– Nie muszę otwierać przeglądarki, nie obciążam przeglądarki, która przecież może służyć do innych rzeczy w tym czasie i mogę całość przeprowadzić w konsoli (Windows Power Shell), w samym Pythonie lub w Visual Studio Code.
– Szybciej pracuję z czatem GPT-4. Nie zaczynam rozmowy od wpisywania tego samego, długiego polecenia.
– Nie muszę czatowi załączać pliku do odczytania. Niestety czat czasem nie czyta całych plików, które mu wysyłamy albo czytając pomija fragmenty. Tutaj treść pliku od razu jest wysyłana wprost do czata w momencie uruchomienia skryptu.

Co nie zadziałało na początku i co kiepsko działa teraz?
Na początku w treści skryptu czat GPT-4 nie znał sam swojej nazwy i wpisał, że używając klucza API kontaktujemy się z modelem GPT-4,0 turbo. Tymczasem prawidłowa nazwa to po prostu GPT-4 i w związku z tym skrypt nie działał. Znalazłem błąd i poprawiłem nazwę.

Teraz skrypt działa, ale w trakcie rozmowy czat nie pamięta nic z tego, co mi pisze. Jego każdorazowa odpowiedź na moje kolejne polecenia czy pytania wyglądają, jakby miał zero informacji na temat kontekstu. Podejrzewam, że tak działa właśnie komunikacja poprzez API. Nie przewidziałem tego, bo poprzez przeglądarkę rozmawiając z czatem on pamięta treść rozmowy i poprzednio wpisane rzeczy. Mieszczą się w jego oknie kontekstowym. Tu, tak jakby nie było tego okna.

Jeśli to będę chciał naprawić, to muszę dodać funkcję symulującą pamięć. Rozważam następującą opcję. Komenda #Respond będzie oznaczała modyfikację pliku .txt w folderze. I każdorazowo z tego pliku będzie wysyłany coraz dłuższy prompt.

Ewentualnie, dla zaoszczędzenia tokenów, dodam polecenie streszczenia wątków w rozmowie zapisanej w pliku .txt i wysyłania tylko streszczeń, jako elementu symulującego pamięć. W ten sposób, każdy kontakt z czatem poprzez API będzie kontynuacją wcześniej rozpoczętej rozmowy a nie nowym kontaktem.


Ta nauka i zabawa kosztowała mnie około złotówki. Nie licząc prądu. W tej chwili nie jest to przydatny skrypt a mimo to jestem zachwycony.

Czemu? Jasne, że w tej chwili nieco drożej, ale po prostu symuluję działania czata z przeglądarki, ale już przetestowałem kolejne fragmenty skryptu i za moment dzięki bibliotece Pythona (czyli całym zestawom już działających innych skryptów), będę mógł połączyć działanie zupełnie różnych plików z komputera. W jednym momencie. Teoretycznie ten skrypt może wysyłać dane mejlem albo innym komunikatorem albo pobierać kolejne informacje z innej usługi, która też jest sprzęgnięta poprzez API.

Bard Google napisał bardzo podobny kod. Również jeden błąd na początku. Jednak Bard nieco gorzej tłumaczy mi sprawy techniczne – ciągle o coś pytam. Po prostu płynność wypowiedzi Barda jest niższa niż czata GPT-4. Musimy rozmawiać po angielsku tylko, bo nie znam polskiego słownictwa programistycznego a ani OpenAI, ani Google w swoich instrukcjach często nie uwzględniają języka polskiego.

Po angielsku, prostym językiem napisane, jak od początku uzyskać kod API, uruchomić Pythona na naszym komputerze tutaj: https://blog.finxter.com/openai-python-api-a-helpful-illustrated-guide-in-5-steps/

Dowolne sugestie mile widziane.

import openai

import datetime

# Replace ‚your-api-key’ with your actual OpenAI API key

openai.api_key = ‚tu wpisujesz swój kod API’

def create_adventure(prompt):

try:

response = openai.ChatCompletion.create(

model=”gpt-4″,

messages=[

{„role”: „system”, „content”: „You are a helpful assistant.”},

{„role”: „user”, „content”: prompt}

]

)

return response.choices[0].message[‚content’]

except Exception as e:

print(f”An error occurred: {e}”)

return None

def save_conversation(conversation, filename):

with open(filename, ‚w’) as file:

for entry in conversation:

if entry[‚role’] == ‚user’:

prefix = „You: „

else:

prefix = „AI: „

file.write(prefix + entry[‚content’] + ‚\n\n’)

def main():

conversation = []

# Read the initial prompt from the file

file_path = „tu wpisujesz ścieżkę dostępu do pliku .txt”

with open(file_path, ‚r’) as file:

initial_prompt = file.read()

# Start the conversation with the initial prompt

conversation.append({„role”: „user”, „content”: initial_prompt})

ai_response = create_adventure(initial_prompt)

conversation.append({„role”: „assistant”, „content”: ai_response})

print(„AI:”, ai_response)

# Main loop for back-and-forth interaction

while True:

user_input = input(„You: „)

# Check if the user wants to end the conversation

if „#Over_and_Out” in user_input:

# Extract the last three words to form the filename

last_words = ‚ ‚.join(user_input.split()[-4:-1]) # The last element is #Over_and_Out, so take the three before that

timestamp = datetime.datetime.now().strftime(‚%H%M’)

filename = f”{last_words}_{timestamp}.txt”

filepath = f”tu wpisujesz ścieżkę dostępu do pliku .txt{filename}”

save_conversation(conversation, filepath)

print(f”Conversation saved to {filename}”)

break

# Add user input to the conversation and remove command if present

conversation.append({„role”: „user”, „content”: user_input.replace(„#Respond”, „”).strip()})

# If user indicated they have finished their response, get the AI response

if user_input.endswith(„#Respond”):

ai_response = create_adventure(user_input.replace(„#Respond”, „”).strip())

print(„AI:”, ai_response)

conversation.append({„role”: „assistant”, „content”: ai_response})

if __name__ == „__main__”:

main()