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

327 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
```bash
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