NOESIS
README.md
# NOESIS v2
> **NOESIS non è un insieme di tool. È un sistema di ottimizzazione cognitiva esposto come server MCP.**
NOESIS è un motore di amplificazione cognitiva che qualsiasi LLM host (Claude, GPT, modelli locali) può invocare via [Model Context Protocol](https://modelcontextprotocol.io). Riceve un task, stima quanto "pensiero" merita, acquisisce conoscenza se serve, ragiona tramite self-consistency campionaria e MCTS, risolve conflitti con argumentation framework di Dung, verifica simbolicamente e restituisce una risposta con confidenza misurata (intervallo Dempster-Shafer) e traccia di ragionamento completa.
## Il modello formale
```
N(T) = A(V(R(K(T)))) con obiettivo: max Q / C
```
| Simbolo | Significato | Modulo v2 |
|---------|-------------|-----------|
| `K` | Acquisizione conoscenza | `knowledge/search.py`, `knowledge/evidence.py` |
| `R` | Ragionamento | `reasoning/self_consistency.py`, `reasoning/mcts.py`, `reasoning/dung.py` |
| `V` | Verifica | `verification/sympy_v.py`, `verification/sandbox_v.py`, `verification/cross_source_v.py` |
| `A` | Adattamento | `memory/`, `memory/evolution.py` |
**Q** = qualità (consensus × verification × confidence), **C** = costo computazionale. L'intero sistema esiste per massimizzare questo rapporto: Expected Value of Computation (EVC) impedisce sprechi sui task semplici e garantisce profondità su quelli difficili — per derivazione matematica, non per if/else.
## Pipeline v2
```
INPUT (task, context)
↓
[1] Complexity Estimator Cₜ = w₁L + w₂D + w₃U + w₄M (0–100)
[2] Knowledge Gap Estimator G = 1 − P(Knowledge) (0–1)
[3] Planner Method = f(C, G)
↓
[4] EVC Gate ─── budget B = C × U; se EVC < costo → risposta diretta
↓
[5] Search (se gap alto) → Evidence → (A, C, U)
↓
[6] Self-Consistency sampling (K campioni) / MCTS (task decomponibili)
[7] Dung Argumentation: grafo di attacco → grounded extension
↓
[8] Verifica simbolica: sympy | sandbox | cross-source → TruthScore
[9] Confidenza: entropia ⊕ Dempster-Shafer ⊕ TruthScore → [belief, plausibility]
[10] EVC Loop: ΔE[Quality] > costo marginale? → altri campioni : stop
↓
[11] Memory + Evolution: Fitness = Quality / Cost
↓
OUTPUT (answer + [belief, plausibility] + evidence + trace)
```
### Il cambio di paradigma v1 → v2
| Funzione | v1 | v2 |
|----------|----|----|
| Esplorazione | Tree-of-Thought + agenti | **MCTS + UCB1** |
| Consenso | Debate tra 4 persona | **Self-consistency campionaria** |
| Conflitti | Agente Critic | **Dung argumentation framework** |
| Verifica | LLM-as-judge | **Solver simbolici** (sympy, sandbox, cross-source) |
| Confidenza | Stima LLM | **Entropia + Dempster-Shafer** — misurata, non dichiarata |
| Budget | Euristica su cicli | **Expected Value of Computation** (Russell & Wefald) |
| Generazione | Multipli LLM | **UN solo Generator** (pluggable: host/local/api/mock) |
## I tool esposti
| Tool | Cosa fa |
|------|---------|
| `noesis(task, context="")` | Pipeline cognitiva completa → answer + confidence + trace |
| `noesis_estimate(task)` | Solo stime senza eseguire la pipeline (~zero costo) |
| `noesis_memory_stats()` | Strategie apprese e ranking fitness |
## Architettura
```
noesis/
├── pyproject.toml
├── noesis.toml # config v2
├── README.md
├── file md/ # documenti di progetto
│
├── src/noesis/
│ ├── server.py # entry point MCP (FastMCP, stdio + SSE)
│ ├── controller.py # ★ la pipeline cognitiva v2
│ ├── state.py # CognitiveState + NoesisResult (pydantic)
│ ├── config.py # config tipizzata da noesis.toml + env override
│ ├── evolution.py # re-export per clean import
│ │
│ ├── generation/ # ★ UNICO modulo neurale
│ │ ├── base.py # Generator Protocol + Sample
│ │ ├── host.py # MCP Sampling (zero-config)
│ │ ├── local.py # Ollama / locale
│ │ ├── api.py # OpenAI-compatible endpoint
│ │ ├── mock.py # Mock deterministico (test)
│ │ └── autoselect.py # host → local → api fallback
│ │
│ ├── reasoning/ # ★ tutto deterministico
│ │ ├── self_consistency.py # clustering + agreement
│ │ ├── mcts.py # MCTS + UCB1
│ │ └── dung.py # argumentation framework
│ │
│ ├── estimators/
│ │ ├── complexity.py # Cₜ = w₁L + w₂D + w₃U + w₄M
│ │ └── knowledge_gap.py # G = 1 − P(Knowledge)
│ │
│ ├── budget/
│ │ └── evc.py # EVC: Expected Value of Computation
│ │
│ ├── planner/ # Workflow = f(C, G)
│ │ └── __init__.py
│ │
│ ├── verification/ # simbolici, deterministici
│ │ ├── base.py # Verifier protocol + registry + router
│ │ ├── sympy_v.py # verifica equazioni matematiche
│ │ ├── sandbox_v.py # esegue codice in subprocess isolato
│ │ └── cross_source_v.py # accordo tra fonti indipendenti
│ │
│ ├── confidence/
│ │ ├── entropy.py # entropia campionaria normalizzata
│ │ └── dempster_shafer.py # fusione evidenza (belief, plausibility)
│ │
│ ├── knowledge/
│ │ ├── search.py # Tavily / Brave / SearXNG / offline
│ │ └── evidence.py # estrazione (A, C, U)
│ │
│ └── memory/
│ ├── store.py # SQLite strategie
│ ├── retrieval.py # similarità Jaccard + sequence
│ └── evolution.py # Fitness = Quality/Cost bandit
│
└── tests/ # tutti offline (MockGenerator)
├── test_config.py # 8 test
├── test_estimators.py # 9 test
├── test_verification.py # 8 test
└── test_e2e.py # 3 test (pipeline completa con mock)
```
## Dipendenze
Solo 4 librerie: `mcp`, `pydantic`, `httpx`, `sympy`. Zero dipendenze cloud obbligatorie.
### Generatori (uno solo serve, zero-config possibile)
| Backend | Config | Note |
|---------|--------|------|
| **HostGenerator** ⭐ | `mode = "host"` | Usa l'LLM dell'host via MCP Sampling. **Nessuna API key, nessun modello locale.** |
| **LocalGenerator** | `mode = "local"` | Ollama / llama.cpp. 100% offline, logprobs disponibili. |
| **APIGenerator** | `mode = "api"` | OpenAI / Anthropic / OpenRouter / qualunque compatibile. |
| **MockGenerator** | `mode = "mock"` | Deterministico, solo per test. |
Selezione automatica: `mode = "auto"` → HostGenerator → LocalGenerator → APIGenerator → errore.
### Provider LLM supportati
| Provider | Chiave API (env var) |
|----------|---------------------|
| **OpenRouter** | `OPENROUTER_API_KEY` |
| **Anthropic** | `ANTHROPIC_API_KEY` |
| **OpenAI** | `OPENAI_API_KEY` |
| **Groq** | `GROQ_API_KEY` |
| **Mistral** | `MISTRAL_API_KEY` |
| **DeepSeek** | `DEEPSEEK_API_KEY` |
| **Together** | `TOGETHER_API_KEY` |
| **Ollama / LM Studio** | *(nessuna)* |
| **Custom** | `NOESIS_API_KEY` + `base_url` |
## Configurazione rapida
```bash
# 1. Clona e installa
git clone <repo> noesis && cd noesis
pip install -e .
# 2. Nessuna chiave? Il server funziona lo stesso:
# - con host MCP che supporta sampling (Claude, Cursor, ecc.)
# - con Ollama in locale (nessuna configurazione extra)
# - con una key API (basta impostare NOESIS_API_KEY)
# 3. Avvia il server (stdio, per Claude Desktop / Cursor)
noesis-server
# Oppure in modalità SSE (istanza condivisa)
noesis-server --sse
```
### Config via env (comodo nei client MCP)
```
NOESIS_GENERATOR_MODE=auto
NOESIS_API_KEY=sk-or-...
NOESIS_SEARCH_PROVIDER=tavily
NOESIS_MAX_TOKENS_PER_TASK=60000
```
Ogni chiave in `noesis.toml` può essere sovrascritta da `NOESIS_*`.
## Integrazione host MCP
### Claude Code
```bash
claude mcp add noesis -- pipx run noesis-server
```
### Claude Desktop
```json
{
"mcpServers": {
"noesis": {
"command": "noesis-server",
"env": { "NOESIS_GENERATOR_MODE": "api", "NOESIS_API_KEY": "sk-or-..." }
}
}
}
```
### Cursor / Windsurf
Stessa configurazione in `.cursor/mcp.json`.
## Test (100% offline)
```bash
uv run pytest # 28 test, nessuna chiamata LLM
```
## La tesi centrale
```
Quality(LLM_piccolo + NOESIS) vs Quality(LLM_grande da solo)
```
Se un modello 7B locale con NOESIS si avvicina a un modello frontier nudo su GSM8K/AIME, la tesi è dimostrata: il potenziamento viene dalla struttura matematica, non da modelli più forti.
## Documenti di progetto
- [`file md/NOESIS_v2_architettura_definitiva.md`](file%20md/NOESIS_v2_architettura_definitiva.md) — architettura v2 completa
- [`file md/NOESIS_struttura.md`](file%20md/NOESIS_struttura.md) — modello formale
- [`file md/NOESIS_architettura_software.md`](file%20md/NOESIS_architettura_software.md) — architettura software v1
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing