feat(analysis): Ground Step 8 Reference Analysis
Improves the competitor reference analysis (Step 8) by replacing the previous LLM-only approach with a grounded, scraping-based method. - Implemented a new scraper to actively search for and parse competitor reference/case study pages. - The analysis is now based on actual website content, significantly increasing the accuracy and reliability of the results and preventing model hallucinations. - Updated documentation to reflect the new 'Grounded References' architecture.
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
# Migration Report: Competitor Analysis Agent
|
||||
|
||||
## Status: Jan 10, 2026 - ✅ FINAL SUCCESS
|
||||
## Status: Jan 11, 2026 - ✅ ROBUSTNESS UPGRADE COMPLETE
|
||||
|
||||
Die App ist unter `/ca/` voll funktionsfähig und verfügt nun über eine "Grounded Truth" Engine (Scraping + SerpAPI). Diese Migration dauerte aufgrund einer extremen Fehlerverkettung über 5 Stunden.
|
||||
Die App ist unter `/ca/` voll funktionsfähig und verfügt nun über eine "Grounded Truth" Engine (Scraping + SerpAPI) sowie eine skalierbare **Map-Reduce Architektur**.
|
||||
|
||||
### 🚨 Vollständige Chronik der Fehler & Lösungen
|
||||
|
||||
@@ -35,18 +35,46 @@ Die App ist unter `/ca/` voll funktionsfähig und verfügt nun über eine "Groun
|
||||
* **Ursache:** Einfache Anführungszeichen `'` in Kombination mit `\n` wurden im Container-Kontext falsch interpretiert.
|
||||
* **Lösung:** **ULTIMATIVE SYNTAX:** Verwendung von **Triple Raw Quotes (`r"""..."""`)** für jeden einzelnen String, der Variablen oder Sonderzeichen enthält.
|
||||
|
||||
8. **Problem: Analyse stoppt nach 5 Konkurrenten (Token Limit / Lazy LLM)**
|
||||
* **Symptom:** Bei 9 Konkurrenten wurden nur die ersten 5 analysiert, der Rest fehlte.
|
||||
* **Ursache:** Der riesige Prompt ("Analysiere alle 9...") überforderte das Kontext-Fenster oder führte zu Timeouts.
|
||||
* **Lösung:** Umstellung auf **Map-Reduce**: Jeder Konkurrent wird in einem eigenen parallelen Task (`asyncio.gather`) analysiert. Erhöhung von `max_output_tokens` auf 8192.
|
||||
|
||||
9. **Problem: `NameResolutionError` im Container**
|
||||
* **Symptom:** Scraping schlug fehl ("Name or service not known").
|
||||
* **Ursache:** Docker-Container nutzten den (instabilen) Host-DNS.
|
||||
* **Lösung:** Explizites Setzen von Google DNS (`8.8.8.8`, `8.8.4.4`) in `docker-compose.yml`.
|
||||
|
||||
10. **Problem: `422 Unprocessable Entity` in Schritt 6 & 8**
|
||||
* **Ursache:** Diskrepanz zwischen Frontend-Request (z.B. sendet `industries`) und Backend-Pydantic-Modell (erwartet `target_industries`).
|
||||
* **Lösung:** Backend-Modelle exakt an die Frontend-Payloads angepasst.
|
||||
|
||||
11. **Problem: Leere Matrizen in der Conclusion**
|
||||
* **Ursache:** Das LLM füllte das `availability`-Array nicht korrekt oder erfand eigene Produktnamen als Zeilenbeschriftung.
|
||||
* **Lösung:** Extrem strikter Prompt ("KEINE Produktnamen", "GENAU einen Eintrag pro Kategorie") und detailliertes JSON-Schema.
|
||||
|
||||
12. **Problem: Blinde KI in Schritt 8 (Referenzen)**
|
||||
* **Symptom:** Die Referenzanalyse lieferte nur generische, oft erfundene Branchen, anstatt echter Kunden.
|
||||
* **Ursache:** Der Prompt bat die KI, "nach Referenzen zu suchen", ohne ihr eine Datengrundlage zu geben. Die KI hat halluziniert.
|
||||
* **Lösung:** Implementierung einer **"Grounded" Referenz-Suche**.
|
||||
1. Ein neuer Scraper (`discover_and_scrape_references_page`) sucht gezielt nach "Referenzen", "Case Studies" oder "Kunden" auf der Website des Wettbewerbers.
|
||||
2. Der Inhalt DIESER Seiten wird extrahiert.
|
||||
3. Nur dieser "grounded" Text wird an das LLM zur Analyse und Extraktion übergeben.
|
||||
* **Ergebnis:** Die Analyse basiert nun auf Fakten von der Webseite des Wettbewerbers, nicht auf dem allgemeinen Wissen der KI.
|
||||
|
||||
### 🛡️ Die finale "Grounded" Architektur
|
||||
|
||||
* **Scraping:** Nutzt `requests` und `BeautifulSoup`, um nicht nur die Homepage, sondern auch Produkt- und Branchen-Unterseiten zu lesen.
|
||||
* **Discovery:** Findet relevante Links automatisch auf der Homepage.
|
||||
* **SerpAPI:** Sucht via Google (`site:domain.com`) nach den tiefsten Fakten, bevor die KI gefragt wird.
|
||||
* **Logging:** Jede KI-Anfrage und jede Antwort wird im `DEBUG`-Level vollständig protokolliert.
|
||||
* **Grounded References:** Für die Referenzanalyse (Schritt 8) wird nun gezielt nach "Case Study" oder "Kunden"-Seiten gescraped, um die Extraktion auf echte Daten zu stützen und Halluzinationen zu vermeiden.
|
||||
* **Map-Reduce:** Statt eines Riesen-Prompts werden Konkurrenten parallel einzeln analysiert. Das skaliert linear.
|
||||
* **Logging:** Ein spezieller `log_debug` Helper schreibt direkt in `/app/Log_from_docker`, um Python-Logging-Probleme zu umgehen.
|
||||
|
||||
### Lessons Learned für die Ewigkeit
|
||||
|
||||
1. **F-STRINGS SIND VERBOTEN** für Prompts und komplexe Listen-Operationen.
|
||||
2. **TRIPLE RAW QUOTES (`r"""..."""`)** sind der einzige sichere Weg für Strings in Docker-Umgebungen.
|
||||
3. **DUAL SDK STRATEGY:** Legacy SDK für Stabilität (`gemini-2.0-flash`), Modern SDK für Spezial-Features.
|
||||
4. **API KEY LOADING:** Immer `/app/gemini_api_key.txt` ZUERST prüfen, dann Environment.
|
||||
4. **MAP-REDUCE:** Bei Listen > 3 Elementen niemals das LLM bitten, "alle auf einmal" zu bearbeiten. Immer zerlegen (Map) und aggregieren (Reduce).
|
||||
5. **SCHEMA FIRST:** Frontend (`types.ts`) und Backend (`Pydantic`) müssen *vorher* abgeglichen werden. `422` bedeutet fast immer Schema-Mismatch.
|
||||
---
|
||||
*Dokumentation finalisiert am 10.01.2026 nach erfolgreicher Migration und Grounding-Implementierung.*
|
||||
*Dokumentation aktualisiert am 11.01.2026 nach erfolgreicher Skalierung auf 9+ Konkurrenten.*
|
||||
|
||||
Reference in New Issue
Block a user