147 lines
7.3 KiB
Markdown
147 lines
7.3 KiB
Markdown
# Technical Design — MiroFish
|
|
|
|
## Graph Backend
|
|
|
|
MiroFish suporta dos backends de knowledge graph, seleccionable via `GRAPH_BACKEND` al `.env`:
|
|
|
|
| Valor | Backend | Requisits |
|
|
|-------|---------|-----------|
|
|
| `zep` (per defecte) | Zep Cloud (gestionat) | `ZEP_API_KEY` |
|
|
| `graphiti` | Graphiti + Neo4j (self-hosted) | `NEO4J_PASSWORD` + variables LLM |
|
|
|
|
La selecció es fa via la factoria `backend/app/graph/factory.py` — un singleton que instancia `ZepBackend` o `GraphitiBackend` en funció de `GRAPH_BACKEND`. La validació de configuració és condicionada: si `GRAPH_BACKEND=graphiti`, `ZEP_API_KEY` no és necessari i viceversa.
|
|
|
|
### Commutació entre backends
|
|
|
|
Només cal canviar al `.env`:
|
|
|
|
```env
|
|
# Per usar Zep Cloud:
|
|
GRAPH_BACKEND=zep
|
|
ZEP_API_KEY=z_...
|
|
|
|
# Per usar Graphiti + Neo4j:
|
|
GRAPH_BACKEND=graphiti
|
|
NEO4J_URI=bolt://<host>:7687
|
|
NEO4J_USER=neo4j
|
|
NEO4J_PASSWORD=<contrasenya>
|
|
```
|
|
|
|
---
|
|
|
|
## Models LLM
|
|
|
|
El projecte usa fins a quatre grups de variables LLM, cadascun per a un ús diferent. Totes les variables `LLM_SMALL_*` i `LLM_EMBED_*` fan **fallback** als valors `LLM_*` si no s'estableixen.
|
|
|
|
### Variables de configuració
|
|
|
|
```env
|
|
# ── Model principal (generatiu, potent) ──────────────────────────────────────
|
|
LLM_API_KEY=...
|
|
LLM_BASE_URL=https://<recurs>.cognitiveservices.azure.com/openai/deployments/<model>/chat/completions?api-version=2024-05-01-preview
|
|
LLM_MODEL_NAME=gpt-5.4
|
|
|
|
# ── Model petit/ràpid (lightweight, econòmic) ────────────────────────────────
|
|
# Fallback a LLM_* si no definit
|
|
LLM_SMALL_API_KEY=...
|
|
LLM_SMALL_BASE_URL=https://<recurs>.cognitiveservices.azure.com/openai/deployments/<small-model>/chat/completions?api-version=2024-05-01-preview
|
|
LLM_SMALL_MODEL_NAME=gpt-5-mini
|
|
|
|
# ── Model d'embedding (vectorització) ────────────────────────────────────────
|
|
# Fallback a LLM_* si no definit. Requerit per Graphiti.
|
|
LLM_EMBED_API_KEY=...
|
|
LLM_EMBED_BASE_URL=https://<recurs>.services.ai.azure.com/openai/deployments/<embed-model>/embeddings?api-version=2024-05-01-preview
|
|
LLM_EMBED_MODEL_NAME=text-embedding-3-large
|
|
|
|
# ── Model boost (simulació OASIS, opcional) ──────────────────────────────────
|
|
# Fallback a LLM_* si no definit
|
|
LLM_BOOST_API_KEY=...
|
|
LLM_BOOST_BASE_URL=...
|
|
LLM_BOOST_MODEL_NAME=gpt-5.4
|
|
```
|
|
|
|
### Mapa d'usos per operació
|
|
|
|
| Grup de variables | Component | Operació |
|
|
|---|---|---|
|
|
| `LLM_*` | `OntologyGenerator` | Pas 1 — Anàlisi del document i generació d'ontologia (tipus d'entitat i relació) |
|
|
| `LLM_*` | `GraphBuilderService` (mode Zep) | Pas 2 — Extracció d'entitats i relacions del text via Zep SDK |
|
|
| `LLM_*` | Graphiti `OpenAIClient` (mode graphiti) | Pas 2 — Extracció d'entitats i relacions del text via graphiti-core |
|
|
| `LLM_*` | `OasisProfileGenerator` | Pas 2 — Generació de perfils d'agents OASIS a partir del graf |
|
|
| `LLM_*` | `ReportAgent` | Pas 4 — Generació de l'informe analític final (multi-turn, tool use) |
|
|
| `LLM_SMALL_*` | Graphiti `OpenAIRerankerClient` | Pas 2 — Reranking de resultats de cerca al graf (mode graphiti) |
|
|
| `LLM_SMALL_*` | Graphiti `ModelSize.small` | Pas 2 — Tasques lleugeres internes de graphiti (extracció simplificada) |
|
|
| `LLM_EMBED_*` | Graphiti `OpenAIEmbedder` | Pas 2 — Generació de vectors d'embedding per a indexació i cerca semàntica a Neo4j (mode graphiti) |
|
|
| `LLM_BOOST_*` | `SimulationRunner` / `run_parallel_simulation.py` | Pas 3 — Decisions d'acció de cada agent durant la simulació OASIS |
|
|
|
|
### API endpoint usada per cada component
|
|
|
|
Tots els components del projecte usen **`chat.completions`** o **`embeddings`** — mai `responses` (beta).
|
|
|
|
| Component | API endpoint | Nota |
|
|
|---|---|---|
|
|
| `LLMClient` (wrapper projecte) | `chat.completions.create` | Síncrona (`OpenAI`) |
|
|
| `OntologyGenerator` | `chat.completions.create` | Via `LLMClient` |
|
|
| `OasisProfileGenerator` | `chat.completions.create` | Client intern |
|
|
| `SimulationConfigGenerator` | `chat.completions.create` | Client intern |
|
|
| `ReportAgent` | `chat.completions.create` | Via `LLMClient` |
|
|
| Graphiti `OpenAIGenericClient` | `chat.completions.create` | AsyncOpenAI, injectable |
|
|
| Graphiti `OpenAIRerankerClient` | `chat.completions.create` | Amb `logprobs=True` per scoring |
|
|
| Graphiti `OpenAIEmbedder` | `embeddings.create` | AsyncOpenAI, injectable |
|
|
| OASIS/CAMEL-AI | `chat.completions.create` | Via `ModelFactory` (CAMEL abstraction) |
|
|
|
|
> **Nota:** graphiti-core inclou també un `OpenAIClient` que usa `responses.parse` (API beta d'OpenAI). MiroFish **no l'usa** — configura `OpenAIGenericClient` que sempre usa `chat.completions`, compatible amb Azure i qualsevol API OpenAI-compatible.
|
|
|
|
### Notes sobre Azure OpenAI
|
|
|
|
- `LLM_BASE_URL` accepta la URL completa d'Azure (`/chat/completions?api-version=...`). El codi la processa automàticament: extreu el `api-version` com a `default_query` i retalla el sufix per al SDK.
|
|
- El mateix tractament s'aplica a `LLM_EMBED_BASE_URL` (sufix `/embeddings?api-version=...`).
|
|
- `LLM_SMALL_BASE_URL` accepta directament la URL base d'Azure AI Foundry (`services.ai.azure.com/api/projects/<proj>/openai/v1/`) sense sufix ni `api-version`.
|
|
- `LLM_EMBED_BASE_URL` pot usar el domini `services.ai.azure.com` o `cognitiveservices.azure.com`.
|
|
|
|
### Recomanació de models (Azure OpenAI)
|
|
|
|
| Grup | Model recomanat | Motiu |
|
|
|------|----------------|-------|
|
|
| `LLM_*` | `gpt-5.4` | Raonament complex: ontologia, extracció de graf, informes |
|
|
| `LLM_SMALL_*` | `gpt-5-mini` | Tasques lleugeres i econòmiques: reranking, classificació |
|
|
| `LLM_EMBED_*` | `text-embedding-3-large` | Màxima qualitat d'embedding semàntic |
|
|
| `LLM_BOOST_*` | `gpt-5.4` o `gpt-5-mini` | Simulació: moltes crides curtes, prioritzar velocitat/cost |
|
|
|
|
---
|
|
|
|
## Pipeline de 5 passos
|
|
|
|
```
|
|
Pas 1 — Graph Build (ontologia)
|
|
└─ OntologyGenerator → LLM_*
|
|
|
|
Pas 2 — Graph Build (construcció)
|
|
├─ mode zep: GraphBuilderService + Zep SDK → LLM_*
|
|
└─ mode graphiti: GraphitiBackend
|
|
├─ extracció: OpenAIGenericClient → LLM_* (chat.completions)
|
|
├─ reranking: OpenAIRerankerClient → LLM_SMALL_*
|
|
└─ embedding: OpenAIEmbedder → LLM_EMBED_*
|
|
|
|
Pas 3 — Simulació OASIS
|
|
└─ SimulationRunner / run_parallel_simulation.py → LLM_BOOST_* (o LLM_*)
|
|
|
|
Pas 4 — Informe
|
|
└─ ReportAgent (multi-turn + tool use) → LLM_*
|
|
|
|
Pas 5 — Interacció live
|
|
└─ Chat amb agents simulats → LLM_*
|
|
```
|
|
|
|
---
|
|
|
|
## Internacionalització (i18n)
|
|
|
|
- Fitxers de traducció: `/locales/{ca,en,es,zh}.json` — compartits per frontend i backend.
|
|
- Instruccions de llengua per al LLM: `/locales/languages.json` (clau `llmInstruction`).
|
|
- El frontend injecta el locale actual via header `Accept-Language` a cada petició API.
|
|
- El backend detecta el locale a `backend/app/utils/locale.py:get_locale()` i l'usa per:
|
|
- Traduccions de missatges d'error (`t()`)
|
|
- Instruccions d'idioma als prompts LLM (`get_language_instruction()`)
|
|
- L'ontologia generada (descripcions, exemples, `analysis_summary`) sortirà en l'idioma de la UI. Els **noms** de tipus d'entitat i relació seguiran PascalCase/UPPER\_SNAKE\_CASE en l'idioma de la UI (p.ex. `AgenciaGovern`, `TREBALLA_PER` en català).
|