# 🔌 Proxy API — klaude-proxy
## 🤔 ¿Qué hago? ¿Cómo lo hago? ¿Y para qué lo hago?
**¿Qué hago?**
Expongo una API HTTP compatible con la API de Anthropic Messages. Claude Code (y cualquier cliente del SDK de Anthropic) puede apuntar a este proxy sin modificar nada más que `ANTHROPIC_BASE_URL`.
**¿Cómo lo hago?**
Con FastAPI en Python 3.12, implementando los mismos endpoints y schemas que `api.anthropic.com`. Añado cabeceras `X-Cache` para observabilidad (ver tabla completa abajo).
**¿Y para qué lo hago?**
Para ser completamente transparente al cliente — ningún código de aplicación necesita saber que existe un proxy.
---
## 📡 Endpoints
### `POST /v1/messages`
Endpoint principal. Compatible con la [Anthropic Messages API](https://docs.anthropic.com/en/api/messages).
**Request:** idéntico al de Anthropic.
**Response headers adicionales:**
| `X-Cache` | Significado |
| --- | --- |
| `HIT` | Respuesta servida directamente desde caché (score ≥ 0.98, sin llamar al LLM) |
| `MISS` | Sin ningún hit — respuesta obtenida de Anthropic sin contexto adicional |
| `CACHE-RAG` | Cache hit parcial (score 0.87–0.97) inyectado como RAG context, se llama al LLM |
| `KNOWLEDGE-RAG` | Chunks de `klaude_knowledge` inyectados en system prompt, se llama al LLM |
| `SOURCES-RAG` | Chunks de `klaude_sources` inyectados en system prompt, se llama al LLM |
| `CACHE+KNOWLEDGE-RAG` | Cache RAG + Knowledge RAG combinados |
| `CACHE+SOURCES-RAG` | Cache RAG + Sources RAG combinados |
| `CACHE+KNOWLEDGE+SOURCES-RAG` | Los tres contextos RAG combinados |
| `MANUAL-STORE` | Trigger `kache` procesado — par Q&A almacenado en caché |
| `MANUAL-ERROR` | Trigger `kache` sin historial Q&A previo en la conversación |
**Soporte streaming:** completo. Si `stream: true`, el proxy devuelve SSE correctamente en todos los modos.
---
### `GET /health`
```json
{"status": "ok", "version": "0.1.0"}
```
---
### `GET /cache/stats`
```json
{
"collection": "klaude_cache",
"vectors_count": 142,
"points_count": 142,
"status": "green"
}
```
> 📌 `vectors_count` puede ser `null` en versiones modernas de `qdrant-client`. El dashboard usa `points_count` como fallback — ambos valores son equivalentes en esta colección.
---
### `GET /dashboard`
Dashboard de observabilidad en tiempo real. Página HTML con:
- **Live Logs** vía SSE (`/logs/stream`)
- **Request Content** — texto plano de cada petición enviada a Anthropic
- **Session Counters** — hits, misses, vectores indexados
- **Costes** — USD gastados y ahorrados + tokens in/out
- **Llamadas Proveedor** — salientes (MISSes) y entrantes (respuestas)
---
### `GET /logs`
```json
[
{"ts": "2026-07-14T09:30:00Z", "level": "INFO", "msg": "CACHE HIT hash=a1b2c3d4..."},
...
]
```
Parámetro opcional: `?n=200` (default 200).
---
### `GET /logs/stream`
SSE stream de logs en tiempo real. Usado por el dashboard. Emite eventos `data: <log-line>\n\n`.
---
### `GET /analytics/stats`
Agregados de la sesión actual (resetean al reiniciar el proxy). Ver [analytics.md](analytics.md).
---
### `GET /analytics/requests?n=50`
Últimas N peticiones de SQLite (históricas, persisten entre reinicios). Ver [analytics.md](analytics.md).
---
### `GET /analytics/history`
Totales acumulados de todas las sesiones históricas en SQLite. Ver [analytics.md](analytics.md).
---
### `DELETE /cache/flush`
Borra y recrea la colección `klaude_cache` (hard flush). Requiere header `x-api-key`.
```bash
curl -X DELETE -H "x-api-key: test" http://localhost:8080/cache/flush
```
```json
{"flushed": true, "deleted_points": 42, "collection": "klaude_cache"}
```
---
### `DELETE /cache/clear`
Elimina todos los puntos pero mantiene la estructura de la colección (soft wipe). Más rápido que flush.
```bash
curl -X DELETE -H "x-api-key: test" http://localhost:8080/cache/clear
```
```json
{"cleared": true, "deleted_points": 42, "collection": "klaude_cache"}
```
---
### Knowledge base — `klaude_knowledge`
| Endpoint | Método | Descripción |
| --- | --- | --- |
| `/knowledge/ingest` | `POST` | Recibe chunks pre-procesados del dashboard, los embebe y almacena |
| `/knowledge/stats` | `GET` | Estadísticas de la colección `klaude_knowledge` |
| `/knowledge/flush` | `DELETE` | Borra y recrea la colección. Requiere `x-api-key`. |
Ver [knowledge_base.md](knowledge_base.md) para detalles de payload y respuestas.
---
### Sources — `klaude_sources`
| Endpoint | Método | Descripción |
| --- | --- | --- |
| `/sources/ingest/web` | `POST` | Crawlea URL con Crawl4AI y almacena chunks. Requiere `x-api-key`. |
| `/sources/ingest/markdown` | `POST` | Indexa markdown por URL o texto directo. Requiere `x-api-key`. |
| `/sources/ingest/pdf` | `POST` | Extrae texto de PDF (multipart). Requiere `x-api-key`. |
| `/sources/stats` | `GET` | Estadísticas de la colección `klaude_sources` |
| `/sources/flush` | `DELETE` | Borra y recrea la colección. Requiere `x-api-key`. |
| `/sources/jobs/{job_id}` | `GET` | Estado de un deep crawl en background |
Ver [sources.md](sources.md) para detalles de payload y respuestas.
---
## ⚙️ Variables de entorno
### Anthropic / Ollama
| Variable | Requerida | Default | Descripción |
| --- | --- | --- | --- |
| `ANTHROPIC_API_KEY` | ⚠️ | `""` | Se reenvía a api.anthropic.com. Opcional si usas exclusivamente Ollama. |
| `DEFAULT_MODEL` | ❌ | `claude-haiku-4-5-20251001` | Modelo usado cuando el cliente no especifica ninguno |
| `OLLAMA_BASE_URL` | ❌ | `http://localhost:11434` | URL base del servidor Ollama local |
| `OLLAMA_TIMEOUT_SECONDS` | ❌ | `120` | Timeout en segundos para llamadas a Ollama |
### Qdrant y caché semántica
| Variable | Requerida | Default | Descripción |
| --- | --- | --- | --- |
| `QDRANT_URL` | ❌ | `http://qdrant:6333` | URL de Qdrant |
| `QDRANT_COLLECTION` | ❌ | `klaude_cache` | Nombre de la colección de caché semántica |
| `EMBEDDING_DIMENSIONS` | ❌ | `768` | Dimensiones del vector (nomic-v1.5) |
| `SIMILARITY_THRESHOLD` | ❌ | `0.87` | Umbral mínimo para RAG context injection (score ≥ 0.87 inyecta como CACHE-RAG) |
| `CACHE_RAG_DIRECT_THRESHOLD` | ❌ | `0.98` | Umbral para retorno directo de caché sin llamar al LLM (score ≥ 0.98 → X-Cache: HIT) |
| `CACHE_TOOL_RESPONSES` | ❌ | `false` | Cachear respuestas con tool_use (no recomendado) |
| `PROXY_PORT` | ❌ | `8080` | Puerto de escucha del proxy |
### Knowledge base
| Variable | Requerida | Default | Descripción |
| --- | --- | --- | --- |
| `KNOWLEDGE_SIMILARITY_THRESHOLD` | ❌ | `0.75` | Umbral dense para búsqueda híbrida en `klaude_knowledge` |
### Sources (web/markdown/PDF)
| Variable | Requerida | Default | Descripción |
| --- | --- | --- | --- |
| `SOURCES_SIMILARITY_THRESHOLD` | ❌ | `0.75` | Umbral de similitud para búsqueda en `klaude_sources` |
| `CRAWL4AI_API_BASE` | ❌ | `http://crawl4ai:11235` | URL base del servicio Crawl4AI |
| `CRAWL4AI_API_TOKEN` | ❌ | `""` | Token de autenticación para Crawl4AI (mismo valor que el contenedor) |
> 📌 No se necesita ninguna API key de embeddings — el modelo corre localmente dentro del contenedor.
---
## 🔗 Documentos relacionados
- [architecture.md](architecture.md) — Visión general del sistema
- [cache.md](cache.md) — Estrategia de caché y embeddings
- [setup.md](setup.md) — Instalación y configuración de Claude Code