# AI Framework Czy kiedykolwiek czułeś się przytłoczony, próbując budować aplikacje AI od podstaw? Nie jesteś sam! Frameworki AI to jak szwajcarski scyzoryk dla programistów AI – to potężne narzędzia, które mogą zaoszczędzić Ci czas i bóle głowy podczas tworzenia inteligentnych aplikacji. Pomyśl o frameworku AI jak o dobrze zorganizowanej bibliotece: zapewnia gotowe komponenty, ustandaryzowane API i sprytne abstrakcje, dzięki czemu możesz skupić się na rozwiązywaniu problemów zamiast zmagać się ze szczegółami implementacji. W tej lekcji odkryjemy, jak frameworki takie jak LangChain mogą zamienić kiedyś skomplikowane zadania integracji AI w czysty, czytelny kod. Dowiesz się, jak radzić sobie z rzeczywistymi wyzwaniami, takimi jak śledzenie rozmów, implementacja wywoływania narzędzi i zarządzanie różnymi modelami AI za pomocą jednego zunifikowanego interfejsu. Po ukończeniu dowiesz się, kiedy sięgnąć po frameworki zamiast surowych wywołań API, jak efektywnie korzystać z ich abstrakcji i jak budować aplikacje AI gotowe na rzeczywiste zastosowania. Poznajmy, co frameworki AI mogą zrobić dla Twoich projektów. ## ⚡ Co możesz zrobić w następnych 5 minut **Szybki start dla zapracowanych programistów** ```mermaid flowchart LR A[⚡ 5 minut] --> B[Zainstaluj LangChain] B --> C[Utwórz klienta ChatOpenAI] C --> D[Wyślij pierwsze zapytanie] D --> E[Zobacz moc frameworka] ``` - **Minuta 1**: Zainstaluj LangChain: `pip install langchain langchain-openai` - **Minuta 2**: Skonfiguruj swój token GitHub i zaimportuj klienta ChatOpenAI - **Minuta 3**: Stwórz prostą rozmowę z wiadomościami systemowymi i od człowieka - **Minuta 4**: Dodaj podstawowe narzędzie (np. funkcję dodawania) i zobacz wywoływanie narzędzi AI - **Minuta 5**: Doświadcz różnicy między surowymi wywołaniami API a abstrakcją frameworku **Szybki test kodu**: ```python from langchain_openai import ChatOpenAI from langchain_core.messages import SystemMessage, HumanMessage llm = ChatOpenAI( api_key=os.environ["GITHUB_TOKEN"], base_url="https://models.github.ai/inference", model="openai/gpt-4o-mini" ) response = llm.invoke([ SystemMessage(content="You are a helpful coding assistant"), HumanMessage(content="Explain Python functions briefly") ]) print(response.content) ``` **Dlaczego to ważne**: W ciągu 5 minut zobaczysz, jak frameworki AI przekształcają skomplikowaną integrację AI w proste wywołania metod. To fundament, który napędza produkcyjne aplikacje AI. ## Dlaczego warto wybrać framework? Jesteś gotowy, aby zbudować aplikację AI – super! Ale sprawa wygląda tak: masz kilka różnych ścieżek do wyboru, a każda z nich ma swoje plusy i minusy. To trochę jak wybór między chodzeniem, jazdą na rowerze lub autem, żeby gdzieś dotrzeć – wszystkie sposoby doprowadzą Cię do celu, ale doświadczenie (i wysiłek) będą zupełnie inne. Rozłożymy na czynniki pierwsze trzy główne sposoby integracji AI w Twoich projektach: | Podejście | Zalety | Najlepsze do | Uwagi | |----------|------------|----------|--------------| | **Bezpośrednie żądania HTTP** | Pełna kontrola, brak zależności | Proste zapytania, nauka podstaw | Bardziej rozbudowany kod, ręczne obsługiwanie błędów | | **Integracja SDK** | Mniej boilerplate’u, optymalizacje specyficzne dla modelu | Aplikacje z jednym modelem | Ograniczone do konkretnych dostawców | | **Frameworki AI** | Zunifikowane API, wbudowane abstrakcje | Aplikacje wielomodelowe, złożone przepływy | Krzywa nauki, możliwość nadmiernej abstrakcji | ### Korzyści z frameworków w praktyce ```mermaid graph TD A[Twoja Aplikacja] --> B[Framework AI] B --> C[OpenAI GPT] B --> D[Anthropic Claude] B --> E[Modele GitHub] B --> F[Modele Lokalnie] B --> G[Narzędzia Wbudowane] G --> H[Zarządzanie Pamięcią] G --> I[Historia Konwersacji] G --> J[Wywoływanie Funkcji] G --> K[Obsługa Błędów] ``` **Dlaczego frameworki są ważne:** - **Integrują** wielu dostawców AI pod jednym interfejsem - **Obsługują** pamięć rozmowy automatycznie - **Dostarczają** gotowe narzędzia do typowych zadań jak embeddingi i wywoływanie funkcji - **Zarządzają** obsługą błędów i logiką ponowień - **Przekształcają** skomplikowane przepływy w czytelne wywołania metod > 💡 **Profesjonalna wskazówka**: Używaj frameworków, gdy przełączasz się między różnymi modelami AI lub budujesz złożone funkcje, takie jak agenci, pamięć czy wywoływanie narzędzi. Stosuj bezpośrednie API, gdy uczysz się podstaw lub tworzysz proste, skoncentrowane aplikacje. **Podsumowując**: Podobnie jak wybór między wyspecjalizowanymi narzędziami rzemieślnika a kompletnym warsztatem, chodzi o dopasowanie narzędzia do zadania. Frameworki sprawdzają się świetnie w złożonych, bogatych funkcjach aplikacjach, podczas gdy bezpośrednie API dobrze działają w prostych zastosowaniach. ## 🗺️ Twoja podróż naukowa przez mistrzostwo frameworków AI ```mermaid journey title Od surowych API do produkcyjnych aplikacji AI section Podstawy frameworka Zrozum korzyści abstrakcji: 4: You Opanuj podstawy LangChain: 6: You Porównaj podejścia: 7: You section Systemy konwersacyjne Buduj interfejsy czatu: 5: You Zaimplementuj wzorce pamięci: 7: You Obsługuj odpowiedzi strumieniowe: 8: You section Zaawansowane funkcje Twórz niestandardowe narzędzia: 6: You Opanuj zorganizowany output: 8: You Buduj systemy dokumentów: 8: You section Aplikacje produkcyjne Połącz wszystkie funkcje: 7: You Obsługuj scenariusze błędów: 8: You Wdrażaj kompletne systemy: 9: You ``` **Cel Twojej podróży**: Pod koniec tej lekcji opanujesz rozwój w frameworkach AI i będziesz w stanie tworzyć zaawansowane, gotowe do produkcji aplikacje AI, które konkurują z komercyjnymi asystentami AI. ## Wprowadzenie W tej lekcji nauczysz się: - Korzystać z popularnego frameworku AI. - Rozwiązywać typowe problemy, takie jak rozmowy czatowe, użycie narzędzi, pamięć i kontekst. - Wykorzystywać to do budowania aplikacji AI. ## 🧠 Ekosystem rozwoju frameworków AI ```mermaid mindmap root((Ramki AI)) Abstraction Benefits Code Simplification Unified APIs Built-in Error Handling Consistent Patterns Reduced Boilerplate Multi-Model Support Provider Agnostic Easy Switching Fallback Options Cost Optimization Core Components Conversation Management Message Types Memory Systems Context Tracking History Persistence Tool Integration Function Calling API Connections Custom Tools Workflow Automation Advanced Features Structured Output Pydantic Models JSON Schemas Type Safety Validation Rules Document Processing Embeddings Vector Stores Similarity Search RAG Systems Production Patterns Application Architecture Modular Design Error Boundaries Async Operations State Management Deployment Strategies Scalability Monitoring Performance Security ``` **Główna zasada**: Frameworki AI upraszczają złożoność, oferując potężne abstrakcje do zarządzania rozmowami, integracji narzędzi i przetwarzania dokumentów, umożliwiając programistom tworzenie zaawansowanych aplikacji AI z czystym i łatwym w utrzymaniu kodem. ## Twój pierwszy prompt AI Zacznijmy od podstaw, tworząc pierwszą aplikację AI, która wysyła pytanie i otrzymuje odpowiedź. Podobnie jak Archimedes odkrywający zasadę wyporu w swojej kąpieli, czasem najprostsze obserwacje prowadzą do najpotężniejszych wniosków – a frameworki udostępniają te wnioski. ### Konfiguracja LangChain z modelami GitHub Użyjemy LangChain do połączenia się z modelami GitHub, co jest całkiem fajne, ponieważ daje darmowy dostęp do różnych modeli AI. Najlepsza część? Potrzebujesz tylko kilku prostych parametrów konfiguracyjnych, aby zacząć: ```python from langchain_openai import ChatOpenAI import os llm = ChatOpenAI( api_key=os.environ["GITHUB_TOKEN"], base_url="https://models.github.ai/inference", model="openai/gpt-4o-mini", ) # Wyślij proste polecenie response = llm.invoke("What's the capital of France?") print(response.content) ``` **Oto co się tutaj dzieje:** - **Tworzy** klienta LangChain za pomocą klasy `ChatOpenAI` – to twój wstęp do AI! - **Konfiguruje** połączenie do modeli GitHub z Twoim tokenem uwierzytelniającym - **Określa**, którego modelu AI używać (`gpt-4o-mini`) – pomyśl o tym jak o wyborze asystenta AI - **Wysyła** pytanie metodą `invoke()` – tutaj dzieje się magia - **Wyciąga** i wyświetla odpowiedź – voilà, rozmawiasz z AI! > 🔧 **Notatka**: Jeśli korzystasz z GitHub Codespaces, masz szczęście – `GITHUB_TOKEN` jest już skonfigurowany! Pracujesz lokalnie? Spokojnie, będziesz musiał stworzyć token dostępu osobistego z odpowiednimi uprawnieniami. **Oczekiwany wynik:** ```text The capital of France is Paris. ``` ```mermaid sequenceDiagram participant App as Twoja aplikacja Python participant LC as LangChain participant GM as Modele GitHub participant AI as GPT-4o-mini App->>LC: llm.invoke("Jaka jest stolica Francji?") LC->>GM: Żądanie HTTP z podpowiedzią GM->>AI: Przetwórz podpowiedź AI->>GM: Wygenerowana odpowiedź GM->>LC: Zwróć odpowiedź LC->>App: response.content ``` ## Budowanie konwersacyjnej AI Ten pierwszy przykład demonstruje podstawy, ale to tylko jedna wymiana – zadajesz pytanie, dostajesz odpowiedź i to wszystko. W rzeczywistych aplikacjach chcesz, aby AI pamiętało, o czym rozmawialiście, tak jak Watson i Holmes budowali swoje śledcze rozmowy na przestrzeni czasu. Tu LangChain okazuje się szczególnie przydatne. Udostępnia różne typy wiadomości, które pomagają strukturyzować rozmowy i pozwalają nadać AI osobowość. Będziesz tworzyć czaty utrzymujące kontekst i charakter. ### Zrozumienie typów wiadomości Pomyśl o typach wiadomości jak o różnych „kapeluszach”, które uczestnicy noszą w rozmowie. LangChain używa różnych klas wiadomości, by śledzić, kto co mówi: | Typ Wiadomości | Cel | Przykład Zastosowania | |--------------|---------|------------------| | `SystemMessage` | Definiuje osobowość i zachowanie AI | "Jesteś pomocnym asystentem programistycznym" | | `HumanMessage` | Reprezentuje wejście użytkownika | "Wyjaśnij, jak działają funkcje" | | `AIMessage` | Przechowuje odpowiedzi AI | Poprzednie odpowiedzi AI w rozmowie | ### Tworzenie pierwszej rozmowy Stwórzmy rozmowę, w której AI przyjmuje konkretną rolę. Niech będzie Kapitanem Picardem – postacią znaną z dyplomatycznej mądrości i przywództwa: ```python messages = [ SystemMessage(content="You are Captain Picard of the Starship Enterprise"), HumanMessage(content="Tell me about you"), ] ``` **Co robi ta konfiguracja rozmowy:** - **Ustala** rolę i osobowość AI przez `SystemMessage` - **Dostarcza** wstępne zapytanie użytkownika za pomocą `HumanMessage` - **Tworzy** podstawę do rozmowy wieloetapowej Pełny kod tego przykładu wygląda tak: ```python from langchain_core.messages import HumanMessage, SystemMessage from langchain_openai import ChatOpenAI import os llm = ChatOpenAI( api_key=os.environ["GITHUB_TOKEN"], base_url="https://models.github.ai/inference", model="openai/gpt-4o-mini", ) messages = [ SystemMessage(content="You are Captain Picard of the Starship Enterprise"), HumanMessage(content="Tell me about you"), ] # działa response = llm.invoke(messages) print(response.content) ``` Powinieneś zobaczyć wynik podobny do: ```text I am Captain Jean-Luc Picard, the commanding officer of the USS Enterprise (NCC-1701-D), a starship in the United Federation of Planets. My primary mission is to explore new worlds, seek out new life and new civilizations, and boldly go where no one has gone before. I believe in the importance of diplomacy, reason, and the pursuit of knowledge. My crew is diverse and skilled, and we often face challenges that test our resolve, ethics, and ingenuity. Throughout my career, I have encountered numerous species, grappled with complex moral dilemmas, and have consistently sought peaceful solutions to conflicts. I hold the ideals of the Federation close to my heart, believing in the importance of cooperation, understanding, and respect for all sentient beings. My experiences have shaped my leadership style, and I strive to be a thoughtful and just captain. How may I assist you further? ``` Aby zachować ciągłość rozmowy (zamiast resetować kontekst za każdym razem), musisz ciągle dodawać odpowiedzi do listy wiadomości. Podobnie jak ustne tradycje przekazujące historie z pokolenia na pokolenie, takie podejście buduje trwałą pamięć: ```python from langchain_core.messages import HumanMessage, SystemMessage from langchain_openai import ChatOpenAI import os llm = ChatOpenAI( api_key=os.environ["GITHUB_TOKEN"], base_url="https://models.github.ai/inference", model="openai/gpt-4o-mini", ) messages = [ SystemMessage(content="You are Captain Picard of the Starship Enterprise"), HumanMessage(content="Tell me about you"), ] # działa response = llm.invoke(messages) print(response.content) print("---- Next ----") messages.append(response) messages.append(HumanMessage(content="Now that I know about you, I'm Chris, can I be in your crew?")) response = llm.invoke(messages) print(response.content) ``` Całkiem niezłe, prawda? Dzieje się tu tak, że wywołujemy LLM dwukrotnie – najpierw z dwoma początkowymi wiadomościami, a potem ponownie z pełną historią rozmowy. To tak, jakby AI naprawdę śledziło naszą rozmowę! Kiedy uruchomisz ten kod, otrzymasz drugą odpowiedź, która może brzmieć tak: ```text Welcome aboard, Chris! It's always a pleasure to meet those who share a passion for exploration and discovery. While I cannot formally offer you a position on the Enterprise right now, I encourage you to pursue your aspirations. We are always in need of talented individuals with diverse skills and backgrounds. If you are interested in space exploration, consider education and training in the sciences, engineering, or diplomacy. The values of curiosity, resilience, and teamwork are crucial in Starfleet. Should you ever find yourself on a starship, remember to uphold the principles of the Federation: peace, understanding, and respect for all beings. Your journey can lead you to remarkable adventures, whether in the stars or on the ground. Engage! ``` ```mermaid sequenceDiagram participant User participant App participant LangChain participant AI User->>App: "Opowiedz mi o sobie" App->>LangChain: [SystemMessage, HumanMessage] LangChain->>AI: Sformatowana konwersacja AI->>LangChain: Odpowiedź Kapitana Picarda LangChain->>App: Obiekt AIMessage App->>User: Wyświetl odpowiedź Note over App: Dodaj AIMessage do konwersacji User->>App: "Czy mogę dołączyć do twojej załogi?" App->>LangChain: [SystemMessage, HumanMessage, AIMessage, HumanMessage] LangChain->>AI: Pełny kontekst rozmowy AI->>LangChain: Odpowiedź kontekstowa LangChain->>App: Nowy AIMessage App->>User: Wyświetl odpowiedź kontekstową ``` Wezmę to jako „może” ;) ## Streaming odpowiedzi Czy zauważyłeś, jak ChatGPT zdaje się „pisać” odpowiedzi w czasie rzeczywistym? To właśnie streaming w akcji. Podobnie jak obserwowanie zręcznego kaligrafa – widzisz, jak pojawiają się litery krok po kroku, zamiast natychmiast – streaming sprawia, że interakcja jest bardziej naturalna i daje natychmiastową informację zwrotną. ### Implementacja streamingu w LangChain ```python from langchain_openai import ChatOpenAI import os llm = ChatOpenAI( api_key=os.environ["GITHUB_TOKEN"], base_url="https://models.github.ai/inference", model="openai/gpt-4o-mini", streaming=True ) # Strumieniuj odpowiedź for chunk in llm.stream("Write a short story about a robot learning to code"): print(chunk.content, end="", flush=True) ``` **Dlaczego streaming jest świetny:** - **Pokazuje** zawartość, gdy jest tworzona – koniec z niezręcznym czekaniem! - **Sprawia**, że użytkownicy czują, iż coś się faktycznie dzieje - **Wydaje się** szybszy, nawet jeśli technicznie taki nie jest - **Pozwala** rozpocząć czytanie, podczas gdy AI jeszcze „myśli” > 💡 **Wskazówka dla UX**: Streaming szczególnie błyszczy przy dłuższych odpowiedziach, takich jak wyjaśnienia kodu, kreatywne pisanie czy szczegółowe tutoriale. Twoi użytkownicy pokochają widzieć postęp zamiast patrzeć na pusty ekran! ### 🎯 Pedagogiczna chwila refleksji: Korzyści abstrakcji frameworku **Zatrzymaj się i pomyśl**: Właśnie doświadczyłeś mocy abstrakcji frameworków AI. Porównaj to, czego się nauczyłeś, z surowymi wywołaniami API z poprzednich lekcji. **Szybka autoocena**: - Czy potrafisz wyjaśnić, jak LangChain upraszcza zarządzanie rozmową w porównaniu z ręcznym śledzeniem wiadomości? - Jaka jest różnica między metodami `invoke()` a `stream()` i kiedy ich używać? - Jak system typów wiadomości w frameworku poprawia organizację kodu? **Połączenie z rzeczywistością**: Schematy abstrakcji, które poznałeś (typy wiadomości, interfejsy strumieniowe, pamięć rozmowy) są używane w każdej dużej aplikacji AI – od interfejsu ChatGPT po pomoc kodową GitHub Copilot. Opanowujesz te same wzorce architektoniczne, które stosują profesjonalne zespoły deweloperskie AI. **Pytanie wyzwania**: Jak zaprojektowałbyś abstrakcję frameworku do obsługi różnych dostawców modeli AI (OpenAI, Anthropic, Google) za pomocą jednolitego interfejsu? Rozważ korzyści i kompromisy. ## Szablony promptów Szablony promptów działają jak struktury retoryczne stosowane w klasycznej oratorii – pomyśl o tym, jak Cyceron dostosowywał swoje wzorce mowy do różnych odbiorców, zachowując tę samą perswazyjną ramę. Pozwalają tworzyć wielokrotnego użytku pytania, w których można wymieniać różne elementy bez przepisywania wszystkiego od nowa. Po skonfigurowaniu szablonu wystarczy wypełnić zmienne odpowiednimi wartościami. ### Tworzenie wielokrotnego użytku promptów ```python from langchain_core.prompts import ChatPromptTemplate # Zdefiniuj szablon do wyjaśnień kodu template = ChatPromptTemplate.from_messages([ ("system", "You are an expert programming instructor. Explain concepts clearly with examples."), ("human", "Explain {concept} in {language} with a practical example for {skill_level} developers") ]) # Użyj szablonu z różnymi wartościami questions = [ {"concept": "functions", "language": "JavaScript", "skill_level": "beginner"}, {"concept": "classes", "language": "Python", "skill_level": "intermediate"}, {"concept": "async/await", "language": "JavaScript", "skill_level": "advanced"} ] for question in questions: prompt = template.format_messages(**question) response = llm.invoke(prompt) print(f"Topic: {question['concept']}\n{response.content}\n---\n") ``` **Dlaczego pokochasz szablony:** - **Utrzymują** spójność promptów w całej aplikacji - **Koniec z** brzydkim łączeniem stringów – tylko czyste, proste zmienne - **Twoje AI** zachowuje się przewidywalnie, bo struktura pozostaje niezmienna - **Aktualizacje** to pestka – zmieniasz szablon raz i zmiana obowiązuje wszędzie ## Strukturalne outputy Czy zdarzyło Ci się frustrować podczas próby analizowania odpowiedzi AI, które wracają jako niestrukturalny tekst? Strukturalny output to jak nauczenie AI, aby stosowało systematyczne podejście, które Linneusz używał do klasyfikacji biologicznej – uporządkowane, przewidywalne i łatwe w obsłudze. Możesz żądać JSON, konkretnych struktur danych lub dowolnego formatu, którego potrzebujesz. ### Definiowanie schematów outputu ```python from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import JsonOutputParser from pydantic import BaseModel, Field class CodeReview(BaseModel): score: int = Field(description="Code quality score from 1-10") strengths: list[str] = Field(description="List of code strengths") improvements: list[str] = Field(description="List of suggested improvements") overall_feedback: str = Field(description="Summary feedback") # Skonfiguruj parser parser = JsonOutputParser(pydantic_object=CodeReview) # Utwórz prompt z instrukcjami formatowania prompt = ChatPromptTemplate.from_messages([ ("system", "You are a code reviewer. {format_instructions}"), ("human", "Review this code: {code}") ]) # Sformatuj prompt z instrukcjami chain = prompt | llm | parser # Pobierz uporządkowaną odpowiedź code_sample = """ def calculate_average(numbers): return sum(numbers) / len(numbers) """ result = chain.invoke({ "code": code_sample, "format_instructions": parser.get_format_instructions() }) print(f"Score: {result['score']}") print(f"Strengths: {', '.join(result['strengths'])}") ``` **Dlaczego strukturalny output zmienia zasady gry:** - **Koniec z** zgadywaniem, jaki format dostaniesz – jest zawsze spójny - **Podłącza się** bezpośrednio do Twoich baz danych i API bez dodatkowej pracy - **Wykrywa** dziwne odpowiedzi AI, zanim zepsują Twoją aplikację - **Upraszcza** Twój kod, bo dokładnie wiesz, z czym pracujesz ## Wywoływanie narzędzi Teraz docieramy do jednej z najbardziej potężnych funkcji: narzędzi. To sposób, aby dać Twojemu AI praktyczne zdolności wykraczające poza samą rozmowę. Podobnie jak średniowieczne gildie tworzyły specjalistyczne narzędzia do konkretnych rzemiosł, możesz wyposażyć AI w ukierunkowane instrumenty. Opisujesz dostępne narzędzia, a gdy ktoś poprosi o coś, co pasuje do ich zakresu, AI może podjąć działanie. ### Używanie Pythona Dodajmy kilka narzędzi w ten sposób: ```python from typing_extensions import Annotated, TypedDict class add(TypedDict): """Add two integers.""" # Adnotacje muszą mieć typ i opcjonalnie mogą zawierać wartość domyślną oraz opis (w tej kolejności). a: Annotated[int, ..., "First integer"] b: Annotated[int, ..., "Second integer"] tools = [add] functions = { "add": lambda a, b: a + b } ``` Co tu się dzieje? Tworzymy szablon narzędzia o nazwie `add`. Dziedzicząc po `TypedDict` i używając tych fajnych typów `Annotated` dla `a` i `b`, dajemy LLM jasny obraz, co to narzędzie robi i czego potrzebuje. Słownik `functions` jest jak nasza skrzynka narzędziowa – mówi naszemu kodowi dokładnie, co zrobić, gdy AI zdecyduje się użyć konkretnego narzędzia. Zobaczmy, jak wywołujemy LLM z tym narzędziem: ```python llm = ChatOpenAI( api_key=os.environ["GITHUB_TOKEN"], base_url="https://models.github.ai/inference", model="openai/gpt-4o-mini", ) llm_with_tools = llm.bind_tools(tools) ``` Wywołujemy `bind_tools` z tablicą `tools`, dzięki czemu nowy LLM `llm_with_tools` posiada wiedzę o tym narzędziu. Aby użyć tego nowego LLM, możemy wpisać następujący kod: ```python query = "What is 3 + 12?" res = llm_with_tools.invoke(query) if(res.tool_calls): for tool in res.tool_calls: print("TOOL CALL: ", functions[tool["name"]](../../../10-ai-framework-project/**tool["args"])) print("CONTENT: ",res.content) ``` Teraz, gdy wywołujemy `invoke` na tym nowym llm, które ma narzędzia, właściwość `tool_calls` może zostać wypełniona. Jeśli tak, każde zidentyfikowane narzędzie posiada właściwości `name` i `args`, które określają, jakie narzędzie ma być wywołane i z jakimi argumentami. Pełny kod wygląda tak: ```python from langchain_core.messages import HumanMessage, SystemMessage from langchain_openai import ChatOpenAI import os from typing_extensions import Annotated, TypedDict class add(TypedDict): """Add two integers.""" # Adnotacje muszą mieć typ i mogą opcjonalnie zawierać wartość domyślną oraz opis (w tej kolejności). a: Annotated[int, ..., "First integer"] b: Annotated[int, ..., "Second integer"] tools = [add] functions = { "add": lambda a, b: a + b } llm = ChatOpenAI( api_key=os.environ["GITHUB_TOKEN"], base_url="https://models.github.ai/inference", model="openai/gpt-4o-mini", ) llm_with_tools = llm.bind_tools(tools) query = "What is 3 + 12?" res = llm_with_tools.invoke(query) if(res.tool_calls): for tool in res.tool_calls: print("TOOL CALL: ", functions[tool["name"]](../../../10-ai-framework-project/**tool["args"])) print("CONTENT: ",res.content) ``` Po uruchomieniu kodu powinieneś zobaczyć wynik podobny do: ```text TOOL CALL: 15 CONTENT: ``` AI przeanalizowało pytanie "Co to jest 3 + 12" i rozpoznało to jako zadanie dla narzędzia `add`. Podobnie jak doświadczony bibliotekarz wie, z którego źródła korzystać w zależności od pytania, podjęło tę decyzję na podstawie nazwy narzędzia, opisu i specyfikacji pól. Wynik 15 pochodzi ze słownika `functions` wykonującego narzędzie: ```python print("TOOL CALL: ", functions[tool["name"]](../../../10-ai-framework-project/**tool["args"])) ``` ### Bardziej interesujące narzędzie wywołujące API sieciowe Dodawanie liczb ilustruje koncept, ale prawdziwe narzędzia zazwyczaj wykonują bardziej złożone operacje, takie jak wywoływanie API internetowych. Rozszerzmy nasz przykład tak, aby AI pobierało zawartość z internetu – podobnie jak operatorzy telegrafu kiedyś łączyli odległe lokalizacje: ```python class joke(TypedDict): """Tell a joke.""" # Adnotacje muszą mieć typ i mogą opcjonalnie zawierać wartość domyślną oraz opis (w tej kolejności). category: Annotated[str, ..., "The joke category"] def get_joke(category: str) -> str: response = requests.get(f"https://api.chucknorris.io/jokes/random?category={category}", headers={"Accept": "application/json"}) if response.status_code == 200: return response.json().get("value", f"Here's a {category} joke!") return f"Here's a {category} joke!" functions = { "add": lambda a, b: a + b, "joke": lambda category: get_joke(category) } query = "Tell me a joke about animals" # reszta kodu jest taka sama ``` Teraz, jeśli uruchomisz ten kod, otrzymasz odpowiedź mówiącą coś w stylu: ```text TOOL CALL: Chuck Norris once rode a nine foot grizzly bear through an automatic car wash, instead of taking a shower. CONTENT: ``` ```mermaid flowchart TD A[Zapytanie użytkownika: "Opowiedz mi dowcip o zwierzętach"] --> B[Analiza LangChain] B --> C{Czy narzędzie jest dostępne?} C -->|Tak| D[Wybierz narzędzie do dowcipów] C -->|Nie| E[Wygeneruj bezpośrednią odpowiedź] D --> F[Wyodrębnij parametry] F --> G[Wywołaj dowcip(kategoria="zwierzęta")] G --> H[Żądanie API do chucknorris.io] H --> I[Zwróć treść dowcipu] I --> J[Wyświetl użytkownikowi] E --> K[Odpowiedź wygenerowana przez AI] K --> J subgraph "Warstwa definicji narzędzi" L[Schemat TypedDict] M[Implementacja funkcji] N[Walidacja parametrów] end D --> L F --> N G --> M ``` Oto kod w całości: ```python from langchain_openai import ChatOpenAI import requests import os from typing_extensions import Annotated, TypedDict class add(TypedDict): """Add two integers.""" # Adnotacje muszą mieć typ i mogą opcjonalnie zawierać wartość domyślną oraz opis (w tej kolejności). a: Annotated[int, ..., "First integer"] b: Annotated[int, ..., "Second integer"] class joke(TypedDict): """Tell a joke.""" # Adnotacje muszą mieć typ i mogą opcjonalnie zawierać wartość domyślną oraz opis (w tej kolejności). category: Annotated[str, ..., "The joke category"] tools = [add, joke] def get_joke(category: str) -> str: response = requests.get(f"https://api.chucknorris.io/jokes/random?category={category}", headers={"Accept": "application/json"}) if response.status_code == 200: return response.json().get("value", f"Here's a {category} joke!") return f"Here's a {category} joke!" functions = { "add": lambda a, b: a + b, "joke": lambda category: get_joke(category) } llm = ChatOpenAI( api_key=os.environ["GITHUB_TOKEN"], base_url="https://models.github.ai/inference", model="openai/gpt-4o-mini", ) llm_with_tools = llm.bind_tools(tools) query = "Tell me a joke about animals" res = llm_with_tools.invoke(query) if(res.tool_calls): for tool in res.tool_calls: # print("WYWOŁANIE NARZĘDZIA: ", tool) print("TOOL CALL: ", functions[tool["name"]](../../../10-ai-framework-project/**tool["args"])) print("CONTENT: ",res.content) ``` ## Embeddingi i przetwarzanie dokumentów Embeddingi to jedno z najpiękniejszych rozwiązań we współczesnej AI. Wyobraź sobie, że możesz wziąć dowolny kawałek tekstu i przekształcić go w współrzędne liczbowe, które uchwytują jego znaczenie. Właśnie to robią embeddingi – przekształcają tekst w punkty w przestrzeni wielowymiarowej, gdzie podobne koncepcje skupiają się razem. To jak system współrzędnych dla pomysłów, przypominający sposób, w jaki Mendelejew uporządkował układ okresowy według właściwości atomowych. ### Tworzenie i używanie embeddingów ```python from langchain_openai import OpenAIEmbeddings from langchain_community.vectorstores import FAISS from langchain_community.document_loaders import TextLoader from langchain.text_splitter import CharacterTextSplitter # Inicjalizuj osadzenia embeddings = OpenAIEmbeddings( api_key=os.environ["GITHUB_TOKEN"], base_url="https://models.github.ai/inference", model="text-embedding-3-small" ) # Załaduj i podziel dokumenty loader = TextLoader("documentation.txt") documents = loader.load() text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) texts = text_splitter.split_documents(documents) # Utwórz magazyn wektorów vectorstore = FAISS.from_documents(texts, embeddings) # Wykonaj wyszukiwanie podobieństwa query = "How do I handle user authentication?" similar_docs = vectorstore.similarity_search(query, k=3) for doc in similar_docs: print(f"Relevant content: {doc.page_content[:200]}...") ``` ### Ładowarki dokumentów dla różnych formatów ```python from langchain_community.document_loaders import ( PyPDFLoader, CSVLoader, JSONLoader, WebBaseLoader ) # Załaduj różne typy dokumentów pdf_loader = PyPDFLoader("manual.pdf") csv_loader = CSVLoader("data.csv") json_loader = JSONLoader("config.json") web_loader = WebBaseLoader("https://example.com/docs") # Przetwórz wszystkie dokumenty all_documents = [] for loader in [pdf_loader, csv_loader, json_loader, web_loader]: docs = loader.load() all_documents.extend(docs) ``` **Co możesz zrobić za pomocą embeddingów:** - **Zbudować** wyszukiwanie, które naprawdę rozumie, co masz na myśli, a nie tylko dopasowanie słów kluczowych - **Stworzyć** AI, które potrafi odpowiadać na pytania dotyczące twoich dokumentów - **Wykonać** systemy rekomendacji sugerujące naprawdę istotne treści - **Automatycznie** organizować i kategoryzować twoje materiały ```mermaid flowchart LR A[Dokumenty] --> B[Podział Tekstu] B --> C[Tworzenie Osadzeń] C --> D[Magazyn Wektorów] E[Zapytanie Użytkownika] --> F[Osadzenie Zapytania] F --> G[Wyszukiwanie Podobieństw] G --> D D --> H[Istotne Dokumenty] H --> I[Odpowiedź AI] subgraph "Przestrzeń Wektorowa" J[Dokument A: [0.1, 0.8, 0.3...]] K[Dokument B: [0.2, 0.7, 0.4...]] L[Zapytanie: [0.15, 0.75, 0.35...]] end C --> J C --> K F --> L G --> J G --> K ``` ## Budowanie kompletnej aplikacji AI Teraz zintegrujemy wszystko, czego się nauczyłeś, w kompleksową aplikację – asystenta do programowania, który potrafi odpowiadać na pytania, korzystać z narzędzi i utrzymywać pamięć rozmowy. Podobnie jak druk łączył istniejące technologie (czcionki ruchome, tusz, papier i nacisk) w coś przełomowego, połączymy nasze komponenty AI w coś praktycznego i użytecznego. ### Przykład kompletnej aplikacji ```python from langchain_openai import ChatOpenAI, OpenAIEmbeddings from langchain_core.prompts import ChatPromptTemplate from langchain_core.messages import HumanMessage, SystemMessage, AIMessage from langchain_community.vectorstores import FAISS from typing_extensions import Annotated, TypedDict import os import requests class CodingAssistant: def __init__(self): self.llm = ChatOpenAI( api_key=os.environ["GITHUB_TOKEN"], base_url="https://models.github.ai/inference", model="openai/gpt-4o-mini" ) self.conversation_history = [ SystemMessage(content="""You are an expert coding assistant. Help users learn programming concepts, debug code, and write better software. Use tools when needed and maintain a helpful, encouraging tone.""") ] # Zdefiniuj narzędzia self.setup_tools() def setup_tools(self): class web_search(TypedDict): """Search for programming documentation or examples.""" query: Annotated[str, "Search query for programming help"] class code_formatter(TypedDict): """Format and validate code snippets.""" code: Annotated[str, "Code to format"] language: Annotated[str, "Programming language"] self.tools = [web_search, code_formatter] self.llm_with_tools = self.llm.bind_tools(self.tools) def chat(self, user_input: str): # Dodaj wiadomość użytkownika do rozmowy self.conversation_history.append(HumanMessage(content=user_input)) # Pobierz odpowiedź AI response = self.llm_with_tools.invoke(self.conversation_history) # Obsłuż wywołania narzędzi, jeśli są if response.tool_calls: for tool_call in response.tool_calls: tool_result = self.execute_tool(tool_call) print(f"🔧 Tool used: {tool_call['name']}") print(f"📊 Result: {tool_result}") # Dodaj odpowiedź AI do rozmowy self.conversation_history.append(response) return response.content def execute_tool(self, tool_call): tool_name = tool_call['name'] args = tool_call['args'] if tool_name == 'web_search': return f"Found documentation for: {args['query']}" elif tool_name == 'code_formatter': return f"Formatted {args['language']} code: {args['code'][:50]}..." return "Tool execution completed" # Przykład użycia assistant = CodingAssistant() print("🤖 Coding Assistant Ready! Type 'quit' to exit.\n") while True: user_input = input("You: ") if user_input.lower() == 'quit': break response = assistant.chat(user_input) print(f"🤖 Assistant: {response}\n") ``` **Architektura aplikacji:** ```mermaid graph TD A[Wejście użytkownika] --> B[Asystent kodowania] B --> C[Pamięć rozmowy] B --> D[Wykrywanie narzędzi] B --> E[Przetwarzanie LLM] D --> F[Narzędzie wyszukiwania w sieci] D --> G[Narzędzie formatowania kodu] E --> H[Generowanie odpowiedzi] F --> H G --> H H --> I[Interfejs użytkownika] H --> C ``` **Kluczowe funkcje, które zaimplementowaliśmy:** - **Pamięta** całą twoją rozmowę dla ciągłości kontekstu - **Wykonuje działania** poprzez wywoływanie narzędzi, nie tylko rozmowę - **Podąża** za przewidywalnymi wzorcami interakcji - **Zarządza** obsługą błędów i złożonymi procesami automatycznie ### 🎯 Pedagogiczne podsumowanie: Architektura AI produkcyjnego poziomu **Zrozumienie architektury**: Zbudowałeś kompletną aplikację AI łączącą zarządzanie rozmową, wywoływanie narzędzi oraz zorganizowane procesy. To reprezentuje rozwój aplikacji AI na poziomie produkcyjnym. **Opanowane kluczowe koncepcje**: - **Architektura oparta na klasach**: uporządkowana, łatwa do utrzymania struktura aplikacji AI - **Integracja narzędzi**: funkcjonalność niestandardowa wykraczająca poza rozmowę - **Zarządzanie pamięcią**: trwały kontekst konwersacji - **Obsługa błędów**: solidne zachowanie aplikacji **Powiązanie z branżą**: Wzorce architektoniczne, które zaimplementowałeś (klasy rozmów, systemy narzędzi, zarządzanie pamięcią) to te same wzorce używane w korporacyjnych aplikacjach AI, takich jak asystent AI Slacka, GitHub Copilot czy Microsoft Copilot. Budujesz z myśleniem na profesjonalnym poziomie. **Pytanie do refleksji**: Jak rozwiniesz tę aplikację, by obsługiwała wielu użytkowników, trwałą pamięć albo integrację z zewnętrznymi bazami danych? Weź pod uwagę wyzwania związane ze skalowalnością i zarządzaniem stanem. ## Zadanie: Zbuduj własnego asystenta naukowego zasilanego AI **Cel**: Stwórz aplikację AI, która pomoże studentom uczyć się programowania, dostarczając wyjaśnienia, przykłady kodu oraz interaktywne quizy. ### Wymagania **Podstawowe funkcje (wymagane):** 1. **Interfejs rozmowy**: Zaimplementuj system czatu, który zachowuje kontekst przez wiele pytań 2. **Narzędzia edukacyjne**: Stwórz co najmniej dwa narzędzia wspierające naukę: - narzędzie do wyjaśniania kodu - generator quizów koncepcyjnych 3. **Spersonalizowane uczenie**: Wykorzystaj komunikaty systemowe, by dostosować odpowiedzi do różnych poziomów zaawansowania 4. **Formatowanie odpowiedzi**: Zaimplementuj ustrukturyzowane wyjście dla pytań quizowych ### Kroki wdrożenia **Krok 1: Przygotuj środowisko** ```bash pip install langchain langchain-openai ``` **Krok 2: Podstawowa funkcjonalność czatu** - Stwórz klasę `StudyAssistant` - Zaimplementuj pamięć rozmowy - Dodaj konfigurację osobowości dla wsparcia edukacyjnego **Krok 3: Dodaj narzędzia edukacyjne** - **Wyjaśniacz kodu**: rozkłada kod na zrozumiałe części - **Generator quizów**: tworzy pytania dotyczące koncepcji programistycznych - **Śledzenie postępów**: monitoruje przerobione tematy **Krok 4: Rozszerzone funkcje (opcjonalnie)** - Wdroż odpowiedzi strumieniowe dla lepszego doświadczenia użytkownika - Dodaj ładowanie dokumentów, aby uwzględnić materiały kursowe - Stwórz embeddingi do wyszukiwania semantycznego w materiałach ### Kryteria oceny | Funkcja | Doskonała (4) | Dobra (3) | Zadowalająca (2) | Wymaga pracy (1) | |---------|----------------|----------|------------------|------------------| | **Przebieg rozmowy** | Naturalne, świadome kontekstu odpowiedzi | Dobra pamięć kontekstu | Podstawowa rozmowa | Brak pamięci między wymianami | | **Integracja narzędzi** | Wiele użytecznych narzędzi działa bezproblemowo | 2+ narzędzia poprawnie zaimplementowane | 1-2 narzędzia podstawowe | Narzędzia nie działają | | **Jakość kodu** | Czysty, dobrze udokumentowany, obsługa błędów | Dobra struktura, częściowa dokumentacja | Podstawowa funkcjonalność działa | Słaba struktura, brak obsługi błędów | | **Wartość edukacyjna** | Naprawdę pomocne w nauce, adaptacyjne | Dobre wsparcie nauki | Podstawowe wyjaśnienia | Ograniczona wartość edukacyjna | ### Przykładowa struktura kodu ```python class StudyAssistant: def __init__(self, skill_level="beginner"): # Inicjalizuj LLM, narzędzia i pamięć konwersacji pass def explain_code(self, code, language): # Narzędzie: Wyjaśnij, jak działa kod pass def generate_quiz(self, topic, difficulty): # Narzędzie: Twórz pytania do ćwiczeń pass def chat(self, user_input): # Główne interfejs konwersacji pass # Przykładowe użycie assistant = StudyAssistant(skill_level="intermediate") response = assistant.chat("Explain how Python functions work") ``` **Dodatkowe wyzwania:** - Dodaj obsługę wejścia/wyjścia głosowego - Wdroż interfejs webowy za pomocą Streamlit lub Flask - Stwórz bazę wiedzy z materiałów kursowych przy pomocy embeddingów - Dodaj śledzenie postępów i spersonalizowane ścieżki nauki ## 📈 Twoja oś mistrzostwa w rozwoju frameworków AI ```mermaid timeline title Droga Rozwoju Produkcyjnego Frameworka AI section Fundamenty Frameworka Zrozumienie Abstrakcji : Decyzje dotyczące głównego frameworka vs API : Poznaj podstawowe koncepcje LangChain : Implementuj systemy typów wiadomości Podstawowa Integracja : Połącz z dostawcami AI : Obsłuż uwierzytelnianie : Zarządzaj konfiguracją section Systemy Konwersacyjne Zarządzanie Pamięcią : Buduj historię konwersacji : Implementuj śledzenie kontekstu : Obsłuż utrzymanie sesji Zaawansowane Interakcje : Opanuj strumieniowanie odpowiedzi : Twórz szablony promptów : Implementuj strukturalne wyniki section Integracja Narzędzi Tworzenie Niestandardowych Narzędzi : Projektuj schematy narzędzi : Implementuj wywołania funkcji : Obsłuż zewnętrzne API Automatyzacja Procesów : Łącz wiele narzędzi : Twórz drzewa decyzyjne : Buduj zachowania agentów section Aplikacje Produkcyjne Kompletną Architekturę Systemu : Połącz wszystkie funkcje frameworka : Implementuj granice błędów : Twórz łatwy do utrzymania kod Gotowość Przemysłowa : Zajmij się problemami skalowalności : Implementuj monitorowanie : Buduj strategie wdrażania ``` **🎓 Kamień milowy ukończenia**: Opanowałeś rozwój frameworków AI używając tych samych narzędzi i wzorców, które napędzają nowoczesne aplikacje AI. Te umiejętności reprezentują najnowszy poziom rozwoju aplikacji AI i przygotowują cię do budowy systemów inteligentnych na poziomie korporacyjnym. **🔄 Kolejne poziomy możliwości**: - Gotowy do eksploracji zaawansowanych architektur AI (agenci, systemy multi-agentowe) - Przygotowany do budowy systemów RAG z bazami wektorowymi - Wyposażony, by tworzyć multimodalne aplikacje AI - Fundament pod skalowanie i optymalizację aplikacji AI ## Podsumowanie 🎉 Opanowałeś podstawy rozwoju frameworków AI i nauczyłeś się, jak budować zaawansowane aplikacje AI używając LangChain. To jak ukończenie wszechstronnego praktykatu — zdobyłeś solidny zestaw umiejętności. Przejrzyjmy, co osiągnąłeś. ### Czego się nauczyłeś **Podstawowe koncepcje frameworku:** - **Korzyści z frameworków**: kiedy wybierać frameworki zamiast bezpośrednich wywołań API - **Podstawy LangChain**: konfiguracja i połączenie z modelami AI - **Rodzaje wiadomości**: stosowanie `SystemMessage`, `HumanMessage` i `AIMessage` dla uporządkowanych rozmów **Zaawansowane funkcje:** - **Wywoływanie narzędzi**: tworzenie i integracja niestandardowych narzędzi zwiększających możliwości AI - **Pamięć rozmowy**: utrzymanie kontekstu przez wiele tur konwersacji - **Streaming odpowiedzi**: implementacja dostarczania odpowiedzi w czasie rzeczywistym - **Szablony promptów**: budowanie wielokrotnego użytku, dynamicznych promptów - **Ustrukturyzowane wyjście**: zapewnienie spójnych, łatwych do przetwarzania odpowiedzi AI - **Embeddingi**: tworzenie możliwości wyszukiwania semantycznego i przetwarzania dokumentów **Praktyczne zastosowania:** - **Budowanie kompletnej aplikacji**: łączenie wielu funkcji w gotowe do produkcji aplikacje - **Obsługa błędów**: implementacja solidnego zarządzania błędami i walidacji - **Integracja narzędzi**: tworzenie własnych narzędzi rozszerzających możliwości AI ### Kluczowe wnioski > 🎯 **Pamiętaj**: Frameworki AI takie jak LangChain to twoi najlepsi przyjaciele ukrywający złożoność i oferujący wiele funkcji. Są idealne, gdy potrzebujesz pamięci rozmowy, wywoływania narzędzi lub chcesz pracować z wieloma modelami AI bez utraty zdrowia psychicznego. **Ramowy schemat decyzji przy integracji AI:** ```mermaid flowchart TD A[Potrzeba integracji AI] --> B{Proste pojedyncze zapytanie?} B -->|Tak| C[Bezpośrednie wywołania API] B -->|Nie| D{Potrzebna pamięć rozmowy?} D -->|Nie| E[Integracja SDK] D -->|Tak| F{Potrzebne narzędzia lub zaawansowane funkcje?} F -->|Nie| G[Framework z podstawową konfiguracją] F -->|Tak| H[Pełna implementacja frameworka] C --> I[Żądania HTTP, minimalne zależności] E --> J[SDK dostawcy, specyficzne dla modelu] G --> K[Podstawowy czat LangChain] H --> L[LangChain z narzędziami, pamięcią, agentami] ``` ### Co dalej? **Zacznij budować już teraz:** - Weź te koncepcje i stwórz coś, co CIĘ ekscytuje! - Eksperymentuj z różnymi modelami AI przez LangChain – to jak plac zabaw pełen modeli AI - Twórz narzędzia rozwiązujące rzeczywiste problemy, z którymi się mierzasz w pracy lub projektach **Gotowy na kolejny poziom?** - **Agenci AI**: Buduj systemy AI, które potrafią samodzielnie planować i wykonywać złożone zadania - **RAG (retrieval-augmented generation)**: Połącz AI z własnymi bazami wiedzy dla supermocy aplikacji - **Multimodalne AI**: Pracuj jednocześnie z tekstem, obrazami i dźwiękiem – możliwości są nieograniczone! - **Wdrożenie produkcyjne**: Naucz się skalować aplikacje AI i monitorować je w rzeczywistym świecie **Dołącz do społeczności:** - Społeczność LangChain jest fantastyczna do pozostania na bieżąco i nauki najlepszych praktyk - GitHub Models daje dostęp do najnowszych możliwości AI – idealne do eksperymentów - Ćwicz na różnych przypadkach użycia – każdy projekt nauczy cię czegoś nowego Masz teraz wiedzę, by budować inteligentne, konwersacyjne aplikacje, które pomagają ludziom rozwiązywać prawdziwe problemy. Jak rzemieślnicy renesansu łączący wizję artystyczną z umiejętnościami technicznymi, możesz łączyć możliwości AI z praktycznym zastosowaniem. Pytanie brzmi: co stworzysz? 🚀 ## Wyzwanie GitHub Copilot Agent 🚀 Użyj trybu agenta, aby wykonać następujące wyzwanie: **Opis:** Zbuduj zaawansowanego asystenta przeglądu kodu zasilanego AI, który łączy wiele funkcji LangChain, w tym wywoływanie narzędzi, ustrukturyzowane wyjście i pamięć rozmowy, by dostarczać kompleksowe opinie o przesłanych kodach. **Prompt:** Stwórz klasę CodeReviewAssistant, która implementuje: 1. Narzędzie do analizy złożoności kodu i sugerowania ulepszeń 2. Narzędzie do sprawdzania kodu względem najlepszych praktyk 3. Ustrukturyzowane wyjście za pomocą modeli Pydantic dla spójnego formatu przeglądu 4. Pamięć rozmowy do śledzenia sesji przeglądu 5. Główny interfejs czatu obsługujący przesyłanie kodu i dostarczający szczegółowe, praktyczne uwagi Asystent powinien potrafić recenzować kod w wielu językach programowania, utrzymywać kontekst przez wiele przesłanych fragmentów w sesji oraz dostarczać zarówno podsumowujące oceny, jak i szczegółowe sugestie ulepszeń. Dowiedz się więcej o [trybie agenta](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) tutaj. --- **Zastrzeżenie**: Niniejszy dokument został przetłumaczony za pomocą automatycznej usługi tłumaczeniowej AI [Co-op Translator](https://github.com/Azure/co-op-translator). Mimo że dążymy do dokładności, prosimy mieć na uwadze, że tłumaczenia automatyczne mogą zawierać błędy lub nieścisłości. Oryginalny dokument w języku źródłowym powinien być uznawany za wiarygodne źródło. W przypadku informacji istotnych zalecane jest skorzystanie z profesjonalnego tłumaczenia wykonanego przez człowieka. Nie ponosimy odpowiedzialności za jakiekolwiek nieporozumienia lub błędne interpretacje wynikające z korzystania z tego tłumaczenia.