Die Sub-Agents aus ADR-0003 brauchen Werkzeuge: Web-Search (News, Recherche), Aufruf externer Daten-APIs (Marktdaten, Filings), Berechnungs-Tools (Indikatoren, Backtests, Risiko), Dokument-Extraktion (PDFs). Ohne Tools sind LLMs auf ihr Trainingswissen begrenzt — was im Investment-Kontext nutzlos und gefährlich ist.
Tools können auf zwei Arten an Agents angebunden werden: als Python-Funktionen (Code-Tools, tightly coupled) oder als MCP-Server (Model Context Protocol, standardisierte externe Schnittstelle).
Wir setzen auf einen Hybrid-Ansatz:
@agent.tool) für Trading-Domain-spezifische, performance-kritische, state-gekoppelte Logik (Marktdaten, Indikatoren, Backtests, Risiko-Metriken).| Tool | Zweck | Quelle / Wartung |
|---|---|---|
| Tavily Search | AI-optimierte Web-Suche mit Relevanz-Scoring. News-Recherche, Sentiment-Quellen. | Offizielles Tavily MCP, Key in .env (gesetzt). |
| Tavily Extract | Volltext aus URL extrahieren, Markdown-konvertiert. Geschäftsberichte, Press Releases. | Selbes Tavily MCP. |
| SEC EDGAR | 10-K, 10-Q, 8-K-Filings (Volltext + Metadaten). Für US-Aktien. | Community-MCP (z. B. sec-edgar-mcp). Backup: SEC EDGAR REST-API direkt. |
| Fetch | Allgemeines URL-Fetching mit Markdown-Konvertierung, für Quellen außerhalb der speziellen Tools. | Offizielles mcp-server-fetch. |
| Jina Reader (Fallback) | Free-Tier-Fallback für URL-Extraktion (https://r.jina.ai/<url>). |
Eigener dünner MCP-Wrapper oder direkter Code-Aufruf (s. u.). |
| Time | Timezone-aware Zeitabfragen, Market-Hours-Checks. | Offizielles mcp-server-time. |
| Tool | Zweck | Implementierung |
|---|---|---|
get_eod_prices |
EOD-Preise für Ticker + Zeitraum. | Provider-Adapter (yfinance v1, später Tiingo/Polygon — siehe ADR-0009). Lokaler SQLite-Cache. |
get_fundamentals |
Fundamentaldaten (PE, P/B, EPS-History, Margins). | yfinance v1, später Provider-Switch. |
compute_indicators |
Technische Indikatoren (RSI, MACD, Bollinger, MA). | pandas-ta oder eigene Funktionen über pandas. |
run_backtest |
Strategie-Backtest auf historischen Daten. | vectorbt oder backtesting.py (Entscheidung in ADR-0010). |
compute_risk_metrics |
Drawdown, Vola, Sharpe, Korrelation zu Watchlist-Items. | numpy/pandas direkt. |
parse_pdf |
Geschäftsberichte als PDF lesen, in strukturierten Text umwandeln. | pdfplumber oder pymupdf. |
get_watchlist / get_run_history |
Lesezugriff auf interne State-DB (Watchlists, vergangene Runs, Decisions). | Direktes SQLite-Repository-Pattern. |
Jeder Sub-Agent erhält explizit nur die Tools, die er braucht. Least-Privilege wird im Code durchgesetzt (Tools werden in der Agent-Konstruktion registriert; was nicht registriert ist, kann der Agent nicht aufrufen).
| Agent | MCP-Tools | Code-Tools |
|---|---|---|
| Screener | — | get_eod_prices, compute_indicators (limitiert auf simple Filter), get_watchlist |
| Research | Tavily Search/Extract, SEC EDGAR, Fetch, Jina, Time | parse_pdf |
| Analyst | — | get_eod_prices, get_fundamentals, compute_indicators |
| Strategy | — | run_backtest, Read-Access auf Research-/Analyst-Outputs |
| Critic | Tavily Search (Counter-Research) | Read-Access auf Strategy-Output, get_eod_prices (Spot-Checks) |
| Risk-Assessment | — | get_eod_prices, compute_risk_metrics, get_run_history |
| Coordinator | — | (kein Agent, kein LLM — orchestriert nur) |
Pydantic AI unterstützt MCP-Server-Clients nativ. MCP-Server werden beim App-Start als
Sub-Prozesse oder über HTTP-Endpunkte aufgebaut und ihre Tools dem jeweiligen Agent
zugewiesen. Konfiguration in config/mcp.yaml:
mcp_servers:
tavily:
transport: stdio
command: ["npx", "-y", "@tavily/mcp-server"]
env:
TAVILY_API_KEY: ${TAVILY_API_KEY}
sec_edgar:
transport: stdio
command: ["uvx", "sec-edgar-mcp"]
fetch:
transport: stdio
command: ["uvx", "mcp-server-fetch"]
time:
transport: stdio
command: ["uvx", "mcp-server-time"]
Jeder Tool-Call (MCP oder Code) wird ins Decision-Log geschrieben (ADR-0012): Tool-Name, Argumente, Result-Hash (nicht der volle Result, kann groß sein — voller Result separat als Blob referenziert), Latenz, ggf. Fehler. Damit ist jede Empfehlung im Nachhinein bis auf den letzten Tool-Call rekonstruierbar.