In letzter Zeit haben wir ein exponentielles Wachstum im Bereich der künstlichen Intelligenz mit großen Sprachmodellen erlebt (LLM), Vision Language Models usw. und seit kurzem auch KI-Agenten. Im Gegensatz zu herkömmlichen regelbasierten Anwendungen sind diese Agenten in der Lage, ihre Denk- und Entscheidungsfähigkeiten zu nutzen, um komplexe Aufgaben autonom oder mit minimalem Benutzereingriff auszuführen. Dazu müssen KI-Agenten oft Code dynamisch generieren und ausführen oder sogar die gesamte virtuelle Maschine steuern. Novita AI Sandkasten bietet diese Funktionen.
In diesem Tutorial erstellen wir einen KI-Agenten, der als unser Datenanalyst fungiert und genau wie ein menschlicher Analyst in der Lage ist, mithilfe des Browsers gemäß unseren Anweisungen einen Datensatz zu suchen und herunterzuladen und bei entsprechender Aufforderung Code zu analysieren, zu visualisieren und auszuführen, um uns mit den daraus gewonnenen Erkenntnissen zu antworten.
Was ist ein KI-Agent?
Ein KI-Agent ist ein Softwareprogramm, das künstliche Intelligenz nutzt, um zu schlussfolgern, Pläne zu erstellen und Aktionen auszuführen, um bestimmte Ziele zu erreichen. Diese Agenten können Tools wie APIs, Codeausführung und Websuchen nutzen, um Informationen zu sammeln oder Aufgaben auszuführen. Manchmal arbeiten sie auch mit anderen Agenten zusammen, insbesondere für komplexere Ziele wie Deep Research.
Hier sind typische Komponenten eines KI-Agenten:
- Argumentation/Planung: Wenn dem Agenten ein Ziel vorgegeben wird, erstellt er schrittweise Pläne, um es zu erreichen. Dieser Prozess kann das Abschließen von Teilaufgaben und das Sammeln zusätzlicher Informationen für seine nächsten Aktionen beinhalten. Dies ist insbesondere bei komplexen Aufgaben üblich, die länger dauern. In solchen Situationen eignen sich Argumentationsmodelle gut.
- Werkzeugverwendung: KI-Agenten können externe Tools und Dienste aufrufen. Dazu können Funktionen, APIs oder andere Ressourcen gehören, die ihre Fähigkeiten erweitern.
- Koordinierung: Mehrere Agenten können zusammenarbeiten, indem sie sich die Verantwortlichkeiten teilen, wobei jeder einzelne dazu beiträgt, ein gemeinsames, komplexes oder langfristiges Ziel zu erreichen.
Novita AI Sandkasten, LLM Übersicht über Produkte und Browsernutzung

Was eine Sandbox ist und warum sie wichtig ist
Eine Sandbox ist eine sichere, isolierte Laufzeitumgebung, in der nicht vertrauenswürdiger Code ausgeführt werden kann, ohne das Hostsystem zu beeinträchtigen. Im Grunde handelt es sich um einen schlanken virtuellen Computer, auf dem Ihr KI-Agent Code und Befehle ausführen, Dateien erstellen usw. kann.
Novita AI stellt diese Sandbox in der Cloud bereit, damit Ihr Agent bei Bedarf schnell darauf zugreifen kann, mit flexibler Abrechnung pro Sekunde basierend auf den verwendeten Ressourcen.
Hauptmerkmale der Novita-Sandbox:
- Sichere Isolierung: Jede Sandbox erhält ihr isoliertes Dateisystem und ihre Umgebung, wodurch Daten geschützt und unbeabsichtigte Interaktionen verhindert werden.
- Schnellstart: Sandbox-Instanzen werden im Durchschnitt in weniger als ~200 ms gestartet, was sie ideal für Szenarien mit geringer Latenz macht.
- Mehrsprachige Unterstützung: Sie können Code in mehreren Programmiersprachen ausführen, darunter Python, JavaScript, TypeScript und mehr.
- Schnelle Pause und Fortsetzung: Sie können die Sandbox jederzeit unterbrechen und bei Bedarf fortsetzen, wobei der Dateisystem- und Prozessstatus vollständig wiederhergestellt wird.
- Hintergrundausführung: Unterstützt die Ausführung von Aufgaben im Hintergrund und eignet sich für Szenarien, in denen auf ein Ergebnis gewartet werden muss.
Novita-Modell-API:

Novita bietet eine umfangreiche Bibliothek mit Open-Source-KI-Modellen führender Forschungslabore wie OpenAI, Google, DeepSeek und Qwen. Dazu gehören Modelle für Sprache, Vision, Audio, Video und Einbettungen. Unsere Sprachmodelle sind zudem vollständig mit dem OpenAI SDK kompatibel. Für den Wechsel von OpenAI zu Novita müssen Sie lediglich die Basis-URL und den API-Schlüssel in Ihrem Client aktualisieren und anschließend ein Novita-Modell auswählen.
| von openai importiere OpenAI Kunde = OpenAI( Basis-URL = ”https://api.novita.ai/v3/openai”, api_key=” ”, ) |
Übersicht zur Browsernutzung:

Browser Use ist eine Open-Source-Python-Bibliothek, die es KI-Agenten ermöglicht, mit Webbrowsern über natürliche Sprachbefehle zu interagieren (z. B. „Check the weather in NY today“). Anstatt komplexe regelbasierte Selektoren zu schreiben, übernimmt die KI die Elementsuche und -interaktion. Und dank Novitas OpenAI-kompatibler Modell-API können Sie beliebige LLM oder VLM (Vision-Language Model) zur Unterstützung der Browsernutzung.
Einrichten Ihrer Entwicklungsumgebung
Um zu beginnen, klonen wir das GitHub-Repository, richten eine saubere Python-Umgebung ein, installieren alle erforderlichen Abhängigkeiten und erhalten Novita AI Schlüssel.
Klonen Sie das GitHub-Repository und installieren Sie Abhängigkeiten mit uv.
1. Installieren uv (ein leichter Python-Paketmanager)
| pip install uv |
2. Klonen Sie das Repository (GitHub Repo) und navigieren Sie hinein.
| Git Klon https://github.com/Studio1HQ/AI-sandbox.git CD KI-Sandbox |
3. Erstellen und aktivieren Sie die uv virtuelle Umgebung
| # Erstellt eine virtuelle Umgebung uv venv # Aktivieren Sie die virtuelle Umgebung Quelle .venv/bin/activate # Für Mac/Linux # oder .venv\Scripts\activate # Für Windows |
4. Installieren Sie Projektabhängigkeiten
| # Abhängigkeiten installieren UV-Synchronisierung |
Erstellen einer Novita AI Konto und Erhalt eines API-Schlüssels
1. Registrieren bei novita.ai.
2. Bewegen Sie den Mauszeiger im Dashboard über das Benutzerprofilsymbol und klicken Sie auf API-Keys im Popup.

3. Klicken Sie auf der Seite „Schlüsselverwaltung“ auf Neuen Schlüssel hinzufügen. Geben Sie im Popup einen Namen für Ihren Schlüssel ein, klicken Sie auf Schichtannahme, und kopieren Sie dann den generierten Schlüssel.

4. Erstellen Sie nun im Projektverzeichnis eine .env Datei und fügen Sie diese unten ein.
| NOVITA_API_KEY=” „ NOVITA_BASE_URL=”https://api.novita.ai/v3/openai” NOVITA_E2B_DOMAIN=”Sandbox.novita.ai" NOVITA_E2B_TEMPLATE=”code-interpreter-v1″ |
Fügen Sie Guthaben hinzu zum Novita AI -Konto.
Um die Novita-Sandbox nutzen zu können, müssen Sie Ihrem Konto Guthaben hinzufügen. Klicken Sie auf der Registerkarte Dashboard auf „Abrechnung.“ Fügen Sie dann auf der Rechnungsseite eine Zahlungsmethode hinzu und laden Sie Guthaben im Wert von mindestens 10 $ auf.

Erstellen des Exploratory Data Analyst (EDA)-Agenten
Jetzt ist unsere Umgebung eingerichtet und wir haben unseren API-Schlüssel. Starten wir unseren Agenten
Herunterladen von Datensätzen (oder Dateien) über den Agent-Browser. Verwendung:
Genau wie ein menschlicher Analyst soll unser Agent Anweisungen entgegennehmen und einen Browser verwenden können, um die Datensätze abzurufen. Wie in browser_agent.py, erstellen wir zunächst eine Pydantic-Datenstruktur für die endgültige Ausgabe des Agenten, die die heruntergeladenen Dateinamen und die Ergebnisse der abgeschlossenen Aufgaben enthält, die in eine Datei geschrieben werden sollen.
| … # unter vorhandenem Code Klasse TaskFile(Basismodell): „““Stellt eine Datei dar, die als Teil eines Aufgabenergebnisses generiert wurde, z. B. Scraped-Daten oder recherchierte Daten.“““ Dateiname: str = Feld(…, Beschreibung=”Name der Datei inkl. Erweiterung”) Inhalt: str = Feld (…, Beschreibung = „Textinhalt, der in die Datei geschrieben werden soll“) Klasse AgentOutput(BaseModel): „Endgültige aggregierte Ausgabe der Browser-Agent-Ausführung.“ heruntergeladene_Dateien: Optional[list[str]] = Feld( Keine, Beschreibung = „Liste der heruntergeladenen Dateinamen (mit Erweiterung), falls vorhanden“ ) task_files: Optional[Liste[TaskFile]] = Feld( Keine, Beschreibung = „Von Benutzeraufgaben generierte Dateien (z. B. ausgelesene oder recherchierte Daten), falls vorhanden“ ) |
Nachfolgend sehen Sie ein Beispiel für die Funktionsweise des Agenten-Browsers. Wir verwenden ein Large Language Model (LLM) für die Browser-Navigation, was die meisten Anwendungsfälle abdecken sollte. Für komplexere UI-Aufgaben (z. B. Captcha-Lösung) wird jedoch ein Vision-Language-Modell (VLM) empfohlen. Bei Verwendung eines VLM können Sie den Detaillierungsgrad der Visualisierung („hoch“, „niedrig“ oder „auto“) einstellen, um die Token-Kosten mit der Visualisierungsqualität abzuwägen.
Anschließend erstellen wir eine Browsersitzung, konfigurieren das Profil mit einem Downloadpfad (./Herunterladen) , Benutzerdatenverzeichnis (eingestellt auf Keine Präsentation für den Inkognito-Modus) und stellen Sie unsere Pydantik Modell als Controller, um die Agentenausgaben zu strukturieren. Dann starten wir den Agenten mit warte auf agent.run(), und die endgültigen Ergebnisse werden analysiert, um die heruntergeladenen Dateinamen zu erhalten.
| # Ein Beispiel dafür, wie der Browser-Agent aussehen wird Agent = Agent( task=”Gehen Sie zu Hugging Face, suchen Sie nach An-j96/SuperstoreData und öffnen Sie die Seite. Navigieren Sie dann zur Registerkarte „Dateien“ und laden Sie die CSV-Datendatei herunter.”, llm=ChatOpenAI(base_url=novita_base_url, model=novita_model, api_key=novita_api_key), use_vision=Falsch, vision_detail_level=”auto”, # verfügbare Optionen ['niedrig', 'hoch', 'auto']; browser_session=BrowserSession( browser_profile=BrowserProfile( downloads_path=”./Download”, user_data_dir=Keine ) ), # Legen Sie den Download-Verzeichnispfad für den Browser fest. Controller=Controller( output_model=Agentenausgabe ), # Lassen Sie den Agenten am Ende der Aufgabe den Namen der heruntergeladenen Datei ausgeben. ) all_results = warte auf agent.run() final_output = AgentOutput.model_validate_json( alle_Ergebnisse.finales_Ergebnis() ) # Analysieren Sie das endgültige Agentenergebnis. |
(Hinweis: Wenn Sie einen Browser-Agenten auf Ihrem lokalen Computer ausführen, wird eine echte Browserinstanz gestartet, sodass Sie sie in Aktion beobachten können.) Die vollständige Methode sammelt die heruntergeladenen Dateinamen, schreibt die Aufgabenergebnisse in eine Datei und gibt alle Dateipfade zum späteren Hochladen zurück.
| … # unter vorhandenem Code asynchron def downloading_task_for_browser_agent( Aufgabe: str, api_key: str, Modell: str, model_api_base_url: str, use_vision: bool, download_dir_path: str = „./Download“, ) -> Tupel[str, Liste[str]]: "" " Führt den Download-Vorgang des Benutzers über den Browser aus und gibt den Download-Verzeichnispfad und die Namen der heruntergeladenen Dateien. Rücksendung: Tupel aus (Downloadverzeichnis, Dateinamen mit Erweiterung) "" " Agent = Agent( Aufgabe=Aufgabe, llm=ChatOpenAI( base_url=model_api_base_url, Modell=Modell, api_key=API-Schlüssel, max_completion_tokens=20_000, frequency_penalty=0, # Diese Strafe kann die Werkzeugnutzung leicht beeinträchtigen; belassen Sie sie bei 0. ), use_vision=use_vision, vision_detail_level=”auto”, # verfügbare Optionen ['niedrig', 'hoch', 'auto']; browser_session=BrowserSession( browser_profile=BrowserProfile( downloads_path=Download-Verzeichnispfad, user_data_dir=Keine, # „./browser_user_data“ ) ), # Legen Sie den Download-Verzeichnispfad für den Browser fest. Controller=Controller( output_model=Agentenausgabe ), # Lassen Sie den Agenten das Ergebnis der Aufgabenausführung gemäß dem AgentOutput-Schema ausgeben. max_failures=5, ) Versuchen: # Führen Sie den Agenten aus und strukturieren Sie seine Ausgabe all_results = warte auf agent.run() final_output: AgentOutput = AgentOutput.model_validate_json( alle_Ergebnisse.finales_Ergebnis() ) wenn final_output.task_files: Konsole.Drucken( Panel( f”[fett gelb]Aufgabenergebnisse in Dateien schreiben…[/fett gelb] {final_output.task_files}”, Titel = „Aufgabenergebnisse“, border_style=”weiß”, ) ) # Schreiben Sie jedes Aufgabenergebnis in eine Datei im Download-Verzeichnis task_result_files: Liste[str] = [] für task_file in final_output.task_files oder []: Dateipfad = Pfad(Aufgabendatei.Dateiname) # Verhindern Sie Pfaddurchquerungen oder unsichere absolute Pfade wenn file_path.is_absolute() oder „..“ in file_path.parts: ValueError erhöhen( f „Der Agent hat einen unsicheren Dateipfad als Dateinamen übergeben: {file_path}“ ) # Zeigen Sie mit dem Dateipfad in das Download-Verzeichnis Dateipfad = Pfad (Downloadverzeichnispfad) / Dateipfad # Stellen Sie sicher, dass das Download-Verzeichnis vorhanden ist, andernfalls erstellen Sie es. file_path.parent.mkdir(Eltern=Wahr, exist_ok=Wahr) # Schreibe den Inhalt des Task-Ergebnisses in eine Datei mit open(file_path, „w“, encoding=“utf-8″) als f: f.write(task_file.content) task_result_files.append(task_file.dateiname) wenn task_result_files: Konsole.Drucken( Panel( f”[bold green]Aufgabenergebnisse in Dateien geschrieben:[/bold green] {task_result_files}”, Titel = „Aufgabenergebnisse“, border_style=”weiß”, ) ) # Heruntergeladene Dateien mit Aufgabenergebnisdateien kombinieren file_results = (final_output.downloaded_files oder []) + task_result_files wenn Dateiergebnisse: Konsole.Drucken( Panel( f”[bold green]Verfügbare Dateien:[/bold green] {file_results} in {download_dir_path}”, Titel = „Heruntergeladene Dateien“, border_style=”grün”, ) ) sonst: raise RuntimeError(„Es wurden keine Dateien heruntergeladen oder geschrieben.“) außer Ausnahme als e: file_results = Keine Konsole.Drucken( Panel( f”[fett rot]Fehler:[/fett rot] {str(e)}\n”, Titel = „Ausführungsfehler“, border_style=”rot”, ) ) return (Downloadverzeichnispfad, Dateiergebnisse) |
Der Agentenanruf wird in eine Versuchen Sie es – außer Block, so dass bei einem Fehler eine Ausnahme ausgelöst wird und Dateiergebnisse eingestellt ist Keine Präsentation. Schließlich gibt die Methode sowohl die Download-Verzeichnispfad und der Dateiergebnisse Pfade.
Definieren von Schemata der verfügbaren Tools für unseren Agenten:
Nachdem wir nun mit der Browsernutzung fertig sind, ist es an der Zeit, die Schemata für die Tools zu definieren, die unserem EDA-Agenten zur Verfügung stehen. Wir stellen vier Tools zur Verfügung:
- Python-Code ausführen: ermöglicht dem Agenten, Python-Code innerhalb der Sandbox auszuführen.
- Auf der Befehlszeile ausführen: ermöglicht dem Agenten, Befehle im Sandbox-Terminal auszuführen (z. B. Python-Pakete zu installieren).
- Synchronisierung mit Benutzer: ermöglicht dem Agenten, erstellte oder aktualisierte Dateien und Verzeichnisse aus der Sandbox mit Ihrem lokalen Synchronisierungsordner zu synchronisieren.
- delete_from_user_sync_folder: ermöglicht dem Agenten, Dateien oder Verzeichnisse aus dem lokalen Synchronisierungsordner zu entfernen.
Zusammen geben all diese Tools dem Agenten die volle Kontrolle über die Codeausführung, die Terminalnutzung und die Dateisynchronisierung zwischen der Sandbox und Ihrem lokalen System.
In sandbox_eda.py, wir sehen das Schema für die Werkzeuge:
- Python-Code ausführen, das einfach den auszuführenden Python-Code als Eingabeparameter verwendet und gegebenenfalls ein Ergebnis zurückgibt.
| { „Typ“: „Funktion“, „Funktion“: { „Name“: „run_python_code“, „Beschreibung“: „Führt den Python-Code aus und gibt das Ergebnis zurück, falls vorhanden.“ „Parameter“: { „Typ“: „Objekt“, "Eigenschaften": { „python_code“: { „Typ“: „Zeichenfolge“, „Beschreibung“: „Der auszuführende Python-Code.“ } }, „erforderlich“: [„Python-Code“], }, }, }, |
- auf der Befehlszeile ausführen, Dies nimmt wiederum einfach den auszuführenden Befehl als Eingabeparameter und gibt gegebenenfalls ein Ergebnis zurück.
| { „Typ“: „Funktion“, „Funktion“: { „Name“: „Auf Befehlszeile ausführen“, „Beschreibung“: „Führt den Befehl in der Befehlszeile aus und gibt das Ergebnis zurück, falls vorhanden.“ „Parameter“: { „Typ“: „Objekt“, "Eigenschaften": { „Befehl“: { „Typ“: „Zeichenfolge“, „Beschreibung“: „Der Befehl, der in der Befehlszeile ausgeführt werden soll.“ } }, „erforderlich“: [„Befehl“], }, }, }, |
- Synchronisierung mit Benutzer, das zwei Eingabeparameter benötigt:
- Sandbox-Pfad: der Pfad zur Datei oder zum Verzeichnis innerhalb der Sandbox.
- Pfad im Synchronisierungsordner des Benutzers: der Pfad, den der Agent für die Datei oder das Verzeichnis im Synchronisierungsordner des Benutzers festlegen möchte.
Dieser zweite Pfad hat die Form (z. B. /neu.txt), unter der Annahme, dass der Synchronisierungsordner der übergeordnete Ordner ist. Beispielsweise werden wir später /neu.txt zu sync_folder/new.txt.
| { „Typ“: „Funktion“, „Funktion“: { „Name“: „Mit Benutzer synchronisieren“, „Beschreibung“: „Synchronisiert eine Datei oder ein Verzeichnis in der Sandbox mit dem Synchronisierungsordner auf dem Computer des Benutzers“, „Parameter“: { „Typ“: „Objekt“, "Eigenschaften": { „Sandbox-Pfad“: { „Typ“: „Zeichenfolge“, „Beschreibung“: „Pfad zur Datei oder zum Verzeichnis in der Sandbox.“ }, „Pfad_im_Benutzer-Synchronisierungsordner“: { „Typ“: „Zeichenfolge“, „Beschreibung“: „Relativer Pfad, in dem die Datei oder das Verzeichnis im Synchronisierungsordner des Benutzers abgelegt wird. Beispielsweise wird „/hello.txt“ direkt in den Synchronisierungsordner gelegt, während „/run1/hello.txt“ in einem Unterordner „run1“ innerhalb des Synchronisierungsordners abgelegt wird.“ }, }, „erforderlich“: [„Sandbox-Pfad“, „Pfad im Benutzer-Synchronisierungsordner“], }, }, }, |
- delete_from_user_sync_folder, das nur einen Eingabeparameter benötigt:
- Pfad im Synchronisierungsordner des Benutzers: der Pfad zur Datei oder zum Verzeichnis, das der Agent aus dem Synchronisierungsordner des Benutzers löschen möchte.
Beachten Sie, dass dies den gleichen Pfadannahmen folgt wie in Synchronisierung mit Benutzer.
| { „Typ“: „Funktion“, „Funktion“: { „Name“: „delete_from_user_sync_folder“, „Beschreibung“: „Löscht eine Datei oder ein Verzeichnis aus dem Synchronisierungsordner auf dem Computer des Benutzers“, „Parameter“: { „Typ“: „Objekt“, "Eigenschaften": { „Pfad_im_Benutzer-Synchronisierungsordner“: { „Typ“: „Zeichenfolge“, „Beschreibung“: „Relativer Pfad zur Datei oder zum Verzeichnis im Synchronisierungsordner des Benutzers. Beispielsweise löscht „/hello.txt“ die Datei direkt aus dem Synchronisierungsordner, während „/run1/hello.txt“ die Datei direkt aus dem Unterordner „run1“ innerhalb des Synchronisierungsordners löscht.“ } }, „erforderlich“: [„Pfad_im_Benutzersynchronisierungsordner“], }, }, }, |
Implementierung der verfügbaren Funktionen:
Zuerst haben wir eine SandboxEDA Klasse, die die folgenden Parameter akzeptiert:
- Sandkasten: die Sandbox-Instanz.
- Modellbasis-URL , model_api_key: zum Anschluss an das Novita-Modell.
- max_zulässige_aufeinanderfolgende_Funktionsaufrufe: Standardmäßig ist 30 um unendliche Funktionsaufrufschleifen vom Agenten zu verhindern, wie wir später sehen werden.
| … # unter vorhandenem Code Klasse SandboxEDA: def __init__( Selbst, Sandkasten: Sandkasten, model_api_base_url: str, model_api_key: str, max_consecutive_function_calls_allowed: int = 30, ): self.sandbox = Sandbox self.model_api_base_url = model_api_base_url self.model_api_key = model_api_key self.max_consecutive_function_calls_allowed = ( max_consecutive_function_calls_allowed ) |
Dann, Python-Code ausführen als Methode der SandboxEDA Klasse. Die Methode verwendet den Python-Code als Eingabe und verwendet die Sandkasten Instanz, um es auszuführen. Wenn die Ausgaben zurückgegeben werden, werden alle Bildausgaben (Hinweis: Sie sind base64-kodiert) in der Temp_Image_Output Verzeichnis. Schließlich gibt die Methode ein Wörterbuch zurück, das die Bildausgaben, andere Ausgaben, Protokolle und etwaige Fehler enthält.
| … # unter vorhandenem Code Klasse SandboxEDA: … # unter vorhandenem Code def run_python_code(self, python_code: str) -> dict: "" " Führt den Python-Code in der Sandbox aus und speichert vorhandene Bilder lokal. Argumente: python_code (str): Der auszuführende Python-Code. Rücksendung: dict: Enthält die Base64-Bildausgaben und andere Ausgaben (Stdout, Protokolle, Fehler usw.). "" " Ausführung = self.sandbox.run_code(python_code, Sprache=”python”) image_outputs = [result.png für Ergebnis in execution.results wenn result.png] # Durchlaufen Sie die Base64-codierten Bilder und speichern Sie sie in einer Datei mit dem Namensformat: temp-{timestamp}.png im Verzeichnis ./temp_image_output für b64_image in image_outputs: Zeitstempel = int(Zeit.Zeit_ns()) Bilddateiname = Pfad(f”./temp_image_output/temp-{timestamp}.png”) # Erstellt das Verzeichnis temp_image_output, falls es noch nicht vorhanden ist. image_filename.parent.mkdir(Eltern=Wahr, exist_ok=Wahr) mit open(Bilddateiname, „wb“) als f: f.write(base64.b64decode(b64_image)) Rückkehr { „Bildausgaben“: Bildausgaben, „andere_Ausgaben“: { „Ausgaben“: [Ergebnis für Ergebnis in execution.results, wenn nicht result.png], „Protokolle“: Ausführungsprotokolle, „Fehler“: Ausführungsfehler, }, } |
Nächstes Auf der Befehlszeile ausführen Methode. Dies führt den Befehl auf ähnliche Weise auf der Sandbox-Instanz aus und gibt dann ein Wörterbuch mit den Ausgaben zurück. Wenn die Ausführung fehlschlägt, wird ein Wörterbuch mit Keine Präsentation für die Ausgänge und Sets "Ausführungsfehler“ zur Fehlermeldung.
| … # unter vorhandenem Code Klasse SandboxEDA: … # unter vorhandenem Code def run_on_command_line(selbst, Befehl: str) -> dict: "" " Führt den Befehl in der Sandbox aus. Argumente: Befehl (str): Der auszuführende Befehl. Rücksendung: dict: Enthält die Ausgabe des Befehls und den Ausführungsfehler, falls vorhanden. "" " Versuchen: Ergebnis = self.sandbox.commands.run(Befehl) Rückkehr { "Ausgabe": { „stdout“: Ergebnis.stdout, „stderr“: Ergebnis.stderr, „exit_code“: Ergebnis.exit_code, „Fehler“: Ergebnis.Fehler, }, „Ausführungsfehler“: Keiner, } außer Ausnahme als e: return {„Ausgabe“: Keine, „Ausführungsfehler“: str(e)} |
Und das Synchronisierung mit Benutzer Methode. Wie bereits beschrieben, wird dies die Sandbox-Pfad , Pfad im Synchronisierungsordner des Benutzers. Wenn der Sandbox-Pfad auf eine Datei verweist, wird diese aus der Sandbox in den entsprechenden Synchronisierungsordner heruntergeladen. Handelt es sich um ein Verzeichnis, durchläuft die Methode rekursiv alle untergeordneten Inhalte und lädt jede Datei an den entsprechenden Speicherort herunter. Bei Erfolg geben wir zurück „Synchronisierung erfolgreich“ andernfalls geben wir die Ausnahmemeldung zurück.
| … # unter vorhandenem Code Klasse SandboxEDA: … # unter vorhandenem Code def sync_with_user(selbst, Sandbox-Pfad, Pfad_im_Benutzer-Synchronisationsordner): "" " Lädt eine Datei oder ein Verzeichnis aus der Sandbox in den Synchronisierungsordner des Benutzers herunter. Argumente: sandbox_path (str): Der Pfad der Datei oder des Verzeichnisses, die/das in der Sandbox synchronisiert werden soll. path_on_user_sync_folder (str): Der relative Zielpfad der Datei oder des Verzeichnisses im Synchronisierungsordner des Benutzers. Rücksendung: str: „Synchronisierung erfolgreich“, wenn die Datei oder das Verzeichnis erfolgreich synchronisiert wurde, andernfalls eine Fehlermeldung. "" " Versuchen: Pfadinfo = self.sandbox.files.get_info(Sandbox-Pfad) wenn path_info.type == FileType.DIR: # Wenn es sich um ein Verzeichnis handelt, durchlaufen Sie den Inhalt und laden Sie ihn herunter. dir_contents = self.sandbox.files.list(sandbox_path) für Inhalte in dir_contents: Pfad zum Inhalt im Synchronisierungsordner = Pfad( Pfad im Synchronisierungsordner des Benutzers ).joinpath(Inhalt.Name) self.sync_with_user(Inhaltspfad, Pfad_zum_Inhalt_im_Sync-Ordner) elif path_info.type == Dateityp.DATEI: # Stellen Sie sicher, dass sich die Datei immer im Ordner ./sync_folder befindet. sandbox_path_obj = Pfad(Pfad_im_Benutzersynchronisierungsordner) # Machen Sie den Pfad relativ, indem Sie alle Stamm- oder Laufwerkskomponenten entfernen relativer_Pfad = Sandbox-Pfad_Objekt.relativ_zu( sandbox_path_obj.anchor oder „.“ ) # Endgültiger Pfad innerhalb des Sync-Ordners Dateipfad = Pfad(„Synchronisierungsordner“) / relativer_Pfad # Erstellt jedes Verzeichnis im Pfad, das noch nicht existiert. file_path.parent.mkdir(Eltern=Wahr, exist_ok=Wahr) # Laden Sie die Datei in den Synchronisierungsordner herunter. Dateiinhalt = self.sandbox.files.read(Sandbox-Pfad, „Bytes“) mit open(Dateipfad, „wb“) als f: f.write(file_content) Rückgabe „Synchronisierung erfolgreich“ außer Ausnahme als e: Rückgabe str(e) |
Schließlich wird der delete_from_user_sync_folder Methode. Wie bereits beschrieben, dauert Pfad im Synchronisierungsordner des Benutzers. Anschließend löschen wir die entsprechende Datei bzw. das Verzeichnis, sofern vorhanden, und kehren zurück „Löschung erfolgreich“ andernfalls wird die Ausnahmemeldung zurückgegeben.
| … # unter vorhandenem Code Klasse SandboxEDA: … # unter vorhandenem Code def delete_from_user_sync_folder(selbst, Pfad_im_Benutzer_sync_folder): "" " Löscht eine Datei oder ein Verzeichnis aus dem Benutzersynchronisierungsordner. Argumente: path_on_user_sync_folder (str): Der Pfad der zu löschenden Datei oder des zu löschenden Verzeichnisses im Benutzersynchronisierungsordner. Rücksendung: str: „Löschen erfolgreich“, wenn die Datei oder das Verzeichnis erfolgreich gelöscht wurde, andernfalls eine Fehlermeldung. "" " # Stellen Sie sicher, dass sich die Datei immer im Ordner ./sync_folder befindet. sandbox_path_obj = Pfad(Pfad_im_Benutzersynchronisierungsordner) # Machen Sie den Pfad relativ, indem Sie alle Stamm- oder Laufwerkskomponenten entfernen relativer_Pfad = Sandbox-Pfad_Objekt.relative_zu(Sandbox-Pfad_Objekt.Anker oder „.“) # Endgültiger Pfad innerhalb des Sync-Ordners delete_path = Pfad(“sync_folder”) / relativer_Pfad Versuchen: wenn nicht delete_path.exists(): Ausnahme auslösen( f„Datei oder Verzeichnis existiert nicht unter {path_on_user_sync_folder} im Synchronisierungsordner.“ ) wenn delete_path.is_file(): delete_path.unlink() elif delete_path.is_dir(): Shutil.rmtree(str(delete_path)) Rückgabe „Löschung erfolgreich“ außer Ausnahme als e: Rückgabe str(e) |
Weitere Sandbox-Funktionen:
1. Laden Sie Dateien mit der Sandbox-Methode hoch.
| … # unter vorhandenem Code Klasse SandboxEDA: … # unter vorhandenem Code def Dateien in die Sandbox hochladen( selbst, Dateipfade: Liste[str], Dateinamen_in_Sandbox: Liste[str] ): "" " Lädt Dateien in die Sandbox hoch. Argumente: file_paths (Liste[str]): Dateipfade der hochzuladenden Dateien (z. B. [“./Download/data.csv“, „./Download/data2.csv“]). file_names_in_sandbox (Liste[str]): Die Namen, die die Dateien in der Sandbox annehmen (z. B. [„data.csv“, „data2.csv“]). Hinweis: Die Dateien werden in das Verzeichnis /home/user der Sandbox hochgeladen (z. B. ./home/user/data.csv, ./home/user/data2.csv). "" " Konsole.Drucken( f”[yellow]Datei(en) unter {file_paths} in die Sandbox hochladen[/yellow] (id: {self.sandbox.sandbox_id})” ) für Dateipfad, Dateiname_in_Sandbox in Zip(Dateipfade, Dateinamen_in_Sandbox): mit open(file_path, „rb“) als Datei: self.sandbox.files.write(Dateiname_in_Sandbox, Datei) Konsole.Drucken( f”[bold cyan]Datei(en) {file_paths} in Sandbox hochgeladen[/bold cyan] (id: {self.sandbox.sandbox_id})” ) |
2. Methode zum Auflisten des Inhalts des Sandbox-Hauptverzeichnisses (/home/user).
| … # unter vorhandenem Code Klasse SandboxEDA: … # unter vorhandenem Code def list_files_in_sandbox_main_dir(self) -> list[str]: return [i.name für i in self.sandbox.files.list("/home/user")] |
Aufbau einer Interaktion mit dem Agenten:
Nun sehen wir uns eine Methode zur Interaktion mit dem Agenten an. Schauen wir uns vorher die parametrisierte System-Eingabeaufforderung an in prompts/system_prompt.py.
| SYSTEM_PROMPT = „““ Sie sind ein Agent für Exploratory Data Analysis (EDA) und haben Zugriff auf eine Sandbox (mit Internetzugang), in der Sie Folgendes tun können: – Führen Sie Python-Code mit dem Funktionsaufruf run_python_code aus. – Sie können grundsätzlich alles tun, was Sie auf einem Linux-Computer tun können, über den Funktionsaufruf run_on_command_line oder run_python_code. – Sie können jedes Verzeichnis (möglicherweise bevorzugt für die Struktur, z. B. Website) oder jede Datei, die Sie erstellt, geschrieben oder aktualisiert haben, über den Funktionsaufruf „sync_with_user“ mit dem Synchronisierungsordner des Benutzers auf seinem lokalen Computer synchronisieren. – Sie können jedes dieser Verzeichnisse oder Dateien aus dem Synchronisierungsordner des Benutzers auf seinem lokalen Computer über den Funktionsaufruf „delete_from_user_sync_folder“ löschen. Ihr aktuelles PWD ist „/home/user“ und unten sind die darin enthaltenen Dateien aufgeführt. {list_sandbox_files} Hinweis: – Die Sandbox ist bereits mit den üblichen Datenanalysepaketen vorinstalliert, aber wenn es ein Paket gibt, Wenn Sie nicht sicher sind, ob es vorhanden ist, oder Ihr Code aufgrund eines fehlenden Pakets einen Importfehler aufweist, können Sie prüfen, ob es installiert ist, und es andernfalls installieren. – Stellen Sie bei Bildausgaben (z. B. aus der Datenvisualisierung) sicher, dass das PNG-Format vorliegt. Richtlinien für Funktionsaufrufe: – Verwenden Sie immer run_python_code, um eine Aufgabe auszuführen, es sei denn, Sie müssen unbedingt run_on_command_line verwenden (z. B. um Pakete zu installieren usw.). – Verketten Sie Funktionsaufrufe bei Bedarf: Nachdem Sie die Ergebnisse eines Funktionsaufrufs erhalten haben, führen Sie sofort weitere Aufrufe durch, wenn weitere Informationen erforderlich sind – Sammeln Sie zunächst nur die benötigten Informationen: Antworten Sie dem Benutzer erst, wenn Sie mindestens genügend Informationen aus Funktionsaufrufen haben, um eine gute Antwort zu geben – Seien Sie effizient: Obwohl es eine Obergrenze von {max_consecutive_function_calls_allowed} aufeinanderfolgenden Funktionsaufrufen gibt, versuchen Sie, so wenig Aufrufe wie möglich zu tätigen, um gerade genug Informationen zu erhalten. – Gehen Sie nicht einfach davon aus, dass der Benutzer die Ausgabe des Tool-Aufrufs liest, sondern antworten Sie ihm mit Ihrer Antwort. Seien Sie ein hilfreicher Assistent für den Benutzer, der wahrscheinlich versucht, EDA an Datensatzdateien ({downloaded_dataset_names}) im Verzeichnis (/home/user/) durchzuführen. Sie können folgende Funktionsaufrufe durchführen: {verfügbares_Funktionsaufrufschema} "" " |
Jetzt rüber zum eda_chat Methode in SandboxEDA Klasse. Diese Methode verwendet die Namen der Dateien, die in die Sandbox hochgeladen wurden (wir kümmern uns um das Hochladen, bevor wir den Chat starten, wie wir später sehen werden) und den Namen des zu verwendenden Novita-Modells.
1. Zuerst richten wir den OpenAI-Client so ein, dass er über die Basis-URL auf Novita verweist, und initialisieren die Konversation mit der Systemaufforderung als erste Nachricht.
| … # unter vorhandenem Code Klasse SandboxEDA: … # unter vorhandenem Code def eda_chat( Selbst, heruntergeladene_Datensatznamen: Liste[str], model_for_eda: str, ): "" " Interaktive EDA-Sitzung mit KI-Agent, der Codeausführung und Terminalbefehle ausführen kann Argumente: downloaded_dataset_names (Liste[str]): Die Namen der heruntergeladenen Datensätze. model_for_eda (str, optional): Das zu verwendende zugrunde liegende Modell. "" " Konsole.Drucken( Panel( „[fett grün]EDA-Sitzung gestartet[/fett grün]\nGeben Sie zum Beenden ‚quit()‘ ein.“, Titel = „Explorative Datenanalyse“, border_style=”grün”, ) ) Kunde = OpenAI( base_url=self.model_api_base_url, api_key=self.model_api_key, ) # Konversation mit Systemaufforderung initialisieren Nachrichten = [ { „Rolle“: „System“, „Inhalt“: SYSTEM_PROMPT.format( heruntergeladene_Datensatznamen=str(heruntergeladene_Datensatznamen), list_sandbox_files=str(self.list_files_in_sandbox_main_dir()), available_function_calls_schema=str( VERFÜGBARE FUNKTIONSANRUFSCHEMAS ), max_consecutive_function_calls_allowed=selbst.max_consecutive_function_calls_allowed, ), } ] |
2. Die Haupt-Chat-Schleife ist eine While-Schleife, in der wir die Nachricht des Benutzers an den bestehenden Nachrichtenverlauf anhängen. Um unendlich viele aufeinanderfolgende Tool-Aufrufe zu vermeiden, gibt es innerhalb der While-Schleife eine For-Schleife bis zum Limit, die bei Erreichen eine Exception auslöst. Anschließend werden die Nachrichten an das Modell weitergeleitet.
| … # unter vorhandenem Code # Haupt-Chat-Schleife während wahr: user_input = Prompt.ask(“\n[fett gelb]>>> Benutzernachricht[/fett gelb]”) wenn user_input.lower().strip() == „quit()“: brechen Nachrichten.anhängen({„Rolle“: „Benutzer“, „Inhalt“: Benutzereingabe}) # Behandeln Sie potenzielle aufeinanderfolgende Tool-Aufrufe mit einem Sicherheitslimit, um Endlosschleifen zu vermeiden für i im Bereich (self.max_consecutive_function_calls_allowed + 1): wenn i == self.max_consecutive_function_calls_allowed: Ausnahme auslösen( f„Aufeinanderfolgende Tool-Aufrufe vom Agenten dürfen {self.max_consecutive_function_calls_allowed} nicht überschreiten.“ ) Antwort = Client.Chat.Completions.create( Modell=Modell_für_EDA, Nachrichten=Nachrichten, tools=VERFÜGBARE_FUNKTIONSANRUFSCHEMAS, Frequenzstrafe = 0, ) Antwortnachricht = Antwort.Auswahl[0].Nachricht |
3. Als nächstes prüfen wir, ob das Modell einen Tool-Aufruf durchgeführt hat. Wenn ja, führen wir das Tool mit den vom Modell bereitgestellten Argumenten aus, drucken die Ausgabe für den Benutzer auf dem Terminal (oder zeigen gegebenenfalls ein Bild an) und geben die Ausgabe anschließend an das Modell zurück, beginnend mit dem Python-Code ausführen Werkzeugaufruf.
| … # unter vorhandenem Code tool_calls = Antwortnachricht.tool_calls wenn tool_calls: Nachrichten.anhängen( Antwortnachricht ) # Assistentennachricht hinzufügen, die Tool-Aufrufe auslöste # Führen Sie jeden angeforderten Tool-Aufruf aus für tool_call in tool_calls: Name = Toolaufruf.Funktionsname args = json.loads(tool_call.function.arguments) wenn Name == „run_python_code“: Konsole.Drucken( Panel( args["python_code"], Titel = „Agent führt Python-Code aus“, border_style=”blau”, ) ) Codeergebnis = self.run_python_code(args["python_code"]) Nachrichten.anhängen( { „tool_call_id“: tool_call.id, „Rolle“: „Werkzeug“, „Name“: Name, # Wenn es irgendwelche Bildausgaben gibt (zB Datenvisualisierung), da es noch nicht möglich ist, Bilder zurückzugeben # Informieren Sie den Agenten einfach über einen Tool-Aufruf, dass dem Benutzer das Bild angezeigt wurde. "Inhalt": [ { „Typ“: „Text“, “text”: ( f”DIE BILDER WURDEN DEM BENUTZER BEREITS AUF DEM TERMINAL ANGEZEIGT UND IN TEMPORÄREN DATEIEN GESPEICHERT, z. B. temp-{{timestamp}}.png auf dem Computer des Benutzers im Verzeichnis ./temp_image_output. DIE ANDEREN AUSGABEN FINDEN SIE UNTEN\n{code_result['other_outputs']}” wenn Codeergebnis["Bildausgaben"] sonst f”{code_result['other_outputs']}” ), } ], } ) display_sandbox_code_output(code_result) |
3b. Auf der Befehlszeile ausführen Werkzeugaufruf.
| … # unter vorhandenem Code elif name == „auf_der_Befehlszeile_ausführen“: Konsole.Drucken( Panel( args["Befehl"], Titel = „Agent führt Befehl auf Terminal aus“, border_style=”blau”, ) ) Befehlsergebnis = selbst.Auf_Befehlszeile_ausführen(Argumente["Befehl"]) Nachrichten.anhängen( { „tool_call_id“: tool_call.id, „Rolle“: „Werkzeug“, # Gibt an, dass diese Nachricht von der Werkzeugverwendung stammt „Name“: Name, „Inhalt“: str(Befehlsergebnis), } ) display_sandbox_command_output(Befehlsergebnis) |
3c. Synchronisierung mit Benutzer Werkzeugaufruf.
| … # unter vorhandenem Code elif name == „sync_with_user“: Konsole.Drucken( Panel( f”[fett gelb]Agent hat mit der Synchronisierung von {args['sandbox_path']} mit dem Synchronisierungsordner des Benutzers begonnen ({args['path_on_user_sync_folder']})[/fett gelb]”, Titel = „Dateisynchronisierung“, border_style=”weiß”, ) ) sync_result = selbst.sync_mit_Benutzer( args["Sandbox-Pfad"], args["Pfad_im_Benutzer-Synchronisierungsordner"] ) Nachrichten.anhängen( { „tool_call_id“: tool_call.id, „Rolle“: „Werkzeug“, # Gibt an, dass diese Nachricht von der Werkzeugverwendung stammt „Name“: Name, „Inhalt“: Synchronisierungsergebnis, } ) … # der Kürze halber übersprungen |
3d delete_from_user_sync_folder Toolaufruf und werfen einen unbekannten Fehler, wenn nicht vorhandene Funktionsaufrufe vorhanden sind.
| … # unter vorhandenem Code elif name == „delete_from_user_sync_folder“: Konsole.Drucken( Panel( f”[fett gelb]Agent löscht Datei(en) aus dem Synchronisierungsordner des Benutzers ({args['path_on_user_sync_folder']})[/fett gelb]”, Titel = „Dateisynchronisierung“, border_style=”weiß”, ) ) delete_result = self.delete_from_user_sync_folder( args["Pfad_im_Benutzer_Synchronisierungsordner"] ) Nachrichten.anhängen( { „tool_call_id“: tool_call.id, „Rolle“: „Werkzeug“, # Gibt an, dass diese Nachricht von der Werkzeugverwendung stammt „Name“: Name, „Inhalt“: Löschergebnis, } ) … # der Kürze halber übersprungen sonst: raise ValueError(f”Unbekannter Funktionsaufruf: {name}”) |
4. Wenn die letzte Antwort des Agenten kein Tool-Aufruf ist, drucken Sie seine Antwort an den Benutzer und brechen Sie die Begrenzungsschleife für aufeinanderfolgende Tool-Aufrufe ab.
| … # unter vorhandenem Code sonst: # Keine Tool-Aufrufe, nur Anzeige der Antwort des Assistenten nach dem Hinzufügen zu den Nachrichten. Nachrichten.anhängen( {„Rolle“: „Assistent“, „Inhalt“: Antwortnachricht.Inhalt} ) Konsole.Drucken( f”[fett grün]>>> Assistentenantwort: {response_message.content} [/]” ) brechen |
Orchestrierung des Agentenflusses:
Endlich haben wir main.py dient als Einstiegspunkt unserer Anwendung und verbindet alles miteinander. Im Inneren befindet sich die start_eda -Methode startet eine neue Sandbox-Sitzung. Die Sandbox-Zeitüberschreitung Der Parameter bestimmt, wie lange die Sandbox aktiv bleibt, bevor sie automatisch beendet wird. Für unsere Demo stellen wir ihn auf 900 Sekunden (≈15 Minuten) ein.
Nachdem die Sandbox erstellt wurde, laden wir Dateien hinein und starten dann die eda_chat Methode, um mit der Interaktion mit dem Agenten zu beginnen.
| … # unter vorhandenem Code def start_eda( model_for_eda: str, dataset_paths: Liste[str], dataset_file_names: Liste[str], api_key_for_sandbox_and_model: str, model_api_base_url: str, sandbox_domain: str, sandbox_template: str, sandbox_timeout: int, ): mit Sandbox( Vorlage=Sandbox-Vorlage, api_key=API-Schlüssel für Sandbox und Modell, Domäne=Sandbox-Domäne, timeout=Sandbox-Zeitüberschreitung, ) als Sandbox: Versuchen: sandbox_eda = SandboxEDA( Sandbox, Modell-API-Basis-URL, API-Schlüssel für Sandbox und Modell ) Konsole.Drucken( f”[bold cyan]Sandbox gestartet[/bold cyan] (id: {sandbox.sandbox_id})” ) sandbox_eda.upload_files_to_sandbox(Datensatzpfade, Datensatzdateinamen) sandbox_eda.eda_chat(Datensatzdateinamen, Modell_für_EDA) Konsole.Drucken( f”\n\n[fett cyan]—— EDA-Sitzung für Sandbox abgeschlossen (id: {sandbox.sandbox_id}) ——[/]” ) schließlich: Konsole.Drucken( f”[fett cyan]—– Geschlossene Sandbox (id: {sandbox.sandbox_id})—–[/]\n” ) |
Unten ist die Haupt- Methode, der Startpunkt unserer Anwendung:
| … # unter vorhandenem Code asynchrone Def-Hauptfunktion ( api_key_for_sandbox_and_model: str, model_api_base_url: str, model_for_browser_agent: str, enable_vision_for_browser_agent: bool, model_for_eda: str, sandbox_domain: str, sandbox_template: str, sandbox_timeout_seconds: int, ): während wahr: # Willkommensbanner Konsole.Drucken( Panel( „[fett weiß]Willkommen zur agentischen explorativen Datenanalyse[/fett weiß]\n\n“ „[grey]Wie möchten Sie fortfahren:[/grey]\n“ „[grey]1.[/grey] Laden Sie zuerst einen Datensatz herunter.\n“ „[grey]2.[/grey] Fahren Sie mit dem bereits heruntergeladenen Datensatz fort.\n“ „[grau]3.[/grau] Ausgang“, Titel = „HAUPTMENÜ“, border_style=”grün”, Breite=70, ) ) Auswahl = Prompt.ask( „\n[fett gelb]Geben Sie Ihre Auswahl ein[/fett gelb]“, Auswahlmöglichkeiten=[„1“, „2“, „3“] ).Streifen() wenn Auswahl == „1“: Ergebnis = warte auf choice_download_dataset( API-Schlüssel für Sandbox und Modell, model_api_base_url, Modell_für_Browser_Agent, enable_vision_for_browser_agent, ) wenn Ergebnis: Downloadpfad, Dateinamen = Ergebnis DATASET_PATHS = [ str(Pfad(Downloadpfad) / Dateiname) für Dateinamen in Dateinamen ] DATASET_FILE_NAMES = Dateinamen sonst: weiter # Benutzer ist zum Hauptmenü zurückgekehrt elif choice == „2“: Ergebnis = Auswahl_mit_bereits_heruntergeladenen_Datensätzen_fortfahren() wenn Ergebnis: DATASET_PATHS = Ergebnis DATASET_FILE_NAMES = [os.path.basename(path) für Pfad im Ergebnis] sonst: Weiter #, da der Benutzer auf „Zurück zum Hauptmenü“ geklickt hat. elif choice == „3“: brechen # Starten Sie die EDA-Sitzung start_eda( model_for_eda, DATASET_PATHS, DATASET_FILE_NAMES, API-Schlüssel für Sandbox und Modell, model_api_base_url, Sandbox-Domäne, Sandbox-Vorlage, Sandbox-Timeout-Sekunden, ) |
Parce que main.py wird ausgeführt Als Skript fügen wir den folgenden Code hinzu und übergeben dabei auch unsere Umgebungsvariablen, das Sandbox-Timeout und die Novita-Modelle, die wir verwenden möchten:
| … # unter vorhandenem Code if __name__ == „__main__“: NOVITA_API_KEY = os.getenv(“NOVITA_API_KEY”) NOVITA_BASE_URL = os.getenv(“NOVITA_BASE_URL”) NOVITA_E2B_DOMAIN = os.getenv(“NOVITA_E2B_DOMAIN”) NOVITA_E2B_TEMPLATE = os.getenv(“NOVITA_E2B_TEMPLATE”) NOVITA_MODEL_FOR_BROWSER_AGENT = „qwen/qwen3-coder-480b-a35b-instruct“ ENABLE_VISION_FOR_BROWSER_AGENT = ( False # Wenn „true“, stellen Sie sicher, dass das Browser-Agent-Modell über Sichtfunktionen verfügt. ) NOVITA_MODEL_FOR_EDA = „qwen/qwen3-coder-480b-a35b-instruct“ NOVITA_SANDBOX_TIMEOUT_SECONDS = 900 # 900 Sekunden (15 Minuten), die Sandbox-Instanz wird danach automatisch beendet. asyncio.run( hauptsächlich( NOVITA_API_KEY, NOVITA_BASE_URL, NOVITA_MODEL_FOR_BROWSER_AGENT, ENABLE_VISION_FOR_BROWSER_AGENT, NOVITA_MODEL_FOR_EDA, NOVITA_E2B_DOMAIN, NOVITA_E2B_TEMPLATE, NOVITA_SANDBOX_TIMEOUT_SECONDS, ) ) |
Testen Sie die Ausführung unseres EDA-Agenten:
Führen Sie den folgenden Befehl im Terminal aus
| uv run main.py |
Fazit
Herzlichen Glückwunsch zum Erstellen Ihres Exploratory Data Analyst-Agenten. Sie können ihn nun bitten, Websites, PowerPoint-Präsentationen usw. zu erstellen und dabei Analysen/Erkenntnisse aus beliebigen Datensatzdateien zu verwenden. Die Ergebnisse werden direkt mit Ihrem lokalen Computer synchronisiert.
Zur kurzen Wiederholung: In diesem Artikel haben Sie gelernt, wie Sie einen Agenten erstellen, der Anweisungen entgegennimmt, dann mit dem Browser im Internet navigiert und Dateien herunterlädt, Code und Befehle in der Novita Sandbox ausführt und Dateien und Verzeichnisse mit Ihrem lokalen Computer synchronisiert.
Dies ist nur die Spitze des Eisbergs. Sie können Ihren Agenten erweitern, um eine Verbindung zu Datenbanken herzustellen, Tools wie Google Docs über MCP zu integrieren und vieles mehr. Gehen Sie zu Ankündigungen um Ihre Ideen zum Leben zu erwecken!
Novita AI ist eine KI-Cloud-Plattform, die Entwicklern eine einfache Möglichkeit bietet, KI-Modelle mithilfe unserer einfachen API bereitzustellen und gleichzeitig die kostengünstige und zuverlässige GPU Cloud zum Erstellen und Skalieren.
Entdecken Sie mehr von Novita
Abonnieren Sie, um die neuesten Beiträge per E-Mail zu erhalten.





