GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GitHub - UPM-RSTI/CC_multiangent

BranchesTags
Open more actions menu
 
 

Latest commit

 

History

12 Commits
12 Commits

Folders and files

NameName
Last commit message
Last commit date
agents
agents
 
 
data/raw
data/raw
 
 
evaluacion
evaluacion
 
 
frontend
frontend
 
 
img
img
 
 
ontologia
ontologia
 
 
orchestration
orchestration
 
 
prompts
prompts
 
 
rag
rag
 
 
scripts
scripts
 
 
tools
tools
 
 
.gitignore
.gitignore
 
 
.gittattributes
.gittattributes
 
 
Dockerfile.api
Dockerfile.api
 
 
README.md
README.md
 
 
api.py
api.py
 
 
docker-compose.yml
docker-compose.yml
 
 
doctrine_eval_dataset_v2.json
doctrine_eval_dataset_v2.json
 
 
doctrine_only_results.json
doctrine_only_results.json
 
 
doctrine_only_results_final.json
doctrine_only_results_final.json
 
 
doctrine_only_results_v2.json
doctrine_only_results_v2.json
 
 
ground_truth_doctrine.json
ground_truth_doctrine.json
 
 
merge_groundtruth.py
merge_groundtruth.py
 
 
models.py
models.py
 
 
requirements.txt
requirements.txt
 
 
session.py
session.py
 
 
sparql_templates.py
sparql_templates.py
 
 

Repository files navigation

SA-MultiAgent

Sistema multiagente para operaciones multidominio en la nube de combate.

SA-MultiAgent permite que operadores de distintos dominios (aire, tierra y mar) consulten en lenguaje natural fuentes de conocimiento heterogéneas sobre un escenario de la nube de combate que incluye redes de mando y control (C2), flotas de drones y nodos que ejecutan algoritmos de aprendizaje federado. El sistema combina conocimiento estructurado (ontología OWL/RDF servida con Apache Jena Fuseki vía SPARQL) y conocimiento doctrinal no estructurado (publicaciones OTAN AJP-3.1, AJP-3.2 y AJP-3.3 indexadas en ChromaDB), coordinados por una tubería de cinco agentes LLM (GPT-4.1 con PydanticAI y arquitectura ReWOO).

Trabajo Fin de Máster — UPM / ETSIT.


Tabla de contenidos

  1. Arquitectura
  2. Requisitos previos
  3. Inicio rápido (plug-and-play)
  4. Configuración
  5. Estructura del proyecto
  6. Datos: ontología y corpus doctrinal
  7. Uso

Arquitectura

El sistema expone una API que ejecuta una tubería fija de cinco etapas por cada consulta. Cada etapa es una única llamada al LLM con salida estructurada (Pydantic).

POST /query
  → Clasificador  → etiqueta la consulta (smalltalk | doctrine_question | ontology_with_context
                    | ontology_question | unclear)
  → Recuperador   → recupera contexto de ChromaDB y expande términos 
  → Planificador  → emite un plan ordenado de llamadas a herramientas;
                    puede invocar el subagente sparql_from_nl
  → Ejecutor      → ejecuta las herramientas en orden, resuelve las
                    referencias {{Ek}} entre pasos y puede re-planificar (≤2)
  → Sintetizador  → compone la respuesta final con citas, patrón detectado
                    y lista de entidades


En la siguiente imagen se puede ver una visión general de la arquitectura propuesta:

Caminos cortos:

  • smalltalk → Clasificador → Sintetizador (omite Recuperador, Planificador y Ejecutor).
  • unclear → el Clasificador devuelve una pregunta de aclaración y la tubería se detiene.

Servicios (contenedores):

Servicio Imagen / build Puerto Función
fuseki stain/jena-fuseki 3030 Almacén de tripletas (ontología, SPARQL)
api Dockerfile.api 8000 Backend FastAPI con el pipeline de agentes
frontend Dockerfile.frontend 8080 Interfaz web servida con Nginx

Requisitos previos

  • Docker y Docker Compose (Docker Desktop en Windows o macOS ya incluyen ambos).
  • Una clave de API de OpenAI con acceso a los modelos GPT-4.1.

No se necesita instalar Python, Fuseki ni ChromaDB en el equipo anfitrión: todo corre dentro de contenedores.


Inicio rápido (plug-and-play)

Tres pasos. Desde la raíz del proyecto:

# 1) Crear el fichero de entorno y poner la clave de OpenAI
cp .env.example .env
#    Edita .env y sustituye el valor de OPENAI_API_KEY

# 2) Levantar todo el sistema
docker-compose up --build

# 3) Abrir la interfaz en el navegador
#    http://localhost:8080

Eso es todo. Al arrancar, el contenedor api espera a que Fuseki esté listo, crea el dataset, carga la ontología en el grafo nombrado y lanza el backend de forma automática. El corpus doctrinal ya viene indexado en el repositorio, por lo que no hay que reconstruir nada.

Servicios disponibles tras el arranque:

  • Interfaz web: http://localhost:8080
  • API (documentación interactiva): http://localhost:8000/docs
  • Fuseki (consola de administración): http://localhost:3030

Para detener el sistema: Ctrl + C, y luego docker-compose down (añade -v para borrar también el volumen de Fuseki y forzar una recarga limpia de la ontología).


Configuración

Toda la configuración vive en el fichero .env (a partir de .env.example). La única variable obligatoria es OPENAI_API_KEY; el resto tiene valores por defecto razonables.

Variable Por defecto Descripción
OPENAI_API_KEY — Obligatoria. Clave de la API de OpenAI.
CLASSIFIER_MODEL gpt-4.1-mini Modelo del Clasificador.
PLANNER_MODEL gpt-4.1 Modelo del Planificador.
SYNTHESIZER_MODEL gpt-4.1 Modelo del Sintetizador.
NL_SPARQL_MODEL gpt-4.1 Modelo del subagente sparql_from_nl.
RETRIEVER_MODEL gpt-4.1-mini Modelo de expansión de términos del Recuperador.
RETRIEVER_TOP_K 6 Número de fragmentos recuperados de ChromaDB.
RETRIEVER_MIN_SCORE 0.10 Puntuación de similitud mínima para conservar un fragmento.
CLASSIFIER_CONFIDENCE_THRESHOLD 0.6 Por debajo de este umbral la consulta se clasifica como unclear.
CLASSIFIER_HISTORY_TURNS 5 Turnos de conversación pasados al Clasificador.
PLANNER_HISTORY_TURNS 5 Turnos de conversación pasados al Planificador.
EXECUTOR_TRANSIENT_RETRIES 3 Reintentos máximos ante errores transitorios.
EXECUTOR_BACKOFF_BASE 1.0 Base del backoff exponencial (segundos).
EXECUTOR_MAX_REPLANS 2 Ciclos máximos de re-planificación por consulta.
LOG_LEVEL INFO Nivel de registro.

Las variables de conexión a Fuseki (FUSEKI_ENDPOINT, FUSEKI_GRAPH, FUSEKI_DATASET) las fija docker-compose.yml automáticamente; solo hace falta definirlas a mano para la ejecución en local sin Docker.


Estructura del proyecto

.
├── agents/                  Agentes del pipeline (clasificador, recuperador, planificador…)
│   └── execution/           Ejecutor, runner de herramientas y resolución de referencias
├── orchestration/           Orquestador: conecta las cinco etapas
├── prompts/                 Prompts de sistema de cada agente
├── tools/                   Catálogo de herramientas, recuperador doctrinal, ejecutor SPARQL
├── ontologia/
│   └── ontologia.ttl        Ontología RDF/OWL (drones, nodos C2, flujos de datos, roles)
├── rag/
│   ├── data/
│   │   ├── raw/             PDF doctrinales originales (AJP-3.1/3.2/3.3)
│   │   ├── processed/       Páginas y fragmentos (JSONL) + léxicos
│   │   └── chroma/          Índice vectorial ChromaDB ya construido
│   └── src/                 Código de ingesta e indexación (build_index.py)
├── scripts/                 Scripts de arranque (entrypoint) y utilidades
├── evaluacion/              Conjuntos de evaluación y métricas (RAGAS)
├── frontend/                Interfaz web + Nginx
├── api.py                   Aplicación FastAPI (/login, /query, /session, /health)
├── models.py                Modelos Pydantic compartidos
├── session.py                Almacén de sesiones en memoria
├── requirements.txt         Dependencias de Python
├── .env.example              Plantilla de configuración
├── docker-compose.yml        Orquestación de los tres servicios
├── Dockerfile.api            Imagen del backend
└── Dockerfile.frontend       Imagen del frontend

Datos: ontología y corpus doctrinal

Ontología. Reside en ontologia/ontologia.ttl (≈ 1.158 tripletas; 11 clases, 109 individuos y 17 propiedades de objeto). Describe la topología de la red de drones, los nodos C2, los flujos de datos y los roles operativos. Se carga en Fuseki de forma automática al arrancar la API, en el grafo nombrado <urn:scenario:static>. Para modificarla, edita el .ttl y reinicia el sistema con el volumen limpio:

docker-compose down -v && docker-compose up --build

Corpus doctrinal. Los PDF de las publicaciones AJP de la OTAN viven en rag/data/raw/. La canalización de ingesta (rag/src/build_index.py) los segmenta por sección (capítulo y sección), genera los fragmentos en rag/data/processed/ y construye el índice vectorial en rag/data/chroma/ con embeddings multilingües (paraphrase-multilingual-mpnet-base-v2). Todo esto ya viene generado en el repositorio, así que el sistema funciona sin pasos adicionales.

Solo si necesitas regenerar el índice (por ejemplo, tras cambiar los PDF), ejecuta dentro del contenedor:

docker exec -it sa_api python rag/src/build_index.py

El mapeo dominio → doctrina que usa el Recuperador es: aire → AJP-3.3, tierra → AJP-3.2, mar → AJP-3.1.


Uso

Desde la interfaz web

Abre http://localhost:8080, inicia sesión indicando el identificador de operador y el dominio (aire, tierra o mar) y formula consultas en lenguaje natural. El dominio es inmutable durante la sesión.

Desde la API (ejemplo con curl)

# 1) Iniciar sesión y obtener el identificador de sesión
curl -X POST http://localhost:8000/login \
  -H "Content-Type: application/json" \
  -d '{"operator_id": "OP-01", "domain": "air"}'

# 2) Lanzar una consulta (usa el X-Session-ID devuelto en el paso anterior)
curl -X POST http://localhost:8000/query \
  -H "Content-Type: application/json" \
  -H "X-Session-ID: <id-de-sesion>" \
  -d '{"text": "¿Qué drones están operativos y a qué nodo C2 pertenecen?"}'

Endpoints

Método Ruta Descripción
POST /login Crea una sesión y fija el dominio del operador.
POST /query Ejecuta la tubería completa y devuelve la respuesta.
GET /session Recupera el estado de la sesión actual.
GET /health Comprobación de estado del servicio.

Las sesiones son solo en memoria (no hay base de datos): se pierden al reiniciar la API. Todas las peticiones tras /login requieren la cabecera X-Session-ID.

About

No description, website, or topics provided.

Resources

Readme
Activity
Custom properties

Stars

0 stars

Watchers

0 watching

Forks

0 forks
Report repository

Releases

Packages

Contributors

Languages

You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.