MicroFish/INSTALL.md

13 KiB

MiroFish — Guia d'instal·lació i desplegament

Aquesta guia cobreix les dues modalitats d'execució:


1. Desenvolupament local

Prerequisits

Eina Versió Comprovació
Node.js ≥ 18 node -v
Python ≥ 3.11, ≤ 3.12 python --version
uv última uv --version

Instal·lació

# 1. Clonar el repositori
git clone https://github.com/jaumemir/MiroFish.git
cd MiroFish

# 2. Configurar variables d'entorn
cp .env.example .env
# Edita .env i omple els valors (vegeu la secció de variables)

# 3. Instal·lar totes les dependències (Node + Python)
npm run setup:all

Variables d'entorn (.env)

# ── LLM principal (OpenAI-compatible) ─────────────────────────────
LLM_API_KEY=la-teva-clau
LLM_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
LLM_MODEL_NAME=qwen-plus

# ── Zep Cloud (graf de memòria) ───────────────────────────────────
ZEP_API_KEY=la-teva-clau-zep

# ── LLM accelerador (opcional) ────────────────────────────────────
LLM_BOOST_API_KEY=
LLM_BOOST_BASE_URL=
LLM_BOOST_MODEL_NAME=

# ── Autenticació ──────────────────────────────────────────────────
# Contrasenya de l'usuari "demo" per accedir a l'app
DEMO_PASSWORD=una-contrasenya-segura

# Clau per signar tokens JWT
# Genera-la amb: python -c "import secrets; print(secrets.token_hex(32))"
SECRET_KEY=una-clau-secreta-llarga

Execució

npm run dev

Obre el navegador a http://localhost:3000.
Fes login amb usuari demo i la DEMO_PASSWORD que has configurat.

El frontend (port 3000) i el backend (port 5001) s'inicien simultàniament.
Vite proxia automàticament les peticions /api/* al backend.


2. Desplegament a Azure Container Apps

Prerequisits

Eina Versió Instal·lació
Azure CLI ≥ 2.60 docs.microsoft.com/cli/azure/install-azure-cli
Docker ≥ 24 docs.docker.com/get-docker
Python 3 ≥ 3.8 (per processar outputs JSON dels scripts)

Estructura dels fitxers de desplegament

azure/
├── config.sh.example   # plantilla de configuració (commited al repo)
├── config.sh           # valors reals amb secrets  (NO comitejar mai — gitignored)
├── infra.bicep         # infraestructura base: ACR + Container Apps Env
├── container-app.bicep # Container App: es re-desplega a cada nova versió
├── 1-infra.sh          # script pas 1: crea la infraestructura (una sola vegada)
└── 2-build-deploy.sh   # script pas 2: build Docker + push + deploy (cada versió)

Pas 0 — Login a Azure

az login

Pas 1 — Configuració

cp azure/config.sh.example azure/config.sh

Edita azure/config.sh i omple tots els valors:

Variables obligatòries

Variable Descripció On obtenir-la
AZURE_SUBSCRIPTION_ID ID de la subscripció Azure az account show --query id -o tsv
AZURE_LOCATION Regió Azure (ex: westeurope) Llista de regions
DEMO_PASSWORD Contrasenya de l'usuari demo Escull una contrasenya segura
SECRET_KEY Clau Flask per signar JWT python -c "import secrets; print(secrets.token_hex(32))"
LLM_API_KEY Clau de l'API LLM Alibaba Bailian o OpenAI
LLM_BASE_URL URL base de l'API LLM Default: Alibaba Qwen
LLM_MODEL_NAME Nom del model Default: qwen-plus
ZEP_API_KEY Clau de Zep Cloud app.getzep.com

Variables opcionals

Variable Descripció Default
LLM_BOOST_API_KEY Clau LLM accelerador (buit = desactivat)
LLM_BOOST_BASE_URL URL LLM accelerador (buit)
LLM_BOOST_MODEL_NAME Model LLM accelerador (buit)
OASIS_DEFAULT_MAX_ROUNDS Rondes màximes simulació 10
REPORT_AGENT_MAX_TOOL_CALLS Crides màximes a eines 5
REPORT_AGENT_MAX_REFLECTION_ROUNDS Rondes de reflexió 2
REPORT_AGENT_TEMPERATURE Temperatura del Report Agent 0.5

Seguretat: azure/config.sh està al .gitignore. Mai el comiteges al repositori.


Pas 2 — Crear infraestructura (una sola vegada)

bash azure/1-infra.sh

Aquest script crea al resource group rg_mirofish:

Recurs Nom Descripció
Resource Group rg_mirofish Contenidor de tots els recursos
Container Registry mirofsihacr Registre privat Docker (SKU Basic)
Container Apps Environment mirofish-env Plataforma d'execució de contenidors

Al final imprimeix l'ACR Login Server i l'ID de l'entorn. Guarda'ls si els necessites.

Idempotent: pots executar-lo múltiples vegades sense errors.


Pas 3 — Build i deploy (a cada nova versió)

bash azure/2-build-deploy.sh

El script fa automàticament:

  1. Obté les dades de la infraestructura existent (ACR, Container Apps Env)
  2. Genera un tag de versió amb format <git-sha>-<timestamp>
  3. docker build de la imatge multi-stage (Vue build + Flask + gunicorn)
  4. docker push a l'ACR privat
  5. Desplega la Container App via Bicep amb tots els secrets configurats

Al final imprimeix la URL de l'aplicació:

URL de l'aplicació: https://mirofish.<hash>.westeurope.azurecontainerapps.io

Gestió de versions i re-deploys

Cada execució de 2-build-deploy.sh genera una nova revisió de la Container App amb tag únic. La versió latest sempre apunta a la darrera imatge.

Per veure l'historial de revisions:

az containerapp revision list \
  --name mirofish \
  --resource-group rg_mirofish \
  --output table

Per consultar els logs en temps real:

az containerapp logs show \
  --name mirofish \
  --resource-group rg_mirofish \
  --follow

Arquitectura de producció

Internet
    │  HTTPS
    ▼
Container Apps Ingress (port 5001)
    │
    ▼
Flask + gunicorn (1 worker, 4 threads)
    ├── GET /              → serveix Vue SPA (frontend/dist/)
    ├── POST /api/auth/login  → autenticació JWT (pública)
    └── /api/*             → protegit per JWT Bearer token

Escalat automàtic: de 1 a 10 rèpliques per nombre de peticions concurrents (llindar: 20).


Solució de problemes habituals

Problema Causa probable Solució
ERROR: No s'ha trobat azure/config.sh Fitxer no creat cp azure/config.sh.example azure/config.sh
Cannot login to ACR Docker no està en execució docker info i arrenca Docker
Login retorna 401 sempre DEMO_PASSWORD buida o incorrecta Verifica el valor a config.sh / secret Azure
Container App no arrenca Imatge no trobada a l'ACR Verifica que 2-build-deploy.sh hagi finalitzat sense errors
Token expirat al cap de 24h Comportament esperat Torna a fer login a /login

3. Backend de graf pluggable (Graphiti + Neo4j)

La branca feat-pluggable-graph-backend introdueix un sistema de backends intercanviables per al graf de coneixement. El backend per defecte és Zep Cloud; l'alternatiu és Graphiti + Neo4j auto-allotjat.

Arquitectura

GraphBuilderService
    │
    │  self._graph = get_graph_backend()
    ▼
┌─────────────────────────────────┐
│   factory.get_graph_backend()   │  ← llegeix GRAPH_BACKEND env var
│   (patró Singleton)             │
└────────────┬────────────────────┘
             │
    ┌────────┴────────┐
    ▼                 ▼
ZepBackend      GraphitiBackend
    │                 │
    ▼                 ▼
Zep Cloud API    Neo4j (bolt://)
                  + graphiti-core
                  + OpenAI embedder

Tots dos backends implementen la mateixa interfície abstracta GraphBackend (backend/app/graph/base.py):

Mètode Descripció
create_graph(graph_id, name) Crea o registra el graf
set_ontology(graph_ids, entities, edges) Defineix l'ontologia
add_batch(graph_id, episodes) Afegeix episodis de text en lot
get_episode(uuid_) Consulta l'estat de processament d'un episodi
get_all_nodes(graph_id) Retorna tots els nodes del graf
get_all_edges(graph_id) Retorna totes les arestes
get_node(uuid_) Node per UUID
get_node_edges(node_uuid) Arestes d'un node
search(graph_id, query, limit) Cerca semàntica
add_text(graph_id, data) Afegeix text directament
delete_graph(graph_id) Elimina el graf complet

Fitxers clau

backend/app/graph/
├── base.py            — interfície abstracta GraphBackend
├── factory.py         — factory + singleton (get_graph_backend)
├── zep_backend.py     — implementació Zep Cloud
└── graphiti_backend.py — implementació Graphiti + Neo4j

Diferències de comportament entre backends

Aspecte ZepBackend GraphitiBackend
Allotjament Zep Cloud (SaaS) Neo4j auto-allotjat
Ontologia API nativa Zep No-op (extracció LLM automàtica)
Polling d'episodis episode.get(uuid_) real Retorna sempre processed=True
Consultes SDK Zep Queries Cypher directes
Paginació nodes/arestes 100 items/pàgina, màx. 2000 Sense límit explícit
Resiliència Retry amb backoff exponencial (3 intents) Sense retry
Cerca reranker=cross_encoder graphiti_core.search()
Credencials ZEP_API_KEY NEO4J_URI, NEO4J_USER, NEO4J_PASSWORD
Threading async No cal (SDK síncron) Thread daemon + asyncio.run_coroutine_threadsafe

Instal·lació de les dependències Graphiti

Graphiti és una dependència opcional. Per activar-la:

# Amb uv (recomanat)
uv pip install -e ".[graphiti]"

# Amb pip
pip install "mirofish-backend[graphiti]"
# o directament:
pip install "graphiti-core>=0.3.0" "neo4j>=5.23.0"

Les dependències base (Zep) segueixen instal·lant-se com sempre:

uv pip install -r requirements.txt

Variables d'entorn per a Graphiti + Neo4j

# Selecció de backend (per defecte: zep)
GRAPH_BACKEND=graphiti

# Connexió Neo4j (protocol bolt)
NEO4J_URI=bolt://<host>:7687
NEO4J_USER=neo4j
NEO4J_PASSWORD=la-teva-contrasenya

# LLM_API_KEY, LLM_BASE_URL i LLM_MODEL_NAME segueixen sent necessaris
# (graphiti-core els usa per a l'extracció d'entitats i els embeddings)

Nota: quan GRAPH_BACKEND=graphiti, ZEP_API_KEY no és necessari.

Desplegament a Azure (aci-graphiti-neo4j)

Al resource group rg_mirofish existeix el container group aci-graphiti-neo4j amb tres contenidors al mateix pod:

Contenidor Imatge Port intern Funció
neo4j mirofishgeneacr.azurecr.io/neo4j:5.26.0 7474 (HTTP), 7687 (bolt) Base de dades de graf
graphiti-mcp mirofishgeneacr.azurecr.io/knowledge-graph-mcp:standalone 8000 API graphiti-core via MCP
caddy mirofishgeneacr.azurecr.io/caddy:2 443 Proxy HTTPS per a graphiti-mcp

Ports exposats públicament:

Port Protocol Destí
443 TCP caddy → graphiti-mcp (HTTPS, certificat Let's Encrypt)
7687 TCP bolt → neo4j (autenticat)

Endpoints:

  • Graphiti MCP: https://graphitigene-mcp.westeurope.azurecontainer.io
  • Neo4j bolt: bolt://52.149.109.53:7687

Variables d'entorn del Container App mirofishgene (configuració activa):

GRAPH_BACKEND=graphiti
NEO4J_URI=bolt://52.149.109.53:7687
NEO4J_USER=neo4j
NEO4J_DATABASE=neo4j
NEO4J_PASSWORD=<secret: neo4j-password>

Tests

# Executar els tests del factory (no requereix Neo4j ni Zep actius)
cd .worktrees/feat-pluggable-graph-backend
pytest backend/tests/test_graph_factory.py -v

El fixture reset_graph_factory_singleton (a backend/tests/conftest.py) reseteja el singleton entre tests per evitar interferències quan es canvia GRAPH_BACKEND.