# 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://:7687 NEO4J_USER=neo4j NEO4J_PASSWORD= ``` --- ## 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://.cognitiveservices.azure.com/openai/deployments//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://.cognitiveservices.azure.com/openai/deployments//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://.services.ai.azure.com/openai/deployments//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//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à).