Preise

Architektur im Überblick

Quelldateien

Diese Seite wurde aus den folgenden Quelldateien erstellt:

GPT Researcher ist eine autonome Forschungsplattform, die auf einer modularen Multi-Agenten-Architektur basiert. Das System kombiniert asynchrone Python-Backends mit WebSocket-basierter Echtzeitkommunikation und unterstützt sowohl einfache Forschungsanfragen als auch komplexe Multi-Agenten-Workflows.

Systemarchitektur

Die Architektur von GPT Researcher folgt einem Schichtenmodell, das die Trennung von Verantwortlichkeiten zwischen API-Schicht, Geschäftslogik und Agenten-Orchestrierung gewährleistet.

正在加载图表渲染器...

Erklärung der Architekturkomponenten:

  1. Client-Ebene: Drei verschiedene Client-Typen können mit dem System interagieren — Web-Frontend, NPM-SDK für JavaScript-Integrationen und ein Discord-Bot für Community-Interaktionen (docs/npm/index.js:1-123, docs/discord-bot/index.js:17-78)

  2. API-Schicht: FastAPI fungiert als zentrale Schnittstelle mit Pydantic-Modellen für Request-Validierung. Die Schicht unterstützt sowohl REST-Endpunkte als auch WebSocket-Verbindungen für Echtzeit-Streaming (backend/server/app.py:52-67)

  3. Kern-Engine: Der GPT Researcher Haupt-Agent koordiniert alle Forschungsaktivitäten und nutzt Skills für spezialisierte Aufgaben sowie Actions für Workflow-Orchestrierung (gpt_researcher/skills/init.py:1-15)

  4. Multi-Agenten-System: ChiefEditorAgent orchestriert komplexe Forschungsaufgaben durch Koordination mehrerer speialisierter Agenten über LangGraph (multi_agents/agent.py:1-16)

Backend-Architektur API-Endpunkte

Das Backend basiert auf FastAPI und bietet eine asynchrone Architektur mit umfassender WebSocket-Unterstützung für Echtzeit-Updates während des Forschungsprozesses.

Datenmodelle und Request-Handling

Die API definiert zwei primäre Request-Modelle:

python
1class ResearchRequest(BaseModel):
2    task: str
3    report_type: str
4    report_source: str
5    tone: str
6    headers: dict | None = None
7    repo_name: str
8    branch_name: str
9    generate_in_background: bool = True
10
11class ChatRequest(BaseModel):
12    model_config = ConfigDict(extra="allow")
13    report: str
14    messages: List[Dict[str, Any]]

(backend/server/app.py:52-67)

Verantwortlichkeiten der Modelle:

ModellZweckPflichtfelder
ResearchRequestStartet neue Forschungsaufgabentask, report_type, report_source, tone
ChatRequestFollow-up-Fragen zu bestehenden Reportsreport, messages

Server-Initialisierung und Logging

Der Haupteinstiegspunkt konfiguriert Uvicorn mit strukturierter Protokollierung:

python
1logging.basicConfig(
2    level=logging.INFO,
3    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
4    handlers=[
5        logging.FileHandler('logs/app.log'),
6        logging.StreamHandler()
7    ]
8)

(main.py:1-37)

Die Logging-Konfiguration unterdrückt zusätzlich verbose FontTools-Ausgaben, um die Lesbarkeit der Logs zu verbessern.

WebSocket-Kommunikation und Logs-Handler

Der CustomLogsHandler implementiert eine duale Speicherstrategie — Echtzeit-WebSocket-Streaming und persistente JSON-Protokollierung:

python
1class CustomLogsHandler:
2    def __init__(self, websocket, task: str):
3        self.logs = []
4        self.websocket = websocket
5        sanitized_filename = sanitize_filename(f"task_{int(time.time())}_{task}")
6        self.log_file = os.path.join("outputs", f"{sanitized_filename}.json")

(backend/server/server_utils.py:33-123)

Fehlerbehandlung:

  • Automatische Dateinamen-Sanitisierung verhindert Path-Traversal-Angriffe
  • Fallback auf lokale Speicherung bei WebSocket-Fehlern
  • Strukturierte JSON-Logs mit Zeitstempeln für Nachvollziehbarkeit

Modulare Skills Komponenten

Das Skills-System implementiert eine klare Trennung der Verantwortlichkeiten durch spezialisierte Klassen, die jeweils einen definierten Aspekt des Forschungsprozesses abdecken.

Skill-Klassen-Übersicht

python
1from .context_manager import ContextManager
2from .researcher import ResearchConductor
3from .writer import ReportGenerator
4from .browser import BrowserManager
5from .curator import SourceCurator
6from .image_generator import ImageGenerator
7
8__all__ = [
9    'ResearchConductor',
10    'ReportGenerator',
11    'ContextManager',
12    'BrowserManager',
13    'SourceCurator',
14    'ImageGenerator',
15]

(gpt_researcher/skills/init.py:1-15)

Grenzen der Skill-Verantwortlichkeiten:

SkillZuständig fürNicht zuständig für
ResearchConductorDurchführung der Web-RechercheBerichtsgenerierung
ReportGeneratorSchreiben des finalen ReportsQuellensammlung
BrowserManagerBildverarbeitung, DeduplizierungTextanalyse
ImageGeneratorKI-gestützte BilderstellungContent-Extraktion
SourceCuratorQuellenbewertungContent-Generierung

ImageGenerator: Erweiterbare Provider-Architektur

Der ImageGenerator demonstriert das Erweiterbarkeitsmuster des Systems:

python
1class ImageGenerator:
2    def __init__(self, researcher):
3        self.researcher = researcher
4        self.cfg = researcher.cfg
5        self.image_provider = None
6        self.max_images = getattr(self.cfg, 'image_generation_max_images', 3)
7        self.generated_images: List[Dict[str, Any]] = []
8        self._init_provider()

(gpt_researcher/skills/image_generator.py:20-419)

Initialisierungslogik:

  1. Provider-Instanziierung nur wenn image_generation_enabled=True
  2. Verfügbarkeitsprüfung vor Aktivierung
  3. Graceful Degradation bei fehlenden API-Keys

BrowserManager: Bildverarbeitung mit Deduplizierung

Die select_top_images-Methode implementiert Hash-basierte Deduplizierung:

python
1def select_top_images(self, images: list[dict], k: int = 2) -> list[str]:
2    unique_images = []
3    seen_hashes = set()
4    current_research_images = self.researcher.get_research_images()
5    
6    for img in sorted(images, key=lambda im: im["score"], reverse=True):
7        img_hash = get_image_hash(img['url'])
8        if (img_hash and img_hash not in seen_hashes 
9            and img['url'] not in current_research_images):
10            seen_hashes.add(img_hash)
11            unique_images.append(img["url"])
12            if len(unique_images) == k:
13                break
14    return unique_images

(gpt_researcher/skills/browser.py:86-115)

Fehlerbehandlung:

  • get_image_hash gibt None bei ungültigen URLs zurück
  • Sortierung nach Score stellt Relevanz sicher
  • Cross-Reference mit existierenden Bildern verhindert Duplikate

Actions Workflow-Orchestrierung

Die Actions-Schicht stellt die operationale Schnittstelle zwischen High-Level-Workflows und Low-Level-Skills dar.

Verfügbare Actions

python
1from .retriever import get_retriever, get_retrievers
2from .query_processing import plan_research_outline, get_search_results
3from .agent_creator import extract_json_with_regex, choose_agent
4from .web_scraping import scrape_urls
5from .report_generation import (
6    write_conclusion, summarize_url, 
7    generate_draft_section_titles, generate_report, 
8    write_report_introduction
9)
10from .markdown_processing import (
11    extract_headers, extract_sections, 
12    table_of_contents, add_references
13)
14from .utils import stream_output

(gpt_researcher/actions/init.py:1-27)

Kategorisierung der Actions:

KategorieActionsZweck
Retrievalget_retriever, get_retrieversSuchmaschinen-Integration
Query Processingplan_research_outline, get_search_resultsAbfrageoptimierung
Scrapingscrape_urls, summarize_urlContent-Extraktion
Generationgenerate_report, write_conclusionBerichtserstellung
Markdownextract_headers, table_of_contentsFormatierung

Deep Research: Kontext-Management

Für tiefe Forschungsaufgaben implementiert das System ein Wortlimit-basiertes Trimming:

python
1def trim_context_to_word_limit(
2    context_list: List[str], 
3    max_words: int = MAX_CONTEXT_WORDS
4) -> List[str]:
5    total_words = 0
6    trimmed_context = []
7    
8    for item in reversed(context_list):
9        words = count_words(item)
10        if total_words + words <= max_words:
11            trimmed_context.insert(0, item)
12            total_words += words
13        else:
14            break
15    return trimmed_context

(gpt_researcher/skills/deep_research.py:23-37)

Design-Entscheidung: Reverse-Processing priorisiert neuere/relevantere Kontexte.

Multi-Agenten-Architektur

Für komplexe Forschungsaufgaben bietet GPT Researcher eine Multi-Agenten-Architektur mit ChiefEditorAgent als Koordinator.

ChiefEditorAgent-Initialisierung

python
1from multi_agents.agents import ChiefEditorAgent
2
3chief_editor = ChiefEditorAgent({
4    "query": "Is AI in a hype cycle?",
5    "max_sections": 3,
6    "follow_guidelines": False,
7    "model": "gpt-4o",
8    "guidelines": [
9        "The report MUST be written in APA format",
10        "Each sub section MUST include supporting sources",
11        "The report MUST be written in spanish"
12    ],
13    "verbose": False
14}, websocket=None, stream_output=None)
15graph = chief_editor.init_research_team()
16graph = graph.compile()

(multi_agents/agent.py:1-16)

Konfigurationsparameter:

ParameterTypZweck
querystrHauptforschungsfrage
max_sectionsintMaximale Report-Abschnitte
modelstrLLM-Modell-Auswahl
guidelinesList[str]Formatierungsregeln
verboseboolDetailliertheit der Logs

Asynchrone Task-Ausführung

python
1async def run_research_task(
2    query, websocket=None, stream_output=None, 
3    tone=Tone.Objective, headers=None
4):
5    task = open_task()
6    task["query"] = query
7    
8    chief_editor = ChiefEditorAgent(
9        task, websocket, stream_output, tone, headers
10    )
11    research_report = await chief_editor.run_research_task()
12    
13    if websocket and stream_output:
14        await stream_output("logs", "research_report", research_report, websocket)
15    
16    return research_report

(multi_agents/main.py:1-61)

Fehlerbehandlung:

  • Validierung der task.json-Konfiguration
  • Environment-Variable-Override für STRATEGIC_LLM
  • WebSocket-Optionalität für Batch-Processing

Alternative AG2-Implementierung

Das System bietet eine parallele Multi-Agenten-Implementierung:

python
1from multi_agents_ag2.agents import ChiefEditorAgent
2
3async def run_research_task(query, websocket=None, stream_output=None, 
4                            tone=Tone.Objective, headers=None):
5    task = open_task()
6    task["query"] = query
7    
8    chief_editor = ChiefEditorAgent(task, websocket, stream_output, tone, headers)
9    research_report = await chief_editor.run_research_task()
10    
11    return research_report

(multi_agents_ag2/main.py:1-60)

Client-Integration SDKs

GPT Researcher bietet mehrere Integrationsmöglichkeiten für verschiedene Anwendungsfälle.

JavaScript/Node.js SDK

Das NPM-Paket implementiert eine vollständige Client-Bibliothek:

javascript
1class GPTResearcher {
2    constructor(options = {}) {
3        this.host = options.host || 'http://localhost:8000';
4        this.socket = null;
5        this.responseCallbacks = new Map();
6        this.logListener = options.logListener;
7        this.tone = options.tone || 'Reflective';
8    }
9
10    async initializeWebSocket() {
11        const protocol = this.host.includes('https') ? 'wss:' : 'ws:';
12        const cleanHost = this.host.replace('http://', '').replace('https://', '');
13        const ws_uri = `${protocol}//${cleanHost}/ws`;
14        this.socket = new WebSocket(ws_uri);
15    }
16}

(docs/npm/index.js:1-123)

SDK-Features:

  • Automatische Protokoll-Erkennung (WS/WSS)
  • Callback-basierte Progress-Updates
  • HTTP-Fallback für nicht-WebSocket-Umgebungen

Discord-Bot-Integration

Der Discord-Bot demonstriert die Vielseitigkeit der API:

javascript
1client.on(Events.InteractionCreate, async interaction => {
2    if (interaction.isChatInputCommand()) {
3        if (interaction.commandName === 'ask') {
4            const modal = new ModalBuilder()
5                .setCustomId('myModal')
6                .setTitle('Ask the AI Researcher');
7            
8            const queryInput = new TextInputBuilder()
9                .setCustomId('queryInput')
10                .setLabel('Your question')
11                .setStyle(TextInputStyle.Paragraph);
12        }
13    }
14});

(docs/discord-bot/index.js:17-78)

Cooldown-Mechanismus: 30-Minuten-Intervall verhindert Spam im Help-Forum.

Datenfluss End-to-End-Aufrufkette

Der folgende Sequenzdiagramm zeigt den vollständigen Datenfluss von der Client-Anfrage bis zum fertigen Report:

正在加载图表渲染器...

Erklärung der Datenflussphasen:

  1. Request-Phase: Client sendet ResearchRequest an FastAPI, das den CustomLogsHandler initialisiert (backend/server/server_utils.py:33-123)

  2. Research-Phase: ResearchConductor nutzt Actions für Suchabfragen und Scraping, LLM generiert optimierte Queries (gpt_researcher/actions/init.py:1-27)

  3. Streaming-Phase: Progress-Updates werden über WebSocket an den Client gestreamt

  4. Generation-Phase: ReportGenerator erstellt den finalen Report mit Referenzen (gpt_researcher/skills/init.py:1-15)

Modulabhängigkeiten Dependency Graph

Die folgende Grafik zeigt die Abhängigkeitsrichtungen zwischen den Kernmodulen:

正在加载图表渲染器...

Abhängigkeitsregeln:

  • Entry Points (main.py) importieren nur die App-Schicht
  • App-Schicht importiert Utils, nie umgekehrt
  • Core-Agent ist unabhängig von Multi-Agenten-Systemen
  • Skills und Actions sind gleichberechtigte Dependencies des Core-Agent

Technologie-Stack Design-Entscheidungen

TechnologieVerwendungszweckBegründungAlternativen
FastAPIREST & WebSocket APIAsynchrone Unterstützung, automatische OpenAPI-DokumentationFlask, Django
PydanticDatenvalidierungType-Safety, automatische SerialisierungMarshmallow, attrs
UvicornASGI ServerProduktionsreife Performance, WebSocket-SupportGunicorn, Hypercorn
WebSocketEchtzeit-StreamingBidirektionale Kommunikation, geringe LatenzServer-Sent Events
LangGraphAgenten-OrchestrierungZustandsmaschinen-basierte WorkflowsLangChain, AutoGen
asyncioAsynchrone I/ONon-Blocking Operationen für parallele Scraping-TasksThreading, Multiprocessing
Python 3.11+LaufzeitumgebungType-Hints-Verbesserungen, Performance-OptimierungenPython 3.10, 3.9
JSONLogging & DatenspeicherungStrukturierte Logs, einfache ParsingSQLite, CSV

Kern-Design-Entscheidungen:

  1. Modulare Skill-Architektur: Ermöglicht einfache Erweiterung durch neue Skills ohne Core-Änderungen (gpt_researcher/skills/init.py:1-15)

  2. Dual-Storage Logging: Kombiniert Echtzeit-WebSocket mit persistenten JSON-Logs für Nachvollziehbarkeit (backend/server/server_utils.py:33-123)

  3. Graceful Degradation: ImageGenerator und andere optionale Features fallen bei fehlenden Dependencies elegant zurück (gpt_researcher/skills/image_generator.py:20-419)

  4. Multi-Agenten-Optionalität: Einfache Forschungsaufgaben benötigen nicht die Komplexität des Multi-Agenten-Systems (multi_agents/agent.py:1-16)

  5. Client-Agnostizismus: API-Design unterstützt Web, CLI, Discord und beliebige andere Clients (docs/npm/index.js:1-123)

Konfiguration Startprozess

Umgebungsvariablen

Das System nutzt dotenv für die Konfiguration:

python
1from dotenv import load_dotenv
2load_dotenv()

(main.py:1-37)

Wichtige Umgebungsvariablen:

VariableZweckStandard
STRATEGIC_LLMÜberschreibt LLM-Modell in Multi-AgentenAus task.json
LANGCHAIN_API_KEYAktiviert LangSmith-TracingOptional
OPENAI_API_KEYLLM-Provider-AuthentifizierungErforderlich

Server-Start

python
1if __name__ == "__main__":
2    import uvicorn
3    logger.info("Starting server...")
4    uvicorn.run(app, host="0.0.0.0", port=8000)

(main.py:1-37)

Startsequenz:

  1. Logging-Konfiguration wird initialisiert
  2. Umgebungsvariablen aus .env geladen
  3. FastAPI-App aus backend.server.app importiert
  4. Uvicorn startet auf Port 8000 mit 0.0.0.0 Binding

Paket-Installation

python
1setup(
2    name="gpt-researcher",
3    version="0.14.7",
4    python_requires='>=3.11',
5    package_dir={'gpt_researcher': 'gpt_researcher'},
6    packages=find_packages(exclude=exclude_packages),
7)

(setup.py:1-48)

Exkludierte Pakete: Selenium, FastAPI, LangGraph werden nicht als Dependencies installiert, um Konflikte zu vermeiden.