MCP und A2A – Model Context Protocol und Agent-zu-Agent-Protokoll | Kartik Marwah | Skillshare

Playback-Geschwindigkeit


1.0x


  • 0.5x
  • 0.75x
  • 1x (normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

MCP und A2A – Model Context Protocol und Agent-zu-Agent-Protokoll

teacher avatar Kartik Marwah, Teaching AI, Agents, MCP, A2A

Schau dir diesen Kurs und Tausende anderer Kurse an

Erhalte unbegrenzten Zugang zu allen Kursen
Lerne von Branchenführern, Ikonen und erfahrenen Experten
Wähle aus einer Vielzahl von Themen, wie Illustration, Design, Fotografie, Animation und mehr

Schau dir diesen Kurs und Tausende anderer Kurse an

Erhalte unbegrenzten Zugang zu allen Kursen
Lerne von Branchenführern, Ikonen und erfahrenen Experten
Wähle aus einer Vielzahl von Themen, wie Illustration, Design, Fotografie, Animation und mehr

Einheiten dieses Kurses

    • 1.

      Einführung in den Kurs

      1:48

    • 2.

      ABSCHNITT 1 MCP Übersicht - Was ist Model Context Protocol?

      4:36

    • 3.

      Code auf Github abrufen

      1:56

    • 4.

      Claude für Desktop installieren

      1:11

    • 5.

      Python-, UV- und VS-Code installieren

      2:52

    • 6.

      ABSCHNITT 2. Erstellen eines eigenen mcpservers

      27:58

    • 7.

      SECTION 3 Build Your Own MCP Client

      37:59

    • 8.

      ABSCHNITT 4 - Containerisierung Ihres MCP-Servers mit Docker

      14:41

    • 9.

      ABSCHNITT 5 – Vereinfachung von Clientcode mit LangGraph und LangChain

      11:28

    • 10.

      ABSCHNITT 6 STARTEN Erstellen von MCP Client mit Unterstützung mehrerer Server: 6.1 Einführung

      0:36

    • 11.

      6.2 Schauen wir uns die Datei config.json an

      0:36

    • 12.

      6.3 Demo - MCP-Client mit mehreren MCP-Servern

      4:10

    • 13.

      6.4 MCP Client (mit JSON config) Code-Anleitung – Teil 1

      2:23

    • 14.

      6.5 Warum sollten Sie Gemini 2.0 Flash und nicht die Pro-Modelle wählen?

      0:47

    • 15.

      6.6 MCP Client (mit JSON config) Code-Anleitung – Teil 2 (Fortsetzung)

      3:52

    • 16.

      6.7 Verwenden vorhandener MCP-Server von MCP Github (Beispiel verwendet "fetch"-Server)

      3:57

    • 17.

      ABSCHNITT 7 START - Vom Server gesendete Ereignisse - MCP-Server und Clients mit SSE - 7.1 Einführung

      0:58

    • 18.

      7.2 Kurzer Zusammenfassung: Was sind STDIO und SSE?

      2:12

    • 19.

      7.3 Setup-Verzeichnisse, GitHub-Code klonen (nur git-Pull, wenn dies zu Kursbeginn durchgeführt wird)

      1:35

    • 20.

      7.4 Virtuelle Umgebung und Abhängigkeiten einrichten

      2:27

    • 21.

      7.5 MCP SSE-Servercode-Übersicht

      8:57

    • 22.

      7.6 MCP SSE-Clientcode-Schritt-für-Schritt-für-

      14:10

    • 23.

      7.6 Dockerfile-Code (für MCP Server) – Schritt-für-Schritt-Durchgang

      0:55

    • 24.

      7.7 Lokales Testen des MCP SSE-Servers und -Clients

      2:36

    • 25.

      ABSCHNITT 8 ERSTE Schritte - Bereitstellen von MCP Server auf der Google Cloud Platform - 8.1 Erstellen eines neuen Gmail-Kontos (falls

      2:34

    • 26.

      8.2 Erstellen eines Google Cloud-Projekts

      2:48

    • 27.

      8.3 Installieren und Einrichten der Google Cloud Command Line Interface (gcloud CLI)

      5:33

    • 28.

      8.4 Erstellen eines Docker-Images für Google Cloud

      1:02

    • 29.

      8.5 Bereitstellen von MCP SSE Server auf Google Cloud Run

      0:58

    • 30.

      8.6 Testen von MCP SSE Server in Google Cloud

      2:04

    • 31.

      ABSCHNITT 9 ERSTE Schritte - STREAMBARER HTTP MCP SERVER - 9.1 Kurzübersicht über MCP und was ist Streamable HTTP

      3:52

    • 32.

      9.2 Überblick über Streamable HTTP mit Sequenzdiagramm

      2:54

    • 33.

      9.3 Initialisierungsphase

      2:12

    • 34.

      9.4 Clientanforderungsphase von Streamable HTTP

      1:46

    • 35.

      9.5 MCP-Clientbenachrichtigungen und -antworten

      0:45

    • 36.

      9.6 Client-Abhören von Nachrichten vom Server in Streamable HTTP

      1:19

    • 37.

      9.7 Sitzungsbehandlung in Streamable HTTP

      1:57

    • 38.

      9.8 Externe Ressource zur Aktualisierung

      1:57

    • 39.

      ABSCHNITT 9.2 STARTEN Streamable HTTP MCP Server – Schritt-für-Schritt-Demo

      12:02

    • 40.

      ABSCHNITT 9.3 STARTEN eines streambaren HTTP-MCP-Clients mit Gemini und Google ADK – Einführung

      6:17

    • 41.

      9.3.2 Codeübersicht

      2:49

    • 42.

      9.3.3 Benutzeroberfläche des MCP Clients - cmd.py

      4:30

    • 43.

      9.3.4 Implementierung des MCP Clients - client.py

      5:11

    • 44.

      9.3.5 Implementierung des MCP Agenten - agent.py

      8:33

    • 45.

      9.3.6 Code – JSON-Datei für die MCP Konfiguration

      2:04

    • 46.

      9.3.7 Code für Dienstprogramme und STDIO-Server + Umgebungskonfiguration

      8:17

    • 47.

      ABSCHNITT 10 START - Streamlit-Benutzeroberfläche für MCP Client - Übersicht über Streamlit UI MCP Client

      2:35

    • 48.

      10.2 Streamlit UI-Demo

      2:39

    • 49.

      10.3 Vergleich unserer Benutzeroberfläche mit Claude Desktop!

      0:26

    • 50.

      10.4 Setup-Verzeichnisse (überspringen, wenn bereits erledigt)

      0:54

    • 51.

      10.5 Google Gemini API-Schlüssel einrichten (Überprüfen Sie dies erneut, falls Sie dies bereits getan haben)

      1:37

    • 52.

      10.6 Erstellen einer virtuellen Umgebung und Installieren von Abhängigkeiten

      1:39

    • 53.

      10.7 Streamlit UI-Code abrufen

      1:00

    • 54.

      10.8 Optimierte App-Importe und Statusinitialisierung

      3:35

    • 55.

      10.9 Code für Dienstprogrammfunktionen

      1:15

    • 56.

      10.10 Streamlit App Sidebar-Code

      3:21

    • 57.

      10.11 Erstellen der Hauptchat-Benutzeroberfläche für die App

      3:04

    • 58.

      10.12 Kernlogik für die Abfragebehandlung

      1:35

    • 59.

      10.13 Auslösemlogik für Senden und andere Chat-Schaltflächen

      1:41

    • 60.

      10.14 Streamlit App MCP-Clientcode

      7:04

    • 61.

      10.15 theailanguage_config.json und andere Dateien

      1:35

    • 62.

      10.16 Ausführen der Streamlit-Benutzeroberfläche

      0:18

    • 63.

      ABSCHNITT 11 START - A2A oder Agent-zu-Agent-Protokoll - Lebenszyklus - 11.1 Einführung

      2:56

    • 64.

      11.2 Warum A2A-Protokoll – A2A im Vergleich zu MCP

      2:09

    • 65.

      11.3 Erkennung – A2A-Client, A2A-Server, Agentkarte

      2:43

    • 66.

      11.4 Initiierung – Aufgaben, Meldungen, Teile

      1:53

    • 67.

      11.5 Verarbeitung – Artefakte, Streaming, Push-Benachrichtigungen, Nicht-Streaming

      1:42

    • 68.

      11.6 Wechselwirkung - Eingabeerforderlicher Zustand

      0:22

    • 69.

      11.7 Abschlussablauf und Zusammenfassung von A2A

      1:35

    • 70.

      ABSCHNITT 12 START - Erstellen eines eigenen A2A-Clients und A2A-Servers

      18:40

    • 71.

      ABSCHNITT 13 START - Erstellen Sie Ihren eigenen A2A-Agenten mit dem Google Agent Development Kit (ADK) - Einführung

      3:56

    • 72.

      13.2 Kurzdemo des A2A Agenten

      1:43

    • 73.

      13.3 Code und Gemini-API-Schlüssel einrichten

      2:57

    • 74.

      13.4 Ausführen des A2A Agent-Servers und -Clients

      1:53

    • 75.

      13.5 Agentencode-Schritt-für-Schritt-durch

      4:41

    • 76.

      13.6 Code-Schrittdurchführung für Agenten Taskmanager

      3:36

    • 77.

      13.7 Code-Walkthrough für Agenten main.py

      2:37

    • 78.

      13.8 Clientcode-Walkthrough – Teil 1

      1:32

    • 79.

      13.9 Clientcode-Walkthrough – Teil 2 – Manuelle Agentenerkennung

      0:50

    • 80.

      13.10 Clientcode-Walkthrough – Teil 3

      2:06

    • 81.

      13.11 Anwendungscode-Walkthrough

      3:25

    • 82.

      13.12 Kurzer Überblick über die Code-Architektur

      0:48

    • 83.

      13.13 Modellcode-Walkthrough

      2:35

    • 84.

      ABSCHNITT 14 START – A2A mit mehreren Agenten

      8:28

    • 85.

      ABSCHNITT 15 START - Verbinden von 3 Agenten mit A2A

      4:28

    • 86.

      15.2 Zusammenfassung der A2A-Architektur

      1:40

    • 87.

      15.3 Agentenerkennung und -registrierung

      4:19

    • 88.

      15.4 Orchestrator-Host-Agent

      12:36

    • 89.

      15.5 Orchestrator-Taskmanager

      1:38

    • 90.

      15.6 Python-Skript für den Orchestrator-Eintrag

      3:10

    • 91.

      15.7 Begrüßungsagent

      8:00

    • 92.

      15.8 Zusammenfassung und andere Dateien, Ordner

      1:03

    • 93.

      15.9 Code und API-Schlüssel einrichten

      3:42

    • 94.

      15.10 Ausführen der Agenten und des Clients

      2:39

    • 95.

      ABSCHNITT 16 START – Einführung in das A2A Python SDK

      0:32

    • 96.

      16.2 Was ist das A2A Python SDK?

      0:28

    • 97.

      16.3 Demo 1 - Grundlegendes zu Single-Turn-A2A-Agent-Streaming-Task-Aktualisierungen

      5:40

    • 98.

      16.4 Demo 2 - Grundlegendes zu mehrstufigen A2A Agent Streaming Tasks-Aktualisierungen

      5:34

    • 99.

      16.5 Einrichten und Ausführen des Codes

      6:14

    • 100.

      16.6 Code-Schrittdurchführung: A2A-Client

      10:39

    • 101.

      16.7 Code-Schrittdurchführung: Agent

      8:37

    • 102.

      16.8 Code-Walkthrough-AgentExecutor

      6:00

    • 103.

      16.9 Code Walkthrough-Agent-Hauptseite

      3:20

    • 104.

      ABSCHNITT 17 ERSTE Schritte – Multi-Agent-A2A- und MCP-Architektur

      10:02

  • --
  • Anfänger-Niveau
  • Fortgeschrittenes Niveau
  • Fortgeschrittenes Niveau
  • Jedes Niveau

Von der Community generiert

Das Niveau wird anhand der mehrheitlichen Meinung der Teilnehmer:innen bestimmt, die diesen Kurs bewertet haben. Bis das Feedback von mindestens 5 Teilnehmer:innen eingegangen ist, wird die Empfehlung der Kursleiter:innen angezeigt.

55

Teilnehmer:innen

--

Projekte

Über diesen Kurs

Kurs-Übersicht: In diesem praktischen Programmierkurs lernen Sie MCP (Model Context Protocol) und A2A (Agent-to-Agent) Protokoll kennen – die grundlegenden Technologien, mit denen KI-Agenten kommunizieren, zusammenarbeiten und auf externe Tools zugreifen können. Sie erstellen fünf MCP-Clients und drei MCP-Server von Grund auf, erstellen eine Streamlit-basierte Benutzeroberfläche für Ihren Client in Python und stellen Ihren MCP-Server mithilfe von Server Sent Events (SSE) in der Google Cloud bereit. Darüber hinaus verwenden wir einen kostenlosen Gemini-API-Schlüssel von Google, damit Sie diese leistungsstarken Technologien ohne Kosten für KI-Modelle erkunden können.

Außerdem implementieren Sie das Agent-to-Agent-Protokoll (A2A), um mehrere Agenten zu verbinden, und erstellen einen Host Orchestrator-Agent, der MCP und A2A mit dem Agent Development Kit (ADK) von Google integriert.

Lernziele

  • Agent-zu-Agent-Protokoll (A2A): Verbinden Sie 3 Agenten und erstellen Sie einen Host-Orchestrator mit A2A + MCP.

  • Erstellen Sie 5 MCP-Clients und 3 MCP-Server von Grund auf – inklusive vollständigem funktionierendem Code.

  • Entwerfen Sie eine Benutzeroberfläche in Streamlit für Ihren MCP-Client in Python

  • Stellen Sie Ihren MCP-Server mithilfe von Server Sent Events (SSE) in Google Cloud bereit.

  • Verwenden Sie die Gemini-API von Google (kostenloser Schlüssel), um KI-gestützte Agenten kostenlos auszuführen.

  • Arbeiten Sie mit Python, Gemini, LangGraph, SSE und Streamlit unter macOS.

Warum Sie diesen Kurs besuchen sollten

  • MCP ermöglicht KI-Agenten die Verbindung mit externen Tools und APIs.

  • A2A ermöglicht die Zusammenarbeit von Mitarbeitern über technische und organisatorische Grenzen hinweg.

  • Diese Protokolle bilden das Kommunikations-Rückgrat moderner autonomer Agentensysteme.

  • Ich habe A2A- und MCP-basierte Agentensysteme entwickelt und unterrichtet, die Code generieren und komplexe Aufgaben ausführen. Ich freue mich darauf, Sie durch die Erstellung dieser Systeme zu führen. mehr

Für wen ist dieser Kurs

  • Entwickler, die MCP-Clients, -Server und -Benutzeroberflächen erstellen möchten.

  • Entwickler von KI-Agenten, LangChain-Entwickler und Softwareentwickler.

  • Unternehmer und Produktentwickler, die einen QuickStart zu MCP + A2A suchen.

Materialien / Ressourcen

  • Dieser Kurs wird unter macOS aufgezeichnet. Der Zugriff auf einen macOS-Computer wird dringend empfohlen.

  • Windows-Anweisungen werden gegebenenfalls bereitgestellt (voraussichtlich: Ende Juli, als Teil der Github-Repositories).

  • Linux-Anweisungen sind derzeit nicht verfügbar und sollen nicht später hinzugefügt werden.

  • Sie erhalten Zugriff auf ein GitHub-Repo mit dem gesamten Projektcode

  • MCP Servercode – https://github.com/theailanguage/terminal_server

  • MCP-Client-Code – https://github.com/theailanguage/mcp_client

  • A2A-Code - https://github.com/theailanguage/a2a_samples
  • MCP und A2A sind sich entwickelnde Protokolle. Es können grundlegende Änderungen auftreten. Der Kursleiter wird dann versuchen, die Codes so schnell wie möglich zu aktualisieren, um die Änderungen widerzuspiegeln.

  • Grundkenntnisse in Python sind erforderlich.

  • Vertrautheit mit LLM-Programmen (wie Gemini oder Claude) ist erforderlich.

Triff deine:n Kursleiter:in

Teacher Profile Image

Kartik Marwah

Teaching AI, Agents, MCP, A2A

Kursleiter:in

IIT Delhi and University of Illinois (UC) Alumnus with ~12 years of work experience in tech, consulting and building startups.

Currently Building "The AI Language" to help anyone build Mobile Apps in minutes using AI. Teaching how to build AI Agents, work with technology like MCP (Model Context Protocol), Front-end app development using Flutter and backend app development using Python-Flask-Firebase.

Vollständiges Profil ansehen

Level: Advanced

Kursbewertung

Erwartungen erfüllt?
    Voll und ganz!
  • 0%
  • Ja
  • 0%
  • Teils teils
  • 0%
  • Eher nicht
  • 0%

Warum lohnt sich eine Mitgliedschaft bei Skillshare?

Nimm an prämierten Skillshare Original-Kursen teil

Jeder Kurs setzt sich aus kurzen Einheiten und praktischen Übungsprojekten zusammen

Mit deiner Mitgliedschaft unterstützt du die Kursleiter:innen auf Skillshare

Lerne von überall aus

Ob auf dem Weg zur Arbeit, zur Uni oder im Flieger - streame oder lade Kurse herunter mit der Skillshare-App und lerne, wo auch immer du möchtest.

Transkripte

1. Einführung in den Kurs: Hallo, alle zusammen. Willkommen zu diesem Kurs über MCP und Eightway, das Model Context Protocol und das Agent-to-Agent-Protokoll und das Agent-to-Agent-Protokoll Ich bin Karthick, ein Alumnus des IIT Deli und der University of Illinois Derzeit baue ich in meinem Startup , der KI-Sprache, KI-Agenten , die Software schreiben können , und ich freue mich unglaublich, diese Reise mit Ihnen zu teilen Das Model Context-Protokoll ermöglicht es Host-Agenten , sich mit externen Tools und Ressourcen von Servern, sogenannten MCP-Servern, zu verbinden und diese zu verwalten Ressourcen von Servern, sogenannten MCP-Servern Dies trägt dazu bei, die Fähigkeiten von Agenten zu erweitern , indem ihnen externe Tools und Ressourcen Agent-to-Agent-Protokoll ist ein Kommunikationsstandard, der es mehreren Agenten ermöglicht , sich gegenseitig zu erkennen und direkt miteinander zu kommunizieren, unabhängig davon, ob sie lokal oder remote sind. Auf diese Weise können sie zusammenarbeiten, Aufgaben delegieren und in einem größeren System über organisatorische und technische Grenzen hinweg organisatorische und technische Grenzen Zusammen bilden sie ein Kommunikations-Backbone für ein leistungsstarkes Multi-Agenten-System, das es Agenten ermöglicht, ihre Fähigkeiten zu erweitern , indem sie sich mit externen Tools und Agenten verbinden und zusammenarbeiten Was werden Sie also in diesem Kurs lernen? Wir beginnen mit MCP und Sie werden fünf MCP-Clients und drei MCP-Server von Grund auf neu erstellen , voll funktionsfähigem Wir lernen, unseren MCP-Server in Google Cloud bereitzustellen. Wir werden eine Benutzeroberfläche für den MCP-Client in Streamlt in Python erstellen und dann zum Agent-to-Agent-Protokoll übergehen Wir werden drei Agenten über einen Tow verbinden und einen Host-Orchestrator-Agenten erstellen, der sich über Ata mit anderen Agenten und über MCP mit anderen MCP-Servern verbinden kann über Ata mit anderen Agenten und über MCP mit anderen MCP-Servern verbinden und über MCP Schließlich verwenden wir einen kostenlosen Gemini-API-Schlüssel, sodass Sie beim Lernen nicht für KI-Modelle bezahlen müssen Und das alles machen wir unter Mac OS, aber ich stelle Windows-Benutzern schriftliche Anweisungen zur Verfügung, aber ich stelle Windows-Benutzern schriftliche Anweisungen zur Verfügung damit Sie Wenn Sie also bereit sind, mit dem Bauen mit MCP und AT zu beginnen, lassen Sie uns anfangen. Wir sehen uns in der ersten Lektion 2. 1.1 MCP – Übersicht – Was ist Model Context Protocol?: Hallo, alle zusammen. Heute werden wir uns die Grundlagen des Model Context-Protokolls und verstehen, was das ist. Das, was Sie sehen können, ist ein Nachrichtenartikel oder ein Blogbeitrag von Anthropic vom 25. November 2024, als das Model Context-Protokoll eingeführt wurde Aber der beste Weg, dem zu folgen besteht darin, auf diesen Link zu klicken , der Sie zu modelctextprotocol dot IO Hier haben Sie diese Website mit einigen Dokumentationen zu den ersten Schritten und einigen Tutorials, und Aber bevor wir das tun, lassen Sie uns einfach die Grundlagen durchgehen. Was ist also das Model Context-Protokoll? Es ist im Grunde ein Protokoll, um große Sprachmodelle, die möglicherweise auf einigen Apps gehostet werden, die dieses spezielle Protokoll verwenden, mit externen Datenquellen und Tools zu verbinden die möglicherweise auf einigen Apps gehostet werden, die dieses spezielle Protokoll verwenden , mit externen Datenquellen und Tools zu externen Datenquellen und , die von Servern verfügbar gemacht werden. Es handelt sich also im Wesentlichen um ein Client-Server-Modell. Das ist also Ihr Client hier drüben, und der MCP-Client oder der Model Context Protocol Client stellt über dieses spezielle Protokoll eine Verbindung zu MCP-Servern Also, was sind die Kunden hier? Bei den Clients handelt es sich um LLM-gestützte Apps wie Cloud-Desktop oder IDs oder Tools, die im Grunde ein LLM auf ihnen hosten Und die Server sind Programme, die Tools, Ressourcen oder Eingabeaufforderungen Dies sind die drei Primitiven, die sie im Grunde verfügbar machen und die dem LLM helfen , diese Funktionen oder Tools auszuführen, die Ressourcen zu nutzen oder im Grunde einige Beispielaufforderungen abzurufen Die Server können sich außerdem mit lokalen Datenquellen wie den lokalen Datenquellen A, B usw. oder über Web-APIs mit Remotediensten wie dem Remotedienst C hier verbinden lokalen Datenquellen wie lokalen Datenquellen A, B usw. oder über Web-APIs mit Remotediensten wie dem , wie auf ihrer Dokumentationswebsite gezeigt Lassen Sie uns also zuerst über den MCP-Server sprechen. Das bietet also im Grunde drei Grundelemente, und Sie können hier zum Schnellstart für Serverentwickler gehen hier zum Schnellstart für Serverentwickler Und wenn Sie nach unten scrollen, werden Sie tatsächlich diese Primitiven sehen, die hier erwähnt Diese Ressourcen bieten also Zugriff auf externe Daten und Dateien für das große Sprachmodell, um Informationen abzurufen Ihre Client-Anwendung, die eine Verbindung zum Server herstellt, kann dann über diese Ressourcen auf diese speziellen Informationen zugreifen . Es gibt Tools, und diese Tools sind im Wesentlichen das, was wir von großen Sprachmodellen und Agenten gewohnt sind , denen wir diese Tools zur Verfügung stellen, und das sind im Grunde Funktionen oder APIs, die das LLM aufrufen kann Und das hilft dem großen Sprachmodell auszuführen. Und dann gibt es Eingabeaufforderungen. Dies sind also wiederverwendbare Vorlagen mit Anweisungen oder Kontext, die das Verhalten des großen Sprachmodells steuern. Ihre Client-App kann dies im Grunde verwenden, Ihre Client-App kann dies im Grunde verwenden indem sie über das MCP-Protokoll eine Verbindung zu den Servern Okay, zurück zur Einführung. Es gibt auch zwei Primitive, die der Client bereitstellt, und diese werden hier nicht erwähnt, aber lassen Sie uns sie einfach durchgehen Das sind also Roots, Schnittstellen oder Einstiegspunkte , über die sich der Client mit den MCP-Servern verbindet . Und Probenahme Sampling ist im Grunde ein Mechanismus, dem der Server den Client auffordern kann , Text auf der Grundlage bestimmter Eingaben oder eines bestimmten Kontextes zu generieren . Dies ist, was der Client als Teil des Protokolls bereitstellt. Angesichts dieser Primitiven können wir nun sehen, dass dies bidirektional ist Mit diesen Primitiven unterstützt MCP also bidirektionale Kommunikation zwischen dem Server und dem Client Ein Server kann also das LLM auffordern, Vervollständigungen zu generieren, was das Sampling-Primitiv ist Gleichzeitig kann der Client, der das umfangreiche Sprachmodell hostet Ausführung des Tools auf dem Server und dann das Ergebnis anfordern, oder er kann Dateninformationen oder Informationen von einem Remote-Service Das ist also im Grunde das Model Context Protocol. Es ist ein bidirektionales Protokoll Clients eine Verbindung zu Servern herstellen können Und auf den Servern stehen Ihnen die Ressourcen, Eingabeaufforderungen und Tools zur Verfügung, und auf den Clients haben Sie die Roots und die Sampling-Primitive, die im Grunde dazu beitragen, dass das Large Language Model und der Server miteinander kommunizieren können Es gibt mehrere vorgefertigte MCP-Server, die für Github, Google Drive, Post Cress usw. existieren , noch in einem frühen Stadium und der Erfolg hängt von der breiteren Akzeptanz durch viele Leute ab, aber es hat sich gezeigt, dass, wenn man vielen Twitter-Threads folgt, man heutzutage tatsächlich viele Leute sehen kann , die mit MCP arbeiten und es als einen von die nächsten großen Dinge in EI So könnten Sie beispielsweise einen MCP-Server haben, um ein großes Sprachmodell mit einer lokalen SQLI-Datenbank, einem Github-Bo und einem Slack-Workspace zu verbinden großes Sprachmodell mit einer lokalen SQLI-Datenbank, einem Github-Bo und einem Slack-Workspace zu , alles im selben Protokoll LLM kann also die Datenbank abfragen. Sie können den Codekontext abrufen und Updates veröffentlichen, alles innerhalb eines einzigen Protokolls Das ist also vorerst alles für MCP. Vielen Dank fürs Zuschauen. 3. 1.2 Code auf Github abrufen: Nun, da wir über die Grundlagen von MCP Bescheid wissen, lassen Sie mich zunächst einen Punkt zur Verwaltung behandeln, in dem es um das Kurs-Repository geht in das ich den gesamten Code pushen werde , der dann tatsächlich geklont und in den verschiedenen Vorlesungen verwendet werden kann den verschiedenen Vorlesungen verwendet Um auf die Code-Repositorys zuzugreifen, gehen Sie bitte zu github.com mit dem Schrägstrich der KI-Sprache. Klicken Sie dann auf Repositorys, um den Tab Repositorys aufzurufen um Sie werden hier mehrere Repositorys in der KI-Sprache sehen , und wir werden im Grunde zwei Repositorys verwenden, und wir werden im Grunde zwei Repositorys verwenden das MCP-Client-Repository. Und das Terminalserver-Repository . Der MCP-Client wird die Implementierung grundsätzlich mit Python, Lang Rap, Gemini und allen anderen von uns implementierten Clients durchführen Wenn ich ein weiteres Repository für eine der anderen Vorlesungen hinzufüge , werde ich das im Kurs erwähnen Das andere Repository ist für den MCP-Server, und ich habe diesen Terminalserver genannt, weil der Server , den wir im Kurs verwenden, zur Ausführung von Befehlen auf dem Terminal verwendet wird , und das ist ein MCP-Server , der Terminalbefehle ausführen kann Um ein Repository zu öffnen, klicken Sie einfach auf den Namen des Und Sie können alle Dateien hier zusammen mit den Read-Me-Dateien hier sehen . Und wenn Sie den Code tatsächlich klonen möchten, können Sie hier auf Code klicken und eine der spezifischen Methoden verwenden, die Sie bevorzugen. Sie können beispielsweise SDDPS verwenden und diesen Link kopieren und dann zu Ihrem Terminal gehen und Git clone mit diesem Link eingeben , um ihn tatsächlich zu klonen Deshalb bitte ich Sie, dieses Repository zu starten und sich das anzusehen, indem Sie auf diese beiden Elemente klicken, wie ich es hier bereits getan habe Dann können Sie tatsächlich zur KI-Sprache zurückkehren und dann hier zum Terminalserver gehen. Und schauen Sie sich diesen Code auf die gleiche Weise noch einmal an, indem Sie auf den Code klicken und eine Ihrer bevorzugten Methoden von hier aus verwenden . Bitte starte und sieh dir auch dieses Repository an, damit du es auf deinem Github-Konto leicht auffindbar hast es auf deinem Github-Konto leicht auffindbar 4. 2.2 Installieren von Claude für Desktop: Lassen Sie uns als ersten Schritt diesen Client installieren und Sie können das tun, indem Sie nach Cloud Desktop suchen. Lassen Sie uns danach suchen und klicken wir hier auf Herunterladen und Sie gelangen auf diese Website, um es herunterzuladen, und klicken Sie auf macOS, weil wir auf macOS sind . Windows-Leute können den Windows-Link hier verwenden. Warten wir eine Minute, bis das heruntergeladen ist. In Ordnung. Sobald es heruntergeladen ist, öffnen wir es einfach und ziehen zwei Cloud-Anwendungen hierher. Starten Sie jetzt Cloud, indem Sie Cloud hier eingeben und auf Öffnen klicken. Lass uns auf Öffnen klicken. Jetzt musst du dich also anmelden. Also lass uns mit einem Google-Konto einloggen. Wenn Sie Cloud also zum ersten Mal verwenden, müssen Sie Ihren vollständigen Namen eingeben. Ordnung. Sobald Sie sich angemeldet haben, sehen Sie einen Willkommensbildschirm wie diesen. Guten Tag, die A-Sprache, und wir haben hier das Cloud 3.7 Sonnet-Modell. Dies ist die Desktop-App für Cloud für macOS, Sie 40 Nachrichten pro Tag kostenlos erhalten, sodass Sie für dieses Tutorial zunächst nicht bezahlen müssen dieses Tutorial zunächst 5. 2.3 Python-, UV- und VS-Code installieren: Das nächste , was wir tun wollen, ist Python zu installieren. Wenn Sie also Python bereits installiert haben, können Sie hier nach der Version suchen. Sie können Python Three Dash Version eingeben. Und zum Beispiel haben wir 3.9 0.6, aber wir benötigen 3.10 oder höher Um also die neueste Version von Python zu installieren, können wir ein neues Browserfenster öffnen und sagen, Python installieren. Und lass uns hier zur Python-Download-Seite gehen . In Ordnung. Klicken wir auf Python 3.13 0.2 herunterladen. Und warten wir, bis der Download abgeschlossen ist. Sobald dies abgeschlossen ist, können Sie es tatsächlich öffnen und Sie erhalten ein installiertes Python-Fenster wie dieses. Es gibt eine Einführung. Lass uns weitermachen. Hier drüben gibt es ein Read Me. Also lass uns hier weitermachen. Und es gibt eine Lizenz, die werde ich akzeptieren. Ich werde die Standardinstallation verwenden und vorerst keine Anpassungen vornehmen, und lassen Sie uns unser Passwort eingeben. Und das wird Python nicht für uns installieren. Ordnung. Also haben wir jetzt Python installiert. Lassen Sie uns das Installationsprogramm in den Ordner verschieben , das wird tatsächlich diesen Python 3.13-Ordner hier öffnen und es wird Ihnen alle installierten Dinge zeigen , einschließlich IDLE Gehen wir jetzt zurück zum Terminal. Lassen Sie uns eingeben, welche Python-Drei, und das zeigt Ihnen, dass dies auf dem lokalen Benutzer Bin Python Three installiert ist , sodass wir jetzt Python Three Version eingeben können, und wir sehen, dass unsere Python-Drei jetzt 3.13 0.2 ist Dies erfüllt tatsächlich unsere Versionsanforderungen für 3.10 und höher. Wir sind jetzt damit einverstanden Als Nächstes wollen wir UV installieren , einen schnellen Paketmanager für Python, der uns hilft, Abhängigkeiten zu installieren und auszuführen. Um das zu installieren, werden wir diesen Befehl einfügen, und Sie finden ihn in der Beschreibung. Drücken Sie die Eingabetaste. Warten wir also einige Zeit bis dies installiert ist. In Ordnung. Also, es gibt einen Fehler, dass die Erlaubnis verweigert wurde, und vielleicht möchten Sie das dann tun und wir können sehen , dass der Fehler auf die Eigentümerschaft von local being with root zurückzuführen ist . Das lokale Verzeichnis befindet sich in unserem Home-Verzeichnis, sodass wir die Zugriffsrechte hier ändern können. Verwenden Sie dafür diesen Befehl, geben Sie Ihr Passwort ein und lassen Sie uns überprüfen, ob der Besitz aktualisiert wurde. Und ja, wir können sehen, dass der Besitz jetzt hier aktualisiert wurde. Diese Erlaubnis schlägt fehl, Sie könnten versucht sein , dies mit Pseudo auszuführen Ausführung mit Sudo könnte dies jedoch als Root installiert werden, was später zu Berechtigungsproblemen führen könnte Also lass uns das nicht tun und lass uns diese Erlaubnis wie folgt aktualisieren Und versuchen wir nicht erneut, UV zu installieren und zu sehen, ob es funktioniert. In Ordnung, großartig Also ist alles installiert. Lassen Sie uns unsere Umgebungsdatei als Quelle , damit wir den Befehl UV erkennen können. Und lassen Sie uns UV Dash Version eingeben. Und wir können sehen, dass UV jetzt installiert ist. Das ist der Paketmanager, den wir wollten. Wenn Sie auf einem Windows-Computer sind, können Sie tatsächlich den Installationsanweisungen auf der UV-Seite von Astral auf Github folgen , und wenn Sie hier weiterblättern, haben Sie die Installation hier 6. ABSCHNITT 2. Erstellen eines eigenen mcpservers: Hallo, alle zusammen. Willkommen zurück in der KI-Sprache. Das Model Context Protocol migriert also von Version eins auf Version zwei Und laut dem offiziellen Migrationsleitfaden , der auf ihrem Modell Context-Protokoll Github für das PythonSDKFast MCP verfügbar Context-Protokoll Github für ist, das unsere bevorzugte MCP-Klasse für die Herstellung von MCP-Servern war, ist es komplett weg es komplett Sie können also nach Fast MCP suchen, und Sie werden hier sehen, dass Fast MCP in MCP-Server umbenannt wurde. Lassen Sie mich Ihnen in diesem Video erklären, wie Sie Ihren ersten MCP-Server mit dieser neuen Klasse erstellen Ihren ersten MCP-Server mit Das wird Ihnen helfen zu verstehen, wie Sie einen MCP-Server erstellen , wenn Sie mit dem Model Context-Protokoll neu beginnen , und wir werden auch den neuesten verfügbaren Code verwenden Und falls Sie bereits mit MCP gebaut haben, wird es Ihnen helfen zu verstehen, wie Sie ein Upgrade auf Version zwei durchführen können, sobald Sie sich dafür entscheiden Beachten Sie, dass sich die zweite Version im Hauptzweig des Projektarchivs noch in der Pre-Alpha-Entwicklung befindet (Stand Mitte Februar 2026), und wir rechnen mit einer stabilen Veröffentlichung von Version zwei , in unserem Quartal 2026. Es könnte also jeden Tag oder bis Ende März sein hoffentlich, dass wir eine stabile Version zwei erhalten Um Ihnen zu helfen, zu verstehen, wie man einen MCP-Server mit dieser neuen MCP-Serverklasse erstellt , verwende ich den MCP Builder, der auf ai language.com verfügbar ist . Dieser hat einen KI-Assistenten, mit dem Sie den Assistenten einfach auffordern können , Ihren MCP-Server zu erstellen Es erstellt einen vollständigen Ausführungsplan und gibt Ihnen dann den gesamten Code Sie können damit auch iterieren , und dies ist in dieser frühen Alpha-Vorschau vorerst kostenlos möglich, indem Sie in dieser frühen Alpha-Vorschau vorerst kostenlos möglich, indem Ihren eigenen Gemini-API-Schlüssel Einstellungen des KI-Assistenten Bitte probieren Sie diesen KI-Assistenten mit Ihrem eigenen Gemini-API-Schlüssel In der Alpha-Vorschau ist er kostenlos Wenn er Ihnen gefällt oder Sie Feedback haben, lassen Sie es mich bitte wissen Bevor wir beginnen, sollten wir den Kontext verstehen, richtig. Das Model Context Protocol migriert also von Version eins auf Version zwei Das ist noch nicht abgeschlossen, okay? Version zwei befindet sich also in einer frühen Phase vor der Alpha-Phase. Es ist derzeit nicht in Produktion, aber es wird erwartet, dass es im Jahr 2026 in Produktion gehen Jahr 2026 in Produktion Dies ist ein Leitfaden zur Migration von V eins zu V zwei, den Sie auf der offiziellen GitHub-Seite von Model Context Protocol finden Sie können dorthin gehen und dann zu Docs gehen und sich diesen Leitfaden in Migration Dot MD ansehen. Nun, was genau ist die Änderung? Die Änderung ist, dass das schnelle MCP weg ist. Sie müssen es bei jedem Upgrade auf VT umbenennen oder es in MCPs-Server es in MCPs-Server umgestalten , da diese Klasse dann komplett verschwunden ist und in MCP-Server umbenannt wird und in MCP-Server umbenannt wird Und der Grund dafür ist, dass es die Rolle dieser speziellen Klasse als Hauptserverklasse im SDK besser widerspiegeln die Rolle dieser speziellen Klasse als Hauptserverklasse im SDK Das ist also eine einfache Umbenennung und es gibt keine funktionalen Änderungen an der Klasse selbst. Eine weitere Sache, die Sie beachten sollten, ist, dass Sie tatsächlich auf die offizielle Website und auf die Gitarrenseite gehen können und Sie können zu Readme Punkt Md gehen, oder? Das ist also ein Read-Me-Dokument, das zwei Teile des SDK dokumentiert, das sich derzeit vor der Alpha-Version auf Main in der Entwicklung befindet Und wie bereits erwähnt , wird eine stabile Version von zwei Versionen im Jahr 2026 erwartet Beachten Sie nun, dass bis zu diesem Zeitpunkt natürlich V one, Version eins, die empfohlene Version für den Produktionseinsatz bleibt Aber da sie, Sie wissen schon, auf den Markt kommen wird, sollten wir uns darauf vorbereiten, wie V Two verwenden und welche Änderungen, Sie wissen schon, in unserem Code notwendig sind. Andernfalls können Sie, bis Sie diese Änderungen vorgenommen haben, sicher weiterhin Version eins verwenden. In Ordnung, also fangen wir jetzt mit etwas sehr Aufregendem an. Lassen Sie uns unseren ersten MCP-Server bauen. Und der Server, den wir bauen werden, wird Terminalserver genannt Ordnung? Warum heißt es Terminalserver Weil es sich um einen MCP-Server handelt , der über ein Tool namens Execute Command verfügt und dieses Tool Befehle auf dem Terminal Ihres Computers ausführen kann. Alles klar? Das ermöglicht Ihnen im Wesentlichen, dass Sie das in eine MCP-Client-App wie Cloud Desktop integrieren können , und Sie können Cloud Desktop fragen, okay, bitte erstellen Sie eine Datei für mich darin, Sie wissen schon, mit diesem Namen und diesem Text Und Cloud stellt eine Verbindung zu diesem MCP-Server, dem Terminalserver, her und ruft dann das Befehlsausführungstool mit den erforderlichen Befehlen Verbindung zu diesem MCP-Server, dem Terminalserver, her und ruft dann das Befehlsausführungstool mit den erforderlichen Und das wird dann diese Datei erstellen und den Text hinzufügen Wir werden das auf sichere Weise tun , indem wir ein Workspace-Verzeichnis haben , damit Sie nicht versehentlich Ihre vorhandenen Dateien löschen oder überschreiben , die für Sie beim Lernen wichtig sind , richtig Und wir werden den SDD-IoT-Transport für diesen speziellen Server verwenden den SDD-IoT-Transport für . Also, was bedeutet das? Das bedeutet, dass der Server die Standardeingabe und -ausgabe für die Kommunikation mit Ihrem Client verwendet , und das ist der SDD-IoT-Transport Es gibt noch eine weitere Gruppe von Servern, die, wissen Sie, streambares SDTBP-Protokoll oder Transport verwenden, was im Grunde bedeutet, dass sie über SGTP kommunizieren. Sie werden im Allgemeinen für Server verwendet , die online in der Cloud bereitgestellt werden und auf die Okay, darauf kommen wir später zurück, aber vorerst werden wir dieses SDD Ioserve erstellen Lassen Sie uns also in den Code eintauchen. Als Erstes müssen Sie nun auf den für diesen Server bereitgestellten Link klicken. Dadurch wird Ihnen diese schöne Ansicht mit dem gesamten MCP-Server geöffnet Ihnen diese schöne Ansicht mit dem gesamten MCP-Server Sobald Sie diese Ansicht geöffnet haben, klicken Sie bitte auf Speichern Dadurch wird dieser MCP-Server in Ihrer Serverliste hier gespeichert. Nun, das ist eine Online-IDE wie VS-Code. Sie haben alle Dateien hier und Sie haben den Code hier drüben. Sie können also jede Datei öffnen, die Sie möchten. Schauen wir uns also zuerst die Verzeichnisstruktur an. Wenn Sie sich nun die Verzeichnisstruktur ansehen, haben Sie einen Hauptordner für Server, okay? Sie haben also vielleicht einen oder mehrere Server. Hier haben wir nur einen Server , der Terminalserver genannt wird. Darin haben wir ein Workspace-Dokument erstellt, in dem der Server arbeiten, Dateien erstellen und löschen kann. Ändern Sie den Dateiinhalt usw. und schützen Sie Ihre anderen Systemdateien und andere persönliche Dateien Dann haben wir die PY-Hauptdatei mit Punkt, und das ist Ihr Haupteinstiegspunkt für den Code Wir haben eine Tools-PY-Datei, die die Tools definiert , die der Server verwenden kann, oder? Und dann haben wir einen Cloud-Desktop-Konfigurationspunkt mit jcnFle. Dies ist eine Beispieldatei, die Ihnen sagt, welche Konfiguration der Cloud-Desktop in seiner eigenen internen Datei benötigt , um den Server erkennen und eine Verbindung zu ihm herstellen zu können Wir werden also nacheinander zu all diesen Dateien kommen. Aber wenn wir nur die Struktur durchgehen, haben wir auch eine ENV-Punkt-Datei, und das ist die Umgebungsvariablendatei Wir werden also die Umgebungsvariable für den Workspace in diese Datei einfügen die Umgebungsvariable für den , und Ihr SCDIO-Server kann diese, Sie wissen schon, Variable von hier aus lesen Sie wissen schon, Variable von hier aus Für den Clot-Desktop wird die Integration die Umgebungsvariable in einem separaten Befehl bereitstellen , und darauf kommen wir später zurück Aber das sind im Wesentlichen die Dateien, die Sie innerhalb des Terminalservers benötigen. Abgesehen davon haben Sie auch einige andere Unterstützungsdateien. Sie haben also eine Attributionsdatei, da Model Context-Protokoll ein Open-Source-Protokoll unter einer bestimmten Lizenz ist ein Open-Source-Protokoll unter einer bestimmten Lizenz Es ist also gut, die Autoren dieses Repositorys anzugeben, wann immer Sie ihren Code verwenden Sie haben also diese Quellendatei hier drüben. Wir haben eine Lizenzdatei , die diesen Code im Grunde genommen auf eine bestimmte Weise lizenziert Wir haben die Read M-Datei mit allen Anweisungen, worum es bei diesem Code geht, wie man ihn einrichtet und wie man ihn ausführt. Und dann haben wir den Punkt TXT, was eine sehr wichtige Datei ist, weil sie alle Anforderungen enthält , die wir in Bezug auf Abhängigkeiten für dieses Projekt haben , und Sie können einfach einen einzigen Befehl ausführen und alle installieren, sobald Sie diesen Server getestet haben. Damit ist unsere Verzeichnisstruktur abgeschlossen, und jetzt werden wir uns den Code im Detail ansehen . Ordnung. Schauen wir uns jetzt den Code an. Wir haben also die Hauptdatei mit Punkt PY hier drüben, und ich fange damit an, richtig? Nun, das ist der Einstiegspunkt für unseren Server. Und das ist wie die grundlegende Serverdefinition. Ähm, wir beginnen damit, einige grundlegende Systembibliotheken wie Betriebssysteme, Logging usw. zu importieren einige grundlegende Systembibliotheken wie Betriebssysteme, , und wir importieren Punkt ENV für die Umgebungsvariablen Nun, hier ist, was Sie verwenden werden , um den MCP-Server zu definieren Also importieren wir vom MCP Dot Server Dot MCP Server die MCP-Serverklasse, und das ist unsere Klasse die der Server definiert wird Danach haben wir das grundlegende Logging-Setup. Nun ist es wichtig zu beachten, dass SDD-IO-Server Standardeingabe und -ausgabe für die Kommunikation verwenden, oder? Für die JCNRPC-Kommunikation. Sie können also nicht einfach Anweisungen ausdrucken , um sie auf der Konsole oder anderswo zu protokollieren Weil das die Kommunikation des Servers stören wird , oder? Es könnte vom Protokoll als eine Kommunikation interpretiert werden , die vom Server kommt und auf die der Client reagiert, und das wird Ihr Kommunikationsprotokoll durcheinander bringen. Stattdessen müssen Sie also eine korrekte Protokollierung einrichten, die dann, Sie wissen schon, Ihre Protokolle so ausdruckt, dass sie das Modellkontext-Protokoll nicht beeinträchtigen. Das ist es also, was wir hier machen. Dann haben wir den Befehl load underscore dot ENV, und dieser wird die Umgebungsvariablen aus der lokalen Entwicklungsumgebung laden Umgebungsvariablen aus der lokalen Entwicklungsumgebung der lokalen Entwicklungsumgebung Es gibt also einen Standardarbeitsbereich, den wir bereitstellen werden, aber wir möchten vielleicht einen anderen Workspace-Ordner, in dem, Sie wissen schon, die Dateien erstellen Das wird also in der lokalen Umgebung bereitgestellt, und dadurch wird diese Variable aus der Umgebung geladen. Nun, das ist der Hauptimport hier , dass Sie das Execute Command Tool importieren werden, das den Befehl tatsächlich vom Server ausführt. Der Server selbst kann den Befehl also nicht ausführen. Um das tun zu können, benötigt er ein Tool. Und das ist ein MCP-Tool, oder? Wir erstellen also ein Tool in einer separaten Datei. Wir werden uns diese Tool-PY-Datei später ansehen. Aber wir importieren daraus das Execute Command Tool. Wir haben zwei verschiedene Fallbacks je nachdem, wie der Code ausgeführt wird Aber im Grunde importieren wir hier nur das Execute-Befehlstool. Jetzt haben wir die Hauptfunktion. Die Hauptfunktion hier ist also im Grunde der Haupteinstiegspunkt für den Terminal-MCP-Server in der Hauptpunkt-PY-Datei Und wir verwenden hier die MCP-Serverklasse, um einen Server zu initialisieren und ihn in der Servervariablen zu speichern Und wir nennen diesen Server den Terminalserver. Dann registrieren wir unser Tool. Also sagen wir Server Dot AD Underscore Tool und wir stellen dieses Tool zum Ausführen von Befehlen zur Verfügung Wir werden uns später ansehen, wie wir ein Tool definieren, aber im Grunde geben wir dem Server nur ein Tool, das er verwenden kann Sobald wir das Tool hinzugefügt haben, werden wir den Server starten. Also sagen wir, wir starten einfach einen Log-Terminal-MCP-Server und dann sagen wir Serverpunkt Run Transport gleich SDDIO Dieser Transport gibt nun an, welchen Transport der Server verwenden wird, und damit wird der Server gestartet Dieser Block hilft uns nun, die Hauptfunktion auszuführen, wenn wir diese Datei direkt ausführen, und genau das wird Cloud Desktop für uns tun. Wir werden den Server nicht separat alleine betreiben. Das ist also dein gesamter Servercode, oder? Jetzt schauen wir uns den Code der Tools an. Lassen Sie mich hier zu Tools Dot PI gehen. Das ist also eine Datei im selben Verzeichnis wie das Serververzeichnis. Sie haben also Server, Terminalserver, und Sie haben hier einen Workspace-Ordner, und dann können Sie sehen, dass Sie Tools mit dem Punkt P im selben Verzeichnis haben . Schauen wir uns jetzt diese Datei an, richtig? Nun, diese Datei wird im Wesentlichen das Tool und seine Logik definieren. Wir werden zuerst einige grundlegende Bibliotheken aus dem System importieren . Wir benötigen einen Unterprozess, um den Befehl auf dem Terminal auszuführen. Wir brauchen OS, wir brauchen Logging und so weiter. Also das wird den Logger für uns einrichten und dann werden wir den Workspace definieren. Jetzt wird der Workspace ein Verzeichnis sein. Also werden wir sagen, os dot environment dot get terminal underscore workspace Dies wird eine Umgebungsvariable in der lokalen Entwicklungsumgebung Wenn das nicht verfügbar ist, wird es einfach standardmäßig auf das aktuelle Arbeitsverzeichnis zugreifen, alles. Also sucht es zuerst nach einer Umgebung, Terminal und Workspace. Wenn es nicht gefunden wird, wird standardmäßig das aktuelle Arbeitsverzeichnis verwendet, das aktuelle Arbeitsverzeichnis in dem der Servercode gespeichert Und genauer gesagt, das wird das Verzeichnis sein , in dem der Server tatsächlich läuft, oder? Definieren Sie also das Workspace-Verzeichnis, denn so habe ich diesen Code auch getestet , indem ich ihn explizit definiert habe. Und es ist eine bewährte Methode, sich nicht im Klaren darüber zu sein , wo sich dieses Verzeichnis befinden wird. Die zweite Sache ist, dass wir sicherstellen, dass das Workspace-Verzeichnis existiert weil es passieren kann, dass Sie ein Verzeichnis angeben, das nicht existiert, und dann wird Ihr Server in diesem Fall diese Datei nicht erstellen können. Und wir werden hier eine Warnung protokollieren, die besagt, dass das Workspace-Verzeichnis nicht existiert, und wir werden standardmäßig das aktuelle Arbeitsverzeichnis hier verwenden, richtig? Das ist also der Fall, wenn das Workspace-Verzeichnis nicht existiert. Andernfalls verwenden wir dieses Workspace-Verzeichnis, konvertieren es aus Konsistenzgründen in einen absoluten Pfad und verwenden diesen. Jetzt haben wir die Funktion „Befehl ausführen“ und das Tool „Befehl ausführen“. Ordnung. Also, was wir hier machen werden ist nur eine einfache Python-Funktion , die einen Befehl aufnimmt Sie auf dem Terminal ausführen möchten, und dann gibt sie Ihnen eine Antwort, die eine Zeichenfolge ist, okay, die Ausgabe dieses Befehls, okay? Nun, das führt einen Shell-Befehl innerhalb des konfigurierten Workspace und gibt seine Ausgabe oder Fehlermeldung zurück, okay? Und diese Funktion ist so konzipiert , dass sie als MCP-Tool verwendet werden kann. So kann die KI mit dem Terminal des Hostsystems interagieren , das das Workspace-Verzeichnis beschränkt Wir geben die Argumente hier an, also haben wir den Befehl STR, und das ist der vollständige Shell-Befehl, der ausgeführt werden soll. Und das gibt eine Zeichenfolge zurück, die die Standardausgabe des Befehls ist oder eine beschreibende Fehlermeldung falls der Befehl fehlschlägt, okay? Nun, das ist ein sehr einfaches, Sie wissen schon, Lehrmittel und Code für den MCP-Server, aber es ist trotzdem ratsam zu beachten dass Sicherheit sehr wichtig ist Shell-Befehle haben also eine Menge Macht, oder? Ich kann tatsächlich viele Dateien mit einem einzigen Befehl löschen . Sie können tatsächlich auch viele Dateien oder schädliche Dateien erstellen. Solange Sie es also für Ihre eigenen Bildungszwecke testen, werden Sie Ihrer KI wahrscheinlich einfache Befehle geben, aber Sie müssen sich der Tatsache bewusst sein , dass Sie in einer Produktionsumgebung den Befehl, Sie erhalten, strikt validieren sollten den Sie erhalten, strikt validieren sollten, oder? Sie können also wahrscheinlich überprüfen, ob Injektionsangriffe für Pseudo-Befehlsausführungen verhindert werden, die dem Befehl Administratorrechte verleihen dem Befehl Administratorrechte usw., richtig Aber für dieses Ausführungsbeispiel wir einfach den Befehl aus Wir führen hier keine Validierung durch. Ordnung. Lassen Sie uns nun damit beginnen, wie wir den Befehl ausführen werden. Also werden wir hier den Unterprozess dot run verwenden, und dieser wird im Grunde den Befehl ausführen, und eine Shell, die gleich true ist, ermöglicht es uns den Befehl als Zeichenfolge an unsere Shell-Umgebung zu übergeben Capture-Ausgabe, die gleich true ist, fängt die Ausgabe ab, SDD out oder SDD-Fehler, beide, der Text gibt die Ausgabe im Grunde als Zeichenfolge zurück Text wahr ist, wird das getan, und ein Timeout von 30 Sekunden Hängenbleiben zu verhindern und das aktuelle Arbeitsverzeichnis ist der Arbeitsbereich Falls angegeben, ist es der eigentliche Ordner, den Sie angegeben haben. Andernfalls ist es das aktuelle Arbeitsverzeichnis des Servers. Dann gehen wir hier runter und schauen uns das Ergebnis an. Wenn der Befehl also erfolgreich war, erhalten wir einen Rückgabecode, der gleich Null ist, und wir geben den Ergebnispunkt SDD O zurück. Dies ist der Fall, wenn es eine Ausgabe gab Andernfalls geben wir einfach den Befehl zurück, der erfolgreich und ohne Ausgabe ausgeführt wurde. Das ist die andere Standardeinstellung , wenn keine Ausgabe erfolgt. Wenn der Befehl fehlgeschlagen ist, geben wir die Fehlermeldung von SDD RR zurück , und hier fügen wir eine Protokollanweisung ein und geben den Fehler hier zurück. Wir führen hier einige grundlegende Fehlerbehandlungen für abgelaufene Timeout und für alle anderen Ausnahmen Das ist also alles, was dieser Server hat, der Haupt-Punkt-P-Code zur Definition des Servers und der Punkt-P-Code der Tools zur Definition des Tools Wenn wir das nun in den Cloud-Desktop integrieren wollen , müssen wir dem Cloud-Desktop mitteilen wo sich der Server befindet und wie er ausgeführt werden soll. In Ordnung. Also dafür werden wir diese Datei haben , und sie heißt Cloud Desktop Config Dot Jason. Und sobald Sie diesen Code tatsächlich ausgeführt haben, müssen Sie dieses spezielle No Snippet für den Terminalserver in die Liste der MCP-Server in der Confit-Datei der eigentlichen Cloud-Desktop-Anwendungen kopieren den Terminalserver in die Liste der MCP-Server in der Confit-Datei der eigentlichen Cloud-Desktop-Anwendungen Aber schauen wir uns diese Datei an. Das definiert also eine Liste von MCP-Servern. Terminalserver ist einer der Server in dieser Liste, und das ist der Server , den wir gerade gebaut haben Möglicherweise haben Sie hier fünf MCP-Server. Sie können einfach, Sie wissen schon, hinter diese spezielle CRE-Klammer ein Komma setzen hinter diese spezielle CRE-Klammer ein Komma und weitere Server hinzufügen, wenn Sie möchten in der eigentlichen Aber hier, in diesem Beispiel, haben wir nur einen Wir müssen Claude sagen, welcher Befehl ausgeführt werden soll. Auf einem MacBook werden Sie jetzt wahrscheinlich Python 3 als Ausführungsbefehl verwenden . Sie können Python auch nur verwenden, wenn Sie Ihre Python-Skripte auf diese Weise ausführen. Einer dieser beiden würde also im Allgemeinen sowohl unter Windows als auch unter Mac für Sie funktionieren . Ihr Befehl wäre also Python drei. Für ein MacBook führe ich es so aus. Und danach werden Sie das Argument tatsächlich vorbringen. Für die Argumente müssen Sie also den Pfad zum Server angeben. Nun, wenn Sie hier drüben nachschauen, habe ich einen Pfad angegeben, nämlich den MCP-Server, Beispiele 01, Terminalserver Das ist der Hauptordner, Sie wissen schon, für das Terminalserver-Projekt Dann haben Sie die Server, dann haben Sie den eigentlichen Server , der ein Terminal-Underscore-Server ist, und dann haben Sie den Hauptpunkt P , der der Einstiegspunkt ist Nun könnten Sie Ihr Repository in einem anderen Pfad klonen , und Sie wissen schon, Sie haben vielleicht nur den MCP-Server hier drüben, Sie könnten einen anderen Ordner hier haben , was auch immer dieser Pfad Bitte fügen Sie diesen Pfad überall dort hinzu, wo Ihr Terminal-Unterstrich-Serverordner mit dem Unterstrich 01 Terminal-Unterstrich-Serverordner mit dem Unterstrich Dann fügen wir eine Umgebungsvariable ein, also sagen wir, dass Terminal Underscore Workspace die Umgebungsvariable ist Wir geben hier einen ENV-Schlüssel an, und die Map hier drüben besteht nur aus dem Variablennamen und dem Der Wert hier ist also wieder der Projektpfad, und das würde eigentlich den gesamten Projektpfad vervollständigen Und dann wäre das wahrscheinlich üblich, weil Sie dieselbe Ordnerstruktur aus dem Repository erhalten werden üblich, weil Sie dieselbe Ordnerstruktur aus dem Repository erhalten dieselbe Ordnerstruktur aus dem , die ich hier habe. Sie könnten also vorher einen anderen Pfad haben. Da wir diesen Arbeitsbereich bereitgestellt haben, wird unser Server alle Terminalbefehle in diesem speziellen Arbeitsbereich erstellen und, wie Sie wissen, ausführen . Das ist also die Config Dot SN-Datei. Wir haben hier eine Punkt-ANV-Datei. Wir können den Workspace tatsächlich als Workspace mit Punkt und Schrägstrich bereitstellen , und das wird nützlich sein, wenn Sie den Befehl ausführen, wenn Sie den Server auf eine andere Weise ohne den Cloud-Desktop-Konfigurationspunkt JCN ausführen, dann wird es nützlich sein, ihn zu definieren, aber wir fügen ihn trotzdem hier ein, damit der Server dieses Verzeichnis immer zur Verfügung hat, wann immer er ausgeführt werden möchte Das deckt also den gesamten Servercode ab, und jetzt sind wir bereit, diesen Server auszuführen. Um diesen Code auszuführen, holen wir uns zuerst den Code. Also klickst du hier auf Connect to Github und lass uns auf Connect Via Github klicken. Die Empfehlung hier lautet nun, bitte erstellen Sie ein Github-Repository für Ihren eigenen Kurs. Du kannst einfach zu Gu gehen, auf Neues Repository klicken und es erstellen. Andernfalls können Sie das Repository verwenden , in das ich es pushen werde. Es ist auch ein öffentliches Repository, also gebe ich dir den Link für dieses Repo. In Ordnung. Sie können also auf Connect via Github klicken, und das öffnet ein Pop-up hier drüben. Bitte melden Sie sich mit Ihrem Github-Konto an und installieren Sie dann einfach diese KI-Sprach-App. Wir werden nur den Lesezugriff auf Metadaten und den Lese- und Schreibzugriff auf den Code für dieses Repository verwenden Metadaten und den Lese- und Schreibzugriff . Also werde ich hier einfach ein einzelnes Repository auswählen . Wie Sie sehen können, habe ich hier ein Repository ausgewählt , das sind MCP V-Serverbeispiele Sie können es auf github.com bekommen, Sie wissen schon, den Schrägstrich MCP in der KI-Sprache zu Serverbeispielen. Also ich zeige dir dieses Repository, aber das ermöglicht nur den Zugriff auf ein Repository, was sicherer ist, als, du weißt schon, die andere Option zu verwenden, bei der es sich um alle Repositorien handelt Also lasst uns auf Installieren klicken und das wird Gita installieren und dann richtig verbinden Wählen Sie nun hier den Namen des Repositorys aus, auf das Sie gerade Zugriff gewährt haben, und das wird es in den Hauptzweig des Ordners verschieben der den gleichen Namen hat, den Sie hier angegeben haben , also Terminalserver, okay Dann können Sie hier eine Nachricht schreiben , Terminalserver-Code. Und klicken Sie auf Änderungen mit Github synchronisieren. Es dauert ein paar Sekunden, um es auf Github zu übertragen und dann haben Sie den Code in Ihrem eigenen Repository. Um diesen Code auszuführen, klone ich zuerst dieses Repository. Gehen wir zu unserem Code hier und gehen wir zu diesem speziellen Depot und kopieren wir den Clone-Befehl Je nachdem, ob Sie die Github-Befehlszeilenschnittstelle installiert haben oder nicht, können Sie einfach hier zur Geub-CLI gehen und auf Kopieren klicken Dadurch wird dieser Befehl kopiert. Andernfalls können Sie auch Git Clone verwenden und Sie können den Repository-Link hier verwenden. Ordnung. Jetzt gehe ich zurück zum Terminal und schreibe diesen Befehl hier drüben, also wird er dieses Repository in meinem Home-Ordner klonen . vorher ein Lassen Sie mich vorher ein Verzeichnis für MCP erstellen, und das wird nur alle MCP-Dateien innerhalb des MCB-Verzeichnisses für mich anordnen , das existiert bereits, also kann ich einfach zu diesem wechseln Und dann kopieren wir diesen Befehl, der Github Repo Clone ist , Das wird also die MCP Vt Server-Beispiele klonen. Ordnung, großartig. Also das ist erledigt. Jetzt können wir das einfach öffnen. Also schreibe einfach Coderaum und dann MCP zwei. Also Beispiele, das wird diesen Ordner im VS-Code für Sie öffnen Ordnung. Also hier habe ich mein Visual Studio-Codefenster mit dem ganzen Code hier drüben, nettes Setup. Die Sache ist, dass wir diesen Server nicht alleine ausführen müssen , weil wir den Cloud-Desktop verwenden werden , um ihn auszuführen, richtig. Also hier ist meine Cloud-Desktop-Konfiguration. Jason-Beispiel. Hier drüben werde ich nur diesen Projektteil aktualisieren. Lassen Sie mich hier einfach einen aktuellen Befehl für das Arbeitsverzeichnis schreiben . Nun, wie Sie sehen können, wird mir das aktuelle Arbeitsverzeichnis angezeigt, und das wird die ganze Sache sein. Lassen Sie mich das jetzt kopieren und gehen wir wieder hierher zurück und lassen Sie uns dann diesen speziellen Projektpfad aktualisieren, richtig. Also werde ich diesen Projektpfad in das aktuelle Arbeitsverzeichnis ändern . Lassen Sie mich das auswählen, und ich muss es bis hierher tun, weil meine Ordnernamen unterschiedlich sind. Und ich habe das eingefügt, lassen Sie uns hier einen zusätzlichen Schrägstrich setzen, und jetzt können Sie sehen, dass ich hier das richtige Verzeichnis eingerichtet habe, oder? Jetzt muss das Gleiche hier gemacht werden. Also lass uns einfach dieses spezielle Ding hier ändern dieses spezielle Ding hier ändern und auch hier einen zusätzlichen Schrägstrich einfügen Und jetzt habe ich den richtigen Pfad eingerichtet. Bevor wir diese Datei schließen, speichern wir sie einfach und kopieren wir das Ganze. Drücken wir also Befehle. Und dann kopieren wir einfach dieses spezielle Snippet von Jetzt gehen wir zum Cloud-Desktop, oder? Gehen wir also zu Clot Desktop. Ordnung. Hier haben wir also unser Cloud-Desktop-Windows, und Sie können Tools mit der Cloud-Desktop-Anwendung verbinden, indem Sie der Cloud-Desktop-Anwendung auf diese Plus-Schaltfläche klicken Also lasst uns hier drüben klicken und wir sehen , dass wir im Moment überhaupt keine Tools haben Jetzt sind Tools von Konnektoren getrennt, aber ich werde trotzdem hier auf Konnektoren hinzufügen klicken , um zu diesem speziellen Fenster zu gelangen, und lassen Sie uns auf Konnektoren verwalten klicken. In Ordnung. Nun, das bringt uns zum Einstellungen-Tab, und wir gehen hier zur Entwickleroption, und dort heißt es, dass momentan keine Server hinzugefügt wurden. Jetzt können Sie auch zu dieser Entwickleroption wechseln indem Sie zum Cloud-Menü und zu den Einstellungen gehen. Im Wesentlichen müssen Sie jedoch zum Bildschirm gehen und auf Konfiguration bearbeiten klicken. Sobald ich das getan habe, öffnet es diesen Cloud-Desktop-Konfigurationspunkt Json. Denken Sie jetzt daran, dass dies der eigentliche Cloud-Desktop-Konfigurationspunkt JCN Es befindet sich im Cloud Cloud Desktop Config JCN für Unterstützung von macOS-Bibliotheksanwendungen Cloud Cloud Desktop Config JCN Es ist nicht die Beispieldatei hier drüben. Aber was wir brauchen, ist dieser Inhalt, also klicke ich einfach mit der rechten Maustaste und kopiere und lass uns hier drüben klicken und dann auf Einfügen klicken. Ordnung, jetzt habe ich das gespeichert und ich kann es komplett speichern, oder? Das ist gespeichert. Lassen Sie uns diese Datei einfach von hier aus schließen. Jetzt ist es wichtig, dass Sie Cloud Cloud Desktop vollständig beenden müssen , oder? Das ist also eine Cloud-Desktop-Anwendung. Wenn Sie es einfach von hier aus schließen, wird es nicht einfach beendet weil es im Hintergrund weiterläuft. Sie müssen also sowohl unter Windows als auch unter Mac zu Ihrem Cloud-Menü gehen . Klicken Sie darauf und klicken Sie auf Beenden. Nun, das ist es, was den Cloud-Code vollständig beenden wird, und er wird aus dem laufenden Hintergrundbetrieb beendet. Nur für den Fall, dass das nicht funktioniert und Sie den Server nicht hochfahren sehen, auch keine Fehler oder so, auch keine Fehler oder so, müssen Sie den Prozess beenden Cloud-Code verwendet , da es manchmal vorkommt, dass Cloud nicht beendet wurde und diese Änderung in der JSON-Datei der Cloud-Desktop-Konfiguration nicht erkannt werden kann, wenn sie nicht ordnungsgemäß beendet wurde diese Änderung in der JSON-Datei der Cloud-Desktop-Konfiguration nicht erkannt werden kann, wenn sie . Sobald dies erledigt ist, können Sie den Cloud-Desktop erneut öffnen . In Ordnung. Sobald Sie dies getan haben, wird die Cloud Distob-Anwendung wieder geöffnet Wenn Sie hier auf Plus klicken, sollten Sie sehen, dass hier einige Tools hinzugefügt werden. Jetzt können wir sehen , dass der Terminalserver hier reingekommen ist. Es ist derzeit aktiv und es wird das Terminalserver-Tool haben. Jetzt können Sie also eine Nachricht an die Cloud senden, in der Erwartung , dass sie diesen Terminalserver verwenden kann, oder? Lassen Sie mich Ihnen jetzt eine kurze Demo geben was dieser Terminalserver kann. Erstellen Sie eine Datei mcpsuccess dot txt und fügen Sie ihr den Inhalt hinzu, dass ich meinen ersten MCP-Server mit STDIO Transport und Version zwei des Protokolls erstellt habe meinen ersten MCP-Server mit STDIO Transport und Version zwei des Protokolls erstellt STDIO Transport und Version zwei des Protokolls Bitte verwenden Sie den Terminalserver und Befehlstool zum Ausführen von Shell-Befehlen, um diese Datei für mich zu erstellen In Ordnung, lassen Sie mich hier heranzoomen und Ihnen erneut die Aufforderung zeigen, die besagt, eine Datei zu erstellen. Und hier werden wir im Grunde den Execute-Befehl vom Terminalserver verwenden. Ordnung. Es kann also vorkommen, dass Claude eine implizite Fähigkeit besitzt, mit Dateien zu arbeiten Wir wollen unseren eigenen Server testen, also werden wir Sie bitten, diesen speziellen Befehl gezielt zu verwenden, oder? Das war's also, lassen Sie mich die Tippfehler hier korrigieren . In Ordnung. Also das ist das, und dann kann ich einfach auf Senden klicken, weißt du, das ausführen. Jetzt führe ich den Befehl hier aus. Es hat ein Ergebnis. Lassen Sie mich dieses Ergebnis überprüfen. Es heißt also, fertig, die Datei cpSuccess Punkt TXT wurde erfolgreich im Workspace-Verzeichnis mit den Shell-Befehlen des Terminalservers erstellt erfolgreich im Workspace-Verzeichnis mit den Shell-Befehlen des Terminalservers Es enthält, dass ich meinen ersten MCP-Server mit SDI-Transport unter Verwendung der zweiten Version des Protokolls erstellt habe meinen ersten MCP-Server mit SDI-Transport unter Verwendung der zweiten Version des Und herzlichen Glückwunsch zum Aufbau Ihres ersten MCB-Servers. Dies ist eine Nachricht von Cloud. Es versteht, dass wir versuchen, zu lernen und diesen Server zu erstellen, also gratuliert es uns dazu, oder? Nun, eine wichtige Sache, die man hier beachten sollte, ist, dass ich den kostenlosen Cloud-Plan verwende, wie Sie vielleicht auf diesem, Sie wissen schon, Startbildschirm gesehen haben, und es erfordert keinen kostenpflichtigen, Sie wissen schon, funktionierenden kostenpflichtigen Plan für die Integration von MCB-Servern Das ist eine Frage, die mir oft gestellt wird. Sie benötigen also den kostenpflichtigen Tarif für einige andere Funktionen, um, Sie wissen schon, auf die neuesten Modelle mit höheren Limits zugreifen zu können. Aber für Lern- und Bildungszwecke können Sie einfach den kostenlosen Tarif verwenden und Ihre MCP-Server zum Testen integrieren . Lassen Sie uns diese Datei herausnehmen Gehen wir zu Visual Studio Code und schauen wir es uns an. Hier sind wir in Visual Studio Code, und lassen Sie uns hier die Verzeichnisstruktur vergrößern. Sie können sehen, dass der Arbeitsbereich korrekt verwendet wurde. Sie haben den MCP-Erfolgspunkt TXT hier drüben und Sie haben die Nachricht hier geschrieben, richtig? Das ist also nur ein Job, was auch immer wir wollten, richtig, und jetzt haben wir erfolgreich unseren ersten MCP-Server gebaut Auch dies ist der MCP-Server, den wir gebaut haben. Sie können über den Link in der Beschreibung auf den Code zugreifen und ihn in Ihrer Liste der MCB-Server speichern Nur um es noch einmal zu wiederholen: Wir verwenden die neueste Version zwei des MCB-Protokolls unter Verwendung der MCP-Serverklasse , ohne schnelles MCP Es ist nur eine einfache Umbenennung, aber wir haben den neuesten Code verwendet und ihn mit STD-IO-Transport erstellt. Das ist der Fall , wenn Ihr Client und Ihr Server über Standardeingabe und -ausgabe kommunizieren, die korrekte Protokollierung verwendet haben und wir Befehle integriert und ausgeführt haben, um mit dem Server zu arbeiten Und das hat uns dann geholfen, es mit dieser Konfiguration in Cloud Desktop zu integrieren . Und sobald wir das getan hatten, konnte Cloud Desktop das für uns ausführen. Ich konnte die Befehle ausführen und diese Datei für uns erstellen. Also vielen Dank fürs Zuschauen, und wir sehen uns in der nächsten Vorlesung mit anderen Beispielen wieder . 7. SECTION 3 Build Your Own MCP Client: Hallo, alle zusammen. Willkommen zurück in der KI-Sprache. Das Model Context-Protokoll ändert sich also, wie Sie wissen, es wird von Version eins auf Version zwei migriert , und es wird für uns sehr wichtig zu verstehen, wie wir die neueste Version von MCP verwenden die neueste Version von , um unsere Server und Clients zu erstellen Nun, wir haben uns bereits in den vorherigen Vorlesungen mit Model Context Protocol Version zwei mit dem Aufbau eines Terminalservers befasst in den vorherigen Vorlesungen , und jetzt werden wir uns ansehen, wie man einen MCP-Client erstellt, und wir werden das Google Agent Development Kit als den Agenten verwenden, der den MCP-Client verwendet, um eine Verbindung zu Servern herzustellen einen MCP-Client erstellt, und wir werden das Google Agent Development Kit als den Agenten verwenden , der den MCP-Client verwendet, um , die auf dem StdioTransport basieren. Wir werden dafür die neueste Version des Model-Context-Protokolls verwenden , die derzeit verfügbar ist, nämlich V One, und wir werden darüber sprechen, wie wir einfach auf jedes Mal aktualisieren können , wenn VT stabil wird. Um Ihnen zu helfen, zu lernen, wie man MCP-Clients erstellt, habe ich dieses anfängerfreundliche Tutorial erstellt. Wir haben hier einen MCP-Client, einen MCP-Server und eine Befehlszeilenschnittstelle, um damit zu arbeiten. Ich habe diesen Code auf alanguage.com gehostet und Sie können ihn ganz einfach über den Link in der Beschreibung abrufen einfach Das wird dir helfen, den Code auf deinen lokalen Computer herunterzuladen und ihn von dort aus auszuführen Und wir werden uns all diese Schritte ansehen während wir das durchgehen. Bevor wir beginnen, möchte ich Ihnen kurz zeigen, was dieser MCP-Client kann Dafür gehe ich zum Terminal. Ich bin hier am Terminal und starte jetzt die Befehlszeilenschnittstelle, die den Client und die Verbindung zum Server initiiert Ich gebe Uvruncmd Punkt p ein und drücke die Eingabetaste. Und jetzt können Sie sehen, dass dort steht, dass Verbindung zum MCP-Server-Echo-Server Dies ist einer der Server, die ich in das Code-Repository aufgenommen habe in das Code-Repository aufgenommen Es ist nur ein einfacher Server, der wiederholen kann, was auch immer Sie ihm sagen, Ordnung, oder Echo, was auch immer Sie ihm sagen. Und es gibt noch einen Server, der Terminal ist, und dieser wird ein Tool haben, das einen Befehl ausführt. Er ist dem Terminalserver sehr ähnlich , den wir uns zuvor mit dem Execute Command Tool angesehen haben . Das ist ein anderer Name hier. Es ist auch ein SDD-IO-basierter Server, und ich helfe Ihnen, die Abfragen auf dem Terminal Ihres Computers auszuführen die Abfragen auf dem Terminal Ihres Computers Sie können also grundsätzlich Befehle auf dem Terminal Ihres Computers ausführen Befehle auf dem Terminal Ihres Computers Jetzt sehe ich, dass die Beschreibung hier fehlt. Lassen Sie mich versuchen, ein kurzes Update zu machen , damit die Beschreibung hier drüben ist. Nun, da ich wieder beim Code hier drüben bin und ich hier zu cmd Punkt P gehen lasse. Und Sie können sehen, dass wir in Zeile 97 tatsächlich auf alle Tools zugreifen und die Beschreibung drucken Ich denke also, die Aufteilung durch N ist wahrscheinlich etwas, das dazu führt, dass nur die erste Zeile , die möglicherweise leer ist, hineinkommt. Und lass uns das einfach von hier entfernen. In Ordnung. Also nimmt es jetzt direkt eine Beschreibung mit dem Werkzeugpunkt auf, falls verfügbar, sonst keine Beschreibung. In Ordnung. Speichern wir die Änderungen und wechseln wir erneut zu Gu. Ordnung. Also ist es schon verbunden. Lassen Sie mich einfach sagen, aktualisieren Sie die Befehlszeilenschnittstelle. Lass uns auf Sync klicken und es werden jetzt die Änderungen übertragen. In Ordnung. Also das ist erledigt. Gehen wir jetzt zurück zum Terminal. Lassen Sie mich den aktualisierten Code noch einmal abrufen. In Ordnung. Dadurch wird ein falsch benannter Ordner mit 01 gelöscht, aber das ist das Update, auf das wir uns eigentlich konzentrieren , Cmdt P. Lassen Sie uns das klären . In Ordnung. Also lass mich das jetzt nochmal machen. Ich sage, können Sie bitte das Echo-Tool verwenden , um den Text wiederzugeben? Ich habe erfolgreich meinen ersten MCP-Client erstellt und ihn in Google ADK integriert. In Ordnung Jetzt sehen Sie also, dass der Agent denkt, er würde Anfrage vom Typ Listentools-Anfrage bearbeiten. Dann heißt es, dass die Antwort vom Modell empfangen wurde. Dann haben Sie eine Verarbeitungsanfrage vom Typ Call Tool Request, dann Tool Echo Tool, das mit Text aufgerufen wird Ich habe erfolgreich meinen ersten MCP-Client erstellt und ihn in das Google Agent Development Kit integriert Wir sehen also, dass dieses grundlegende Tool erfolgreich aufgerufen wurde. Es ist nur ein Echo-Tool und Sie können es tatsächlich modifizieren, um viel sinnvollere Dinge zu tun. Und schließlich erhält das Modell die Antwort auf den Aufruf des MCP-Tools und es heißt, dass ich den Text erfolgreich wiedergegeben habe, und das ist der Text hier. Und jetzt können wir einfach quit eingeben, um das zu beenden. Schauen wir uns nun an, wie wir den Code bekommen. Verwenden Sie also bitte den Link und verwenden Sie ihn, um diese spezielle Website zu besuchen. Sie können den Code dann über die Download-Schaltfläche herunterladen oder ihn auch für Ihren eigenen Gebrauch nach Github exportieren. Wenn Sie möchten, können Sie hier Ihren eigenen Gemini-API-Schlüssel einrichten , der mit diesem Code mithilfe des KI-Assistenten handelt, oder Sie können auch einen MCP-Serverclient von Grund auf neu erstellen Verwenden Sie diesen A-Assistenten hier auf alanguage.com. Sobald Sie den Code erhalten haben, müssen Sie ihn einrichten, bevor Sie ihn ausführen können Ordnung. Lassen Sie mich Sie durch die Schritte zur Einrichtung führen. Sie können sich auch die Readme-Datei hier ansehen und versuchen zu verstehen, was die Einrichtungsschritte sind. Aber lassen Sie mich Sie jetzt durch sie führen. Wenn Sie den Code herunterladen, speichern Sie ihn auf Ihrem lokalen Computer und navigieren Sie zu diesem Verzeichnis. Also habe ich es in diesem Verzeichnis gespeichert und bin zu dem Ordner navigiert , der 02 MCP AD Gig Line ist Sobald Sie das getan haben, müssen Sie ein UV-Projekt initialisieren, oder? müssen Sie ein UV-Projekt initialisieren Also werde ich UV hineintippen. Nun, ich habe das bereits initialisiert, also heißt es, dass es bereits initialisiert ist, aber Sie werden es erneut tun und Sie werden dieses Projekt und Sie werden Und dann müssen Sie eine virtuelle Umgebung erstellen. Lassen Sie uns also UV Space VNV machen und es wird jetzt diese virtuelle Umgebung bei Punkt VENV erstellen Dann müssen Sie diese virtuelle Umgebung aktivieren Quellpunkt NV slash bin slash activate eingeben Und die Windows-Benutzer können tatsächlich ihrem eigenen Quellbefehlsformat folgen, das hier geschrieben wird, und das aktiviert das Einfügen eines Labels hier drüben mit dem 02 MCP Sobald das erledigt ist, fügen Sie die Anforderungen hinzu Sie werden UV addRequirements dot TXT sagen. Dies hilft nun dabei, alle in dieser speziellen Datei angegebenen Anforderungen hinzuzufügen alle in dieser speziellen Datei angegebenen Anforderungen Dies ist bereits Teil des Repositorys, sodass nur alle Anforderungen hinzugefügt werden. Lass uns den Bildschirm leeren. Jetzt können Sie dies in Visual Studio-Code öffnen, sodass Sie Code und dann einen Leerzeichen eingeben können. Sobald Sie das getan haben, erhalten Sie hier das Visual Studio-Codefenster mit Ihrem Ordner. Bitte gehen Sie zur DOT-ANV-Datei und fügen Sie hier Ihren Google-API-Schlüssel hinzu. Dies ist der API-Schlüssel, den Sie für das Modell benötigen, die Gemini-Modelle, die wir hier verwenden , um die Anfragen zu verarbeiten, die Sie an das Modell senden Sobald Sie das getan haben, können Sie tatsächlich UV run cmd dot py sagen , und Sie können die Eingabetaste drücken . Dadurch werden Ihre beiden Server gestartet und eine Verbindung hergestellt , und Sie werden aufgefordert unten hier eine Abfrage hinzuzufügen. Wir haben uns bereits eine Demo angesehen, wie das funktioniert Lassen Sie uns nun durchgehen und verstehen wie der Code strukturiert ist und wie das alles funktioniert Um den Code zu verstehen, gehe ich zurück zur Website und schauen uns zunächst den MCP-Client an, die Manager-Dot-Py-Datei Ordnung, dieser Manager hilft uns also im Grunde zu verstehen, wie der Client mit dem Server über JCNRPC über SDD IO kommuniziert dem Server über JCNRPC über SDD IO Es hilft uns, das gesamte Lebenszyklusmanagement zu verstehen. Deshalb verwenden wir das asynchrone Exit-Tag, um sicherzustellen, dass alle um sicherzustellen Dies ist auch die Erkennung von Tools. Wie fragt also ein Client einen Server, über welche Fähigkeiten er verfügt? Und dann gibt es ein Multiplexing. Das bedeutet also, dass Sie tatsächlich gleichzeitig eine Verbindung zu zwei Servern herstellen können , wie wir es gerade in der Demo gesehen Ordnung, also lasst uns nach unten scrollen und versuchen, den Code zu verstehen. Also haben wir die Import-Anweisungen hier und wir haben die MCP-Importe hier drüben, und dann haben wir ein Logger-Setup Wie wir in der letzten Vorlesung verstanden haben, können wir hier keine Print-Anweisungen verwenden, da sie die SDD-IO-Kommunikation stören Wir müssen also ein geeignetes Logging-Setup verwenden. Dann haben wir den MCP-Client-Manager, und dieser verwaltet die Verbindungen zu mehreren MCP-Servern über Es fungiert als Brücke zwischen Ihrer Anwendungslogik und dem externen MCP-Serverprozess. In Ordnung. Also, hier drüben ist ein Konstruktor. Es gibt eine Ladekonfiguration, eine Verbindung, um alle Tools aufzulisten, und dann gibt es hier ein Call-Tool. Und schließlich haben wir eine Shutdown-Funktion. In Ordnung. Jetzt können Sie sehen, was dieser ganze Kundenmanager macht, oder? Es kann tatsächlich einen Konstruktor haben, um es zu starten, richtig, und sich selbst einzurichten Sie haben eine Funktion zum Laden der Konfiguration. Der Manager hilft Ihnen also beim Laden der Konfiguration , die Sie in der Datei Config Dot Gen haben werden . Es hat eine Verbindung zu allen Funktionen, also hilft es Ihnen im Grunde, eine Verbindung zu allen MCB-Servern herzustellen, die in der Ladekonfiguration gefunden wurden Und dann hat es die Funktion „ Alle Tools auflisten“, sodass es all die verschiedenen Tools, ihre Namen, Beschreibungen usw. auflisten kann , was auch immer Sie wollen, indem Sie diese Funktion hier verwenden Und schließlich hat es eine Funktion zum Aufrufen , mit der alle Tools aufgerufen werden können Und wenn Sie dann mit allem fertig sind und die Anwendung herunterfahren, müssen Sie sie herunterfahren, um die gesamte Verbindung ordnungsgemäß zu beenden und die Bereinigung durchzuführen Schauen wir uns diese Funktionen nun nacheinander an. Sie haben also zuerst den Konstruktor und hier drüben haben Sie einen Konfigurationspfad , den Sie hier für die Konfiguration angeben Dann haben Sie die verschiedenen Sitzungen. Wir werden alle Sitzungen speichern, die gestartet wurden, um eine Verbindung zu allen MCP-Servern herzustellen, die sich darin befinden Es ist ein Wörterbuch mit Namen und einem Client-Sitzungsobjekt Dann definieren wir das Exits-Tag, und das ist ein Async-Exits-Stag Damit können Sie mehrere asynchrone Ressourcen in einer Schleife öffnen und es wird garantiert , dass alle zu einem späteren Zeitpunkt geschlossen werden Es ist also wie ein Stapel von Bereinigungsfunktionen. Jedes Mal, wenn Sie einen Async-Kontext aufrufen, merkt er sich, wie er beendet werden kann, und Sie können Close aufrufen, und alles wird in umgekehrter Reihenfolge geschlossen Das ist also wichtig, um am Ende aufzuräumen. Jetzt haben wir die Serverparameter. Auch hier werden wir ein Wörterbuch der Server und ihrer Parameter haben , und wir werden es später dem STD-Client zur Verfügung stellen , um dann tatsächlich eine Verbindung zum SD-IO-Server herzustellen. Und wir werden sehen, wie wir sie definieren , sobald wir die Konfiguration geladen haben. Das ist also der Konstruktor. Jetzt haben wir die Funktion Load Confict. Schauen wir uns das an. Nun, das ist eine einfache Funktion, da sie nur die MCP-Serverkonfigurationen aus der Konfliktdatei lädt . Überprüfen Sie also zuerst, ob der Pfad existiert oder nicht, und geben Sie einen Fehler aus, falls dies nicht der Fall ist Dann wirst du die Datei öffnen. Sie werden die Server unter MCP-Servern unterteilen. Wir können uns also bald mit Konflikten befassen und so werden unsere MCP-Server gerettet Also bringen wir alle MCP-Server hierher und dann gehen wir den Namen und die Informationen in allen Elementen auf diesem MCP-Server Also nochmal, wenn Sie sich den Konfliktpunkt Jason ansehen, haben Sie einen Echo-Server, was der Name des Servers ist, und dann sind das die Informationen rund um diesen speziellen Server, okay? Jetzt werden wir die SDD-IO-Serverparameter abrufen. Aus den Informationen werden wir also den Befehl, die Argumente und die Umgebung abrufen , sie diesem speziellen Konstruktor für die SDD-Ioserver-Parameter zur Verfügung stellen und ein Objekt dafür abrufen Dann speichern wir es in Serverparametern mit dem Namen des Jetzt haben wir also ein Wörterbuch mit dem Servernamen und seinen Verbindungsparametern Im Grunde definiert dies, wie der Serverprozess gestartet wird. Wir haben hier eine Ausnahmebehandlung , und das ist alles. Das ist also im Grunde unsere Load-Config-Funktion. Jetzt haben wir die Verbindungsfunktion, also stellen Sie eine Verbindung zu allen her, und das wird eine Verbindung zu allen konfigurierten MCP-Servern Es wird also die Serverprozesse verkleinern und die JCN-RPC-Sitzungen einrichten Wir werden also die Serverparameter, die wir im vorherigen Schritt erhalten haben, alle darin enthaltenen Elemente auflisten und die Namen und Parameter abrufen Für jeden von ihnen werden Sie also sagen, dass die Verbindung zum MCP-Server mit dem Befehl Params dot Und danach weitere Argumente. Ordnung. Das ist nur ein einfaches Protokoll hier drüben. Alles klar. Dann verwenden wir die Parameter, um den Serverprozess zu starten. Dadurch wird im Grunde der MCP-Serverprozess gestartet. Es öffnet die SDD-IO-Pipes und registriert sie für die Bereinigung Nun, warum verwenden wir hier den EnterASN-Kontext? Weil dies ein ASN-Prozess sein wird. Wir sagen also nur, dass Sie diesen ASN-Prozess öffnen und daran denken , ihn später zu schließen Wenn das nur ein Prozess und nur ein Server gewesen wäre, wäre das in Ordnung gewesen, aber wir werden mehrere solcher Prozesse öffnen Deshalb kommt der Exit-Stack wie ich bereits erklärt habe, ins Spiel. Es ermöglicht Ihnen, mehrere solcher asynchronen Ressourcen zu öffnen, und garantiert dann , dass alle diese später zur Bereinigung in einer Schleife geschlossen werden alle diese später zur Bereinigung in einer Schleife Ordnung. Also diese ganze Leitung verbindet uns dann einfach mit dem MCP-Server und registriert ihn gewissermaßen für die spätere Bereinigung über den Exit-Stack Und es gibt dieses Transportobjekt zurück. Jetzt werden wir einen weiteren Rennprozess eröffnen, nämlich die Clientsitzung. Dabei wird im Grunde die Protokollebene erstellt, die das gesamte Messaging abwickelt. Wir werden also den Client-Sitzungskonstruktor verwenden , wir werden die Lese- und Schreib-Pipes hier bereitstellen, und das wird eine Client-Sitzung für uns erstellen Wir werden wieder Enter acing Context verwenden, weil wir diesen ACN-Prozess öffnen und daran denken wollen diesen ACN-Prozess öffnen , ihn später zu schließen, und wir werden das Exits-Tag verwenden, um ihn für die spätere Bereinigung zu Und das wird uns helfen, ihn auf nette Weise zu bereinigen und sicherzustellen, dass alle ACN-Prozesse, die wir gestartet haben , Nun, wissen Sie, sind zwei Dinge offen. Sie haben die Transportschicht geöffnet, das sind, Sie wissen schon, der Prozess und die Pipes, die Serverprozesse und die Pipes damit. Und dann haben Sie die Client-Sitzung geöffnet, das ist das Protokoll, das die JCNRPC-Nachrichten von unserer Anwendung an diese Server verarbeitet die JCNRPC-Nachrichten von unserer Anwendung an diese Jetzt werden wir einfach die Sitzung initialisieren. Das ist eine Anforderung, und wir werden diese Sitzung in unserem Wörterbuch mit dem Namen des Servers speichern diese Sitzung in unserem Wörterbuch mit dem Namen des Servers Ein Recht? Und dann protokollieren wir einfach , dass die Verbindung zum MCP-Server erfolgreich hergestellt wurde Jetzt haben wir hier eine Ausnahmebehandlung, und damit ist diese Funktion, die Verbindung zum MCP-Server, im Grunde abgeschlossen ist diese Funktion, die Verbindung zum MCP-Server Jetzt haben Sie also eine saubere Möglichkeit, die Konfiguration zu laden und eine Verbindung zum MCP-Server Wir haben uns diese beiden Funktionen angesehen. Schauen wir uns nun die Liste an, in der alle Tools funktionieren, oder? Jetzt werden die Tools von allen verbundenen Servern zusammengefasst . So sieht der Agent also, was er tun kann. Jeder Server gibt eine Liste seiner Tools zurück und wir kombinieren sie hier. Also werden wir hier diese, du weißt schon, leere Liste mit allen Tools erstellen . Und dann werden wir für Name und Sitzung im Sitzungswörterbuch , das wir erstellt haben, alle Elemente daraus holen und die Namen und die Sitzungsobjekte daraus abrufen. Dann nennen wir Session Dot is Tool für einen von ihnen, sodass wir hier ein Ergebnis erhalten, und dann gehen wir alle Tools in result Dot Tools durch. Das sagt uns, dass wir für diese Sitzung all diese Tools haben, und für jedes Tool werden wir es einfach an unsere Tool-Liste anhängen Also alle Tools in der Liste. Dann werden wir alle Werkzeuge zurückgeben. Im Wesentlichen haben wir jede der Sitzungen durchgemacht. Wir haben List Tools genannt. Wir haben alle Tools. Und dann haben wir es für jedes Tool an die A-Tool-Liste angehängt Das ist also eine einzigartige, einzige Liste aller Tools. Als Nächstes haben wir die Funktion „Tool aufrufen“. Jetzt benötigt die Funktion Call Tool zwei Argumente. Es sind der Name des Tools und die Argumente für diesen Werkzeugaufruf Anschließend wird ein Ergebnis des Aufruf-Tools zurückgegeben. Und wie der Name schon sagt, ruft es im Grunde ein Tool auf dem entsprechenden Server auf, und wie machen wir das? Es gibt also mehrere Möglichkeiten, dies zu tun. Ich denke, es gibt effizientere Möglichkeiten, dies zu tun, aber schauen wir uns diese Methode jetzt an. Was wir also im Grunde tun, ist, dass wir eine Liste von Sessions als Wörterbuch hatten und wir alle Sessions daraus herausholen. Jetzt nehmen wir hier eine Sitzung auf und nehmen ihren Servernamen und das Sitzungsobjekt, richtig? Und dann listen wir alle Tools in dieser Sitzung auf. Jetzt wissen wir also, dass wir für diesen Server all diese Tools haben, die in Tools Underscore Results enthalten sind Dann gehen wir die einzelnen Tools durch und versuchen, die Namen zuzuordnen. In Ordnung. Also sehen wir, ob, der angegebene Name des Tools mit einem der Toolnamen auf diesem Server übereinstimmt. Wenn wir das erste Tool finden, das wir für okay halten, das ist, äh, das ist der richtige Werkzeugname, rufen wir die Sitzung einfach underscoeTOL mit einem Werkzeugnamen In Ordnung. Also, es ist ein Match, das auf dem Namen des Tools basiert, und wir nehmen das erste Spiel, das verfügbar ist, okay? Und das nennen wir Tool. Falls dieses Tool auf dem ersten Server nicht verfügbar wäre , wären wir dann zum nächsten Eintrag in der Sitzungsliste oder im Wörterbuch gegangen und hätten den Namen abgerufen, wir haben das Sitzungsobjekt und dann den gleichen Vorgang wiederholt und das Tool auf diesem Server aufgerufen , falls es verfügbar war, oder? Das ist also einfach die Funktion „Tool aufrufen“. Und schließlich haben Sie den Shutdown. Es ist also erforderlich, weil es alle Sitzungen schließt und problemlos transportiert wird. Durch das Schließen des Exit-Stacks werden die A-Exit-Methoden aller registrierten Kontextmanager in umgekehrter Reihenfolge ausgelöst die A-Exit-Methoden aller registrierten Kontextmanager in umgekehrter Wir hatten also all diesen verschiedenen Async-Prozessen mit diesem Exit-Stack in unserem gesamten Code widerstanden all diesen verschiedenen Async-Prozessen mit diesem Exit-Stack in unserem gesamten Code Und jetzt müssen wir nur A close für diesen Exit-Stack aufrufen, und das wird all unsere MCP-Verbindungen schließen, sowohl die Transportschicht mit den Serverprozessen als auch die Lese- und Schreib-Pipes und auch die Clientsitzungen Das ist also die Punkt-P-Datei des MCP-Client-Managers. Und das ist eines der wichtigsten Dinge, die es rund um den MCP-Client zu verstehen Richtig? Wir haben schon, Sie wissen schon, Server usw. durchsucht , aber das ist neu, und so funktioniert der MCP-Client Und da es dadurch in verschiedene Funktionen unterteilt wird, hilft es uns meiner Meinung nach zu verstehen, wie jedes dieser Dinge In Ordnung, jetzt haben wir also einen einfachen Echo-Server. Nun, ich werde den Code nicht durchgehen weil wir bereits einen viel komplizierteren Server gesehen haben , nämlich einen Terminalserver. Ich habe hier viele Kommentare hinzugefügt. Es ist wieder ein sehr einfacher, du weißt schon, ähm, Server. Wir verwenden Fast MCP, um ihn zu initialisieren. Wir verwenden hier keinen MCP-Server, das ist die neue Klasse, die umbenannte Version von Fast MCP, weil Google ADK derzeit gut mit der Produktionsversion von MCP funktioniert, die derzeit Version die Und sobald das auf Version zwei aktualisiert wird, werde ich den Code so aktualisieren, dass er Version zwei verwendet , wann immer das für diesen Code relevant ist, Aber vorerst bleiben wir in diesem speziellen Beispiel bei Fast MCP Wir haben also das MCP, Server-Overhead, das Objekt Wir registrieren ein Tool mit der Geschwindigkeit von mcptTOL Wir stellen eine Dokumentzeichenfolge zur Verfügung, im Grunde hilft zu uns im Grunde hilft zu verstehen, was das Tool tut Das KI-Modell wird das tatsächlich verwenden, und es wird nur, Sie wissen schon, Echotext zurückgeben, und es kann auch diese speziellen Informationen protokollieren. Das ist alles für diesen speziellen Server, und Sie können sich einfach die Befehle hier durchlesen , um das besser zu verstehen. Wir haben auch einen Ressourcen-Punktstapel, das ist eine Ressource, die der Server tatsächlich lesen kann. Wir gehen jetzt hier nicht auf die Details weil wir uns hier nur mit dem Echo-Tool befassen . Dann haben wir Tools Dot PY. Das definiert tatsächlich das Echo-Tool, und auch hier es nur Echo und den Text zurück , den es als Eingabe bereitgestellt hat, oder? Das ist ein sehr einfacher Server und ich werde es für diesen speziellen Server dabei belassen . Dann haben wir endlich den Befehl PY File, die Cmd Dot PY Datei, und das ist unser Haupteinstiegspunkt für unsere Schnittstelle Dieses Skript zeigt nun, wie Google ADK in das Context-Protokoll des Modells integriert Google ADK in das Context-Protokoll des Modells da wir uns nur den Client angesehen Wir haben uns den Servercode angesehen und wissen, dass der Client jetzt in der Lage ist, eine Verbindung herzustellen, alle Tools aufzulisten, Tools aufzurufen usw., richtig Aber wie integrieren wir ihn in einen Agenten, sodass wir den Agenten abfragen können und er dann entscheiden kann , die Liste der Tools abzurufen, ein bestimmtes Tool zu verwenden und so weiter Das werden wir also hier tun. Dadurch wird ein autonomer Agent geschaffen, der Tools von externen MCB-Servern entdecken und verwenden kann Tools von externen MCB-Servern entdecken und verwenden um Benutzern zu helfen, oder? Und die wichtigsten ADC-Konzepte , die wir hier verwenden , sind LLM-Agenten Nun, ADK selbst ist ein agentisches Framework, oder? Es bietet Ihnen also die gesamte Unterstützungsstruktur für den Aufbau eines netten Agenten- oder Multiagentensystems in einem bestimmten Arbeitsablauf usw. Aber was wir hier machen, ist dass wir nur einen einzigen Agenten verwenden Was als LLM-Agent bezeichnet wird. Es ist also eine LLM-Agentenklasse, die wir verwenden werden. Sie repräsentiert das KI-Modell Gemini mit seinen Anweisungen und Tools Also packt es als Agent alles zusammen. In Ordnung. Jetzt verwenden wir auch das MCP-Toolset, eine ADC-Komponente, die automatisch die Komplexität der Verbindung zu und der Kommunikation mit MCP-Servern bewältigt Komplexität der Verbindung zu und der Kommunikation mit Dann verwenden wir einen In-Memory-Runner, also einen übergeordneten Orchestrator , der die Konversation, den Loop, den Sitzungsverlauf und die Toolausführung für diesen speziellen Agenten verwaltet , Toolausführung für diesen speziellen Um diesen Code zu verstehen, sollten Sie sich zunächst mit diesen Begriffen vertraut machen, denn wir wollen uns darauf konzentrieren, ADK für Abfragen und Verbindungen zum MCP-Server zu verwenden Abfragen und Verbindungen zum MCP-Server zu Wir haben auch einen Sitzungsdienst, der den dauerhaften Status einer Konversation verwaltet Wenn wir jetzt nach unten scrollen, haben wir alle grundlegenden Importe. Ganz oben haben wir hier Google ADG Imports und wir haben umfangreiche Importe für, Sie wissen schon, die Formatierung der Ausgabe Dann haben wir hier den Befehl load dot ANV. Das wird also, du weißt schon, deinen API-Schlüssel aus der DOT-ENV-Datei laden Dann haben wir das Setup für die Protokollierung. Dann machen wir das hier drüben. Also dann haben wir die Konsole hier drüben. Das hilft uns also, die formatierte Ausgabe auf dem Terminal zu drucken. Und jetzt haben wir endlich den Einstiegspunkt, der die Hauptfunktion ist Also werden wir die Setup-Protokollierung aufrufen. Das wird also die Protokollierung für uns einrichten. Sie sehen das hier drüben, und dann haben wir die Config-Datei, die Confict Jon ist Das ist behoben, im Grunde musst du es im selben Verzeichnis haben Und dann prüfen wir, ob es existiert, und laden dann endlich die Konfiguration. Wir sagen also nur, dass config gleich json loDF und servers Config ist, wir bekommen das mit dem Config-Punkt Get MCP Das lädt also nur die Konfiguration, die Liste der MCP-Server, zu denen wir eine Verbindung herstellen wollen Jetzt stellen wir eine Verbindung zu MCP-Servern her. Eine wichtige Sache hier ist also , dass wir MCP-Toolsets aus dem Google Agent Development Kit verwenden werden, da dieses die Komplexität der Verbindung selbst bewältigen wird Wir müssen also nicht den Low-Level-Manager dort drüben verwenden den Low-Level-Manager , den wir erstellt haben, Der Low-Level-Manager existiert jedoch für den Fall, dass Sie einen MCP-Client unabhängig verwenden möchten Aber generell gilt: Wann immer Sie in echtem Produktionscode einen Agenten erstellen, Sie in echtem Produktionscode einen Agenten erstellen einen MCP-Server verwenden möchte , wird dieser Agent wahrscheinlich als Teil eines Frameworks erstellt, und dieses Framework hätte eine Art Bibliothek für MCP-Verbindungen, die ihm hilft, diese MCB-Verbindung effizient zu verwalten, okay ? und dieses Framework hätte eine Art Bibliothek für MCP-Verbindungen, die ihm hilft, diese MCB-Verbindung effizient zu verwalten, effizient Wir werden hier also MCP-Toolsets verwenden, weil das heißt , wissen Sie, in ADC ist ein Toolset eine Sammlung von Tools, die ein Agent verwenden kann, und MCP-Toolsets helfen uns, diese Verbindung mit MCP-Servern sehr, sehr einfach zu verwalten . Also sagen wir für Namenskomma-Informationen in Punktelementen der Serverkonfiguration, das heißt, Sie wissen schon, MCP-Server, die wir haben, genau wie wir es im Low-Level-MCP-Manager getan haben, werden wir Serverparameter und SDD-IO-Serverparameter erstellen . Dann werden wir es den Verbindungsparametern als Verbindungsparameter zur Verfügung stellen , und das wird der MCP-Toolset-Klasse zur Verfügung gestellt zur Verfügung gestellt Wie Sie nun sehen können, werden die SDD-IO-Serverparameter aus MCP importiert , von den SDD-IO-Verbindungsparametern aus dem Google Agent Development Kit verwendet und dann wiederum dem MCP-Toolset zur Verfügung gestellt, um die MCP-Verbindung zu initiieren und zu verwalten Jetzt haben wir endlich das MCP-Toolset, das die SDD-IO-Verbindung automatisch verarbeitet . Und wieder verwenden wir die SDD-IO-Serverparameter Dann übergeben wir sie an die SDD IO Connection Params. Dies ist aus dem Google Agent Development Kit. Und schließlich übergeben wir es an den MCP Toolset-Klassenkonstruktor, um dieses Toolset zu erhalten Jetzt führen wir awittolset dot cd tools aus, und das ist der Erkennungsprozess. Also rufen wir die Tools ab, um die Verbindung zu überprüfen und sie dem Benutzer in einer echten App anzuzeigen Das LLM Aber da wir es dem Benutzer zeigen wollen, rufen wir diese Funktion auf und sagen, dass wir, wenn Tools verfügbar sind, nette Tabelle erstellen, die wir in der Demo gesehen haben, und wir werden den Namen und die Beschreibung der Tools wie folgt anzeigen Also sagen wir Werkzeugpunktbeschreibung und wir verwenden den Namen des Werkzeugpunkts und wir erstellen eine Tabelle mit allen Werkzeugen. In Ordnung. Diese Tools haben wir aus dem Toolset Dot Get Tools bekommen Und zum Schluss drucken wir noch einmal einige Informationen über erfolgreiche Verbindungen auf der Konsole einige Informationen über erfolgreiche Verbindungen und laden die Tools Und wir führen hier eine Ausnahmebehandlung durch. Jetzt haben wir gerade das MCP-Toolset bekommen. Wir wollen jetzt den Agenten erstellen, den wir abfragen können. Das ist also ein dritter Schritt. Wir werden den Agenten des Agent Development Kit initialisieren Agenten des Agent Development Kit Und wie ich bereits erwähnt habe, werden wir die LLM-Agentenklasse verwenden Das ist das Gehirn. Wir sagen ihm, wer es ist, welches Modell es verwenden soll. Wir geben ihm die Anweisungen und die Werkzeuge. Und das bildet dann den Agenten für uns. Also werden wir die LLM-Agentenklasse verwenden. Wir geben ihm einen Namen. Wir geben ihm ein Modell. Wir geben ihm Anweisungen. Sie sind ein hilfreicher Assistent, der die bereitgestellten Tools von MCP-Servern verwendet der die bereitgestellten Tools von MCP-Servern , um Benutzeranfragen zu beantworten Und wir geben ihm direkt das MCP-Toolset. Wir müssen also nicht anrufen, wissen Sie, CP-Toolsets werden nicht abgerufen. Wir geben ihm einfach die Toolsets und wir bekommen ein Agentenobjekt Um das Agent-Objekt auszuführen, brauchen wir einen Runner, oder? Also verwenden wir den In-Memory-Runner für, wissen Sie, welcher für die Schleife verantwortlich ist, in der der Agent läuft, richtig? Es nimmt also die Benutzereingaben entgegen, sendet sie an den Agenten und prüft, ob der Agent ein Tool aufrufen möchte. Dann führt es das Tool aus und sendet die Ergebnisse zurück an die Alterstoilette Seine Schleife ist eine Art Schleife hier drüben, die im Grunde all diese Aspekte abarbeitet und dann die gesamte Anfrage und die Antwort usw. verwaltet. Sie haben also das Runner-Objekt hier drüben. Es ist ein In-Memory-Runner. Es nimmt hier einen Agenten und einen App-Namen auf und gibt Ihnen ein Runner-Objekt. Jetzt werden wir eine Konversationssitzung beginnen. Auch hier handelt es sich um ein Konzept zur Agentenentwicklung. Was wir hier also tun werden, ist, dass Sitzungen es dem Agenten ermöglichen, sich an den Kontext früherer Nachrichten zu erinnern . Also werden wir Runner Dot Session Service sagen. Der Runner selbst hat also einen Sitzungsdienst, und dann werden wir eine Sitzung erstellen. Und das ist eine Sitzung , die wir hier haben, und das ist eine Konversationssitzung, richtig? Wir geben ihr einen Namen für die App. Wir stellen eine Benutzer-ID zur Verfügung. Jetzt weiß die Sitzung, dass es sich um eine Sitzung handelt , die zu dieser App und dieser Benutzer-ID gehört, und sie merkt sich die Konversation, in einem Lauf der Anwendung stattfindet. Die vergangenen Nachrichten müssen also nicht immer wieder verwaltet oder gesendet werden. Die Framework-Sitzung des Agent Development Kit selbst wird all diese Komplexität bewältigen. Aus unserer Sicht müssen wir, während wir gleichzeitig etwas über Model Context Protocol und Agent Development Kit lernen Model Context Protocol und , nur verstehen, dass wir, wissen Sie, im Grunde eine Konversationssitzung starten , die einen Runner verwendet, und der Runner selbst verwaltet im Grunde, Sie wissen schon , den Agenten-Lebenszyklus, und er nimmt diesen Agenten auf , der ein LLM-Agent hier drüben. So fließt es also nach unten. Sobald wir die Sitzung eingerichtet haben, können wir mit der Sitzung arbeiten, um sie abzufragen, richtig. Also starten wir jetzt eine interaktive Chat-Schleife in der Befehlszeilenschnittstelle selbst, der CmdTpv-Datei Also sagen wir wild true, und jetzt haben wir eine Abfrage Wir können also eine Abfrageaufforderung mit der Benutzerbezeichnung dort drüben anzeigen der Benutzerbezeichnung dort drüben und den Benutzer auffordern, eine Eingabe einzugeben. Wenn der Benutzer Exit oder Quit sagt, unterbrechen wir diese Schleife und beenden den Vorgang. Wenn es keine Abfrage gibt, drücken wir einfach die Eingabetaste in einer leeren Zeile. Wir fahren einfach mit der nächsten Iteration fort. Und dann sagen wir, der Console Dot Status Agent denkt nach. Wenn wir also die Anfrage erhalten, nehmen wir an, wir bekommen eine Anfrage, um etwas zu tun, wir sagen einfach, dass der Agent denkt und jetzt starten wir den Agentenfluss hier drüben, richtig? Nun benötigt das Agent Development Kit ein bestimmtes System, um mit dem Agenten zu kommunizieren. Wenn wir also eine Anfrage vom Benutzer erhalten, können wir sie einfach nicht direkt an den Agenten weiterleiten. Wir werden also Typen mit Punktinhalt verwenden und die Rolle user angeben, die nur besagt, dass diese Anfrage von einem Benutzer kommt, nicht vom KI-Modell. Dann stellen wir einen Inhaltsteil bereit, bei dem es sich um Punkte aus Text handelt. Es ist also ein Textteil und der Text ist die Abfrage selbst. Im Wesentlichen sagen wir, dass wir einen Text haben , den wir an den Agenten senden möchten. Wir signieren ihn von der Textfunktion aus in die Texteigenschaft hier drüben. Und wir erstellen hier ein Punktteilobjekt vom Typ , das wir dem Inhaltsobjekt zur Verfügung stellen. Aus der Perspektive des Kennenlernens von MCP und ADK wollen wir also nur verstehen, dass wir nur verstehen müssen, dass wir eine Abfragezeichenfolge nicht direkt an die Framework-Sitzung des Agent Development Kit übergeben können Framework-Sitzung des Agent Development Kit Wir müssen also ein Inhaltsobjekt erstellen , das vom Agent Development Kit bereitgestellt wird Das erfordert zwei Dinge. Das eine ist die Rolle, also der Benutzer, und das andere ist ein Teil. Hier ist der Teil ein Textteil, und der Weg, ihn bereitzustellen, besteht darin, diese spezielle Methode zu verwenden Wir verwenden die Textabfrage, wir verwenden den Text aus dem Text für den Teil, und dann erstellen wir diesen Teil hier drüben. Wir stellen ihn hier als einen Punkt in einer Liste zur Verfügung. Jetzt wollen wir eine Antwort erhalten, daher ist der Antworttext hier leer. Wir nennen Runner Dot im Grunde Run Acing. Runner verwaltet jetzt den gesamten Lebenszyklus des Sendens der Nachrichten und des Erhalts der Antworten. Das wird jetzt also asynchrone Ereignisse zur Folge haben, oder? Es ist ein asynchroner Generator, diese Ereignisse ausgibt, Textblöcke überprüft, Tools aufruft usw. Textblöcke überprüft, Tools aufruft Also gehen wir jedes Ereignis durch, das hier generiert wird, und wir werden es später erneut verarbeiten Und nur um hier zu bestätigen, dass Runner dot run Async unsere Benutzer-ID verwendet Es nimmt den Verweis auf die Sitzung unter Verwendung der Sitzungspunkt-ID und nimmt den Inhalt , und nimmt den Inhalt wir an die Abfrage senden möchten, der in ein Objekt mit vollem Inhalt verpackt ist , das ADC erwartet, oder? Dann können Sie Rana Run Async aufrufen. Es wird eine Reihe von Ereignissen ergeben, und wir werden jedes Ereignis nehmen und verarbeiten. In Ordnung. Nun, wenn das Ereignis veröffentlicht wird, hat es auch Inhalt, und zwar Teile, die wir oben gesehen haben , als wir den Inhalt der Abfrage generiert haben, richtig? Nun, das ist der Inhalt des Ereignisses, der vom Agenten zurückgegeben wird. Also schauen wir uns nur die Teile an. Also überprüfen wir, ob das zurückgegebene Event-Objekt Inhalt enthält, und wenn das einige Teile enthält, gehen wir jeden Teil dieses Inhalts durch. Und wenn der Teil Text enthält, sagen wir, dass der Antworttext der P-Punkt-Text ist, und wir hängen ihn an den Text mit dem Unterstrich der Antwort an Das gibt uns also den Antworttext und kombiniert ihn aus allen Ereignissen , die wir zurückerhalten haben Wenn wir nun endlich einen Antworttext haben, sagen wir einfach Punktdruck auf der Konsole, Antworttext für den Antworttest, und wir geben einfach einen Titel hinzu, der Antwort des Agenten lautet, und wir fügen einen schönen Rahmen hinzu. Das ist also die ganze nette Formatierung , die Sie in der Demo gesehen haben. Andernfalls sagen wir, dass eine Antwort ohne Textnachricht eingegangen ist. Auch hier gibt es einige grundlegende Ausnahmebehandlungen , oder? Nun, das ist das Ganze für die Befehlszeilenschnittstelle. Und nur um noch einmal zu verdeutlichen, was ist der Unterschied zwischen cmd dot PY und dem Low-Level-Manager hier drüben. Versuchen wir also, den Unterschied zwischen dem Manager und der Cmd Dot PY-Datei zu verstehen zwischen dem Manager und der Cmd Dot PY-Datei Die Cmd Dot PY-Datei ist eine richtige Befehlszeilenschnittstelle. Es ist wie eine Mini-App. Das 8. ABSCHNITT 4 - Containerisierung Ihres MCP-Servers mit Docker: Hallo, alle zusammen. Heute werden wir also verstehen, wie wir unseren MCP-Server containerisieren und ihn mithilfe von Docker bereitstellen und ihn dann mit dem Cloud-Desktop verbinden können Bevor wir beginnen, möchte ich Ihnen einen Überblick darüber geben , was wir mit Hilfe eines MCP-Servers, der mithilfe von Docker containerisiert und mit dem Cloud-Desktop verbunden ist, tatsächlich erreichen Hilfe eines MCP-Servers, der mithilfe von Docker containerisiert und mit dem Cloud-Desktop verbunden ist, mithilfe von Docker containerisiert werden. Lassen Sie uns nun den Cloud-Desktop-Konfliktpunkt jcnFle durchgehen Cloud-Desktop-Konfliktpunkt jcnFle Hier haben Sie also einen Terminalserver, das ist nur ein Server, den wir unter MCP-Servern haben, und es gibt einen Befehl namens Docker , der Cloud im Grunde anweist, die Docker-Befehlszeilenschnittstelle zu verwenden , um Ihren MCP-Server zu starten zu Dann haben Sie eine Liste von Argumenten. Das ist also ein vollständiger Satz von Argumenten die an den Docker-Befehl übergeben wurden Jetzt haben wir Cloud geöffnet und wir sehen, dass wir hier ein MCP-Tool zur Verfügung haben . Wenn wir darauf klicken, heißt es, dass Sie einen Run-Befehl haben , den Befehl run terminal im Workspace-Verzeichnis, was die Beschreibung ist, die wir in der Terminalserver-PY-Datei bereitgestellt haben . Und wenn ein Terminal-Befehl eine Aufgabe ausführen kann, teilen Sie dem Benutzer mit, dass Sie dieses Tool verwenden werden, um sie zu erledigen, auch wenn Sie es nicht direkt Das ist also im Grunde eine Anweisung für Cloud, und dann haben Sie das Argument, das ist der auszuführende Befehl, der auszuführende Shell-Befehl, und dann haben Sie im Grunde die Befehlsausgabe oder eine Fehlermeldung , die zurückgegeben wird. Cloud sieht also den Docker-Container mit dem verfügbaren Server, und jetzt versuchen wir, ihn zu testen. In Ordnung. Also werde ich Claude bitten , eine Datei namens MCP Docker ServerSuccess Punkt TXT zu erstellen , und im Text habe ich erfolgreich einen Docker-Container mit einem MCP-Server gebaut einen Docker-Container mit einem MCP-Server Schauen wir uns also an, was das macht. Also gut, es heißt, das Tool vom lokalen Terminalserver ausführen lassen , und ich sage, erlaube diesen Chat hier drüben. Und dann heißt es, ich helfe Ihnen, die Datei mit dem Run Command-Tool zu erstellen . Und dann wird es immer ausgeführt der Befehl fordert Sie auf, das Ergebnis anzuzeigen. Schauen wir uns das an. Also der Befehl, den es ausgeführt hat, war echo und dann der Text, den wir ihm gegeben haben, und dann der Dateiname. Also sieht es bis jetzt gut aus. Und lassen Sie mich überprüfen, ob die Datei korrekt erstellt wurde. Es heißt also, Ergebnis des Befehls run vom tamilischen Server anzeigen , also führt es dann tatsächlich den Befehl cat für diese bestimmte Datei aus und erhält diese Ausgabe Und auf dieser Grundlage heißt es, dass die Datei erfolgreich erstellt wurde und dass sie den angegebenen Text enthält Also kann ich dir noch mit etwas anderem weiterhelfen? Also das ist alles, was wir von Claude wollten. Und jetzt schauen wir uns das auch selbst in unserem lokalen Verzeichnis auf unserem MacBook an, um zu sehen , ob sich das tatsächlich auf dem bereitgestellten Volume widerspiegelt oder nicht Ordnung. Also habe ich meinen Finder geöffnet Lassen Sie mich das Workspace-Verzeichnis öffnen. In Ordnung. Und Sie können sehen, dass ich diesen MCP Docker Server Success Dot TXT hier drüben habe diesen MCP Docker Server Success Dot , und ich kann ihn öffnen Und es gibt einen Text, der besagt, dass ich erfolgreich einen Docker-Container mit einem MCP-Server gebaut einem MCP-Server Und Sie können jetzt sehen, dass wir unseren Server in einen Container gesteckt haben unseren Server in einen Container gesteckt und diesen mit Cloud Desktop verwenden Das hilft uns im Grunde, unseren MCP-Servercode von der Umgebung zu isolieren unseren MCP-Servercode von , in der er läuft. In Ordnung. Also, bevor wir beginnen, eine sehr kurze Zusammenfassung dessen, was das Model Context-Protokoll ist MCP oder Model Context Protocol ist also ein neuer Standard, der es KI-Anwendungen wie Cloud Desktop ermöglicht , über sogenannte MCP-Server mit externen Datenquellen und Tools zu interagieren externen Datenquellen und Tools über sogenannte MCP-Server Es basiert auf einem Client-Server-Modell, bei dem MCP-Clients, die in Ihre KI-App eingebettet sind, Anfragen senden und MCP-Server die angeforderten Aufgaben ausführen Ganz gleich, ob es sich dabei um den Zugriff auf ein Dateisystem, die Verwaltung von Repositorys oder den Aufruf direkte Bereitstellung dieser MCP-Server auf Ihrem Hostsystem kann jedoch zu echten Kopfschmerzen führen, da Sie mit Problemen wie Abhängigkeitskonflikten konfrontiert werden Verschiedene Tools erfordern bestimmte Versionen von Programmiersprachen oder Bibliotheken Die komplexen Setups, bei denen die Serverumgebung manuell installiert und konfiguriert wird, sind zeitaufwändig Und es fehlt an Isolation. also den Server direkt auf Ihrem Host ausführen, besteht die Gefahr dass Ihr System unerwünschten Zugriffen oder Konflikten ausgesetzt Hier kommt also Docker ins Spiel. Und wenn Sie untergehen, können Sie diese nette Infografik auf ihrer Website sehen diese nette Infografik auf ihrer Docker packt diese Server in Container, die alle Abhängigkeiten kapseln und die Umgebung isolieren, wodurch die Konsistenz auf verschiedenen Plattformen gewährleistet wird Tools wie Docker Desktop, Docker Hub, Docker Scout und Docker Build Cloud arbeiten zusammen, um Entwicklung, Tests und arbeiten zusammen Bereitstellung zu optimieren. Jetzt haben Sie also im Wesentlichen den Client, der eine Verbindung zu MCP-Servern herstellt, die sich zusammen mit ihren Tools in ihrem eigenen Container befinden in ihrem eigenen Container . In Ordnung, gehen wir also zu unserem Terminalserver-Code. Und wir haben diesen Code das letzte Mal geschrieben und wir sehen, dass wir ein Terminalserver-Verzeichnis haben, in dem wir die Terminal-Underscore-Server-Dot-p-Datei haben , die im Grunde einen Run-Befehl enthält, und dieses Tool ist ein MCP-Tool mit diesem Decorator hier definiert Und das bedeutet im Grunde, dass Ihr MCP-Server dies als ein MCP-Tool erkennt , das dann Befehle auf dem Terminal ausführen kann , wie vom MCP-Client angefordert, und dann die Ausgabe der Ausführung des Befehls oder des Fehlers zurückgibt , was auch immer der Fall sein mag. Wenn es eine Ausnahme gibt, speichern wir diese im Cache und geben dann den Ausnahmetext als Zeichenfolge zurück Das ist es, worum es bei diesem Server geht. Gehen wir auch zum Terminal und überprüfen wir unsere Verzeichnisstruktur. Wie Sie wissen, haben wir in unserem Home-Verzeichnis ein Verzeichnis namens MCP erstellt in unserem Home-Verzeichnis ein Verzeichnis namens MCP Und wenn Sie eine LSL erstellen, werden Sie feststellen, dass wir drei Ordner haben: Clients, die unseren MCP-Client den wir in einem der anderen Videos erstellt haben, und den Serverordner , der den Terminalserver enthält, den wir gebaut haben und in diesem speziellen Video verwenden werden , und einen Workspace-Ordner, der der Arbeitsbereich für unseren Server ist , um alle Terminalbefehle auszuführen. Und dies dient im Grunde dazu, sicherzustellen, dass andere Dateien in unserem Dateisystem nicht von diesem Tutorial betroffen sind. Als Nächstes müssen wir Docker herunterladen. Suchen wir also nach Docker Desktop Download und klicken wir auf den Link docker.com, die offizielle Download-Website, und scrollen wir Und Sie finden diesen Link zum Herunterladen von Docker Desktop. Lassen Sie uns den Mauszeiger auf diese Schaltfläche und Sie werden die Optionen hier sehen Bitte laden Sie es für Ihr System herunter. Ich werde es für Mac Apple Silicon herunterladen. Warten wir eine Minute bis das heruntergeladen ist. In Ordnung. Ich habe es also schon einmal heruntergeladen, und sobald Sie es heruntergeladen haben, haben Sie eine DMG-Datei, die Sie einfach doppelklicken und dann die Docker-Anwendung in den Anwendungsordner hier ziehen die Docker-Anwendung in den Anwendungsordner und dort lassen Ich habe das also bereits installiert, und dann öffne ich es einfach in der Anwendung, gehe von hier aus zum Anwendungsordner, suche nach Docker und doppelklicke dann, um es zu Sobald Sie das geöffnet haben, können Sie sich anmelden. Andernfalls können Sie es tatsächlich überspringen, indem Sie hier klicken. Und jetzt haben Sie Ihren Docker-Desktop geöffnet, und falls Sie einige frühere Container haben, werden Sie sie möglicherweise hier sehen. In Ordnung. Also müssen wir zuerst eine Docker-Datei erstellen, um unseren benutzerdefinierten Terminalserver zu containerisieren Ändern wir also unser Verzeichnis den Terminalserver-Ordner und erstellen wir diese Docker-Datei Lassen Sie uns nun diese Docker-Datei im VS-Code öffnen, alles. Also hier haben wir unsere Docker-Datei. Das wird also unsere Docker-Datei sein, und ich habe Befehle hinzugefügt, um zu beschreiben, was in den einzelnen Zeilen getan wird, und wir werden das kurz durchgehen um zu verstehen, wie das funktioniert Also werden wir das offizielle Python 3.11 Slim Image als Basisimage für unser Python verwenden 3.11 Slim Image als Basisimage für unser Python Und das stellt im Grunde sicher, dass wir unser Python-en haben, das über 3.1 liegt, was für MCP erforderlich ist Dann setzen wir das Arbeitsverzeichnis innerhalb des Containers auf Slash-App und kopieren alle Dateien aus dem aktuellen Arbeitsverzeichnis auf unserem Host-Computer in dieses App-Verzeichnis im Das wird passieren, wenn wir diesen Talk of File ausführen. Also wird unser gesamter Code in den Container übertragen. Dann installieren wir alle erforderlichen Python-Pakete aus dem Anforderungsspeicher TXT. Wir exportieren den Code 5.000, sodass der Container eingehende Verbindungen annehmen kann, und sofern Sie keinen Grund haben, ihn zu ändern, können Sie ihn dabei belassen und dann haben wir endlich den Befehl für den Docker definiert, um unseren Server auszuführen, und das wäre Python und dann Terminal Underscore Server Punkt PI Und es startet im Grunde unseren benutzerdefinierten Terminalserver, wenn der Container gestartet wird. Das ist es also. Eine einfache Docker-Datei für uns. In Ordnung. Also was wir jetzt tun müssen, ist eine virtuelle Umgebung zu schaffen. Und nur für den Fall, dass Sie aus den vorherigen Videos verfolgt haben, hätten Sie dies bereits erstellt, aber wenn nicht, können Sie es erstellen, indem Sie einfach CD MCP servers terminal server eingeben , um in das Verzeichnis zu wechseln und dann Python Three vNV eingeben, wodurch im Grunde eine virtuelle Umgebung in diesem speziellen Verzeichnis erstellt wird in diesem speziellen Und jetzt können Sie die virtuelle Umgebung aktivieren, indem Sie den Quellpunkt nv Bins Activate eingeben Und jetzt können Sie MCP in dieser virtuellen Umgebung installieren , indem Sie PIP install MCP eingeben, und dann können Sie tatsächlich alle Anforderungen in die Anforderungsdatei DotXD schreiben , indem Sie PIP frees requirements dot TXT eingeben Gehen wir zum VS-Code und sehen uns unsere Anforderungen an die sehen Und das ist unsere TXT-Datei für unsere Anforderungen, und wir sehen, dass wir hier MCP haben. Und das wird von Docker benötigt, um alle Anforderungen im Docker-Container zu installieren alle Anforderungen im , sobald er Ordnung, jetzt werden wir das Docker-Image erstellen und dafür den Befehl Docker build verwenden Die Docker-Build-Befehle erstellen im Grunde das Docker-Image Der T-Terminalserver Docker kennzeichnet das Image mit dem Namen Terminalserver Der Punkt gibt grundsätzlich an , dass das aktuelle Verzeichnis das die Docker-Datei enthält, als Build-Kontext verwendet wird . Drücken wir die Eingabetaste Der Aufbau kann eine Weile dauern. Warten wir, bis alles, was benötigt wird, installiert und heruntergeladen ist. Es ist Zeit, es in den Cloud-Desktop zu integrieren. Diese Konfiguration teilt Cloud Desktop also mit , wie Sie Ihren benutzerdefinierten MCP-Server über Docker aufrufen Und das ist im Grunde dieselbe Konfigurationsdatei, die wir zuvor für unseren Server aktualisiert haben, ohne dass Sie zuerst Ihre Cloud-Desktop-Konfikt-JCN-Datei öffnen müssen und diese in Ihrem System suchen müssen, aber sie befindet sich im Allgemeinen an dieser Stelle auf einem MacBook und lassen Sie aber sie befindet sich im Allgemeinen an dieser Stelle auf einem MacBook Und das zeigt uns im Grunde den zuletzt verwendeten Cloud-Desktop-Konfigurationspunkt JCN und wir sehen, dass der Pfad korrekt ist. Hier drüben. Als Nächstes müssen wir den bestehenden Terminal-MCP-Server durch die neue Definition ersetzen , die den Container verwendet Ordnung. Lassen Sie uns jetzt die Cloud-Desktop-Konfiguration JCNFle durchgehen. Hier drüben haben Sie also einen Terminalserver, es ist nur ein Server, den wir unter MCP-Servern haben, und es gibt einen Befehl namens Docker, der Claude im Grunde sagt, dass er die Docker-Befehlszeilenschnittstelle verwenden soll, um Ihren es ist nur ein Server, den wir unter MCP-Servern haben, und es gibt einen Befehl namens Docker, der Claude im Grunde sagt, dass er die Docker-Befehlszeilenschnittstelle verwenden soll, um Ihren MCP-Server zu starten. Dann haben Sie eine Liste von Argumenten. Das ist also ein vollständiger Satz von Argumenten die an den Docker-Befehl übergeben wurden Sie haben also ausgeführt, dies wird einen neuen Container starten. Du hast mich, und das hält SDD IN im Grunde offen. Es wird benötigt, damit Claude Nachrichten über SDD IO senden und empfangen Und dann haben Sie den Dash RM, und das weist Docker im Grunde an, den Container automatisch zu entfernen, wenn er beendet wird Dadurch bleibt Ihr System sauber, sodass nach jedem Gebrauch keine Container übrig Und dann haben Sie Dasdash drin, was dem System im Grunde genommen ein Minimum hinzufügt Wenn E Docker-Container gleich true ist, was im Grunde eine Umgebungsvariable festlegt, Docker-Container innerhalb des Containers gleich true, und das MCP-Tool oder der MCP-Server könnte dies im Grunde überprüfen und sich in einer Container-Umgebung anders verhalten Dann haben Sie V, und das ist im Grunde ein Volume-Mount. Die linke Seite verwendet also die KI-Sprache MCP und Workspace. Dies ist im Grunde ein Workspace-Verzeichnis, und dies ist das Host-Verzeichnis Und was wir wollen, ist, dass wir es in ein bestimmtes Verzeichnis im Docker-Container mounten ein bestimmtes Verzeichnis im Docker-Container mounten Was Sie jetzt tun können, ist, dass Sie tatsächlich zum Terminalserver Punkt P gehen können tatsächlich zum Terminalserver Punkt P gehen . Und Sie können überprüfen , ob wir eine Tilda für das Home-Verzeichnis und SlapAs Workspace als den Pfad verwendet haben, den In der Welt der Docker-Container wird das im Grunde genommen zu Slash/McPlash Workspace mit Schrägstrich (Root) übersetzt Slash/McPlash Workspace mit Schrägstrich (Root . Anstatt also Benutzer und Ihren Benutzernamen zu schreiben, müssen Sie den Schrägstrich MCP Slash Workspace angeben müssen Sie den Schrägstrich MCP Slash Workspace angeben. Und das bedeutet dann, beide einfach zuzuordnen oder Ihr Host-Volume auf dem Docker-Container zu mounten auf Jetzt hat der Container also Zugriff auf Ihre echten Workspace-Dateien Wenn Ihr Terminalserver beispielsweise einen Befehl wie Shoot Slash MCP Slash Workspace ausführt , listet er tatsächlich Dateien aus Ihrem lokalen Schließlich haben Sie den Namen des Docker-Images, und es ist im Grunde der Name, den wir zuvor mit dem Befehl Docker build erstellt Diese Konfiguration sieht also gut aus, und wir haben bereits überprüft, ob diese Konfiguration im Cloud-Verzeichnis befindet Was wir jetzt tun können, ist, dass wir tatsächlich weitermachen und Cloud starten können . Wenn Sie Cloud bereits gestartet haben, schließen Sie es bitte und klicken Sie dann mit der rechten Maustaste auf das Symbol, um es zu beenden , sodass Sie es vollständig geschlossen haben. Anschließend können Sie es erneut öffnen, indem Sie hier darauf klicken Ordnung, großartig. Jetzt haben wir die Cloud geöffnet und wir sehen, dass wir hier ein MCP-Tool zur Verfügung haben. Wenn wir darauf klicken, heißt es, dass Sie einen Run-Befehl haben, dem es sich um einen Run-Terminal-Befehl im Workspace-Verzeichnis handelt. Dies ist die Beschreibung, die wir in der Terminalserver-PY-Datei bereitgestellt haben der Terminalserver-PY-Datei Und wenn ein Terminalbefehl eine Aufgabe ausführen kann, teilen Sie dem Benutzer mit, dass Sie dieses Tool verwenden werden, um sie zu erledigen, auch wenn Sie es nicht direkt ausführen können. Das ist also im Grunde eine Anweisung für Cloud und dann haben Sie das Argument, das ist der auszuführende Befehl, der auszuführende Shell-Befehl, und dann haben Sie im Grunde die Befehlsausgabe oder eine andere Nachricht , die zurückgegeben wird. Claude sieht also den Container mit dem verfügbaren Server, und jetzt wollen wir versuchen, ihn zu testen. In Ordnung. Also werde ich Claude bitten , eine Datei namens MCP Docker ServerSuccess Punkt TXT zu erstellen , und im Text habe ich erfolgreich einen Docker-Container mit einem MCP-Server gebaut einen Docker-Container mit einem MCP-Server Schauen wir uns also an, was das macht. Ordnung, es heißt also, dass das Tool vom lokalen Terminalserver ausgeführt werden darf, und ich sage, erlaube diesen Chat hier. Und dann heißt es, ich helfe Ihnen, die Datei mit dem Run Command-Tool zu erstellen die Datei mit dem Run Command-Tool Und dann werden immer die Befehle ausgeführt , in denen ich aufgefordert werde, mir das Ergebnis anzusehen. Schauen wir uns das an. Also der Befehl, den es ausgeführt hat, war echo und dann der Text, den wir ihm gegeben haben, und dann der Dateiname. Also sieht es bis jetzt gut aus. Und lassen Sie mich überprüfen, ob die Datei korrekt erstellt wurde. Es heißt also, Ergebnis des Befehls run vom tamilischen Server anzeigen , also führt es dann tatsächlich den CAT-Befehl für diese bestimmte Datei und erhält diese Ausgabe Und auf dieser Grundlage heißt es, dass die Datei erfolgreich erstellt wurde und dass sie den angegebenen Text enthält Also kann ich dir noch mit etwas anderem weiterhelfen? Also das ist alles, was wir von Claude wollten. Und jetzt schauen wir uns das auch selbst in unserem lokalen Verzeichnis auf unserem MacBook an, um zu sehen , ob sich das tatsächlich auf dem bereitgestellten Volume widerspiegelt oder nicht Ordnung. Also habe ich meinen Finder geöffnet Lassen Sie mich das Workspace-Verzeichnis öffnen. In Ordnung. Und Sie können sehen, dass ich diesen MCP Docker Server Success Dot hier drüben habe, und ich kann ihn öffnen Und es gibt einen Text, der besagt, dass ich erfolgreich einen Docker-Container mit einem MCP-Server gebaut einem MCP-Server Und Sie können jetzt sehen, dass wir unseren Server in einen Container gesteckt haben unseren Server in einen Container gesteckt und diesen mit Cloud Desktop verwenden. Das hilft uns im Grunde, unseren MCP-Servercode von der Umgebung zu isolieren unseren MCP-Servercode , in der 9. ABSCHNITT 5 – Vereinfachung von Clientcode mit LangGraph und LangChain: Hallo zusammen. Heute werden wir einen MCP-Client mit Lang Chin MCP-Adaptern Langchin macht es sehr einfach, Ihren eigenen MCP-Client zu erstellen, und ich werde alle Schritte behandeln, um den MCP-Client zu erstellen und ihn mit dem Lang Graph Agent zu verbinden Bevor ich anfange, möchte ich Ihnen eine einminütige Vorschau darauf geben , was wir heute mit dem Lang Chin MCP-Client erreichen werden heute mit dem Lang Chin MCP-Client erreichen Vertrauen Sie mir, es ist ziemlich erstaunlich, dass Sie Lang Chains MCP-Adapter verwenden können , um eine sehr einfache Implementierung eines Clients durchzuführen und mit allen Toolaufrufen eine Verbindung zur Gemini-API Und das alles kann kostenlos gemacht werden, da Gemini Ihnen einen kostenlosen API-Schlüssel zur Verfügung stellt. Also los geht's Also werden wir unseren MCP-Client bitten, eine Datei zu erstellen und etwas Text hinzuzufügen, und lassen Sie uns sehen, wie das funktioniert Drücken wir die Eingabetaste. In Ordnung. Also das bedeutet, dass unser MCB-Client jetzt angefangen hat. Lassen Sie uns eine Anfrage stellen. Lassen Sie also die Abfrage B zum Langhin MCP-Client oder TXT machen und fügen Sie den Text hinzu, den ich mit Lang Chin erfolgreich mit Smiley für einen MC-Client erstellt habe mit Lang Chin erfolgreich mit Drücken wir also die Eingabetaste. Also, Sie können die Antwort hier sehen und wir haben die menschliche Botschaft, die besagt, Make File Lang Chain MCP Client oder DHT Und das ist im Grunde die Anfrage, die wir gesendet haben. Und dann haben wir eine KI-Nachricht, die keinen Inhalt hat. Dann haben wir eine Werkzeugnachricht, und das wäre ein Tool-Call gewesen. Sie können die Antwort tatsächlich einfach direkt ausdrucken , um weitere Details zu sehen. Ich drucke gerade den Inhalt hier mit meinem benutzerdefinierten Encoder Und dann haben Sie endlich die AI-Nachricht mit dem Inhalt, der besagt: Okay, ich habe die Datei Lang Chain CP Client Dot TXT erstellt und den Text hinzugefügt, den Sie angegeben haben, etwas anderes Schauen wir uns das jetzt einfach an. Suchen wir nach einem und ich habe mein MCB-Verzeichnis hier geöffnet. Ich gehe in meinen Arbeitsbereich und sehe, dass ich Lang Chain MCB Client Punkttext habe, und Sie können sehen, dass der Text hinzugefügt wurde , nach dem ich gefragt habe, und das funktioniert erstaunlich gut In Ordnung, also eine kurze Zusammenfassung dessen, was MCP ist. MCP beginnt also mit dem Model Context Protocol und bietet im Grunde genommen eine Möglichkeit für große Sprachmodelle, sich mit externen Tools und Diensten zu verbinden Es gibt einige grundlegende Komponenten wie MCP-Server, die Kontexttools bereitstellen und die Clients dazu auffordern Sie können beispielsweise einen MCP-Server mit einem Tool zum Addieren oder Dividieren von Zahlen haben , und er kann auch Ressourcen wie Daten bereitstellen Es gibt MCP-Clients, und die Clients halten eine Verbindung den Servern innerhalb einer Host-App aufrecht, und es gibt Clients, die Sie in Python erstellen können Sie können die Cloud-Desktop-App als Client verwenden, und wir werden heute unseren eigenen Client in Python mit Lang-Chains-MCP-Adaptern erstellen heute unseren eigenen Client in Python mit Lang-Chains-MCP-Adaptern MCP-Clients können die Server tatsächlich auffordern, Tools aufzurufen oder auszuführen und die Ergebnisse als Client bereitzustellen Die Clients stellen hier eine Verbindung mit dem Lag-Sprachmodell her, wir werden den Lang-Graph-Agenten verwenden, und der Langraph-Agent kann tatsächlich Adapter verwenden, um eine Verbindung zu diesem bestimmten Client und die verfügbaren Tools zu laden, Terminal zurückzukehren und eine Umgebungsvariablendatei zu erstellen , indem Sie Touch Dot NV eingeben und die Eingabetaste drücken Ich habe diese Datei bereits hier, also werde ich sie einfach mit NaNo öffnen und wie Sie sehen, habe ich apiksGemini APIke und Google APIke definiert und meinen Schlüssel hier eingefügt. Sie können diese Zeile tatsächlich hier drüben schreiben und Ich habe zwei Umgebungsvariablen verwendet, Google ApiKey und Gemini APIke , weil ich in meinem persönlichen Projekt gerne die Umgebungsvariable Gemini APIKey verwende Lang Chin erwartet jedoch, dass der Schlüssel unter einer Umgebungsvariablen namens Google APIK vorhanden Umgebungsvariablen Nur um Verwirrung zu vermeiden und die Verwendung beider Variablen zu ermöglichen, habe ich den Schlüssel tatsächlich zweimal mit zwei Umgebungsvariablennamen definiert zweimal mit zwei Umgebungsvariablennamen Und du kannst das Gleiche tun. Für Lang Chain müssen Sie Google API verwenden, Control X drücken und die Datei speichern, bevor Sie sie beenden Jetzt haben Sie also Ihre Umgebungsdatei eingerichtet. Jetzt können wir also eine virtuelle Umgebung erstellen , die uns im Grunde hilft, unsere Projektabhängigkeiten von allen anderen Arbeiten, die wir an einem Computer erledigen, zu trennen , source dot NV slashBN slash Activate Und damit betreten Sie im Grunde die virtuelle Umgebung des MCP-Clients Okay, jetzt werden wir einige Pakete hinzufügen, die wir für die Entwicklung unseres MCP-Clients benötigen Diese Pakete sind Lang Chin, die Lang Chin MCP-Adapter, Lang Graph, Lang Chin Google Gen AI-Paket, das Google Genitive AI-Paket und das Python Environment-Paket für die Umgebungsvariablen Nachdem Sie die UV-Anzeige und die Liste der Pakete geschrieben haben , drücken Sie die Eingabetaste . Ich habe es bereits installiert, aber es dauert einige Sekunden oder Minuten, bis es installiert ist Und sobald das installiert ist, sind wir bereit, tatsächlich mit dem Schreiben unseres Angchinmcp-Clients Dot PII zu beginnen Schreiben unseres Angchinmcp-Clients Code vom Typ N und der Dateiname, und das wird im Grunde genommen im VS-Code geöffnet Ordnung. Fangen wir an, über die Punkt-PY-Datei für den Lang-CB-Client zu sprechen und darüber, wie sie funktioniert. Also werde ich hier mit den Importen beginnen, und wir haben einige Standardimporte für asynchrone Operationen, für den Zugriff auf die Umgebungsvariablen, für die Verarbeitung von Befehlszeilenargumenten und andere Dann importieren wir die MCP-Client-bezogenen Pakete für die Sitzungsverwaltung sowie für die Einrichtung und den Start des Servers Und das wird verwendet, um tatsächlich eine Verbindung zum MCB-Server herzustellen. Jetzt haben wir den Ang Chin Agent und die LLM-Importe. Wir haben die Load MCP-Tools. Dies wird im Grunde verwendet, um die MCP-Tools korrekt zu laden. Dann haben wir den vorgefertigten React Agent von Lang Graph und wir haben den Google Gemini LLM-Wrapper Schließlich laden wir die Umgebungsvariablen mit Load Underscore Dot ENV aus dem Dot ENV-Paket Das sind also im Grunde alle Ihre Importe, und jetzt können wir tatsächlich direkt zum LLM übergehen . Wir verwenden im Grunde das generative KI-Paket von Google für den Chat , das wir importiert haben, und die Instanziierung des LM ist genauso einfach wie die Verwendung von generativer Chat-KI von Google mit einem bestimmten Modellnamen, also verwenden wir hier Gemini 1.5 P. Du kannst tatsächlich auch Two Point Oh verwenden. Sie haben die Temperatur , die wir für eine vollständig deterministische Ausgabe auf Null gesetzt haben für eine vollständig deterministische Ausgabe auf Null Sie können sie also grundsätzlich erhöhen, um die Leistung kreativer zu gestalten Dann haben Sie die maximale Anzahl von Wiederholungen, die hier zwei Im Grunde werden die API-Aufrufe automatisch bis zu zweimal wiederholt, um Fehler aller Art zu Und dann hast du den Google-API-Schlüssel. Langhin verwendet also im Grunde den Google-API-Schlüssel in einer Variablen, um diesen Schlüssel zu laden und Zugriff auf die Gemini-API zu gewähren Okay, hier überprüfen wir nur, ob wir die richtige Anzahl von Argumenten für ein Python-Skript bereitgestellt haben die richtige Anzahl von Argumenten für ein Python-Skript bereitgestellt . Als Nächstes haben wir die MCP-Serverparameter. Wir konfigurieren diese Parameter, indem wir den Befehl bereitstellen , der Python ist und tatsächlich ein Serverskript haben kann , das mit PI für ein Python-Skript endet. Andernfalls gehen wir davon aus, dass es sich um einen Knoten oder Jspace handelt, und geben den Serverskriptpfad an, den wir tatsächlich durch den Python-Programmaufruf hier erhalten haben Dann haben wir also eine globale Variable die aktive MCP-Sitzung, und wir werden sie mit dem Tooladapter verwenden , den wir uns ansehen werden, wenn wir den Code durchgehen. Okay, dann gehen wir runter zur Funktion „Agent ausführen“. Das ist unsere Hauptfunktion , die die ganze Arbeit erledigt. Es öffnet im Grunde eine Verbindung zum MCP-Server. Es startet die MCP-Sitzung, speichert die Sitzung für den Toolzugriff und lädt diese Tools mit dem MCP-Tool Sie haben also im Grunde Ihren Server, Ihre MCP-Sitzung und Ihre Tools neu gestartet, dann wird es einen Agenten erstellen und diesem Agenten diese Tools zur Verfügung stellen Und schließlich wird es in eine Schleife geraten, der der Benutzer aufgefordert wird, eine Anfrage zu stellen, und dann wird der Agent asynchron aufgerufen und die Antwort als gut formatiertes Jason ausgegeben es noch einmal zu wiederholen, wir haben im Grunde die Verbindung zum Server Wir haben eine MCP-Sitzung eingerichtet. Wir haben die Tools eingerichtet und dann erstellen wir im Grunde einen Agenten mit diesen Tools und verarbeiten dann die Benutzeranfragen und die Druckerantwort Das sind im Grunde alle Schritte, die wir machen werden. Und um das zu tun, hier ist der Code. Wir erhalten also im Grunde die Lese - und Schreibeigenschaften für den Server mithilfe des SED-IO-Clients und des oben definierten Servermusters . Mithilfe von Lesen und Schreiben erstellen wir tatsächlich die Sitzung des Clients und speichern sie als Sitzung. Anschließend initialisieren wir die Sitzung mit Session Dot Initialize und dann verwenden wir die globale MCP-Clientvariable ein einfaches Objekt, das diese spezielle Sitzung enthält Jetzt laden wir die MCP-Tools mit dem Adapter von Lang Chain Das ist also im Grunde eine sehr einfache Implementierung. Wenn Sie das vorherige Video über die Implementierung eines MCP-Clients mit der Gemini-API gesehen haben , wissen Sie, dass wir dort viele Konvertierungen vorgenommen haben, um die Konvertierung von einem MCP-Tools-Format in das Gemini-Format zu verwalten MCP-Tools-Format in das Gemini-Format zu Aber Ang Chin macht es einfach indem es Load-MCP-Tools verwendet, und wir haben hier direkt eine Liste Jetzt haben wir endlich die Tools und das LLM , das wir oben mit dem Google-API-Schlüssel definiert haben , das wir oben mit dem Google-API-Schlüssel definiert Wir verwenden das, um einen sogenannten React-Angrap-Agenten zu erstellen , den wir hier als Agenten speichern Wir geben aus, dass wir den MCP-Client gestartet haben und Quid eingeben können, um den Vorgang zu beenden, und dann gehen wir in eine Schleife und fordern den Benutzer eine Anfrage zu stellen, sobald wir die Abfrageeingabe erhalten. Wir erzeugen tatsächlich eine Antwort, indem den Agenten mit der Funktion Asynchrons invoked aus der Lang-Kette aufrufen Funktion Asynchrons invoked aus der Lang-Kette und Da dieser Agent bereits alle Tools und das Modell kennt , die wir verwenden, bietet uns Lang Chain die Implementierung, diese Anfrage an Gemini zu senden, die Tool-Aufrufe zu verstehen und dann die Tools mit diesen Adaptern für uns auszuführen, und so einfach ist es, dann die Antwort zu erhalten. Schließlich formatieren wir den JSON mit dem benutzerdefinierten Encoder, den wir oben definiert haben . Sie können es sich ansehen Es druckt die Ausgabe im Grunde genommen gut formatiert, und das vervollständigt unsere Run-Agent-Funktion Das ist also eine einfache Erklärung des gesamten Codes. Und noch einmal, wenn Sie die vorherigen Videos zur Erstellung des MCP-Clients ohne Lang Chin verfolgt haben , können Sie feststellen, dass dies viel, viel einfacher ist, und das ist einer der Hauptvorteile der Verwendung von Lang Chain hier Jetzt können wir diesen Agenten tatsächlich testen , indem wir zum Terminal gehen Deshalb haben wir unsere Client-Datei Lang Chain MCP client dot PY genannt , sodass Sie UV run und den Client-Dateinamen eingeben und dann den Python - oder den Javascript-Serverdateinamen angeben oder den Javascript-Serverdateinamen Für unsere Situation gehen wir also in unseren Serverordner, gehen wir also in unseren den ich Ihnen gerade am Anfang gezeigt habe, und gehen zum Terminalserver und zur Terminalserver-PY-Datei über den Terminalserver der Sie Befehle in Ihrem Terminal ausführen Also werden wir unseren MCP-Client bitten, eine Datei zu erstellen und etwas Text hinzuzufügen, und lassen Sie uns sehen, wie das funktioniert. Drücken wir die Eingabetaste Ordnung. Also das bedeutet, dass unser MCB-Client jetzt angefangen hat Lassen Sie uns eine Anfrage stellen. Lassen Sie also die Abfrage B zum Lang Chin MCP-Client oder TXT machen und fügen Sie den Text hinzu, den ich mit Lang Chin erfolgreich als MCB-Client erstellt habe , A mit Drücken wir also Enter Right, damit Sie die Antwort hier sehen können und wir haben die menschliche Botschaft, die besagt, Make File Lang Chain MCP Und das ist im Grunde die Anfrage, die wir gesendet haben. Und dann haben wir eine KI-Nachricht, die keinen Inhalt hat. Dann haben wir eine Werkzeugnachricht, und das wäre ein Tool-Call gewesen. Sie können die Antwort tatsächlich einfach direkt ausdrucken , um weitere Details zu sehen. Ich drucke gerade den Inhalt hier mit meinem benutzerdefinierten Encoder Und dann haben Sie endlich die AI-Nachricht mit dem Inhalt, der besagt: Okay, ich habe die Datei Lang Chain CP Client Dot TXT erstellt und den Text hinzugefügt, den Sie angegeben haben, etwas anderes Schauen wir uns das jetzt einfach an. Suchen wir nach einem und ich habe mein MCB-Verzeichnis hier geöffnet. Ich gehe in meinen Arbeitsbereich und sehe, dass ich Lang Chin MCB-Client Punkttext habe, und Sie können sehen, dass der Text hinzugefügt wurde , nach dem ich gefragt habe, und das funktioniert erstaunlich gut So können Sie also einen MCP-Client mit Lang Chin erstellen einen MCP-Client mit Lang Chin Im Grunde bietet es Wrapper für alle Arten von KI-Modellen und für die MCP-Verbindungen, was uns hilft, die Implementierung des Codes erheblich zu vereinfachen Implementierung des Und Sie würden das bemerken, wenn Sie tatsächlich das Video gesehen haben, in dem Sie Ihren MCP-Client ohne Lang Chin erstellen, und dieses spezielle Video , in dem Sie mit Angin bauen Ihren MCP-Client ohne Lang Chin und dieses spezielle Video 10. ABSCHNITT 6 STARTEN Erstellen von MCP Client mit Unterstützung mehrerer Server: 6.1 Einführung: Jeder. Heute werden wir einen auf Lang Chin basierenden MCP-Client entwickeln , der eine JCN-Konfiguration für mehrere Server unterstützt Und so können wir tatsächlich eine Datei wie den Unterstrich der AI-Sprache Underscore Config Dot JCN bereitstellen den Unterstrich der AI-Sprache Underscore Config Dot JCN , die tatsächlich mehrere Server spezifizieren kann, ähnlich dem, was Sie für Clot Desktop haben Aber dieses Mal werden wir es selbst machen, indem wir Lang Chin oder Lang Graph für den Reaktionsagenten verwenden, und wir werden MCP und Google Gemini API für das große Sprachmodell verwenden, und wir werden das in Python tun 11. 6.2 Schauen wir uns die Datei config.json an: Lassen Sie mich Ihnen einfach den Beispielkonfliktpunkt jcnFle zeigen , den ich verwenden werde Hier drüben werden wir zwei MCP-Server definiert haben. Einer wird der Terminalserver sein , den wir zuvor in diesem Kurs erstellt haben, und der andere wird ein bereits vorhandener MCP-Server sein , den ich vorerst als Fetch verwende Sie können einen beliebigen MCP-Server auswählen, und ich werde tatsächlich den Docker-Befehl verwenden, um diese beiden Server auszuführen Und wir haben uns bereits angesehen, wie Sie einen Terminalserver erstellen und ihn in einen Docker-Container legen und ihn dann mit Ihrem eigenen Client verwenden können 12. 6.3 Demo - MCP-Client mit mehreren MCP-Servern: Bevor ich anfange, möchte ich Ihnen zeigen, wie das funktioniert. Und dafür gehe ich zum Terminal. Lassen Sie mich also zu unserem MCP-Verzeichnis wechseln, dann zu Clients, dann zu MCP-Client Lassen Sie mich dann unseren Lang-Chain-MCP-Client mit Conflict-PY ausführen mit Dies wird unseren MCP-Client starten. Und wie Sie sehen können, stellt es im Grunde eine Verbindung zum MCP-Server-Terminalserver her , unserem ersten MCP-Server, und lädt den Befehl zum Ausführen des Tools diese Weise können der MCP-Client und das LLM im Grunde Befehle auf dem Terminal auf dem lokalen Host-Computer ausführen Terminal auf dem lokalen Host-Computer Und dann heißt es, ich habe ein Tool vom Terminalserver geladen ein Tool vom Terminalserver Dann stellt es eine Verbindung zum MCP-Server Fetch her. Dies ist der bereits vorhandene Referenzserver aus dem Modellkontext-Protokoll Github und er lädt das Tool fetch, das grundsätzlich Inhalte von einer URL abrufen kann, und dann heißt es, ich habe ein Tool von fetch geladen Und dann heißt es, dass der MCP-Client bereit ist und dann gibt es quid ein, um den Vorgang zu beenden . Fragen wir den Kunden also zuerst welche Tools ihm zur Verfügung stehen. In Ordnung. Also, welche Tools stehen Ihnen zur Verfügung? In Ordnung. Also auf diese Anfrage, im Grunde die Antworten, dass ich Zugriff auf die folgenden Tools habe. Führen Sie den Befehl aus, um Terminalbefehle auszuführen und rufen Sie ihn ab, um Inhalte von einer URL abzurufen Lassen Sie uns nun eine Abfrage bereitstellen, um Inhalte von einer Wiki-URL abzurufen, sie dann zusammenzufassen und mit einem Terminalbefehl in eine Datei zu schreiben mit einem Terminalbefehl in eine Datei zu In Ordnung, also schreiben wir die Abfrage. Kannst du Inhalte von der Wiki-Seite für Flugzeuge abrufen, die ersten paar Zeilen, und eine Zusammenfassung des Inhalts in eine Datei namens Airplanes Dot TXT schreiben des Inhalts in eine Datei namens Airplanes Dot Lass uns die Eingabetaste drücken und sehen, was passiert. Ordnung, also habe ich hier explizit das Befehlstool Ausführen angegeben, da Gemini dies beim Schreiben des Inhalts anscheinend nicht erkennt dies beim Schreiben des Inhalts Okay, Leute, das ist die Antwort, die ich bekommen habe. Also da ist die Nachricht, die wir gesendet haben, und dann haben wir die Tool-Nachricht, die den Inhalt der Wikipedia-Seite über Flugzeuge enthält Und dann heißt es, dass Sie das Fetch-Tool tatsächlich mit einem Startindex von 500 aufrufen können , um mehr Inhalt zu erhalten, und das erledigt es dann Es heißt, dass der Inhalt gekürzt wurde. Ich werde weitere Inhalte abrufen, um eine Zusammenfassung bereitzustellen. Und das ist mehr Inhalt. Und dann wieder gibt es einen neuen Startindex und dann gibt es wieder mehr Inhalt. Und dann scheint es ein Verbindungsproblem gegeben zu und es konnte nicht mehr abgerufen Es heißt also, dass ich aufgrund von Kürzungs- und Verbindungsproblemen nicht den gesamten Inhalt der Wikipedia-Seite abrufen aufgrund von Kürzungs- und Verbindungsproblemen nicht den gesamten Inhalt der Wikipedia-Seite Kürzungs- und Ich habe jedoch die ersten Zeilen und hier ist eine Zusammenfassung des Abrufinhalts Und am Ende heißt es dann, dass ich das Runommand-Tool verwenden werde, um die Zusammenfassung zu speichern Und dann habe ich die ersten Zeilen von der Wikipedia-Seite für Flugzeuge abgerufen Wikipedia-Seite für Flugzeuge und eine Zusammenfassung des Inhalts erstellt. Ich habe das mit dem Run Command-Tool in eine Datei namens airplanes dot THD geschrieben mit dem Run Command-Tool in eine Datei namens airplanes dot THD Gehen wir also zum Finder und schauen uns diese Datei an. Also hier ist die Datei Airplanes Dot HD in unserem Workspace-Verzeichnis Und wenn wir direkt klicken, um sie zu öffnen, können wir sehen, dass es eine Zusammenfassung der Inhalte gibt, egal was sie hier abrufen konnte . Ein Flugzeug ist also ein Starrflügelflugzeug , das von einem Düsentriebwerk, Propeller oder Raketentriebwerk Propeller oder Sie sind in verschiedenen Größen, Formen und Flügelkonfigurationen und werden für Freizeit, Transport, Militär und Forschung usw. verwendet Transport, Militär und Forschung usw. Es scheint also so zu sein, dass es tatsächlich eine Zusammenfassung aller Inhalte geschrieben hat , die es von der Wikipedia-Seite abrufen konnte , und sie in eine Datei geschrieben hat, indem es sowohl fetch als auch das Run-Befehlstool Das ist also ziemlich erstaunlich. Jetzt haben wir unseren eigenen MCP-Client , der im Grunde mit der Google Gemini-API funktioniert Er kann tatsächlich Server auf der Grundlage einer Konfliktpunkt-cN-Datei verbinden und initialisieren und dann die Tools verwenden, um Aktionen auszuführen, indem der React-Agent von LangRapt einen Client mit dieser zusätzlichen Funktionalität robuster macht robuster 13. 6.4 MCP Client (mit JSON config) Code-Anleitung – Teil 1: Okay, lassen Sie uns nun den Code für diesen Client mit dem Confit durchgehen für diesen Client mit dem Also der Name der Datei für diesen Client ist Lang Chain MCP Wconfg dot py und W Config stehen im Grunde für W ConfIC. Dieser Code implementiert einen Lang-Chain-MCP-Client, der eine Konfiguration aus einer benachbarten Datei lädt, die durch die Umgebungsvariable AI-Sprachkonfiguration angegeben ist, und Verbindung zu einem oder mehreren MCP-Servern herstellt, eine Verbindung zu einem oder mehreren MCP-Servern herstellt, die in dieser Konfiguration definiert sind. Es lädt die verfügbaren MCP-Tools von jedem verbundenen Server und verwendet dann die Google Gemini-API über die Lang-Kette, um einen Reaktionsagenten mit Zugriff auf alle Tools zu erstellen. Anschließend wird eine interaktive Chat-Schleife ausgeführt, Anschließend wird eine interaktive Chat-Schleife ausgeführt in der Benutzeranfragen vom Agenten verarbeitet werden Jetzt baut dieser Client auf dem vorherigen Client auf , den wir auf der Lang-Chain NcpClientPy aufgebaut haben Falls Sie diesen speziellen Code noch nicht durchgegangen sind, schauen Sie sich bitte das vorherige Video an. In Ordnung. Zunächst verwendet dieser Client die Konfigurationsvariable AI Language Underscore, um den Pfad für die JCN-Datei mit dem AI-Sprachkonfliktpunkt anzugeben JCN-Datei mit dem AI-Sprachkonfliktpunkt Wenn dieser Pfad nicht festgelegt ist, verwendet er die Standarddatei, die im Code-Stammverzeichnis verfügbar ist, den AI-Sprachunterstrich Conflict Wenn Sie jetzt nach unten scrollen, haben wir die regulären Importe , die wir haben Wir haben unseren benutzerdefinierten Encoder. Dann definieren wir jetzt eine JSN-Funktion für Lesekonflikte, im Grunde die MCP-Serverkonfiguration Jason liest Und wieder versucht es, den Pfad aus der KI-Sprachumgebungsvariablen zu lesen , und wenn nicht self, wird auf eine Standarddatei zurückgegriffen, der AI-Sprachkonflikt oder Jason ist dasselbe Verzeichnis wie der Code Und es gibt ein Wörterbuch zurück, das hinter JSN-Inhalten mit MCP-Serverdefinitionen Dies ist der Versuch, die Umgebungsvariable zu lesen. Und wenn das nicht gesetzt ist, gibt es einen Fallback, um das Skriptverzeichnis abzurufen und dann den Dateinamen mit dem Skriptverzeichnis zu verknüpfen, und dann den Dateinamen mit dem Skriptverzeichnis zu verknüpfen um den tatsächlichen Dateipfad zu erhalten, dann öffnet es den Pfad, je nachdem, welchen es bekommt, entweder die Umgebungsvariable oder den Standardpfad, und es gibt die JSN zurück, die von dort geladen wurde. Wir behandeln Ausnahmen, um eine Fehlermeldung auszugeben und das Programm zu Dann instanziieren wir Google Gemini LLM. Ein Unterschied besteht darin, dass wir Gemini Two Point Oh Flash verwenden und dafür gibt es 14. 6.5 Warum sollten Sie Gemini 2.0 Flash und nicht die Pro-Modelle wählen?: Der Grund dafür ist, dass Sie tatsächlich auf atudiogle.com gehen und sich mit Ihrem Gmail-Konto anmelden Dann können Sie sich die verschiedenen Modelle hier ansehen können. Dann können Sie sich die verschiedenen Modelle hier ansehen. Gemini Two Point Oh Flash hat also eine Geschwindigkeitsbegrenzung für Anfragen pro Minute für 15 Anfragen pro Minute Wenn Sie sich einige der Pro-Modelle wie Gemini 2.5 Pro Experimental ansehen , hat es nur fünf Anfragen pro Minute Dies ist jetzt auch bei 1.5 P der Fall, das zwei Anfragen pro Minute hat. Das ist zu wenig für eine Agentenausführung, die möglicherweise mehrere Aufrufe pro Minute benötigt, aber wir erwarten nicht, dass mehr als 15 Anfragen pro Minute eingehen, was von Gemini Two Pinto Flash bereitgestellt wird, sodass wir mit dieser speziellen Modellauswahl zufrieden sind Das ist also ein Unterschied zum vorherigen Client, und dann haben wir den Google-API-Schlüssel, den wir laden 15. 6.6 MCP Client (mit JSON config) Code-Anleitung – Teil 2 (Fortsetzung): Lassen Sie die Funktion „Agent ausführen“ eine Verbindung zu allen in der Konfiguration definierten MCP-Servern herstellen, die Tools laden und aus dem Lang-Diagramm einen einheitlichen React-Agenten erstellen. Anschließend wird eine interaktive Schleife gestartet, um den Agenten abzufragen Dies ist anders als bei der vorherigen Client-Implementierung , bei der wir nur einen Server hatten, zu dem wir über ein Python-Skript eine Verbindung hergestellt haben. Also haben wir im Grunde zuerst das Confit gelesen. Dann holen wir uns im Grunde die MCP-Serverdefinitionen aus dem Confit, und wenn sich darin keine MCP-Server befinden, drucken wir im Grunde eine Fehlermeldung und definieren und initialisieren dann eine leere Liste, die alle Tools von den verbundenen Servern enthält, weil wir sie in einer einzigen Liste zusammenfassen wollen . Und jetzt verwenden wir diesen AsnceIT-Stack, um im Grunde mehrere Async-Ressourcen zu verwalten und sauber zu schließen, im Grunde mehrere Async-Ressourcen zu verwalten und sauber zu schließen, und iterieren über jeden in der Konfiguration definierten MCP-Server . Jetzt haben wir also im Grunde den Servernamen und die Serverinformationen mcpservers dot IM Wir haben also die MCP-Server aus der Confit-Datei geladen und schauen uns die Confit-Datei noch einmal an, um das noch einmal MCP-Server haben also diese Elemente, Element Nummer eins und Element Nummer zwei, und jedes Element hat einen Servernamen und dann es Informationen in Form von Befehlen Jetzt erhalten Sie also im Grunde den Servernamen , der im Grunde entweder Terminalserver oder Fetch entspricht , und Sie erhalten die Serverinformationen, die im Grunde allen Informationen entsprechen , die wir dagegen notiert haben, Befehl und den Argumenten Wir geben dann aus, dass wir mit einem bestimmten Namen eine Verbindung zum MCP-Server herstellen, und dann erstellen wir die STDIO-Serverparameter mit dem Befehl und den Argumenten, die für den Server angegeben Also geben wir den Befehl an , der in diesem Fall Docker für beide sein wird Und dann geben wir die Argumente so an, und für Docker verwenden wir im Grunde die Docker-Image-Datei Das gibt uns also im Grunde Serverparameter, die wir dann verwenden werden, um eine STD-IO-Verbindung zum Server herzustellen Also verwenden wir die Serverparameter und dann erhalten wir die Lese- und Schreibstream-Objekte für diesen bestimmten Server Wir durchlaufen also jeden Server in einer Schleife. Also führen wir für jeweils einen Server all diese Schritte durch Anschließend verwenden wir die Lese- und Schreibparameter , um eine Clientsitzung zu erstellen Anschließend initialisieren wir die Sitzung und laden dann die MCP-Tools in die Servertools Und für jedes Servertool informieren wir den Benutzer grundsätzlich darüber, dass wir das Tool mit einem bestimmten Namen geladen haben, und fügen es dann an unsere Liste der vereinheitlichten Tools an Sobald wir mit allen Tools für diesen speziellen Server fertig sind , sagen wir, dass wir im Grunde Tools von diesen bestimmten Servern geladen haben , und wir werden die Länge der Servertools verwenden , um anzugeben, wie viele Tools geladen wurden Dann setzt sich die Vierschleife für den nächsten Server fort, und auf diese Weise laden wir alle Tools in eine einzige einheitliche Toolliste , die wir dann an den Agenten weitergeben Ordnung. Dann haben wir eine grundlegende Fehlerbehandlung und danach erstellen wir im Grunde den Agenten, der ein React-Agent von Langrap ist , ein React-Agent von Langrap ist , und wir haben den LLM bereitgestellt, das ist die Google Gemini LLM-Instanziierung , die wir oben gemacht haben, zusammen mit der Dann starten wir eine interaktive Chat-Schleife wie wir es für unseren vorherigen MCP-Client getan haben, und dieser erwartet eine schnelle Anweisung, und dieser erwartet Andernfalls ruft es im Grunde den Agenten mit der vom Benutzer bereitgestellten Anfrage auf und druckt dann die Und dann haben wir natürlich den Einstiegspunkt hier drüben. Ordnung, das ist also alles über den Code für den Ankchin MCP-Client mit der JSON-Confit-Datei 16. 6.7 Verwenden vorhandener MCP-Server von MCP Github (Beispiel verwendet "fetch"-Server): Schauen wir uns nun die Konfigurationsdatei selbst an. Sie erinnern sich bestimmt an den Terminalserver aus den vorherigen Videos in diesem Kurs, und wir haben ihn zuvor mit dem Lang Chin Client ohne Konfiguration verwendet . Jetzt fügen wir tatsächlich weitere Server hinzu, und dafür habe ich einen bereits vorhandenen Server verwendet, nur um meine Implementierung des MCP-Clients mit der Konfiguration zu überprüfen meine Implementierung des MCP-Clients mit der Dafür können Sie einen beliebigen Server auswählen. Ich habe nach der MCP-Serverliste gesucht und bin dann zur Github-Seite gegangen Und hier drüben haben Sie mehrere MCP-Server. Ich habe hier den Abrufserver ausgewählt , der im Grunde Webinhalte abrufen kann, weil ich als Demo Inhalte abrufen, zusammenfassen und dann mit meinem eigenen Terminalserver in eine Datei schreiben wollte zusammenfassen und dann mit meinem eigenen Terminalserver in eine Datei schreiben mit meinem eigenen Terminalserver in eine Datei Wenn Sie also auf den Abrufserver klicken, können Sie sehen, dass er über eine Docker-Datei und eine Konfiguration zum Hinzufügen zur Cloud mithilfe von Docker bereitstellt , wobei der Befehl Docker verwendet wird, und dann haben sie den Befehl run mit dem Image-Namen. Wenn Sie das einrichten, müssen Sie also zuerst diese Server klonen Also gehen wir zurück zur Gu-Hauptseite für alle Server und kopieren dann tatsächlich den Clone-Befehl. Ich habe SSH eingerichtet, also werde ich den SSH-Clone-Befehl von hier kopieren Sie können ein neues Terminalfenster öffnen und zu CD MCP gehen, und hier können Sie tatsächlich ein Verzeichnis für diese Referenzserver erstellen ein Verzeichnis für diese Sie können die Server also tatsächlich in ein Verzeichnis namens servers Ref klonen die Server also tatsächlich in ein Verzeichnis namens servers Ref habe ich bereits getan, und das sind im Grunde alle bereits existierenden Referenzserver, die auf ihrer Github-Seite bereitgestellt werden Geben Sie dazu einfach clone ein und fügen Sie dann ein, was Sie von dort kopiert haben , und geben Sie einen Namen für das Verzeichnis ein, nämlich servers underscore reef, und drücken Sie dann Ich habe das bereits getan, also werde ich es nicht wiederholen, und Sie können das Verzeichnis so in diesen bestimmten Ordner klonen so in diesen bestimmten Ordner Beachten Sie, dass wir dies in unserem MCP-Verzeichnis tun, und dadurch werden die Server das darin enthaltene Ref-Verzeichnis unterstreichen Sie müssen es nicht separat erstellen. Sobald Sie dies erstellt haben, können Sie tatsächlich in das Ref-Verzeichnis des Servers wechseln. Und dann finden Sie ein SRC-Verzeichnis, das eine Quelle direkt darin ist, und dann finden Sie den Abruf direkt darin Jetzt bin ich im Fetch-Verzeichnis, und Sie können ein H L machen, um alle Dateien hier aufzulisten, und Sie sehen, dass Sie die Docker-Datei hier haben Bevor wir also diesen speziellen MCP-Server in unserer MCP-Client-Konfigurationsdatei verwenden können , müssen wir Dafür können wir also den Befehl Docker build verwenden . T, das das Bild im Grunde mit einem bestimmten Namen kennzeichnet. Sie können es mit einigen Namen versehen. Lassen Sie mich einfach den Namen überprüfen, den ich verwendet habe. Ich habe den MCP Feed Server Test verwendet. Ich werde es einfach kopieren, um zu zeigen, wie Sie es erstellen können, und so bauen Sie es Dann setzt du einen Punkt ans Ende, um das aktuelle Verzeichnis im Grunde als erstellten Kontext bereitzustellen , und drückst Ender. Dies wird im Grunde das Docker-Image für Sie erstellen Jetzt ist Ihr Docker-Image erstellt. Und dann können Sie tatsächlich zum AI Language Underscore-Konfliktpunkt jcnFle wenn Sie diesen Docker-Image-Namen angeben. Docker versteht, dass Sie dies dies Wenn Sie es aus unseren vorherigen Videos wissen, muss Docker Desktop natürlich im Hintergrund laufen, wofür Sie Docker Desktop tatsächlich öffnen können, indem Sie in Ihren Anwendungsordner gehen und dort nach Docker Ihren Anwendungsordner suchen. Okay, mit diesem Konfliktpunkt jcnFle und dem Lang-Chain-MCP-Client mit der Konfigurations-Py-Datei haben wir tatsächlich unsere MCP-Clients eingerichtet, und jetzt können wir im Grunde zum Terminal gehen um diesen bestimmten Client tatsächlich auszuführen und zu testen. 17. ABSCHNITT 7 START - Vom Server gesendete Ereignisse - MCP-Server und Clients mit SSE - 7.1 Einführung: Das wird also ziemlich spannend, denn bis jetzt haben wir mit MCP-Servern gearbeitet , die lokal auf unserem Computer liefen Und wie Sie in dieser speziellen Infografik sehen können, war das auch bei Claude Desktop als Client und Python- oder JavaScript-Servern, die auf unserem Computer laufen, der allgemeine Trend war das auch bei Claude Desktop als Client und Python- oder JavaScript-Servern, die auf unserem Computer laufen, Jetzt haben wir die Möglichkeit, Server-Sent-Events zu verwenden und einen MCP-Server aufzubauen , der sich grundsätzlich über eine STDP-Verbindung verbindet Heute werden wir also unseren eigenen MCP-Server erstellen, und wir werden Server Sent Events oder SSE verwenden , um ihn zu erstellen und ihn dann auf einer URL bereitzustellen und damit unseren Client mit dem SSE-Server zu verbinden, und wir werden auch versuchen, diesen SSE-Server kostenlos über das Internet auf der Google Cloud-Plattform bereitzustellen diesen SSE-Server kostenlos über , und wir werden versuchen, unseren MCP-Client damit zu verbinden SSE-Server 18. 7.2 Kurzer Zusammenfassung: Was sind STDIO und SSE?: Bevor wir beginnen, wollen wir die Grundlagen dessen verstehen, was MCP Das Model Context Protocol ermöglicht eine strukturierte und konsistente Kommunikation zwischen großen Sprachmodellen , die auf Clients gehostet werden, die wir als MCP-Clients bezeichnen Und ein Server, den wir MCP-Server nennen. Es kann mehrere Server geben, und die Server können Funktionen wie Tools bereitstellen, mit denen Tools zusätzliche Funktionen bereitstellen können , die der Server für das Large-Sprachmodell ausführen kann Dann können sie Datenquellen bereitstellen. Zum Beispiel haben wir hier lokale Datenquelle A, die lokale Datenquelle B, oder sie können den Zugriff auf Remotedienste über das Internet ermöglichen , so wie wir hier den Remotedienst C haben. In Ordnung. Also, es gibt zwei Hauptkomponenten, wie wir gerade gesagt haben. Einer ist der MCP-Client, und das ist der benutzerorientierte Agent oder die Schnittstelle, die die Eingabeaufforderungen sendet die Antworten aus dem Large-Sprachmodell empfängt Und kümmert sich um die Benutzerinteraktion. Dies ist auch in den Server integriert und sendet dann alle Arten von Anfragen aus dem großen Sprachmodell an den Server , der dann im Grunde auf Ihre Modelleingaben mit Aktionen, Werkzeugaufrufen, Daten usw. reagiert auf Ihre Modelleingaben mit Aktionen, . Jetzt gibt es zwei Möglichkeiten, wie MCP-Clients eine Verbindung zu MCP-Servern herstellen können Eine Möglichkeit ist SDD IO, Standardeingabeausgabe , bei jeder Client über Standardeingabeausgabe mit seinem eigenen Server kommuniziert Es besteht also im Grunde eine Eins-zu-Eins-Verbindung zwischen dem Client und dem Server, und im Grunde erhält der Client den Pfad zur Serverdatei und er startet den Server und beginnt dann mit ihm zu kommunizieren Die andere Möglichkeit sind vom Server gesendete Ereignisse oder SSE, bei denen sich mehrere Clients verbinden können ein webbasiertes Streaming-Protokoll grundsätzlich mit einem bereits laufenden Server . Mit SSE können Sie Ihre MCP-Clients grundsätzlich über einen Weblink und einen Port eine Verbindung zu einem bereits laufenden Server herstellen lassen Ihre MCP-Clients grundsätzlich über einen Weblink und einen Port eine Verbindung zu , genau wie bei einer Verbindung zu einer API Es unterstützt langlebige unidirektionale Datenströme, die sich perfekt für den Empfang von Modellausgaben in Echtzeit Andererseits erfordert SUD IO, für jeden einzelnen Client ein neuer MCP-Server gestartet wird Das bedeutet einen Server pro Client. 19. 7.3 Setup-Verzeichnisse, GitHub-Code klonen (nur git-Pull, wenn dies zu Kursbeginn durchgeführt wird): In Ordnung, also lasst uns zuerst unsere Projektverzeichnisse einrichten. also in Ihrem Home-Ordner hier Lassen Sie uns also in Ihrem Home-Ordner hier das MCB-Verzeichnis erstellen Ich habe das schon gemacht. Sie können diesen Befehl eingeben, um es zu erstellen. Dann wechseln wir zum MCP-Verzeichnis und erstellen hier drei Verzeichnisse, eines für all unsere Clients, das andere für unsere Server und das dritte für unseren Workspace Lassen Sie uns also das Serververzeichnis erstellen und die Eingabetaste drücken. Dann lassen Sie uns das Client-Verzeichnis erstellen. Und drücken Sie die Eingabetaste, und dann erstellen wir ein Workspace-Verzeichnis, das wir für alle Arten von Dateien verwenden können, die unser Server erstellt, oder jede Art von Daten, die er lesen muss. Dadurch wird das verbleibende Dateisystem von unserem Arbeitsbereich getrennt, wodurch grundsätzlich jegliche Probleme und Risiken vermieden werden. Okay, jetzt wechseln wir in unser Serververzeichnis und checken zuerst den Code für den Server aus. Bitte verwenden Sie den Link in der Beschreibung , um einen Git-Klon des Servercodes zu erstellen. Und dann wird hier im Grunde ein Verzeichnis erstellt, das als Terminal-Underscore-Server bezeichnet wird Ich habe das schon gemacht und ich habe bereits dieses Terminalserver-Verzeichnis Das gibt dir also im Grunde den gesamten Code für deinen Server. Gehen wir jetzt zum übergeordneten Verzeichnis und wechseln wir zum Client-Verzeichnis. Und dann klonen wir den Github-Code für unseren Client. Sobald Sie das getan haben, haben Sie ein MCP-Client-Verzeichnis, das im Grunde den gesamten Code für unseren Client enthält 20. 7.4 Virtuelle Umgebung und Abhängigkeiten einrichten: Ordnung, jetzt haben wir sowohl Python als auch UV installiert, und wir haben auch einen Gemini-API-Schlüssel von Google, und wir haben ihn in die DOT-ENV-Datei in unserem MCP-Client-Verzeichnis Jetzt müssen wir mit dem verbleibenden Setup fortfahren, indem eine virtuelle Umgebung erstellen und die Anforderungen installieren Lassen Sie uns das also zuerst für unseren Kunden tun. Wechseln wir also zum MCP-Client-Verzeichnis und gehen wir zu unserem MCP-Client Dann schreiben wir UV VENV und das schafft im Grunde eine virtuelle Umgebung wie wir es mit Python MVNV tun Dann aktivieren wir das indem wir den Quellpunkt Slash Bins Activate eingeben Jetzt öffnen wir die Pi-Projektdatei und den Overhead Wir spezifizieren das Modul, für das wir eigentlich bauen wollen, nämlich unseren Client mit SSE Wir gehen zurück zum Terminal und können einfach UV PIP install dot eingeben , um dann alle Abhängigkeiten zu installieren Dadurch wurden alle Abhängigkeiten installiert , die wir für unseren Client benötigt haben Bitte beachten Sie, dass Sie bereits über all diese Dateien verfügen und nur Ihre virtuelle Umgebung aktivieren und dann die Anforderungen mit UV PIP install dot installieren müssen Ihre virtuelle Umgebung aktivieren und dann die Anforderungen mit UV PIP install dot installieren In Ordnung, ich bin also zurück im Home-Verzeichnis. Jetzt machen wir das Setup für unseren Servercode. Also gehen wir zuerst zum Serververzeichnis. Verzeichnis wird also MCP-Server, Terminalserver und dann SSE-Server sein, da dies das Verzeichnis ist , das tatsächlich den SSE-Servercode für unseren Terminalserver enthält den SSE-Servercode für unseren Terminalserver Nur um Sie daran zu erinnern, dass der Terminalserver ein Server ist, der Befehle mithilfe der Shell auf dem Terminal Ihres Computers ausführen kann Befehle mithilfe der Shell auf dem Terminal Ihres Computers Jetzt erstellen wir eine virtuelle Umgebung, indem UV space VE NV eingeben. Jetzt aktivieren wir diese virtuelle Umgebung, indem wir den Quellpunkt und den Schrägstrich Bnlash Activate eingeben Quellpunkt und den Schrägstrich Bnlash Jetzt öffnen wir unsere Pi-Projektdatei hier. Und wir stellen nur sicher , dass das Pi-Modul auf Terminal Underscore Server Underscore SSE eingestellt ist auf Terminal Underscore Server Underscore SSE eingestellt Jetzt gehen wir zurück zum Terminal und können UV PIP install dot eingeben . Dadurch werden alle Abhängigkeiten installiert, Dadurch werden alle Abhängigkeiten installiert, die wir für unseren Server benötigen Ordnung, großartig. Damit sind also unser Server und unsere Client-Abhängigkeiten alle installiert. Wir haben das Code-Setup und wir haben alles andere, was wir brauchen, um jetzt mit dem Testen zu beginnen. 21. 7.5 MCP SSE-Servercode-Übersicht: Lassen Sie uns nun zuerst den Code für unseren Server durchgehen Sie müssen den Terminal-Underscore-Servercode aus unserem Github-Repo ausgecheckt haben Terminal-Underscore-Servercode aus unserem Github-Repo Und wenn Sie das nicht getan haben, können Sie das über den Link in der Beschreibung tun das über den Link in der Beschreibung Und in diesem Ordner haben wir einen SSE-Serverordner. Möglicherweise sehen Sie hier andere Dateien , darunter eine Docker-Datei, es sich im Grunde um den einfachen Server , den wir in unserem vorherigen Video erstellt hatten Jetzt gehen wir zum SSE-Serverordner und hier drüben haben wir die Datei mit dem Unterstrichpunkt Serverunterstriche mit Punkt PY Dies ist unsere Hauptserverdatei, und das werden wir uns im Grunde ansehen Wir haben auch eine Docker-Datei, die uns im Grunde hilft, diesen Server fortzusetzen, und wir werden sie später verwenden, um unseren Server zu betreiben Schauen wir uns zunächst die Py-Datei mit den Unterstrichen auf unserem Terminalserver an. Ich habe diese Datei hier geöffnet, und sie implementiert im Grunde einen MCP-Server, der das vom Server gesendete Ereignisse oder das SSE-Transportprotokoll verwendet Es verwendet schnelles MCP, es verwendet schnelles MCP-Framework, um Tools bereitzustellen , die Clients über eine SSE-Verbindung aufrufen können, und SSE ermöglicht eine Einwegkommunikation in Echtzeit vom Server zum Client Dieser Server verwendet Starlet für den Webserver uCon als AHGI-Server Schnelles MCP zur Definition der Tools und des SSE-Servertransports zur Verwaltung der von Ihnen verwendeten langlebigen SSE-Verbindungen Um das kurz zu erklären ASGI steht für Async Server Es ist also im Grunde wie ein Mittelsmann, der definiert, wie ein Python-Webserver wie UVCon mit einer Web-App wie Starlt kommuniziert Es ermöglicht eine asynchrone Eingabeausgabe, sodass Ihre App Tausende von Benutzern verarbeiten, Web-Sockets verwenden und Daten wie SSE streamen kann Web-Sockets verwenden und Das ist es also, was ASGI tut. UVCon ist der ASGI-Webserver. Es ist die eigentliche Engine , die Ihre Python-App ausführt. Es hört auf sedPRquests, versteht das AsgipTocol und leitet eingehende Anfragen an Ihre App weiter, bei der es sich um Starlt oder Fast MCP versteht das AsgipTocol und leitet eingehende Anfragen an Ihre App weiter, bei der es sich um Starlt oder Fast MCP handelt. Es bringt im Grunde eingehende Daten in Ihre App und sendet die Antworten an den Ihre App und Starlt hier drüben ist das leichtgewichtige Web-Framework, es ist also ein minimales ASGI-Web-Framework Und wir verwenden es, um die Wurzeln in unserer App zu definieren, wie z. B. Slash SSE und Slash-Nachrichten , die wir uns weiter unten ansehen werden Wir verwenden es auch, um die Logik zur Bearbeitung von Anfragen und die Middleware-Hintergrundaufgaben usw. zu definieren auch, um die Logik zur Bearbeitung von Anfragen und die Middleware-Hintergrundaufgaben Das ist also das Web-Framework, das wir verwenden, und alle Verbindungen zu MCP, was im Grunde das Kommunikationsprotokoll für das Sprachmodell ist Sprachmodell MCP definiert hier, wie die Clients mit dem Server kommunizieren, welche Tools verfügbar sind, wie strukturierte Eingabeaufforderungen, Antworten, Tool-Calls usw. gesendet und empfangen Antworten, Tool-Calls Und schließlich haben wir SSE oder vom Server gesendete Ereignisse, und das ist im Grunde ein Streaming-HTTP-Protokoll Es ist ein unidirektionaler Kommunikationsserver zum Client, der für die Übertragung von Updates, Tokens und Ergebnissen in Echtzeit verwendet wird und sich perfekt für KI- und Modellausgaben In diesem Fall verwenden wir ihn, um den MCP-Client über GTP mit unserem MCP-Server zu verbinden über GTP mit unserem MCP-Server und dem Server zu ermöglichen, Ergebnisse aus den Toolaufrufen zurückzustreamen Wir haben also im Grunde einen MCP-Client-Slash-Agent im Browser, der über SSE über SGTPT eine Verbindung zu unserem Server herstellt, der der UVCon-Server ist, und dieser verwendet die AsgipTocol-Brücke, um eine Verbindung zur Starlt-Web-App herzustellen. Die Sarlet-Web-App kümmert die gesamte Logik, Roots usw. und stellt im Grunde eine Verbindung zum MCP-Server her, der die MCP-Tools wie Run command und numbers anbietet, auf die wir uns weiter unten konzentrieren werden . Das ist also im Grunde die visuelle Darstellung dessen wie unser Flow abläuft Und jetzt gehen wir den Code durch. Also importieren wir unsere Basisbibliotheken und alle MCP-Bibliotheken Wir haben also den zentralen MCP-Wrapper Tools zu definieren und Wir haben die zugrunde liegende Serverabstraktion von Fast MCP verwendet wird, und wir haben die Dann importieren wir alles, was mit Starlight zu tun hat. Wir importieren also im Grunde das Web-Framework, um Roots zu definieren, importieren Routing für SCDP und Nachrichtenendpunkte über Root und Mount und importieren die SGDPRQuest-Objekte Dann importieren wir uCon, den ASGI-Server, auf dem die StarLt-App ausgeführt wird ASGI-Server, auf dem die StarLt-App ausgeführt Und dann beginnen wir mit Schritt eins, der im Grunde die schnelle MCP-Instanz initialisiert, und das ist Also nennen wir dieses Terminal und das ist unser MCP-Server Wir definieren den Workspace als den Home-Directory-Slash-MCP-Slash-Workspace , den wir bereits in den vorherigen Schritten definiert haben Dann definieren wir unser erstes Tool, das Run-Befehlstool, und der Zweck dieses Tools besteht darin, einen Shell-Befehl auf dem Terminal auf unserem lokalen Computer auszuführen und das Ergebnis zurückzugeben, das wir dem MCPT-Tool-Decorator als MCP-Tool vermarkten, und es ist im Grunde eine ASN-Funktion , die eine Zeichenfolge aufnimmt, , die eine Zeichenfolge aufnimmt, den Befehl, den wir auf dem Terminal ausführen müssen, und antwortet dann mit einer Zeichenkettenausgabe, die entweder die Ausgabe des Befehls oder eines Fehlers ist . Und diese Funktion ist ziemlich einfach. Also verwenden wir einen Unterprozess, um dies auf der Shell auszuführen, und wir geben den STD-SDD-Fehler zurück, was auch immer der Fall sein mag Wenn es eine Ausnahme gibt, fangen wir sie im Grunde ab und geben die Ausnahmezeichenfolge hier zurück Wir haben dann das zweite Tool, das Zahlen addiert, und es ist auch ein einfaches Tool, um zwei Zahlen zu addieren und das Ergebnis zurückzugeben. Wir haben den Dekorateur wieder als MCP-Tool auf den Markt gebracht. Und dann nimmt dieses Tool zwei Argumente auf, A und B, was die erste und die zweite Zahl ist, und es addiert die beiden Zahlen und gibt die Summe zurück, die ein Gleitkommawert ist , der eine Summe aus A und B ist. Das ist ein sehr einfaches Tool da drüben Jetzt müssen wir die Sarlet-App erstellen, um die Tools über STTP mithilfe von SSE verfügbar Wir definieren diese Funktion grundsätzlich mit dem Namen Create Starlet App. Sie erstellt im Grunde eine Starlet-App mit SSE und Nachrichtenendpunkten MCP-Server ist die zentrale MCP-Serverinstanz, und wir aktivieren den Debug-Modus für Verbenprotokolle, die vollständige Sarlet-App Roots. Dann erstellen wir einen SSE-Transporthandler , um die SE-Verbindungen zu verwalten. Danach definieren wir eine Handle-Underscore-SSE-Funktion, die grundsätzlich immer dann ausgelöst wird, wenn ein Client eine Verbindung zu Slash-SSE grundsätzlich immer dann ausgelöst wird, wenn herstellt Das ist also das Stammverzeichnis, zu dem der Client eine Verbindung herstellt, und es wird diese Funktion auslösen Und das macht im Grunde genommen die neue SSE-Client-Verbindung und verbindet sie mit dem MCP-Server. Also, wie machen wir das? Wir öffnen eine SC-Verbindung und geben dann die Lese- und Schreibstreams an MCP Und dann geben wir die Starlet-App mit den konfigurierten Endpunkten zurück mit den konfigurierten Endpunkten Wir haben zwei Endpunkte. Einer ist der Schrägstrich SSE, dem die SSC-Verbindung initiiert wird, und dann haben wir den Nachrichtenendpunkt, der im Grunde für die postbasierte Kommunikation bestimmt ist, der im Grunde verwendet wird , verwendet wird , wenn wir den SSE-Transporthandler hier drüben erstellen Jetzt starten wir den Server im Grunde mit UVCon. Also holen wir uns zuerst die zugrundeliegende MCP-Serverinstanz vom schnellen MCP zum Weiput RC Pass, was im Grunde dazu dient, Befehlszeilenargumente für die Host-Slash-Port-Steuerung zu übergeben Befehlszeilenargumente für die Host-Slash-Port-Steuerung Also erstellen wir einen Parser mit einer Beschreibung. Dann fügen wir hier den Host und den Port hinzu. Wir verwenden den lokalen Host und wir verwenden 80 81 als Port, und dann bekommen wir im Grunde die Argumente vom Parser Wir haben die Sarlet-App mit der Funktion Create Starlet App erstellt die wir im Grunde genommen früher verwendet haben, indem wir ihr den MCP-Server zur Verfügung gestellt haben, und wir haben die Sarlet-App hier, und dann starten wir den Server mit UVcon, indem wir Uicon dot run sagen, und wir stellen der App den Host und den Port mit den Argumenten zur Verfügung , die wir gerade oben übergeben haben. Wenn wir also zu unserer visuellen Darstellung zurückkehren, haben wir im Wesentlichen zu unserer visuellen Darstellung zurückkehren, eine Starlet-App erstellt, die wenn sie eine Verbindung über Slash SSE empfängt, diese an den schnellen MCP-Server weitergibt , der Tools wie Anzeigennummern und Run-Befehle verfügbar macht. Die Sarlet-App bietet auch eine weitere Route, nämlich Slash-Nachrichten, die für die Kommunikation nach der Initialisierung vorgesehen ist, für die Kommunikation nach der Initialisierung vorgesehen ist und der UVCon-Server führt diese App im Grunde über die AsdipTocol-Brücke eine weitere Route, nämlich Slash-Nachrichten, die für die Kommunikation nach der Initialisierung vorgesehen ist, und der UVCon-Server führt diese App im Grunde über die AsdipTocol-Brücke aus. Das war also ein kurzer Überblick über den Code. Aber vorerst werden wir zu unserem Client-Code übergehen , um ihn kurz durchzugehen, bevor wir anfangen, unseren Client und Server gemeinsam zu testen. 22. 7.6 MCP SSE-Clientcode-Schritt-für-Schritt-für-Schritt-Anleitung: Ordnung, das ist also die SSE-PY-Datei mit dem SSE-Unterstrich für den Client , und sie implementiert den MCP-Client, der mithilfe von Server-Cen-Ereignissen oder SSE-Transport eine Verbindung zu einem MCP-Server herstellt eine Verbindung zu einem MCP-Server Dieser Client baut auf dem vorherigen Client auf , den wir erstellt haben, nämlich Client Dot PI, der SDD IO verwendet, und der einzige Unterschied zwischen den beiden Clients ist der Unterschied zwischen SDD IO und SSE, der für die Kommunikation verwendet wird Gehen wir also das Angebot für den Kunden durch. Wir haben hier zunächst einige grundlegende Importe, die selbsterklärend sind Sie können die Befehle hier lesen , um zu verstehen, wofür sie importiert werden Dann importieren wir die Clientsitzung aus dem MCP-Paket, und dieses verwaltet im Grunde die gesamte Kommunikation mit dem MCP-Server Anschließend importieren wir den SSE-Client-Helper und anschließend die Comperens aus dem Gemini SDK für KI-basierten Funktionsaufruf und Hier importieren wir im Grunde Gemini-SDK-Hauptmodul Geni Dies haben wir verwendet, um den Gemini-Client zu konfigurieren und Eingabeaufforderungen zu senden und Abschlüsse Das ist also der zentrale SDK-Einstiegspunkt. Dann importieren wir die Typen. Das Typenmodul enthält wichtige Datenstrukturen, die für Tool- und Funktionsdeklarationen, Generierungskonfigurationen und strukturierte Eingabeaufforderungen und die Antwortbehandlung verwendet für Tool- und Funktionsdeklarationen, Generierungskonfigurationen und strukturierte Eingabeaufforderungen und die Antwortbehandlung Dann importieren wir die Tool- und Funktionsdeklaration aus Typen die Tool- und Funktionsdeklaration importiert also im Grunde diese spezifischen Klassen, die für den Funktionsaufruf verwendet werden. Das Tool stellt ein Tool dar, das vom KI-Modell aufgerufen werden kann Jedes Tool teilt dem Modell mit, was es tun kann, wie die Funktion aufgerufen und welche Parameter erwartet werden Die Funktionsdeklaration definiert Namen, die Beschreibung und die Parameter einer einzelnen Funktion. Also werden wir das unten im Code verwenden. Inhaltskonfiguration generieren wird verwendet, um zu konfigurieren, wie das Modell Inhalte generiert. Wir stellen hier im Grunde die Temperatur und andere Details ein, und auch hier werden wir dies verwenden wenn wir im Code nachlesen. Dann importieren wir die ENV-Datei um Umgebungsvariablen zu laden, und hier speichern wir im Grunde den Gemini-API-Schlüssel Dies ist eine bewährte Methode, um Ihren API-Schlüssel nicht offenzulegen, während Sie ihn tatsächlich im Code verwenden oder ihn in ein Get-Repository Falls du dich erinnerst, haben wir die Datei Dot NV hinzugefügt , damit sie ignoriert werden kann. Wir laden die Datei dann tatsächlich nachdem wir die erforderlichen Pakete importiert haben. Wir haben dann unsere MCP-Client-Hauptklasse mit der Initialisierungsfunktion , die den MCP-Client initialisiert Dieser Konstruktor wird also im Grunde den Gemini AI-Client mithilfe des API-Schlüssels aus den Umgebungsvariablen einrichten den Gemini AI-Client mithilfe des , und er richtet im Grunde Platzhalter für die Clientsitzung und den Stream-Kontext ein, der die SSC-Verbindung verwalten und er richtet im Grunde die Platzhalter für die Clientsitzung und den Stream-Kontext ein, der die SSC-Verbindung verwalten wird. Der Gemini-Client wird grundsätzlich verwendet, um Inhalte zu generieren und jegliche Art von Toolaufrufen vom MCP-Server anzufordern Dies ist ein Platzhalter für die MCP-Sitzung , die die Kommunikation mit dem MCP-Server verwaltet Diese werden im Grunde unsere Kontextmanager für die SSE-Verbindung enthalten unsere Kontextmanager für die Es wird also einen SSE-Stream-Lebenszyklus , für den wir den Kontext verwalten müssen , der hier stattfinden wird, und es wird einen MCP-Sitzungslebenszyklus geben , der hier stattfinden wird Jetzt verwenden wir die OS Dot Get ENV-Funktion, um den Gemini-API-Schlüssel tatsächlich Falls wir ihn nicht finden, wir einen Wertfehler aus Und schließlich initialisieren wir den Gemini-Client mit dem API-Schlüssel, und dieser Client wird im Grunde für die Kommunikation verwendet Als Nächstes in der MCP-Klasse haben wir also die Funktion „Verbindung zum SSE-Server herstellen Die Schritte, die wir ausführen, bestehen darin, eine SSE-Verbindung über die angegebene Server-URL zu öffnen eine SSE-Verbindung über die angegebene Server-URL Das ist also die Server-URL , die wir verwenden werden. Wir verwenden die Verbindungsstreams, um eine MCP-Client-Sitzung zu erstellen Wir initialisieren die MCP-Sitzung, die das Protokoll für die Kommunikation einrichtet, und wir rufen die Liste der verfügbaren Tools vom MCP-Server ab und zeigen sie an In Ordnung. Also öffnen wir zuerst die SEC-Verbindung mit dem SSE-Client und speichern sie in der Streams-Kontextvariablen , die wir oben definiert haben. Die SSE-Client-Funktion gibt also einen asynchronen Kontextmanager zurück , der den Stream liefert Oder die Datenkanäle für die Kommunikation, und das werden wir im Streams-Kontext speichern Wir erhalten nun diesen Datenkanal oder diese Streams mithilfe des Streams-Kontextes von oben, indem wir den Async-Kontext eingeben Es wird also erwartet, dass Streams wie ein Tupel sind , wie Reader oder Reader und Das kann die Client-Sitzung verwenden. Jetzt erstellen wir hier eine MCP-Clientsitzung mit den von der SSE-Verbindung bereitgestellten Streams Wir haben also die Lese - und Schreibstreams, wir verwenden sie, um jetzt die MCP-Client-Sitzung zu erstellen, und das Client-Sitzungsobjekt kümmert sich im Grunde genommen um das Senden und Empfangen von Nachrichten nach dem MCB-Protokoll Auch hier rufen wir zuerst den Sitzungskontext ab und geben dann diesen Sitzungskontext ein, und geben dann um die Clientsitzung zu erstellen Jetzt initialisieren wir die MCP-Sitzung, indem wir session dot initializes aufrufen. Dabei wird im Grunde eine Initialisierungsnachricht an den Server gesendet, um Funktionen auszuhandeln und das Protokoll zu starten. In Ordnung. Jetzt werden wir endlich die verfügbaren Tools vom MCP-Server abrufen und auflisten, und wir geben dem Benutzer grundsätzlich aus, dass wir den SSE-Client initialisiert haben, und wir listen die Und dann rufen wir Session Dot List Tools auf. Und wenn wir die Antwort erhalten, erhalten wir die Liste der Tools aus der Antwort als Antwortpunktwerkzeuge, und dann sagen wir im Grunde, dass wir mit Tools mit dem Server verbunden sind, und wir geben den Werkzeugnamen für jedes der Tools in der Tool-Liste aus. Ordnung, dann haben wir also eine Funktion, die MCP-Tools im Grunde in das Gemini-Format konvertiert Die Tools, die wir von MCP erhalten, haben also einige Felder oder Eigenschaften , die Gemini nicht erwartet, und wir müssen Wir haben also im Grunde eine Funktion zur Konvertierung von MCP-Tools in Gemini. Schauen wir uns das kurz an um zu verstehen, was es tut Dies ist eine Funktion zum Konvertieren von MCP-Tools in Gemini, und ich werde einfach nach unten scrollen Ihnen genau zu zeigen, was sie tut Es erstellt im Grunde eine leere Liste von Tools und für jedes Tool in den MCP-Tools , das es als Argument erhalten hat, wird es im Grunde das Schema für die Parameter bereinigen Schema für die Die Reinigung erfolgt in der Clean-Schema-Funktion Und wenn Sie sich die Funktion „ Clean Schema“ ansehen, entfernt sie im Grunde nur den Titelschlüssel, wenn er in diesem Schema rekursiv in allen Eigenschaften vorhanden rekursiv in allen Eigenschaften Und das ist es. Das ist eine einfache Entfernung , die wir vornehmen müssen, da Gemini diesen Titelschlüssel nicht erwartet, wenn er im Schema vorhanden ist Kehren wir nun zur Funktion „MCP-Tools in Gemini konvertieren“ zurück Funktion „MCP-Tools in Gemini konvertieren Nachdem wir das Schema bereinigt haben, erstellen wir einfach eine So möchte Gemini die Funktionsdeklaration haben. Und wenn Sie sich erinnern, haben wir das aus den Google GNI SDK-Typen importiert das aus den Google GNI SDK-Typen Dies ist der Typ, den es für die Definition einer Funktion erwartet, und wir geben den Namen an, der der Name des Tool-Punkts ist, sowie die Beschreibung und die Parameter , die bereinigt wurden, um den Titel zu entfernen Jetzt packen wir die Funktionsdeklaration in ein Tool und weisen sie einem GeminiTol-Objekt zu Dann hängen wir das an die Liste der vorhandenen Gemini-Tools an und geben diese Gemini-Tools-Liste von hier zurück Das ist also alles, was die Tools zur Konvertierung von MCP nach Gemini tun. Sie können sich die Funktion ansehen. Es ist ziemlich selbsterklärend, basierend auf all den Kommentaren, die ich hier abgegeben habe Wir erhalten jetzt also alle Funktionsdeklarationen für den MCP-Client, und damit ist die Funktion „Verbindung zum SSE-Server herstellen“ im Grunde abgeschlossen Verbindung zum SSE-Server herstellen Als Nächstes haben wir die Bereinigungsfunktionen. Es bereinigt im Grunde die Ressourcen, indem die SSE-Sitzungs- und Stream-Kontexte ordnungsgemäß geschlossen Wir müssen also ihre Exit-Funktionen grundsätzlich manuell aufrufen, um ihre Exit-Funktionen grundsätzlich manuell aufrufen, sicherzustellen, dass alle Netzwerkverbindungen und Ressourcen ordnungsgemäß geschlossen werden, wenn der Client fertig Und genau das machen wir hier. Jetzt haben wir die Funktion „Abfrage verarbeiten und dies ist eine wichtige Funktion , die uns viel Arbeit abnimmt , um die vom Benutzer angegebene Abfrage zu verarbeiten. Es verwendet im Grunde die Gemini-API, um die Abfrage zu verarbeiten, und die Gemini-API fordert möglicherweise einen Tool-Aufruf per Funktionsaufruf an. Wenn das passiert, wird die Antwort übergeben und der MCP-Server wird aufgerufen, um Das Ergebnis des Tool-Aufrufs wird dann für eine endgültige Antwort an Gemini zurückgesendet an Gemini zurückgesendet In den folgenden Schritten formatieren wir die Abfrage des Benutzers als strukturiertes Inhaltsobjekt Wir senden die Anfrage an Gemini, einschließlich der verfügbaren MCP-Tool-Deklarationen Und wenn die Antwort von Gemini eine Funktionsaufrufanforderung enthält, führen wir das Tool auf dem Server und senden dann die Antwort von der Ausführung des Tools Wenn GeminizSrResponse einen Funktionsaufruf enthält, senden wir das Ergebnis einer Werkzeugausführung zurück an Gemini und erhalten dann eine endgültige Antwort, die als Text senden wir das Ergebnis einer Werkzeugausführung zurück an Gemini und erhalten dann eine endgültige Antwort, die als Text von Gemini verarbeitet wird. Und dann erhalten wir im Grunde die endgültige Antwort von Gemini und geben zurück, dass die Argumente nur die Abfragezeichenfolge sind und dass diese endgültige Antwortzeichenfolge endgültige Antwortzeichenfolge die endgültige Antwort von Gemini und geben zurück, dass die Argumente nur die Abfragezeichenfolge sind und dass diese endgültige Antwortzeichenfolge dann als Rückgabewert zurückgegeben wird. Ordnung. Lass uns jetzt den Code durchgehen. Wir erstellen ein Gemini-Inhaltsobjekt. Es stellt die Anfrage des Benutzers dar und dazu gehört im Grunde die Rolle Benutzer, was im Grunde besagt, dass die Anfrage vom Benutzer kommt und die Abfrage aus Text besteht, der in einen Teil eingeschlossen ist Die Rolle und Teile werden der Inhaltsklasse zur Verfügung gestellt, und diese wird dann im Grunde verwendet, um den Inhalt der Benutzeraufforderung zu bilden. Dann senden wir die Anfrage an das Gemini-Modell. Deshalb verwenden wir dafür grundsätzlich Generate Content. Wir spezifizieren das Modell, wir spezifizieren den Inhalt, was hier nur der Inhalt der Benutzeraufforderung ist, und wir generieren im Grunde die Inhaltskonfiguration , die wir oben importiert haben. Dort stellen wir die Tools zur Verfügung, die auf den Funktionsdeklarationen basieren, die wir im Grunde bei der Konvertierung der MCP-Tools in Gemini-Tooldefinitionsformate erhalten haben Konvertierung der MCP-Tools Gemini-Tooldefinitionsformate Also bekommen wir die Antwort hier drüben und dann analysieren wir die Antwort im Grunde Vorher erstellen wir im Grunde eine leere endgültige Textliste um den endgültigen Antworttext zu sammeln Was nun die Antwort angeht, schauen wir uns jeden Kandidaten als Antwortpunktkandidaten an, und dann hat jeder Kandidat Inhaltsteile und wir suchen nach jedem Teil. Und wenn es sich bei dem Teil im Grunde um einen Funktionsaufruf handelt, extrahieren wir den Namen des Tools und die Argumente und teilen dem Benutzer dann mit, dass Gemini einen Aufruf dieses speziellen Tools mit diesen speziellen Argumenten angefordert hat dieses speziellen Tools mit diesen speziellen Argumenten Und schließlich versuchen wir, das angegebene Tool auf dem MCP-Server aufzurufen , und hier verwenden wir im Grunde die MCP-Sitzung, um das Tool mit dem Namen und den Argumenten aufzurufen Tool mit dem Namen und den Argumenten Wir erhalten das Ergebnis und dieses Ergebnis wird dann in die Funktionsantwort Oder wenn es eine Ausnahme gibt, fügen wir die Ausnahmezeichenfolge in die Funktionsantwort ein und erstellen dann einen Teil der Funktionsantwort, und erstellen dann einen Teil der Funktionsantwort wobei die Antwort die Funktionsantwort ist , die wir oben definiert haben, und wir benennen sie als Werkzeugnamen. Und das ist im Grunde der Teil der Funktionsantwort. Dann wickeln wir den Teil der Funktionsantwort in ein Inhaltsobjekt ein. Als von einem Tool stammend markiert. Die Rolle ist grundsätzlich als Tool spezifiziert. Dann rufen wir erneut die Gemini-API auf, indem wir generierte Inhalte verwenden. Wir spezifizieren das Modell hier und im Inhalt schließen wir jetzt alle drei Teile Wir haben die erste Benutzerabfrage. Wir haben den angeforderten Tool-Call und die Antwort vom Tool-Call. Alle drei sind enthalten, sodass Gemini den vollständigen Kontext des Geschehens hat und wir die Funktionsdeklarationen erneut zur weiteren Verwendung Basierend auf der Antwort, die wir erhalten, schauen wir uns im Grunde noch einmal die Inhaltsteile und den Text der Kandidaten an und fügen diesen Text hier an den endgültigen Text an. Falls kein Funktionsaufruf erforderlich war, verwenden wir im Grunde einfach den von Gemini bereitgestellten Text und hängen ihn hier an den endgültigen Text an und wir geben diesen endgültigen Text hier zurück Das ist also im Grunde die Prozessabfragefunktion. Als nächstes haben wir die Chat-Schleife. Chat-Schleife ist im Grunde eine interaktive Chat-Schleife, die im Terminal läuft und im Grunde die Benutzereingabeabfrage wartet Sie fordert den Benutzer zur Eingabe der Anfrage auf. Wenn der Benutzertyp beendet wird, bricht er quasi aus der Schleife aus Andernfalls verwendet es die Funktion „Abfrage verarbeiten“, um die vom Benutzer bereitgestellte Anfrage zu verarbeiten , wartet auf die Antwort und druckt die Antwort dann hier aus. Schließlich haben wir noch die Hilfsfunktion Clean Schema , die wir uns bereits angesehen haben , zusammen mit der Funktion „ MCP-Tools in Gemini konvertieren“, die wir uns auch zuvor Die letzte, aber nicht zuletzt, ist die Hauptfunktion, die der Haupteinstiegspunkt für den Client ist Und das prüft im Grunde ob dies grundsätzlich aufgerufen wird, wenn wir das Client-Python-Skript ausführen, und es überprüft im Grunde, ob die Server-URL bereitgestellt wird Es erstellt hier eine Instanz des MCP-Clients. Dann versucht es im Grunde, mithilfe der Funktion Connect to SE Server eine Verbindung zum SSE-Server herzustellen, und dann ruft es im Grunde die Client-Chat-Schleife auf und fordert den Benutzer zu einer Und schließlich führt es im Grunde die gesamte Bereinigung durch, die vor dem Beenden erforderlich ist Und hier führen wir diese Hauptfunktion einfach mithilfe der Async-IO-Ereignisschleife aus, indem wir asyncodt run verwenden und die Hauptfunktion dort übergeben Das ist alles für die UnderscoreSS Dot PV-Funktion Ihres Clients, und das ist 23. 7.6 Dockerfile-Code (für MCP Server) – Schritt-für-Schritt-Durchgang: Schauen Sie sich auch die Docker-Datei an, die wir verwenden werden Es ist eine einfache Docker-Datei und wir verwenden im Grunde Python 3.11 SLM, das offizielle Python 3.11 SLIM-Image, als Basis-Image SLIM-Image, als Basis-Image Wir haben das Arbeitsverzeichnis im Container auf Slash-App eingestellt Container auf Slash-App Wir kopieren alle Dateien aus dem aktuellen Verzeichnis dem lokalen Host im Grunde in das App-Verzeichnis im Container Dann installieren wir die erforderlichen Python-Pakete von Requirements Dot TXT. Wir machen den Port 8081 , damit der Container eingehende Verbindungen annehmen kann Im Grunde ist 881 also der Port, über den wir auf den MCP SSE-Server zugreifen können Und schließlich verwenden wir den Python-Befehl, um unseren SSE-Server auszuführen handelt es sich um den Terminal-Unterstrich SSE Punkt PY Five Das ist also alles für die Docker-Datei. Es ist eine ziemlich einfache Docker-Datei , um diesen Server tatsächlich auszuführen 24. 7.7 Lokales Testen des MCP SSE-Servers und -Clients: In Ordnung, also lassen Sie uns jetzt weitermachen und zuerst unseren Server laufen lassen. Also können wir hier klicken , um das Terminal zu öffnen. Verwenden wir also den Befehl Docker build, Docker Bildt, um das Bild zu taggen, und nennen wir das Image-Terminal underscoe server underscore SSE Und vergessen wir nicht, den Punkt für den erstellten Kontext einzufügen und die Eingabetaste zu drücken . Dadurch wird unser Docker-Image mit allen Anforderungen usw. erstellt , und jetzt ist dieses Image tatsächlich Lassen Sie uns jetzt unseren Server laufen lassen. Lassen Sie uns nun den Container mit Docker Run ausführen. Der Dash RM wird uns helfen, aufzuräumen, wenn der Container verlassen wird Das P hilft uns dabei den lokalen Port dem Containerport zuzuordnen Das V ist ein Volume-Mount, und wir mounten im Grunde das lokale Host-Volume, das sich in unserem Workspace befindet , in den Root-MCPs-Workspace innerhalb des Containers Und dann geben wir den Namen unseres Images ein und drücken die Eingabetaste Und jetzt haben wir einen Server, der auf dem lokalen Host 80 81 läuft. Lassen Sie uns jetzt den Client ausführen. Also werden wir hier drüben klicken, um das Terminal zu öffnen , und wir werden den Befehl UV run verwenden. Also verwenden wir UV run client unscos dot P, was unsere Client-Datei ist, was unsere Client-Datei ist, und wir werden die URL für unseren Server als lokales Host-Codon 881 mit dem Port-Slash SSE angeben unseren Server als lokales Host-Codon 881 , weil das der Ort ist, an dem unser Server auf die Initialisierung wartet Drücken wir die Eingabetaste. Und jetzt heißt es initialisierte SSE-Client-Tools, die Tools auflisten, und jetzt ist es mit dem Befehl Tools Run und Add Numbers mit dem Server verbunden Befehl Tools Run und Add Numbers Lassen Sie uns das also testen. Bitten wir Gemini also, tatsächlich zwei Zahlen zu addieren. Also werde ich sagen, addiere bitte zwei Zahlen zwei und fünf mit den Tools, zwei und fünf mit den Tools, denn das ist ein einfacher Vorgang, vielleicht fügt es sie einfach von selbst hinzu Ich wollte das Tool verwenden und überprüfen, ob der Server über diese SSE-Verbindung läuft oder nicht. Also lass uns Enter drücken. Ordnung, jetzt erhalten wir also das Ergebnis , dass Gemini einen Tool-Call angefordert hat, Zahlen mit den Argumenten A gleich zwei und B gleich fünf addiert hat und die Summe von zwei und fünf sieben Punkt ergibt Also das ist wunderbar. Unser Server läuft jetzt über eine HTTP-Verbindung, und jetzt können wir diesen Server tatsächlich auf der Google Clot-Plattform bereitstellen und versuchen, ihn über eine Remoteverbindung zu verwenden , da sich auf unserem lokalen Computer immer noch der lokale Host befindet auf unserem lokalen Computer immer noch der lokale Host Also werde ich diesen Server im Internet bereitstellen. Lass uns das jetzt versuchen. 25. ABSCHNITT 8 ERSTE Schritte - Bereitstellen von MCP Server auf der Google Cloud Platform - 8.1 Erstellen eines neuen Gmail-Kontos (falls: Okay, lassen Sie uns zunächst ein neues Google-Konto einrichten , mit dem wir ein Projekt auf der Google Cloud-Plattform erstellen Dafür suche ich einfach nach „Neues Google-Konto erstellen “ und gehe dann dorthin. Lass uns hier drüben klicken. Und, ähm, wie Sie sehen können, heißt es, Sie können zum Google-Konto gehen, sich auf der Anmeldeseite anmelden und auf Konto erstellen klicken. Also werde ich das in einem neuen Inkognito-Fenster öffnen in einem neuen Inkognito-Fenster Okay. Und ich werde ein Konto erstellen. Und hier werde ich es für meine Arbeit oder für mein Geschäft verwenden , und Sie können es entsprechend wählen. Da ich es für eine App verwenden werde, entscheide ich mich für meine Arbeit oder für mein Unternehmen. Okay, und ich werde hier eine Gmail-Adresse angeben oder mich nach einem Vor- oder Nachnamen fragen. Also nur für diese Demo werde ich die KI-Sprache angeben und ich werde Demo als Nachnamen für mich angeben. Sie können wählen, was für Sie geeignet ist. Okay, und nachdem Sie diese, Sie wissen schon, Details eingegeben haben, werden Ihnen möglicherweise diese Optionen angezeigt. Und im Moment verwende ich dieses Format zur Verwendung der AI Language Dot Demo. Geben Sie also eine Gmail-Adresse ein, die Sie bevorzugen, und klicken Sie dann auf Weiter. Okay, und dann können wir ein neues Passwort für uns selbst erstellen. Und es wird auch deine Telefonnummer verifizieren. Also, ähm, bitte gib deine Telefonnummer ein. Also habe ich meine Telefonnummer hier drüben eingegeben. Okay, ich habe also mein Google-Konto eingerichtet , das ich verwenden werde. Es werden Sie nach etwas mehr Informationen wie Ihrer Telefonnummer oder Ihrer Wiederherstellungs-E-Mail und allem gefragt . Folgen Sie also bitte diesen Schritten, um es einzurichten. Und sobald Sie Ihr Konto vorerst eingerichtet haben, werde ich „Nicht jetzt“ verwenden, um mein Unternehmen einzurichten, richtig, und das Google-Konto weiterhin verwenden, oder? Jetzt habe ich dieses Google-Konto eingerichtet und kann es für die Einrichtung meines Google Cloud-Projekts verwenden . 26. 8.2 Erstellen eines Google Cloud-Projekts: Okay, lassen Sie uns jetzt ein Google Cloud-Projekt erstellen. Also öffnen wir einen neuen Tab und gehen zur Google Cloud-Plattform. Und hier haben wir es. Okay, und lass uns zuerst auf Anmelden klicken. Lass uns auf Weiter klicken. Und ein Passwort. Ordnung, jetzt haben wir uns in einem Google-Konto angemeldet und können tatsächlich kostenlos auf Erste Schritte klicken Und Ordnung. Und um kostenlos mit einem Guthaben von 300$ zu beginnen, müssen Sie auf Kostenlos starten klicken, aber Sie benötigen ein bestimmtes, ähm, Sie wissen schon, Zahlungsprofil Okay, jetzt, da ich eine Demo aufnehme und sie nicht für eine Organisation ist, wähle ich hier Sing Individual Ich muss meine Daten, die echten Details, die wahren Details hier drüben eingeben , weil dafür mein offizieller Name erforderlich Also werde ich das tun und dann auf Erstellen klicken. Jetzt habe ich das Zahlungsprofil ausgefüllt und eine Kreditkarte hinzugefügt, für die zur Überprüfung ein sehr geringer Betrag belastet wurde. Daraufhin wird uns dieser Willkommensbildschirm angezeigt. Also ein kleiner Haftungsausschluss hier drüben, bitte stellen Sie sicher, dass Sie all die Dinge lesen und verstehen , die Sie, Sie wissen schon, als Richtlinien von Google eingeben und akzeptieren, denn das ist ein Live-Konto, das für, Sie wissen schon, Dinge hosten können, für die Beträge berechnet werden können , oder? Und Sie sind verantwortlich für die Einrichtung und Verwaltung dieses Kontos. Schenken Sie dem also die gebührende Aufmerksamkeit und Überlegung, bevor Sie fortfahren, oder? Nun, hier drüben, fragen wir nach einigen sehr grundlegenden Dingen, z. B. nach dem, was Bedürfnisse Ihres Unternehmens am besten beschreibt. Lassen Sie mich einfach sagen, dass es ein sehr, Sie wissen schon, kleines Unternehmen ist. Ich denke, Start, richtig, und wir klicken auf Weiter. Und was hat dich zu Google Cloud gebracht? Nehmen wir an, Sie lernen mehr und erkunden Sie und was sind dann Ihre Interessen? Lassen Sie uns also vorerst Web- und Mobil-Apps auswählen. Und dann, was Ihre Rolle am besten beschreibt , und Sie können alles einsetzen , was zu Ihnen passt Ich werde Engineer Developer hier drüben platzieren und auf Fertig klicken. Okay. Und jetzt, wie Sie sehen, haben Sie die Willkommensseite und Sie können hier einige kostenlose Credits verwenden, die in etwa drei Monaten ablaufen. Okay, schauen wir uns das Projekt an, das wir hier haben. Google hat also bereits ein Projekt für uns erstellt, das MiFirstPject heißt, und es hat hier eine bestimmte ID, und wir werden vorerst dabei bleiben und dies für die weitere Einrichtung verwenden 27. 8.3 Installieren und Einrichten der Google Cloud Command Line Interface (gcloud CLI): Ordnung. Gehen wir also weiter. Jetzt installieren wir die GCloud-CLI, die Befehlszeilenschnittstelle für Google Cloud Lassen Sie uns also nach der Google Cloud CLI suchen und installieren. In Ordnung. Und wir bekommen diesen Link. Lass uns hier klicken. Okay. Und hier sind wir mit allen Anweisungen. Also benutze ich McOS und ich werde das wählen. Zunächst müssen wir also bestätigen, ob wir eine unterstützte Version von Python installiert haben oder nicht, ? Und lass uns das machen. Also öffnen wir das Terminal und hier haben wir unser Terminalfenster. Und dann folgen wir einfach den Anweisungen von Google Spade Also müssen wir zuerst überprüfen, ob wir Python drei haben oder nicht. Schauen wir uns also einfach Python drei an. Wir und wir bekommen, wir haben Python 3.12 0.2 installiert, oder? Und falls Sie das nicht installiert haben, können wir eine Python-Version installieren , indem wir zu Python deLISF Macua gehen Schauen wir uns das auch einmal an, oder? Es heißt also, weißt du, das neueste ist Python 3.13 0.1. Also lass mich einfach versuchen, das über 3.12 zu installieren. Wenn Sie also nach unten scrollen, sehen Sie all diese verfügbaren Dateien. Nun, da ich macOS verwende, kann ich diese spezielle Datei hier verwenden nur um zu bestätigen, welche macOS-Version Sie Sie können tatsächlich auf die Befehlszeile klicken und dann können Sie etwas über diesen MAC auswählen, oder? Also werde ich auf diese Datei klicken. Und erlaube die Downloads, richtig? Und ich werde warten, bis das heruntergeladen ist. Sobald Sie dieses Installationsprogramm für Macaws heruntergeladen haben, können Sie zu Ihren Downloads gehen, darauf klicken und das spezielle Paket hier öffnen, und Ihnen wird das Python-Installationsprogramm angezeigt Sie können also den Anweisungen im Installationsprogramm folgen. Ich werde das jetzt für mich selbst tun. In Ordnung, jetzt klicke ich auf Installieren. Okay, jetzt wird Python 3.13 0.1 für mich installiert Python 3.13 0.1 für mich Also werde ich vorerst auf Schließen klicken und das Installationsprogramm in den Papierkorb verschieben Und jetzt lass mich zum Terminal gehen. Und wenn ich das einfach noch einmal mache, erhalte ich die aktualisierte Python-Version, nämlich Python 3.13 0.1 Auf diese Weise können Sie Python installieren, falls Sie es noch nicht installiert haben, und jetzt können wir mit der Einrichtung unserer Google Cloud-Befehlszeilenschnittstelle fortfahren . Kehren wir also zu unserem Browser zurück und klicken Sie auf Zurück, um zu Google Cloud zurückzukehren. Und lass uns mit dem nächsten Schritt fortfahren. Der nächste Schritt besteht also darin, eines der folgenden Programme herunterzuladen, nämlich das Paket für Google Cloud CLI. In Ordnung. Also werde ich das 64 Apple M One Silicon verwenden 64 Apple M One Silicon , weil das meine Maschine ist. Lass uns darauf klicken und es heißt, wir wollen den Download zulassen. Und wieder erlauben wir den Download und warten, bis der Download abgeschlossen ist. Okay, sobald der Download abgeschlossen ist, wählen wir eine heruntergeladene TAR-Datei aus und sie sollte automatisch erweitert werden. Und jetzt sehen wir, dass wir das Google Cloud SDK heruntergeladen haben. Es wurde hier zu einem Ordner erweitert. Und was wir tun werden, ist , das in unser Entwicklungsverzeichnis zu verschieben , das wir beim letzten Mal erstellt haben. Also werden wir zur Entwicklung übergehen. Hier drüben drücken wir Command Enter, um ein neues Terminal zu öffnen und einen neuen Tab zu öffnen. Versuchen wir einfach, es hierher zu ziehen , und schon haben wir es hierher gezogen Also, weißt du, all unsere Sachen im Entwicklungsverzeichnis übersichtlich angeordnet Okay, jetzt, da wir das SDK heruntergeladen haben, können wir mit den nächsten Schritten fortfahren, nämlich es tatsächlich zu installieren. Kopieren wir also diesen Befehl von hier, um das SDK zu installieren, und fügen wir ihn in eine Shell ein. Und natürlich müssen wir in das Entwicklungsverzeichnis wechseln und dann diesen Befehl einfügen. Dadurch wird die Google-Befehlszeilenschnittstelle für uns installiert , Google Cloud-Befehlszeilenschnittstelle. Und möchten Sie dazu beitragen, Google zu verbessern? Lassen Sie mich vorerst hier wählen. Okay, und weißt du, es gibt mir eine Reihe von Komponenten , die es installiert hat. Abgesehen von den Komponenten aktualisiert es auch Ihre Pfadvariable und ermöglicht die Vervollständigung von Shell-Befehlen. Außerdem wird Ihre Pfadvariable und ermöglicht die Vervollständigung von Shell-Befehlen nach einer RC-Datei für alle Einstellungen gefragt , die in dieser Datei eingegeben werden müssen Also lasse ich dieses Feld leer , um das Standardfeld zu verwenden. Ich möchte den Python-Installer nicht ausführen , da ich ihn bereits installiert habe, also sage ich dort nein, dann gehe ich zurück und beginne mit dem Befehl init Also das ist der Innit-Befehl für mich, und lassen Sie uns ihn einfach hier einfügen. werden also aufgefordert, uns tatsächlich in unser Google-Konto einzuloggen, und da ist es Sie müssen sich also anmelden, um fortzufahren. Möchten Sie sich anmelden? Also sage ich ja. Also melde dich hier mit deinem Konto an. Sobald Sie sich angemeldet haben, werden Sie um Erlaubnis gebeten, also werde ich hier auf Weiter klicken. Okay, und jetzt heißt es, dass Sie mit der Google-Befehlszeilenschnittstelle authentifiziert sind mit der Google-Befehlszeilenschnittstelle authentifiziert Also gehe ich zurück zum Terminal und es heißt, du weißt schon, wähle ein Cloud-Projekt aus, das du verwenden möchtest Das wird also das Standardprojekt sein , das es verwenden wird, und ich werde das erste Element verwenden, also werde ich eins drücken und es eingeben. Es ist also das aktuelle Projekt, und es scheint, dass alle Int-Aspekte abgeschlossen sind. 28. 8.4 Erstellen eines Docker-Images für Google Cloud: Leute. Jetzt werden wir unseren Server mit Cloud Run in Googles Cloud bereitstellen Run in Googles Cloud Um unseren MCP-Server in der Cloud von Google bereitzustellen, müssen wir zunächst das Docker-Image dafür für Google Cloud erstellen das Docker-Image dafür für Wechseln wir zum Terminalserver-Verzeichnis. Ordnung, also werde ich zum SSE-Serververzeichnis des MCP-Servers wechseln SSE-Serververzeichnis des MCP-Servers Dann verwende ich einen Docker-Build-Befehl. Ich gebe die Plattform als Linux-Slash AMD 64 an, was für Googles Cloud benötigt wird Und ich werde das gemäß den Cloud-Namenskonventionen von Google kennzeichnen , was gcar dot IO für Googles Container Registry ist Dann haben wir die KI-Sprache Pd, was mein Projektname ist, und dann haben wir den Namen des Images und den Punkt für den Build-Kontext. Drücken wir die Eingabetaste. Ordnung. Sobald der Build fertig ist, können wir das Image tatsächlich in die Container-Registry von Google übertragen, von wo aus wir es tatsächlich in Google Cloud bereitstellen können . 29. 8.5 Bereitstellen von MCP SSE Server auf Google Cloud Run: Ordnung. Sobald der Build fertig ist, können wir das Image tatsächlich in die Container-Registry von Google übertragen, von wo aus wir es tatsächlich in Google Cloud Run bereitstellen können . Um das Image zu pushen, verwenden wir Docker Pushgc Punkt I, die KI-Sprache Prod und einen Schrägstrich für den MCPSSE-Server. Dadurch wird das Image, das wir gerade erstellt haben, übertragen In Ordnung. Sobald der Push-Befehl abgeschlossen ist, wir den Befehl Deploy aus. Das ist GCloud Run Deploy. Wir geben den Namen an , der MCP SSE Server lautet, dann stellen wir das Image-Tag Wir verwenden grundsätzlich die verwaltete Plattform, wählen eine Region aus und stellen einen Port zur Verfügung, und wir ermöglichen den nicht authentifizierten Zugriff für sicher, dass Sie die Cloud-Run-API tatsächlich deaktivieren , nachdem Sie sie selbst getestet haben , und verwenden dafür einen Sicherheitsmechanismus, da es riskant sein kann, sie nicht authentifiziert zu lassen Drücken wir die Eingabetaste, um sie bereitzustellen. Ordnung. Also das wird bereitgestellt und stellt uns eine URL für den Dienst zur 30. 8.6 Testen von MCP SSE Server in Google Cloud: Lassen Sie uns das jetzt löschen und in unser Kundenverzeichnis wechseln . Jetzt schreiben wir UV run und dann schreiben wir den Namen unseres Clients und geben die URL an, die wir gerade erhalten haben, und wir geben SSE als Endpunkt an, weil das für die Initialisierung benötigt wird wir nun die Eingabetaste. Und Leute, ist es nicht erstaunlich , dass unser MCP-Server jetzt hier in Googles Cloud läuft und wir unseren Client mit diesem bestimmten Endpunkt ausführen können unseren Client mit diesem bestimmten Endpunkt Jetzt haben wir die SR-Client-Auflistungstools initialisiert und die Verbindung zum Server mit den Tools Run Command und Hinzufügen von Nummern getrennt . Der MCP-Client wurde gestartet, geben Geben wir also unsere Abfrage ein. Also werden wir das AdNumbersToL verwenden und ich werde es bitten, Zahlen zu addieren Jetzt habe ich Sie gebeten, mit dem Tool zum Hinzufügen von Zahlen zwei und vier zu addieren Da es sich um eine einfache Bedienung handelt, habe ich das zu verwendende Tool ausdrücklich erwähnt, da ich möchte, dass Gemini das Tool verwendet , anstatt nur Zahlen selbst hinzuzufügen Und jetzt werden wir prüfen, ob unser in der Cloud gehosteter MCP-Server tatsächlich eine Verbindung zu dem Client herstellen kann , der gerade auf unserem Laptop läuft Lass uns die Eingabetaste drücken und sehen, was passiert. Okay, also hat Gemini den Tool-Aufruf angefordert , Zahlen mit den Argumenten vier und zwei hinzuzufügen Das ist perfekt. Und dann ist die Summe von zwei und vier sechs. Und Leute, ist es nicht ganz erstaunlich, dass wir unseren MCP-Server erstellen, ihn in der Cloud auf Google Cloud hosten und das dann im Grunde mit einem Client auf unserem Laptop ausführen konnten ihn in der Cloud auf Google Cloud hosten und das dann im Grunde mit einem Client auf unserem Laptop ausführen Und dies ist der erste Schritt um MCP-Server grundsätzlich im Internet einzurichten und sie für Kunden auf der ganzen Welt leicht zugänglich zu machen der ganzen Welt leicht zugänglich zu 31. ABSCHNITT 9 ERSTE Schritte - STREAMBARER HTTP MCP SERVER - 9.1 Kurzübersicht über MCP und was ist Streamable HTTP: Heute betrachten wir den Transportmechanismus im Modellkontextprotokoll, das bezeichnet Es ist ein neuer Mechanismus im Vergleich zu den beiden früheren, die wir hatten, nämlich STD IO, er ist immer noch da, und dann hat der Server Ereignisse gesendet, was jetzt möglicherweise veraltet sein wird Ich gehe auf die Interaktionen zwischen Client und Server ein , des gesamten Lebenszyklus einer Sitzung möglich Sie können also zu Model Context Protocol Dot IO Slash Introduction übergehen . Dort finden Sie eine ziemlich gute Einführung in MCP Ich werde hier nur einige grundlegende Konzepte durchgehen , und wie Sie vielleicht bereits wissen, handelt es sich um einen Kommunikationsstandard, der von anthropic veröffentlicht wurde und darauf ausgelegt ist von anthropic veröffentlicht wurde und darauf ausgelegt ist , strukturierte Interaktionen zwischen Clients zu erleichtern , die wir als MCP-Clients und MCP-Server bezeichnen , was Sie Dies sind eine Reihe von Servern hier, die über den MCP-Client Verbindung zu einem Host Und dieser Client ist zum Beispiel eine Anwendung auf Ihrem Computer oder Mobilgerät, die Daten oder Aktionen anfordert Und kann auch auf andere Ressourcen zugreifen. Daher hosten die Kunden in der Regel ein LLM oder greifen darauf zu, wie Cloud oder GPT oder Gemini oder was Dabei kann es sich um einen LLM-basierten Agenten handeln, MCT verwenden kann Der Agent kann also das Model Context-Protokoll verwenden und hat Zugriff auf all diese Server und Tools auf den Servern Der Agent kann also entscheiden , dass er ein Tool verwenden möchte von einem dieser Server und dieses dann verwenden, um beispielsweise über einen anderen Server auf eine Datenquelle A oder eine Datenquelle B zuzugreifen oder auf Ressourcen über das Internet oder auf Remotedienste wie den hier erwähnten Remotedienst C Über eine Web-API über diesen MCP-Server. Die Kommunikation zwischen dem Host mit dem MCP-Client und dem MCP-Server erfolgt jedoch MCP-Client und dem MCP-Server über das Model Der Server verarbeitet im Grunde die Client-Anfragen und sendet Antworten zurück oder er kann Nachrichtenströme über vom Server gesendete Ereignisse zurücksenden , die wir uns ansehen, und sogar Es handelt sich also um eine bidirektionale Client-Server-Kommunikationsarchitektur wie Sie hier sehen können Nun, da diese Kommunikation stattfindet, müssen wir einen Standardtransportmechanismus für diese Client-Server-Kommunikation definieren , und soci macht das und sie geben uns zwei davon Einer dieser Transportmechanismen ist also Streamable SGDP und der andere ist Streamable SUDP ermöglicht die Kommunikation über das Internet. Dieser Server muss also nicht lokal betrieben werden. Es kann auf einer Cloud-Plattform gehostet werden, und Streamable SDDP hilft Ihrem Client, der möglicherweise lokal auf Ihrem Computer ausgeführt wird, oder Sie greifen möglicherweise über eine Website darauf zu, die auf einem anderen Server gehostet wird So kann es über streambares SDDP mit diesem externen MCP-Server kommunizieren, bei dem es sich um einen Remoteserver handelt . Transportmodus. Dadurch wird die Kommunikation über das Internet ermöglicht und die Server können mehrere Clients gleichzeitig über kontinuierliche Nachrichtenströme verwalten . Das ist also der Vorteil der SEDP-Kommunikation über das Internet und Verarbeitung mehrerer kontinuierlicher Nachrichtenströme Mit mehreren Clients. Was ist also SDD IO? SDD IO ist ein weiterer Transportmechanismus und es handelt sich um eine Client-Server-Kommunikation, die andererseits die Kommunikation über Standard-Eingangs- und Ausgangskanäle ermöglicht über Standard-Eingangs- und Ausgangskanäle Möglicherweise haben Sie einen MCP-Server B. Nehmen wir an, dieser läuft auf einem lokalen Unterprozess auf Ihrem Computer und die Client-Server-Kommunikation kann Sie können das also mit SDD IO aktivieren und dabei werden im Grunde die Standardeingabe und -ausgabe für die Kommunikation zum und vom Client verwendet die Standardeingabe und -ausgabe für die Kommunikation zum und vom 32. 9.2 Überblick über Streamable HTTP mit Sequenzdiagramm: Also, was werden wir heute tun? Wir werden die MCV-Kommunikation über das Internet mithilfe von Streamable GDP untersuchen über das Internet mithilfe und wir werden jeden Schritt aufschlüsseln und dies in einem Sequenzdiagramm zeigen Lassen Sie mich jetzt zu dem Sequenzdiagramm übergehen. Großartig. Sehen wir uns jetzt dieses Sequenzdiagramm an. Dieses Diagramm zeigt die beiden Teilnehmer, den Client und den Server, an diesem Transport und die Interaktionen zwischen ihnen über den gesamten Lebenszyklus. weiteren Verlauf sehen wir also die Lebenszyklusereignisse wie Initialisierung, Client-Anfrage usw. Und das sind die beiden Teilnehmer, die interagieren, und das sind die detaillierten Interaktionen , die zwischen ihnen stattfinden , wie Aosovos zeigt Das ist im Grunde ein Sequenzdiagramm. Der Kunde initiiert die Kommunikation, indem Anfragen und Benachrichtigungen sendet. Der Server beantwortet Kundenanfragen, sendet Daten zurück, verwaltet die laufende Kommunikation und initiiert möglicherweise auch Anfragen nach zusätzlichen Daten. Streamable SEDP ermöglicht diese kontinuierliche Kommunikation über drei Mechanismen Es gibt SEDP-Post-Anfragen. kann eine Post-Anfrage Der Client kann eine Post-Anfrage an den Server Es gibt auch Get-Anfragen, die gestellt werden können , um diese Kommunikation zu initiieren und die Kommunikation zu ermöglichen. Es gibt Server-Send-Event-Streams, sodass der Server Datenströme zurücksenden kann. Möglicherweise wird JSN RPC an verschiedenen Stellen erwähnt oder es werden Jason-Nachrichten gesendet JCN RPC ist also das Protokoll für Nachrichten. den gesendeten Nachrichten handelt es sich also um JCN-RPC-Nachrichten, die in UTF 8 codiert sind , und JCN RPC ist im Grunde ein leichtes Textbasisformat für den Datenaustausch und stützt sich auf JCN, die JavaScript-Objektnotation, dann ist UTF 8 ein Kodierungsstandard, dann ist UTF 8 Bei den gesendeten Nachrichten handelt es sich also um JCN-RPC-Nachrichten, die in UTF 8 codiert sind, und JCN RPC ist im Grunde ein leichtes Textbasisformat für den Datenaustausch und stützt sich auf JCN, die JavaScript-Objektnotation, dann ist UTF 8 ein Kodierungsstandard, der alle möglichen Unicode-Zeichen kodieren kann. Dadurch wird sichergestellt, dass Nachrichten, die über das Netzwerk gesendet werden, unabhängig von der Komplexität der Sprache oder der Symbole usw. allgemein verstanden werden verstanden . Das ist also das Protokoll für Nachrichten, das innerhalb von streamable SGDP verwendet wird innerhalb von streamable SGDP verwendet wird Wir werden uns also fünf verschiedene Aspekte des Lebenszyklus der streambaren SGDP-Kommunikation Einer davon ist die Initialisierung, die hier in der grauen Box angezeigt wird Der Client führt also die Initialisierung durch. Dann können Sie in der grünen Box sehen, wie der Client Anfragen an die Server stellt , und wie wird das behandelt? Im gelben Feld können Sie dann Benachrichtigungen und Antworten der Kunden sehen. Wie sendet der Client also Benachrichtigungen oder Antworten an den Server? Dann die lila Box hier drüben, wir haben die vierte, die auf Nachrichten vom Server wartet. Der Client kann tatsächlich Nachrichten abhören , die vom Server gesendet werden. Und schließlich haben wir die Sitzungsverwaltung. Wie werden also verschiedene Aspekte der Sitzung in Stream Let behandelt? 33. 9.3 Initialisierungsphase: Fangen wir mit der Initialisierung an. Der Client sendet eine Post-Anfrage auf dem Slash-MCP-Endpunkt an den Server . Dabei handelt es sich um eine initialisierte Anfrage zum Starten der MCP-Sitzung handelt es sich um eine initialisierte Anfrage zum Starten Sie spezifiziert die akzeptierten Antworten, d. h. Anwendungs-JSON für eine einzelne einfache Antwort in Jason Und der andere, den es spezifiziert, ist der Text-Slash-Event-Stream, dem es sich im Grunde um einen Stream von SSE-Nachrichten handelt, die er empfangen kann Gemäß dem streambaren SVB-Protokoll müssen die Clients beide akzeptieren Der Client kann nicht sagen, dass wir SSE-Nachrichten nicht als Stream akzeptieren Wir akzeptieren nur einfache JSON-Antworten, aber das kann nicht passieren. Client Wenn Sie einen Client erstellen, müssen Sie für beide erstellen. Zweitens gibt diese Initialisierungsanfrage keine MCP-Sitzungs-ID an Diese MCP-Sitzungs-ID wird also vom Server generiert. Es ist eine optionale ID, aber in diesem vollständigen Sequenzdiagramm gehen wir davon aus, dass der Server diese MCP-Sitzungs-ID erstellt, weil das dann die Verwaltung der Sitzung ermöglicht, oder? MCP-Sitzungs-ID erstellt, weil das dann die Verwaltung der Sitzung ermöglicht, oder Und dann ist da noch die initialisierte Anfrage, die als Teil dieser Post-Anfrage enthalten ist als Teil dieser Post-Anfrage enthalten Der Server antwortet mit einer initialisierten Antwort. Er stellt eine eindeutige Sitzungs-ID bereit, die MCP-Sitzungs-ID, und das nennen wir eine initialisierte Diese Sitzungs-ID wird für nachfolgende Kommunikationen verwendet, und wenn der Server mit der Sitzungs-ID antwortet, müssen die Clients diese MCP-Sitzungs-ID für alle weiteren Anfragen in den Header aufnehmen diese MCP-Sitzungs-ID für alle weiteren Anfragen in , und das ist ein Mandat Nach dieser initialisierten Antwort sendet der Client eine POST-Anfrage an den MCP-Endpunkt mit einer initialisierten Benachrichtigung weitere Interaktionen bereit ist Ich sende die MCP-Sitzungs-ID und die Benachrichtigung im Hauptteil, und der Server antwortet mit einer Bestätigung, dass er die Benachrichtigung erhalten hat, mit einer SDDP 202-Antwort, die SDDP Das passiert bei der Initialisierung. 34. 9.4 Clientanforderungsphase von Streamable HTTP: Jetzt gehen wir zu den Kundenanfragen über. Was hier passiert, ist, dass der Client , der durch diese vertikale Linie dargestellt wird, eine Post-Anfrage an den Slash-MCP-Endpunkt sendet eine Post-Anfrage an , die die Sitzungs-ID enthält, und wiederum mit dem Accept-Header, der besagt, dass er beide Arten von Antworten akzeptiert , und einen Hauptteil mit der Was auch immer die Anfrage ist, ob ich dieses Tool ausführen möchte oder was auch immer das sein mag, der Server kann antworten und hat zwei Es gibt eine Option, nämlich eine einzige Antwort. Und der Server sendet sofort eine einzige JSON-Objektantwort und die Antwort befindet sich im Hauptteil und damit ist die Antwort im Grunde abgeschlossen. Die zweite Option ist, dass der Server einen SSE-Stream öffnen kann. Der Server antwortet also entweder mit dem Inhaltstyp „ Anwendungs-JSON “ oder mit einem Text-Slash-Event-Stream-Inhaltstyp, was im Grunde bedeutet, dass er einen SSE-Stream initiiert, kontinuierlich Daten sendet und mit dem Client in Echtzeit interagiert, wobei der Server kontinuierlich SSE-Nachrichten an den Client sendet, bei denen es sich um Echtzeitaktualisierungen handelt Das sind also die SSE-Nachrichten vom Server. Und es gibt eine optionale Eingabeanfrage , die der Server senden kann , und dann kann der Client antworten. Es kann die erforderliche Eingabe zurücksenden. Es gibt auch eine optionale Benachrichtigung. Jason RPC-Benachrichtigungen, die vom Server gesendet werden können, um den Client über wichtige Aspekte zu informieren , die er möchte Und wenn das alles erledigt ist, kann der Server den SSE-Stream mit einer abschließenden Antwort hier schließen den SSE-Stream mit einer abschließenden Antwort hier So läuft die Kommunikation also ab, wenn der Client eine Anfrage stellt 35. 9.5 MCP-Clientbenachrichtigungen und -antworten: Als Nächstes haben wir Kundenbenachrichtigungen oder -antworten. Was hier passiert, ist, dass der Client Benachrichtigungen oder Antworten per Post-Slash-MCP an den Server sendet Post-Slash-MCP an und der Server auf zwei Arten reagiert Entweder sendet er die 202, die akzeptiert wurde, ohne Text. Ich akzeptiere einfach die Benachrichtigung oder Antwort oder es kann mit einer 400 Bad Request antworten, was darauf hinweist, dass eine ungültige Eingabe mit Fehler gemacht wurde, und es wird auch eine optionale JCN-RPC-Fehlerantwort zurückgesendet auch eine optionale JCN-RPC-Fehlerantwort Also akzeptiert der Server entweder diese Benachrichtigung oder Antwort oder der Server kann sie nicht akzeptieren 36. 9.6 Client-Abhören von Nachrichten vom Server in Streamable HTTP: Als Nächstes hört der Client Nachrichten vom Server ab. Der Client kann eine GET-Anfrage an den MCP-Endpunkt senden und explizit das Öffnen eines SSE-Streams anfordern Ich würde sagen, es akzeptiert Text-Event-Streams mit MCP-Sitzungs-ID mit einer G-Anfrage Und das bedeutet, dass der Server jetzt antworten kann, indem er sagt , dass SSE unterstützt wird, und er kann einen SSE-Stream öffnen, oder der Server selbst unterstützt SSE möglicherweise nicht SSE, der Server hat die Option, SSE nicht zu unterstützen, sodass er sagen kann, dass SSE nicht unterstützt wird. Dies ist ein trivialer Fall, in dem es heißt, dass die 405-Methode nicht zulässig ist, und das ist die Antwort , die der Client zurückerhält Aber der nicht triviale Fall ist dass sie tatsächlich den SSE-Stream öffnet und dann etwas Ähnliches passiert, wie wir gesehen haben, wenn Clients Anfragen initialisieren Der Server antwortet also, indem er SSE-Nachrichten in einem kontinuierlichen Stream sendet SSE-Nachrichten in einem kontinuierlichen Stream Wahlweise kann er auch Eingaben anfordern und der Client antwortet mit einer Antwort, oder er kann bei Bedarf eine Art JCN-RPC-Benachrichtigung senden Bedarf eine Art JCN-RPC-Benachrichtigung Diese sind also optional, und wenn er SSE-Stream akzeptiert, kann er Nachrichten über die SSE-Verbindung senden 37. 9.7 Sitzungsbehandlung in Streamable HTTP: Endlich haben wir die Sitzungsverwaltung und wie wird das in streamablem STP gemacht? Der erste Teil wird also nach dem Trennen wieder aufgenommen. So kann der Client eine Verbindung wieder aufnehmen, nachdem die Verbindung unterbrochen wurde, indem er eine Get-Anfrage mit der letzten Event-ID an den MCP-Endpunkt sendet mit der letzten Event-ID an den MCP-Endpunkt Und dies ist eine Ereignis-ID , die der Server möglicherweise in einer der letzten gesendeten Nachrichten angegeben hat Und dann kann der Server diese Anfrage annehmen und dann mit dem letzten Ereignis fortfahren, sodass er alle Nachrichten erneut abspielen kann, wobei die Ereignis-ID angegeben wird, sodass der Client diese Informationen abrufen kann Der Server hat also auch die Möglichkeit, die Sitzung zu beenden , wenn er aus irgendeinem Grund möchte, oder? Und wenn in diesem Fall ein Client eine Anfrage mit einer Sitzungs-ID sendet, wenn in diesem Fall ein Client eine Anfrage mit einer Sitzungs-ID sendet dass der Server geschlossen hat, muss der Server mit einer SCDP-Antwort „Vier oder Vier nicht gefunden“ antworten , und der Client muss wiederum verstehen, dass diese Sitzung geschlossen ist oder möglicherweise ungültig oder abgelaufen ist, und er muss eine neue Sitzung mit der Initialisierungsanfrage starten , die wir am Anfang gesehen haben. Dies passiert also, wenn eine Anfrage vom Client mit einer Sitzungs-ID gestellt wird , die entweder geschlossen oder ungültig oder abgelaufen ist. Und schließlich haben Sie den Client, der Sie auffordert , die Sitzung zu beenden. Der Client kann eine MCP-Löschanfrage mit der Sitzungs-ID senden eine MCP-Löschanfrage mit der Sitzungs-ID Der Server hat also zwei Optionen. Er kann entweder die Beendigung der Sitzung zulassen, und das ist hier der zulässige Fall, und der Server sendet in diesem Fall einfach eine 204-Antwort ohne Inhalt, die besagt , dass die Sitzung erfolgreich beendet wurde. Der Server könnte stattdessen auch sagen, dass die Clients die Sitzung nicht auf diese Weise beenden können , und das ist etwas, das der Server beispielsweise nicht zulässt. In diesem Fall kann er eine 405-Methode senden, die nicht erlaubt ist, und eine Sitzungsbeendigung ist nicht zulässig, was dem Client mitgeteilt wird. 38. 9.8 Externe Ressource zur Aktualisierung: Meiner Meinung nach sind dies die wichtigsten Interaktionen, die zwischen dem Client und dem Server im streambaren SGDP stattfinden , wenn es als Transportmodus für die MCP-Client-Server-Kommunikation verwendet wird für die MCP-Client-Server-Kommunikation Dies deckt die meisten Interaktionen ab, die stattfinden. Es gibt einige, die vielleicht nicht behandelt wurden, und Sie können sich dafür diese spezielle Website ansehen, Modell Context Protocol Punkt I, Sie können das Menü hier aufrufen und dann nach unten zum Protokoll und dann zum Transport scrollen . Und sobald Sie auf Transporte klicken, haben Sie alle Informationen darüber, wie SGDIO funktioniert, wie streamable SGDP Und es gibt viele Textdetails . Ich habe versucht, dies mit den meisten dieser Dinge in ein Diagramm umzuwandeln mit den meisten dieser Dinge in ein Diagramm Aber nur als Vorbehalt, Sie sollten sich das auch durchlesen und eine der Regeln ist, dass Sie jedes Mal, wenn Sie mit einem Protokoll arbeiten, die Vor- und Nachteile dieses der Regeln ist, dass Sie jedes Mal, wenn Sie mit einem Protokoll arbeiten, Protokolls verstehen Dies ist etwas, das mit jeder Version von MCP aktualisiert wird , was im Video möglicherweise nicht zu 200% möglich Wann immer Sie dieses Video sehen, gehen Sie bitte hier zur neuesten Version, gehen Sie zum Protokoll und verstehen Sie die Transporte von hier aus, um zu sehen, ob sich etwas geändert hat oder etwas aktualisiert oder übersehen wurde , sodass Sie über gehen Sie zum Protokoll und verstehen die Transporte von hier aus, um zu sehen, ob etwas geändert hat oder etwas aktualisiert oder übersehen wurde , sodass die neuesten Updates dieses Protokolls auf dem Laufenden sind . MCP ist ziemlich neu, Sie erwarten, dass Updates auch sehr, sehr schnell erfolgen Das sieht man an streambarem STDP, das nun anstelle des früheren SSE-Transportmechanismus der empfohlene Transportmechanismus sein wird SSE-Transportmechanismus der empfohlene Transportmechanismus anstelle des früheren Das ist das Sequenzdiagramm, das sie haben. Es hat eine geringere Anzahl von Interaktionen, die hier erwähnt werden, was das Sequenzdiagramm lediglich vereinfacht, aber es werden einige der Interaktionen weggelassen was das Sequenzdiagramm lediglich vereinfacht, , die wir in der anderen Sequenz behandelt haben könnten. I. Halten Sie diese Seite griffbereit und gehen Sie sie durch um sich die neuesten Updates anzusehen und nach allem, was ich möglicherweise übersehen oder falsch dargestellt habe , da dieses Protokoll sehr, sehr neu und Sie erwarten, dass sich das sehr, sehr schnell ändern wird. 39. ABSCHNITT 9.2 STARTEN Streamable HTTP MCP Server – Schritt-für-Schritt-Demo: Ich habe es getan. MCP kündigte das streamable STDP-Transportprotokoll Das ist ein Protokoll, um Ihre MCP-Clients mit Remote-MCP-Servern über das Internet zu verbinden mit Remote-MCP-Servern über Es ersetzt den STDP plus SSE-Transport aus der früheren Protokollversion Ich habe ein Beispiel für einen streambaren STDP-Server erstellt. Nachdem wir diese streambaren STDP-Server erstellt haben, fügen wir sie dem Cloud-Desktop-Konfliktpunkt jcnFLEF Jetzt unterstützt Cloud Desktop nicht nativ streambare STP-Server, daher werden wir eine Bibliothek namens MCP Remote verwenden daher Es ist keine offizielle anthropische Bibliothek. Aber es macht den Job, und vorerst werden wir dabei bleiben Sobald Cloud seine eigene native Unterstützung für streambare HTP-Server einführt , wird empfohlen, dass Sie selbst zu dieser speziellen Implementierung wechseln Zurück zum Code, er wird sehr anfängerfreundlich mit vielen Befehlen sein und ich werde den gesamten Code hier durchgehen Und dann werden wir endlich unseren Cloud-Desktop starten und sehen, dass diese beiden streambaren STB-Server hier mit beiden Tools aufgelistet sind , und wir werden Chat verwenden, um diese Server zu testen Vergessen Sie nicht, dass wir den gesamten Code beifügen werden, den Sie herunterladen und selbst testen können also mit dieser Übersicht Lassen Sie uns also mit dieser Übersicht in die Details dieses Codes, der Codestruktur und der Dateien usw. eintauchen der Codestruktur und der Dateien usw. und dann den Code durchgehen und versuchen, ihn auszuführen Schauen wir uns also zuerst die Dateien und die Ordnerstruktur an die Dateien und die Ordnerstruktur Sie sollten den Code aus unserem Github-Repo auschecken und Sie erhalten einen MCP-Unterstrich, Streamablece, einen SEDP-Stammordner Darin befindet sich ein streambarer SDP-Serverordner mit der ersten Implementierung, bei dem es sich um einen statusfreien Server handelt . Dieser ist durch den einen statusfreien streambaren Ordner gekennzeichnet. Und das implementiert zwei Server, Server eins und Server Bei beiden handelt es sich um streambare SDB-Server , die jeweils zwei Tools bereitstellen Server eins stellt ein Tool zur Verfügung, um Zahlen zu addieren und Zahlen zu subtrahieren, und Server zwei stellt ein Tool zum Multiplizieren und Dividieren von Zahlen und Server zwei stellt ein Tool zum Multiplizieren und Dividieren ein Tool zum Multiplizieren Das Hauptskript mit Punkt P wird verwendet, um die Server einzeln zu starten Indem Sie den Servernamen entweder als Server eins oder als Server zwei angeben . Schauen wir uns nun den Code für den Server an. Also gehen wir zum Server One Dot Py und wir sehen, dass wir hier einen schnellen MCP-Server erstellen . Das initialisiert also einen MCP-Server mit den Eigenschaften Name, der auf Stateless Arithmetic Server gesetzt ist , Host, der auf Local Host gesetzt ist, dann haben Sie einen Port , der standardmäßig 3.000 für Server eins und 3.001 für Server zwei ist 3.000 für Server eins und 3.001 für Server Sie können jedoch einen Port angeben, während Sie dies mit während Und dann erzwingen wir das zustandslose Verhalten, indem das STP-Flag mit statusfreiem Unterstrich STP-Flag Dadurch wird sichergestellt, dass zwischen Anfragen kein Sitzungsspeicher gespeichert wird Und das liegt daran, dass wir in dieser speziellen Vorlesung ein grundlegendes Beispiel für einen streambaren HTTP-Server behandeln möchten Vorlesung ein grundlegendes Beispiel für einen streambaren HTTP-Server dieser speziellen Schauen wir uns nun die Codefragmente für das Schema, das Eingabeschema und das Ausgabeschema aus den Tools Sie sehen, dass wir das Eingabeschema pedantisch definieren. Dieses Schema validiert die an das Tool übergebenen Eingaben. Also zum Beispiel A, Colin 3.5 und B Colin 7.2, sind zwei doppelte Zahlen, die das Tool erwartet und Sie tun dies, indem Sie hier eine Klasse erstellen, wir nennen Und hier sind zwei Variablen A und B mit spezifizierten Typhinweisen angegeben, sodass schnelles MCP dann verstehen kann, was das Eingabeschema In ähnlicher Weise haben wir ein arithmetisches Ergebnis, das das Ausgabeschema ist Es ist auf die gleiche Weise definiert, aber hier haben wir zwei Variablen Ergebnis und Ausdruck Das Ergebnis ist ein Float, das das Ergebnis der Operation angibt , und der Ausdruck ist die Operation, die ausgeführt wurde, und es ist wieder so, dass und es ist wieder so, diese Typhinweise MCP helfen analysieren, wie das Ausgabeschema aussehen soll Als Nächstes werden wir uns die MCP-Tooldefinition selbst ansehen die MCP-Tooldefinition Sie können also sehen, dass wir den Decorator verwenden und das Tool Rate of MCP Dot hinzufügen, um diese Funktion als aufrufbares Tool im MCP-Server zu registrieren aufrufbares Tool im Und der Name des Tools ist Unterstrichzahlen hinzufügen. Es ist als Python-Funktion definiert und nimmt die Eingabe, die vom Typ Aalthmetic Input ist, und gibt uns dann nach der Ausführung der Operation das Ergebnis, das vom Typ arithmetisches Ergebnis ist Das Ergebnis ist einfach Params Punkt A plus Params Punkt B, weil es sich um eine Addition von Zahlen handelt, und hier geben wir das arithmetische Ergebnis zurück Ähnlich haben wir auch das Tool zum Subtrahieren von Zahlen, das wiederum mit diesem Dekorator spezifiziert wird Und dann haben Sie die Operation hier ausgeführt, das ist Params Punkt A minus Params Punkt B und die Rückgabe für das arithmetische Ergebnis hier drüben das ist Params Punkt A minus Params Punkt B und die Rückgabe für das arithmetische Schließlich werden wir uns ansehen, wie dieser Server betrieben wird. Dazu rufen wir einfach mcp dot run mit dem Transport auf, der als streamable STTP spezifiziert ist, und das startet den schnellen MCB-Server mit streamablem STTP-Transport Er lauscht auf dem Slash-MCP-Endpunkt. Und reagiert auf JSON-RPC-Anfragen. Es gibt einige Ausnahmebehandlungen, die wir hier durchführen, und schließlich ist es das, was unseren Server startet Das gesamte Skript wird mit der Hauptfunktion ausgeführt. Die Hauptfunktion wird mit Click in einen CLI-Befehl umgewandelt , und Sie können die Optionen für den Port angeben, angibt, auf welchem Port der Server ausgeführt werden soll. Der Standardport ist 3.000 und Sie können auch eine Protokollebene angeben, den Standard-Beam-Debug, wo Sie angeben können, welche Protokollierungsebene für alle Logging-Anweisungen verwendet werden soll , die im Con gedruckt werden , das ist alles für den Servercode, und Server zwei ist sich ziemlich ähnlich, außer dass die beiden Tools eine andere Logik implementieren für Multiplizieren und Dividieren der Zahlen. Sie können sich das also ansehen und der Code ist dem was wir bereits in Server 1 behandelt haben, sehr ähnlich bereits in Server 1 behandelt Schauen wir uns nun die endgültige Datei an, nämlich Hauptpunkt P , der der Treiber für unseren Code ist, und diese wird verwendet, um beide Server zu starten. Zunächst importieren wir Server eins und Server zwei, ihre Hauptfunktionen als Server eins underscore main und Server zwei underscore Dann haben wir wieder die Hauptfunktion für dieses spezielle Treiberskript, das mit einem Klick in einen Einstiegspunkt für die Befehlszeilenschnittstelle umgewandelt wird mit einem Klick in einen Einstiegspunkt für die Befehlszeilenschnittstelle Die verfügbaren Optionen bestehen darin, den Server anhand von zwei Optionen anzugeben Server eins und Server zwei. Und es gibt wieder eine Protokollebene, die definiert, welche Protokollierungsebene wir verwenden müssen. Wir haben dann den Anfang der Hauptfunktionen. wird der Server verwendet, der in der Protokollebene angegeben ist, die während der Ausführung angegeben wurde. Wenn es sich bei dem Server um Server eins handelt, starten wir Server eins mit demselben Log-Level-Argument, und wenn es sich um Server zwei handelt, starten wir Server zwei. Dieser Block stellt sicher , dass die Hauptfunktion nur ausgeführt wird, wenn dieses Skript direkt ausgeführt wird. Okay, jetzt haben wir die wichtigsten Komponenten für den Servercode behandelt und verstehen den Treibercode , der den Server startet. Bevor wir den Server tatsächlich starten und testen, schauen wir uns auch den Cloud-Desktop-Konfigurationspunkt jcnFle an Dies ist die Cloud-Desktop-Konfigurationsdatei mit dem Punkt GSN und enthält auch eine Erklärung, wie man sie unter Windows einrichtet Aber hier spezifizieren wir MCP-Server und wir spezifizieren Server eins und Server zwei Server eins, wir verwenden den Befehl NPX, weil wir dieses MCP-Remote-Paket ausführen möchten, und geben dazu die URL des Servers MCP Remote hilft uns dabei, diesen Server, einen streambaren HTTP-Server, mit dem Cloud-Desktop-Client zu verbinden einen streambaren HTTP-Server, mit dem zu Wie Sie derzeit wissen, unterstützt der Cloud-Client StreamBL STDP nicht , und MCP Remote ist dazu da, dieses Problem für uns zu lösen, indem es diesem Client ermöglicht, eine Verbindung zu dem von uns bereitgestellten StreamBL ist dazu da, dieses Problem für uns zu lösen, indem es diesem Client ermöglicht, eine Verbindung zu dem von uns bereitgestellten StreamBL STB-Server herzustellen. In ähnlicher Weise spezifizieren wir Server zwei. Der Befehl lautet NPx und für die Argumente geben wir im Grunde den Paketnamen MCP remote an, wir im Grunde den Paketnamen der bei der Verbindung hilft, und wir geben die URL für Server zwei an, der dem lokalen Host befindet, aber auf Pod Auch hier sind die Endpunkte beide Schrägstrich-MCP, und genau das haben wir für den Cloud-Desktop-Konflikt Punkt GSN 5 eingerichtet Cloud-Desktop-Konflikt In Ordnung, schauen wir uns jetzt an, wie die Server gestartet werden. Dazu öffnen Sie ein Terminalfenster und wechseln zu dem Verzeichnis in dem Sie den Code ausgecheckt haben. Also habe ich das ausgecheckt und cp MCP Underscorestream Undersce STP. Ich werde in dieses Verzeichnis wechseln. Lassen Sie uns jetzt unsere virtuelle Umgebung aktivieren. Also werden wir zuerst UV Space V NV ausführen. Dadurch werden der Ordner Dot V NV und die virtuelle Umgebung für uns erstellt. Jetzt werden wir die virtuelle Umgebung mit dem Quelltext dot n slash Bnlash Activate aktivieren Quelltext dot n slash Bnlash Dann können wir einfach alle Pakete installieren , indem wir uvSpaceSync eingeben Dadurch werden alle Pakete für uns eingerichtet Jetzt können Sie Server eins ausführen, indem Sie UV run eingeben und dann die aktive Flanke für diese virtuelle Umgebung durchmachen, dann den Namen des Ordners eingeben, bei die aktive Flanke für diese virtuelle Umgebung durchmachen, dann den Namen des Ordners eingeben, dem es sich um einen streambaren HDP-Server handelt, und dann einen stateless Dash Streamable angeben , der der Ordnername für unseren Staless-Server ist , und dann gefolgt vom Hauptskript zum Ausführen dieses Servers. Außerdem geben wir das Server-Flag an, das wir zuvor gesehen haben, und wir geben Server 1 als den Server an , den Dann geben wir die Protokollebene an, die nur Informationen enthält, und drücken die Eingabetaste. Dadurch wird Ihr Server auf dem lokalen Host 3.000 gestartet, was ein Standardport für Server 1 ist. In ähnlicher Weise können Sie ein neues Terminalfenster im selben Ordner öffnen und Ihre virtuelle Umgebung aktivieren. Geben Sie dann denselben Befehl ein, geben Sie hier jedoch Server zwei als Serveroption an und drücken Sie die Eingabetaste. Und das wird Ihren zweiten Server auf dem lokalen Host-Port 3.001 starten Ihren zweiten Server auf dem lokalen Host-Port 3.001 Sobald diese beiden Server gestartet sind, können wir sie tatsächlich mit einem MCP-Client testen , der streambares HTTP unterstützt Im Moment werden wir Cloud Desktop mit Hilfe des Pakets MCP Remote verwenden , das uns hilft, Cloud-Desktop mit diesen beiden Servern zu verbinden Ordnung. Lassen Sie uns jetzt endlich mit Cloud Desktop, unserem streambaren HTP-Server, testen unserem streambaren HTP-Server Starten Sie einfach Cloud Desktop, nachdem Sie die Desktop-Konfliktdatei eingerichtet haben, die wir Danach sehen Sie dieses Willkommensfenster. Und sobald Sie hier auf die Schaltfläche Suchen und Tools klicken , können Sie sehen, dass zwei Server mit jeweils zwei Tools verfügbar sind . Der erste Server hat Zahlen addieren und Zahlen subtrahieren und der zweite Server hat Zahlen multipliziert und Zahlen dividiert Dies sind die beiden verfügbaren Tools . Wir können hier auf B klicken und es einfach bitten , die gewünschten Funktionen auszuführen Ich werde zuerst fragen, auf welche Tools Sie Zugriff haben, Okay. Und wir sehen, dass es erfolgreich die Werkzeuge für mathematische Operationen auflisten, Zahlen addieren, Zahlen subtrahieren, Zahlen multiplizieren und Zahlen dividieren kann die Werkzeuge für mathematische Operationen auflisten, Zahlen addieren, Zahlen subtrahieren, Zahlen multiplizieren und Zahlen dividieren Ordnung, also werde ich es bitten, zwei beliebige Zufallszahlen, 513 und drei, mit Hilfe der Tools zu dividieren zwei beliebige Zufallszahlen, 513 und drei, mit Hilfe der Wir sehen also, dass dort steht, dass ich 513 mit dem Divisionswerkzeug durch drei teilen werde , und es sendet eine Anfrage mit den Parametern A als 513 und B als Und die Antwort, die es erhält, enthält die beiden Klassenvariablen, die wir im Pitantic-Modell betrachtet haben Das eine ist das Ergebnis, das 171 ist, was richtig ist. Und dann haben wir den Ausdruck , der 513 geteilt durch ist Und schließlich interpretiert es dieses Ergebnis und sagt uns, dass das Ergebnis 171 ist, also 513/3 gleich 171 ist also 513/3 Also, Leute, das ist unglaublich. Dies ist der erste Schritt, den wir unternommen haben , um unseren MCP-Server aufzubauen, dem es sich um einen streambaren SDP-Server handelt. Dies ist ein neues Protokoll, das servergesendete Ereignisse durch das SGTP-Protokoll ersetzen wird servergesendete Ereignisse durch das SGTP-Protokoll ersetzen das SGTP-Protokoll 40. ABSCHNITT 9.3 STARTEN eines streambaren HTTP-MCP-Clients mit Gemini und Google ADK – Einführung: Alle, das Model Context-Protokoll hatte das streamable STTP-Transportprotokoll angekündigt, und dieses wird den STTPPlus SSE-Transport aus den früheren Protokollversionen ersetzen STTPPlus SSE-Transport aus den früheren Protokollversionen und dieses wird den STTPPlus SSE-Transport aus den früheren Protokollversionen ersetzen. Es wird verwendet, um MCP-Server zu erstellen, die remote bereitgestellt werden können und über das Internet mit MCP-Clients arbeiten über das Internet mit MCP-Clients Ich werde Sie durch den gesamten Code führen, damit Sie Ihren MCP-Client mit dem streambaren SGTP-Transport erstellen können Ihren MCP-Client mit dem streambaren SGTP-Transport Bevor wir uns den Code ansehen, möchte ich Ihnen eine kurze Demo zeigen, was wir heute erstellen werden und wie Sobald die beiden Server laufen, können wir unseren MCP-Client starten Also schreiben wir UV run und geben dann den Pfad für unser cmd dot pifle an und Jetzt können Sie sehen, dass der ADK LLM-Agenten-Chat gestartet wurde. Es bietet die Möglichkeit, das Programm zu beenden, indem Sie quit oder Colin Q eingeben. Zunächst müssen wir uns ansehen, dass wir Tools von Server eins laden konnten, das ist der HTTP-Server mit Zahlen addieren und subtrahieren, HTTP-Server mit Tools, und dann haben Sie Tools, die auch vom Server zwei geladen wurden, um Zahlen zu multiplizieren und auch vom Server zwei Zahlen zu dividieren. Und schließlich haben Sie Tools vom Serverterminal geladen Dies ist der STDIO-Server mit dem Befehl Tool run, mit dem Sie einen Terminalbefehl auf Ihrem lokalen Computer ausführen Jetzt gebe ich diesem Client eine Abfrage, die zwei Zahlen nimmt und alle Operationen ausführt, addiert, subtrahiert, multipliziert, dividiert und dann mit dem Tool „Befehl ausführen“ eine nette Zusammenfassung in eine Datei in meinem Arbeitsbereich schreibt mit dem Tool „Befehl ausführen“ eine nette Zusammenfassung , und das wird Spaß machen , weil diese einzelne Abfrage alle Tools in dieser einen Abfrage selbst verwendet. Ordnung. Also werde ich schreiben, können Sie die beiden Zahlen 32 und Zwei addieren, subtrahieren, multiplizieren und dividieren und dann die Ausgabe mit den verfügbaren Tools in eine Datei in einer gut formatierten Tabelle schreiben mit den verfügbaren Tools in eine Datei in einer gut formatierten Tabelle Lassen Sie uns die Eingabetaste drücken und sehen, was es macht. Die Sache mit dem Agent Development Kit ist nun, dass der Agent, den wir erstellt haben, Ereignisse zurückstreamt, und diese Ereignisse können dann nacheinander gedruckt werden , um den Fortschritt des Agenten zu sehen. Hier können Sie also sehen, dass wir das Ereignis Nummer eins haben, und das ist ein Funktionsaufruf der Funktion Zahlen hinzufügen. Und die beiden Parameter, die bereitgestellt wurden , sind die beiden Zahlen, die wir bereitgestellt haben, nämlich 32 und zwei Wir können jetzt runtergehen und sehen , dass es hier einen weiteren Funktionsaufruf zum Subtrahieren von Zahlen mit den beiden Parametern wieder nach unten gehen, können wir sehen, dass es einen Funktionsaufruf zum Multiplizieren von Zahlen gibt und dass es auch einen Funktionsaufruf zum Teilen von Zahlen Das sind die vier Funktionsaufrufe die das Tool im Rahmen des ersten Streaming-Updates angefordert hat , das es uns geschickt hat. Jetzt haben wir Ereignis Nummer zwei, das Zahlen addieren, und das ist eine Funktionsantwort. Das Ergebnis ist hier also 34, was richtig ist, und das ist nur die Antwort auf den Funktionsaufruf , der ausgeführt wurde. In ähnlicher Weise haben Sie eine weitere Funktionsantwort, und diese ist für das Subtrahieren von Zahlen vorgesehen Sie haben auch eine Funktionsantwort für die Multiplikation von Zahlen und Sie haben auch eine Funktionsantwort für die Division von Zahlen Das sind also die vier Funktionen , die vom Tool erfolgreich aufgerufen wurden. Jetzt können wir zu Ereignis Nummer drei gehen und dieses hat eine Textantwort, die besagt, dass ich die Berechnungen durchgeführt habe , um die Ausgabe in einer Datei zu speichern, und es hier einen Funktionsaufruf gibt dass es hier einen Funktionsaufruf gibt, der einen Befehl ausführt, der mit einer Echo-Operation für eine bestimmte Datei angefordert wurde . Dies sollte im Grunde die gesamte Ausgabe in einer gut formatierten Weise in diese Datei schreiben die gesamte Ausgabe in einer gut formatierten Weise in diese Datei Gehen wir runter und überprüfen Ereignis Nummer vier. Ereignis Nummer vier ist hier eine Funktionsantwort, und das ist der Befehl run underscore, und wir haben keine weiteren Informationen in dieser speziellen Funktionsantwort Schließlich haben Sie Ereignis Nummer fünf , ein Text vom Agenten oder unserem MCP-Client, der besagt, dass ich die Ergebnisse in den Ergebnispunkt TXT geschrieben habe Ergebnisse in den Ergebnispunkt TXT geschrieben Und schließlich sagt mir auch der Agent, dass ich die Ergebnisse in den Ergebnis-Punkt TXT geschrieben habe, was der Ausdruck der endgültigen Antwort hier ist. In diesen Streaming-Updates finden Sie detaillierte Informationen zur Funktionsweise des Agenten Und Sie haben eine abschließende Antwort, die hübsch formatiert ist, die Antwort, die Sie dem Benutzer vielleicht in einer Chat-Oberfläche mitteilen möchten , dass ich die Ergebnisse in dsuLTSTTTT geschrieben habe In Ordnung. Also bin ich im Finder-Fenster in meinem MCB-Verzeichnis und es gibt ein Workspace-Verzeichnis, das der Terminalserver verwendet. Also lass mich dazu übergehen Hier drüben habe ich diese Datei mit den Ergebnissen von DHT, also lass mich das öffnen Und jetzt können Sie sehen, dass Sie die Operation und das Ergebnis haben Die E-Flagge des Agenten wird tatsächlich angezeigt. Lass mich das ein bisschen vergrößern. Ordnung. Sie haben also die Operation und das Ergebnis mit Addition, Subtraktion, Multiplikation und Division Der Agent macht also einen ziemlich guten Job, bis auf dieses E, das extra vom Echo-Befehl kommt Gehen wir zurück zu unserem Terminalfenster Was wir jetzt gesehen haben , ist, dass zwei Server auf einer HTTP-URL mit einem bestimmten Port laufen. Diese laufen vorerst lokal, aber wir können sie sehr gut auf einem Cloud-Server bereitstellen, und es gibt einen MCP-Client, den wir mit Hilfe von Google ADK und dem Gemini-Modell erstellt haben , und dieser funktioniert, um alle auf den MCP-Servern verfügbaren Tools auszuführen , einschließlich des einschließlich Das ist ein Terminalserver, den wir nicht starten müssen, weil er lokal läuft und dann alle Operationen in einer einzigen Abfrage Wir haben fünf verschiedene Tool Calls in einer einzigen Abfrage durchgeführt. Und wir haben die Ergebnisse hier in zuls dot TXT gespeichert . Mit diesem Setup können Sie dies also als Grundlage verwenden, um dies zu verbessern und einen vollwertigen MCP-Client zu erstellen, der mit zwei verschiedenen Arten von Transporten arbeitet, die MCP bereitstellt, nämlich um dies zu verbessern und einen vollwertigen MCP-Client zu erstellen , der mit zwei verschiedenen Arten von Transporten arbeitet, die MCP bereitstellt, SDD-IO-Server und dem streambaren SGTP-Transport dem SDD-IO-Server und dem streambaren SGTP-Transport. 41. 9.3.2 Codeübersicht: Also hier ist ein Überblick über das, was ich vorbereitet habe. Ich habe den Code für einen universellen Client mit dem Agent Development Kit von Google erstellt , das unser Agent-Framework sein wird, und Gemini wird das Modell sein, das wir dafür verwenden Dies wird als universeller Client bezeichnet , da er eine Verbindung zu STD-IO-Servern und auch zu streambaren TDP-Servern herstellen kann STD-IO-Servern und auch zu streambaren TDP-Servern Dies ist also ein Client, den Sie für alle Arten von Servern verwenden können , und wir werden drei Hauptteile haben Der erste Teil wird eine Befehlszeilenschnittstelle sein. Dies ist vorerst wie die Benutzeroberfläche , in der Sie mit Ihrem Client interagieren, was vorerst über eine CLI erfolgen wird. Es wird Ihnen eine Abfrage geben, eine Aufforderung, in der Sie die Abfrage für den Kunden eingeben können, und das wird sie dann an etwas übertragen, das als Client bezeichnet wird. Die Punkt-P-Datei des Clients definiert einen MCP-Client, der eine Sitzung erstellt , den Agenten erstellt und eine Verbindung zu dem in der Punkt-PY-Datei des Agenten definierten Agenten herstellt dem in der Punkt-PY-Datei des Agenten definierten Es leitet also im Grunde alle Anfragen von Ihrer Benutzeroberfläche an den Agenten Die Punkt-P-Datei für den Agenten wird das zentrale Gehirn des MCP-Clients implementieren Es wird einen LLM-Agenten aus dem ADK-Framework von Google instanziieren , das Gemini verwendet, und es wird das MCP-Toolset von ADK verwenden, um alle verfügbaren Tools aus der MCP-Konfigurationsdatei zu laden alle verfügbaren Tools aus der und es wird das MCP-Toolset von ADK verwenden, um alle verfügbaren Tools aus der MCP-Konfigurationsdatei zu laden. Kommen wir zum Konfliktpunkt jcnFle, das wird der KI-Sprach-Underscore-Konflikt JCN sein , der unsere streambaren SDTP-Serverendpunkte und auch die Speicherorte der SDD-IO-Serverdateien definieren wird unsere streambaren SDTP-Serverendpunkte und auch die Speicherorte der SDD-IO-Serverdateien , was ein Python-Skript sein wird, das das wird der KI-Sprach-Underscore-Konflikt JCN sein, der unsere streambaren SDTP-Serverendpunkte und auch die Speicherorte der SDD-IO-Serverdateien definieren wird, was ein Python-Skript sein wird, das diesen SDD-IO-Server ausführt. Wir werden die beiden streambaren STB-Server verwenden, die wir beim letzten Mal definiert haben, um dies zu testen. Und ich werde hier einen Terminal-Underscore-Server Punkt PY hinzufügen. Dabei handelt es sich um einen Server , der über sdDiO lokal auf Ihrem Computer ausgeführt werden kann und Bearbeitungsdateien mithilfe von Terminalbefehlen erstellen kann Deshalb heißt es Terminal Underscore Server, und das wird ein dritter Server für diesen speziellen Test sein für diesen Wir werden also diesen SCD-IO-Server und die beiden streambaren STB-Server verwenden , um damit zu arbeiten Und beachten Sie, dass dies sehr anfängerfreundlich sein wird sehr anfängerfreundlich viele Kommentare im Code Ich werde auch einen Großteil des Codes durchgehen , damit Sie ihn verstehen können Der vollständige Code wird in dieser Lektion enthalten sein , sodass Sie ihn selbst herunterladen und testen können . Lassen Sie uns also eintauchen und verstehen, wie wir diesen MCP-Client erstellen können, der sowohl mit SDD-IO-Servern als auch mit streambaren GTB-MCP-Servern funktioniert sowohl mit SDD-IO-Servern als auch mit streambaren GTB-MCP-Servern streambaren GTB-MCP-Servern 42. 9.3.3 Benutzeroberfläche des MCP Clients - cmd.py: Beginnen wir also mit unserer Basisdatei, dem Befehlspunkt PI , der unser Einstiegspunkt zur Befehlszeilenschnittstelle ist , die wir gerade Der Zweck dieser Datei besteht also darin, als Einstiegspunkt für den ADK-Chat-Client zu dienen und es dem Benutzer zu ermöglichen, mit einem LLM-Agenten zu interagieren, der über das ADK von Google mit MCP-Tool-Servern verbunden Die wichtigen Aspekte dieser Datei sind also, dass sie die Kennung für die ADK-App bereitstellt Es ist also der Google ADK Gemini MCP-Client. Es stellt eine Benutzer-ID und eine Sitzungs-ID bereit, um den Benutzer und die Sitzung zu identifizieren, und es tut noch eine weitere Sache Es definiert die Tools, die der Client verwenden darf Dies ist in gewisser Weise eine Sicherheitsfunktion . Wenn Sie eine Verbindung zu einem MCP-Server herstellen und nur eine bestimmte Anzahl von Tools zugreifen möchten, können Sie diese einschränken, indem den Benutzer fragen, welche Tools er verwenden möchte , und den Benutzer, der sie auf Ihrer Chat-Oberfläche oder auf Ihrer Benutzeroberfläche bereitstellt . Oder in Ihrer App. Dies ist die Befehlszeilen-App, die wir hatten, und sie ist hier fest codiert, aber das könnte von einem Benutzer sehr gut gefragt aber das könnte von einem Benutzer sehr gut gefragt werden, welche Tools er verwenden lassen möchte. Dies ähnelt dem, was Sie in Cloud Desktop sehen, wenn Sie tatsächlich auf die Schaltfläche Suchen und Tools klicken und eine bestimmte Anzahl von Servern oder Tools zulassen oder verbieten Der andere Hauptaspekt dieser Datei ist, dass sie eine Chat-Schleife definiert, sodass der Benutzer nacheinander Anfragen stellen kann nacheinander Anfragen Es fordert den Benutzer zur Eingabe auf und sendet diese Eingabe an den ADK MCP-Agenten. Anschließend streamt es die Agentenantwort und zeigt sie an, was genau das ist, was wir In dieser Schnittstelle wird dann zuerst der ADK MCP-Client initialisiert Der MCP-Client ist in unserer Client-Pi-Datei definiert. Wir werden uns das gleich ansehen. Es liefert ihm jedoch den Namen der App, die Benutzer-ID und die Sitzungs-ID sowie den Toolfilter, den es vom Benutzer gesammelt hat. Dann rufen wir die Sitzung für unseren Kunden auf. Dadurch wird die Sitzung mit allen MCP-Tools eingerichtet. Und schließlich führen wir die Logik für diese spezielle Chat-Schleife aus , bei der der Benutzer um eine Anfrage gebeten wird Suchen Sie nach Nachrichten für quit, Q oder exit Wenn diese Nachrichten eingehen, unterbrechen wir die Schleife und beenden unser Programm. Das passiert also hier, und wenn das nicht passiert, verwenden wir im Grunde unseren Client, um eine Aufgabe mit der Benutzereingabe an den MCP-Agenten zu senden , und dann warten wir, bis alle Ereignisse zurückgestreamt werden Für jedes Ereignis verwenden wir einen Zähler, um einen bestimmten Titel anzuzeigen, nämlich Ereignis Nummer eins, zwei, drei usw. Und dann drucken wir jedes dieser Ereignisse als zugehörige Antwort Wenn eines der Ereignisse als endgültige Antwort gekennzeichnet ist, drucken wir außerdem die Antwort des Agenten Dies ist die letzte Antwort, in der der Agent sagt, ich diese spezielle Aufgabe erledigt habe, dass ich diese spezielle Aufgabe erledigt habe, und dafür greifen wir nur auf das Ereignis wegen seines Inhalts zu . Gehen Sie alle Teile durch, nehmen Sie den ersten Teil, nehmen Sie den Textinhalt von dort und drucken Sie ihn aus. wird also so etwas gedruckt wie, wissen Sie, ich habe alle Berechnungen erfolgreich durchgeführt und das Es wird also so etwas gedruckt wie, wissen Sie, ich habe alle Berechnungen erfolgreich durchgeführt und das Ergebnis als TXT-Datei mit Punkt bearbeitet, was wir auf dem Bildschirm gesehen haben. Also drucken wir die Textnachricht für die letzte Antwort aus. Aber nur für diesen Demo-Code drucken wir hier auch alle Zwischenantworten aus, damit wir sehen können, wie unser MCP-Agent funktioniert Am Ende nennen wir Client dot Shut DON. Das ist die elegante Art unserer MCP-Kunden, alle Ressourcen zu schließen und freizugeben sodass wir die Clients sicher herunterfahren können Schließlich gibt es noch den Einstiegspunkt , der ausgeführt wird, und das wird die Chat-Schleife für uns starten Und schließlich gibt es noch eine Ausnahmebehandlung für einen abgebrochenen Fehler, der möglicherweise von ACNIO herrührt Das passiert, wenn Sie aufgrund der internen Mechanik in ADK und MCP das System herunterfahren, als Sie Client Dot Shutdown aufgerufen aufgrund der internen Mechanik in ADK und MCP das System herunterfahren, als Sie Client Dot Shutdown internen Mechanik in ADK und MCP das System herunterfahren, Bei dieser Demo und dem Lerncode ignorieren wir das, indem wir es einfach aufzeichnen und diese spezielle Meldung ausdrucken Das ist also Ihre Befehls-Py-Datei. Es ist eine UI-Schnittstelle zu Ihrem MCP-Client und -Agenten. 43. 9.3.4 Implementierung des MCP Clients - client.py: Jetzt gehen wir zur nächsten bestimmten Datei in dieser Serie über , der Client-P-Webdatei Dies implementiert also die MCP-Client-Logik, und diese Datei definiert den MCP-Client , den wir in unserer Benutzeroberfläche oder der Befehlsschnittstelle verwendet haben, und es ist ein Zapper, der die Benutzeroberfläche oder die Chat-Oberfläche mit dem Google ADK-Agenten verbindet der die Benutzeroberfläche oder die Chat-Oberfläche mit dem Google ADK-Agenten Es verwaltet also den Sitzungsstatus. Es leitet die Benutzereingaben über den Agenten an die verbundenen MCP-Toolsets Der Hauptteil dieser Datei ist also die MCP-Client-Klasse, und dies ist die Haupt-Client-Schnittstelle, die die Chat-App mit dem ADK-Agenten verbindet Es wird also wieder die Sitzungserstellung, das Laden des Agenten und die Nachrichtenweiterleitung durch den Agenten an das Toolset übernehmen die Sitzungserstellung, das Laden des Agenten und die Nachrichtenweiterleitung durch den Agenten an das Toolset Zunächst haben wir den Konstruktor , der diesen speziellen Client initialisiert. Er verwendet den Anwendungsnamen, die Benutzer-ID und die Sitzungs-ID , die zusammen mit dem Toolfilter bereitgestellt wurden , der auch von der Befehlszeilenschnittstelle der Chat-App, cmd Punkt Pi, angegeben wurde Befehlszeilenschnittstelle der Chat-App, cmd Punkt Pi, Schließlich verwenden wir den In-Memory-Sitzungsdienst , der alle Ereignisse und sitzungsbezogenen Informationen während der Interaktion verarbeitet sitzungsbezogenen Informationen während der Interaktion Dabei handelt es sich um einen In-Memory-Sitzungsdienst, was bedeutet, dass es im Arbeitsspeicher und nicht in einem persistenten Speicher gespeichert wird . Dann haben wir den Agenten-Wrapper. Dies wird in der Punkt-PY-Datei für den Agenten definiert, die wir uns später ansehen Dadurch wird der Agent-Wrapper nur mit dem Tool-Filter hier erstellt , und dann haben wir den ADK-Runner , den wir später erstellen werden, während wir diese Sitzung initialisieren Der nächste wichtige Teil nach dem Konstruktor für diese Client-Klasse ist Wir erinnern uns also daran, dass wir das in der Cmd PY-Datei nennen. Dies wurde hier aufgerufen, was client.it-Sitzung Und das macht es so, dass es den Sitzungsdienst nimmt und drüben eine neue Sitzung für ADK erstellt Dann bauen wir den Agenten. Also haben wir die Build-Methode für den Agenten aufgerufen, die wir uns im Agenten ansehen Dadurch werden im Grunde das Tool und die Konfigurationen usw. für den Agenten geladen usw. für den Agenten Und schließlich werden wir den Runner mithilfe des erstellten Agenten und des Sitzungsdienstes erstellen , also werden wir den Agenten bereitstellen, den wir gerade erstellt Wir werden ihm einen App-Namen geben und wir werden einen Sitzungsdienst bereitstellen. Das ist es also, was all diese Dinge zusammenfasst und sie alle miteinander zu einem Runner-Objekt verbindet Und schließlich verwendet ADK dies, um Runner Dot Run Ace aufzurufen und den Agenten schließlich auszuführen Der dritte wichtige Aspekt in MCP-Client-Klasse ist die Funktion „Task senden Dadurch wird eine Benutzernachricht an den ADK-Agenten gesendet und die Antworten werden zurückgestreamt Wir haben bereits den Konstruktor und die Int-Sitzung erstellt, die den Agenten vorbereitet Aber schließlich müssen wir die Anfrage an den Agenten senden. Deshalb ist diese Funktion hier definiert. Und die Eingabe ist die Benutzereingabe, das ist die Roheingabe des Benutzers in natürlicher Sprache, und sie gibt einen asynchronen Generator zurück Das führt also zu Streaming-Antwortereignissen vom Agenten, was wir in der ersten Demo gesehen haben, nämlich Ereignis eins, zwei, drei usw. Um all das zu erreichen, haben wir die Benutzereingabe in ein Inhaltsobjekt mit dem Benutzer zusammengefasst. Warum tun wir das, weil ADK bestimmte Typen benötigt , um alle eingehenden und ausgehenden Daten zu verwalten Wir nehmen also die Benutzereingaben und fügen sie in einen Teil ein , der als Textteil bezeichnet wird Dann fügen wir es einer Liste hinzu und nennen das die Teileliste. Und diese Liste von Teilen, zusammen mit dem Roll-Benutzer, um anzuzeigen, dass dies vom Benutzer stammt. Dies ist eine Nachricht des Benutzers, die in ein Inhaltsobjekt verpackt ist. Dieses Inhaltsobjekt erwartet ADC, und so nennen wir die neue Nachricht Schließlich nehmen wir das Runner-Objekt, das wir oben erstellt haben, und rufen die Run-Async-Funktion mit der Benutzer-ID, der Sitzungs-ID und der neuen Das wird also unseren Runner ausführen und wir geben das zurück. Diese Rückgabe selbst wird also tatsächlich einen Async-Generator zurückgeben Es wird also ein Strom von Ereignissen sein , die vom Agenten zurückkommen werden Wenn wir jetzt zu unserer Cmd PY-Datei zurückkehren, sehen wir, dass wir mit der Benutzereingabe den Client Dot Sen Task aufgerufen haben , und das ist ein Strom von Ereignissen , der zurückkommt und von ASN Four hier drüben bearbeitet wird Am Ende haben wir hier endlich eine Shutdown-Methode. Dadurch werden der Agent und seine Tools ordnungsgemäß heruntergefahren. Daher sollte er am Ende der Sitzung aufgerufen werden, um alle ASN-Aufgaben der Agent und seine Tools ordnungsgemäß heruntergefahren. Daher sollte er am Ende der Sitzung aufgerufen werden zu bereinigen Dadurch wird einfach die Funktion zum Schließen des Agenten-Wrappers aufgerufen, und wir werden uns das in der Punkt-PY-Datei des Agenten ansehen Das ist alles für die Punkt-P-Datei des Clients, und jetzt schauen wir uns unsere Agenten-Implementierung an 44. 9.3.5 Implementierung des MCP Agenten - agent.py: Ordnung. Schauen wir uns nun die Agentenimplementierung an. Die Punkt-PY-Datei des Agenten definiert die Agenten-Wrapper-Klasse, die einen Google ADK LLM-Agenten lädt und erstellt Dies ist in der Lage, mit MCP-Servern über beide verfügbaren Transporte, nämlich SGTP oder SDIO , zu kommunizieren MCP-Servern über beide verfügbaren Transporte, nämlich SGTP oder SDIO , , Das ist also großartig, und das haben wir bereits in der Demo gesehen, und es protokolliert auch jedes geladene Tool So können Sie sehen, welche Tools es während der Initialisierung von jedem Server geladen hat während der Initialisierung von jedem Server geladen Gehen wir zur Klassendefinition selbst über. Wir haben hier die Agenten-Wrapper-Klasse, über. Wir haben hier die Agenten-Wrapper-Klasse die den Wrapper initialisiert, den aber noch nicht erstellt werden wir Self Dot Build verwenden Danach werden wir Self Dot Build verwenden, um das Setup abzuschließen, und es nimmt nur den Tool-Filter in Anspruch Der Agent muss nur wissen, welche verschiedenen Werkzeugfilter er benötigt, und er nimmt außerdem alle Serverdefinitionen, alle URLs für die SDTP-Server und den Dateipfad für das Python-Skript für die SDD-IO-Server aus dem Konfliktpunkt Also schauen wir uns am Ende das ConficTo JcnFle an, aber so lädt es alle Tools, die Confit oder JCNFle verwenden , wo es weiß, mit welchen Servern es sich verbinden muss, und es hat einen Tool-Filter, um zu wissen, welche Tools in Betracht gezogen werden müssen. Also weisen wir Filter erstellt den Agenten noch nicht und die Toolsets sind zunächst leer. Dies wird all unsere MCP-Tools enthalten. Dann ist der nächste wichtige Teil dieser Klasse die Build-Funktion, und diese wird eine Verbindung zu allen MCP-Servern herstellen , die in der Konfiguration aufgeführt sind Ich lade die Tools von jedem der Server und danach wird der ADK-Agent mit diesen Tools initialisiert Also laden wir zuerst alle Toolsets. Das wird also diese Toolsets laden und wir werden uns diese Funktion später ansehen Nehmen wir zunächst an, dass Toolsets eine Liste von MCP-Tools enthält, und zwar im richtigen Format, das ADK erwartet, da die Funktion „Toolsets laden“ eine ADK-Bibliotheksfunktion verwenden wird, um die Tools von den MCP-Servern zu laden Jetzt können wir davon ausgehen, dass die Funktion „Toolsets laden“ uns die Toolsets zur Verfügung stellt, und dann konstruieren wir den DIC-Agenten . Dieser LLM-Agent. Wir bieten das Gemini 2.0-Flash-Modell an. Wir nennen es den Enterprise Assistant. Also können wir ihm einen beliebigen Namen geben, wir geben ihm einen beschreibenden Namen , der beschreibt, was dieser Agent ist, dann haben wir einige Systemanweisungen gegeben Wir sagen, das unterstützt den Benutzer bei Dateisystem- und MCP-Serveraufgaben Auch dies könnte geändert werden. Ich habe vorerst ein sehr einfaches beibehalten, und dann haben Sie die Toolsets, die MCP-Tools Jetzt stehen diese Tools dem LLM-Agenten als Agententools zur Verfügung , die er nach eigenem Ermessen verwenden kann Wir haben hier also auch Self-Punkt-UnderscoeTol-Sets zugewiesen, was eine der Eigenschaften der Agent-Wrapper-Klasse ist der Damit ist dann das gesamte Laden, die Zuweisung der Tools und das Erstellen der Agenten abgeschlossen , und das ist die Build-Funktion, die wir in der Agent-Wrapper-Klasse haben Jetzt haben wir also die Funktion „ Toolsets laden“. Hier werden also alle MCP-Serverinformationen aus der Konfliktpunkt-JCN-Datei gelesen der Konfliktpunkt-JCN-Datei und das Toolset von jedem der Server geladen Es stellt also über SCTP oder SED IO eine Verbindung zu Es filtert die Tools, falls zutreffend. Wenn also der Werkzeugfilter bereitgestellt wurde, behält er nur die Tools bei, die in der Liste enthalten sind , und ignoriert alle anderen Tools. Anschließend druckt er die Werkzeugnamen aus, damit der Benutzer sehen kann, mit welchen Tools er eine Verbindung hergestellt hat. Es wird eine Liste von MCP-Toolset-Objekten zurückgegeben , die Agenten verwendet werden können, da wir die von ADK selbst bereitgestellte MCP-Toolset-Funktionalität verwenden bereitgestellte All dies wird also in einer gut formatierten Liste von Tools zusammengefasst. Also nennen wir zuerst Read Underscoe Conflict Association. Das ist also eine einfache Funktion aus einer Hilfsfunktion, die alle Serverinformationen aus der Konfliktdatei lädt alle Serverinformationen aus der Konfliktdatei Wir werden uns das am Ende zusammen mit der Konfliktdatei ansehen. Und wir initialisieren eine Toolset-Liste mit einer leeren Liste. Dann wird jeder Server einen Namen haben. Wir haben also alle Server unter MCP-Servern zusammengefasst. Dies ist der Standard , den alle MCP-Clients erwarten, dass alle Server unter diesem bestimmten Schlüssel aufgeführt werden Wir erhalten also diesen speziellen Schlüssel, den gesamten Inhalt, und wir konvertieren sie in Elemente und für jede Kombination aus Name und Server Jeder Server hätte also einen Namen und dann alle Serverinformationen. Wir führen diese spezielle Vierschleife durch. Also sehen wir zuerst , was der Typ ist. Der Server wird also einen Typ haben , weil wir eine gemischte Gruppe von Servern haben. In dieser speziellen Konfliktdatei geben wir einen Typschlüssel an , der sie entweder als SCTP-Server oder als SDD-IO-Server erwähnt und spezifiziert SCTP-Server oder als SDD-IO-Server Also überprüfen wir, um welchen Typ es sich handelt, und wenn der Typ SGTP ist, verwenden wir die URL-Eigenschaft der Serverinformationen, die wir aus der Konfliktdatei gelesen haben, und weisen sie der URL-Eigenschaft hier zu. Außerdem erstellen wir die streambaren SDPS-Serverparameter und speichern sie in Wenn der Typ SDD IO ist, nehmen wir den Serverbefehl und die Serverargumente, setzen sie in den SDD-IO-Serverparametern auf die Eigenschaft command and arguments in den SDD-IO-Serverparametern auf die Eigenschaft und verwenden diese dann als Serverparameter für den SD-IO-Verbindungsparameter. Und wir werden hier wieder die Verbindungsvariable erstellen , die die Wir bieten ein Timeout für den Fall, dass es einige Zeit dauert, den Server hier zu starten In der Konfiguration hier gibt es einige grundlegende Fehlerbehandlungen für unbekannte Servertypen Schließlich initialisieren wir das MCP-Toolset , indem wir es mit den Verbindungsparametern versehen, die wir oben für einen der Server erstellt haben , der gerade gelesen wird Und wir stellen ihm einen Toolfilter zur Verfügung, der uns über die Befehlszeilenschnittstelle, die wir hatten, zur Verfügung gestellt wurde , und wir erstellen das Toolset hier Das ist das initialisierte Toolset hier drüben, und jetzt holen wir uns das Also rufen wir die G-Unterstrich-Tools-Funktion des Toolsets auf und fügen sie in eine Liste von Tools ein Und dann kümmern wir uns hier um hübsches Drucken. Also nehmen wir den Namen der Tools von jedem Tool und drucken ihn auf dem Bildschirm aus, so wie Sie sagen, dass wir von diesem Servernamen gelesen haben, wir haben all diese Tools gelesen, was hier gedruckt wird. Schließlich haben wir diese erste globale Liste aller Toolsets und wir werden dieses spezielle Toolset, das wir hier bekommen haben, an diese spezielle Liste anhängen hier bekommen haben, an diese Auch hier gibt es einige grundlegende Ausnahmebehandlungen , die, wissen Sie, wenn Sie keinen bestimmten Typ angegeben haben oder eine andere Art von Fehler, dieser bestimmte Servername übersprungen wird Und schließlich werden Sie die Werkzeugsets hier zurückgeben. Und nur um es noch einmal zu wiederholen, das wird für jeden Server passieren. Und je nach Servertyp werden hier die richtigen Verbindungsparameter erstellt . Und nach dem Erstellen dieser Verbindungsparameter wird das Toolset hier initialisiert, die Tools abgerufen und dann dieses spezielle Toolset in der angehängten Liste zurückgegeben dieses spezielle Toolset in der Dieses Toolset wird also die Liste aller Toolsets von allen Servern enthalten Und das ist das richtige Format, das ADG erwartet weil wir das MCP-Toolset aus der ADG-Klasse verwenden, das alles bereits in das richtige Format verpackt. Und schließlich haben wir hier eine geschlossene Funktion, die jedes geladene Toolset ordnungsgemäß herunterfährt. Das ist also wichtig, um übrig gebliebene Aufgaben oder Ressourcen im Hintergrund zu vermeiden übrig gebliebene Also gehen wir jedes Toolset durch und rufen die Funktion „Punkt schließen“ des Toolsets auf Wir behandeln jede Art von Ausnahme, die hier auftreten könnte, und sorgen dann für eine kleine Verzögerung, um sicherzustellen, dass die Stornierung und Reinigung hier abgeschlossen ist Damit wird Ihre Punkt-P-Datei für Agenten mit der Agent-Wrapper-Klasse abgeschlossen, was uns hilft, den Agenten zu erstellen und alle Tools zu laden 45. 9.3.6 Code – JSON-Datei für die MCP Konfiguration: Wir werden uns den Punkt jcnFle ansehen, der den Konflikt in der KI-Sprache unterstreicht Dies ist der Konfliktpunkt jcnFle, den Ihr MCP-Client erwartet Vielleicht kennen Sie dieses Format, wenn Sie schon einmal an MCP gearbeitet haben, und wir haben einen MCP-Serverschlüssel, bei dem und wir haben einen MCP-Serverschlüssel jeder Server einen Namen angegeben hat, und dann haben wir hier in den geschweiften Klammern Serverinformationen. in den geschweiften Klammern Serverinformationen. Für unser spezielles Beispiel, da wir hier einen gemischten Servertyp haben, geben wir den Servertyp explizit an, entweder Eine andere Möglichkeit könnte darin bestehen, automatisch zu erkennen, ob die URL angegeben wurde oder ob es sich um Befehle und Argumente handelt. Und dann entscheiden Sie auf dieser Grundlage dynamisch, um welchen Servertyp es sich handelt. Aber vorerst werden wir diese expliziten Schlüssel-Wert-Paare verwenden, diese expliziten Schlüssel-Wert-Paare um zu spezifizieren, um welche Art von Server es sich handelt. den beiden Servern geben wir natürlich die URL an, wo Streamable TB Server steht , weil STB-Server über eine URL funktionieren würden, und wir versehen den MCP-Endpunkt hier mit einem abschließenden Schrägstrich Das ist wichtig, da Ihr Server sonst auf diesen MCPs trifft, eine Umleitung erhalten und sie dann zu einem Schrägstrich-Endpunkt umleiten, dann funktioniert es Schrägstrich-Endpunkt Geben Sie hier einfach direkt den abschließenden Schrägstrich ein, und das sind die beiden Server, die über streambares SGT funktionieren Endlich haben Sie den SED-IO-Server. Das sind also die guten alten Server, an die jeder gewöhnt ist , wenn Sie überhaupt mit MCP-Servern gearbeitet haben, und hier geben Sie einen Befehl ein, um eine lokale Datei auszuführen Der Befehl hier ist also der UV-Befehl, den wir verwenden werden Also werden wir UV und dann den Terminalserver Punkt PY ausführen und das Verzeichnis für diesen Overhead bereitstellen. Dieser Punkt-PY-Code für den Terminalserver ist also in den streambaren SGTP-Serverimplementierungen hier enthalten den streambaren SGTP-Serverimplementierungen Sie können sich diesen speziellen Code später tatsächlich ansehen, aber so diesen speziellen Code später tatsächlich ansehen, werden wir den STD-IOServer ausführen 46. 9.3.7 Code für Dienstprogramme und STDIO-Server + Umgebungskonfiguration: Ordnung, damit sind alle Dateien außer den Hilfsprogrammen Also werde ich die Dienstprogramme hier ganz schnell durchgehen . Die kannst du dir tatsächlich ansehen. Dies sind sehr einfache Python-Funktionen. Also laden wir einfach alle Umgebungsvariablen hierher und lesen die Konfigurationsdatei. Wir erwarten also, dass die Konfigurationsdatei entweder als Umgebungsvariable bereitgestellt wird, was die Unterstrich-Konfiguration in der Sprache A ist Der Pfad wird hier in der Umgebung angegeben, oder es ist nur die lokale Datei, die im selben Verzeichnis mit diesem bestimmten Namen bereitgestellt Das erwartet der Code also, und das ist der Konfliktpfad, und wir öffnen diesen Konfliktpfad im Lesemodus und geben einfach das JSN zurück, das wir von dort gelesen haben Dies ist eine einfach zu lesende Confic JCN-Datei. gibt es eine einfache Ausnahmebehandlung Hier gibt es eine einfache Ausnahmebehandlung für den Fall, dass ein Fehler auftritt Es gibt auch eine Funktion zum Drucken von Jason-Antworten , mit der wir die Jason-Antwort in einem hübschen Format drucken können. Dies ist, was Sie auf dem Bildschirm sehen , wenn Sie den ganzen farbenfrohen Druck sehen. Wenn Sie diese Funktion nicht verwenden, wird es sich um einen Speicherauszug von Zeichen handeln , die nicht richtig umgebrochen sind und nicht richtig angeordnet sind, was nicht sehr gut anzusehen ist Zu unserem eigenen Verständnis erstellen wir also diese Funktion zum Drucken von JsnRsResponse. Ich möchte Sie ermutigen, sich diese Funktion anzusehen und zu sehen diese Funktion Es ist eine ziemlich gute Methode, JCN-Drucke in Ihrem Code zu handhaben , sodass Sie aus dem, was gedruckt wird, einen Sinn machen können und nicht aus dem Standard-JCN-Dump, den Standard-JCN-Dump In Ordnung. Und jetzt schauen wir uns endlich diesen Terminalserver Punkt P an weil das eine weitere Ausgabe ist , die wir hier gemacht haben. Wir müssen das verstehen und es ist ein ziemlich einfacher Server hier drüben. Also verwenden wir schnelles MCP , um einen Server zu erstellen. Wir nennen das Serverterminal hier drüben und stellen einen Arbeitsbereich zur Verfügung Das ist also wichtig , weil wir nicht möchten, dass dieser Demo-Server all unseren Dateien und unserem gesamten System arbeitet. Also haben wir explizit einen Pfad angegeben. Es wird also das Home-Benutzerverzeichnis sein gefolgt von MCP und Workspace Sie müssen also sicherstellen , dass dieses Verzeichnis existiert, bevor Sie diesen Server ausführen können Wenn dieses Verzeichnis nicht existiert, erhalten Sie eine Fehlermeldung, dass dieses bestimmte Verzeichnis nicht gefunden oder die Datei nicht erstellt werden dieses bestimmte Verzeichnis nicht gefunden konnte. Das wird also benötigt werden. Und auf einem Windows-Computer wird sich herausstellen, dass dies Ihr C-Home-Ordner mit einem Doppelstrich und dann der Schrägstrich MCP und Workspace Auf einem MacOS- oder Ubuntu-Computer wird dies ein Schrägstrich sein, der Ihren Benutzernamen und dann Ihr MCP-Workspace-Verzeichnis enthält So ist also Ihr MCP Workspace-Verzeichnis definiert, und dann haben Sie endlich das Befehlstool Run, und wir verwenden den MCP Tool Decorator hier, um es als MCP-Tool zu klassifizieren Dies ist die Dokumentzeichenfolge , die wir zur Verfügung stellen, und sie wird unserem MCP-Client als Information dienen, damit er versteht, was dieses unserem MCP-Client Moment sagen wir nur, dass damit ein Terminalbefehl innerhalb des Workspace-Verzeichnisses ausgeführt werden kann ein Terminalbefehl innerhalb des Workspace-Verzeichnisses Wenn ein Terminal-Befehl eine Aufgabe ausführen kann, teilen Sie dem Benutzer mit, dass Sie dieses Tool verwenden, um sie auszuführen, auch wenn Sie dies nicht direkt tun Das wird hinzugefügt, denn wenn Sie den Agenten bitten, eine Datei zu erstellen, könnte er sagen, dass ich keine Datei erstellen kann. Aber wenn es versteht, dass es ein Tool gibt, das dieselbe Aufgabe ausführen kann, indem es einen Befehl ausführt, was nicht direkt von Ihnen verlangt wurde, aber es weiß, dass es das erreichen kann indem es diesen Befehl ausführt. Es wird Ihnen nur sagen, dass dies mit diesem Tool möglich ist, obwohl der Agent nicht direkt eine Datei erstellen kann dies mit diesem Tool möglich ist, , aber er kann den Befehl ausführen, um die Datei zu erstellen. Und die Argumente sind der Befehl, bei dem es sich um einen Shell-Befehl handelt, der nur als Zeichenfolge ausgeführt Er gibt die Befehlsausgabe oder eine Fehlermeldung zurück , die nach der Ausführung dieses Befehls angezeigt wird. Hier nennen wir also den Unterprozess dot run, und dieser wird verwendet, um den Befehl auf der Shell auszuführen Wir stellen hier einen Standardarbeitsbereich und wir erfassen die Ausgabe hier. Dadurch wird einfach unser Befehl ausgeführt und wir geben den SCD-Out- oder SCD-Fehler zurück, den wir beim Ausführen dieses Tools erhalten . Wir fangen jede Ausnahme ab , die auftreten könnte, und geben die Ausnahme zurück , falls dies der Fall ist Und wenn das Skript fertig ist, ruft es die Funktion mcpt run mit dem SDD Iotransport auf Es ist also ein sehr einfacher Server, Ihnen helfen kann, viele Aufgaben zu erledigen , indem Sie Terminalbefehle ausführen Bitte benutzen Sie den Link in der Vorlesungsbeschreibung , um sich den Code anzusehen. Sobald Sie das getan haben, können Sie zu diesem bestimmten Ordner wechseln und Ihre virtuelle Umgebung einrichten. Also habe ich meinen Code in das MCP-Verzeichnis ausgecheckt und dieses Verzeichnis aus dem Github-Repo erstellt . Ich werde darauf umsteigen. Sie können eine virtuelle Umgebung erstellen, indem Sie UV VE NV eingeben und dann die Eingabetaste drücken. Aktivieren Sie dann die virtuelle Umgebung, indem Sie Quellpunkt und den Schrägstrich BNS Wenn Sie unter Windows auf einem MAT arbeiten, würde dies funktionieren, indem hier gezeigten Aktivierungsbefehl eingeben, bei dem es sich um ein Skript mit dem Schrägstrich Drücken wir die Eingabetaste, und das wird unsere virtuelle Umgebung hier aktivieren. Wir müssen zuerst alle Anforderungen synchronisieren, damit wir UV Space Sync eingeben und die Eingabetaste drücken können. Dadurch werden alle Pakete aus der Liste der Projektabhängigkeiten in der Punkt-TML-Datei für Pie Projects hinzugefügt , und Ihre virtuelle Umgebung wird vollständig eingerichtet Ihre virtuelle Umgebung wird vollständig Lassen Sie uns den Bildschirm leeren, und jetzt haben wir eine virtuelle Umgebung eingerichtet Die erste Aufgabe besteht darin, die beiden Server zu starten , die auf streambarem HTTP arbeiten werden , das wir bereits in den vorherigen Vorlesungen erstellt haben Gehen wir also zu einem anderen Tab hier drüben. Sie können eine neue Registerkarte öffnen und dann in dasselbe Verzeichnis wechseln. Wir haben die virtuelle Umgebung bereits erstellt sodass wir sie einfach direkt aktivieren können. Lassen Sie uns nun unseren Server mit dem Befehl UV Run ausführen und ihm den statusfreien Haupt-PY-Dateipfad des streambaren STDP-Servers statusfreien Haupt-PY-Dateipfad des streambaren zur Verfügung stellen und dann den Servernamen als Servernamen angeben Drücken wir die Eingabetaste. Und jetzt läuft Server eins auf dem lokalen Host 3.000. Wir können jetzt wieder zum zweiten Terminalfenster gehen, dasselbe Verzeichnis wechseln und dann Ihre virtuelle Umgebung aktivieren. Verwenden Sie jetzt erneut den Befehl UV Run, der den Hauptdateipfad und den Server als Server zwei angibt, und drücken Sie die Eingabetaste. Jetzt läuft der zweite Server auf dem lokalen Host 3.001 Jetzt werden wir unseren Client starten. Sobald die beiden Server laufen, können wir unseren MCP-Client starten Also schreiben wir UVRun und geben dann den Pfad für unsere cmd dot p Datei an und Jetzt können Sie sehen, dass der ADK LLM-Agenten-Chat gestartet wurde. Er bietet die Möglichkeit, den Vorgang durch Eingabe von quit oder Cl und Q zu beenden. Dies ist eine Benutzerwarnung für experimentelle Funktion, es sich um ein authentifiziertes Basiswerkzeug handelt, das für diese spezielle Vorlesung ignoriert wird Vorerst müssen wir uns ansehen, dass wir Lage waren, Tools vom ersten Server zu laden, dem HTTP-Server mit Zahlen addieren und Zahlen subtrahieren, Tools, und dann haben Sie Tools, die auch von Server zwei geladen auch von Server zwei multiplizieren und Zahlen zu dividieren. Und schließlich haben Sie Tools vom Serverterminal geladen Dies ist der SDD IO-Server mit dem Befehl Tool run, mit dem Sie einen Terminalbefehl auf Ihrem lokalen Computer ausführen Ordnung. Das war also der gesamte Code , den wir uns ansehen mussten, und damit ist die Implementierung unseres Universalclients und unseres SDD-IO-Servers abgeschlossen , dem das Terminal den Punkt PI des Servers unterstreicht 47. ABSCHNITT 10 START - Streamlit-Benutzeroberfläche für MCP Client - Übersicht über Streamlit UI MCP Client 1: Also werden wir heute etwas ziemlich Tolles machen . Wir werden unserem Python-basierten MCP-Client, der tatsächlich mit MCP-Servern funktioniert , tatsächlich eine Benutzeroberfläche hinzufügen , wie Sie hier sehen können unserem Python-basierten MCP-Client, der tatsächlich mit MCP-Servern , Wir werden das mit Streamlt machen und Sie können diese Benutzeroberfläche jetzt auf meinem Bildschirm sehen Bevor wir beginnen, werfen wir einen Blick auf die Benutzeroberfläche und darauf, was wir in diesem speziellen Video erstellen werden in diesem speziellen Video erstellen So sieht die gesamte Benutzeroberfläche aus. Hier gibt es einen Hauptbereich für den Chat und eine Seitenleiste. Dies ist im Grunde die Benutzeroberfläche für unseren MCP-Client. Der Client wurde mit dem LangrapsRact-Agenten erstellt und verwendet API von Gemini als großes Sprachmodell. Er ist in Python geschrieben Die Benutzeroberfläche wurde mit Streamlt erstellt und das ist und Lassen Sie mich die Ansicht vergrößern, um Ihnen die verschiedenen Komponenten dieses speziellen Clients zu zeigen die verschiedenen Komponenten dieses speziellen Clients Wir können die Seitenleiste von hier aus reduzieren, und Sie haben den Titel mit dem Logo hier drüben Und du hast einen Untertitel, in den ich gerade einen Abonnement-Link zu einem YouTube-Kanal eingefügt habe Abonnement-Link zu einem YouTube-Kanal Es gibt einen Bereich, in dem der Chat ins Spiel kommt und Sie die vom Benutzer gesendeten Nachrichten und die Antwort des MCP-Clients sehen können die vom Benutzer gesendeten Nachrichten und die Antwort des MCP-Clients Dann gibt es ein Chat-Feld, in das Sie Ihre Anfrage stellen können, und Sie können Eingabetaste drücken, um Ihre Anfrage einfach zur Bearbeitung einzureichen, oder Sie können auf die Schaltfläche Senden klicken Sie haben auch eine neue Konversationsschaltfläche um eine neue Konversation zu beginnen, und Sie können die Konversation speichern, indem Sie hier auf Sichere Konversation klicken. Sie können die Seitenleiste erweitern, indem Sie auf diese Schaltfläche Anschließend haben Sie einige Einstellungen vorgenommen. Sie können also auswählen, welche Art von MCP-Client Sie möchten? Sie können also entweder einen MCD-Client haben, tatsächlich eine Verbindung zu SDD-IO-Servern herstellt, denen es sich im Grunde um Python- und JavaScript-Skripte handelt, die lokal auf Ihrem Computer ausgeführt werden , oder Sie können einen MCP-Client verwenden, der über das Internet eine Verbindung zu einem Server herstellen kann , oder das XDDB-Protokoll, das vom Server gesendete Ereignisse als Transportprotokoll verwendet Ich habe den Code für beide hinzugefügt, aber der SSE-Code ist Sie können ihn tatsächlich als Platzhalter oder Ausgangspunkt verwenden , wenn Sie möchten Wenn wir den SCD-IO-Server auswählen, können Sie hier tatsächlich ein Konfliktpunkt-JCNFle mit allen MCP-Servern hochladen , und Sie können dazu auf Dateien durchsuchen klicken Andernfalls verwendet das System eine Standard-Konfigurationsdatei, bei der es sich um den Unterstrichpunkt JSON in der KI-Sprache handelt Sie können die historischen Konversationen, die Sie gespeichert haben , hier sehen haben , hier Diese werden in einem Konversationsordner mit dem Zeitstempel am Ende der Datei gespeichert mit dem Zeitstempel am Ende der Datei gibt es auch einen erweiterbaren Protokollausgabeblock Hier gibt es auch einen erweiterbaren Protokollausgabeblock, in dem Sie das gesamte Protokoll für Ihre MCP-Client- und Server-Interaktion sehen können Ihre MCP-Client- und In Ordnung, lassen Sie uns eine Vorschau davon sehen, wie das jetzt funktioniert. 48. 10.2 Streamlit UI-Demo: Schauen wir uns also an, wie das jetzt funktioniert. Also drücken wir auf Neue Konversation , um eine neue Konversation zu beginnen. Geben wir also zuerst Hi ein und drücken die Eingabetaste. Jetzt können Sie sehen, dass es im Grunde im Hintergrund ausgeführt wird und wir die Antwort von MCP erhalten Hallo zusammen. Wie kann ich dir heute helfen? Ich verwende also den Benutzer, um die Nachrichten des Benutzers zu kennzeichnen , und MCP, um die Antwortnachrichten vom MCP-Client und -Server zu kennzeichnen . In Ordnung Also lass uns jetzt eine Abfrage schreiben. Erstellen Sie mit dem Run-Befehlstool eine Datei streamltUnderscore success dot TXT mit dem Text TXT mit dem Text Streamlt success und drücken Sie die Eingabetaste Auch hier wird die Abfrage ausgeführt. Okay, und wir erhalten die Antwort, dass ich diese Datei Streamlt Underscoe Success Dot mit dem Text Streamlt Success erstellt habe Streamlt Underscoe Success Dot mit dem Text Streamlt Success mit dem Text Schauen wir uns das also im Finder-Fenster an. Ordnung, das ist also das Finder-Fenster mit dem Arbeitsbereich für unseren Terminalserver, und wir sehen, dass wir hier eine Datei namens StreamltundersCO Success Dot TXT haben hier eine Datei namens StreamltundersCO Success Dot TXT Lassen Sie mich diese Datei jetzt öffnen. Okay, und Sie können sehen, dass der Text Streamlt Success in der Datei steht Das bedeutet, dass unser Client und Server gut mit der Benutzeroberfläche zusammenarbeiten Ordnung. Sie können also auch hier auf Konversation speichern klicken, und das wird im Grunde die Konversation speichern. Sie können auf neue Konversation klicken, indem Sie hier auf diese Schaltfläche klicken. Dadurch wird hier eine neue Konversation gestartet. Wenn Sie nun tatsächlich auf diese Seitenleiste hier klicken, haben Sie die Möglichkeit, die Konversation zu laden Lassen Sie mich also einfach diese spezielle Konversation laden. Und das ist die letzte Konversation, die wir gerade gespeichert haben, und Sie können sehen, dass Sie den gesamten Nachrichtenverlauf hier haben . Nun haben Sie für den MCP-Client Config jcnFle die Standarddatei, die AI Language underscoconfg dot JCN, die sich im Grunde im selben Verzeichnis wie die Anwendung befindet die sich im Grunde im selben Verzeichnis wie die Anwendung befindet. Falls Sie Ihre eigene Datei bereitstellen möchten, können Sie hier auf Dateien durchsuchen klicken Sie können eine Datei auswählen und sie ersetzt im Grunde den Inhalt in dieser AI Language Underscoconfit Dot JCN-Datei, und dann wird Ihr Client im Grunde diese Datei verwenden Sie haben auch die Möglichkeit, zu einer anderen Art von MCP-Client- und Server-Kombination zu wechseln von MCP-Client- und Server-Kombination SSE steht also für Server Sent Events. Es ist eine Transportmethode, die von MCP-Clients verwendet wird , um über STTP zu arbeiten Ich habe dafür einen Platzhaltercode bereitgestellt, aber dieser ist derzeit in dieser speziellen Client-Implementierung nicht aktiv in dieser speziellen Sie können sich diesen Code ansehen und ihn bei Bedarf an Ihre Bedürfnisse anpassen Ich habe gerade mit dem SDDIO-Client hier gearbeitet. 49. 10.3 Vergleich unserer Benutzeroberfläche mit Claude Desktop!: Es geht im Grunde darum zu zeigen, wie man tatsächlich einen MCP-Client erstellen kann , und das ist der erste Schritt um eine App von einer Größenordnung wie, sagen wir, Cloud Desktop zu erstellen , der auch ein MCP-Client ist. Man müsste tatsächlich viele Funktionen integrieren, um eine wunderbare Benutzererfahrung zu haben Dies ist jedoch nur als Lehrcode gedacht , der Ihnen zeigt, wie Sie Streamlt verwenden können , um eine grundlegende Client-Benutzeroberfläche für Ihre MCP-Clients und -Server zu erstellen für Ihre MCP-Clients 50. 10.4 Setup-Verzeichnisse (überspringen, wenn bereits erledigt): Sobald Sie UV installiert haben, können Sie tatsächlich Ihre MCP-Verzeichnisstruktur einrichten Ich richte also tatsächlich ein MCP-Verzeichnis in meinem Home-Ordner ein und dann richte ich hier drei Verzeichnisse ein, Clients, Server und Im Kundenverzeichnis speichere ich alle meine Kunden, und ich werde den Langhain MCB-Client hier speichern Im Serververzeichnis habe ich alle meine Server gespeichert, alle vorgefertigten Server, die ich heruntergeladen habe, und alle Server, die ich selbst erstellt habe Dann habe ich hier einen Workspace-Ordner , denn wenn ich möchte, dass die MCP-Server Aktionen lokal auf meinem Computer ausführen, verwende ich den Workspace-Ordner für jede Art von Dateierstellung, -löschung usw. Im Moment gehen wir zum Kundenordner und Sie sehen, dass ich bereits einen MCP-Client habe Sie können den Github-Repository-Link tatsächlich verwenden , um diesen MCP-Client-Ordner auszuchecken Sobald Sie ihn ausgecheckt haben, können Sie tatsächlich in den Ordner gehen 51. 10.5 Google Gemini API-Schlüssel einrichten (Überprüfen Sie dies erneut, falls Sie dies bereits getan haben): Bevor wir das tun, benötigen wir den Gemini-API-Schlüssel. Also gehe ich zu Chrome und gehe zu atudiogogle.com Wenn Sie diese Seite erreichen, einfach Sie müssen natürlich mit Ihrer Gmail-ID angemeldet sein. Sie können auf Create ApiKey klicken, um einen Schlüssel zu erstellen. Ich habe hier bereits einen Schlüssel erstellt und ich kann einfach auf diese Schaltfläche klicken und den Schlüssel kopieren Stellen Sie sicher, dass Ihre API-Schlüssel sicher sind. Sie sollten sie nicht teilen oder irgendwo im Code oder in einem Repository einbetten . Ich werde diesen APIKey deaktivieren , nachdem ich mit der Aufnahme dieses Videos fertig bin, also werde ich ihn einfach hier sichtbar lassen. Sobald Sie diesen ApiKey kopiert haben, kehren zum Terminal zurück und erstellen eine Umgebungsvariablendatei, indem Sie Touch Dot NV eingeben und Enter drücken habe diese Datei bereits hier, Ich habe diese Datei bereits hier, also öffne ich sie einfach mit NNO und wie Sie sehen, habe ich APIKysGemini ApiKey und Google APIke definiert und meinen Schlüssel hier eingefügt. Sie können diese Zeile tatsächlich hier drüben schreiben und Ihren Schlüssel daneben einfügen. Ich habe zwei Umgebungsvariablen verwendet, Google ApiKey und Gemini ApiKey , weil ich in meinem persönlichen Projekt gerne die Umgebungsvariable Gemini API key verwende Ein Kinn erwartet jedoch, dass der Schlüssel unter einer Umgebungsvariablen namens Google APIK vorhanden einer Umgebungsvariablen Nur um Verwirrung zu vermeiden und die Verwendung beider Variablen zu ermöglichen, habe ich den Schlüssel tatsächlich zweimal mit zwei Umgebungsvariablennamen definiert zweimal mit zwei Umgebungsvariablennamen Sie können das Gleiche tun. Für Lang Chain müssen Sie Google API verwenden, Control X drücken und die Datei speichern, bevor Sie sie beenden Jetzt haben Sie Ihre Umgebungsdatei eingerichtet. 52. 10.6 Erstellen einer virtuellen Umgebung und Installieren von Abhängigkeiten: Wir können eine virtuelle Umgebung erstellen , die uns im Grunde hilft, unsere Projektabhängigkeiten von allen anderen Arbeiten, die wir an einem Computer erledigen, zu trennen allen anderen Arbeiten, die wir an einem Computer erledigen Sie können also U, V, NV eingeben und Eingabetaste drücken, um diese Umgebung tatsächlich zu erstellen. Ich habe das bereits erstellt, und wenn Sie meinen vorherigen Videos folgen , hätten Sie auch dieses Verzeichnis und diese Umgebung erstellt, sodass Sie sie nicht erstellen müssen. Für alle, die sich etwas Neues ansehen, erstellen Sie bitte diese Umgebung. Sobald Sie diese Umgebung erstellt haben, können Sie sie tatsächlich aktivieren, indem Sie den Quellpunkt nvlashBN slash Activate eingeben Quellpunkt nvlashBN Und das führt Sie im Grunde dazu des MCP-Clients aufzurufen Okay, jetzt werden wir einige Pakete hinzufügen, die wir für die Entwicklung unseres MCP-Clients benötigen Diese Pakete sind Lang Chin, die Lang Chin MCP-Adapter, Lang Graph, Lang Chin Google Gen AI-Paket, Google Genitive AI-Paket und das Python Dot Environment-Paket für die Umgebungsvariablen Nachdem Sie die UV-Anzeige und die Liste der Pakete geschrieben haben , drücken Sie die Eingabetaste . Ich habe es bereits installiert, aber es dauert einige Sekunden oder Minuten, bis es installiert ist . In Ordnung. Sobald Sie all diese Pakete hinzugefügt haben, müssen Sie die anderen Pakete für das spezielle Streaming und die Benutzeroberfläche, die wir gerade erstellen, hinzufügen spezielle Streaming und die Benutzeroberfläche, die wir gerade erstellen, Also werden wir das Streamlt-Paket aus der Datei hinzufügen. Wir werden auch Nest Underscore AC IO hinzufügen Nest Underscore AC IO und wir werden auch Pillow installieren Das sind also drei zusätzliche Pakete, die wir installieren möchten Ordnung, also gib einfach UV add Streaml Nest underscore ASN, IO und Pillow ein und werden auch diese drei Pakete installiert Ordnung, das installiert also alle Abhängigkeiten für Ihren 53. 10.7 Streamlit UI-Code abrufen: Ordnung. Um den Code für die Benutzeroberfläche, den Client und den Server zu erhalten, können Sie tatsächlich auf die Links in der Beschreibung verweisen. Sie werden sehen, dass wir uns gerade auf den MCP-Client-Ordner beziehen , in dem wir alle Clients haben , die wir zuvor implementiert haben , wenn Sie sich die vorherigen Videos angesehen haben die vorherigen Videos Hier haben wir drei verschiedene interessante Dateien. Eine davon ist die Streamlint-Client-UI-PY-Datei. Dies implementiert die gesamte Streamlint-Benutzeroberfläche und stellt eine Verbindung zu den verschiedenen Client-Implementierungen über dieser Datei hier Wir haben also vorerst zwei Client-Implementierungen. Eine davon ist die SDD IO-Client-Implementierung. Auch dies sind im Grunde alle Server , die Sie tatsächlich in Ihrer Konfliktdatei angeben können, und diese werden lokal auf Ihrem Computer ausgeführt Sie haben auch die SC Dot PI-Implementierung, die momentan nur ein Platzhalter ist, den Sie verwenden und weiter implementieren wenn Sie tatsächlich damit arbeiten möchten Im Moment werde ich mich mit der UI-Datei und der SDD-IO-Serverdatei 54. 10.8 Optimierte App-Importe und Statusinitialisierung: Lassen Sie uns den Code der Datei ui dot py des Streamlt-Clients durchgehen , gemeinsam bearbeiten Zunächst haben wir die Importe und ich habe dem gesamten Code sehr detaillierte Anweisungen hinzugefügt, damit gesamten Code sehr detaillierte Anweisungen hinzugefügt Sie verstehen, was jede Zeile bedeutet, und auch die Installationsanweisungen Streamlt ist also die Codebibliothek, mit der wir die Benutzeroberfläche erstellen, und wir importieren sie hier. Dann haben wir ASN Kio für ASN-Prozesse, insbesondere für die Tool-Kommunikation, insbesondere für die Tool-Kommunikation und wir importieren Wir haben ein Betriebssystem, das hauptsächlich Dateisysteminteraktionen ermöglicht, und wir haben JCN, um die Konversationsdaten zu lesen und in JCNFles zu schreiben Konversationsdaten Wir haben dann Datetime, das für Zeitstempel verwendet wird, wir haben Nest Async IO, das Sie tatsächlich installieren können , indem Sie PIP install Nest Async IO eingeben. Dies ermöglicht grundsätzlich die verschachtelte Verwendung von Async-IO-Event-Loops, was in interaktiven Notebooks oder Streamlt nützlich ist Dann haben Sie die Python-Bildbibliothek, der die Bilder im Grunde wie das Logo in unserem Tool gestaltet werden . Sie können sie installieren, indem Sie PIP install Pi eingeben Verwenden Sie die EstimL-Komponenten für eine grundsätzlich erweiterte Anpassung, und damit sind im Grunde alle unsere Eingaben abgeschlossen Dann haben Sie Nest Underscore asynco dot apply, und wenn Sie in Python etwas namens Async oder Await verwenden, teilen Sie dem Programm mit, dass diese Aufgabe im Hintergrund erledigt , während Sie darauf warten, dass andere Dinge Aber Python erlaubt normalerweise nur eine Event-Schleife gleichzeitig. Streamlt und Jupiter, alle Tools wie diese verwenden bereits eine Event-Schleife im Hintergrund Wenn Ihr Code also versucht, einen neuen zu erstellen oder auszuführen, gibt Python einen Fehler aus Diese Zeile sagt also , dass es okay ist, lass diese neue Event-Schleife innerhalb der bestehenden laufen Es ist, als würde man eine Schleife in die andere verschachteln. Das patcht also im Grunde die asynchrone I/O von Python. Sie können verschachtelte Event-Loops sicher ausführen, besonders nützlich ist in interagierenden Umgebungen wie dem Client, den wir mit streamlt erstellen, oder Dingen wie Jupiter-Notebooks oder sogar Repels, in denen bereits eine Jetzt haben Sie die Initialisierung des Sitzungsstatus der App. Wir haben eine Konversationsliste. Wenn diese im Sitzungsstatus noch nicht vorhanden ist, initialisieren wir sie mit einer leeren Liste Wir haben eine Client-Konfiguration, und auch diese initialisieren wir als SDD IO, was der Typ des Clients ist Dies ist auf verschiedene Clienttypen erweiterbar. Sie können hier grundsätzlich kategorisierte Kunden einbeziehen. Sie haben eine Server-URL für SSE-Clients und Sie haben eine SDD-IO-Konfigurationsdatei für Clients vom Typ SDD IO Dann haben Sie einen Platzhalter für ein wiederverwendbares Client-Objekt. Wenn sich die Client-Instanz also nicht im Sitzungsstatus befindet, weisen wir sie grundsätzlich keiner zu, und wir werden dies im Grunde später initialisieren Es gibt ein Theme zum Umschalten des Dunkelmodus. Ich habe versucht, das in den Code aufzunehmen, aber am Ende habe ich es nicht aufgenommen Aber wenn Sie müssten, würden Sie das im Sitzungsstatus speichern. Dann haben Sie die Protokolle, die wir im Log-Blog gesehen haben, und wir initialisieren sie mit einer leeren Liste. In Ordnung. Dann haben wir im Bundesstaat ein Kennzeichen, das beim Senden ausgelöst wurde, und das dient nur dazu, festzustellen, und das dient nur dazu, festzustellen, ob jemand die Anfrage in der Chat-Box absendet, indem er die Ent-Taste drückt anstatt auf die Schaltfläche Senden zu klicken. Dann gibt es eine Markierung, die verhindert, dass die Schleifen nach der Verarbeitung einer Anfrage unendlich oft wiederholt Es ist eine Markierung, die eine Abfrage ausgeführt hat, die anfänglich falsch ist und auf die wir sie gesetzt haben Wir werden es später verwenden. Und es gibt eine ausstehende Abfragezeichenfolge, die tatsächlich die aktuelle Abfrage enthält, die nach dem Absenden ausgeführt werden soll. Auch hier werden wir uns im Laufe der Zeit die Verwendung dieser Statusvariablen ansehen. 55. 10.9 Code für Dienstprogrammfunktionen: Wir haben einige Hilfsfunktionen und die erste wird asynchron in einer Ereignisschleife ausgeführt Diese Funktion ist also wie ein Task-Manager für Hintergrundjobs oder auch als Routinen bekannt Um eine asynchrone Aufgabe in Python auszuführen, benötigen Sie normalerweise eine sogenannte Event-Schleife. Sie ist wie eine Engine, die Multitasking abwickelt, aber Streamit führt bereits Wenn wir also versuchen, unsere eigenen separat auszuführen , wird Python verwirrt. Diese Funktion überprüft, ob bereits eine Ereignisschleife läuft? Wenn nein, erstellt sie im Grunde eine. Und falls ja, bittet es den Running Loop höflich , unsere Aufgabe in seinen Zeitplan aufzunehmen, und wartet auf das Ergebnis Dann haben wir die Meldung zum Hinzufügen von Protokollen. Es handelt sich also um ein Protokollierungsprogramm , das die Nachrichten mit einem Zeitstempel sowohl in Konsolen- als auch in UI-Protokollen protokolliert Diese Funktion ist also wie ein Notizbuch oder ein Tagebuch. Jedes Mal, wenn etwas passiert, wie Empfangen einer Nachricht oder das Verarbeiten einer Anfrage, schreibt diese Funktion es auf Sie fügt also einen Zeitstempel hinzu, damit wir wissen, wann es passiert ist Sie fügt die Nachricht sowohl dem Bildschirm hinzu, der im Grunde im gestreamten Zustand befindet der Konsole, die sie im Grunde auf der Konsole ausdruckt Dies hilft Ihnen im Grunde dabei, Ereignisse zu debuggen, zu kennzeichnen oder einfach nur zu sehen, was wann passiert ist 56. 10.10 Streamlit App Sidebar-Code: Dann haben wir also die Seitenleiste für die Einstellungen und die Protokollansicht Diese Zeile mit der Punkt-Seitenleiste erzeugt also ein Seitenleisten-Panel auf der linken Seite der Streamlt-App, und alles, was sich in diesem Block befindet, wird in dieser Seitenleiste auf der linken Seite der Streamlt-App, und alles, was sich in diesem Block befindet, wird in dieser angezeigt Es ist, als würde man sagen, dass alles, was Sie hier hinzufügen, im Grunde Dinge sind , die dem Menü auf der linken Seite hinzugefügt wurden . In Ordnung. SD-Header-Einstellungen fügen also oben in der Seitenleiste eine Abschnittsüberschrift mit der Bezeichnung Einstellungen hinzu eine Abschnittsüberschrift mit der Bezeichnung oben in der Seitenleiste eine Abschnittsüberschrift mit der Bezeichnung Einstellungen Dies zeigt also im Grunde ein Optionsfeld , mit dem Benutzer zwischen SDD IO und SSE wählen können Die ausgewählte Option wird im Sitzungsstatus unter der Client-Konfiguration als Clienttyp gespeichert , sodass sie später verwendet werden kann Und wir verwenden Adog, um diese Auswahl, die sowohl im Terminal als auch in der Benutzeroberfläche angezeigt wird, grundsätzlich zu protokollieren diese Auswahl, die sowohl im Terminal als auch in der Benutzeroberfläche angezeigt wird, grundsätzlich zu . In Ordnung. Dann haben wir also den SddioCfig-Punkt Json oder den Fallback auf die Standardoption, wenn wir keine Datei bereitstellen. Also laden wir im Grunde unser Cfict-Punkt-JCN für SDD IO mit einem Datei-Uploader Cfict-Punkt-JCN für SDD Dies fügt also im Grunde eine Datei-Upload-Option hinzu, mit der der Benutzer bei jcnFle hochladen Es wird erwartet, dass das JCNFle die Konfiguration für die MCP-Server enthält, und dies wird später verwendet, um eine Verbindung zu Wenn also eine Datei hochgeladen wird, speichern wir sie auf der Festplatte mit dem Namen The AI language underscore Dadurch wird die Standard-Konfigurationsdatei installiert, die Ihr Bend-Code erwartet. Wenn die Datei also hochgeladen wird, speichern wir sie im Grunde in diesem Pfad, sich in unserem, Sie wissen schon, Verzeichnis hier drüben befindet. Und wir werden diese Datei tatsächlich öffnen und speichern. Dann setzen wir das Client-SDI auf Square Config mit diesem Pfad, und wir drucken auch eine Erfolgsmeldung und eine analoge Meldung und fügen diese dem Protokoll hinzu Wenn eine Datei nicht hochgeladen wird, verwenden wir grundsätzlich die Standarddatei, die KI-Sprache underscconfg Und gleich nach einer grundlegenden Überprüfung , ob dieser Pfad tatsächlich existiert, was auch der Fall sein sollte, da wir die Datei bereits hier haben Wir setzen es im Grunde wieder auf SDDI oder Config im Sitzungsstatus und fügen dazu eine Log-Anweisung hinzu Falls diese Datei nicht vorhanden ist, werden wir tatsächlich eine Warnung dafür ausgeben und diese Warnung erneut zum Protokoll hinzufügen. In Ordnung. Dann haben wir einen Abschnitt über das Laden der Konversation. Dies ist im Grunde eine horizontale Teilung, und dann haben wir einen Header mit der Konversation zum Laden des Titels Dann richten wir unseren Konversationsordner oder unser Konversationsverzeichnis ein, und wenn es schon existiert, ist das okay, weil dadurch jegliche Art von Fehlern verhindert wird jegliche Art von Fehlern Dann listen wir alle Dateien aus dem Konversationsordner auf. Und wenn wir irgendwelche Konversationsdateien finden, gehen wir im Grunde jede dieser Dateien durch und erhalten einen Dateipfad. Dann öffnen wir die Datei im Lesemodus und laden den Json aus der Datei. Wir laden eine Bewertung mit den ersten 20 Zeichen, falls Sie sie zeigen möchten. Und dann fügen wir eine Schaltfläche , um diesen bestimmten Dateinamen zu laden. Wenn der Benutzer auf diese Ladeschaltfläche klickt, wird die Konversation im Speicher gespeichert, und sessionstg dot conversation wird auf diesen Wert gesetzt Anschließend wird im Grunde eine Erfolgsmeldung auf der Benutzeroberfläche angezeigt und sie wird auch dem Protokoll hinzugefügt Und wenn keine alten Chats gefunden wurden, wir im Grunde die Information, geben wir im Grunde die Information, dass wir derzeit keine gespeicherten Konversationen haben Endlich haben wir wieder eine Abschnittsteilung und dann haben wir eine Protokollanzeige, und das ist im Grunde ein Textbereich mit allen Protokollen aus unseren Sitzungsstatusprotokollen 57. 10.11 Erstellen der Hauptchat-Benutzeroberfläche für die App: Als Nächstes haben wir also die Haupt-Chat-Benutzeroberfläche, und oben im Chat rendern wir zuerst das Logo und den Titel Call one and call two teilt also im Grunde den oberen Teil der App in zwei Spalten auf, und Spalte eins entspricht im Grunde genommen einer von sieben der Gesamtbreite, und Spalte zwei entspricht im Grunde sechs mal siebten der Gesamtbreite Und das wird im Grunde für den Titel verwendet, und das wird für das Logo verwendet. In Ordnung. Für die erste Spalte laden wir also das Bild , das in assetlashogo dot JPG vorhanden ist, und Sie können nachsehen, dass wir hier einen Assets-Ordner mit der Logopunkt-JPG-Datei haben hier einen Assets-Ordner mit der Logopunkt-JPG-Datei Dann nehmen wir die kleinste Abmessung (Höhe oder Breite), um einen quadratischen Ausschnitt zu erstellen . Dies hilft uns im Grunde dabei, das Logo kreisförmig zu gestalten Dadurch entsteht eine kreisförmige Maske, ein weißer Kreis auf dem Hintergrund, der auf das Bild aufgetragen wird , damit es rund aussieht. Dadurch wird das ursprüngliche Logo in ein Quadrat zugeschnitten und die Kreismaske als Alpha- oder Transparenzmaske angewendet. Alles außerhalb des Kreises wird grundsätzlich transparent. Dadurch wird schließlich das kreisförmige Logo in der ersten Spalte angezeigt , wobei die volle Breite des Containers genutzt wird, und so sehen Sie das kreisförmige Logo oben. Ordnung, dann haben Sie die zweite Spalte, und dort drüben zeigen wir im Grunde die Hauptüberschrift unserer Apps in der rechten Spalte. Okay, also für einen Untertitel verwende ich einen YouTube-Aufruf zum Handeln als anklickbaren Link, und das ist im Grunde das, was wir hier machen Der Wert unsafe allow STML, der gleich true ist, ermöglicht es uns im Grunde , grundlegende SML-Formatierungen wie fett gedruckten Text zu verwenden, und die Markdown-Formatierung wird im Grunde verwendet, um den wird im Grunde Dann zeigen wir die vergangene Konversation. also im Grunde alle vorherigen Chat-Nachrichten durch , die im Speicher gespeichert sind. Wir bekommen den Zeitstempel, wir bekommen den Absender und wir bekommen die Nachricht Und dann zeigen wir es fett im Markdown-Format mit dieser bestimmten Zeile und in diesem speziellen und in diesem speziellen Dann haben wir eine Callback-Funktion, die das vom Senden ausgelöste Flag setzt, wenn die Eingabetaste gedrückt wird Diese Funktion wird also automatisch aufgerufen , wenn der Benutzer die Eingabetaste in der Box drückt Also prüfen wir zuerst, ob die Eingabe nicht leer ist. Wenn es also nicht leer ist, setzen wir das Flag submit triggered auf true, um anzuzeigen, dass eine Abfrage verarbeitet werden muss. Das bedeutet nur, dass, und dann kopieren wir den Text in die ausstehende Abfrage, sodass wir ihn verwenden können, nachdem streamlt die App erneut geladen Darauf. Dann haben wir also das Eingabefeld. Das macht also im Grunde eine einzeilige Texteingabe. Das Label ist deine Anfrage. Wenn der Benutzer die Eingabetaste drückt, wird „ Senden bei Eingabe“ automatisch aufgerufen, und die Eingabe wird im Grunde als Query-Unterstrich-Eingabe innerhalb des Sitzungsstatus gespeichert Query-Unterstrich-Eingabe innerhalb des Sitzungsstatus Der Platzhaltertext, den wir verwenden, ist, Ihre Abfrage hier einzugeben, und das ist das Eingabefeld Dann haben wir drei Aktionsschaltflächen zum Senden der Anfrage, eine Schaltfläche für eine neue Konversation und eine Schaltfläche zum Speichern der Konversation Mit der Schaltfläche Senden wird die Anfrage also im Grunde an den MCP-Agenten gesendet. Die neue Konversationsschaltfläche löscht den Chat-Verlauf und Die Schaltfläche Konversation speichern speichert das aktuelle Chat-Protokoll als 58. 10.12 Kernlogik für die Abfragebehandlung: Jetzt haben wir also die Codelogik für die Abfragebehandlung, und zuerst haben wir diese Funktion Das ist also eine ASN-Funktion , die die Benutzeranfrage über SDD IO an das Backend sendet über SDD IO an das Backend und die Antwort als Zeichenfolge zurückgibt Wir fügen einen Protokolleintrag hinzu, dass wir den SDD-IO-Modus verwenden. Dann versuchen wir, die Run-Agent-Funktion aus dem Streamlt-Client SDD IO zu importieren Run-Agent-Funktion aus dem Streamlt-Client SDD IO Dies ist die Implementierung , die wir hier haben, und wir werden sie später durchgehen Und wir behandeln jeden Importfehler, falls er hier passiert, und dann starten wir den Agenten im Grunde mit der Abfrage, die wir importieren und der Abfrage , die wir hier erhalten haben, und wir erhalten das Ergebnis, wir fügen ein Protokoll hinzu, das besagt, dass wir die Anfrage verarbeitet haben , und wir geben das Ergebnis zurück. Dann haben wir also die Abfragefunktion handle und diese Funktion behandelt im Grunde den gesamten Lebenszyklus einer einzelnen Nachricht. Der Benutzer sendet es, wir senden es an das Backend und dann zeigen wir die Antwort an. Wenn der Benutzer also quid eingibt, setzen wir die Konversation hier auf eine leere Liste und protokollieren dasselbe. Andernfalls erhalten wir die aktuelle Uhrzeit, um die Benutzernachricht mit einem Zeitstempel Wir speichern die Benutzeranfrage im Konversationsverlauf und protokollieren sie hier. Dann senden wir die Anfrage mit der Funktion, die wir uns gerade angesehen haben, an das Backend und warten auf die Antwort Wir verwenden hier den SDD IO-Client. Wir speichern die Antwort von MCP hier. Dies ist im Grunde die Unterstützungsnachricht und wir protokollieren die beiden hier. Dann setzen wir die ausgeführte Abfrage auf zwei, sodass wir diese Abfrage nicht bei jedem erneuten Laden erneut ausführen. Dies hilft uns grundsätzlich dabei, Endlosschleifen für die Ausführung der Abfrage zu vermeiden Endlosschleifen für die Ausführung der Abfrage 59. 10.13 Auslösemlogik für Senden und andere Chat-Schaltflächen: Wir haben die Hauptauslöserlogik. Wenn der Benutzer also auf die Schaltfläche Senden geklickt hat oder der Benutzer die Eingabetaste im Eingabefeld gedrückt hat und die Abfrage in diesem Zyklus noch nicht ausgeführt wurde, das heißt, das Flag für die ausgeführte Abfrage ist falsch, wir holen die Abfrage aus der ausstehenden Abfrage im Sitzungsstatus, und wenn die Abfrage existiert, führen wir den Lebenszyklus der Abfrage im Grunde wir holen die Abfrage aus der ausstehenden Abfrage im Sitzungsstatus, und wenn die Abfrage existiert, führen wir den Lebenszyklus der Abfrage im Grunde mit Handle Query aus, was wir habe mir die Verwendung dieses Helpers angesehen, den wir uns am Anfang angesehen haben und der asynchronen Code innerhalb eines Streams ausführt. Und dann setzen wir dieses Flag auf false , damit sich der nächste Tastendruck Dann führen wir nach Abschluss der Abfrage die Streamlet-App nach Abschluss der Abfrage Wenn die ausgeführte Abfrage den Wert true hat, setzen wir sie auf False zurück, sodass wir uns grundsätzlich auf die neue Abfrage vorbereiten können, und wir erzwingen eine erneute Ausführung der Benutzeroberfläche mithilfe von st dot rerun den Bildschirm zu aktualisieren und die neuen Chat-Nachrichten anzuzeigen Dann haben wir die neue Logik der Konversationsschaltflächen. Wenn Sie darauf klicken, wird im Grunde der gesamte Chat-Verlauf gelöscht und protokolliert. Anschließend wird die App erneut ausgeführt, um den leeren Status widerzuspiegeln Dann haben wir die Schaltfläche „ Konversation speichern“. Dies wird uns im Grunde helfen, den Chat in einer Datei zu speichern . Wir stellen im Grunde sicher, dass das Konversationsverzeichnis hier existiert. Dann erstellen wir mit dieser speziellen Anweisung einen Dateinamen mit Zeitstempel und geben dann einen Pfad an, in dem das Konversationsverzeichnis und der Dateiname zusammengefügt Wir öffnen diese Datei und dann verwenden wir im Grunde Jasen Ton Dump, um die Konversation dort drüben abzulegen Wir fügen dann im Grunde ein Protokoll über unseren erfolgreichen Speichervorgang und zeigen es auch auf der Dies ist unsere gesamte StreamLTUnderscore-Client-Underscore-UI-PY-Datei StreamLTUnderscore-Client-Underscore-UI-PY-Datei 60. 10.14 Streamlit App MCP-Clientcode: Schauen wir uns nun die Stdio-PY-Datei des Stream-Clients an , die wir tatsächlich verwenden, um den Agenten im MCP-Client auszuführen den Agenten Dies ist im Grunde der Lang-Chain-MCP-Client Lang-Chain-MCP-Client Wenn Sie sich also diese bestimmte Vorlesung oder dieses Video bereits angesehen haben , können Sie diese Erklärung überspringen Andernfalls werden wir die Konzepte hier kurz durchgehen . In Ordnung. Diese Datei implementiert also im Grunde einen auf Lang-Chain oder Lang-Graphen basierenden MCP-Client Sie lädt die Konfiguration aus einer JCN-Datei, die durch die Umgebungsvariable AI-Sprachkonfiguration spezifiziert ist durch die Umgebungsvariable AI-Sprachkonfiguration spezifiziert Umgebungsvariable AI-Sprachkonfiguration Und wenn Sie das nicht finden , greift es im Grunde auf die lokale Datei hier zurück. Es stellt eine Verbindung zu allen MCP-Servern die in der Konfiguration definiert sind, lädt die verfügbaren MCP-Tools von jedem verbundenen Server und verwendet die Google Gemini-API über Langraph und Anchin, und verwendet die Google Gemini-API über Langraph und um einen Reaktionsagenten mit Zugriff auf alle Tools zu erstellen mit Zugriff Dann wird eine interaktive Chat-Schleife ausgeführt, sodass Sie diese Datei auch unabhängig ausführen können Aber wir werden es mit unserer Client-Benutzeroberfläche verwenden. In Ordnung. Dann haben wir die regulären Importe, mit denen wir uns früher befasst haben , als wir unsere Kunden entworfen haben. Wir haben also diese Importe für asynchrone Operationen, Umgebungsvariablen usw. Wir haben die MCP-Client-bezogenen Importe für die Verwaltung der MCP-Client-Sitzung und des MCP-Servers sowie für den Aufbau einer STD-IO-Verbindung Dann haben wir die Importe von Agenten und großen Sprachmodellen. Wir haben also einen Adapter, um die MCP-Tools in das Lang-Chin-Format zu Wir haben den React-Agent, vorkonfiguriert ist und mit Lang Graph geliefert wird, und dann haben wir den generativen KI-Zapper von Google für die Gemini-API Dann richten wir unsere Umgebung ein, sodass wir im Grunde die DOT-ENV-Datei laden , die unsere Umgebung ist Sie können hier tatsächlich sehen, dass wir die Punkt-ENV-Datei hier haben, was das ist, und Sie haben einen Google- und Gemini-API-Schlüssel definiert , der derselbe Schlüssel ist Wir verwenden einfach zwei verschiedene Variablen, um, du weißt schon, beide Optionen in unserem Code zu handhaben Dann haben wir einen benutzerdefinierten Encoder, der im Grunde genommen die Formatierung unseres JCN-Inhalts verwaltet, indem er nach einem Inhaltsattribut in den JCN-Schlüsseln sucht Dann haben wir die Funktion „Konfiguration lesen “. Das liest also im Grunde die JSON der MCP-Konfiguration , sodass wir tatsächlich die Umgebungsvariable AI-Sprachkonflikt haben Wenn das gesetzt ist, verwenden wir diesen Konfliktpfad. Wenn das nicht gesetzt ist, überprüfen wir grundsätzlich das aktuelle Verzeichnis und formulieren den Konfliktpfad auf der Grundlage aktuellen Verzeichnisnamens hier drüben und des KI-Sprachkonfliktpunkts jcnFLEM Das gibt uns also im Grunde diesen Dateipfad. Dann öffnen wir die Datei, wir hier ausgewählt haben, wir öffnen und laden das JCN Wir führen hier natürlich einige Ausnahmebehandlungen durch, um alle Arten von Fehlern zu behandeln. In Ordnung. Dann haben wir also die Run-Agent-Funktion und diese nimmt die Abfrage im Grunde als Zeichenfolge auf und gibt eine Zeichenkettenausgabe für die Benutzeroberfläche für unseren MCP-Client Das ist dem, was wir hier im Lang Chain MCP-Client mit Confect oder PI gemacht haben, sehr ähnlich im Lang Chain MCP-Client mit Confect oder PI Der einzige Unterschied besteht darin, dass die Abfrage hier eine Eingabe ist , die von der Benutzeroberfläche kommt, und nicht von der Funktion hier selbst als Abfrageeingabe als Benutzereingabe vom Terminal Im Grunde stellt dies eine Verbindung zu allen MCP-Servern her, die in der Konfliktdatei definiert sind, lädt deren Tools und verarbeitet dann diese Abfrage Das ist nun die Google Gemini LLM-Instanziierung. Wir haben dies verwendet, um das Modell hier zu spezifizieren . Wir verwenden auch den API-Schlüssel, den wir im Grunde aus den Umgebungsvariablen beziehen, und richten dann einige andere Parameter , die wir hier in den Kommentaren erklärt haben. Dann lesen wir die Konfliktdatei und rufen die MCP-Serverliste aus der Konfliktdatei ab, indem wir MCP-Serverliste aus der Konfliktdatei ab, indem den MCP-Serverschlüssel in der Konfiguration Wenn es keine MCP-Server gibt, wir einfach aus, dass wir keine MCP-Server finden konnten Andernfalls erstellen wir eine leere Liste von Tools, und diese wird im Grunde genommen am Ende verwendet, um sie an Gemini weiterzugeben Oder der React-Agent, den wir damit verwenden, wird im Grunde genommen an die Gemini-APA weitergeleitet, sodass das veraltete Sprachmodell versteht, welche Tools es zur Verfügung hat Ordnung. Also verwenden wir einen Async-Exit-Stack, um im Grunde mehrere asynchrone Ressourcen zu verwalten, und dann iterieren wir über jeden Servernamen und jede Serverinformation in den Punktelementen von cp servers Schauen wir uns kurz unseren AI-Sprachkonfigurationspunkt jcnFle an unseren AI-Sprachkonfigurationspunkt jcnFle und Sie können sehen, dass wir innerhalb der MCP-Server zwei Server haben, einen Terminalserver wir innerhalb der MCP-Server zwei Server haben Terminalserver ist im Grunde der Name eines Servers und Fetch ist der Name des Und alles andere sind die Serverinformationen , also im Grunde der Befehl und die Argumente Gehen wir nun zurück, damit wir jetzt verstehen, dass wir die Servernamen und die Serverinformationen in allen MCP-Serverelementen Dann nehmen wir im Grunde einen Server , wir stellen eine Verbindung zu ihm her Wir rufen dann die Serverparameter mit dem Befehl und den Argumenten ab. Wir verwenden die Serverparameter, um eine STD-Verbindung zum Server herzustellen , und wir erhalten die Lese- und Schreibstreams für diese Verbindung. Dann verwenden wir diese Lese - und Schreibstreams aus der Verbindung und erstellen im Grunde eine Clientsitzung, die wir in der Sitzung speichern. Dann initialisieren wir die Sitzung, es ist im Grunde ein Handshake - oder Einrichtungsvorgang , der mit MCP Dann verwenden wir den MCB-Adapter von Lang Chain um die MCP-Tools aus der Sitzung zu laden, und wir speichern sie in der Liste der Nun informieren wir den Benutzer im Grunde für jedes Tool in den Server-Tools durch Drucken darüber, informieren wir den Benutzer im Grunde dass wir dieses spezielle Tool geladen haben , und fügen es an die Liste der Tools an, die wir die Liste der Tools an, die Wir machen dann hier einen letzten Ausdruck und finden jede Ausnahme hier, und das wird im Grunde für jeden Servernamen gemacht Falls keine Tools gefunden wurden, wir im Grunde hier eine entsprechende Druckerklärung ab. Schließlich erstellen wir einen React-Agenten, indem die oben beschriebene Instanziierung des großen Sprachmodells und die Liste der Tools verwenden, die wir nach der Initialisierung aller Server im Grunde aus der Konflikt-JSON-Datei erhalten haben der Konflikt-JSON-Datei nach der Initialisierung aller Das ist unser Agent, und dann nehmen wir die Abfrage und rufen den Agenten mit Wir erhalten hier eine Antwort und drucken diese Antwort dann Wir drucken diese Antwort, nachdem wir sie formatiert haben, also suchen wir grundsätzlich Nachrichten im Antwortwörterbuch. Und wenn wir Nachrichten finden, nehmen wir sie in umgekehrter Reihenfolge auf. Wir wollen die letzte Nachricht von der KI, und wenn sie den Inhaltsparameter hat, drehen wir diesen Inhalt quasi um. Andernfalls geben wir grundsätzlich zurück , dass in der Nachricht keine KI-Antwort gefunden wurde. Schließlich haben wir hier den Haupteinstiegspunkt für diese Funktion definiert. In Ordnung. Damit ist die SDD-PY-Datei des Clients abgeschlossen. Endlich können wir uns hier die Punkt-Json-Datei mit dem AI-Sprachkonflikt ansehen hier die Punkt-Json-Datei mit dem AI-Sprachkonflikt 61. 10.15 theailanguage_config.json und andere Dateien: Schauen wir uns den Konfliktpunkt jcnFle in der KI-Sprache an. Schauen wir uns den Konfliktpunkt jcnFle in der KI-Sprache an. Hier drüben haben wir uns das schon kurz angeschaut, und wissen Sie, Sie haben einen MCP-Serverschlüssel, der eine Liste von MCP-Servern enthält, die in jcnfMat definiert sind, und wir haben hier zwei Server jcnfMat Wir haben den FET-Server. Dies ist ein vorgefertigter Server, den ich von Github für vorkonfigurierte Server für Modellkontextprotokolle bekommen den ich von Github für vorkonfigurierte Server für Modellkontextprotokolle habe , die ich online gefunden habe, und dann haben wir den Terminalserver Das ist also ein Server, den wir in einem unserer vorherigen Videos erstellt haben und der im Grunde dazu verwendet wird, und der im Grunde dazu verwendet wird Befehle auf dem Terminal auszuführen Deshalb nennen wir ihn Terminal Underscoe Server und daher der Name Und wir verwenden diese beiden Server nur um zu demonstrieren, dass mit mehreren Servern eine Verbindung hergestellt werden kann, und wir können tatsächlich alle Tools von diesen Servern laden und sie dann mit unserem MCP-Client verwenden Bevor ich also mit dem Ausführen dieser Datei und dem Einrichten auf dem Terminal weitermache , zeige ich Ihnen auch die Konversationsdatei, sodass Sie sehen können , dass Sie hier einen Konversationsordner mit zwei Konversationen haben hier einen Konversationsordner mit zwei Konversationen Lassen Sie uns also einen von ihnen öffnen, und so speichern wir Konversationen tatsächlich. Es ist also eine Liste von Nachrichten mit einem Absender , der der Benutzer oder MCP ist Dann haben wir die Nachricht, die hoch ist, und in diesem Fall ist es eine Antwort auf diese Nachricht, die lautet Hallo, wie kann ich Ihnen heute helfen Und dann haben wir hier einen Zeitstempel. Denken Sie am Ende auch daran, dass wir ein Logo verwenden Sie müssen hier eine JPG-Datei mit Logopunkten bereitstellen, die tatsächlich auf die Client-Benutzeroberfläche geladen und dort angezeigt wird 62. 10.16 Ausführen der Streamlit-Benutzeroberfläche: Führen Sie den UI-Typ Stream Run Streamlt Underscore Client Dies wird im Grunde die Benutzeroberfläche für uns starten. 63. ABSCHNITT 11 START - A2A oder Agent-zu-Agent-Protokoll - Lebenszyklus - 11.1 Einführung: Hallo, alle zusammen. Heute werfen wir einen spannenden Blick auf das ATA-Protokoll oder das Agent-to-Agent-Protokoll und wie es mit zwei leistungsstarken Tools funktioniert : Model Context Protocol und Agent Development Kit. Wir werden erläutern, was ATA ist, warum wir es benötigen und wie es eine leistungsstarke Zusammenarbeit zwischen Agenten über organisatorische oder technologische Grenzen hinweg ermöglicht leistungsstarke Zusammenarbeit zwischen Agenten über organisatorische oder technologische Grenzen hinweg . Wir werden uns auch mit den wichtigsten Komponenten von ATA befassen, die Sie gerade auf Ihrem Bildschirm sehen können und wie die typischen Abläufe verwaltet werden, z. B. die Verarbeitung von Datenermittlungen und andere Abläufe, die im Rahmen von A bis zu einer Kommunikation stattfinden. Wenn Sie also Programmierer oder Entwickler sind oder einfach nur technisch neugierig sind, sind Sie hier genau richtig Ordnung. Also fangen wir gleich am Anfang von einer leeren Tafel an. Um A bis A zu verstehen, müssen wir zunächst das Konzept von Agenten verstehen und wie sie in der Welt der großen Sprachmodelle oder LLMs funktionieren großen Sprachmodelle oder LLMs Wir haben zunächst ein großes Sprachmodell, und LLM ist im Grunde die Abkürzung dafür Das ist also wie GPT oder Gemini, und diese werden auf riesigen Datensätzen trainiert , die Antworten in natürlicher Sprache generieren, Code schreiben, Dokumente zusammenfassen und in vielen Bereichen argumentieren können Antworten in natürlicher Sprache generieren, Code schreiben, Dokumente zusammenfassen und Standardmäßig ist dieses umfangreiche Sprachmodell jedoch zustandslos und passiv. Es wartet auf eine Aufforderung und gibt eine Antwort, und das war's. Um mehr zu tun, packen wir es in etwas Intelligenteres ein. Das nennen wir einen Agenten. Um das zu tun, haben wir ein Agenten-Framework , eine Softwareschicht, die diesem großen Sprachmodell Speicher, Ziele und Tools bietet . Im Grunde hilft es uns also, Systeme aufzubauen , bei denen ein LLM weiß, was es zu tun versucht Es kann Schritt für Schritt argumentieren und Tools wie APIs, Suchmaschinen oder Datenbanken aufrufen , Suchmaschinen oder Datenbanken Stellen Sie sich das so vor einem einfachen Chat-Bot einen hilfreichen Mitarbeiter mit einem Gehirn, einer Aufgabenliste und Zugriff auf Software machen. Jetzt kommen mehrere lokale Agenten. In einer einzigen App oder Organisation haben wir also möglicherweise mehrere Agenten. Diese drei können also mehrere Agenten sein, einer zum Schreiben, einer für Analyse und einer für Datenbankabfragen usw. Sie können intern zusammenarbeiten , indem sie einen gemeinsamen Speicher, gemeinsamen Kontext oder die Nachrichtenübertragung verwenden. Und dann bilden diese zusammen im Grunde unseren Agenten , der im Grunde aus mehreren lokalen Agenten besteht die zusammenarbeiten, und der im Grunde Multi Agent Colab genannt wird im Grunde Multi Agent Colab genannt Jetzt können diese Agenten tatsächlich auf Tools, Ressourcen und andere Arten von APIs und Unternehmensanwendungen zugreifen , und zwar über ein sogenanntes Model Context-Protokoll Und wir haben bereits alle Details zur Funktionsweise von MCP durchgesehen alle Details zur Funktionsweise von MCP Und MCP hilft diesen Agenten im Grunde dabei, diese APIs und Unternehmensanwendungen mithilfe von Tools oder anderen Ressourcen zu nutzen diese APIs und Unternehmensanwendungen mithilfe von Tools oder anderen 64. 11.2 Warum A2A-Protokoll – A2A im Vergleich zu MCP: Hier ist der Haken. Die meisten Agentensysteme sind durch ihre eigene Infrastruktur begrenzt Ein Agent innerhalb eines Unternehmens oder eines Cloud-Servers kann nicht einfach mit einem anderen Agenten kommunizieren, der an einem anderen Ort entwickelt wurde, beispielsweise in einem anderen Unternehmen, einem anderen Rechenzentrum oder einer anderen Programmiersprache Das nennen wir organisatorische oder technologische Grenzen. Möglicherweise können diese Agenten aufgrund von API-Sicherheit, Netzwerkisolierung oder Systemkompatibilität oder Systemkompatibilität nicht über diese Grenze hinaus kommunizieren. Was passiert, wenn Agenten über diese Grenzen hinweg zusammenarbeiten müssen? Hier brechen die Dinge zusammen. Zwei intelligente Agenten, auch wenn sie beide brillant sind, können sich nicht gegenseitig helfen , weil es kein gemeinsames Protokoll oder keine gemeinsame Sprache für die Kommunikation gibt. Und hier kommt das Agent-to-Agent-Protokoll ins Spiel. ATA steht für Agent-to-Agent-Protokoll. Es ist ein Protokoll, das es Agenten ermöglicht, über diese organisatorischen oder technischen Grenzen hinweg miteinander zu kommunizieren über diese organisatorischen oder technischen Grenzen hinweg miteinander . Es bietet Agenten eine sichere und strukturierte Möglichkeit , sich gegenseitig zu entdecken, Nachrichten zu senden, Artefakte auszutauschen und gemeinsam an Aufgaben zu arbeiten, Artefakte auszutauschen und gemeinsam an Aufgaben zu arbeiten während sie gleichzeitig modular und in ihrer eigenen Umgebung in der Sandbox bleiben in ihrer eigenen Umgebung in der Sandbox Wie funktioniert ATA mit MCP und ADK? MCP ist also, wie wir uns bereits angesehen haben , das Modellkontextprotokoll, und es hilft diesen Agenten, mit diesen APIs und Unternehmensanwendungen zu arbeiten , indem es Tools oder Ressourcen und andere Arten von Datenbankabfragen usw. ADK hier ist das Agenten-Entwicklungskit, das Ihnen die Bausteine für die schnelle Erstellung und Bereitstellung Könnte andere Agenten-Frameworks wie Langraf verwenden und ADK ist eines davon von Google. ATA gibt jedem Agenten im Grunde einen Reisepass, um systemübergreifend zu reisen und bei globalen Problemen mit anderen Agenten zusammenzuarbeiten bei globalen Problemen mit anderen Das ist das Was und Warum von ATA. Als Nächstes werden wir die wichtigsten Komponenten des Lebenszyklus einer AA-Interaktion vom Handschlag bis zur Reaktion auf die Form von Artefakten aufschlüsseln die wichtigsten Komponenten des Lebenszyklus einer AA-Interaktion vom Handschlag bis zur Reaktion auf die Form von Artefakten aufschlüsseln 65. 11.3 Erkennung – A2A-Client, A2A-Server, Agentkarte: In Ordnung. Lassen Sie uns nun in die Kernkomponenten von away eintauchen, die auf dieser speziellen Seite im Grunde als Blöcke dargestellt werden . Außerdem der gesamte Lebenszyklus, im Grunde durch diese Pfeile gekennzeichnet ist und die typischen Abläufe zeigt, die bei der Kommunikation zwischen A und einem Protokoll passieren, und wie all diese zusammenwirken, um Eta zum Leben zu erwecken Fangen wir also mit dem ATA-Client an. Der 80-Client ist normalerweise eine App, Skript oder ein anderer Agent. Er nutzt im Grunde die ATS-Dienste und wird daher als Client bezeichnet Der Client ist derjenige, der die Anfragen wie die Aufgaben SEND, die wir uns ansehen, an die URL eines AT-Servers sendet Aufgaben SEND, die wir uns ansehen, an die URL eines AT-Servers Was ist der ATS-Server? Er stellt eine Reihe von Standard-STDP-Endpunkten zur Verfügung, die durch das ATA-Protokoll definiert sind, und ist dafür verantwortlich, Anfragen zu empfangen, Aufgaben zu verarbeiten und mit Ergebnissen zu antworten Als Nächstes haben wir die Agentenkarte. Nun, hier ist ein wirklich cooler Teil. Jeder ATA-Server hat eine Metadatendatei, die als Agentenkarte bezeichnet wird. Diese steht normalerweise unter bekannten Schrägstrich AgnToTJSN AgnToTJSN Wir nennen dies die bekannte URL und sie beschreibt den Namen des Agenten sowie die Beschreibung, die Fähigkeiten, die Fähigkeiten, die Endpunkt-URL und jede Authentifizierung, die der jede Authentifizierung Auf diese Weise kann der Client herausfinden und verstehen, was diese Agenten über den ATA-Server tun können. Ein Client kann also einfach die Agentenkarten abrufen , um die Fähigkeiten eines Servers zu ermitteln Dadurch ist das A-Protokoll selbsterklärend und sofort einsatzbereit Das haben wir Discovery genannt, bei der der AA-Client herausfindet , welche verschiedenen Agenten verfügbar sind und was sie tun können Jetzt wissen wir also, was ein Client und was ein Server ist und wie der Client all die verschiedenen Agenten über den Server, durch den Discovery-Flow, erkennen kann all die verschiedenen Agenten über den Server, durch den Discovery-Flow, durch den Discovery-Flow Als Beispiel könnten Sie einen Client haben, bei dem es sich um einen Personal Assistant Agent handelt , der für jeden Benutzer ausgeführt wird, und Sie könnten einen Server haben, drei verschiedene Agenten für diesen Personal Assistant Agent bereitstellt Dies könnte die Buchung von Flugtickets, Hotels und die Buchung von Taxis sein Ihr persönlicher Assistent kann dann im Grunde über den AT-Server herausfinden , dass es diese drei Agenten gibt , die Ihnen bei Reisebuchungen helfen Wenn der Benutzer den Kunden bittet , eine bestimmte Reise für ihn zu buchen, kann dieser Kunde dann diese Agenten finden und verwenden, um diese Reisebuchung abzuschließen 66. 11.4 Initiierung – Aufgaben, Meldungen, Teile: Wie läuft diese Arbeit nach dem Entdeckungsprozess ab? Dies geschieht durch Aufgaben, und das wollen wir uns als Nächstes ansehen. Die Kerneinheit der Arbeit in A wird also als Aufgabe bezeichnet. Wenn der Client möchte, dass etwas erledigt wird, sendet er eine Anfrage zum Starten einer Aufgabe, indem entweder Aufgaben senden oder Aufgaben SND abonnieren verwendet. Jeder Aufgabe ist eine eindeutige ID zugeordnet und sie kann sich in mehreren Zuständen befinden. Sie kann also entweder eingereicht werden oder sie kann sich im Status „In Bearbeitung“ befinden, oder sie kann den Status Eingabe erforderlich “ oder „Abgeschlossen“ haben. Fehlgeschlagen oder storniert. Der Client sendet im Grunde eine Anfrage zum Starten einer Aufgabe, und innerhalb der Anfrage sendet der Client eine Nachricht von der Benutzerrolle. Nachrichten stehen also für Kommunikationswege zwischen dem Client, der die Rolle Benutzer hat , und dem Agenten , der die Arbeit erledigt und den Rollenagenten hat. Und die Botschaft besteht im Grunde aus Teilen. Ein Teil ist eine grundlegende Inhaltseinheit innerhalb einer Nachricht oder eines Artefakts, dem wir uns später befassen werden Es gibt drei Typen, d. h. es kann sich entweder um einen Text- oder einen Dateiteil oder um einen Datenteil handeln Der Dateiteil kann grundsätzlich verwendet werden, um Dateien mit Inline-Bytes oder einem URI darzustellen . Und das Datenpad kann für strukturierte JSON-Beispielformulare verwendet werden . Kurz gesagt, wenn der Client möchte, dass etwas erledigt wird, generiert er eine eindeutige Aufgaben-ID und sendet die erste Benutzernachricht. Die Aufgabe selbst enthält eine Nachricht und die Nachricht besteht im Wesentlichen aus Teilen Dadurch wird offiziell eine Aufgabe auf dem As-Server gestartet. Dies wird als Initiation bezeichnet, und dies ist einer der Abläufe im 80-Protokoll, der nach dem Discovery-Flow stattfindet. 67. 11.5 Verarbeitung – Artefakte, Streaming, Push-Benachrichtigungen, Nicht-Streaming: Ordnung. Also, sobald wir die Aufgabe gestartet haben der Agent arbeitet, kann er so genannte Artefakte erzeugen. Bei diesen Artefakten handelt es sich also im Grunde um strukturierte Ergebnisse wie endgültige Antworten oder generierte Dateien oder strukturierte Daten. Und sie folgen auch derselben Teilstruktur, auf die Aufgaben und Nachrichten folgen. Wie kommuniziert der ATA-Server also seine Updates an den Client? An erster Stelle steht die Streaming-Option. Für lang andauernde Aufgaben, bei denen die Server Streaming unterstützen, können Clients das Streaming mithilfe von „Gesendete Aufgaben abonnieren“ aktivieren Der Server verwendet dann vom Server gesendete Ereignisse oder SSE, um Updates wie den Aufgabenstatus, neue Nachrichten oder die generierten Artefakte zu veröffentlichen. So sieht der Client den Fortschritt in Echtzeit. Alternativ unterstützt Gateway auch Push-Benachrichtigungen, sodass die Clients einen Webhook einrichten können, indem sie den Schrägstrich für die Push-Benachrichtigung von Aufgaben verwenden Schrägstrich für die Push-Benachrichtigung von Aufgaben Der Server ruft zurück, wenn neue Ereignisse eintreten, und das ist ideal für Integrationen, bei denen Polling oder Dies bildet also einen der Verarbeitungsmodi , der als Streaming-Modus bezeichnet wird Es gibt auch einen anderen Verarbeitungsmodus , der als Non-Streaming-Modus bezeichnet wird, und der Server erledigt die ganze Arbeit und antwortet am Ende mit dem Endergebnis. Die Wahl hängt von den Serverfunktionen und dem Anwendungsfall ab, und dieser Non-Streaming-Verarbeitungsfluss erfolgt direkt vom Server zum Client, wo der Server diese spezielle Aufgabe an den Client zurücksendet . 68. 11.6 Wechselwirkung - Eingabeerforderlicher Zustand: Manchmal erreicht der Agent einen Punkt, an dem er mehr Eingaben benötigt In diesem Fall geht er in den Status „ Interaktion“ oder „ Eingabe erforderlich“ über. In diesem Fall kann der Client die Konversation fortsetzen, indem er weitere Nachrichten mit derselben Task-ID an den Server sendet mit derselben Task-ID an den Server um die Anforderungen in diesem Interaktionsablauf zu erfüllen. 69. 11.7 Abschlussablauf und Zusammenfassung von A2A: Irgendwann werden die Aufgaben einen Zustand erreichen , den wir als Abschluss bezeichnen Dies ist also ein Terminalstatus und die Aufgabe kann entweder abgeschlossen, fehlgeschlagen oder abgebrochen werden. An diesem Punkt ist die Aufgabe erledigt und die Artefakte und die Nachrichtensperre können nach Bedarf gespeichert oder angezeigt werden. Das ist also ein detaillierter Blick auf die Kernkomponenten und Lebenszyklus des A-zu-Protokolls. Es gibt Agentenkarten für die Erkennung über den Server , mit denen der Client herausfinden kann welche Agenten verfügbar sind und was sie tun können. Es gibt Aufgaben und Nachrichten, darunter auch Teile für die Kommunikation, bei denen die Clients eine Aufgabe mit einer ID initiieren und an den Server senden können Das ist im Grunde der Initiationsablauf. Dann gibt es zwei Verarbeitungsmodi, nämlich den Streaming-Modus und den Non-Streaming-Modus, und der Server kann dann grundsätzlich Artefakte verwenden, das sind die Ausgaben, die er generiert um den Client in Echtzeit über den Fortschritt zu informieren, oder er kann auch Push-Benachrichtigungen verwenden, und auf der anderen Seite kann die Verarbeitung über den Non-Streaming-Modus erfolgen, kann die Verarbeitung über den Non-Streaming-Modus erfolgen wo Das Endergebnis mit der Aufgabe und derselben ID kann an den Client zurückgesendet werden. Immer wenn weitere Informationen benötigt werden, kann der Interaktionsablauf im Grunde mehr Nachrichten an den Server weiterleiten, und dann haben Sie einen endgültigen Abschlussstatus in dem die Aufgabe abgeschlossen ist. Entweder wurde sie erfolgreich abgeschlossen oder sie schlägt fehl oder sie wird abgebrochen. ATA ermöglicht es auf diese Weise, modulare, dezentrale und kollaborative KI-Agenten zusammenzuarbeiten, unabhängig davon, wo sie gehostet werden. 70. ABSCHNITT 12 START - Erstellen eines eigenen A2A-Clients und A2A-Servers: Heute machen wir einen einfachen ersten Schritt in die Welt des Agent-to-Agent-Protokolls von Google und erstellen zwei Agenten, einen Server-Agenten Das ist der Server-Agent hier im letzten Video Wir haben uns bereits mit den verschiedenen Komponenten des ATA-Protokolls und dem Lebenszyklus der ATA-Protokoll-Kommunikation befasst ATA-Protokolls und dem Lebenszyklus der . Wir werden uns einen Server-Agenten ansehen , der die aktuelle Uhrzeit anzeigt. Ein sehr einfacher Serveragent, der Ihnen einfach sagt, wie spät es gerade ist. Und dann schauen wir uns einen Client-Agenten an , der diesen Serveragenten im Grunde durch den Erkennungsprozess entdeckt , die Agentenkarte abruft, im Grunde die Fähigkeiten, Fähigkeiten und Endpunkte usw. dieses bestimmten Agenten angegeben sind , und dann eine Aufgabe an diesen bestimmten Serveragenten sendet Dieses Tutorial ist also sehr anfängerfreundlich und konzentriert sich nur darauf, diesen Erkennungsablauf zu verstehen Wie der ATA-Client den Agenten über die Agentenkarte und den AOS-Server erkennt den Agenten über die Agentenkarte und den AOS-Server Und dabei werden wir auch verstehen, wie der Client mithilfe des Task-Slash Send Endpoint eine Aufgabe über den ATA-Server an den Agenten senden kann mithilfe des Task-Slash Send Endpoint eine Aufgabe über den ATA-Server an den Agenten senden Und dann, wie der Server mit einer Antwort reagiert und wie der Client diese empfangen und anzeigen kann Während wir über die Aufgabe sprechen, schauen wir uns auch an, wie die Aufgabe aus Nachrichten zusammengesetzt ist , und jede Nachricht wird in diesem Fall aus Teilen bestehen. In unserem Fall verwenden wir nur einen einfachen Textteil, um die Nachricht und die Aufgabe zu erstellen. Nur ein Hinweis, dass wir tatsächlich einen sehr einfachen Server- und Client-Agenten verwenden einen sehr einfachen Server- und Client-Agenten , der vorerst kein großes Sprachmodell verwenden wird , sodass wir einfach verstehen können , wie diese grundlegenden Aspekte des AA-Protokolls funktionieren, und von hier aus werden wir es in zukünftigen Vorlesungen und Videos weiterentwickeln, um komplexere Server und komplexere Server und Clients zu erstellen. Okay, lassen Sie uns also anfangen und uns diese erstaunliche erste Implementierung eines Clients und eines Servers ansehen, die wir heute durchführen werden Ordnung, also lassen Sie uns zuerst die Ordnerstruktur für dieses Projekt erstellen Also, genau wie wir es für MCP getan haben, werden wir ein Stammverzeichnis namens Two A erstellen, und darin werden wir ein Beispielverzeichnis für unseren Client und Server Lassen Sie uns also das Verzeichnis 82 erstellen. Dann machen wir das A Two zu einem Beispielverzeichnis innerhalb des Stammverzeichnisses 82. Lassen Sie uns nun ein Serververzeichnis zwei Unterstrichen erstellen, und lassen Sie uns auch ein Client-Verzeichnis erstellen Jetzt haben wir diese beiden Ordner, einen für den Server-Agenten und einen für den Client-Agenten Lassen Sie uns jetzt den Code für unseren Server schreiben. Also werde ich eine Datei für diesen Server-Agenten erstellen, die sich im Serververzeichnis befindet, und der Name der Datei ist telltserver dot P. Also dieser Server wird uns auch hier nur die aktuelle Uhrzeit mitteilen, und das ist die grundlegende einfache Funktion Wir werden eigentlich kein großes Sprachmodell oder einen echten Agenten verwenden , da dies nur eine Demo ist, um das Achta-Protokoll für uns einzurichten und die ersten Schritte zu unternehmen, um zu verstehen, wie diese Client - und Server-Agenten codiert werden. Lassen Sie uns nun diese Datei im VS-Code öffnen. In Ordnung. Das ist unsere Telltserver Punkt P-Datei, und das ist im Grunde ein Zweierserver für uns, der einige grundlegende Aspekte des Protokolls implementieren wird , sodass wir verstehen, wie wir mit der Codierung unserer 80 Server beginnen, und wir werden dieses Verständnis im Grunde in späteren Videos weiter nutzen , um dann komplexere Lassen Sie uns also diesen Code durchgehen. Also importieren wir zuerst die FLASK-Klasse und die Hilfsfunktionen aus dem FLASK-Paket, und FLASK ist im Grunde ein leichtes Web-Framework, das zum Erstellen von GDP-APIs und Webservern verwendet wird Erstellen von GDP-APIs und Importieren Sie dann die Daytime-Klasse aus dem eingebauten Daytime-Modul von Python, und dies wird im Grunde verwendet um die aktuellen Daten und die aktuelle Uhrzeit abzurufen, und das ist vorerst die grundlegende Funktion unseres Servers Dann erstellen wir eine neue Flask-App-Instanz und diese initialisiert im Grunde unsere Serveranwendung , sodass wir Endpunkte darauf definieren können Jetzt definieren wir also den Endpunkt für die Agentenkarte, und das hilft uns im Grunde in Und falls Sie mein Video mit einem vollständigen Überblick über ATA-Komponenten und deren Lebenszyklus gesehen haben , lassen Sie mich kurz darauf eingehen und es Ihnen zeigen. Der ATA-Client verwendet also den Discovery-Flow um die Agent-Karte über den ATA-Server zu ermitteln, und genau das versuchen wir hier zu implementieren. Agent-Karte wird auf Wellnonlash AGO ASN mit Schrägstrich gehostet handelt es sich um die bekannte URL für den Server . Sie definiert im Grunde die Fähigkeiten, Fähigkeiten, die Endpunkt-URL und die Authentifizierung für Kehren wir nun zu unserem Servercode zurück. Und jetzt können Sie sehen, dass wir einen STDPG-Root für diesen bekannten Agent-Discovery-Pfad definiert haben diesen bekannten Agent-Discovery-Pfad wie es das Protokoll verlangt Und gemäß der ATS-Spezifikation entdeckt der Client einen Agenten, entdeckt der Client einen Agenten indem er diese spezielle URL aufruft Also haben wir diese spezielle Wurzel mit Python und der G-Methode definiert mit Python und der G-Methode und nennen diese Funktion Agent underscoecard Der einzige Zweck dieser Funktion besteht darin, die Metadaten über diesen Agenten im JCN-Format zurückzugeben , und das beinhaltet im Grunde all diese Details Name des Agenten, und wir nennen ihn Tell Time Agent, und dann gibt es eine Beschreibung, die angibt, was der Agent tut Das ist nur der Agent, der nur die aktuelle Uhrzeit mitteilt, wenn er danach gefragt wird. Beachten Sie also noch einmal, dass dies im Grunde genommen bedeuten würde , einen Agenten anzurufen, ein umfangreiches Sprachmodell oder sogar mehrere lokale Agenten verwendet , um vorerst nützliche Arbeit für uns zu erledigen nützliche Arbeit für uns , nur um zu verstehen, wie TA funktioniert. Wir programmieren das fest als Agent, der die aktuelle Uhrzeit mitteilt, wenn wir danach gefragt werden, und wir verwenden dafür eigentlich kein LLM Wir geben die Uhrzeit einfach direkt mithilfe der Datums- und Uhrzeitbibliothek in Path an Dann teilt es die URL mit. Hier werden wir also im Grunde unseren Agenten und in diesem Fall diese Flask-App hosten, und das wird der lokale Host Colon 5.000 sein, was die Portnummer ist Eine Versionsinformation für den Agenten wird hier bereitgestellt, was ein Punkt ist, und dann stellen wir die Funktionen den Funktionen für Row handelt es sich um Streaming- und Push-Benachrichtigungen, die beide so eingestellt sind, dass sie ausfallen. Das bedeutet also, dass unser Agent keine Streaming-Updates unterstützt. Es informiert den Client also nicht in Echtzeit über den Fortschritt der Aufgabe. Und es bietet auch keine Push-Benachrichtigungen , da dies der erste Schritt ist , den wir einfach halten wollen. Also machen wir einfach weiter und setzen diese beiden Fehler. Dann definieren wir den Endpunkt für die Aufgabenbehandlung. Das ist also wieder Tasks CNN, wie es das ATA-Protokoll verlangt, und wir definieren einen Post-Root für diesen speziellen Endpunkt Und das ist der Hauptendpunkt, über den die 80 Clients eine Aufgabe an diesen Agenten senden können Wie Sie sehen können, haben wir den Schrägstrich Send für die Root-Aufgabe der FAS-App zusammen mit der Post-Methode verwendet , und der Name der Funktion zur Bearbeitung dieses speziellen Stammverzeichnisses lautet Handle Underscore-Aufgabe Das macht also im Grunde genommen die eingehende JSON-Nutzlast in ein Python-Wörterbuch Es extrahiert die Aufgaben-ID aus der jeweiligen Nutzlast. Nochmals, falls Sie sich erinnern, wir haben eine Aufgabe mit einer eindeutigen ID, und genau das versuchen wir hier zu vermitteln. Dadurch wird die Aufgabe im Acht-Wege-Protokoll im Grunde eindeutig identifiziert Dann extrahieren wir den Text der Benutzernachricht aus dem ersten Nachrichtenteil. Die Aufgabe selbst hat im Grunde eine Nachricht, die aus Teilen besteht, und wir gehen davon aus, dass der erste Teil etwas namens Text enthält, was der Textteil ist, und wir werden das als Benutzernachricht erhalten. Wenn die Anfrage nicht der erwarteten Struktur entspricht, drehen wir hier im Grunde einen 400-Fehler um. Jetzt werden wir eine Antwort auf die Benutzernachricht generieren . Auch in diesem Fall ist die Antwort sehr einfach. Der Agent verwendet kein umfangreiches Sprachmodell, sondern wir verwenden lediglich die Tagesbibliothek, um die aktuelle Uhrzeit abzurufen , sie als Zeichenfolge zu formatieren und diese aktuelle Uhrzeit zurückzugeben. Die Antwortnachricht des Agenten lautet, dass die aktuelle Uhrzeit die aktuelle Uhrzeit ist. Dann geben wir eine korrekt formatierte Aufgabenantwort von A bis 8 zurück , und diese beinhaltet im Grunde die Nachricht bei der es sich um die ursprüngliche Nachricht handelt und eine neue Nachricht vom Agenten Es heißt also, dass wir neben der Aufgaben-ID zurückkehren, wir verwenden dieselbe Aufgaben-ID wie in der Antwort Wir geben dem Aufgabenstatus einen Aufgabenstatus an , der den Status „Abgeschlossen“ darstellt. Dann platzieren wir die Nachrichten. Also zuerst die ursprüngliche Benutzernachricht für den Kontext, und dann haben wir eine weitere Nachricht , die eine Rolle für den Agenten hat, was im Grunde besagt, dass diese Nachricht vom Agenten stammt. Und dann haben wir die Teile, was wiederum nur ein einfacher einzelner Textteil ist, in dem der beantwortete Text enthalten ist. Schließlich betreiben wir den Flask-Server, und im Grunde ist dies der Hauptblock, der die Flask-Cap nur dann ausführt , wenn das Skript direkt ausgeführt wird, und er startet als Server auf dem Port Five Triple Zero In Ordnung, das ist alles für unseren Servercode. Ordnung. Also machen wir jetzt die Datei für unser E zu einem Client. Ich schreibe also Touch, also schreibe ich Touch also schreibe ich Touch Client Schrägstrich und Unterstrich Klient Punkt P, und das ist im Grunde unser A für einen Kundenagenten Dieser Agent wird dann im Grunde den Tell Time-Server und den Agenten erkennen und sie im Grunde verwenden, um die aktuelle Uhrzeit abzurufen Drücken wir die Eingabetaste. Lassen Sie uns das mit VS-Code öffnen. Ordnung. Das ist unsere Zeit Punkt-Py-Datei für den Client zu unterstreichen, und lassen Sie uns den Code für diesen Kundenagenten durchgehen Zunächst importieren wir die Anforderungsbibliothek, um HTTP G- und POST-Anfragen zu senden. Dadurch kann der Client im Grunde über STDP Dadurch kann der Client im Grunde mit dem Server kommunizieren Dann hast du eine UUID. Dadurch wird das UID-Modul importiert , um eindeutige Aufgaben-IDs zu generieren, und jede ATA-Aufgabe muss eine eindeutige ID haben. In Ordnung. Der erste Schritt für den Kunden besteht also darin, den Agenten zu finden. Also definieren wir eine Basis-URL für unseren Agenten, und das wird der lokale Host Coren 5.000 sein, was dem entspricht, was wir in tellt server dot PI definiert haben Dann verwenden wir StdPgrQuest, um die Karte des Agenten vom bekannten Erkennungsendpunkt für den AS-Server abzurufen Karte des Agenten vom bekannten Erkennungsendpunkt für den AS-Server Also schreiben wir den Anforderungspunkt G und geben die Basis-URL Im Grunde fügen wir ihr dann den Pfad für die Nur für den Fall, dass die Anfrage fehlschlägt, kümmern wir uns darum und geben einen Fehler Dann übergeben wir die Antwort Jason in ein Python-Wörterbuch. Wir erhalten also die Underscoe-Informationen für den Agenten, und das sind alle Informationen von der Agentenkarte, die wir in der Antwort aus dem Discovery-Prozess erhalten haben Jetzt drucken wir also im Grunde, dass wir mit dem Namen dieses bestimmten Agenten verbunden sind Namen dieses bestimmten Agenten und die Beschreibung des Agenten so und so ist Und das wird auf die Konsole gedruckt, um zu zeigen, dass wir diesen Agenten entdeckt haben. In Ordnung. Der nächste Schritt besteht also darin, eine Aufgabe so vorzubereiten, dass wir mit UID vier eine eindeutige ID für diese Aufgabe generieren Das ist also eine zufällige UID, und so erhalten wir die Aufgaben-ID. In Ordnung. Als Nächstes werden wir also die erstellen Payload für 82 Aufgaben als Python-Wörterbuch Gemäß der achten Spezifikation müssen wir also die ID, also die eindeutige Aufgaben-ID, und die Nachricht angeben eindeutige Aufgaben-ID, und die Nachricht Es ist also ein Objekt mit der Rolle Benutzer und einer Liste von Teilen. In diesem Fall sind es nur Textteile. Wir haben also eine Aufgaben-Payload. Wir haben die eindeutige Aufgaben-ID hier drüben. Und wir haben eine Nachricht. Die Nachricht hat eine Benutzerrolle und dies weist im Grunde darauf hin, dass die Nachricht vom Benutzer oder vom 80-Client stammt . Und dann haben wir die Teile und für die Teile haben wir nur einen Textteil, der nur sagt, wie spät es ist. Ordnung. Also dann schicken wir die Aufgabe quasi an den Agenten. Also senden wir eine StdpPostrQuest Endpunkt Tasks Send Wir verwenden den JcnParameter, sodass Anfragen Also sagen wir im Grunde Request Dot Post . Wir verwenden die Basis-URL und dann den Standardpfad für das Senden einer Aufgabe, nämlich den Schrägstrich der Aufgabe , den Schrägstrich SND und erhalten im Grunde eine Antwort Wenn der Server nun nicht den Status 2000 zurückgegeben hat, wir hier einen Fehler aus. Dann analysieren wir die Antwort Jason in unterstrichene Antwortdaten. Schließlich haben wir Schritt vier, hier drüben werden sie die Antwort des Agenten anzeigen des Agenten Also extrahieren wir die Liste der Nachrichten, die in der Antwort zurückgegeben wurden. Die Antwort besteht also im Wesentlichen aus Nachrichten, und dazu gehören in der Regel sowohl die Nachricht des Benutzers als auch die Antwort des Agenten. So kommen wir also zu Nachrichten. Wenn es Nachrichten gibt, extrahieren wir die letzte und drucken sie aus. Es wird also erwartet, dass dies die Antwort des Agenten ist. Wir haben also eine endgültige Antwort, die aus Nachrichten minus eins besteht, was im Grunde die letzte Nachricht ist. Bei dieser speziellen Nachricht schauen wir uns dann alle Teile an und nehmen den ersten Teil. In diesem Teil nehmen wir dann den Textteil heraus, und das ist im Grunde die endgültige Antwort des Agenten. Und dann drucken wir einfach, was der Agent sagt, und hier drüben erwarten wir, dass er uns die aktuelle Uhrzeit mitteilt. Auch hier behandeln wir jede Art von Fehler. Wenn keine Nachricht empfangen wurde, benachrichtigen wir den Benutzer grundsätzlich nur, indem wir ihm mitteilen, dass keine Antwort eingegangen ist. Das ist alles für die Zeit wenn der Kunde fünf Punkte bezahlt . Alles klar Jetzt sind wir bereit, unseren Client und Server zu testen. Bevor wir das tun, müssen wir zunächst überprüfen, ob wir die richtige Version von Python installiert haben und ob wir alle Bibliotheken , die wir verwenden, installiert haben oder nicht. Und wie Sie sehen können, habe ich 3.13 0.2. Gemäß der Spezifikation benötigen Sie mindestens 3.12 oder höher von A bis A. Falls Sie nicht die richtige Python-Version installiert haben , öffnen Sie bitte einen Browser Ihrer Wahl und suchen Sie nach Python bitte einen Browser herunterladen. Gehen Sie auf den Python-Download-Link mit Punkt oder Schrägstrich, indem Sie hier klicken, und dann können Sie auf Python 3.13 0.3 herunterladen oder was auch immer die neueste Version hier ist klicken . Sobald Sie darauf klicken, wird ein Installationsprogramm für Sie heruntergeladen und Sie können Python installieren, indem Sie den Anweisungen auf dem Bildschirm folgen. Sobald Sie Python installiert haben, überprüfen Sie bitte die Version, indem Python Three Dash Version eingeben. Als Nächstes werde ich die Flask- und die Request-Pakete installieren , die wir im Code verwenden Und um das zu tun, schreibe einfach PIP install FAsk and requests. In Ordnung Also das hat beide Pakete für uns installiert. Lass uns den Bildschirm löschen. In Ordnung. Jetzt können wir unseren Server und Client testen. Gehen wir dazu zunächst zum Verzeichnis mit 80 Beispielen. Und wie Sie sehen können, ist das mein aktuelles Verzeichnis im Home-Verzeichnis. In Eta befinde ich mich im Verzeichnis mit acht Unterstrichen Wechseln wir nun zum Serverordner und starten diesen Server, indem wir Python Drei eingeben. Sag dem Server, nicht zu zahlen. In Ordnung Also jetzt habe ich den Server auf dem lokalen Host Colon 5.000 laufen lassen. Lassen Sie mich jetzt ein neues Terminal öffnen. Hier werde ich in das Client-Verzeichnis wechseln und meinen Client starten, indem ich Python Three, Time Undisco Client Punkt PY eintippe. In Ordnung. Sobald Sie also den Punkt PI des Time Clients ausführen, möglicherweise ein Fehler angezeigt, der den Agenten nicht erkannt Dies ist eine der Ausnahmen , die wir codiert haben. Und das liegt daran, dass Sie möglicherweise lokalen Host verwenden. Ich habe den Code aktualisiert, sodass er 127.0 0.0 0.1 verwendet, und das hängt nur davon ab, wie Ihr System den lokalen Host auflöst Einige Systeme lösen den lokalen Host möglicherweise auf diese bestimmte Adresse auf, was dann in Ordnung ist Aber für mein System habe ich es auf 127.0 0.0 0.1 geändert. Und jetzt, wenn ich meinen Time Underscore Client Punkt PY starte, ich im Grunde eine Verbindung mit dem Tell Time Agent her, der mir die aktuelle Uhrzeit mitteilt, wenn ich danach gefragt werde, und jetzt erhalte ich die Antwort, wo Agent sagt, dass die aktuelle Uhrzeit ist, der Agent sagt, dass die aktuelle Uhrzeit ist, und dann haben wir das aktuelle Datum und die aktuelle Uhrzeit Also, Leute, ist es nicht erstaunlich , dass wir im Grunde unser erstes Beispiel für 80 Clients und achtzig Server gebaut haben ? Zurück zu unseren acht Komponenten und unserem Lebenszyklus-Sheet hier haben wir uns im Grunde genommen damit befasst, wie man ein einfaches A an einen Client schreibt , der Anfragen an den Task-Slash SEND senden kann Wir haben eine Aufgabe mit einer Nachricht verwendet, die einen Teil hatte , der ein Textteil war, und jetzt können wir diesen auf kompliziertere Aufgaben ausdehnen Diese Aufgabe wird dann an einen Server gesendet, der diese Aufgabe im Grunde analysiert und dann eine Antwort zurückgibt , und der Client zeigt diese Antwort Bevor all das passiert, erkennt der Client den Agenten im Grunde anhand des Erkennungsprozesses mithilfe der Agentenkarte Wir haben all diese Komponenten jetzt in unserer ersten sehr einfachen Implementierung behandelt und werden dieses Wissen nun nutzen, um detailliertere Agenten zu erstellen , während wir uns mit dem ATA-Protokoll vertraut machen 71. ABSCHNITT 13 START - Erstellen Sie Ihren eigenen A2A-Agenten mit dem Google Agent Development Kit (ADK) - Einführung: Wird mit dem brandneuen Agent Development Kit von Google, auch ADK genannt, einen ATA-Agenten erstellen brandneuen Agent Development Kit von Google, auch ADK genannt, einen ATA-Agenten auch ADK genannt Wenn Sie wissen möchten, wie Agenten reibungslos kommunizieren und zusammenarbeiten können, ist dieses Video Ihr schrittweiser Ausgangspunkt Bevor ich anfange, werfen einen kurzen Blick darauf, was wir heute bauen werden. Das A-zu-A-Agent-zu-Agent-Protokoll ist leistungsfähiger und etwas komplexer als das herkömmliche Modellkontext-Protokoll , mit dem einige von Ihnen vielleicht gearbeitet haben. Daher ist es sehr wichtig zu verstehen, wie diese Komponenten zusammenarbeiten , denn das ist das Geheimnis beim Aufbau skalierbarer 80 Agenten Wir werden also vier Hauptkomponenten behandeln, und um Ihnen das zu zeigen, habe ich hier die Ordnerstruktur für unseren speziellen AA-Agenten, der das Google ADK verwendet Also hier sind die vier Schlüsselkomponenten. Sind Agenten Server, Client und App, und dann haben wir einige Datenmodelle, die uns im Grunde helfen , Daten zwischen dem Client und der Server-Site auszutauschen. Also die Serverseite sind im Wesentlichen die Agenten, und hier haben wir vorerst nur einen Agenten, nämlich einen auf Google ADK basierenden Agenten Unter Agent Punkt PI. Dies definiert den von Gemini betriebenen Tell Time Agent, und dann haben wir einen Task Manager , einen benutzerdefinierten Manager, der den Agenten mit der Aufgabe verbindet Er verwaltet im Grunde die Aufgabenlogik, ruft das Gemini-Modell auf und so weiter, und dann haben wir Die Server-PY-Datei startet im Grunde den ATA-Server und er empfängt und rootet die Aufgabe, und der Task Manager PI hier drüben ist im Grunde nur eine Basisklasse, und diese wird verwendet, um dann tatsächlich auf dem eigentlichen Agent-Taskmanager hier drüben aufzubauen auf dem eigentlichen Agent-Taskmanager hier drüben Beide zusammen sind also im Grunde serverseitig , weil Sie den Agenten ausführen möchten , der dann seinen Server hochfährt und sich selbst über die URL und den Port des Servers zugänglich macht. Dann haben Sie die Client-Seite. Auf der Client-Seite gibt es also den eigentlichen Client , der im Grunde Aufgabenanfragen an A-Agenten sendet . Dies stellt im Grunde eine Verbindung zum Agenten sendet Anfragen und ruft die Ergebnisse ab Jetzt ist der Cmd Dot PI im Grunde eine Befehlszeilenschnittstelle, mit der wir Anfragen testen und auslösen Es ist im Grunde eine App, bei der es sich um eine Befehlszeilenschnittstelle handelt, über die der Client ausgeführt und Aufgaben an den Agenten gesendet Diese beiden zusammen bilden die Client-Seite, und wie Sie sehen, der Server, der Agent, sind der Server, der Agent, der Client und die App alle modular aufgebaut, Sie könnten mehrere Agenten haben und derselbe Server kann mit allen Agenten hier arbeiten. Der Agent muss nur seinen eigenen Server einrichten und kann dann den allgemeinen Code hier verwenden. In ähnlicher Weise haben Sie einen Client, der grundsätzlich Aufgaben an jeden Agenten senden kann. Sie müssen nur angeben, an welchen Agenten Sie senden möchten, oder Sie möchten eine Erkennungslogik haben , bei der der Client die verfügbaren Agenten erkennt und dann die Aufgabe sendet, was eine komplexere Angelegenheit ist, auf die in späteren Videos tatsächlich eingegangen wird Dann haben Sie eine App. Also, wie lässt man den Client laufen? Wie Sie damit interagieren, erfolgt im Grunde über eine Befehlszeilenschnittstelle hier drüben, das ist der Cmd Dot Pyle Andernfalls können Sie tatsächlich eine visuelle Oberfläche haben , wie wir es für unseren MCP-Code getan haben Wir haben eine schlanke Benutzeroberfläche erstellt. Wir können hier mehrere Arten von Apps erstellen, die denselben Client-Server und dieselben Agenten verwenden hier mehrere Arten von Apps erstellen, die denselben Client-Server und dieselben Agenten Schließlich haben wir die Modelle, und diese Modelle definieren im Grunde verschiedene Aspekte der Datenstruktur für die Kommunikation zwischen diesen Komponenten. Agent PI definiert also die Agentenkarte und die Agentenfähigkeiten. JSON-Unterstrich RpcTPI ist im Grunde die Basisklasse für das JCN-RPC-Protokoll, bei dem es sich um ein Protokoll zum Aufrufen von Remoteprozeduren handelt Die Anforderungs-PY-Datei verarbeitet im Wesentlichen Aufgaben- und Metadaten-Anforderungstypen, und die Task-Dot-PY-Datei ist die zentrale 72. 13.2 Kurzdemo des A2A Agenten: Wir bauen einen ATS-Server und unseren Agenten. Wir starten den As-Server und unseren Agenten in einem Terminalfenster. Im Grunde führen wir den Agenten und der Server wird dann hochgefahren und ist bereit, auf eingehende Aufgaben von jedem Client auf diesem bestimmten Host-Link zu warten. Dann starten wir in einem separaten Terminalfenster den Befehlszeilenclient mit einem einfachen Python-Skript. Wir erstellen einen Befehlszeilenhost oder eine App für unseren Client und haben die Server-URL des Agenten angegeben hier die Server-URL des Agenten angegeben, und dann starten wir das. Wir werden die Anfrage schreiben. Wie viel Uhr ist es? Wir wollen das von unserem Agenten wissen. Und jetzt, wie Sie sehen können, sendet der Client im Grunde eine JSON-RPC-Anfrage RPC steht also für Remote Procedure Call, und hier haben wir die Methode Task CIN, die zum Senden einer Aufgabe verwendet wird Wir haben eine ID für die Aufgabe, die hier drüben ist. Wir haben eine Sitzungs-ID, die unsere Post-App grundsätzlich verwaltet. Dann haben wir eine Nachricht vom Benutzer, die Teile hat, und das ist im Grunde ein Textteil , um wie viel Uhr ist es? Und dann gibt es noch einige andere Eigenschaften , die wir derzeit nicht verwenden. Und dann bekommen wir eine Antwort vom Agenten, die besagt, dass die Zeit gekommen ist und dann haben wir die Zeit hier drüben. Wir haben im Wesentlichen eine App erstellt, also eine Befehlszeile basierende App die im Grunde mit einem Client kommuniziert und eine Aufgabe an einen Server sendet, dann mit dem Agenten kommuniziert, um die Aufgabe zu erledigen, und eine Antwort sendet Der Agent verwendet das ADK-Agenten-Framework von Google um mithilfe der Gemini-API einen Agenten zu erstellen 73. 13.3 Code und Gemini-API-Schlüssel einrichten: Lassen Sie uns über die Einrichtung dieses Codes sprechen. Als Erstes verwenden Sie bitte die URL in der Beschreibung, um den Code von Github auszuchecken. Und sobald Sie das getan haben, haben Sie eine Ordnerstruktur wie diese. Wie bereits erwähnt, haben Sie Agenten, Sie haben die App, Sie haben den Client und Sie haben die Modelle und den Server. wir weitere Versionen davon erstellen, werden wir den alten Code tatsächlich in die Versionsordner verschieben . Im Moment habe ich zum Beispiel den älteren Code auf Version eins verschoben und es ist Code Simple, das war ein einfacher 8-Wege-Server und -Client, und Version zwei ist diese spezielle Version, also hat sie den gleichen Code. In diesem Ordner wie hier drüben, wenn wir Version zwei verbessern und eine Version drei erstellen, werden sie den Code für Version drei hier hinzufügen und falls Sie auf den Code der Version zwei verweisen möchten, können Sie sich diesen speziellen Ordner ansehen. Als Nächstes werden wir unsere Umgebungsvariablen so einrichten, dass sie einen Google-API-Schlüssel enthalten. Dafür werden sie eine Punkt-ENV-Datei erstellen. Gehen Sie tatsächlich zu astodi.google.com und melden Sie sich über Ihr Gmail-Konto Dort erhalten Sie kostenlos einen Gemini-API-Schlüssel Es gibt also einige Bedingungen , die Sie überprüfen können, wenn Sie diesen Schlüssel verwenden, und im Grunde können Sie ihn sogar kostenlos zu Testzwecken mit bestimmten Untergrenzen verwenden und indem Sie ihnen erlauben Ihre Daten zu verwenden, während Und das macht es dann zur idealen Wahl für dieses Tutorial und das Experimentieren Ich bin auf atodigg.com, und wenn ich diese Seite besuche, ich automatisch aufgefordert, hier einen API-Schlüssel zu erhalten Und ansonsten glaube ich, dass es hier auch einen Button gibt , um die APK zu bekommen Also werde ich hier einfach auf API-Schlüssel abrufen klicken. Okay, es gibt also einen Code zum Testen der Gemini-API und hier gibt es eine Schaltfläche zum Erstellen eines APIKeys . Lassen Sie mich also einfach den API-Schlüssel von hier aus verwenden. Es wird jetzt den ApiKey für mich generieren, und Sie sollten Ihren ApiKey sicher verwenden und ihn nicht teilen oder in Code einbetten , den die Öffentlichkeit sehen kann Ich werde das nach dem Tutorial deaktivieren. Im Moment kopiere ich es einfach von hier und lasse es sichtbar sein. Gehen Sie dazu zu Ihrem ATA-Beispielordner, dem Ordner, den Sie von Github auschecken , und wechseln Sie in den Ordner der zweiten Version, dem sich im Grunde unser ADK-Agent Sagen Sie dann Touch Dot NV. Und das ist deine Umgebungsdatei. Fahren Sie nun mit dem VS-Code fort. Gehen Sie zum ADK-Agentenordner für Version zwei und suchen Sie dann nach Ihrer DOT-ANV-Datei Und hier müssen Sie einen Google-API-Schlüssel in diesem Format hinzufügen einen Google-API-Schlüssel in diesem Um die DOT-ANV-Datei zu Get Ignore hinzuzufügen. Was Sie tun können, ist, zum Terminal zurückzukehren und in den ADK-Agentenordner der zweiten Version zu gehen und in den ADK-Agentenordner der zweiten Version Sie können Touch Dot Get Ignore schreiben und dann Visual Studio-Code verwenden, um diese Datei zu öffnen, und dann einfach Punkt ENV hier eingeben und diese Datei speichern 74. 13.4 Ausführen des A2A Agent-Servers und -Clients: Schauen wir uns nun an, wie wir den Code ausführen können. Um den Code auszuführen, wechseln Sie in den ausgecheckten Ordner, der aus zwei , einem Schrägstrich 82 und einem Unterstrich besteht Das ist also der Ordner , den Sie aus Github ausgecheckt hätten Github ausgecheckt hätten Dann wechseln Sie zum Ordner der zweiten Version da der ADK-Agent im Grunde eine Version zwei der 80-Protokoll-Client und Server und Agenten Also wechseln wir zu diesem speziellen Ordner. Dann aktivierst du im Grunde eine virtuelle Umgebung, die ich hier bereits erstellt habe . Also schreiben wir den Quellpunkt NV shbinlas Activate. Und jetzt haben wir diese spezielle virtuelle Umgebung. Jetzt können wir einfach UV eingeben. Jetzt können wir einfach UV pip install dpi project dot Toml eingeben install dpi project dot Toml Dadurch werden alle in dieser Datei aufgeführten Pakete installiert . Schauen wir uns das an. Wir haben also Async-Klick-Click Google ADK, GogenAI und Um den Agenten jetzt auszuführen, können wir Python Three Agents Google Underscore ADK eingeben Three Agents Google Underscore ADK Dadurch wird der Agentenserver gestartet und der Task-Manager und der Agent für uns verknüpft Sie können sehen, dass der Server unter dieser bestimmten URL läuft dieser bestimmten URL läuft Nur um zu demonstrieren, wie der Client gestartet wird, können Sie Python three dm app dot cmd dot CMD eingeben Und damit wird im Grunde die App gestartet, die Befehlszeilenschnittstelle, die dann mit dem Client verbunden wird Wir werden die Agenten-URL hier angeben . Drücken wir die Eingabetaste. Jetzt heißt es, was Sie an den Agenten senden möchten und geben Sie Colin Que ein, um den Vorgang zu beenden Geben wir Colin Q ein und beenden das Programm vorerst. Dies soll nur zeigen, wie der Agent und der Befehl und die Benutzeroberfläche gestartet Um dies auszuführen, schauen Sie sich bitte zu Beginn die Demo an, in der Sie den Server in einem separaten Terminalfenster und den Client in einem separaten Terminalfenster starten den Client in einem separaten Terminalfenster und dann die Abfragen senden. 75. 13.5 Agentencode-Schritt-für-Schritt-durch: Damit wir verstehen, wie alles strukturiert ist, wollen wir uns den Code ansehen , der all dem zugrunde liegt Fangen wir also von der Agenten- und Serverseite an. Wir haben also einen Agentenordner, einen Unterordner für die auf Google ADK basierenden Agenten Und die Idee ist, dass wir diesen Bereich tatsächlich erweitern können , um so viele Agenten zu haben, wie wir wollen Jeder Agent hat ein Haupttreiberskript, das hier der Hauptpunkt P ist. Es hat die Agentenlogik und die Aufgabenbehandlungslogik im Task-Manager-Punkt PY. Lassen Sie uns zuerst die Punkt-V-Datei des Agenten durchgehen. Diese Datei definiert einen sehr einfachen AI-Agenten. In unserem Fall wird es im Grunde als Tell Time Agent bezeichnet und verwendet das ADK oder Agent Development Kit von Google und das Gemini-Modell, um mit der aktuellen Uhrzeit zu antworten Wir verwenden im Grunde diese beiden. Dies ist unser Agenten-Framework, und dies ist das große Sprachmodell , das wir verwenden, um diesen Agenten zu erstellen. Zunächst haben wir alle Eingaben, also ein wichtiger ist hier der also ein wichtiger ist hier Gemini basierende EI-Agent, der von Googles ADK bereitgestellt für den Sie die Ag-Bibliotheken von Google installieren und importieren müssen . Dann haben wir ADG-Dienste für Sitzung und Speicher , für die wir diese Bibliotheken hier importieren Dann haben wir einen Runner, also der Runner verbindet den Speicher und die Dateien der Agentensitzung zu einem kompletten System Und wieder wird es vom Agent Development Kit bereitgestellt. Dann haben wir die Gemini-kompatiblen Typen zum Formatieren Eingabe- und Ausgabenachrichten von Googles Gen AI Und schließlich haben wir die Umgebungsvariablen wie API-Schlüssel, die wir aus einer ENV-Punkt-Datei laden Um den Agenten zu definieren, definieren wir eine Klasse, die Tell Time Agent ist , weil unser Agent im Grunde nur die Uhrzeit angibt Wir definieren zunächst, welche Art von Inhalten dieser Agent unterstützt. Wir werden nur sagen, dass er die Eingabe und Ausgabe von Klartext unterstützt , indem wir hier unterstützte Inhaltstypen bereitstellen. Dann initialisieren wir den Tell Time Agent. Es erstellt den LLM-Agenten, der von Gemini betrieben wird, und richtet den Sitzungsverwaltungsspeicher und einen Runner zur Ausführung von Aufgaben ein Im Grunde genommen die Build-Agent-Funktion, die unten aufgeführt ist , und diese richtet den Agenten ein, und dann verwenden wir der Einfachheit halber im Grunde eine feste Benutzer-ID, nämlich Time Agent Jetzt definieren wir im Grunde den Runner , der im Grunde genommen den Agenten und seine Umgebung verwaltet. Also geben wir den Namen des Agenten an , der im Grunde während des Erstellungsprozesses eingerichtet wird. Dann stellen wir den Agenten selbst und dann bieten wir einige Dienste für Dateien an, um Konversationen zu verfolgen und vergangene Fehlnachrichten als Verlauf zu speichern. Dann definieren wir die Build-Agent-Funktion , die tatsächlich den LLM-Agenten zurückgibt , der hier ein kompletter ADK-Agent ist. Es erstellt also einen Gemini-Agenten mit Grundeinstellungen und gibt ihn zurück einen Gemini-Agenten mit Und das ist ein Agentenobjekt aus Googles ADK. Also geben wir einfach die Modellversion an, die wir verwenden möchten. Wir geben dem Agenten einen Namen. Wir stellen eine Beschreibung und geben dem Agenten Anweisungen , wie er eine Anfrage bearbeiten kann. Im Grunde ist dies also die Systemaufforderung, die wir bereitstellen. Dann haben wir die Aufruffunktion. Dies behandelt also im Grunde eine Benutzerabfrage und gibt eine Antwortzeichenfolge zurück Wir haben also die Abfrage, die eine Zeichenfolge ist, also was der Benutzer gesagt hat. Nehmen wir an, der Benutzer sagt, wie viel Uhr es ist und dann haben wir eine Sitzungs-ID, die im Grunde hilft, Nachrichten in einer Sitzung zu gruppieren, und wir geben dann eine Zeichenfolge zurück, die die Antwort des Agenten ist, normalerweise die aktuelle Uhrzeit. Wir verwenden also den Sitzungsdienst, bei dem wir versuchen eine bestehende Sitzung mit dieser Sitzungs-ID wiederzuverwenden, oder wir erstellen eine neue wenn sie noch nicht existiert. Jetzt definieren wir den Inhalt der Benutzernachricht in einem Format, das Gemini erwartet Es hat also im Grunde eine Rolle, nämlich Benutzer, und es hat die Teile, was im Grunde die Textabfrage ist Jetzt führen wir den Agenten mithilfe des Runners aus und sammeln das Antwortereignis. Wir stellen die Benutzer-ID, die Sitzungs-ID und den Inhalt der Nachricht bereit. Wir haben einen Fallback, um eine leere Zeichenfolge zurückzugeben, falls etwas schief gelaufen ist Wenn es keine Ereignisse gibt oder das letzte Ereignis keinen Inhalt enthält oder das Ereignis keinen Inhaltsteil enthält, geben wir eine leere Zeichenfolge zurück Dann extrahieren wir alle Textantworten und fügen sie zu einer Zeichenfolge zusammen. Für alle Teile des letzten Ereignisses nehmen wir also alle Teile heraus und fügen sie dann im Grunde mit einem neuen Zeilenzeichen zusammen, und genau das geben wir hier zurück. Wir haben auch eine Stream-Funktion, aber das ist etwas, das ich noch entwickle, also werde ich nicht näher darauf eingehen. Dieser spezielle Agent unterstützt derzeit kein Streaming. Das ist also unser ganzer einfacher Agent, im Grunde die Uhrzeit ablesen kann und eine Verbindung zum Geminia-Modell von Google herstellt. Er verwendet das Agent Development Kit von Google, Er verwendet das Agent Development Kit von Google um den Agenten zu erstellen 76. 13.6 Code-Schrittdurchführung für Agenten Taskmanager: Gehen wir zur nächsten Datei unter dem Google EdgFolder des Agenten , nämlich taskmanager dot py, und diese Datei ist im Grunde die Brücke zwischen dem Agenten und dem Server Sie empfängt die Aufgabe, ruft die Benutzeranfrage ab, ruft den Agenten auf und sendet die Antwort zurück. In Ordnung. Also nochmal, der Zweck dieser Datei ist es Ihren Gemini-Agenten, den Tell Time Agent, mit dem Task-Handling-System zu verbinden Tell Time Agent, mit dem Task-Handling-System zu Es erbt also vom In-Memory-Taskmanager. Dies ist im Grunde eine Basisklasse, von der sie erbt, und sie erhält im Grunde eine Aufgabe vom Benutzer Sie extrahiert die Frage. Also zum Beispiel die Abfrage, wie viel Uhr ist es? Dann wird der Agent aufgefordert, zu antworten, was wir uns bereits angesehen haben was wir uns bereits angesehen haben. Der Agent verwendet die dort definierten Agentenfunktionen die dort definierten und speichert dann die Antwort des Agenten und gibt sie zurück. Es gibt also grundlegende Importe , die hier sind, und es gibt eine Protokollierung , die wir hier vornehmen. Und danach haben wir im Grunde den Task-Manager. Um einen Gesamtüberblick über diesen Task-Manager erhalten: Sie können tatsächlich alle Codeblöcke zusammenklappen, und es gibt im Grunde diese drei einfachen Funktionen, die darin enthalten sind. Die Initialisierung des Task-Managers, die Get-User-Abfrage, die im Grunde die Benutzerabfrage aus der eingehenden Aufgabe extrahiert , und dann die Hauptlogik zur Bearbeitung und Fertigstellung einer Aufgabe, die sich auf Centask befindet Task-Manager sendet die Aufgabe grundsätzlich an den Agenten und erhält dann die Antwort Es erbt also im Grunde die gesamte Logik vom In-Memory-Task-Manager , der Basisklasse Ich überschreibe den Teil, in dem wir die neue Aufgabe bearbeiten , die sich auf der Cen-Aufgabe befindet Das ist es also, was es überschreibt und es dann für diesen bestimmten Agenten bereitstellt, und dann verwendet es den Gemini-Agenten, um eine Antwort zu generieren Schauen wir uns zunächst die Initialisierungslogik an. Ich speichere den auf Gemini basierenden Agenten nur als Eigenschaft, abgesehen vom Aufrufen des Superklassenkonstruktors So verbinden Sie den Agenten im Grunde mit dem Task-Manager Dann haben wir die nächste Funktion, die Benutzeranfragen abruft, sodass sie die Texteingabe des Benutzers aus dem Anforderungsobjekt abruft. Wenn der Benutzer beispielsweise sagt, wie spät es ist, ziehen wir diese Zeichenfolge heraus. Ich erhalte im Grunde ein Anforderungsobjekt, bei dem es sich um ein Objekt zum Senden einer Aufgabenanfrage handelt, und dann gibt es den tatsächlichen Text zurück , nach dem der Benutzer gefragt hat. Es durchläuft im Grunde die Anforderungsparameter, und dann überprüft es für den Parameter im Grunde die Nachricht, und es nimmt den ersten Teil und dann den Text dafür Dann haben wir die Aufgabenfunktion on sent. Dies ist die Hauptlogik für die Bearbeitung und Erledigung einer Aufgabe , und genau das tut der Task-Manager . Es macht also Folgendes. Es speichert die Aufgabe im Speicher oder aktualisiert sie. Es bittet den Gemini-Agenten um eine Antwort. Dann formatiert es die Antwort als Nachricht, speichert die vom Agenten bereitgestellten Informationen im Aufgabenverlauf und sendet die aktualisierte Aufgabe an den Anrufer zurück Also wird es die Aufgabe mit dem Basisklassen-Helper speichern. Ich werde mit der Abfragefunktion „Benutzer abrufen“ das bekommen, wonach der Benutzer gefragt hat. Dann fordert es den Gemini-Agenten auf, zu antworten. Es verwendet die Aufruffunktion für den Agenten, den wir uns angesehen haben, und es stellt die Abfrage bereit und stellt die Sitzungs-ID Aus dem Ergebnistext wird im Grunde eine Agentennachricht mit dem Rollenagenten und dem Textteil erstellt , der hier der Ergebnistext ist. Schließlich aktualisiert es den Status der Aufgabe und fügt die Nachricht dem Verlauf hinzu Anschließend gibt es eine strukturierte Antwort zurück an A an einen Client. Es führt also im Grunde das Objekt „ Task Response senden “ mit der Anforderungs-ID und dem Ergebnis aus. Das ist also im Grunde Ihr Task-Manager, und auch hier verbindet er Ihren Agenten im Grunde mit dem Task-Handling-System und steuert im Grunde den Agenten. 77. 13.7 Code-Walkthrough für Agenten main.py: Jetzt gehen wir zur dritten wichtigen Datei. Diese Datei ist die Hauptdatei von Dot Py, und dies ist im Grunde das Hauptskript, das wir auf dem Terminal ausführen werden , um unseren Telet-Agent-Server zu starten Also werden wir uns den Servercode ansehen. Aber letztendlich ist dies ein Skript, das den Agenten und den Server startet und einrichtet und ihn im Grunde so einrichtet, dass er an einem bestimmten Port lauscht. Es deklariert die Fähigkeiten und Fertigkeiten des Agenten. Dann richtet es das A auf einem Server mit einem Task-Manager und einem Agenten Wir haben uns nur den Task-Manager und den Agenten angesehen , wir werden uns als Nächstes die auf einem Server ansehen. Dann fängt es an, auf einem bestimmten Host und Port zu lauschen, und dieses Skript kann im Grunde direkt von der Befehlszeile aus ausgeführt werden, und das ist es, was wir tun werden , um unseren Server laufen zu lassen. Wir importieren unseren A2-Server. Wir importieren alle Modelle, die wir möchten, wir geben unseren Agenten und unseren Task-Manager ein, und im Grunde wird das alles miteinander verbinden. Gehen wir hier zur Hauptfunktion. Im Grunde definiert sie hier die Fähigkeiten der Agenten und wir werden sagen, dass dieser Agent kein Streaming durchführen kann. Streaming wird nicht unterstützt. Dann definiert es die Fähigkeiten, die dieser Agent anbietet. Es ist also im Grunde eine Skill-ID, die im Grunde sagt , dass er die Uhrzeit ablesen kann , und es gibt einen benutzerfreundlichen Namen und eine Beschreibung. Es gibt einige häufig verwendete Tags und dann gibt es einige Beispielabfragen. Das ist im Grunde das, was wir ein Agenten-Skill-Objekt halten, und das ist der Skill. Dann wird im Grunde eine Agentenkarte erstellt , die die Identität und die Metadaten dieses Agenten beschreibt . Wenn wir das ausführen, steht uns im Grunde die Agenten-Karte zur Verfügung, die dann den Namen, die Beschreibung, die URL, die Version, die Eingabe- und Ausgabemodi, die dieser Agent unterstützt, die Fähigkeiten und die Fähigkeiten enthält Version, die Eingabe- und Ausgabemodi, die dieser Agent unterstützt, . Dies wird von Kunden verwendet, um den Agenten zu finden und zu verstehen, über welche Fähigkeiten er verfügt. Dann starten wir den AS-Server. Wenn wir also diese spezielle Datei ausführen, definiert sie im Grunde einen Server mit einem Host, einem Port, einer Agentenkarte und einem Task-Manager. Der Task-Manager selbst übernimmt den Agenten hier drüben. Jetzt sehen Sie also, dass Sie den Agenten im Grunde genommen bereitgestellt haben . Dann haben Sie einen Task-Manager bereitgestellt , der im Grunde diesen Agenten verwendet, und Sie haben die Agentenkarte bereitgestellt, und all das wird dann dem Server zur Verfügung gestellt , um ein Serverobjekt zu erstellen , das wir dann starten. Wir haben damit angefangen, Server Punkt Start zu sagen, und damit läuft im Grunde der Server. Das ist also unsere Hauptdatei mit Punkt P, und wenn wir das ausführen, alles auf der Serverseite, einschließlich des Agenten und des Task-Managers, gestartet 78. 13.8 Clientcode-Walkthrough – Teil 1: Im Client-Ordner befindet sich die Client-PY-Datei mit Punkt. Dies ist der asynchrone SDP-Client, der eine Verbindung zu unserem Server herstellt Also verpackt er unsere Nutzdaten in das erwartete JCN-RPC-Format und So einfach ist das also. Diese Datei definiert also einen verwendbaren Async-Python-Client für die Interaktion mit einem A zu einem Server Es unterstützt das Senden der Aufgabe und das Empfangen von Antworten, Abrufen des Aufgabenstatus oder des Aufgabenverlaufs sowie Streaming und Abbrechen werden in dieser vereinfachten Version nicht unterstützt unterstützt In dieser speziellen Version werden also grundsätzlich das Senden von Aufgaben und das Empfangen von Antworten Also hier sind die grundlegenden Importe. Und dann haben wir den Import aller Modelle, die wir wollen. Also wollen wir das Anforderungsmodell und das JCN-RPC-Modell hier haben, zusammen mit den Aufgaben- und Agentenmodellen hier drüben Wir haben also das Modell „ Aufgabenanfrage senden , das wir in dieser speziellen Implementierung verwenden werden Wir haben auch das JSON-RPC-Anforderungsmodell. Wir haben die Aufgabe selbst, wir die Aufgabe erstellen und die Aufgabe Sendeparameter für die Parameter verwenden werden , und wir haben das Agentenkartenmodell für die Agentenkarte Es gibt einige benutzerdefinierte Fehlerklassen, die wir hier haben. Und das sind unsere wichtigsten acht für einen Kunden. Lassen Sie uns also alle Codeblöcke hier zusammenklappen. Und jetzt können Sie sehen, dass es sich um einen ziemlich einfachen Client handelt. Es gibt also einen Konstruktor. Es gibt eine Möglichkeit , eine Aufgabe zu senden und eine Aufgabe abzurufen Wir verwenden das hier gerade nicht, und es gibt eine Option, um eine Anfrage zu senden. Das heißt , wenn Sie eine Aufgabe senden, verwenden Sie die Funktion Anfrage senden, um diese Anfrage tatsächlich an den Server zu senden. Schauen wir uns also zuerst den Konstruktor an. 79. 13.9 Clientcode-Walkthrough – Teil 2 – Manuelle Agentenerkennung: Kursleiter nimmt im Grunde nur entweder die Agentenkarte oder eine URL Sie müssen dem Kunden also mitteilen, welchem Server Sie interagieren möchten. Das nennen wir hier manuelle Erkennung. Wir geben also manuell den Server an, mit dem der Client interagieren soll. Es gibt auch verschiedene Erkennungsmethoden , die wir uns ansehen können und die komplizierter sind. Server registrieren sich bei komplizierter sind. Server einer gemeinsamen Registrierung und der Client greift dann tatsächlich auf diese Registrierung zu, um zu sehen, welche Server sich dort befinden In diesem ersten Schritt verwenden wir jedoch die manuelle Erkennung. Also werden wir dafür tatsächlich eine URL bereitstellen. Und da die Agentenkarte nicht bereitgestellt wird , wenn wir den Client ausführen, geben wir einfach die URL an und weisen diese URL dem Client zu. Und das ist alles, was der Client in seinem Konstruktor wissen muss 80. 13.10 Clientcode-Walkthrough – Teil 3: Wir haben Aufgabe senden , bei der im Grunde eine neue Aufgabe an den Agenten gesendet wird Es wird also ein Anforderungsobjekt erstellt, bei dem es sich um ein Objekt zum Senden einer Aufgabenanfrage mit einer eindeutigen ID und Parametern handelt, denen es sich um Sendeparameter für Aufgaben handelt Die Sendeparameter dieser Aufgabe werden also im Grunde eine Nutzlast haben. Und das wird dazu führen , dass die Nutzlast im Grunde genommen in ein geeignetes Modell umgewandelt wird , das für die Aufgabenanfrage senden benötigt wird Wenn Sie sich also die Sendeparameter der Aufgabe ansehen, hat sie eine ID. Es hat eine Sitzungs-ID. Es hat eine Nachricht. Dann hat es eine Länge des Verlaufs und einige Metadaten, die wir im Grunde nicht verwenden. Die Payload selbst liefert die ID-Sitzungs-ID-Nachricht, Verlauf, die Länge und die Metadaten, einige Metadaten, die wir im Grunde nicht verwenden. Die Payload selbst liefert die ID-Sitzungs-ID-Nachricht, den Verlauf, die Länge und die Metadaten, und das ist die Nutzlast, die sie von unserer App empfangen wird Die Befehlszeilen-App, die wir im Grunde verwenden werden, sendet diese Nutzdaten also an die Funktion Aufgabe senden Sobald Sie dieses Anforderungsobjekt erstellt haben, verwenden wir grundsätzlich die unten stehende Funktion Anfrage senden und senden diese Anfrage an den Agenten Wir warten auf eine Antwort und geben dann die Aufgabe mit dem Ergebnis der Antwort zurück . Also auch hier extrahieren wir nur das Ergebnisfeld aus der Antwort und erstellen aus diesem Antwortergebnis ein Aufgabenobjekt . Und das geben wir zurück. Sie werden die Funktion „Aufgabe abrufen“ hier nicht verwenden, wir werden in einem zukünftigen Video darauf zurückkommen. Und schließlich haben wir die Funktion zum Senden von Anfragen. Diese Funktion ist also im Grunde ein Helfer beim Senden einer JCN-RPC-Anfrage Wir posten die Anfrage im Grunde an die URL, im Grunde die URL des Agenten ist Wir nehmen das Anforderungsmodell und konvertieren es in Jason und bieten einen Timeout Und dann bekommen wir im Grunde eine Antwort. Wir überprüfen, ob der Antwortstatuscode Fehler vier XX oder fünf XX lautet, und geben dann die vorherige Antwort im Grunde als Wörterbuch zurück. Dann behandeln wir einige grundlegende Ausnahmen , die wir oben im Code erstellt haben. Das ist also unsere Funktion zum Senden von Anfragen, die die Anfrage tatsächlich senden wird, und unsere Funktion zum Senden von Aufgaben verwendet diese Funktion, um die Anfrage dann tatsächlich zu senden. Das ist also unser Client, und dann haben wir endlich die Befehlszeilenschnittstelle. 81. 13.11 Anwendungscode-Walkthrough: Erstellen Sie einen App-Ordner, in dem Sie tatsächlich mehrere Apps haben können , die denselben Client-Server, Agenten usw. verwenden . Und was wir hier tun werden , ist, dass wir zuerst eine befehlszeilenbasierte App erstellen, die sich in Cmd Punkt PY befindet Diese Datei ist also eine Befehlszeilenschnittstelle, über die Benutzer mit dem Tell Time Agent interagieren können mit dem Tell Time Agent interagieren , der auf einem 80-Server läuft Sie sendet einfache Textnachrichten an den Agenten, wie spät es ist, und er wartet auf eine Antwort und zeigt sie im Terminal an Es wird also tatsächlich die Acht an den Client verwenden und die Aufgabe im Grunde über diesen 80-Client senden Wir haben einige grundlegende Importe gefolgt vom Import des 80-Clients und importieren im Grunde das Aufgabenmodell, damit wir die Antworten des Agenten bearbeiten und einfügen können die Antworten des Agenten bearbeiten und einfügen Wir verwenden den Befehl click dot, um die unten stehende Funktion in einen Befehlszeilenbefehl umzuwandeln Im Grunde können wir einen Agentenparameter mit der URL angeben , und dies ist die Basis-URL des A-Two-Agent-Servers. Wenn wir diese Befehlszeilen-App verwenden und ausführen, stellen wir im Grunde den Agenten zur Verfügung , den der Client benötigt um eine Verbindung zu dieser Befehlszeilen-App hilft uns dabei. Es gibt auch einige andere Parameter, die wir für die Sitzung und den Verlauf der zukünftigen Verwendung definiert haben für die Sitzung und den Verlauf der zukünftigen Verwendung definiert . Diese werden wir hier nicht verwenden, aber wir werden in einem zukünftigen Video darauf eingehen. Dies ist die Hauptdefinition für die Befehlszeilenschnittstelle, um Benutzernachrichten an einen A-2-Agenten zu senden und die Antwort anzuzeigen. Es nimmt also im Grunde den Agenten in Anspruch. welchem Agenten wir uns also im verbinden, nimmt im Grunde die Agenten-URL auf, und es werden auch eine Sitzung und ein Verlauf benötigt, die wir derzeit nicht verwenden, und wir werden in einem zukünftigen Video darauf zurückkommen. Zuerst initialisieren wir den Client, indem wir den vollständigen Post-Endpunkt für das Senden der Aufgabe Ein Spielzeug-Client nimmt also einfach die URL auf. Wir haben uns bereits die 80-Client-Klasse in der Client-PY-Datei angesehen und sie weiß jetzt , mit welchem Agenten sie sich verbinden muss. Dann geben wir im Grunde eine Sitzungs-ID an, also definieren oder erstellen wir eine neue Sitzungs-ID, falls sie nicht angegeben wird. Dann fordern wir den Benutzer dazu auf. Wir starten die Hauptschleife und fordern den Benutzer zur Eingabe auf. Also, was möchten Sie an den Agenten senden und wir bieten eine Option zum Beenden an. Wenn der Benutzer im Grunde darum bittet, den Vorgang zu beenden, unterbrechen wir diese spezielle Schleife und beenden den Vorgang. Andernfalls erstellen wir die Nutzlast. Dies ist eine Payload , die wir in der anderen Datei von Client Dot PI gesehen haben der anderen Datei von Client Dot Und wir konstruieren die Nutzlast im erwarteten Format für eine Aufgabe Es hat also eine ID. Es hat eine Sitzungs-ID und besteht aus Nachrichten, die wir bereits gesehen haben, die für jede Nachricht eine Rolle spielen und jede Nachricht besteht aus Teilen. Hier gibt es nur einen Teil, dessen Typ Text ist, und der Text selbst ist die Benutzeraufforderung. Das ist also das komplette Format, das wir erwarten. Dann verwenden wir den Client, um die Aufgabe an den Agenten zu senden. Im Grunde verwenden wir hier also die Funktion „Anfrage senden“ des Clients , die letztendlich die Funktion „Anfrage senden“ verwendet Funktion „Anfrage senden um die Anfrage an den 80-Server zu senden. Es sendet also im Grunde die Aufgabe an den Agenten und erhält eine strukturierte Aufgabenantwort. Und wenn der Agent geantwortet hat, überprüfen wir im Grunde den Parameter für den Aufgabenverlauf, und dann nehmen wir im Grunde die letzte Nachricht und drucken dann den Text aus dem ersten Teil der Nachricht aus, was im Grunde die Textantwort des Agenten ist. Vielleicht möchten wir den Konversationsverlauf anzeigen , aber auch hier verwenden wir ihn momentan nicht, und dann finden wir hier einige Ausnahmen. Dies ist der Haupteinstiegspunkt für die Ausführung der Befehlszeilenschnittstelle, und damit ist unser Code für die Befehlszeilenschnittstelle im Grunde vervollständigt. 82. 13.12 Kurzer Überblick über die Code-Architektur: wieder zu unserer 80-Projektstruktur zurückkehren, können Sie feststellen, dass Sie einen Agenten und einen Task-Manager haben einen Agenten und einen Task-Manager , die im Grunde bei der Ausführung dieses Agenten helfen Sie haben einen Server, der die Aufgabe an den Task-Manager delegiert und sich selbst dem Client zugänglich Dann haben Sie den Client, sich im Grunde mit dem Server verbindet , um Aufgaben zu senden, und dann haben Sie hier eine App, eine Befehlszeilen-App, die im Grunde den Benutzer mit dem Client die Anfrage vom Benutzer empfängt und sie dann über den Client an den Server sendet über den Client an den Server sie vom Agenten verarbeitet wird Um all dies zu tun, haben Sie auch einige Modelle, die in der Agent-PY-Datei, JcnrpcflerQuest-PY-Datei und der Task-PY-Datei enthalten sind. Schauen wir uns nun schnell all diese Modelle an. 83. 13.13 Modellcode-Walkthrough: Gehen Sie tatsächlich jede dieser Dateien durch. Ich habe zu jedem Modell hier eine Menge Kommentare hinzugefügt zu jedem Modell hier eine Menge Kommentare , sodass es im Grunde selbsterklärend ist und Sie jeden der Parameter verstehen können Ich werde hier nur als Referenz eines dieser Modelle durchgehen , welches das wichtigste ist, nämlich das der Agentenkarte Wir haben dieses Modell bereits an mehreren Stellen im Code verwendet , und im Grunde hat es einen Namen, eine Beschreibung, URL-Version, Funktionen und Fähigkeiten. Dies stellt im Grunde die wichtigsten Metadaten zu einem Agenten bereit, und diese Informationen können während der Erkennung mit dem Verzeichnisdienst oder anderen Agenten geteilt werden . Und es beschreibt im Grunde, was der Agent tut, wo er zu erreichen ist und welche Funktionen er unterstützt. Dann haben Sie die JSON-RPC-Modelldatei, und diese enthält all diese Modelle. Sie haben also ein Modell für alle Nachrichten, ein Modell für einen Anruf von einem Agenten an einen anderen, die auf eine Anfrage antworten, entweder ein Ergebnis oder einen Fehler, bei dem es sich um eine RPC-Antwort handelt, und dann haben Sie die Struktur einer Fehlerantwort und einen vordefinierten Standardfehler für unerwartete Sie finden hier also all diese Modelle ausführlich kommentiert und Sie können sich all diese Modelle ansehen Endlich haben Sie die Punkt-P-Datei mit allen Modellen, die sich auf die von uns gestellten Anfragen beziehen. Wir haben also die Aufgabenanfrage Senden, die wir tatsächlich verwenden. Wir haben das E auf eine Anfrage und wir haben die Antwort auf die Aufgabe Senden. Die Aufgabenanfrage senden hat also im Grunde nur die Methode Task CID, die hier definiert ist, und dann haben wir die Sendeparameter für die Aufgabe Dann haben wir das A für eine Anfrage, was im Grunde eine diskriminierte Vereinigung der unterstützten Anforderungstypen Es ermöglicht grundsätzlich die automatische Übergabe von Anforderungstypen auf der Grundlage des Methodenfeldes Wir verwenden vorerst nur die Option Aufgabenanfrage senden und wir werden hier im Laufe der Zeit weitere Anfragen hinzufügen. Dann haben wir die Antwort auf Aufgabe senden, und es ist im Grunde ein Antwortmodell für eine erfolgreiche Aufgabe mit Schrägstrich. Die Anfrage hat das Ergebnis, nämlich die vom Agenten zurückgegebene Aufgabe Jetzt haben wir fast alle Dateien durchgesehen und es gibt noch ein paar weitere Dateien , die Sie tatsächlich durchgehen können Zum Beispiel die Task-PY-Datei, auch hier, sie ist ziemlich ausführlich kommentiert und es nur Basismodelle, die verwendet werden, um alle Aufgaben zu erledigen und alle Parameter zu senden. Die anderen Dateien, die Sie sich vielleicht ansehen möchten, sind die Task-Manager-Punktdatei, und das definiert im Grunde, wie Aufgaben in A an ein Protokoll verwaltet werden. Es gibt eine abstrakte Basisklasse namens Task-Manager und einen einfachen Taskmanager im Speicher, der die Aufgaben vorübergehend im Speicher hält. Dies wird verwendet, um dann auf dem Agententaskmanager aufzubauen , wir in diesem speziellen Ordner haben. Ich denke, das deckt alle Dateien ab, die wir wollen. 84. ABSCHNITT 14 START – A2A mit mehreren Agenten: Heute werden wir etwas sehr Aufregendes tun, nämlich mit der Einrichtung und Entwicklung von Multiagent A zwei beginnen Einrichtung und Entwicklung von Multiagent A zwei Und bevor ich das mache, wird in diesem Video zunächst die Architektur erklärt, der ich folgen werde, und dann werden wir auf unserem A-2a-Client und der Architektur aufbauen unserem A-2a-Client , die wir bereits erstellt haben. Um es zu einem Multiagentensystem weiterzuentwickeln, bei dem mehrere Agenten miteinander sprechen können . In Ordnung. Das ist also unsere gesamte Architektur, die wir verwenden werden, um unser Multiagenten-A-Two-Setup zu erstellen. Es wird also zuerst aus einem Frontend bestehen. Hier wird der Benutzer also mit Ihrem Setup-System oder Ihrer App interagieren. Das wird also aus einem App-Frontend bestehen, und das App-Frontend wird im Grunde genommen eine Acht pro Client haben. Dass es hosten wird, und dieses A an einen Client wird unser Einstiegspunkt in unser Acht-Tage-Backend und all die anderen 80 Remote- oder lokalen Agenten , die wir im Grunde für das Setup verwenden werden Als Beispiel dafür könnte dieses App-Frontend einfach wie eine Befehlszeile aussehen Das haben wir also in unserem letzten Video gemacht, in dem wir eine Befehlszeilenschnittstelle als App für unseren A two a-Client erstellt eine Befehlszeilenschnittstelle haben, und wir könnten dies ausführen, indem wir den Python-Drei-Befehl wie folgt auf dem Terminal eingeben . Und dann bekamen wir eine Frage, was Sie an den Agenten senden möchten, und eine Option zum Beenden. Im Grunde ist dies die App, die eine Schnittstelle zum Client und dann weiter zu den Servern herstellt. Dies ist ein Beispiel für das App-Frontend. Sie können auch eine browserbasierte Web-App oder mobile App oder etwas anderes mit einer Benutzeroberfläche haben. Das App-Frontend hostet also im Grunde eine sogenannte Acht für einen Kunden. Und das macht im Grunde Ihr gesamtes Frontend aus. Für einen Kunden haben wir das bereits in unserem letzten Video codiert, und ich werde es Ihnen nur schnell zeigen. Wenn Sie sich erinnern, haben wir eine zweite Version unseres ATA-Agentensystems, das ist ADK-Agent der zweiten Version und hat einen Client mit Client-Punkt, und dieser Client kann Ihnen im Grunde helfen, eine Aufgabe an den Server zu senden und die Antwort zurückzubekommen Das ist also unser 80-Client und das hilft uns im Grunde, eine Verbindung zu den 80 Servern Ordnung. Jetzt haben wir also den 80-Client und die App, die ihn im Grunde hostet, und der Benutzer kann dann mit dieser App interagieren und eine Abfrage eingeben, die der 80-Client verarbeiten soll. Wie stellt der 80-Client dann eine Verbindung zu Ihrem 80-Server her? Das nennen wir das Acht-Wege-Backend. Das ist es, was die Anfrage vom Client über das 80-Protokoll empfängt die Anfrage vom Client über das 80-Protokoll Das bedeutet, dass der Server im Grunde alle Endpunkte verfügbar macht, die das Acht-Wege-Protokoll benötigt , also im Grunde den bekannten Agent-George-Jason-Endpunkt und den Send-Task-Endpunkt sowie andere Arten von Endpunkten, andere Arten von Endpunkten die 80 im Grunde genommen bietet Zum Beispiel verwenden wir hier einfach den Endpunkt Aufgabe senden, wo der 80-Client eine Aufgabe an diesen 80-Server sendet Für diese spezielle App haben wir nun einen Host-Agenten. Dies bedeutet, dass dieser A-to-Client eine Verbindung zu diesem Host-Agenten und zu keinem anderen Agenten herstellen wird. Im Grunde können wir diesen Agenten einfach als unseren Host-Agent fest programmieren , der im Grunde alle Interaktionen von diesem A zu einem Client verwaltet und sie dann nach Bedarf an andere Agenten weiterleitet . Der Aoi-Client weiß also, dass er im Grunde mit einem Host-Agenten sprechen wird Jetzt macht dieser Host-Agent einen ATA-Server verfügbar, der die Anfrage vom Ao-Client empfängt und sie dann verarbeitet Lassen Sie uns nun diesen Host-Agenten im Detail verstehen. Dieser Host-Agent wird im Grunde einen ATX-Server verfügbar machen, und dieser wird eine eingehende Anfrage von einem ATX-Client empfangen eine eingehende Anfrage von einem ATX-Client Dieser spezielle Host-Agent hostet im Grunde auch einen sogenannten Orchestrator weil dieser die Aufgabe für uns orchestriert und mit mehreren anderen Agenten kommuniziert, um eine Lösung für diese Aufgabe für unseren Client und den Benutzer bereitzustellen diese Aufgabe für unseren Client Sobald der Host-Agent eine Aufgabe erhält, übergibt er sie an den Orchestrator-Agenten , der im Grunde ein Teil des Host-Agenten ist Wir sagen dem Orchestrator-Agenten , dass Sie über zwei Tools verfügen Eines ist das Tool zum Auflisten von Agenten und eines ist das Tool zum Delegieren von Aufgaben Jetzt hilft das List Agent Tool dem Orchestrator dabei, alle Agenten aufzulisten , die in einer Agentenregistrierung verfügbar sind Wir erstellen also im Grunde eine Agentenregistrierung. Alle Agenten auf der Welt, mit denen wir alle Aufgaben lösen wollen , die wir bekommen könnten, listen wir alle in diesem Agentenregister auf. Wenn der Orchestrator also eine Aufgabe erhält, weiß er, dass er im Grunde ein Tool ausführen kann , das ihm hilft, alle Agenten zu Also führt er dieses Tool aus, das im Grunde das List-Agent-Tool genannt wird, und es ruft die Liste der Agenten mit gesamten Beschreibung und den Fähigkeiten ab, über die jeder der Agenten verfügt Dann wird ihm ein anderes Tool zur Verfügung gestellt, das als Delegate Task Tool bezeichnet wird Und dieses Tool, so der Orchestrator-Agent, kann Ihnen helfen, eine Aufgabe an einen anderen Agenten zu delegieren und eine Antwort zu erhalten Was der Orchestrator-Agent jetzt weiß, ist, dass er über eine Liste dieser verfügbaren Agenten verfügt und ein Tool ausführen kann , um eine Aufgabe zu delegieren und ein Antwortpaket zu erhalten Ordnung. Also, was passiert , wenn du eine Aufgabe bekommst? Was passiert, ist, dass der Orchestrator eine Liste der Agenten erhält, über die er verfügt, und entscheidet dann anhand der dort genannten Fähigkeiten und Fertigkeiten des Agenten , zusammen mit der Beschreibung und dem Namen, welcher anhand der dort genannten Fähigkeiten und Fertigkeiten des Agenten Agent verwendet werden , zusammen mit der Beschreibung und dem soll, und dann für diesen bestimmten Agenten heikle Aufgabe Das Tool für heikle Aufgaben, über das der Orchestrator verfügt, verwendet im Grunde genommen einen sogenannten Agenten-Connector Der Agent-Connector ist im Grunde ein Connector pro Remote-Agent, zu dem Sie eine Verbindung herstellen möchten, und er stellt im Grunde eine Acht zu einem Client auf Ihrem eigenen Backend her, dann im Grunde über das 80-Protokoll eine Verbindung zum Remote-Agenten herstellt über das 80-Protokoll eine Verbindung zum Remote-Agenten Verwendet die Funktion zum Senden von Aufgaben, um die Aufgabe an diesen Remote-Agenten zu senden und die Antwort zurückzuerhalten. Ich kann dieses Tool beliebig oft aufrufen und all diese Remote-Agenten wieder über das 8-Wege-Protokoll verwenden . Im Grunde ist das Ihr gesamtes Backend, das Sie erstellen könnten, und das sind externe Agenten oder Agenten von Drittanbietern, die Sie möglicherweise verwenden, oder einige lokale Agenten , die Sie möglicherweise selbst erstellt haben die Sie für Ihre eigene 8-Wege-Implementierung verwenden können Ihre eigene 8-Wege-Implementierung Der unterhaltsame Teil ist, dass diese Remote-Agenten selbst über Orchestratoren verfügen können , die die gleiche Weise funktionieren können Wenn Sie also eine Aufgabe von Ihrem Host-Agenten an den Agenten 1 gesendet haben. Agent 1 entscheidet dann möglicherweise, dass er zwei oder drei weitere Agenten benötigt, um diese Aufgabe tatsächlich zu erfüllen , und verwendet dann seinen eigenen Orchestrator, um alle in seiner eigenen Registrierung verfügbaren Agenten aufzulisten , und sendet dann die Aufgabe im Grunde an diese Agenten Über die Funktion zum Delegieren von Aufgaben. Dies ist Ihre gesamte Systemarchitektur für Ihr 80-Multi-Agent-Setup Um es kurz zusammenzufassen: Sie haben ein Frontend mit acht Frontends, bei dem der Benutzer eine Anfrage über ein App-Frontend an einen 80-Client sendet Es stellt über das 80-Protokoll eine Verbindung zu einem Host-Agenten her , der im Grunde ein Orchestrator-Agent ist Der Orchestrator-Agent macht seinen Server für die Interaktion mit diesem 80-Client Der Orchestrator überprüft dann grundsätzlich, über welche Agenten er verfügt, um die vom At-Client eingegangene Anfrage zu erfüllen vom At-Client eingegangene Dann verwendet er im Grunde das Delegate Task Tool, um sich über Funktionsaufrufe so oft wie nötig mit einem der Agenten zu verbinden Agenten so oft wie nötig mit einem der . Jeder der Agenten-Connectors ist im Grunde ein ATA-Client, Jeder der Agenten-Connectors ist der dann das 80-Protokoll verwendet, um eine Verbindung zu diesem bestimmten Remote-Agenten herzustellen, wie in der Registrierung erwähnt, und die Aufgabe zu erledigen und übergibt das Ergebnis zurück an den Server-Agenten Diese Remote-Agenten können außerdem ihre eigenen Orchestratoren haben , die ähnliche Weise eine Verbindung zu anderen Agenten herstellen, obwohl es klar ist und ich diese Frage einige Male von mehreren Personen erhalten habe diese Frage einige Male von mehreren Personen erhalten , dass diese Remote-Agenten auch über diese Koordinationsrechner miteinander kommunizieren können miteinander kommunizieren über diese Koordinationsrechner Wenn also der Remote-Agent I weiß, dass es einen Remote-Agenten N gibt , der ihm helfen kann , kann er die Registrierung hier über diesen Orchestrator überprüfen die Registrierung hier über diesen Orchestrator um diesen Remote-Agenten N herauszufinden und dann auch diesen Remote-Agenten N aufrufen. 85. ABSCHNITT 15 START - Verbinden von 3 Agenten mit A2A: Jeder. Lassen Sie uns also etwas wirklich Lustiges tun, nämlich drei verschiedene Agenten, die hier in den roten, grünen und blauen Terminalfenstern angezeigt werden, zusammen mit einem Zwei-A - und einem A-Zwei-A-Client , der hier im schwarzen Fenster auf der Rückseite angezeigt wird, miteinander verbinden die hier in den roten, grünen und blauen Terminalfenstern angezeigt werden , zusammen mit einem Zwei-A - und einem A-Zwei-A-Client , . Bevor ich anfange und mit dem Code beginne, möchte ich Ihnen eine coole Demo zeigen, wie das funktioniert. Auf dem blauen Bildschirm werden wir also einen Agenten starten, bei dem es sich um einen einfachen Agenten handelt, der als Tell Time Agent bezeichnet wird. Die Aufgabe dieses Agenten besteht also nur darin, uns die Uhrzeit mitzuteilen, und dieser Agent wurde mithilfe des Gemini LLM unter Verwendung von Googles ADK erstellt des Gemini LLM unter Verwendung von Googles ADK Es ist also ein Gemini Google ADK-Agent. Also habe ich diesen Agenten laufen lassen und der ATS-Server für diesen Agenten ist Local Host 10.000 Gehen wir jetzt zum Green Agent. Das wird also ein Begrüßungsagent sein, und der Zweck dieses Agenten besteht darin, anhand der aktuellen Uhrzeit eine poetische Begrüßung für den Benutzer zu erstellen anhand der aktuellen Uhrzeit eine poetische Begrüßung für den Benutzer In Ordnung, also lass uns diesen Agenten jetzt starten. Und jetzt läuft dieser Agent auf einem AS-Server, der lokale Host 10.001 ist Jetzt werde ich meinen dritten Agenten starten. Das ist also ein Orchestrator oder ein Host-Agent. Dabei werden im Grunde Agenten-Konnektoren verwendet und eine Verbindung zum Tellt-Agenten und zum Begrüßungsagenten Jetzt ist es also im Grunde genommen mit diesen beiden Agenten über ihre jeweiligen Codes verbunden diesen beiden Agenten über ihre jeweiligen Codes und es selbst stellt sich selbst auf einem AA-Server zur Verfügung , der der lokale Host 10.002 ist Jetzt laufen auf diesen drei Agenten der rote Orchestrator-Agent, der grüne Begrüßungs-Agent und der blaue Tell Lassen Sie uns jetzt unseren 80-Client starten. In Ordnung, das ist also unser A-Zwei-A-Client. Also ist es eine Kommandozeilen-App , die mit einem Client verbunden ist und dann sagt sie: Was möchten Sie an den Agenten senden? Wir haben angegeben, dass wir eine Verbindung zum Orchestrator-Agenten herstellen möchten , der sich bei 10.002 befindet Nun, all das ist über eine Zwei-A miteinander verbunden, sodass ich ihm jede Frage stellen kann, die sich auf die Begrüßung oder die Angabe der aktuellen Uhrzeit bezieht, und er sollte diese Kommunikation orchestrieren Lassen Sie uns also zunächst fragen, wie die aktuelle Uhrzeit ist. Ordnung, es erstellt also im Grunde ein JCN-RPC-Anforderungsobjekt und sendet es dann an den Orchestrator-Agenten, und Sie erhalten, dass die aktuelle Uhrzeit ist und das Datum ist im Grunde das, was sich der LLM einfallen lässt ein JCN-RPC-Anforderungsobjekt und sendet es dann an den Orchestrator-Agenten, und Sie erhalten, dass die aktuelle Uhrzeit ist und das Datum ist im Grunde das, was sich der LLM einfallen sodass er möglicherweise keinen Zugriff auf die neueste Uhrzeit hat, also gibt es uns im Grunde etwas Zeit, nämlich 16:17 Uhr Schauen wir uns nun unseren Orchestrator-Agenten an. Es hat also im Grunde diese JCNR-Anfrage erhalten. Dann sendet es eine JCN-RPC-Anfrage an den Tell Time Agent. Und hier drüben wird im Grunde die Frage weitergegeben, wie viel Uhr ist es? Weil es die Zeit will. Und dann bekommt es im Grunde die aktuelle Uhrzeit zurück und das ist was es an den 80-Client zurückgibt. Sie können sehen, dass der grüne Begrüßungsagent nichts getan hat, weil er keine Anfrage erhalten hat , und der blaue Agent hier drüben , der Tellt-Agent, hat die Uhrzeit tatsächlich zurückgegeben Gehen wir jetzt zurück zu unserem Kunden und fragen wir etwas anderes. Bitten wir ihn, uns zu begrüßen. Sagen wir also, grüß mich bitte. Gehen wir jetzt zurück zu unserem Orchestrator hier drüben. Es sendet also im Grunde eine JSON-RPC-Anfrage, die besagt, dass der Benutzer begrüßt Und jetzt erhält Ihr Begrüßungsagent im Grunde diese Anfrage. Da es also um die Begrüßung des Benutzers geht , versteht der Orchestrator, dass er diesen Agenten anrufen muss , und empfängt im Grunde genommen die Anfrage Dieser Agent muss sich dann die Zeit nehmen. Also schlägt er im Grunde den Tellt-Agenten vor, die Zeit zu bekommen, die er jetzt hier mit sechs und 28 zurückgibt Dann ist es mit dieser Zeit wieder hier drüben. Jetzt steuert der Orchestrator quasi beide Agenten und wir können zum Client zurückkehren und sehen, dass der Agent sagt, liebe Grüße, lieber Benutzer, die Uhr schlägt vier und 28, das war die Zeit, zu der wir ein sanftes Abendlicht sahen und eine Zeit, um den Empfang zu feiern Im Grunde handelt es sich also um eine poetische Begrüßung , die der Grußagent produziert Also, Leute, ist es nicht völlig erstaunlich, dass wir tatsächlich diese drei Agenten gebaut haben, die roten, grünen und blauen Agenten, und wir haben hier ein A-zu-a-Client , der im Grunde mit einer Befehlszeilenschnittstelle verbunden ist einer Befehlszeilenschnittstelle über die wir eine Anfrage stellen können Der rote Agent ist der Orchestrator , der entscheidet, mit welchen anderen Agenten eine Verbindung hergestellt werden soll Auf dieser Grundlage hat es dann entweder den Begrüßungsagenten oder den Tellt-Agenten in diesem Fenster veranlasst , und das alles funktioniert nahtlos von A bis A, um Ihnen hier die endgültige Antwort zu geben. 86. 15.2 Zusammenfassung der A2A-Architektur: Bevor wir mit dem Code beginnen, lassen Sie uns kurz die 82-Wege-Architektur zusammenfassen , der wir für den Code folgen werden Wir haben den Benutzer hier im Grunde mit einem App-Frontend interagiert, das wir gerade als Befehlszeilenschnittstelle gesehen haben, die im Grunde einen A-Toy-Client hostet Es verbindet sich über ein Zwei-A-System mit dem Host oder dem Orchestrator-Agenten Der Host-Orchestrator-Agent hat einen A-Zwei-A-Server, auf dem diese Verbindung hergestellt wird Dieser Agent listet im Grunde alle Agenten in einer Agentenregistrierung auf und stellt fest, dass es zwei weitere Remote-Agenten gibt , die vorerst lokal auf dem MacBook ausgeführt Diese Agenten können sehr gut auf einem Server mit einer URL für diesen Server gehostet Server mit einer URL für diesen Server Sobald es diese Agenten entdeckt hat, versteht es im Grunde, dass das, was der Benutzer fragt, ob es nun darum geht, die Uhrzeit mitzuteilen oder den Benutzer zu begrüßen, je nachdem, es die Aufgaben an einen der Agenten delegiert , einen grünen Agenten , der der Begrüßungsagent war, wenn der Benutzer nach einer Begrüßung und wenn der Benutzer fragt , wie spät es ist, ruft es das nicht auf Agent, ich stelle einfach eine Verbindung zu dem anderen Agenten der der Tellt-Agent ist, und das passiert über einen A-Zwei-A-Client, der sich wieder mit diesen Agenten über ihre ATA-Server verbindet , die wir auf Port 10.000 und 10.001 verfügbar gemacht , die wir auf Port 10.000 und 10.001 verfügbar und das passiert wieder über ATA, die Server antworten mit der Antwort an den Etway-Client und das geht dann zurück zum Host-Agent, der dann dem Client und dem App-Frontend antwortet Dies ist eine sehr kurze Zusammenfassung der Funktionsweise unserer Architektur. Wenn Sie sich weitere Details ansehen möchten, können Sie sich auf das vorherige Video über die Architektur von Etway mit mehreren Agenten beziehen , und jetzt werden wir den Code für dieses Setup durchgehen den Code für dieses Setup durchgehen 87. 15.3 Agentenerkennung und -registrierung: Ordnung, lassen Sie uns zunächst den Agent Discovery-Code durchgehen und Sie werden sehen, dass gesamte Codebasis im Multi-Agent-Ordner der Version 3 befindet , und Sie haben einen Dienstprogramm-Ordner , den ich hier erstellt habe, und wir haben den Erkennungspunkt PY und den Agenten-Unterstrichpunkt CHASE Die Idee ist also, dass dies eine skalierbare Methode sein wird, um, Sie wissen schon, alle Agenten zu entdecken Alle Agenten werden sich in dieser Registrierung registrieren , die im Grunde einfach die URL des ATA-Servers sein wird . Wir haben also drei Agenten. Wir haben den Agenten mit Port 10.000, 10.001 und 10.002, und das ist der Tellt-Agent Das ist der Begrüßungsagent und das ist der Host. Gehen wir nun zur PY-Discovery-PY-Datei Dabei handelt es sich im Grunde ein gemeinsam genutztes Dienstprogrammmodul zur Erkennung von achtzig Servern Es liest also die Registrierung der agentenbasierten URLs, bei der diese spezielle Datei handelt, und ruft die es sich um diese spezielle Datei handelt, und ruft die Agentenkarten der einzelnen Agenten ab Wie Sie sich erinnern, enthält die Agentenkarte also im Grunde die Details des Agenten in Bezug auf seine Fähigkeiten, seine URL und die verschiedenen Funktionen, die der Agent anbietet Im Grunde hilft das also , dass es jedem anderen Agenten oder Client dabei hilft , dynamisch herauszufinden, welche Agenten in Ihrer Anwendung verfügbar sind und Remote-Agenten Sie möglicherweise in dieser Registrierungsdatei angegeben haben. Lassen Sie uns den Discovery-P-Code durchgehen. Wir haben hier nur die grundlegenden Importe und wir haben die Agenten-Karte und dann haben wir den Discovery-Client, das ist die Klasse, die im Grunde für die Erkennung von zwei Agenten verantwortlich ist . Lassen Sie mich alle Codeblöcke zusammenklappen , sodass Sie die Struktur hier drüben sehen können. Wir haben also die Discovery-Client-Klasse, und sie nimmt im Grunde die Registrierungsdatei auf, das ist ein Pfad zur JCNFle , die alle URLs auflistet Sie hat also einen Konstruktor, sie hat eine Funktion zum Laden der Registrierung und sie ist eine Funktion zum Auflisten Agentenkarten, die im Grunde alle Agentenkarten auflistet, und das ist es, was Sie von jedem anderen Client oder Agenten aus aufrufen werden von jedem anderen Client oder Agenten aus Ordnung, der Konstruktor weist einfach Wenn die Registrierungsdatei verfügbar ist, sie im Grunde standardmäßig Wenn nicht, dann nimmt er im Grunde den Agenten-Unterstrich JCN aus dem Die Basis-URL-Eigenschaft wird mithilfe der Load-Registry-Funktion zugewiesen , die hier definiert ist. Ordnung. Die Funktion zum Laden der Registrierung übergibt im Grunde die Registrierungs-JCN-Datei an eine Liste von URLs Es öffnet also einfach die Datei hier im Lesemodus. Dann wird sichergestellt, dass es sich bei der JSON um eine Liste handelt und nicht um ein Objekt oder einen anderen Typ. Dann gibt es eine Ausnahme für die Datei, die nicht gefunden wurde, und eine Ausnahme für ungültige JCNs. Wenn alles in Ordnung ist, wird im Grunde die Liste der URLs hier zurückgegeben. Dann haben wir die Funktion „ Agentenkarten auflisten“. Im Grunde genommen wird der Erkennungsendpunkt asynchron von jeder registrierten URL abgerufen , was wir in der obigen Datei angegeben haben, und dann wird im Grunde eine JCN zurückgegeben , die die Agentenkarte darstellt Ich werde das an ein Agentenkartenobjekt übergeben. Dann gibt es im Grunde die Liste der Agentenkarten zurück , die es von allen Agenten abgerufen hat. Wir bereiten im Grunde eine leere Liste vor, um alle Instanzen der Agentenkarten zu sammeln alle Instanzen der Agentenkarten und erstellen dann einen neuen asynchronen Client Dann durchlaufen wir jede URL in den Basis-URLs. Jeder Agent, ein Agent nach dem anderen, dann normalisieren wir die URL, um jeden nachfolgenden Schrägstrich zu entfernen und hängen dann den Erkennungsendpunkt an, der Der Agent registriert sich selbst mit der Basis-URL. Wir müssen den bekannten Schrägstrich für Agenten mit dem Punkt jcnPath für die Agentenkarte anhängen Punkt jcnPath für die Agentenkarte Dann senden wir im Grunde eine Anfrage mit einem zweiten Timeout an den Discovery-Endpunkt und wir erhalten mit einem zweiten Timeout an den Discovery-Endpunkt eine Wir überprüfen die Antwort auf alle vier XX- oder fünf XX-Fehler und konvertieren dann die JCN in eine Agentenkarte und validieren Und dann fügen wir diese validierte Agentenkarte zu unserer Kartenliste hinzu und geben sie am Ende zurück Es gibt auch eine Ausnahmebehandlung für den Fall , dass ein Fehler auftritt Deshalb drucken wir diese Ausnahme für spezifische URL mithilfe des Loggers aus. Das ist alles für die Discovery-PY-Datei, eine ziemlich einfache Datei mit diesen drei Funktionen zum Auflisten der Agentenkarten, die im Grunde die Funktion „Registry laden“ verwendet, und es gibt auch eine Initialisierung, um den Pfad für die Datei anzuwenden, nämlich den Agenten-Unterstrichpunkt jCNle 88. 15.4 Orchestrator-Host-Agent: Im Grunde haben wir uns hier mit der Erkennungslogik befasst. Jetzt gehe ich zum nächsten Aspekt über , den wir im Grunde hinzugefügt haben, nämlich dem Orchestrator und dem Host-Agenten Das ist der Host-Agent hier drüben und wir haben hier den Orchestrator Punkt PY , der unser Basisagent ist Der Host-Agent und der Orchestrator sind also tatsächlich identisch Es wird einfach Orchestrator genannt, weil es im Grunde entscheidet, wie die Erfüllung der Aufgabe, die wir vom Kunden erhalten haben, verwaltet der Aufgabe, die wir vom Kunden erhalten haben, In Ordnung. Also Agent Host Agent Orchestrator Punkt PY, er definiert im Grunde den Orchestrator-Agenten und verwendet das auf Gemini basierende LLM, und verwendet das auf Gemini basierende um Benutzeranfragen zu interpretieren und sie an jedes Kind zu delegieren, das ein Es definiert auch den Task-Manager für den Orchestrator, der all diese Logik über JCN RPC verfügbar macht Nur um mich zu wiederholen, wir haben in den vorherigen Videos bereits über die Erstellung eines Agenten mit Googles ADK , das im Grunde genommen A-konform ist Was ist die Rolle des Task-Managers Was ist die Rolle des Agenten. Dann haben Sie im Grunde ein Skript, das der Eintrag oder das Hauptskript ist. In diesem Fall nennen wir es Entry Dot PI, das im Grunde den gesamten Agenten mit dem Server und dem Task-Manager ausführt und einrichtet . Nur eine kurze Zusammenfassung wäre, dass Sie einen Agenten haben und dieser Agent im Grunde von einem Task-Manager umgeben ist , der dem Agenten hilft , die Aufgaben vom Server zu empfangen und dem Server im Grunde die gesamte Funktionalität des Agenten zur Verfügung stellt des Agenten zur und kümmert sich um die gesamte Aufgabenerfüllung. Der Server selbst ist im Grunde ein gemeinsamer Code , der im Grunde den Task-Manager übernimmt, der den Agenten umschließt, und derselbe Server kann von mehreren Agenten verwendet werden Sie definieren jeweils ihre eigene Serverinstanz, die auf einer separaten URL läuft. In Ordnung. Hier gibt es einige grundlegende Importe und dann laden wir die Umgebungsdatei für den Gemini-API-Schlüssel Dann haben wir hier alle Google ADK - und Gemini-Importe Ich werde diese einfach überspringen und Sie können tatsächlich alle Befehle hier lesen , um zu wissen, wofür diese Dateien importiert werden Dann haben wir die serverseitige ATA-Infrastruktur. Im Grunde müssen wir also den Task-Manager für den Server importieren. Dies ist eine Basisklasse, die wir verwenden, um einen sehr spezifischen Task-Manager für diesen Agenten zu implementieren. Auch dies haben wir im vorherigen Video behandelt und wir werden darüber sprechen, wenn wir zum Task-Manager gehen. Dann haben wir die Datenmodelle , die wir grundsätzlich verwenden. Die anforderungsbezogenen Datenmodelle sind also in der Modell-Slash-Anfrage enthalten, und wir verwenden im Grunde die Aufgabenanfrage Senden, die im Grunde ein Objekt ist, um die Aufgabe zu kapseln, die wir als Anfrage senden, und dann die Antwort auf die Aufgabe senden, die eine Antwort auf diese Anfrage ist Dies sind die Datenmodelle für eingehende und ausgehende Aufgabenanfragen und Antworten sowie ziemlich einfache Modelle Wir haben sie in unserem vorherigen Video zum Aufbau eines einzigen 80-konformen ADK-Agenten behandelt Aufbau eines einzigen 80-konformen Sie können sich also dieses Video ansehen, wenn Sie die Details all dieser Punkte durchgehen möchten Dann haben wir in ähnlicher Weise Aufgabenmodelle. Im Grunde genommen umfassen die Nachricht, der Aufgabenstatus, der Aufgabenstatus, der Textteil und die Nachricht die Rolle plus die Teile der Nachricht, die hier Textteile sind. Dann haben wir den Aufgabenstatus und den Status und wir haben auch Textteile, was im Grunde die Textnutzlast ist Dann haben wir also den Konnektor zum untergeordneten Ato-Agenten. Also schauen wir uns den Agenten-Connector an und er ist im Grunde ein einfacher Wrapper rund um den Ato-Client, mit dem andere Agenten angerufen werden können Es ist ein ziemlich einfacher Code, aber wir werden ihn immer dann durchgehen, wenn wir in dieser speziellen Datei auf diesen Code stoßen in dieser speziellen Datei auf diesen Code stoßen Dann haben wir den Agenten, also importieren wir im Grunde die Agentenkarte, das ist das Agentenmodell, und das ist die Metadatenstruktur für die Ergebnisse der Agentenerkennung, und dann haben wir das Logger-Setup. Gehen wir nun zum Orchestrator-Agenten, und wir haben bereits erwähnt, dass er den LLM von Gemini und den ADC von Google verwendet , um einen Agenten zu erstellen, und dass er dann alle untergeordneten Agenten oder alle anderen vorhandenen Agenten erkennen kann alle untergeordneten Agenten oder alle anderen vorhandenen Agenten Und er kann diese Agenten mithilfe von Tools aufrufen, und wir werden uns im Folgenden ansehen, wie er Wir haben einen unterstützten Inhaltstyp , der für diesen bestimmten Agenten definiert werden kann, nämlich Text oder Klartext. Dann haben wir den Konstruktor hier drüben. Also, wenn wir den Agenten an einer anderen Stelle im Code definieren, haben wir über die Liste der verfügbaren Agenten-Karten eine Liste verfügbarer Agenten bereitgestellt Liste der verfügbaren Agenten-Karten eine Liste , die dem Eigentum dieser Agenten-Karte zugewiesen wird Und dann haben wir für jede gefundene Agentenkarte einen Agenten-Connector erstellt , und hier sind Agentenkarten im Grunde eine Liste von Objekten der Agentenkarte, die bei der Entdeckung zurückgegeben wurden. Die Entdeckung hier findet also nicht im Agenten selbst statt. Es passiert außerhalb des Agenten, und wir stellen die Liste der entdeckten Agenten hier als Agentenkarten zur Verfügung. Und für jede Agenten-Karte erstellen wir im Grunde ein Agenten-Connector-Objekt, das den Kartennamen und die Karten-URL aufnimmt das den Kartennamen und die Karten-URL aufnimmt und sie dann quasi einem Connector-Wörterbuch hinzufügt . Das ist es, was hier passiert. Ich werde hier schnell den Agenten-Connector-Code durchgehen . In Ordnung. Der Agent-Connector ist also ein sehr einfacher Wrapper rund um einen Client um Aufgaben an jeden Remote-Agenten zu senden , der durch eine Basis-URL identifiziert wird Im Grunde genommen entkoppelt dies den Orchestrator von den SDP-Details auf niedriger Ebene und der Einrichtung des SDP-Clients Wir haben hier also einfache Importe, und ich werde einfach den Kurs hier durchgehen Der Agenten-Connector stellt also eine Verbindung zu einem Remote-Agenten her und bietet eine einheitliche Methode zum Delegieren von Aufgaben Und es hat im Grunde zwei Eigenschaften. Einer ist der Name, der die für Menschen lesbare Kennung des Remote-Agenten ist . Und dann haben wir den 80-Client. Dies ist der STTP-Client, der auf die URL dieses Agenten verweist, und das ist es, was die Aufgabe tatsächlich delegiert oder vom Orchestrator an den anderen Agenten sendet die Aufgabe tatsächlich delegiert oder vom Orchestrator an den , den wir verwenden möchten Wie Sie sehen können, definiert er hier im Grunde einen Acht-Tow-Client, nur die Basis-URL für den Agenten verwendet, für den wir den Konnektor definieren Dann haben wir die Funktion Aufgabe senden. Dabei wird im Grunde eine Textaufgabe an den Remote-Agenten gesendet und die abgeschlossene Aufgabe zurückgegeben. Es hat also zwei Argumente. Eines ist die Botschaft. Was ist also die Textabfrage , die Sie im Grunde senden möchten? Und dann die Sitzungs-ID. Die Sitzung wurde identifiziert , um verwandte Anrufe zu gruppieren. Und was sie zurückgibt, ist im Grunde das Task-Objekt vom Remote-Agenten, und sie erhält im Grunde eine eindeutige ID für diese Aufgabe mithilfe von UID vier und erstellt dann diese spezielle Payload, bei der es sich um eine JSON-RPC-Nutzlast handelt, die dem Sendeparameterschema der Aufgabe entspricht haben eine ID in der Payload, Sie haben eine Sitzungs-ID in der Payload und dann haben Sie eine Nachricht und die Nachricht hat eine Benutzerrolle und sie besteht aus mehreren Teilen besteht Hier ist der Teil nur ein Teil, nämlich die Nachricht, die wir im Grunde vom Benutzer erhalten Dann verwenden wir im Grunde die Funktion zum Senden von Aufgaben an einen Client , um diese Nutzdaten zu senden, und dann erhalten wir das Ergebnis der Aufgabe Und schließlich haben wir im Grunde einige grundlegende Logging und dann geben wir das Ergebnis der Aufgabe von hier aus zurück Das ist also alles, was der verbundene Agent tut Er bietet dem Orchestrator im Grunde nur die Möglichkeit, einen Aic-Client zu verwenden , um die Aufgabe zu senden und das Ergebnis so einfach zurückzubekommen Ordnung. Also, jetzt können wir zurück zum Orchestrator hier drüben Und wir waren beim Konstruktor des Orchestrators. Jetzt haben wir also ein Wörterbuch mit Konnektoren für jeden Agenten, das wir im Grunde in der Agenten-Registrierungsdatei haben Dann haben wir die Build-Agent-Funktion. Damit wird im Grunde der interne LLM-Agent mit unseren benutzerdefinierten Tools und Anweisungen erstellt der interne LLM-Agent mit unseren benutzerdefinierten Tools und Anweisungen Nun, diese Build-Agent-Funktion haben wir bereits durchgemacht, aber das wird für den Orchestrator etwas anders sein , da wir Funktionen zum Delegieren von Aufgaben bereitstellen müssen Wir schauen uns das an, sobald wir auf eine Funktion stoßen. Wir geben eine Benutzer-ID für die Sitzungsverfolgung von Zeilenaufrufen an, und dann definieren wir im Grunde den Runner, der im Grunde die Speicherartefakte der Sitzung verkabelt und Agent Dot verarbeitet. Alles klar. Also hier ist die Build-Agent-Funktion. Und was wir hier machen, ist, dass wir im Grunde einen Google ADK LLM-Agenten erstellen Wir geben hier all die verschiedenen Argumente an, die dafür erforderlich sind, und der Unterschied zwischen dem, was wir zuvor gelernt haben, und dem, was wir jetzt gelernt haben , besteht darin, dass wir jetzt diese beiden Funktionen haben Eine ist die Funktion zum Auflisten von Agenten und eine ist die Funktion zum Delegieren von Aufgaben Und das teilt dem Agenten im Grunde mit, dass Ihnen jetzt diese beiden Funktionen zur Verfügung stehen , sodass Sie alle anderen Agenten auflisten können , mit denen Sie arbeiten müssen, und dass Sie mit diesem speziellen Tool Aufgaben an sie delegieren können diesem speziellen Tool Aufgaben an sie Diese Delegierung von Aufgaben in 80 Fällen erfolgt also nur durch Funktionsaufrufen Und was Sie tun müssen, ist, die Agenten zu finden und sie dann dem LLM-Agenten hier als Tools zur Verfügung LLM-Agenten hier als Tools zur Wir haben hier einige grundlegende Anweisungen für unseren Agenten. Definieren Sie also im Grunde, dass Sie ein Orchestrator mit zwei Tools sind Das eine ist das Auflisten von Agenten, das die verfügbaren untergeordneten Agenten auflistet, und dann können Sie Aufgaben mit dem Namen und der Nachricht des Agenten delegieren mit dem Namen und der Nachricht des Agenten Im Grunde können Sie diesen Agenten anrufen. Verwenden Sie diese Tools, um den Benutzer zufrieden zu stellen, halluzinieren Sie nicht und die verfügbaren Agenten sind es, und dann stellen Sie eine Wenn Sie dann also Listenagenten definieren, werden im Grunde nur die Konnektoren verwendet und die Namen der Agenten gedruckt Und das ist im Grunde das, was Ihrem Host-Agenten helfen wird , zu verstehen welche verschiedenen Agenten verfügbar sind. Sie könnten hier mehr tun, indem Sie weitere Informationen angeben. Ich habe gerade die Liste der Namen der untergeordneten Agenten zurückgegeben , die derzeit registriert sind, und dann haben Sie die Delegate-Task-Funktion Im Grunde leitet diese Funktion die Nachricht an den spezifischen untergeordneten Über den Agenten-Connector? Es wartet auf die Antwort und gibt den Text der letzten Antwort zurück den Text der letzten Antwort Was im Grunde genommen Namen des Agenten enthält, an den Sie die Aufgabe delegieren möchten Was ist die Nachricht oder die Abfragezeichenfolge, die Sie delegieren, und was ist der Tool-Kontext Nur zur Verdeutlichung: Der Werkzeugkontext ist im Grunde eine Klasse, die von ADC bereitgestellt wird. Sie bietet im Grunde den Kontext für den Werkzeugaufruf und beinhaltet den Zugriff auf den Aufrufkontext, die Funktionsaufruf-ID, die Ereignisaktionen, die Authentifizierungsantwort usw. im Grunde eine Klasse, die von ADC bereitgestellt wird bietet im Grunde den Kontext für Werkzeugaufruf und beinhaltet den Zugriff auf den Aufrufkontext, die Funktionsaufruf-ID, die Ereignisaktionen, Authentifizierungsantwort Im Grunde werden wir dies hier verwenden, um sicherzustellen, dass die Sitzungs-ID bei allen Toolaufrufen über den Werkzeugkontext-Punkt State grundsätzlich dieselbe ist Toolaufrufen über den Werkzeugkontext-Punkt Wir erhalten also das State-Objekt und suchen dann nach der Sitzungs-ID. Wenn es nicht vorhanden ist, weisen wir es im Grunde dem Zustandsobjekt zu. Und dann nehmen wir im Grunde die Sitzungs-ID aus dem Zustandsobjekt, falls es vorhanden ist. Dann delegieren wir die Aufgabe also grundsätzlich asynchron und warten auf die Ergebnisse der Aufgabe Also werden wir den Konnektor verwenden und das ist dann die Funktion zum Senden von Aufgaben Und wie wir bereits gesehen haben, wird dabei im Grunde der Acht-to-Way-Client aufgerufen, um die Nachricht und die Sitzungs-ID zu senden die Nachricht und die Sitzungs-ID und dann im Grunde die Antwort zurückzubekommen. Und wir speichern diese Antwort dann im Grunde in einem untergeordneten Aufgabenobjekt. Und dann überprüfen wir den Verlauf des untergeordneten Aufgabenobjekts und dann die Länge des Verlaufs, falls diese größer als eins ist, nehmen wir den letzten Teil der Verlaufsnachrichten und dann nehmen wir im Grunde den ersten Teil und dann antworten wir mit dem Text innerhalb dieses Teils. Ordnung. Dann fahren wir mit der Aufruffunktion fort und das wird uns helfen, den Orchestrator aufzurufen Dies ist der Haupteintrag. Er empfängt die Benutzerabfrage und die Sitzungs-ID. Es richtet eine Sitzung ein oder ruft sie ab, schließt die Abfrage für das LLM und führt dann den Runner mit aktivierten Tools aus und gibt den endgültigen Text zurück Wir haben die Sitzung hier drüben. Und wir versuchen, eine bestehende Sitzung wiederzuverwenden. Wenn nicht, erstellen wir hier im Grunde eine neue Sitzung. Dann verpacken wir die Benutzerabfrage in eine Textnachricht vom Typ Dot. Dies sind also im Grunde das Format und die Typen, die uns von Google zur Verfügung gestellt werden, was Gemini erwartet Wir verwenden also Typen mit Punktinhalten. Wir bieten eine Rolle und wir stellen die Teile zur Verfügung. Und hier ist der Teil nur ein Textteil, der die Benutzerabfrage enthält, und das ist im Grunde der Inhalt hier. Wir stellen diesen Inhalt während der Ausführung des Laufs mit der Benutzer-ID Intercession ID zur Verfügung und dann erhalten wir im Grunde eine sogenannte Event-Liste Dann überprüfen wir die Ereignisse. Wenn es keine Inhalte oder Teile gibt, im Grunde genommen ein leeres Fallback verwendet Andernfalls fügen wir alle Textteile einer einzigen Zeichenkettenantwort zusammen und geben sie hier zurück. Das ist im Grunde unser Orchestrator-Agent nur um zu wiederholen, dass wir uns bereits in unseren vorherigen Videos mit dieser Art von Agentendefinition und all den verschiedenen Funktionen für den Agenten befasst dieser Art von Agentendefinition und all den verschiedenen Funktionen für haben. Der Unterschied besteht darin, dass für den Agenten grundsätzlich zwei Tools verfügbar sind für den Agenten grundsätzlich zwei Tools verfügbar Eine besteht darin, die Agenten aufzulisten und eine darin, eine Aufgabe zu delegieren, und die Funktion zum Delegieren von Aufgaben verwendet einen Agenten-Connector , der hier neu ist, und das hilft uns im Grunde die anderen Agenten, die über eine Acht entdeckt wurden, an einen Client anzurufen über eine Acht entdeckt wurden, an , um die Aufgabe von diesem Agenten zu erledigen. Das ist der Unterschied hier und das vervollständigt im Grunde unsere Orchestrator-Agentenklasse 89. 15.5 Orchestrator-Taskmanager: Gehen Sie jetzt zum Task-Manager. Task-Manager wird so ziemlich derselbe sein, Der Task-Manager wird so ziemlich derselbe sein, wie wir es zuvor gesehen haben , und er implementiert im Grunde den In-Memory-Taskmanager als Basisklasse, und der Task-Manager-Apper macht den Orchestrator-Agenten Dot Invoke direkt über dem A-Aufgabenendpunkt Also nimmt er den Agenten hier im Konstruktor auf. Es kann den Benutzertext aus dem Objekt „ Aufgabenanfrage senden“ extrahieren aus dem Objekt „ Aufgabenanfrage senden handelt es sich um den Typ des Anforderungsobjekts , das wir grundsätzlich erhalten Und wenn dann eine Aufgabe zum Senden aufgerufen wird, wird die Aufgabe im Grunde genommen an den Agenten gesendet. Es wird also vom TA-Server aufgerufen, wenn eine neue Aufgabe eintrifft. Es speichert die eingehende Benutzernachricht und ruft den Orchestrator-Agenten auf, um eine Antwort zu erhalten . Anschließend hängt es die Antwort an den Verlauf an und markiert die Aufgabe als abgeschlossen Anschließend gibt es eine Antwort zum Senden der Aufgabe mit der vollständigen Aufgabe zurück Antwort zum Senden der Aufgabe mit der vollständigen Aufgabe Das ist es, was es tut. Nochmals, wir haben uns den Code angesehen. Ich werde es einfach schnell noch einmal durchgehen. Wir speichern die erste Nachricht in einem Aufgabenobjekt. Dann erhalten wir im Grunde den Benutzertext aus dem Anforderungsobjekt. Dann rufen wir den Agenten dot Invoke mit dem Agenten auf, den wir für diesen Task-Manager haben, und im Grunde genommen nimmt er den Benutzertext und die Sitzungs-ID und gibt einen Antworttext zurück, dann formulieren wir eine Antwort, also packen wir die LLM-Ausgabe in Die Nachricht hat also im Grunde die Rolle Agent und den Teil, den Antworttext enthält, dann markieren wir den Aufgabenstatus als erledigt, und wir hängen im Grunde die Antwort, die wir erhalten haben, an den Aufgabenverlauf an, und dann geben wir die Antwort auf die Sendeaufgabe mit der Anforderungs-ID und der Aufgabe als Ergebnis zurück . Das ist es, was der orchestrierte Aufgabenmanager tut. 90. 15.6 Python-Skript für den Orchestrator-Eintrag: Ich habe mir bereits die Orchestrator-PY-Datei angesehen, die im Grunde die Agenten - und die Task-Manager-Logik enthält Wir haben die PY-Datei mit dem Agenten-Connect-Punkt , die wir uns angesehen haben, und jetzt schauen wir uns die einfache Einstiegspunkt-PY-Datei hier an. In Ordnung. Die Einstiegspunkt-PY-Datei ist genau wie die Haupt-PY-Datei, die wir zuvor für die anderen Agenten gesehen haben , und sie startet den Orchestrator-Agenten als ATA-Server Sie verwendet die gemeinsam genutzte Registrierungsdatei, um alle untergeordneten Agenten zu ermitteln , und delegiert dann das Routing über ATA an den Orchestrator-Agenten Wir haben die grundlegenden Importe hier. Einschließlich der Protokollierung. Und um dann diesen Orchestrator-Agenten auszuführen, bieten wir grundsätzlich eine Option zur Bereitstellung des Hosts Wo möchten Sie also binden, an welchen Host möchten Sie den Orchestrator-Agent-Server binden den Orchestrator-Agent-Server Dann haben wir den Port für den Orchestrator-Agent-Server und dann haben wir eine optionale Registrierungsdatei Und wenn Sie diese Datei nicht bereitstellen, im Grunde die Datei in Inside Utility Slash Agent Underscore Registry JCN Dann haben wir die wichtigsten Einstiegspunkte. Im Grunde werden wir hier zuerst alle URLs der untergeordneten Agenten aus der Registrierung jcnFle laden alle URLs der untergeordneten Agenten aus der Registrierung jcnFle Auf diese Weise entdeckt der Host-Agent im Grunde alle untergeordneten Dann rufen wir die Metadaten jedes Agenten über den bekannten Agent Dot JCNE-Endpunkt Wir instanziieren einen Orchestrator-Agenten mit den erkannten Agentenkarten mit den erkannten Agentenkarten Dann packen wir ihn in einen Orchestrator-Taskmanager für die JCNRPC-Bearbeitung, und dann starten wir endlich den ATS-Server, um eingehende Aufgaben abzuhören , und wir haben diesen speziellen Taskmanager für die JCNRPC-Bearbeitung, und dann starten wir endlich den ATS-Server, um eingehende Aufgaben abzuhören, und wir haben diesen speziellen Taskmanager bereitgestellt. Wir haben also zuerst Discovery, also haben wir einen Discovery-Client und wir stellen die Registrierungsdatei bereit, was der Registrierung entspricht Es könnte Null sein und dann wird es den Standard verwenden. Wir haben dann die Agentenkarten. Wir führen die ASN-Erkennung beim Start grundsätzlich synchron durch, und dadurch erhalten wir die Agentenkarten Auch dies ist eine Art der Erkennung über eine Agentenregistrierung, und beim Start sehen wir tatsächlich unseren Begrüßungsagenten, der dieselbe Art von Erkennung verwendet , die über eine Registrierung erfolgt, aber beim Start nicht Ich mache es, solange es läuft. Dann werden wir warnen, falls keine Agentenkarten gefunden werden, also das ist die Warnung hier drüben. Dann definieren wir die eigenen Metadaten des Orchestrator-Agenten für die Erkennung Wir werden also die Möglichkeit haben, KurduFalls zu streamen. Wir haben das Skill-Objekt hier drüben. Und dann haben wir die Orchestrator-Karte. Ordnung. Dann instanziieren wir den Orchestrator-Agenten und seinen Task-Manager Für den Agenten haben wir also alle Karten bereitgestellt, die wir entdeckt haben, und für den Task-Manager haben wir im Grunde den Agenten bereitgestellt, wir im Grunde den Agenten bereitgestellt für den wir ihn als Task-Manager haben wollen, das ist der Orchestrator-Agent das ist der Orchestrator-Agent hier, den wir definiert haben, und wir bekommen den Task-Manager, und dann nehmen wir einfach diesen Task-Manager und dann erstellen und starten wir und für den Task-Manager haben wir im Grunde den Agenten bereitgestellt, für den wir ihn als Task-Manager haben wollen, das ist der Orchestrator-Agent hier, den wir definiert haben, und wir bekommen den Task-Manager, und dann nehmen wir einfach diesen Task-Manager und dann erstellen und starten wir den 80-Server mit dem Host und dem Port, der zusammen mit der Agentenkarte bereitgestellt wurde Wir nennen Server Dot Start, und damit starten wir im Grunde unseren 80-Server. Das ist also unser Einstiegspunkt P für unseren Orchestrator-Agenten, und das vervollständigt nun die gesamte Logik für unsere Agentenerkennung, für unseren Orchestrator-Agentencode selbst, den Task-Manager und für die Serverinitialisierung 91. 15.7 Begrüßungsagent: Also werde ich jetzt den Begrüßungsagenten durchgehen. Und im Begrüßungsagenten haben wir uns bereits angesehen, wie die Agenten ausgeführt und eingerichtet werden usw. Als wir uns mit der Erstellung des Google AD-Agenten mit Gemini und ATA-Konformität befassten des Google AD-Agenten mit Gemini und ATA-Konformität befassten Was wir hier tun, ist, uns nur die Unterschiede zu diesem bestimmten Agenten anzusehen , was im Grunde die Orchestrierungslogik ist Gehen wir also Agent Punkt PY hier durch. In Ordnung. Nun kann der Begrüßungsagent selbst auch die Uhrzeit vom Tellt-Agenten bekommen wollen Also stellen wir dem Begrüßungsagenten auch einen Orchestrator zur Verfügung, sodass er selbst als Host-Agent agieren und dann Informationen vom Tell-Time-Agenten abrufen kann, richtig? Und wenn wir den Code durchgehen, haben wir im Grunde alle Importe hier, und dann haben wir die Klasse Greeting Agent Also noch einmal, wir bieten grundsätzlich zwei LLM-Tools an, nämlich List-Agents und Call Agent Der Unterschied zu dieser Orchestrierung und dem Orchester-Host-Agenten besteht lediglich darin , dass zwei verschiedene Formen angezeigt Ist das so, dass die Listenagenten hier nicht eine vorab abgerufene Liste von Agentenkarten verwenden werden? eine vorab abgerufene Liste von Agentenkarten verwenden Es wird tatsächlich die Erkennungslogik verwenden , um die Liste der Agentenkarten abzurufen , verglichen dem, was im Host-Agenten passiert ist, wo wir dem Agenten mit dem, was im Host-Agenten passiert ist, wo wir dem Agenten tatsächlich eine Liste von Agentenkarten zur Verfügung gestellt haben, die wir während der Agentenkonfiguration vorab abgerufen hatten während der Agentenkonfiguration vorab abgerufen Und dann verwenden wir die Funktionen des Listenagenten nur, um die Agentenkarten aufzulisten , die im Konstruktor bereitgestellt wurden Hier drüben wird die Funktion „Agenten auflisten“ die Agenten zur Laufzeit dynamisch durch Erkennung abrufen durch Erkennung Bei einer Begrüßungsanfrage ruft diese Funktion den Listenagenten an, ruft diese Funktion um zu sehen, welche Agenten aktiv sind Es ruft den Call-Agenten Tellt Agent an, was der aktuellen Uhrzeit entspricht. Er wird einfach versuchen, diese Zeit daraus zu Und dann erstellt es einen zwei- bis dreizeiligen poetischen Gruß, der sich auf diese Zeit bezieht. Und auch das ist eine sehr einfache Logik, nur um zu zeigen, wie das alles funktioniert Sie können dies tatsächlich verwenden und für jeden komplizierteren Anwendungsfall modifizieren , aber das ist ein ziemlich einfacher Mechanismus nur um Ihnen zu helfen, zu verstehen, wie diese Agenten funktionieren. Wir haben also die unterstützten Inhaltstypen gefolgt von den Konstruktoren Der Konstruktor wird den internen Orchestrator-LLM-Runner und den Discovery-Client erstellen internen Orchestrator-LLM-Runner und den Orchestrator-LLM-Runner Wir haben also den Orchestrator, der Build-Orchestrator ist Wir haben eine Benutzer-ID, das ist der Begrüßungsbenutzer, und dann haben wir hier unser übliches Runner-Objekt. Wir haben Self Dot Discovery, was im Grunde ein Discovery-Client ist. Und dann definieren wir Konnektoren. Das ist also ein Cache für erstellte Konnektoren, sodass wir sie wiederverwenden können. Und im Moment wird es leer sein. Nun, jetzt kommen wir zur Hauptlogik, wir haben das Tool List Agents hier drüben, und das wird im Grunde den Discovery-Client verwenden, den wir oben hier erstellt haben und ihn Funktion List Agent Cards nennen , um die Kartenliste abzurufen. Dann wird jede Karte in ein Wörterbuch umgewandelt, alle Gefühle der Nonne weggelassen werden, und das dann zurückgegeben. Das ist also im Grunde das, was Ihr Tool für Listenagenten tut, und das wird von Ihrem Begrüßungsagenten verwendet , um zu verstehen, welche Agenten verfügbar sind. Dann haben wir die Call-Agent-Funktion. Also nochmal, sehr ähnlich dem was wir für den Host-Agenten gesehen haben. Es hat einen Agentennamen und eine Nachricht. Und was es tut, ist, dass es wieder alle Agentenkarten abruft, und das ist im Grunde dazu da, jede Art von neuem Agenten abzurufen Und es ruft im Grunde alle Karten wieder ab, um alle neuen Agenten dynamisch zu fangen Und dann versucht es im Grunde, genau nach Name oder ID abzugleichen. Es bedeutet also, dass der hier angegebene Agentenname mit einem der hier verfügbaren Agenten übereinstimmen muss. Dann gibt es eine Übereinstimmung mit der Teilzeichenfolge, falls keine exakte Übereinstimmung gefunden wird, und, wissen Sie , falls der Agent, dessen Anruf angefordert wurde , nicht existiert, geben Sie hier einen Wertfehler zurück Andernfalls haben Sie den Namen des entsprechenden Agenten und dann das Connector-Objekt für diesen bestimmten Connector Definieren Sie hier die Sitzungs-ID, und dann verwenden Sie im Grunde die Funktion zum Senden von Aufgaben des Connectors , bei der im Grunde der Natoa-Client verwendet wird , um die Nachricht mit dieser Sitzungs-ID an diesen untergeordneten Agenten zu senden dieser Sitzungs-ID an diesen untergeordneten Agenten zu und Sie erhalten dann das Ergebnis als Aufgabenobjekt. Wie üblich verwenden wir im Grunde den Aufgabenverlauf, um die Teile der letzten Nachrichten abzurufen Teile der letzten Nachrichten und dann drucken Sie im Grunde den Text aus dem ersten Teil dieser letzten Nachricht hier drüben Ordnung. Dann fahren wir mit der Build-Orchestrator-Funktionalität fort der Build-Orchestrator-Funktionalität Abgesehen von diesen beiden Tools haben wir die Systemanweisung, dass Sie zwei Tools haben die die Metadaten für alle wertvollen Agenten zurückgeben werden , das ist das Tool List Agents, und dann haben Sie das Call Agent Tool, das eine Nachricht entgegennimmt und diesen bestimmten Agenten anruft diesen bestimmten Agenten seinen Namen und dann eine Antwort von diesem Agenten abrufen. Wenn Sie also um eine Begrüßung gebeten werden, handelt es sich um einen Greet-Agent, also müssen wir auch die Begrüßungsanweisungen bereitstellen. Das heißt , wenn Sie um eine Begrüßung gebeten werden, rufen Sie zuerst die Listenagenten an, rufen Sie dann den Tell Time Agent an, was die aktuelle Uhrzeit ist, und erstellen Sie dann einen zwei- bis dreizeiligen poetischen Gruß, der erstellen Sie dann einen zwei- bis dreizeiligen poetischen Das ist hier wichtig , weil wir diesem Agenten sagen müssen, dass er eine Begrüßung geben muss eine Begrüßung geben muss indem er den Tellt-Agenten benutzt oder zumindest die Zeit nutzt. Man könnte das so ändern , dass er nicht ausdrücklich sagt, dass er den Tellt-Agenten anrufen soll, sondern die Zeit mit einem der geeigneten Agenten nutzen soll , oder? Hier drüben habe ich ausdrücklich angegeben, dass Sie den Tellt-Agenten anrufen. Sie könnten es allgemeiner machen, indem Sie einfach sagen, dass Sie die Zeit benötigen, und dann einen anderen Agenten anrufen , der Ihnen die Uhrzeit sagen kann Aber auf jeden Fall wird es dieser Anweisung folgen, sich die verfügbaren Agenten ansehen und dann den Tellt-Agenten anrufen Das sagt Ihnen im Grunde , dass es alle Agenten entdeckt und dann seinen Anweisungen folgt, um einen der fähigen Agenten anzurufen. In Ordnung. Dann definieren wir hier die Werkzeugliste und packen diese beiden Python-Funktionen in das vom ADK definierte Funktionstoolobjekt ein Und dann geben wir den LM-Agenten mit den Tools hierher zurück. Wir stellen hier auch die Systemanweisungen und die anderen Parameter zur Verfügung. Wir haben dann die aufgerufene Funktion. Im Grunde ist dies die Funktion, die vom Task-Manager aufgerufen wird, um den Begrüßungsagenten aufzurufen Dadurch wird also im Grunde eine Benutzeranfrage über die LLM-Pipeline des Orchestrator gesendet , wobei die Gleichung für die Wiederverwendung der Sitzung sichergestellt und die endgültige Textantwort zurückgegeben wird Auch das ist dem, was wir uns zuvor für andere aufgerufene Funktionen angesehen haben, sehr ähnlich , und Sie können diesen Code mit den Befehlen durchgehen , um das zu verstehen, und damit ist unser Begrüßungsagent im Grunde abgeschlossen Ordnung. Also dann haben wir den Taskmanager, und dieser wird mehr oder weniger den anderen Agenten-Task-Managern sehr ähnlich sein . Es wird also ein Modell zum Senden einer Aufgabenanfrage erhalten. Es speichert die Benutzernachricht im Speicher und ruft die Funktion dot Invoke des Begrüßungsagenten auf, die wir uns gerade angesehen haben, um asynchron eine Begrüßung zu generieren Es aktualisiert den Aufgabenstatus und fügt die Begrüßung an den Aufgabenverlauf an Anschließend wird eine Antwort auf Aufgabe senden mit der abgeschlossenen Aufgabe ausgewählt . Also noch einmal, wenn wir den gesamten Code durchgehen, haben wir die gemeinsamen Eingaben Ordnung. Also dann haben wir den Aufgabenmanager für die Begrüßung. Also auch hier verwendet es im Grunde die Basisklasse, die sich im Memory-Taskmanager befindet. Und es erbt Speicher, Aufgaben und Sperren aus dem Arbeitsspeicher des Task-Managers Er überschreibt die Aufgabe beim Senden, speichert die eingehende Nachricht, ruft den Begrüßungsagenten dot invoke auf , um eine Begrüßung zu erstellen, aktualisiert den Status und den Verlauf der Aufgabe und gibt das Ergebnis anschließend als Antwort auf „Aufgabe senden“ zurück das Ergebnis anschließend als Wir haben uns also schon einmal Aufgabenmanager angesehen und es sind so ziemlich die gleichen Strukturen Ich werde diesen Code mit Befehlen belassen, damit alle Schüler und Benutzer das alles durchgehen und verstehen können, wie das funktioniert. Auch hier können Sie sich die vorherigen Videos ansehen , um zu verstehen, wie der Task-Manager funktioniert. Und schließlich haben wir hier die PY-Hauptdatei mit Punkt, die den Geting-Agent im Grunde als ATS-Server startet . Und auch das ist dem, was wir für die anderen Agenten getan haben, sehr ähnlich , nämlich den Teleti-Agenten und den Host-Agenten Sie können diese Datei also tatsächlich durchgehen. Es enthält umfangreiche Befehle für jeden Aspekt der Datei und wird dem, was wir zuvor gemacht haben, sehr ähnlich sein. Schauen Sie sich bitte auch hier die vorherigen Videos zur Definition eines AA-Agenten mithilfe von Googles ADK und Gemini LLM an, und das deckt im Grunde all diese Details Zeile für Zeile 92. 15.8 Zusammenfassung und andere Dateien, Ordner: Vervollständigt dann im Grunde den gesamten Multi-Agenten-Code der Version drei Wie Sie sehen können, haben wir diese drei Agenten. Einer ist der Begrüßungsagent, einer ist der Tellt-Agent, einer ist der Host-Agent hier drüben. Wir haben eine App, die Befehlszeile basiert und in Version drei und Version zwei wiederverwendet wird in Version drei und Version zwei wiederverwendet Wir haben einen Kunden, also acht pro Kunde. Auch dies ist derselbe Client , den wir in Version zwei verwendet haben, und dann haben wir die Modelle, die wiederum alle dieselben Modelle sind, die aufgabenbezogenen Modelle, die anforderungsbezogenen Modelle, die JCN-RPC-bezogenen Modelle und die agentenbezogenen Auch diese werden ab Version zwei wieder verwendet. Und dann haben wir den Server , der ab Version zwei wieder verwendet wird. Das deutet im Grunde auf die Modularität des Codes hin , den wir hier aufbauen , dass wir viele Komponenten verwenden und nur die neuen Komponenten definieren, das sind und nur die neuen Komponenten definieren, das Host-Agent und die Orchestrierungslogik hier zusammen mit der Agentenerkennung Das ist neu in dieser Version, nämlich den Hilfsprogrammen für Discovery Dot P und Agent Underscore 93. 15.9 Code und API-Schlüssel einrichten: Lassen Sie uns nun über die Einrichtung dieses Codes und dessen Ausführung Das erste, was wir tun werden, ist, den Code über den Link in der Beschreibung auszuchecken, was Ihnen im Grunde helfen wird, diese gesamte Verzeichnisstruktur auf Ihrem lokalen Computer zu erhalten . Sobald Sie das getan haben, können Sie tatsächlich weitermachen und Ihre Umgebungsvariablen einrichten. Wir müssen also eine Datei mit dem Punkt ENV innerhalb dieses speziellen Ordners erstellen . Dies wird hinzugefügt, um Ignore zu erhalten, sodass Sie diese Datei nicht erhalten , wenn Sie den Code auschecken Sie können tatsächlich auf astodi.google.com gehen und sich über Ihr Gmail-Konto anmelden Dort erhalten Sie kostenlos einen Gemini-API-Schlüssel Es gibt also einige Bedingungen , die du überprüfen kannst, wenn du diesen Schlüssel verwendest, und im Grunde kannst du ihn sogar kostenlos für Testzwecke mit bestimmten Untergrenzen verwenden und indem du ihnen erlaubst deine Daten zu verwenden, während Und das macht es dann zur idealen Wahl für dieses Tutorial und das Experimentieren Ich bin auf astodigg.com. Und wenn ich diese Seite besuche, ich automatisch aufgefordert, hier einen API-Schlüssel zu erhalten Und ansonsten glaube ich, dass es hier auch einen Button gibt, um die APK zu bekommen. Ich werde einfach hier auf Get ApiKey klicken. Okay, es gibt also einen Code zum Testen der Gemini-API und hier gibt es eine Schaltfläche zum Erstellen eines APIKeys Lassen Sie mich also einfach den API-Schlüssel von hier aus verwenden. Es wird jetzt den API-Schlüssel für mich generieren , und wissen Sie, Sie sollten Ihren API-Schlüssel sicher verwenden und ihn nicht teilen oder in Code einbetten , den die Öffentlichkeit sehen kann. Ich werde das nach dem Tutorial deaktivieren. Im Moment kopiere ich es einfach von hier und lasse es sein, nachdem Sie den Code ausgecheckt haben , um die Umgebungsvariablen hinzuzufügen, gehen Sie in Ihr Code-Verzeichnis. Sobald Sie in Ihrem Codeverzeichnis sind, schreiben Sie einfach Touch Dot ENV Dadurch wird die ANV-Datei für Sie erstellt. Geben Sie auch Touch Dot Genore ein. Dadurch wird die Get Ignore-Datei für Sie erstellt. Gehen Sie nun zum VS-Code, gehen Sie zur DOT-ANV-Datei und fügen Sie hier Ihren Google-API-Schlüssel hinzu. Bitte beachten Sie, dass dies, wie bereits erwähnt, sicher gespeichert und keinem Code zugewiesen werden sollte gespeichert und keinem Code zugewiesen Ich werde diesen Schlüssel löschen, bevor ich dieses Video-Tutorial herausgebe Dann hast du die Get Ignore-Datei und du gibst einfach Punkt ENV ein und speicherst die Datei Jetzt ist Ihr Schlüssel vorhanden , damit Ihr Code verwendet werden kann und Sie werden ihn nicht auf Github oder ein anderes Code-Repository übertragen auf Github oder ein anderes Code-Repository Sobald du einen G-Push machst. Sobald Sie Ihre Umgebung eingerichtet haben, können Sie tatsächlich alle Agenten ausführen und Ihren Code testen , wie wir es bereits in der Demo gesehen haben , die wir zuvor gesehen haben. In Ordnung. Um diesen Code und alle Agenten auszuführen , können Sie zunächst eine virtuelle Umgebung für diesen Typ Python Three DN Dot NV erstellen diesen Typ Python Three DN Dot NV Dadurch wird ein NV-Ordner für Sie eingerichtet. Und Sie können diesen Ordner hier überprüfen. Aktivieren Sie dann Ihre virtuelle Umgebung, indem Sie source dot v SlashBNAS Activate eingeben source dot v SlashBNAS Also verwenden wir UV Ad und fügen danach all diese Pakete hinzu, um sie zu installieren Ich habe das bereits installiert, sodass Sie möglicherweise etwas Zeit benötigen , bis Sie das gesamte Setup abgeschlossen haben. Beachten Sie, dass Sie, sobald Sie den Code ausgecheckt und Ihre virtuelle Umgebung nach dem Erstellen aktiviert haben den Code ausgecheckt und Ihre virtuelle Umgebung nach dem Erstellen aktiviert Ihre virtuelle Umgebung nach dem , auch diesen Befehl eingeben können UV pip install pypject dot TM Dadurch werden alle Pakete in pypjectt TML five installiert in pypjectt Ich habe das schon wieder installiert, aber Sie können überprüfen, was diese aber Sie können überprüfen, was Also ASN, klicken Sie auf Fast API, Gold ADK, GNEI Alle diese Pakete werden also installiert, wenn Sie Andernfalls können Sie diese manuell installieren , indem Sie UV und alle Paketnamen eingeben , nachdem Sie Ihre virtuelle Umgebung initialisiert und aktiviert haben 94. 15.10 Ausführen der Agenten und des Clients: Sobald wir damit fertig sind, können wir mehrere Terminalfenster mit aktivierter virtueller Umgebung öffnen , wie wir es in der Demo getan haben, um alle Agenten zu starten Sie können diese tatsächlich farblich kennzeichnen indem Sie ein neues Fenster verwenden, und Sie können hier eine bestimmte Farbe auswählen , wenn Sie möchten, damit es versteht, welcher Agent in welchem Fenster ausgeführt wird sehr einfach versteht, welcher Agent in welchem Fenster ausgeführt wird. Ich zeige Ihnen hier nur die Befehle, die eingeben müssen, um diese Agenten auszuführen. Also werden wir zuerst den Tell Time Agent ausführen. Also geben wir im Grunde Python drei NM ein. Und dann schreiben wir den Dictary Structure Agents Punkt Tell Time Agent Wir geben den Host an, an den wir den Server binden wollen, also verwenden wir den lokalen Host, und dann geben wir den Port an , der für diesen bestimmten Agenten 10.000 sein wird, und dadurch wird im Grunde der Agent gestartet Nur für den Fall, dass auf diesem Port bereits etwas läuft, wird dieser Fehler angezeigt. Sie können also einen neuen Port wählen oder den Prozess beenden. Also habe ich den Server geschlossen, der bereits lief, und jetzt ist er auf dem lokalen Host 10.000 gestartet. Plus Control C, um vorerst zu beenden und den anderen Agenten zu starten. Als Nächstes werden wir also im Grunde auf 10.001 beginnen und den Begrüßungsagenten lokal hosten Also ändern wir einfach den Namen des Agenten hier drüben und ändern den Port auf 10.001 und das startet Sie müssen das am Laufen halten. Vorerst werde ich es beenden, um den Host-Agenten zu starten. Wir werden den Host-Agenten auf 10.002 starten. Wir geben den Einstiegspunkt PI als Einstiegspunkt und Moderator Beachten Sie nur, dass Sie hier nur Till Entry und nicht die PI-Erweiterung angeben müssen . Dadurch wird unser Host-Agent gestartet. Nochmals, wir werden das vorerst beenden. Und jetzt starten wir den Client. Um den Client zu starten, geben wir Python drei dmapptcmd Punkt CMD ein, was der Pfad zu unserem App-Skript ist Und dann haben wir dem Host-Agenten mitgeteilt , dass er auch als Client agieren soll Technisch gesehen ist es also eine unterhaltsame Übung, dass Sie alle drei Agenten hier ausprobieren können, 100021 und 10.000, wodurch der Client im Grunde genommen mit all diesen Agenten getrennt interagiert Aber wir wollen mit dem Host-Agenten zusammenarbeiten. Also geben wir hier 10.002 ein und drücken die Eingabetaste laufen Damit das funktioniert, müssen alle anderen drei Agenten in separaten Terminalfenstern Im Moment gebe ich CN Q ein, weil wir uns die Demo bereits zu Beginn angesehen haben und von hier aus beenden. Das ist alles für dieses spezielle Video, und es war für mich persönlich sehr aufregend, das zu testen, indem diese acht Agenten gebaut und sie dann separat ausgeführt habe und sie nahtlos über zwei Agenten mit denselben Client-Servern kommunizieren lassen nahtlos über zwei Agenten mit denselben Client-Servern kommunizieren , die wir zu Beginn verwendet haben. Das Interessante für mich ist also die Modularität des Codes und die Art und Weise, wie die verschiedenen Agenten tatsächlich nahtlos miteinander kommunizieren können . 95. ABSCHNITT 16 START – Einführung in das A2A Python SDK: Heute werden wir das Acht-Wege-Python-SDK verwenden , um achtway-konforme Agenten und Clients zu erstellen , um achtway-konforme Agenten und Wir werden einen Client und einen Agenten erstellen, die das Acht-Wege-Python-SDK verwenden , und der Agent wird Streaming und Multi-Turn-Konversationen unterstützen, und wir werden sehen, wie wir die Menge an Code reduzieren können, die wir schreiben müssen, um diese Acht-Wege-Clients und -Agenten mit dem Python-SDK zu erstellen, anstatt all die verschiedenen Funktionen für das EightwaypTocol Streaming und Multi-Turn-Konversationen unterstützen, und wir werden sehen, wie wir die Menge an Code reduzieren können, die wir schreiben müssen, um diese Acht-Wege-Clients und -Agenten mit dem Python-SDK zu erstellen diese Acht-Wege-Clients und , anstatt all die von Hand zu programmieren für das EightwaypTocol 96. 16.2 Was ist das A2A Python SDK?: Ordnung. Lassen Sie uns zunächst sehen, was das A two Python SDK ist. Es handelt sich um eine Python-Bibliothek , mit der Agent-Anwendungen als zwei Server ausgeführt Agent-Anwendungen als zwei Server die dem Agent-to-Agent-Protokoll folgen Was sie macht, ist, dass sie viele Typen, Klassendefinitionen, Funktionen usw. in das SDK einschließt , und Sie müssen nur die SDK-Klassen oder -Funktionen verwenden , um diese Funktionalität auf einer höheren Ebene zu implementieren , anstatt alles von Grund auf neu zu programmieren 97. 16.3 Demo 1 - Grundlegendes zu Single-Turn-A2A-Agent-Streaming-Task-Aktualisierungen: Bevor ich anfange, möchte ich Ihnen eine kurze Vorschau dessen zeigen , was wir heute erreichen werden Auf der rechten Seite sehen Sie einen blauen Terminalbildschirm, auf dem ich meinen ATA-Agenten starten werde, der mit dem A two a Python SDK erstellt wurde, und dieser wird sich wie üblich auf einem Zwei-Server ausstellen . Wir haben mit diesem Befehl begonnen, und das ist im Grunde ein Tell Time Agent , der ein von uns definiertes Tool verwendet, um die Systemzeit zurückzugeben. Wir sehen, dass es im Grunde auf dem lokalen Host-Port 10.002 gestartet wurde , und jetzt werde ich meinen 8-Wege-Client starten Auch hier haben wir das mit dem 8-TowayPython-SDK erstellt, und wir werden die Agenten-URL bereitstellen, die hier dieselbe ist Und das wird in diesem schwarzen Terminalfenster ausgeführt. Jetzt habe ich den Client gestartet, und wie Sie sehen, ist er im Grunde verbunden, und er kann erkennen, dass dieser spezielle Tellt-Agent jetzt Streaming unterstützt Wir verwenden also die SDK-Unterstützung, um Streaming bereitzustellen, und sie fordert uns im Grunde auf, unsere Anfrage unten einzugeben und den Vorgang zu beenden, um den Vorgang zu beenden Ordnung. Nehmen wir an, ich frage den Agenten, wie viel Uhr es ist? Der Agent antwortet mit mehreren Streaming-Updates. Lassen Sie uns nun aufschlüsseln, wie diese Streaming-Updates funktionieren. Dies ist also das erste Streaming-Update, und im Grunde heißt es, dass, Sie wissen schon, diese Aufgabe eingereicht wurde. Das ist also die erste Einreichung. Und das können Sie hier sehen, wo der Status einen Status hat, und dieser wurde im Grunde vom Agenten so eingestellt, dass er eingereicht wurde. Die ID ist eine eindeutige ID für diese JcnrpcrQuest. Die JCN RPC-Versionsnummer wird hier angezeigt. Dann haben Sie eine Kontext-ID, die im Grunde alle Nachrichten in einer Konversation gruppiert alle Nachrichten in einer Konversation Sie bleibt während Ihrer gesamten Interaktion mit dem Agenten gleich . Dann haben Sie den Verlauf und dieser führt das gesamte Nachrichtenprotokoll bis jetzt durch. Im Moment ist nur deine Frage da drüben, nämlich wie spät ist es. Dann haben wir die Sorte. Das kennzeichnet das Objekt im Grunde als Aufgabe, was bedeutet, dass es etwas ist, das der Agent erledigen muss. Und dann haben Sie den Status und den Status, und das bedeutet, dass der Agent Ihre Aufgabe erhalten hat und sie sich nun in der Warteschlange für die Bearbeitung befindet, weshalb sie hier eingereicht wurde Neben dieser ID haben Sie auch eine ID für den Kontext und für die Aufgabe. In Ordnung. Gehen wir jetzt zum nächsten Streaming-Update, und das ist im Grunde ein Status-Update durch den Agenten. Dies ist das erste Status-Update nachdem die Aufgabe eingereicht wurde. Und das hat im Grunde einen Statusknoten, der einen erweiterten Nachrichtenknoten hat, und das ist eine Zwischenantwort des Agenten würde der Agent sagen , dass ich daran arbeite und jetzt können wir sehen, dass die Nachricht einen Textteil hat, in dem steht , dass die aktuelle Uhrzeit nachgeschlagen wird. Das ist es, was der Agent Ihnen sagen möchte. Die Regel selbst ist auf Agent gesetzt, was im Grunde bedeutet, dass die Nachricht vom Agenten und nicht vom Benutzer stammt, und der Status ist auf „Funktioniert“ gesetzt, was bedeutet, dass der Agent daran arbeitet. Sie haben im Grunde eine Art Update , das heißt Status-Update, und der Status ist, dass der Agent nur sagen möchte , dass er an der Aufgabe arbeitet und die aktuelle Uhrzeit nachschlägt, der Status ist auf Funktioniert gesetzt und die Rolle ist auf Agent gesetzt. Sie können sehen, dass die IDs hier wiederverwendet wurden , um die Streaming-Updates miteinander zu verknüpfen Sie haben die JSON-RPC-ID, Sie haben die Kontext-ID und Sie haben die Aufgaben-ID Ordnung, jetzt haben wir das dritte Streaming-Update, und das erste war, dass die Aufgabe eingereicht wurde Das zweite war ein Status-Update, und das ist jetzt das nächste Status-Update. Das zweite Status-Update , das wir vom Agenten erhalten. Und Sie können wieder sehen, dass wir ein ähnliches Format haben. Die Art ist wieder ein Status-Update, und die Rolle ist Agent. Und der Text, den der Agent Ihnen sagen möchte, ist, dass er das Zeitergebnis verarbeitet und der Status immer noch funktioniert. Der Agent sendet Ihnen also im Grunde ein zweites Status-Update hier drüben und versucht damit zu sagen, dass er das Zeitergebnis verarbeitet. Ordnung. Schauen wir uns jetzt das nächste Streaming-Update an, und das ist im Grunde das Endergebnis-Artefakt Sie können also sehen, dass es sich bei der Art hier nicht um ein Status-Update handelt, sondern um ein Artefakt-Update Dies ist die endgültige Ausgabe des Agenten. Stellen Sie sich das also als das Ergebnis der Aufgabe vor. Der Name sagt Ihnen, wie die Ausgabe heißt. Hilfreich, wenn Agenten mehrere Dinge zurückgeben. Dies ist im Grunde das aktuelle Ergebnis. Die Beschreibung gibt im Grunde mehr Kontext. Es ist gut für UI-Labels. Dies ist also das Ergebnis einer Anfrage an Agenten und die Teile enthalten den tatsächlichen Inhalt. In diesem Fall der Text. Im Grunde ist der Text so, dass die aktuelle Zeit 13 406 ist und Sie hier eine Variable haben, die Last Chunk genannt wird, was wahr ist, was Ihnen sagt, dass dies der letzte Teil der Ausgabe ist der letzte Teil der Ausgabe Für diese spezielle Aufgabe kommt nichts mehr. Auch wenn das das letzte Ergebnis war , sendet uns der Agent immer noch ein letztes Streaming-Update zum Abschluss der Aufgabe Und das ist das letzte Status-Update, das wir im Grunde erhalten werden handelt sich also um ein Status-Update und der Status wurde auf „abgeschlossen“ gesetzt. Das sagt uns also nur, dass die Aufgabe abgeschlossen wurde und das Ergebnis bereits geliefert wurde, und final wurde auf true gesetzt, was uns im Grunde sagt, dass es sich um was uns im Grunde sagt, dass eine endgültige Statusmeldung handelt. Das war's also für diese spezielle Ausgabe. Wir haben gerade einen kompletten Austausch von Aufgaben zum Streamen von Spielzeug von Anfang bis Ende dekodiert einen kompletten Austausch von Aufgaben zum Streamen von Spielzeug von Anfang bis Ende Du weißt, was jeder einzelne Teil dieses Jason bedeutet, wie man ihn bei einem echten Kunden einsetzt 98. 16.4 Demo 2 - Grundlegendes zu mehrstufigen A2A Agent Streaming Tasks-Aktualisierungen: Stimmt, also werden wir dort nicht aufhören. Was wir weiterhin tun werden , ist, dies zu einer Interaktion mit mehreren Runden zu machen. In diesem speziellen Beispiel , das ich Ihnen gerade gegeben habe, gab es nur eine Frage, nämlich wie spät ist es? Und es gab eine Antwort mit mehreren Streaming-Updates. Aber jetzt stellen wir eine Anfrage, die uns die Uhrzeit, aber auch das Zeitformat mitteilen soll . Der Agent wird uns eine Antwort in Form von Streaming-Updates geben , was mehr Input von uns erfordert, und dann werden wir mit der zweiten Eingabe mit den Bedürfnissen des Agenten antworten der zweiten Eingabe mit den Bedürfnissen des Agenten und uns dann die letzten Streaming-Updates mit der endgültigen Antwort senden die letzten Streaming-Updates mit der . Lassen Sie uns das also ausprobieren. In Ordnung. Also werde ich es fragen. Sag mir die Uhrzeit und am wichtigsten, frag mich nach dem Zeitformat, bevor du mir die Uhrzeit mitteilst. Ordnung. Also, jetzt haben wir eine Menge Streaming-Updates, und das endet damit, dass der Agent mehr Input benötigt und Ihre Antwort. Lassen Sie uns also zunächst diese Streaming-Updates durchgehen. Ordnung, lassen Sie uns nun die Streaming-Updates verstehen , wenn der Agent mehr Eingaben benötigt. Das erste Update besteht also im Grunde darin , dass die Benutzeranfrage gesendet wird, und Sie können sehen, dass der Status übermittelt wurde Es ist dem, was wir im vorherigen Beispiel als erstes Streaming-Update gesehen haben, sehr ähnlich . Wir haben also die Idee für dieses spezielle Update-Ereignis. Wir haben JCN RPC Two Point Oh, was bestätigt, dass es sich um eine JCN RPC Two Point Oh Nachricht handelt eine JCN RPC Two Dann haben wir die Kontext-ID, eine eindeutige Kennung für diese Konversation, und es ist nützlich, den Überblick über den Austausch mehrerer Runden zu behalten Dann haben wir den Verlauf, im Grunde alle vorherigen Nachrichten enthält. In diesem Fall ist es nur die Benutzernachricht. Dann haben wir die Art, die im Grunde besagt, dass es sich um eine Nachricht handelt. Dann haben wir den Text, der der Inhalt der Nachricht ist, was der Benutzer gefragt hat, was die Anfrage hier ist. Dann haben wir die Rolle , die bestätigt, dass die Nachricht vom Benutzer und nicht vom Agenten stammt. Dann haben wir die Aufgaben-ID, die die eindeutige ID dieser speziellen Aufgabe ist. Dann haben wir die Art , die als Aufgaben festgelegt ist. Das ist also eine neue Aufgabe, die erstellt wird, und dann haben wir die Statusstatus übermittelt. Das sagt uns also , dass der Agent die Aufgabe erhalten hat und mit der Bearbeitung beginnt. Der aktuelle Status wurde übermittelt. Ordnung, das ist jetzt das zweite Streaming-Update, das wir haben, und hier wird es interessant, dass der Agent uns tatsächlich mitteilt , dass er mehr Informationen benötigt. Hier drüben können Sie sehen, dass Final auf True gesetzt wurde. Diese Nachricht schließt also diese Phase der Interaktion ab. Bei der Art handelt es sich um ein Status-Update. Status hier enthält das Hauptstatusobjekt , das eine Nachricht und einen Status enthält. Nachricht ist die Antwortnachricht des Agenten, also haben wir den Text , der im Grunde sagt: Könnten Sie bitte das Format angeben , in dem Sie die Uhrzeit haben möchten? Der Mitarbeiter befolgte also unsere Anweisung, uns vor der Antwort nach dem Zeitformat zu fragen. Dann haben wir die Rolle , die auf Agent gesetzt ist , was bestätigt, dass dies vom Agenten kommt. Der Status ist dieses Mal auf Eingabe erforderlich gesetzt, was wichtig ist, weil er uns sagt, dass der Client und der Agent ohne weitere Eingaben des Benutzers nicht fortfahren können . Schließlich haben wir die Reaktion des Kunden. Dies ist der Kunde, der Ihnen auf der Grundlage dieser Nachricht mitteilt, dass der Agent mehr Input benötigt Bitte geben Sie Ihre Antwort hier ein. Nachdem wir die Antwort hier gegeben haben, sendet der Kunde dieses Follow-up mit derselben Aufgaben-ID und Kontext-ID an den Agenten und setzt dieselbe Konversation fort. Ordnung. Ich habe das Format 12 OA angegeben, bitte hier drüben als Antwort und lassen Sie uns Eingabetaste drücken. Alles klar, damit wir jetzt wieder ein paar Streaming-Updates bekommen. Schauen wir uns also nach der Klärung an, wie der Agent die Zeitdaten streamt. Dies ist also das erste Streaming-Update , bei dem der Agent anfängt, nach der Uhrzeit zu suchen. Sie sehen also, dass der Status auf funktionierend gesetzt wurde. Es handelt sich um eine Statusaktualisierungsnachricht, und der Agent hat uns eine Nachricht geschickt, die besagt, dass und der Agent hat uns eine Nachricht geschickt, die besagt, dass er die aktuelle Uhrzeit sucht und die Rolle an den Agenten gesendet wurde. Sie können auch sehen, dass wir die vorherige Kontext-ID und die vorherige Aufgaben-ID übernommen haben , aber die ID für die Konversationsrunde wurde aktualisiert, da es sich um eine neue Anfrage handelt, also haben wir eine neue. Beim nächsten Streaming-Update der Agent die Verarbeitung fort. Es handelt sich also um eine weitere Statusmeldung, die anzeigt, dass der Agent die Uhrzeit abgerufen hat und nun das Ergebnis vorbereitet Dieses schrittweise Status-Update eignet sich im Grunde hervorragend für die Benutzeroberfläche in Echtzeit Der Status funktioniert immer noch und die endgültige Version wird immer noch fallen Dies ist also nicht das endgültige Status-Update. Der Agent befindet sich mitten in der Aufgabe. Ordnung. Also hier drüben haben wir das dritte Streaming-Update , bei dem der Agent die Antwort zurückgibt. Die Art ist also im Grunde auf Artefakt-Update eingestellt, was bedeutet, dass der Agent ein Ergebnis erstellt hat, ein fertiges Ergebnis. Der Name ist auf aktuelles Ergebnis gesetzt, und dies ist die Bezeichnung für diese Es gibt auch eine Beschreibung , die im Grunde ausführlicher ist und aus der hervorgeht, dass es sich um das Ergebnis der Anfrage an den Agenten Dann haben Sie den Text, der uns die aktuellen Zeiten mitteilt. Die aktuelle Uhrzeit ist 13:22 Uhr und das ist im richtigen Format, das wir angefordert haben, und der letzte Abschnitt ist auf true gesetzt, was dem Client im Grunde sagt, dass dies die letzten Ausgabedaten für diese Am Ende haben Sie das letzte Streaming-Update, bei dem der Agent die Aufgabe schließt Dies ist die letzte Zusammenfassung durch den Agenten. Der Status ist auf abgeschlossen gesetzt und der Client kann nun die Ladeindikatoren deaktivieren, die Ergebnisse anzeigen oder den Benutzer eine weitere Anfrage stellen lassen. Der Client ist wieder auf Status-Update gesetzt und final wurde auf true gesetzt, um all dem Rechnung zu tragen. Jetzt haben wir hier die Aufforderung zu einer weiteren Abfrage. 99. 16.5 Einrichten und Ausführen des Codes: Schauen wir uns nun an, wie dieser Code eingerichtet wird. Der erste Schritt wäre also, den Code von Github auszuchecken . Und dafür brauchst du den Link in der Beschreibung. Sobald Sie das getan haben, erhalten Sie einen Ordner wie diesen mit zwei Beispielen. Ich speichere diesen Ordner in einem Zweier-Ordner in meinem Benutzerverzeichnis. Sie können es speichern, wo immer Sie möchten. Aber dann müssen Sie in den Ordner 82 a samples wechseln und dann zur Version 582, einem SDK-Ordner darin Wechseln wir also in dieses Verzeichnis. Sobald Sie sich in diesem Verzeichnis befinden, wir als Erstes überprüfen wir als Erstes unsere Python-Version. Wir benötigen Python 3.13 oder höher. Also lass uns das jetzt machen. Also gebe ich Python Three Dash Version ein und drücke Enter. Und ich habe Python 3.13 0.2 installiert, das ist also alles gut für mein System Falls Sie Python nicht installiert haben oder eine ältere Version installiert haben, besuchen Sie bitte die offizielle Website von Python. Auf der Download-Seite findest du den Download für ein Installationsprogramm, das diesen ganz einfach für dich installiert. Wir haben auch ein Video dazu, falls du dir dieses spezielle Video ansehen möchtest. Als Nächstes müssen Sie Ihr Projekt also tatsächlich mit UV einrichten . Also werde ich UV int Python, Python 3.13, verwenden und es generiert Ihre Pi-Projekt-Punkt-TML-Datei und den NV-Ordner mit dem angegebenen Python-Interpreter , der In Ordnung. Also jetzt haben wir das initialisiert. Wir können jetzt tatsächlich unsere Verzeichnisstruktur überprüfen. Wir haben alle erforderlichen Dateien wie die Pi-Projekt-TML-Datei Wir haben jetzt die Python-Versionsdatei. Wir haben den Ordner für die virtuelle VENV-Umgebung nicht, also müssen wir ihn anscheinend erstellen, indem wir UV VENV eingeben und die Eingabetaste drücken Und jetzt haben wir den Virtual Management-Ordner hier eingerichtet. Lassen Sie uns nun unsere virtuelle Umgebung aktivieren. Also geben wir os dot nv slash Bin slash Activate Und jetzt haben wir die virtuelle Umgebung hier aktiviert. Und jetzt haben wir die virtuelle Umgebung hier aktiviert. Als Nächstes werden wir alle Pakete einrichten , die wir benötigen. Also geben wir UV ad und den Namen der Pakete ein , die wir installieren möchten. Wir haben also ein SDK für das Python-SDK für das 80-Protokoll, das wir jetzt verwenden das in dieser speziellen Version neu ist. Dann haben wir Lang Chain Lang Graph, Google GNI, Tpx Python Dot Wir haben das Anhain Google GNI-Paket, UVCon für den Server, und dann haben wir auch Click and Rich UVCon für den Server, und dann haben wir auch Click and . Drücken wir die Eingabetaste Es wird einen Moment dauern, bis alle Pakete installiert sind. Sobald der Vorgang abgeschlossen ist, wird die Aufforderung wieder angezeigt. Was wir jetzt tun können, ist, UV Sync All Groups zu schreiben. Dies hilft uns im Grunde, alle fehlenden Pakete zu installieren, falls vorhanden, und Sie können dies verwenden, wenn Sie Ihrer Pi-Projektdatei ein neues Paket hinzufügen. Da wir bereits alles installiert haben , ist dies sofort abgeschlossen. Jetzt müssen wir eine ANV-Datei erstellen um unseren Google ApiKey we doTuchtenV zu hosten . Dann können wir diese im Code öffnen, indem wir den Codepunkt ANV eingeben Dann müssen Sie Ihren Google-API-Schlüssel hier hinzufügen Bitte denken Sie daran, diesen Schlüssel mit niemandem zu teilen oder ihn in ein Github-Repo zu übertragen , da dies ein privater Schlüssel sein soll und dieser aus diesem Grund zu Git Ignore hinzugefügt wird zu Git Ignore hinzugefügt wird Lass uns unsere Git Ignore-Datei überprüfen. Also habe ich all diese Dateien hinzugefügt, um Igno zu bekommen , sodass sie nicht festgeschrieben werden, und jeder, der diesen Code ausführen möchte erstellt diese Dateien im Grunde mit den Befehlen , die wir gerade gesehen Um den Google-API-Schlüssel zu erhalten, folgen Sie bitte diesen Schritten Sie können tatsächlich zu astudiotggle.com gehen und sich über Ihr Gmail-Konto anmelden erhalten Sie kostenlos einen Gemini APIKey Es gibt also einige Bedingungen , die Sie überprüfen können, wenn Sie diesen Schlüssel verwenden, und im Grunde können Sie ihn sogar kostenlos zu Testzwecken mit bestimmten Untergrenzen verwenden Testzwecken mit bestimmten Untergrenzen und indem Sie ihnen erlauben, Ihre Daten zu verwenden können Sie ihn sogar kostenlos zu Testzwecken mit bestimmten Untergrenzen verwenden und indem Sie ihnen erlauben, Ihre Daten zu verwenden , während sie ihren Modus trainieren. Das macht ihn dann zu unserer idealen Wahl für dieses Tutorial und das Experimentieren Ich bin auf astudihol.com, und wenn ich diese Seite besuche, ich automatisch aufgefordert, hier einen APIKey zu bekommen. Ansonsten glaube ich, dass es hier auch eine Schaltfläche gibt, um die APK herunterzuladen Ich werde einfach hier auf Get ApiKey klicken. Okay, es gibt also einen Code zum Testen der Gemini-API und hier gibt es eine Schaltfläche zum Erstellen eines APIKeys Lassen Sie mich also einfach den API-Schlüssel von hier aus verwenden. Es wird jetzt den API-Schlüssel für mich generieren , und wissen Sie, Sie sollten Ihren API-Schlüssel sicher verwenden und ihn nicht teilen oder in Code einbetten , den die Öffentlichkeit sehen kann. Ich werde das nach dem Tutorial deaktivieren. Im Moment werde ich es einfach von hier kopieren und sichtbar machen. Um den API-Schlüssel erneut hinzuzufügen, öffnen Sie die DOT-ANV-Datei im VS-Code und fügen Sie sie hier wie folgt hinzu Damit schließen Sie im Grunde die Einrichtung dieses Codes ab. Lassen Sie uns nun sehen, wie wir diesen Code ausführen können. Zuerst werden wir den Server betreiben. Dafür geben wir UV run Python drei dm agents dot Tellt Agent Wir geben den Host als lokalen Host und den Port als 10.002 an. Drücken wir die Eingabetaste Antwort: Jetzt läuft unser Server auf dem lokalen Host 10.002. In einem neuen Tab werde ich wieder die virtuelle Umgebung aufrufen und dann den Client hier ausführen Ordnung, jetzt läuft mein Server in diesem Tab hier drüben, sodass ich den Client hier ausführen kann. Dafür gebe ich UV run Python three dm client dot client ein, was für das Verzeichnis und die Python-Datei ist, und dann gebe ich hier die Agenten-URL an, die 127 Punkt Punkt eins ist, was für den lokalen Host ist. Wir müssen den lokalen Host explizit angeben , da der lokale Host manchmal nicht korrekt aufgelöst wird. Und dann gebe ich die Portnummer an, die 10.002 ist, und drücke dann die Eingabetaste Wir haben die Demo bereits im Detail gesehen, daher werde ich sie hier nicht testen Dies sollte Ihnen nur zeigen, wie Sie den Agenten und den Server starten , gefolgt vom Client. 100. 16.6 Code-Schrittdurchführung: A2A-Client: Lassen Sie uns nun den Code durchgehen. Beginnen wir mit der Client-PY-Datei, die unser A für einen Kunden ist. Diese Datei definiert also einen dynamischen Async-Client, der auf dem offiziellen 80-Python-SDK basiert der auf dem offiziellen 80-Python-SDK Dadurch können Agentenfunktionen erkannt werden, unabhängig davon, ob es sich um Streaming handelt oder nicht Es kann Abfragen in einer Schleife senden. Es kann Single-Turn- und Multi-Turn-Konversationen verarbeiten und automatisch zwischen Streaming-Flows und Nicht-Streaming-Flows wechseln. Also nur ein kleiner Vorbehalt hier, dass ich den Streaming-Flow während meiner Demo hier getestet habe Und während der Entwicklung ist der Non-Streaming-Flow tatsächlich als einfachere Alternative für Agenten enthalten , die Streaming nicht unterstützen, aber das habe ich nicht getestet Nur für den Fall, dass Sie Probleme haben, stellen Sie bitte Fragen und ich helfe Ihnen gerne weiter. Dann haben wir Importe. Wir haben also Async IO, das asynchrone Programmierung und IO-Operationen unterstützt Wir haben JCN, um das Kodieren und Dekodieren von JCN-Daten zu ermöglichen. Wir haben Traceback , das im Grunde genommen detaillierte Tracebacks ausgibt UUID wird grundsätzlich importiert , um eindeutige IDs zu generieren. Dann haben wir eine Typisierung, die es Funktionsargumenten und Variablen ermöglicht , jeden Typ zu akzeptieren Wir haben click, was im Grunde eine Bibliothek zum Erstellen von Befehlszeilenschnittstellen ist . Auf dieser Grundlage können Sie die Optionen für Ihren Agenten und Ihre URL angeben, und auf der Agentenseite können Sie tatsächlich Ihren Host und Port angeben. Dann haben wir TDPX, den asynchronen HDDP-Client zum Senden von Wir haben Rich, das für erweiterte Druckfunktionen zur Unterstützung von Farben und Formatierungen verwendet wird erweiterte Druckfunktionen zur , und dann haben wir die Rich-Syntax, die JSON-Ausgabe im Begriff hervorgehoben wird Jetzt importieren wir den offiziellen A-Two-SDK-Client und die zugehörigen Typen. Wir haben ab 82 beim Kunden, wir importieren die A zwei als Client und ab acht Punkttypen importieren wir all diese verschiedenen Typen. Wenn Sie sich aus den vorherigen Videos erinnern, haben wir all diese Typen tatsächlich selbst definiert, aber jetzt können wir tatsächlich das Python-SDK für zwei verwenden, das hier durch 80 dargestellt wird, und dann all diese Typen abrufen ohne sie explizit codieren zu müssen. In ähnlicher Weise haben wir tatsächlich ein A zwei als Client definiert, aber jetzt können wir diesen Client direkt aus unserem 80-Python-SDK abrufen . Schauen wir uns also im Folgenden an, wie wir dieses SDK verwenden. Wir haben also zunächst einen Helfer, um eine Nachrichtennutzlast im erwarteten Acht-Wege-Format zu erstellen eine Nachrichtennutzlast im erwarteten Acht-Wege-Format zu Das ist also nur eine einfache Funktion, um eine Wörterbuch-Payload zu erstellen , die dem Acht-Wege-Nachrichtenformat entspricht Sie haben also die Botschaft , die eine Rolle hat, die Teile hat und die Teile haben eine Art von Und was den Inhalt betrifft, so hat es in diesem speziellen Fall im Grunde den Text weil wir hier nur Textnachrichten verwenden. Dann haben wir eine Nachrichten-ID, die eine eindeutige Nachrichten-ID für die Nachverfolgung ist, und dann haben wir eine Aufgaben-ID und eine Kontext-ID. Diese sind nur enthalten , wenn sie bereitgestellt werden. Dann haben wir den nächsten Helfer, darin besteht , HasN-Objekte mithilfe von Syntax-Culling hübsch auszudrucken , und das macht es einfacher zu verstehen, was gedruckt wurde Wir verwenden dafür die Rich-Bibliothek und die Rich-Dot-Syntax Es wird also eine formatierte und farbig hervorgehobene Ansicht der Antwort angezeigt und farbig hervorgehobene Ansicht der Antwort Wir drucken zuerst den Titel. Gründen der Übersichtlichkeit ist dies also ein Abschnittstitel , der hier als Eingabe bereitgestellt wird. Dann prüfen wir, ob die Antwort das Attribut root hat, das uns sagt, ob die Antwort vom SDK umschlossen wurde. Ist dies der Fall, greifen wir auf die Daten von der Antwortwurzel aus zu, andernfalls greifen wir direkt über die Antwort darauf zu. Nachdem wir die JCN-Daten erhalten haben, konvertieren wir sie hier aus einem Wörterbuch in eine hübsche JCN-Zeichenfolge hier aus Dann wenden wir die Syntaxhervorhebung an und drucken sie dann im Grunde mit Farbe auf dem Bildschirm Wenn es eine Ausnahme gibt, kümmern wir uns hier darum. Als Nächstes haben wir das Handle Non-Streaming-Flow. Das ist also der Fall , wenn unser Agent Streaming nicht unterstützt. Dies ermöglicht also das Senden einer Nachricht, die nicht gestreamt wird und optional das Follow-up falls der Agent weitere Daten benötigt. Also stellen wir diese Funktion zusammen mit dem 80-Client und dem Text , den wir senden möchten, zur Verfügung. Also verwenden wir zuerst die Funktion „ Nachrichtennutzlast erstellen mit dem Text, um diese Nachrichtennutzlast zu erstellen Wir entpacken es in Nachrichtensendeparameter und geben diese als Parameter an, um eine Nachrichtenanfrage zu senden und geben diese als Parameter an, um eine Und das ist im Grunde unser Anforderungsobjekt. Dann verwenden wir den bereitgestellten Client , um die Nachricht mit der Anfrage zu senden , und warten auf das Ergebnis. Sobald wir das Ergebnis haben, drucken wir die JSON-Antwort, bei der die Antwort des Agenten handelt, mit unserem obigen Helper. Als Nächstes prüfen wir also, ob der Agent mehr Eingaben benötigt. Also fragen wir den Benutzer erneut, wenn das der Fall ist. Wenn wir also eine erfolgreiche Antwort haben, werden wir die Aufgabe daraus extrahieren, und wir haben in unserer JSNrResponse im Streaming-Update gesehen , dass die ein Ergebnisobjekt enthält Wir erhalten also im Grunde dieses Ergebnisobjekt . Wenn die Statusvariable innerhalb des Statusobjekts mit der erforderlichen Eingabe übereinstimmt, müssen wir eine Folgefrage stellen. Wir werden dann sagen, dass der Agent weitere Eingaben benötigt , und Sie stellen die Lösung bereit und wir warten hier auf die Eingabe. Sobald wir die Eingabe erhalten haben, erstellen wir erneut eine Nachrichten-Payload diesmal mit der Nachverfolgung, und wir geben eine Aufgaben-ID und eine Kontext-ID für die Aufgabe an, um die Konversation fortzusetzen Wir erstellen diese Nachrichtennutzlast und stellen sie den Nachrichtenparametern zur Anschließend stellen wir sie als Parameter für das Senden einer Nachrichtenanfrage bereit Das ähnelt dem, was wir oben gemacht haben, aber hier geben wir eine Aufgaben-ID und eine Kontext-ID Um die Kontinuität aufrechtzuerhalten, da es sich um eine Folgefrage und nicht um eine neue Frage handelt. Dann haben wir eine Folgeantwort. Dies erreichen wir, indem wir die Funktion zum Senden von Nachrichten des Clients verwenden und die Folgeanfrage hier senden . Sobald wir die Folgeantwort erhalten haben, drucken wir sie mit unserem Helfer als Folgeantwort aus. Jetzt haben wir Underscoe-Streaming übernommen, das Streaming-Nachrichten verarbeitet und rekursiv weitermacht, wenn mehr Eingaben erforderlich Hier stellen wir ihm den 80-Client und die Textzeichenfolge zur Verfügung. Zusätzlich stellen wir eine optionale Aufgaben-ID und eine optionale Kontext-ID bereit, Zusätzlich stellen wir eine optionale Aufgaben-ID und eine optionale Kontext-ID sodass wir rekursiv fortfahren können , falls weitere Also auch das ist dem, was wir oben gesehen haben, sehr ähnlich. Wir erstellen zunächst die Nachrichtennutzlast mit dem Text, der Aufgaben-ID und der Kontext-ID Anschließend erstellen wir die Sendeparameter für die Nachricht und stellen diese als Parameter für die Anfrage zum Senden von Streaming-Nachrichten bereit, die über das EtsDkt , unser Anforderungsobjekt, verfügbar ist Dann verfolgen wir die aktuelle Aufgabe und die Kontext-ID, um Multi-Turn zu unterstützen Dann verarbeiten wir jedes gestreamte Update. Wir werden den Client verwenden, um die Nachricht mit Streaming zu senden, und wir stellen das Anforderungsobjekt bereit, das wir gerade erstellt haben. Dadurch werden mehrere Updates vom Agenten zurückgesendet Für jedes Update in der Antwort drucken wir also zunächst die JSON-Antwort mit dem Update als Streaming-Update aus. Dann extrahieren wir den Kontext oder die Aufgabe aus dem aktuellen Update. Also werden wir prüfen, ob dies das Attribut Ergebnis hat. Wenn dies das Attributergebnis hat, suchen wir nach einer Kontext-ID und nach dem Status. Wenn es die Kontext-ID hat, speichern wir diese als neueste Kontext-ID, und wenn es den Status hat, prüfen wir, ob der Status „ Eingabe erforderlich“ entspricht. Wenn das wahr ist, erhalten wir die neueste Aufgaben-ID, die hier die Aufgaben-ID ist , und setzen die Eingabe erforderlich auf true. Und im Folgenden behandeln wir die erforderlichen Eingaben. Wenn also Eingaben erforderlich sind und wir die neueste Aufgaben-ID und die Kontext-ID haben , geben wir dem Benutzer eine Folgeaufforderung , dass der Agent weitere Eingaben benötigt. Bitte geben Sie hier Ihre Antwort ein, und wir rufen dann rekursiv Handle-Streaming mit der neuesten Aufgaben-ID und der Kontext-ID Jetzt sehen wir also, dass wir diese Konversation mit dieser Aufgaben-ID und Kontext-ID fortsetzen können diese Konversation mit dieser Aufgaben-ID und Kontext-ID , nachdem wir alle Updates hier erhalten haben , falls wir weitere Eingaben benötigen Das ist die Verwendung dieser beiden Variablen hier. Ordnung, jetzt haben wir die Schleife um den Agenten wiederholt abzufragen Das ist eine interaktive Schleife. Wir drucken zuerst die Anweisungen für den Benutzer hier aus, um die Abfrage einzugeben, oder geben Sie exit ein, um den Vorgang zu beenden. Und obwohl das stimmt, warten wir, bis der Benutzer die Abfrage eingibt, und wenn die Abfrage gleich Exit oder Quit ist, verlassen wir die Schleife. Wenn nicht, prüfen wir, ob unser Agent Streaming unterstützt. Wenn ja, bearbeiten wir diese Anfrage mit der Handle-Streaming-Funktion. Wenn nicht, behandeln wir sie mit einer Non-Streaming-Funktionalität. Für die Handle-Streaming-Funktionalität haben wir zunächst keine Kontext-ID oder Aufgaben-ID, sodass sie leer Wenn sie die Konversation in mehreren Runden fortsetzt, verwendet sie die Client-ID und die Task-ID , wie sie in der Antwort zurückgegeben wurden. Jetzt haben wir den Befehlszeilen-Einstiegspunkt für den Client, also verwenden wir ClickOHE, um lediglich eine Option für die Eingabe der Agenten-URL bereitzustellen, und wir geben die Standard-URL wie hier an. Und dann führt die Hauptfunktion einfach die ASIC-Event-Schleife mit der angegebenen Und das ist der ASN-Runner , den wir oben ausführen. Es richtet den Client die Agentenkarte ein und startet den Loop Also teilen wir dem Benutzer mit , dass wir die Verbindung zu dem jeweiligen Agenten hier aufbauen. Dann verwenden wir den ASN-Kontext , um die Sitzung offen zu halten. Dann erstellen wir den ATA-Client mithilfe der Sitzungs- und der Agenten-URL-Objekte Wir legen ein Timeout für lange Operationen fest, die passieren können. Dann verwenden wir Session Dot Get, um den bekannten Agent-Punkt JCNURL aufzurufen, um die Agent-Metadaten abzurufen Und wir erhalten daraus die Agentenkarte, indem wir die Struktur dieser Metadaten validieren Wir überprüfen, ob der Agent Streaming unterstützt oder nicht, indem wir seine Fähigkeiten überprüfen dieser Grundlage entscheiden wir uns Auf dieser Grundlage entscheiden wir uns dann für einen der beiden Datenflüsse, wie wir oben gesehen haben Dann geben wir aus, dass wir verbunden sind und ob Streaming unterstützt wird oder nicht, und dann treten wir in die interaktive Schleife ein, die im Grunde das ist, was wir oben gesehen haben. Wir behandeln hier Ausnahmen, indem wir den Fehler-Trace und die Meldung „Failed to connect or run“ hier drucken . Schließlich haben wir die Hauptfunktion, die ausgeführt wird , wenn wir sie als Skript ausführen. In Ordnung. Also das ist die Client-P-Datei in unserem Kundenordner. 101. 16.7 Code-Schrittdurchführung: Agent: Jetzt gehen wir zum Agentencode. Schauen wir uns zunächst Agent Dot Py an. Diese Datei definiert den Tell Time Agent. Es verwendet den Lang Chain React Agent mit Gemini über Lang Chain Google Gen AI und unterstützt Streaming-Antworten Es definiert jetzt ein einfaches Tool namens GT und verarbeitet strukturierte Antworten mit Unterstützung für Multi-Turn-Logik Wir haben also zuerst die grundlegenden Importe. Sie können sich die Befehle hier ansehen, um zu verstehen, wofür diese Importe gedacht sind. Ich werde mit dem nächsten Schritt fortfahren, dem Einrichten der Protokollierung. Wir haben auch einen einfachen Speicher für den Graphstatus von Nan Graph. Dann haben wir das Tool Get Time definiert. Jetzt verwenden wir den Decorator in der Geschwindigkeit von Tool hier, um es als Tool zu spezifizieren, und wir geben die Dokumentzeichenfolge an, die besagt, dass es die aktuelle Systemzeit in diesem speziellen Format zurückgibt , und dann geben wir hier die aktuelle Uhrzeit zurück Dann haben wir das Antwortformatschema , das bestätigt, was der Agent zurückgibt Dies gilt nur für strukturierte Endausgaben am Ende nur einmal zurückgegeben Sie sehen den Status also einfach als abgeschlossene Eingabe erforderlich oder Fehler. Die Zwischenmeldungen zum Streaming-Status hier sind nicht enthalten, da sie nur für die eine Antwort gelten, die wir am Ende senden. Und wir haben auch die Nachricht, bei der es sich eine Zeichenfolge handelt, die dem Benutzer angezeigt wird. Dies ist die Klasse des Antwortformats, die der Agent unter Verwendung dieses pedantischen Modells am Ende des Streams explizit zurückgibt unter Verwendung dieses pedantischen Modells am Ende des Streams Dann haben wir die Tell Time Agent Klassendefinition. Dies ist ein Angin-React-Agent , der zeitbezogene Anfragen beantwortet Es verwendet nur die Antwort des Tools Get Time Now auf einem strukturierten Format basiert und auf dem Gemini-Flash-Modell Hier sind die Anweisungen, die wir dem Agenten LLM geben. Sie sind ein spezialisierter Assistent für zeitbezogene Anfragen. Verwenden Sie das Tool GT now , wenn der Benutzer nach der aktuellen Uhrzeit fragt , um die Uhrzeit im HH-MSS-Format Und konvertieren Sie diese Zeit selbst in das vom Benutzer angeforderte Format , das dürfen Sie tun Das wurde ausdrücklich erwähnt, weil ich in einigen Tests gesehen habe , dass der Mitarbeiter gesagt hat, ich die Uhrzeit nicht in ein bestimmtes Format umwandeln darf . Ich habe das als Aussage hier in der Systemanleitung erwähnt . Schließlich haben wir die Anweisungen zum Antwortformat. Dies sind also die Richtlinien zur Formatierung von Antworten, Dies sind also die Richtlinien zur Formatierung von Antworten die vom Agenten erwartet werden. Verwenden Sie also „abgeschlossen“, wenn die Aufgabe erledigt ist, Eingabe erforderlich“, wenn eine Klärung erforderlich ist, und „Fehler“, wenn etwas fehlschlägt Fügen Sie immer eine Nachricht für den Benutzer hinzu. Dann haben wir also den Konstruktor. Dadurch wird das Gemini LLM-Modell initialisiert. Dazu verwenden wir die generative KI von Google und weisen diese dem autodidaktischen Modell zu Dies ist mit dem Google Gene Import von Lang Chin verfügbar , den wir oben durchgeführt haben, und Nanchan Dann haben wir die Tools, wir haben das Get Time Now-Tool hier bereitgestellt . Dies ist im Grunde die Registrierung der verfügbaren Tools für diesen Agenten. Dann erstellen wir mithilfe des Lang-Graphen ein vollständiges Agentendiagramm im Reaktionsstil. Wir haben also einen Create React Agent. Wir haben das Modell, die Tools, den Speicher, die Systemanweisungen und das Antwortformat sowie die Anweisungen zum Antwortformat bereitgestellt die Tools, den Speicher, die Systemanweisungen und das Antwortformat . Ordnung. Als Nächstes haben wir die Stream-Funktion. Die Stream-Methode streamt also Teilupdates vom Agenten in Echtzeit. Sie gibt Schritt für Schritt Antworten zurück, während der Agent arbeitet, anstatt auf alles gleichzeitig zu warten. Also definieren wir hier eine asynchrone Funktion, die wie eine Wörterbuchschleife ein I-Triple zurückgibt Jedes Wörterbuch ist ein Teilupdate vom Agenten. Wir stellen ihm die Zeichenkettenabfrage und die Sitzungs-ID zur Verfügung. Diese Funktion wird also verwendet, wenn ein Benutzer eine Nachricht an den Agenten sendet. Anstatt auf eine einzige Antwort zu warten, gibt sie uns Updates, sobald sie geschehen, was eine iterierbare Anzahl von Wörterbüchern sein wird Query ist die Frage oder der Befehl des Benutzers. Beispiel, wie viel Uhr ist es? Sitzungs-ID ist eine eindeutige ID für Interaktion dieses Benutzers, um den Kontext aufrechtzuerhalten. Dies führt zu Aktualisierungen, z. B. zum Nachschlagen von Zeit, Verarbeitung und dem Endergebnis. Als Erstes müssen wir eine Konfiguration einrichten, die diese Anfrage mit einer Sitzung verknüpft. Langrap benötigt also eine Sitzung oder eine Thread-ID, um diese Konversation zu verfolgen Und was wir hier tun, ist, dass wir diese eindeutige ID angeben, um eine Benutzerkonversation von einer anderen zu trennen, und wir erzeugen einen Konflikt Dann ist das das Eingabeformat. Langrap erwartet eine Liste von Nachrichten. Jede Nachricht ist ein Tupel mit der Rolle und der Abfrage selbst Hier senden wir also nur eine Nachricht vom Benutzer, die hier so bereitgestellt wird, und das ist die Eingabevariable , die wir hier haben. Dann fangen wir an, die Denkschritte des Agenten mithilfe von Angrap zu streamen Denkschritte des Agenten mithilfe von Angrap Jeder Punkt hier ist also ein Schritt in der Argumentation, wie eine Also stellen wir die Eingaben und die Konfiguration für Self Dot Graph Dot Stream zur und wir stellen einen Stream-Modus mit Werten zur Verfügung , der im Grunde darin besteht nur nützliche Ergebnisse zu streamen Jetzt bekommen wir alle Nachrichten von item. Dann erhalten wir die neueste Nachricht aus der Liste aller Nachrichten. Der Agent könnte während des Nachdenkens mehrere Nachrichten hinzufügen , sodass wir uns nur für den Status um die letzte kümmern, und genau das bekommen wir hier. Wenn es sich bei der Nachricht um eine KI-Nachricht handelt, handelt es sich um ein langatmiges Konzept, was im Grunde bedeutet, dass, wenn die Nachricht von der KI stammt und die Nutzung von Tools beinhaltet, der Agent im Begriff ist ein Tool wie Get Time Now aufzurufen. Wir geben also diese spezielle Antwort oder ein Update, was bedeutet, dass wir dieses Ergebnis sofort senden, bevor wir fortfahren. Jede abgeschlossene Aufgabe wird also auf „Falsch“ gesetzt, „ Benutzereingabe erforderlich“ ist auf „Falsch“ gesetzt und der Inhalt sucht nach der aktuellen Uhrzeit. Dies möchten wir auf der Benutzeroberfläche oder der Befehlszeilenschnittstelle anzeigen . Wenn die Nachricht von einem Tool wie get time now stammt, was bedeutet, dass der Agent gerade das Ergebnis erhalten hat und daran arbeitet, es zu formatieren, geben wir an , dass die Aufgabe immer noch nicht abgeschlossen ist. Wir benötigen keine Benutzereingabe, aber jetzt teilen wir dem Benutzer , dass wir die Zeitergebnisse verarbeiten. Wir haben also das Ergebnis und wir verarbeiten es gerade. Sobald der Stream endet, gibt es keine Teilschritte mehr, dann senden wir das Endergebnis. Das könnte also eine abgeschlossene Nachricht oder eine Folgefrage sein. Wir sagen also Yield Self Dot Final Underscor antwortet, und wir geben hier den Konflikt an, das ist die Funktion, die hier definiert ist Also gut. Schauen wir uns jetzt die endgültige Antwortfunktion an. Diese Methode liefert also nach dem Ende des Streams ein endgültiges strukturiertes Ergebnis. Es liest die endgültige Entscheidung des Agenten und erstellt ein Wörterbuch mit Markierungen. Nachdem alle Streaming-Nachrichten fertig sind, überprüft diese Funktion, was der Agent letztendlich entschieden hat. Sie verwendet den Konflikt, um die gespeicherte Antwort zu finden , die als strukturierte Antwort bezeichnet wird. Was wir tun, ist, dass wir den internen Speicherstatus aus der Langarp-Sitzung hier abrufen den internen Speicherstatus aus . Dann ziehen wir das strukturierte Ergebnis heraus. Es sollte dem Schema des Antwortformats entsprechen. Wir verwenden Stat, Punktwerte (Punkt). Strukturierte Antwort abrufen. Wenn die strukturierte Antwort nun gültig ist, das heißt, sie entspricht dem Schema des Antwortformats, dann überprüfen wir den darin enthaltenen Status , also ob sie abgeschlossen ist. Wenn sie abgeschlossen ist, markieren wir diese Aufgabe als erledigt. Wir kennzeichnen, dass keine weiteren Benutzereingaben erforderlich sind, und wir stellen den Inhalt bereit, der die Botschaft des strukturierten Endergebnisses darstellt Abgesehen von der Eingabe als abgeschlossen kann uns der Mitarbeiter die erforderlichen oder fehlerhaften Eingaben geben In diesem speziellen Fall markieren wir die Aufgabe als noch nicht erledigt. Wir benötigen Benutzereingaben. Stimmt. Wir bitten den Benutzer um eine Klarstellung, also benötigen wir eine Benutzereingabe, die auf true gesetzt ist, und der Inhalt ist wieder diese Nachricht aus der strukturierten Antwort. Und nur für den Fall, dass die Antwort fehlerhaft war oder fehlt, behandeln wir das elegant, indem wir die strukturierte Antwort hier drucken . In allen anderen Fällen geben wir zurück, dass die Aufgabe noch nicht abgeschlossen ist Wir benötigen weitere Benutzereingaben und es gibt einen Standardinhalt , der im Grunde besagt, dass wir Ihre Anfrage derzeit nicht bearbeiten können. Bitte versuchen Sie es erneut. Und hier deklarieren wir vorerst die Formate, die dieser Agent für Eingabe und Ausgabe verarbeiten kann Wir verwenden nur Klartext. Damit sind die endgültigen Antwortnachrichten, die hier enden, sowie die unterstützten Inhaltstypen abgeschlossen . 102. 16.8 Code-Walkthrough-AgentExecutor: Okay. Schauen wir uns die vom Agenten ausgeführte Punkt-PY-Datei an. Diese Datei definiert also den Executor, der als Brücke zwischen dem Acht-Twos-Server und dem zugrundeliegenden Tellt-Agenten fungiert zwischen dem Acht-Twos-Server und dem zugrundeliegenden Tellt-Agenten Sie ähnelt dem Aufgabenmanager , den wir bereits gesehen haben, und er hört sich Aufgaben an und leitet sie an den Agenten weiter. Anschließend werden die Aufgabenaktualisierungen und Ergebnisse über die Ereigniswarteschlange zurückgesendet und Wir importieren die Tellt-Agent-Klasse aus demselben Verzeichnis Dann importieren wir die Basisklassen aus dem 82-HDK, um das Agentenverhalten zu definieren Wir haben also die Ausführung von 80 Server-Agenten und importieren den Agent-Executor und den Der Agent-Executor ist die Basisklasse für die Definition der Logik des Agenten-Task-Executors Und der Anforderungskontext enthält Informationen über die eingehende Benutzeranfrage und den Dann importieren wir das Ereignis Q, das verwendet wird, um Updates , Status oder Ergebnisse an den IOS-Server zurückzuschicken Aufgaben, Status oder Ergebnisse an den IOS-Server zurückzuschicken. Dann importieren wir die verschiedenen Typen. Wenn Sie sich erinnern, hatten wir viele dieser Typen früher selbst definiert . Aber jetzt verwenden wir den Zerfall von A Two a Python, um diese zu importieren. Aktualisiertes Ereignis für das Aufgabenartefakt. Dies ist das Ereignis, bei dem Ergebnisartefakte an den Client zurückgesendet werden, wie wir in der Demo gesehen haben Ereignis zur Aktualisierung des Aufgabenstatus Dabei handelt es sich um das Ereignis für das Senden von Statusmeldungen wie z. B. Arbeit abgeschlossen. Auch dies haben wir zuvor in der Demo gesehen. Aufgabenstatus, dies ist das Objekt , das den aktuellen Status der Aufgabe enthält, und der Aufgabenstatus ist eine Aufzählung, die den Status „Arbeitet“, „ Abgeschlossen“, „Eingabe erforderlich“ usw. definiert Arbeitet“, „ Abgeschlossen“, „Eingabe erforderlich“ usw. Dann haben wir Hilfsfunktionen, um standardisierte Nachrichten und Artefaktformate zu erstellen standardisierte Nachrichten und Artefaktformate Aus ao dot Utils importieren wir also neue Agenten-Textnachrichten Dadurch wird ein Nachrichtenobjekt vom Agenten zum Client Wir haben eine neue Aufgabe, die aus der ursprünglichen Nachricht ein neues Aufgabenobjekt erstellt , und wir haben ein neues Textartefakt Dadurch entsteht ein textuelles Ergebnisartefakt. Dies sind also Hilfsfunktionen zur Erstellung standardisierter Nachrichten und Artefaktformate Auch hier ist all diese Codierung von unserer Seite nicht erforderlich und das Python 80 SDC erledigt all dies Sehen wir uns unten an, wie diese verwendet werden. Jetzt haben wir den Tell Time Agent Executor, der einen neuen Executor definiert , indem er die achtfache Agent-Executor-Klasse erweitert . Diese Klasse verbindet den Tellt-Agenten mit der Serverlaufzeit von etwas. Sie implementiert die Execute-Funktion, um Aufgaben auszuführen und Updates in die Ereigniswarteschlange zu verschieben Wir haben zuerst den Konstruktor für die Executive-Klasse und dieser erzeugt lediglich eine Instanz des Tellt-Agenten für die Bearbeitung Dann haben wir die Execute-Funktion, die aufgerufen wird, wenn eine neue Aufgabe empfangen wird Wir verwenden zunächst den Kontext, um den tatsächlichen Text der Benutzernachricht zu extrahieren. Dann erhalten wir das Task-Objekt , falls es bereits existiert. Wir prüfen zuerst, ob die Nachricht nicht fehlt und geben einen Fehler aus, wenn etwas nicht stimmt. Und wenn es keine bestehende Aufgabe gibt, handelt es sich um eine neue Interaktion. Wir erstellen eine neue Aufgabe, die auf der Nachricht basiert. Wir stellen die neue Aufgabe in die Warteschlange , um den AS-Server zu benachrichtigen. Dann verwenden wir den Agenten, um die Anfrage über den Async-Stream zu bearbeiten Wir haben uns diese Stream-Funktion bereits in der Agent-PY-Datei angesehen und nennen diese Self-Dot-Agent-Dotstream-Funktion mit der Abfrage und der Aufgabenkontext-ID Dadurch werden uns mehrere Ereignisse angezeigt, wie wir in dieser Funktion erneut gesehen haben. Und wir werden für jedes Ereignis im Stream ein Async verwenden für jedes Ereignis im Stream ein Async Wir prüfen, ob die Aufgabe erfolgreich abgeschlossen wurde. Wenn wir das Ergebnisartefakt an den AS-Server schicken, so sagen wir Event und Scope Q und Q Event Dabei handelt es sich um ein Aktualisierungsereignis für Aufgabenartefakte mit der Aufgaben-ID, der Kontext-ID und einem Artefakt, das ein neues Textartefakt sein wird Mit dem Namen aktuelles Ergebnis die Beschreibung das Ergebnis der Anfrage an den Agenten und der Text ist der Inhalt des Ereignisses Wir geben dies als letzten Teil des Ergebnisses an und hängen es nicht an das vorherige Ergebnis an Und wenn die Aufgabe abgeschlossen ist, senden wir die letzte Statusmeldung , dass die Aufgabe abgeschlossen ist Dabei handelt es sich um ein Aktualisierungsereignis mit der Aufgaben-ID, der Kontext-ID und dem Status der Statusleiste mit dem Status Aufgaben als Punkt abgeschlossen und mit final gleich true, was im Grunde bedeutet, dass dies die letzte Statusmeldung ist Diese beiden sind also die letzten beiden Meldungen, die wir sehen, sobald das gesamte Streaming abgeschlossen ist. Wir haben das bereits in der Demo gesehen , die wir gerade am Anfang gesehen haben. Wenn der Agent weitere Informationen vom Benutzer benötigt, beenden wir schließlich weitere Informationen vom Benutzer benötigt, beenden ein Ereignis. Dabei handelt es sich um ein Ereignis zur Aktualisierung des Aufgabenstatus. Wir haben die ID der Aufgabe, wir haben die Kontext-ID und dann haben wir den Status der Aufgabe mit einem Status, der eingegeben werden muss, und die Nachricht wird eine neue Agenten-Textnachricht sein. Dies stellt im Grunde eine Nachricht dar, in der um Eingabe mit dem Nachrichteninhalt, der Kontext-ID und der Aufgaben-ID gebeten um Eingabe mit dem Nachrichteninhalt, wird. Und schließlich wird es auf true gesetzt, weil die Eingabe erforderlich ein letzter Status ist, bis der Benutzer antwortet. Am Ende haben wir die letzte Ls-Bedingung, die besagt, dass die Aufgabe noch bearbeitet wird oder sich im Arbeitszustand befindet . PNQ ist ein Statusaktualisierungsereignis, das die laufende Arbeit anzeigt. Dabei handelt es sich um ein Ereignis zur Aktualisierung des Aufgabenstatus mit einer Aufgaben-ID und einer Kontext-ID, und der Status im Inneren wird auf „ Arbeitend“ gesetzt und der Status im Inneren wird auf „ Arbeitend“ gesetzt. Wir eine neue Agenten-Textnachricht mit dem Inhalt, Fortschritt oder dem Protokoll, mit einer Kontext-ID und einer Aufgaben-ID. Abschließend wird der Status „ erzwungen“ gesetzt , da weitere Updates folgen könnten Schließlich haben wir Cancel , eine optionale Methode, um lang andauernde Aufgaben abzubrechen , die hier nicht unterstützt wird, also werden wir das hier nicht aufrufen. 103. 16.9 Code Walkthrough-Agent-Hauptseite: Schauen wir uns nun die endgültige Datei an, bei der die Hauptdatei mit Punkt PY handelt, und mit dieser Datei wird der 80-kompatible Agent-Server gestartet Sie richtet die Umgebung ein, konfiguriert den Task-Execution-Handler und die Agent-Karte und startet dann einen Starlight-Paste-Webserver für eingehende Agentenaufgaben Wir haben die grundlegenden Importe hier. Dann importieren wir den Tellt Agent und den Agent Executor hierher Schließlich importieren wir die 82 SDK-Komponenten. Wir haben die Hauptanwendungsklasse, die auf Starlet basiert. Wir haben die Standardlogik für die Bearbeitung von Aufgaben. Wir haben den Taskmanager und den Notifier im Speicher, und wir haben die Definitionen der Agenten-Metadaten wie Agentenkarte, Fähigkeit und Fähigkeiten Anschließend laden wir die Umgebungsvariablen aus der DOT-ANV-Datei, falls sie vorhanden ist, und jetzt haben wir den Haupteingangspunkt um den Agent-Server zu starten wo wir den Host und den Port als Optionen angeben können In der Hauptfunktion prüfen wir, ob der erforderliche API-Schlüssel in der Umgebungsvariablen festgelegt ist Das machen wir hier. Dann erstellen wir den STB-Client für Post-Benachrichtigungen verwendet wird Dies ist unser Client, dann richten wir den Request-Handler für die Bearbeitung eingehender Aufgaben Also stellen wir den Agent-Executor zur Verfügung, wir stellen einen Aufgabenspeicher und wir stellen einen Push-Notifier Der Agent-Executor verbindet sich mit unserem benutzerdefinierten Agenten. Der Aufgabenspeicher I verwendet den internen Speicher zur Verwaltung des Aufgabenstatus, und der Push-Notifier hier drüben ermöglicht Server-Push-Updates Dann richten wir die achte Serveranwendung mithilfe der Agentenkarte und Also stellen wir die Fähigkeiten und Fertigkeiten des Agenten bereit, fügen den Request-Handler und wir erhalten das Serverobjekt. Dann starten wir den Server mit dem UVCon Acing-Server, Server Dot Bill, den Host und den Port bereitstellt den Host und den Port Als Nächstes haben wir die Funktion Build Agent Card , die die Metadaten-Karte für diesen Agenten definiert und einfach eine Agentenkarte mit allen Details zurückgibt Wir haben den menschenlesbaren Namen des Agenten, wir haben die kurze Beschreibung. Wir haben die vollständige URL , unter der der Agent erreichbar ist , die Version des Agenten, die vorerst nur einen Punkt offen ist, und dann haben wir die unterstützten Funktionen. Wir geben an, dass Streaming gleich true und Push-Benachrichtigung gleich true ist. Wir haben die Standard-Eingabemodi und wir haben die Standard-Ausgabemodi und wir haben die nötigen Fähigkeiten. Und dafür erstellen wir ein Agenten-Skill-Objekt mit einer eindeutigen ID für diesen Skill. Wir haben hier nur ein Skill-Objekt. Wir können sogar eine Liste von ihnen bereitstellen. Für diesen speziellen Agenten-Skill haben wir die ID, das heißt „Zeit sagen“. Wir haben den Anzeigenamen „ Aktuelle Uhrzeit abrufen“. Dann haben wir eine Beschreibung, die besagt, dass sie die aktuelle Systemzeit im HHMSS-Format angibt, und dann haben wir einige nützliche Tags zum Suchen und Filtern wie Zeit und Uhr Und dann haben wir eine Liste von Beispielen, denen es sich um Beispiel-Benutzeraufforderungen handelt Also, wie viel Uhr ist es und sag mir die aktuelle Uhrzeit usw. Und schließlich haben wir den Code, um den Server hier zu starten Damit sind alle Codedateien vervollständigt , die wir in der Python-Acht-Wege-SDK-Implementierung Python-Acht-Wege-SDK-Implementierung haben, wo wir einen einzigen Client , der dann eine Verbindung zu einem Agenten herstellen kann, der ihm die Uhrzeit mitteilt und Streaming-Updates unterstützt. 104. ABSCHNITT 17 ERSTE Schritte – Multi-Agent-A2A- und MCP-Architektur: Heute werden wir untersuchen, wie ein verteiltes Multiagentensystem aufgebaut werden kann, das das Agent-to-Agent-Protokoll von Google oder ein Tow mit dem Context-Protokoll des Anthropyx-Modells, bekannt als MCP, kombiniert von Google oder ein Tow mit dem Context-Protokoll des Anthropyx-Modells Und am Ende dieses Videos werden Sie genau sehen, wie ein Frontend-Client, ein zentraler Host-Orchestrator, ein zentraler Host-Orchestrator, Remote-A-Tow-Agenten und externe MCP-Server nahtlos miteinander kommunizieren, um reale Aufgaben zu lösen Lassen Sie uns zunächst darüber sprechen, warum wir diese beiden Protokolle zusammenführen wollen MCP, das hier im grünen Zweig abgebildet ist , wurde am 24. November von Anthropyic auf den Markt gebracht MCP steht für Model Context Protocol und bietet großen Sprachmodellen eine standardisierte Möglichkeit, und bietet großen Sprachmodellen externe Tools aufzurufen Alles, von der Ausführung von Shell-Befehlen über das Abfragen von Datenbanken bis hin zur Durchführung von Websuchen Auf der anderen Seite hat Google ein To-a-Protokoll veröffentlicht, das für Agent-to-Agent-Protokoll steht, das hier in diesem roten Zweig im April 2025 abgebildet ist diesem roten Zweig im April 2025 Auf diese Weise können ausgereifte KI-Agenten sich gegenseitig entdecken und Aufgaben mithilfe von JCN RPC über STDP Kurz gesagt, MCP hilft einem Modell, mit Tools zu kommunizieren, und AA ermöglicht es einem Modell , mit einem anderen Durch die Kombination dieser beiden versetzen wir unser System in die Lage, spezialisierte Tools zu nutzen und mehrere Agenten zu orchestrieren, jeder über seine eigenen Fähigkeiten verfügt Wie funktioniert diese Architektur? Unsere Architektur besteht aus drei Hauptebenen , die hier oben abgebildet sind. Die erste sind die Frontend-Clients. Dies ist das A Two MCP-Frontend. Das zweite ist das gesamte System, das wir entwerfen, nämlich das 80-MCP-Multiagenten-System Und das dritte besteht im Grunde zwei Agenten und MCP-Servern, von denen wir erwarten, dass es sich um Agenten und Server von Drittanbietern handelt, mit denen wir unser System verbinden möchten Dies können auch die Server und Agenten sein, die wir lokal erstellt haben und die unser System verwenden soll Wir als Entwickler bauen also im Grunde die Schichten eins und zwei. Darauf konzentrieren wir uns und jeder kann diese zusätzlichen A-2-Agenten oder MCP-Server bereitstellen , und unser System wird sie grundsätzlich dynamisch erkennen und integrieren Hier sind also die endgültigen Daten Der Benutzer sendet eine Anfrage über das Frontend und ein Client leitet sie dann mithilfe von AA an den ein Client leitet sie dann mithilfe Host-Agenten oder den Orchestrator Und das ist grundsätzlich über einen ATS-Server verfügbar. Der AWS-Server macht den Host-Agenten also den 80-Clients am Frontend zugänglich Das LLM des Orchestrators ermittelt die MCP-Tools und alle Agenten und wählt dann das richtige Tool oder den richtigen Es kann also den grünen Zweig verwenden, um MCP-Tools aufzurufen und die Antwort zu erhalten, oder es könnte den roten Zweig verwenden, um eine Aufgabe an einen Remote-Agenten zu delegieren und Es könnte beide verwenden und dann im Grunde genommen die Antworten sammeln, sie bei Bedarf zusammenfügen und dann die endgültige Antwort zurückgeben Der Benutzer sieht im Grunde die endgültige Antwort und sieht nicht die gesamte Komplexität , die im Backend passiert Nun, diese Architektur ist sehr vorteilhaft, weil sie eine wichtige Sache bietet, nämlich Modularität. Sie können diese Agenten und Tools grundsätzlich hinzufügen oder entfernen , ohne diese zentrale Orchestrierungslogik hier zu berühren . Sie müssen lediglich Ihre MCP-Server zur MCP-Konfliktrotationsdatei hinzufügen und Sie müssen nur Ihre Agenten zur Agentenregistrierungsdatei hinzufügen Dieses Design ist auch skalierbar, da jeder Agent oder Toolserver einem eigenen Container oder Prozess ausgeführt wird und Sie so viele Server und Agenten haben können, und Sie so viele Server und Agenten haben können wie Sie möchten oder so viel, wie es der Kontext der großen Sprachmodelle zulässt Außerdem bietet dieses Design ein hohes Maß an Flexibilität, sodass Sie zur Laufzeit entscheiden können , welche Komponente für die jeweilige Aufgabe am besten geeignet ist. Möchten Sie den grünen Zweig nehmen und ein MCP-Tool aufrufen, oder möchten Sie den roten Zweig nehmen und einen 80-Agent anrufen , um die Anfrage des Benutzers zu Dies ist auch ziemlich robust , da jeder MCP-Server und ATA-Agent im Grunde auf einem separaten Container oder Prozess ausgeführt Wenn also einer von ihnen ausfällt oder aus irgendeinem Grund nicht verfügbar ist, fällt das gesamte System nicht Und dein System funktioniert immer noch. Aus diesen Gründen denke ich, dass dies ein sehr gutes Systemdesign für unser nächstes Video ist , in dem wir tatsächlich die Ärmel hochkrempeln und eine Live-Demo implementieren werden. Also werden wir drei Zweiweg-Agenten einrichten, wie wir es beim letzten Mal für das Video getan haben , in einem Schlepptau, das mit mehreren Agenten zusammenarbeitet, und dieses Mal werden wir sie mit MCP-Servern Wir verwenden also mindestens einen MCP-Server, der die Shell des lokalen Rechners für die Ausführung lokaler Befehle verfügbar macht, und Sie werden den gesamten Code, die Startskripts, den Erkennungsprozess, die Konnektoren und die Orchestrierungslogik sehen die Startskripts, den Erkennungsprozess, die Konnektoren und die Orchestrierungslogik Und wie das alles zusammenarbeitet , wo Sie tatsächlich eine Abfrage eingeben können, um entweder einen Befehl über Ihren MCP-Server auszuführen , oder eine Abfrage eingeben , um eine Aufgabe tatsächlich über einen Remote-Agenten auszuführen, alles über dasselbe App-Frontend und einen einzigen Host-Orchestrierungsagenten. Lassen Sie uns also zunächst über unseren Frontend-Client sprechen. Stellen Sie sich einen Benutzer in einer Web - oder mobilen App oder sogar einer Befehlszeilenschnittstelle sich anmeldet und eine Frage eingibt. Sagen wir, suchen Sie nach den neuesten Finanzierungsnachrichten für Acme Corp und drücken Sie die Eingabetaste Hinter den Kulissen wird diese Anfrage an unsere 80 Kunden weitergeleitet. Welches das 82-Protokoll an unseren Host oder Orchestrator weiterleitet. Der Benutzer sieht nichts von dieser Komplexität. Sie bekommen einfach die Antwort zurück. Schauen wir uns nun den Host-Agenten oder Orchestrator-Agenten Das ist das Gehirn unseres Systems. Der Host-Agent selbst hat also einen A-Spielzeug-Server, was bedeutet, dass er Anfragen wie Aufgaben usw. über das ATA-Protokoll empfangen kann was bedeutet, dass er Anfragen wie Aufgaben usw. über das ATA-Protokoll empfangen kann, und er kann mithilfe des 80-Protokolls entdeckt werden, das unser A-Zwei-A-Client verwendet Die andere Sache ist, dass es sich im Grunde um einen Orchestrator-Agent handelt. Es hat also etwas, das als Orchestrator bezeichnet wird. Was eigentlich zwei Dinge bewirken kann. Es kann alle Agenten und alle MCP-Server, über die es verfügt, mithilfe eines Prozesses namens Discovery auflisten alle MCP-Server, über die es verfügt, mithilfe eines Prozesses namens Discovery und dann Aufgaben an diesen Agenten delegieren oder diese Aufgaben über den MCP-Client an die MCP-Tools Lassen Sie uns also zuerst über Discovery sprechen. Beim Start oder während der Laufzeit kann der Host-Agent grundsätzlich einen Erkennungsprozess verwenden , um alle Agenten aufzulisten , die in einer Agentenregistrierung registriert sind. Er ruft im Grunde die URLs für die ATS-Server der anderen Agenten ab. Diese URLs werden in der Registrierung erwähnt, die im Wesentlichen vom Orchestrator verwendet wird , um eine Liste der verfügbaren Agenten abzurufen Gleichzeitig kann es während des Starts oder während der Laufzeit einen MCP-Connector verwenden, es während des Starts oder während der Laufzeit um alle verfügbaren MCP-Server aufzulisten , indem auf ein sogenanntes MCP-Konfliktpunkt-JCN zugegriffen handelt es sich um eine Art Registrierung für alle verfügbaren MCP-Server Auch hier kann es alle Serverdetails abrufen, wie den Befehl, den Sie zum Ausführen des Servers benötigen, den Pfad für die Serverskriptdatei, und falls Sie tatsächlich Server über das implementieren , kann es auch die Server-URL abrufen. Wir werden uns vorerst tatsächlich lokale Server in diesem speziellen System ansehen. Das ist also eine Aufgabe des Orchestrators, Informationen über verfügbare Agenten und verfügbare MCP-Server abzurufen Informationen über verfügbare Agenten und verfügbare MCP-Server Die zweite Rolle des Orchestrator-Agenten besteht darin, Aufgaben zu delegieren Nachdem der Orchestrator die gesamte MCP-Server-URL gelesen hat, verwendet er einen MCP-Client und stellt über das Model Context-Protokoll eine Verbindung zu den Servern her, um eine Liste aller Tools Gleichzeitig erhält er auch eine Liste aller Agentenkarten, der Fähigkeiten und Fähigkeiten In gewisser Weise werden nun alle MCP-Tools als Tools betrachtet, die der LL zugewiesen sind und vom LLM einzeln aufgerufen werden können, und es gibt zwei Tools, nämlich Agenten auflisten und Aufgaben delegieren, also Tools betrachtet, die der LL zugewiesen vom LLM einzeln aufgerufen werden können, und es gibt zwei Tools, nämlich Agenten auflisten und Aufgaben delegieren, die beiden Tools, die es tatsächlich aufrufen kann, um alle wertvollen Agenten aufzulisten und Aufgaben an einen bestimmten Agenten zu delegieren Wenn also eine Anfrage vom Frontend und an einen Client eingeht, überprüft das interne LLM des Orchestrators die Anfrage anhand des Werkzeuggürtels überprüft das interne LLM des Orchestrators die Anfrage anhand des Werkzeuggürtels und entscheidet dann , welcher Zweig verwendet werden soll. Es kann also entweder eine Antwort auf die Abfrage geben, indem sein eigenes internes L verwendet, oder es könnte sich entscheiden, entweder den grünen Zweig oder den roten Zweig zu Wenn es die Aufgabe nicht alleine bewältigen kann, listet es alle Agenten auf listet es alle Agenten um zu sehen, welche anderen Agenten verfügbar sind, und es verfügt bereits über eine Liste von MCP-Tools, die dem internen Large Language Model als Tools zugewiesen die dem internen Large Language Model als sind, die tatsächlich aufrufen können, um die Abfrage zu erfüllen Wenn die Aufgabe also am besten von einem anderen KI-Agenten erledigt werden kann, wie Planung einer Reise, könnte der Orchestrator diese A an Agenten weiterleiten und die Aufgabe an diese delegieren Sobald die Aufgabe delegiert ist, sendet ein Agenten-Connector eine A-Verbindung zu einem Client, der über das ATA-Protokoll mit dem 80-Server für den Helper-Agent kommunizieren kann ATA-Protokoll mit dem 80-Server für den , den der Orchestrator Dieser Helper- oder Remote-Agent verfügt möglicherweise über einen eigenen Orchestrator , der dann über das Abwesenheitsprotokoll mit weiteren Agenten Sobald er die Antwort erhalten hat, sendet er sie im Grunde zurück an den Etoway-Client , der sie dann an den Host-Agenten oder Orchestrator hier zurücksendet den Host-Agenten oder Das heißt, Sie rufen einen Kollegen über ein Netzwerk an, um Ihnen bei einem Teil der Aufgabe zu helfen , und erhalten dann diese Antwort zurück , um Ihrem Kunden eine endgültige Antwort zu Andererseits könnte sich der Host-Agent dafür entscheiden, den grünen Zweig zu verwenden. Wenn für die Anfrage also ein spezielles Tool erforderlich ist, ein Shell-Befehl ausgeführt, ein Datenbankschema oder erweiterte Berechnungen durchgeführt werden müssen, verwendet der Orchestrator möglicherweise den grünen Zweig, abgerufen oder erweiterte Berechnungen durchgeführt werden müssen, verwendet der Orchestrator möglicherweise den grünen Zweig, und er verfügt bereits über eine Liste von Tools, die er zuvor geladen die Es ruft dieses Tool also im Grunde direkt über das Modellkontext-Protokoll indem es etwas verwendet, das wir Der MCP-Connector startet also im Grunde einen MCP-Client, der das Model Context-Protokoll verwendet Das Tool wird für den Orchestrator aufgerufen, und der Orchestrator stellt bestimmte Eingabeargumente bereit , die das Tool benötigt, und erhält dann im Grunde