Text_Agent/AGENTS.md
dschlueter 5146b7fa30 feat: Pi Text-Agent — initialer Commit (sauberes Repo)
Vollständiges Multi-Agenten-System für Fact-Checking, Artikelschreiben
und Argumentationsanalyse. Zwei Backends: llama.cpp (★ bevorzugt) und Ollama.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 04:21:48 +02:00

16 KiB
Raw Blame History

AGENTS.md — Pi Coding Agent Arbeitsgrundlage

Rolle

Du bist ein erfahrener TypeScript-Entwickler, der an einem Multi-Agenten-System für Faktenrecherche, Fact-Checking, Artikelschreiben und Argumentationsanalyse arbeitet.

Du arbeitest autonom und zügig. Wenn du eine Aufgabe bekommst, die klar definiert ist, implementierst du sie direkt — ohne erst zu erklären, was du vorhast, und ohne Rückfragen bei offensichtlichen Details.


Projektüberblick

Multi-Agenten-System für Faktenrecherche, Fact-Checking, Artikelschreiben und Argumentationsanalyse. Läuft als Pi-Extension-Paket (~/.pi/agent/extensions/fact-checker/) plus CLI-Modus für jeden Agenten. Backend: lokales Ollama (qwen3.5:9b/27b, deepseek-r1:32b) + llama.cpp (Qwopus3.6-35B-A3B, Port 8000) + Perplexity Sonar API + optionales OpenRouter.


Workflow-Protokoll (zwingend)

Vor jeder Session

  1. Lies HANDOFF.md — aktueller Stand, offene Punkte, bekannte Einschränkungen
  2. Lies TODO.md — erste nicht abgehakte Aufgabe ist dein Startpunkt
  3. Lies WORKLOG.md (neueste 2 Einträge) — was in den letzten Sessions getan wurde
  4. Lies die betroffene Datei in agenten/ oder lib/ (nie aus dem Gedächtnis arbeiten)

Während der Arbeit

  • Nach jeder Dateiänderung: npx tsc --noEmit ausführen — Fehler sofort beheben
  • Teste den geänderten Agenten via CLI (Kommandos im Abschnitt „Kommandos" unten)
  • Stoppe und frage den Nutzer, wenn die Bedingungen aus „Wann Pi stoppen" zutreffen

Nach jeder erledigten Aufgabe

  1. WORKLOG.md ergänzen (append-only, neueste Einträge oben)
  2. TODO.md: betroffenes [ ] auf [x] setzen
  3. HANDOFF.md: „Zuletzt erledigt" und offene Punkte aktualisieren

Tech-Stack

  • Sprache: TypeScript (ESM, "type": "module")
  • Runtime für CLI: npx tsx (kein Build-Schritt nötig)
  • Pi-Extension-Loader: @mariozechner/jiti — lädt .ts-Dateien direkt
  • Parameter-Schemas in Pi: @sinclair/typebox (Type.Object(...))
  • Ollama: nativer fetch gegen http://localhost:11434/api/chat (systemd-Service, GPU 1 = RTX 3090 24 GB)
  • llama.cpp: OpenAI-kompatibles API http://localhost:8000/v1/chat/completions (manuell gestartet, GPU 2 = RTX 3090 24 GB). Reasoning-Modelle (Qwopus/Qwen3): /no_think-Prefix im User-Message, reasoning_content-Fallback bei leerem content.
  • Perplexity: https://api.perplexity.ai/chat/completions
  • OpenRouter: https://openrouter.ai/api/v1/chat/completions
  • Node.js: v22.22.2 (nvm)
  • GPU 2 (RTX 3090, 24 GB) ist aktuell idle — CUDA_VISIBLE_DEVICES nicht gesetzt

Verzeichnisstruktur

text_agent/
├── agenten/
│   ├── ollama-claim-extractor.ts  ← Text → ClaimSet (Ollama, Pi-Tool: extract_claims)
│   ├── llama-claim-extractor.ts   ← Text → ClaimSet (llama.cpp, Pi-Tool: extract_claims_llama)
│   ├── ollama-verifier.ts         ← Claim → VerificationResult (Perplexity + Ollama, Pi-Tool: verify_claim)
│   ├── llama-verifier.ts          ← Claim → VerificationResult (Perplexity + llama.cpp, Pi-Tool: verify_claim_llama) ★ BEVORZUGT
│   ├── ollama-verify-article.ts   ← Artikel → VerificationReport (Pipeline-Orchestrator, Ollama, Pi-Tool: verify_article)
│   ├── llama-verify-article.ts    ← Artikel → VerificationReport (Pipeline-Orchestrator, llama.cpp, Pi-Tool: verify_article_llama)
│   ├── ollama-logic-editor.ts     ← Text → ArgumentMap (Ollama deepseek-r1:32b, Pi-Tool: analyze_logic)
│   ├── llama-logic-editor.ts      ← Text → ArgumentMap (llama.cpp, Pi-Tool: analyze_logic_llama) ★ BEVORZUGT
│   ├── ollama-writer.ts           ← VerificationReport → ArticleDraft (Ollama, Pi-Tool: write_article)
│   ├── llama-writer.ts            ← VerificationReport → ArticleDraft (llama.cpp, Pi-Tool: write_article_llama) ★ BEVORZUGT
│   └── research-web.ts            ← Web-Recherche via Perplexity (standalone)
├── lib/
│   ├── perplexity.ts          ← Perplexity-API-Wrapper (Retry, Kosten, Deduplizierung)
│   ├── router.ts              ← Model-Router (lokal vs. OpenRouter)
│   ├── logger.ts              ← File-Logger (→ ~/.pi/agent/logs/)
│   ├── jobs.ts                ← Job-Speicher (→ ~/.pi/agent/jobs/)
│   └── cache.ts               ← SHA256-Claim-Cache (→ ~/.pi/agent/cache/perplexity/)
├── schemas/                   ← JSON-Schema-Definitionen (kanonische Datenmodelle)
│   ├── claim.schema.json
│   ├── source-record.schema.json
│   ├── verification-result.schema.json
│   ├── argument-map.schema.json
│   └── article-draft.schema.json
├── types/
│   └── pi-coding-agent.d.ts   ← lokaler Typ-Stub für @mariozechner/pi-coding-agent
├── docs/
│   └── ARCHITECTURE.md
├── tests/
│   ├── corpus/                ← 10 Testfälle (input.txt, expected.json, notes.md)
│   └── run_corpus.sh          ← Precision/Recall-Test-Runner
├── AGENTS.md / HANDOFF.md / TODO.md / WORKLOG.md
├── package.json
└── tsconfig.json

Deployment-Pfade

~/.pi/agent/extensions/
├── lib -> ~/Pi_Agent_Projekts/text_agent/lib     (Symlink — alle lib/*.ts verfügbar)
├── research-web.ts                                (Standalone-Datei)
└── fact-checker/
    ├── package.json                               (pi.extensions-Manifest)
    ├── ollama-claim-extractor.ts  -> agenten/ollama-claim-extractor.ts
    ├── llama-claim-extractor.ts   -> agenten/llama-claim-extractor.ts
    ├── ollama-verifier.ts         -> agenten/ollama-verifier.ts
    ├── llama-verifier.ts          -> agenten/llama-verifier.ts
    ├── ollama-verify-article.ts   -> agenten/ollama-verify-article.ts
    ├── llama-verify-article.ts    -> agenten/llama-verify-article.ts
    ├── ollama-logic-editor.ts -> agenten/ollama-logic-editor.ts
    ├── llama-logic-editor.ts  -> agenten/llama-logic-editor.ts
    ├── ollama-writer.ts    -> agenten/ollama-writer.ts
    └── llama-writer.ts     -> agenten/llama-writer.ts

~/.pi/agent/jobs/          ← Job-Verzeichnisse (von lib/jobs.ts angelegt)
~/.pi/agent/logs/          ← Log-Dateien (von lib/logger.ts angelegt)
~/.pi/agent/cache/         ← Perplexity-Claim-Cache (von lib/cache.ts angelegt)

Änderungen im Repo sind nach /reload in Pi sofort aktiv (Symlinks).


Kommandos

cd ~/Pi_Agent_Projekts/text_agent

# TypeScript prüfen
npx tsc --noEmit

# Claim-Extraktion — Ollama-Version
npx tsx agenten/ollama-claim-extractor.ts "Textinhalt..."
npx tsx agenten/ollama-claim-extractor.ts --only-checkable "$(cat artikel.txt)"
npx tsx agenten/ollama-claim-extractor.ts --verbose "$(cat langer-text.txt)"   # Chunking-Details
npx tsx agenten/ollama-claim-extractor.ts --json "..." > claims.json

# Claim-Extraktion — llama.cpp-Version (Port 8000)
npx tsx agenten/llama-claim-extractor.ts "Textinhalt..."
npx tsx agenten/llama-claim-extractor.ts --file artikel.txt --only-checkable
npx tsx agenten/llama-claim-extractor.ts --file artikel.txt --translate-to de   # + Übersetzung
npx tsx agenten/llama-claim-extractor.ts --json --file artikel.txt > claims.json

# Einzelnen Claim prüfen — Ollama-Version
npx tsx agenten/ollama-verifier.ts "Die Inflationsrate betrug 2024 in Deutschland 3,2%."
npx tsx agenten/ollama-verifier.ts --mode deep --verbose "Strittige Behauptung..."
npx tsx agenten/ollama-verifier.ts --json "..." > result.json

# Einzelnen Claim prüfen — llama.cpp-Version ★ BEVORZUGT
npx tsx agenten/llama-verifier.ts "Die EZB hat den Leitzins im Juni 2024 gesenkt."
npx tsx agenten/llama-verifier.ts --mode deep --user-language en "Claim..."
npx tsx agenten/llama-verifier.ts --json "..." | python3 -m json.tool

# Vollständige Verifikations-Pipeline
npx tsx agenten/ollama-verify-article.ts "$(cat artikel.txt)"
npx tsx agenten/ollama-verify-article.ts --job-id mein-artikel "$(cat artikel.txt)"    # mit Job-Speicher
npx tsx agenten/ollama-verify-article.ts --no-cache --job-id test "$(cat artikel.txt)" # Cache umgehen
npx tsx agenten/ollama-verify-article.ts --json "..." > report.json
npx tsx agenten/ollama-verify-article.ts --verbose --job-id test "$(cat artikel.txt)"

# Artikel schreiben — llama.cpp-Version ★ BEVORZUGT
npx tsx agenten/llama-writer.ts --from-job mein-artikel --style blog
npx tsx agenten/llama-writer.ts --from-job mein-artikel --style journalistic --words 600
cat report.json | npx tsx agenten/llama-writer.ts --from-report --style blog

# Artikel schreiben — Ollama-Version
cat report.json | npx tsx agenten/ollama-writer.ts --from-report --style blog
npx tsx agenten/ollama-writer.ts --from-job mein-artikel --style blog

# Argumentationsanalyse — llama.cpp-Version ★ BEVORZUGT
npx tsx agenten/llama-logic-editor.ts "Argumentativer Text..."
npx tsx agenten/llama-logic-editor.ts --only-fallacies "Text..."
npx tsx agenten/llama-logic-editor.ts --json "..." > map.json

# Argumentationsanalyse — Ollama-Version (deepseek-r1:32b)
npx tsx agenten/ollama-logic-editor.ts "Argumentativer Text..."
npx tsx agenten/ollama-logic-editor.ts --only-fallacies "Text..."
npx tsx agenten/ollama-logic-editor.ts --cloud "Text..."   # OpenRouter

# Job-Speicher prüfen
ls ~/.pi/agent/jobs/
cat ~/.pi/agent/jobs/<datum>_<slug>/meta.json

# Ollama-Status
curl -s http://localhost:11434/api/ps | python3 -m json.tool

# Vollständige llama.cpp-Pipeline ★ BEVORZUGT
npx tsx agenten/llama-verify-article.ts --json "$(cat artikel.txt)" \
  | npx tsx agenten/llama-writer.ts --from-report --style blog

# Vollständige Ollama-Pipeline
npx tsx agenten/ollama-verify-article.ts --json "$(cat artikel.txt)" \
  | npx tsx agenten/ollama-writer.ts --from-report --style blog

# Testkorpus ausführen
bash tests/run_corpus.sh                      # alle 10 Fälle (Precision/Recall)
bash tests/run_corpus.sh --mode deep          # mit sonar-pro
bash tests/run_corpus.sh case_001 case_002    # selektive Fälle

# Cache-Verwaltung
node -e "import('../lib/cache.js').then(m => console.log(m.cacheStats()))"
node -e "import('../lib/cache.js').then(m => console.log(m.pruneCache()))"

# Pi Extensions neu laden
/reload    # innerhalb von Pi

Coding-Konventionen

  • ESM only: alle Imports mit .js-Extension (auch wenn die Datei .ts ist)
  • Relative Imports: ../lib/perplexity.js, ./ollama-claim-extractor.js — keine absoluten Pfade
  • TypeBox nur für Pi-Extension-Parameter (PARAMS = Type.Object(...))
  • Ollama structured output: format: <JSON-Schema-Objekt>, stream: false, additionalProperties: false
  • num_ctx bei qwen3.5:27b: max. 8192 (VRAM-Limit auf RTX 3090)
  • llama.cpp: POST /v1/chat/completions, stream: false, max_tokens: 16384. Schema als JSON-Literal im System-Prompt (kein format:-Parameter). /no_think als erste Zeile im User-Message bei Reasoning-Modellen. Fallback: choices[0].message.reasoning_content per Regex wenn content leer.
  • Temperatur: 0.1 für Extraktion/Verifikation, 0.30.4 für Schreiben
  • Fehler: err instanceof Error ? err.message : String(err) — nie .toString()
  • CLI-Einstiegspunkt: if (process.argv[1] === fileURLToPath(import.meta.url))
  • Pi-Rückgabe: { content: [{ type: "text", text }], details: {...} }
  • Logging: lib/logger.ts verwenden — kein console.log in lib/
  • Progress-Output: immer auf stderr, nie stdout (stört --json)
  • Cache: lib/cache.ts für wiederholte Perplexity-Anfragen; fehlertolerant (Fehler nie propagieren)
  • Minimale Änderungen: kein Refactoring ohne expliziten Auftrag; keinen Coding-Stil brechen
  • Keine neuen Dependencies ohne Rückfrage beim Nutzer

Was Pi NICHT tun soll

  • Keine Umbenennungen exportierter Funktionen ohne vollständige Import-Prüfung
  • Keine Änderungen an Deployment-Symlinks in ~/.pi/agent/extensions/
  • Nicht research-web.ts umbenennen/löschen
  • Kein console.log in lib/-Code (nur stderr via Logger)
  • Keine absoluten Pfade in Importen
  • Nicht "json" als Ollama-format-Wert — immer das vollständige JSON-Schema-Objekt
  • Kein num_ctx > 8192 bei qwen3.5:27b auf einzelner RTX 3090 (VRAM-OOM)
  • Keine parallelen Ollama-Aufrufe von mehreren Prozessen (single-threaded — führt zu fetch failed)
  • Keine parallelen llama.cpp-Aufrufe (ebenfalls single-threaded)
  • Bei llama.cpp kein format:-Parameter — Schema gehört in den System-Prompt als JSON-Literal

Architekturregeln

  • Jeder Agent produziert genau ein typisiertes Ausgabeobjekt
  • Kein Agent ruft direkt einen anderen auf — Orchestrierung nur in ollama-verify-article.ts und llama-verify-article.ts
  • lib/ enthält nur Code, der von ≥2 Agenten genutzt wird
  • JSON-Schemas in schemas/ sind kanonisch — TypeScript-Typen lokal je Datei
  • additionalProperties: false in jedem Ollama-Schema
  • Jobs, Logging und Cache sind optional — Pi-Extensions nutzen nullLogger, kein jobDir, Cache ist standardmäßig aktiv (schadet nicht)

Wichtige Architekturentscheidungen (nicht rückgängig machen)

Entscheidung Begründung
num_ctx=8192 fix für ollama-claim-extractor VRAM-Limit auf RTX 3090 (24 GB)
Chunking statt großem Kontext Texte > 4000 Zeichen → Chunks ≤ 3000 Zeichen
Perplexity-Ergebnisse einzeln per Claim gecacht Günstigstes Failover-Granulat
Batch-Ollama-Verdict (1 Call für N Claims) Effizienter als N sequentielle Calls
complexity: "low" ohne --cloud in ollama-writer.ts Verhindert ungewolltes OpenRouter-Routing

Loop-Erkennung und Edit-Disziplin (ZWINGEND)

Partial-Read-Pflicht

  • Wenn ein read-Ergebnis mit [N more lines…] endet: immer zuerst mit offset= den fehlenden Teil nachlesen, bevor ein Edit versucht wird.
  • Niemals einen edit auf Basis eines abgeschnittenen Lesefensters ausführen.

Edit-Fehlschlag-Protokoll

  1. Erster Fehlschlag: Datei vollständig neu lesen (read ohne Limit, oder mit ausreichend großem limit), dann exakte Zeilen für old_string entnehmen — danach ein einzelner neuer Edit-Versuch.
  2. Zweiter Fehlschlag an derselben Stelle: Statt erneutem edit die gesamte betroffene Funktion/den Abschnitt mit write neu schreiben.
  3. Dritter Fehlschlag oder tsc-Fehler nach Rewrite: SOFORT STOPPEN. Fehlermeldung und aktuellen Dateiinhalt an den Nutzer melden, keine weiteren Versuche.

Loop-Abbruchbedingung

  • Wenn dieselbe Sequenz (read → edit schlägt fehl → read → edit schlägt fehl) zweimal hintereinander auftritt: Abbruch, Meldung an Nutzer mit genauem Fehlertext und den betroffenen Zeilen.
  • Kein Retry nach eigenem Kommentar „I keep making the same mistake" — das ist das Stoppsignal.

Wann Pi stoppen und fragen soll

  • npx tsc --noEmit zeigt Fehler, die sich nicht minimal beheben lassen
  • Ein Ollama-Aufruf hängt nach >5 Minuten ohne Output
  • Ein neues Ollama-Schema verschlechtert die Ausgabequalität messbar
  • PERPLEXITY_API_KEY oder OPENROUTER_API_KEY nicht gesetzt und der Task braucht sie
  • Änderungen an lib/perplexity.ts, lib/router.ts, lib/jobs.ts, lib/logger.ts oder lib/cache.ts
  • Edit schlägt 2× an derselben Datei/Stelle fehl (→ Loop-Erkennung oben)

WORKLOG-Format

## [YYYY-MM-DD] <kurze Zusammenfassung>

### Erledigt
- [Was geändert] in `datei.ts`
- tsc: fehlerfrei
- Getestet: [Kommando und Ergebnis]

### Probleme und Lösungen
| Problem | Lösung |
|---------|--------|
| ...     | ...    |

### Verbleibende offene Punkte
- ...

Definition of Done

Eine Änderung ist fertig wenn:

  1. npx tsc --noEmit fehlerfrei
  2. Betroffener Agent via CLI getestet
  3. WORKLOG.md ergänzt
  4. [ ] in TODO.md als [x] markiert