Skip to main content
Glama
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