Livrare LOT 1 - Didi
This commit is contained in:
commit
5380c3fc63
990 changed files with 133308 additions and 0 deletions
193
ai_platform/modules/web/BRAIN_INTEGRATION.md
Normal file
193
ai_platform/modules/web/BRAIN_INTEGRATION.md
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
# Web-API ↔ didi-brain integration
|
||||
|
||||
Web-api folosește didi-brain ca **layer de cache cu 2 fețe**:
|
||||
|
||||
1. **Cache read** (ambele tiers — free și premium) — înainte să cheme SearXNG
|
||||
sau paid providers, web-api întreabă brain. Dacă brain are evidence
|
||||
relevante cached, le servește direct; clientul primește răspuns în ~1-2s
|
||||
în loc de 10-30s.
|
||||
2. **Cache write** (doar tier premium, quality-gated) — după o cerere premium
|
||||
care a trecut pragurile de calitate, web-api pompează evidence în brain
|
||||
fire-and-forget. Brain face extraction async. Viitoarele cereri pe claim-uri
|
||||
similare vor hit-ui cache-ul.
|
||||
|
||||
Ideea de bază: **free users primesc quality-ul plătit de premium users**, dar
|
||||
doar premium plătește pentru popularea cache-ului.
|
||||
|
||||
---
|
||||
|
||||
## Flow-ul per request
|
||||
|
||||
```
|
||||
POST /v1/gather { claim, tier }
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────┐
|
||||
│ 1. Cache READ (brain /v1/gather) │
|
||||
│ (ambele tiers, dacă brain configured│
|
||||
│ și brain_cache_read_enabled=true) │
|
||||
└────────┬────────────────────────────────┘
|
||||
│
|
||||
├─ brain HIT cu quality OK
|
||||
│ → returnează direct răspunsul (skip orchestrator)
|
||||
│
|
||||
└─ brain MISS sau quality slab
|
||||
│
|
||||
▼
|
||||
┌────────────────────────────────┐
|
||||
│ 2. Orchestrator normal │
|
||||
│ free → SearXNG + Qwen │
|
||||
│ premium → Paid + OpenRouter│
|
||||
└────────┬───────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────────────────┐
|
||||
│ 3. Cache WRITE (doar premium) │
|
||||
│ dacă quality_ok_for_cache │
|
||||
│ fire-and-forget ingest │
|
||||
│ (nu blochează response) │
|
||||
└────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
Return to client
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Componente
|
||||
|
||||
### `src/web/brain/client.py` — `BrainClient`
|
||||
|
||||
Client HTTP minimal pentru brain:
|
||||
- `gather(claim, max_evidence, run_nli, ...)` — cache read, returnează JSON sau None pe eroare
|
||||
- `ingest(payload)` — cache write, fire-and-forget via sink de obicei
|
||||
|
||||
Timeout-uri separate (gather e rapid, ingest poate fi mai lent).
|
||||
|
||||
### `src/web/brain/sink.py` — `BrainIngestSink`
|
||||
|
||||
Queue bounded (1000 items max) processat de un single worker task.
|
||||
Overflow → drop oldest. Eșecuri → log DEBUG, swallowed. Zero impact
|
||||
pe latența web-api.
|
||||
|
||||
### `src/web/brain/quality.py` — Quality gates
|
||||
|
||||
- `quality_ok_for_cache(response)` — decide dacă un gather result e worth-caching
|
||||
(3+ evidence, cel puțin 1 sursă credibilă dacă sunt scored, toate stages OK,
|
||||
execution > 2s)
|
||||
- `brain_hit_acceptable(brain_raw)` — decide dacă un brain HIT e suficient
|
||||
de bun (HIT = da; PARTIAL = da doar dacă 3+ items cu relevance ≥ 0.7)
|
||||
|
||||
### `src/web/brain/adapter.py` — Schema conversion
|
||||
|
||||
- `brain_response_to_web(brain_raw, request_id)` — convertește response-ul
|
||||
brain în `GatherResponse` web (datetime → ISO string, provenance dict,
|
||||
`brain_meta` flatten în provenance per evidence item)
|
||||
- `web_response_to_ingest_payload(response, claim)` — convertește
|
||||
`GatherResponse` în `IngestRequest` pentru brain (ISO dates, safe defaults
|
||||
pentru field-urile required brain-side: title/retrieved_at/score defaults)
|
||||
|
||||
---
|
||||
|
||||
## Configurare
|
||||
|
||||
În `deploy/.env`:
|
||||
|
||||
```bash
|
||||
WEB_BRAIN_URL=http://didibrain-api:8090
|
||||
|
||||
# Feature toggles (default true dacă brain_url setat)
|
||||
WEB_BRAIN_CACHE_READ_ENABLED=true
|
||||
WEB_BRAIN_INGEST_ENABLED=true
|
||||
|
||||
# Quality thresholds pentru ingest
|
||||
WEB_BRAIN_INGEST_MIN_EVIDENCE=3
|
||||
WEB_BRAIN_INGEST_MIN_CREDIBILITY=0.7
|
||||
WEB_BRAIN_INGEST_MIN_EXECUTION_MS=2000
|
||||
|
||||
# Acceptance thresholds pentru PARTIAL cache hit
|
||||
WEB_BRAIN_HIT_MIN_EVIDENCE=3
|
||||
WEB_BRAIN_HIT_MIN_RELEVANCE=0.7
|
||||
|
||||
# Timeouts
|
||||
WEB_BRAIN_GATHER_TIMEOUT=8.0
|
||||
WEB_BRAIN_INGEST_TIMEOUT=15.0
|
||||
```
|
||||
|
||||
Toate sunt optional. Dacă `WEB_BRAIN_URL` e gol, integrarea e dezactivată
|
||||
complet (fallback la orchestrator normal pentru tot).
|
||||
|
||||
---
|
||||
|
||||
## Networking Docker
|
||||
|
||||
Web-api trăiește pe rețeaua `deploy_default` (cu dashboard, video, audio,
|
||||
searxng). Brain trăiește pe rețeaua proprie `didibrain`.
|
||||
|
||||
Web-api e atașat la **ambele** rețele în `deploy/docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
networks:
|
||||
deploy_default:
|
||||
external: true
|
||||
didibrain:
|
||||
external: true
|
||||
|
||||
services:
|
||||
web-api:
|
||||
networks:
|
||||
- deploy_default
|
||||
- didibrain
|
||||
```
|
||||
|
||||
Asta îi permite să rezolve `didibrain-api` prin DNS-ul Docker.
|
||||
|
||||
---
|
||||
|
||||
## Fail-open
|
||||
|
||||
Brain down ≠ web-api down. Toate apelurile spre brain sunt wrapped cu
|
||||
try/except generos:
|
||||
- Gather cache read eșuează → continuă la orchestrator normal
|
||||
- Ingest eșuează → log și drop event (queue-ul va reumple)
|
||||
|
||||
Clientul nu vede niciodată o eroare datorită brain.
|
||||
|
||||
---
|
||||
|
||||
## Cum monitorizezi HIT rate
|
||||
|
||||
Log-urile web-api emit `Brain cache HIT [tier=X, N items]: <claim>` pe fiecare
|
||||
hit. Pentru producție, integrarea cu dashboard face count-uri în tabela
|
||||
`request_history` (câmp `raw_response.stages` conține `retrieval`/`rerank` când
|
||||
e din brain vs `search`/`fetch` când e direct).
|
||||
|
||||
Query exemplu (post-deploy):
|
||||
|
||||
```sql
|
||||
-- HIT rate per tier pe ultimele 24h
|
||||
SELECT
|
||||
tier,
|
||||
COUNT(*) FILTER (
|
||||
WHERE raw_response::jsonb -> 'stages' @> '[{"stage":"retrieval"}]'
|
||||
) AS brain_hits,
|
||||
COUNT(*) AS total_gathers,
|
||||
ROUND(100.0 * COUNT(*) FILTER (
|
||||
WHERE raw_response::jsonb -> 'stages' @> '[{"stage":"retrieval"}]'
|
||||
) / NULLIF(COUNT(*), 0), 1) AS hit_rate_pct
|
||||
FROM request_history
|
||||
WHERE endpoint = '/v1/gather'
|
||||
AND created_at > now() - interval '24 hours'
|
||||
GROUP BY tier;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Ce NU face integrarea
|
||||
|
||||
- Nu scrie la brain pe tier `free` (doar citește) — tip premium gold standard
|
||||
- Nu face fallback la premium când brain MISS pe free (menține tier isolation)
|
||||
- Nu retry — un singur request la brain, orice eșec → fallback silent
|
||||
|
||||
Pentru detaliile contractului verification_cache (backend ↔ brain),
|
||||
vezi `modules/didi_brain/CONTRACT_VERIFICATION_CACHE.md`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue