trustgraph/docs/tech-specs/python-api-refactor.es.md
Alex Jenkins f95fd4f052
Feat: TrustGraph i18n & Documentation Translation Updates (#781)
Native CLI i18n: The TrustGraph CLI has built-in translation support
that dynamically loads language strings. You can test and use
different languages by simply passing the --lang flag (e.g., --lang
es for Spanish, --lang ru for Russian) or by configuring your
environment's LANG variable.

Automated Docs Translations: This PR introduces autonomously
translated Markdown documentation into several target languages,
including Spanish, Swahili, Portuguese, Turkish, Hindi, Hebrew,
Arabic, Simplified Chinese, and Russian.
2026-04-14 12:07:58 +01:00

54 KiB

layout title parent
default Especificación Técnica de Refactorización de la API de Python Spanish (Beta)

Especificación Técnica de Refactorización de la API de Python

Beta Translation: This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.

Resumen

Esta especificación describe una refactorización integral de la biblioteca de cliente de la API de Python de TrustGraph para lograr la paridad de funciones con la API Gateway y agregar soporte para patrones de comunicación en tiempo real modernos.

La refactorización aborda cuatro casos de uso principales:

  1. Interacciones de LLM en Streaming: Habilitar el streaming en tiempo real de las respuestas de LLM (agente, RAG de grafos, RAG de documentos, finalización de texto, prompts) con una latencia significativamente menor (~60 veces menor, 500 ms frente a 30 s para el primer token).
  2. Operaciones de Datos Masivos: Soporte para la importación/exportación eficiente de triples, incrustaciones de grafos e incrustaciones de documentos para la gestión de grafos de conocimiento a gran escala.
  3. Paridad de Funciones: Asegurar que cada punto final de la API Gateway tenga un método de API de Python correspondiente, incluidas las consultas de incrustaciones de grafos.
  4. Conexiones Persistentes: Habilitar la comunicación basada en WebSocket para solicitudes multiplexadas y una menor sobrecarga de conexión.

Objetivos

Paridad de Funciones: Cada servicio de la API Gateway tiene un método de API de Python correspondiente. Soporte de Streaming: Todos los servicios capaces de streaming (agente, RAG, finalización de texto, prompt) admiten el streaming en la API de Python. Transporte WebSocket: Agregar una capa de transporte WebSocket opcional para conexiones persistentes y multiplexación. Operaciones Masivas: Agregar importación/exportación masiva eficiente para triples, incrustaciones de grafos e incrustaciones de documentos. Soporte Completo Async: Implementación completa de async/await para todas las interfaces (REST, WebSocket, operaciones masivas, métricas). Compatibilidad con Versiones Anteriores: El código existente continúa funcionando sin modificaciones. Seguridad de Tipos: Mantener interfaces con seguridad de tipos utilizando dataclasses y sugerencias de tipo. Mejora Progresiva: El streaming y el async son opcionales a través de la selección explícita de la interfaz. Rendimiento: Lograr una mejora de latencia de 60 veces para las operaciones de streaming. Python Moderno: Soporte para paradigmas tanto síncronos como asíncronos para una máxima flexibilidad.

Antecedentes

Estado Actual

La API de Python (trustgraph-base/trustgraph/api/) es una biblioteca de cliente REST con los siguientes módulos:

flow.py: Gestión de flujos y servicios con ámbito de flujo (50 métodos). library.py: Operaciones de la biblioteca de documentos (9 métodos). knowledge.py: Gestión central de grafos (4 métodos). collection.py: Metadatos de colecciones (3 métodos). config.py: Gestión de configuración (6 métodos). types.py: Definiciones de tipos de datos (5 dataclasses).

Operaciones Totales: 50/59 (cobertura del 85%).

Limitaciones Actuales

Operaciones Faltantes: Consulta de incrustaciones de grafos (búsqueda semántica sobre entidades de grafos). Importación/exportación masiva para triples, incrustaciones de grafos, incrustaciones de documentos, contextos de entidades, objetos. Punto final de métricas.

Capacidades Faltantes: Soporte de streaming para servicios de LLM. Transporte WebSocket. Solicitudes concurrentes multiplexadas. Conexiones persistentes.

Problemas de Rendimiento: Alta latencia para las interacciones de LLM (~30 s para el primer token). Transferencia de datos masiva ineficiente (solicitud REST por elemento). Sobrecarga de conexión para múltiples operaciones secuenciales.

Problemas de Experiencia de Usuario: Sin retroalimentación en tiempo real durante la generación de LLM. No se pueden cancelar las operaciones de LLM de larga duración. Mala escalabilidad para las operaciones masivas.

Impacto

La mejora de streaming de noviembre de 2024 en la API Gateway proporcionó una mejora de latencia de 60 veces (500 ms frente a 30 s para el primer token) para las interacciones de LLM, pero los usuarios de la API de Python no pueden aprovechar esta capacidad. Esto crea una brecha significativa de experiencia entre los usuarios de Python y los que no lo utilizan.

Diseño Técnico

Arquitectura

La API de Python refactorizada utiliza un enfoque de interfaz modular con objetos separados para diferentes patrones de comunicación. Todas las interfaces están disponibles tanto en variantes síncronas como asíncronas:

  1. Interfaz REST (existente, mejorada). Sync: api.flow(), api.library(), api.knowledge(), api.collection(), api.config(). Async: api.async_flow(). Solicitud/respuesta síncrona/asíncrona. Modelo de conexión simple. Predeterminado para la compatibilidad con versiones anteriores.

  2. Interfaz WebSocket (nueva). Sync: api.socket(). Async: api.async_socket(). Conexión persistente. Solicitudes multiplexadas. Soporte de streaming. Mismas firmas de método que REST donde la funcionalidad se superpone.

  3. Interfaz de Operaciones Masivas (nueva). Sync: api.bulk(). Async: api.async_bulk(). Basado en WebSocket para la eficiencia. Importación/exportación basada en iterador/AsyncIterator. Maneja conjuntos de datos grandes.

  4. Interfaz de Métricas (nueva). Sync: api.metrics(). Async: api.async_metrics(). Acceso a métricas de Prometheus.

import asyncio

# Synchronous interfaces
api = Api(url="http://localhost:8088/")

# REST (existing, unchanged)
flow = api.flow().id("default")
response = flow.agent(question="...", user="...")

# WebSocket (new)
socket_flow = api.socket().flow("default")
response = socket_flow.agent(question="...", user="...")
for chunk in socket_flow.agent(question="...", user="...", streaming=True):
    print(chunk)

# Bulk operations (new)
bulk = api.bulk()
bulk.import_triples(flow="default", triples=triple_generator())

# Asynchronous interfaces
async def main():
    api = Api(url="http://localhost:8088/")

    # Async REST (new)
    flow = api.async_flow().id("default")
    response = await flow.agent(question="...", user="...")

    # Async WebSocket (new)
    socket_flow = api.async_socket().flow("default")
    async for chunk in socket_flow.agent(question="...", streaming=True):
        print(chunk)

    # Async bulk operations (new)
    bulk = api.async_bulk()
    await bulk.import_triples(flow="default", triples=async_triple_generator())

asyncio.run(main())

Principios clave de diseño: Misma URL para todas las interfaces: Api(url="http://localhost:8088/") funciona para todas. Simetría sincrónica/asincrónica: Cada interfaz tiene variantes tanto sincrónicas como asincrónicas con firmas de método idénticas. Firmas idénticas: Donde la funcionalidad se superpone, las firmas de los métodos son idénticas entre REST y WebSocket, sincrónicas y asincrónicas. Mejora progresiva: Elija la interfaz según las necesidades (REST para tareas simples, WebSocket para transmisión, Bulk para conjuntos de datos grandes, asíncrono para marcos modernos). Intención explícita: api.socket() indica WebSocket, api.async_socket() indica WebSocket asíncrono. Compatible con versiones anteriores: El código existente no se modifica.

Componentes

1. Clase API principal (modificada)

Módulo: trustgraph-base/trustgraph/api/api.py

Clase API mejorada:

class Api:
    def __init__(self, url: str, timeout: int = 60, token: Optional[str] = None):
        self.url = url
        self.timeout = timeout
        self.token = token  # Optional bearer token for REST, query param for WebSocket
        self._socket_client = None
        self._bulk_client = None
        self._async_flow = None
        self._async_socket_client = None
        self._async_bulk_client = None

    # Existing synchronous methods (unchanged)
    def flow(self) -> Flow:
        """Synchronous REST-based flow interface"""
        pass

    def library(self) -> Library:
        """Synchronous REST-based library interface"""
        pass

    def knowledge(self) -> Knowledge:
        """Synchronous REST-based knowledge interface"""
        pass

    def collection(self) -> Collection:
        """Synchronous REST-based collection interface"""
        pass

    def config(self) -> Config:
        """Synchronous REST-based config interface"""
        pass

    # New synchronous methods
    def socket(self) -> SocketClient:
        """Synchronous WebSocket-based interface for streaming operations"""
        if self._socket_client is None:
            self._socket_client = SocketClient(self.url, self.timeout, self.token)
        return self._socket_client

    def bulk(self) -> BulkClient:
        """Synchronous bulk operations interface for import/export"""
        if self._bulk_client is None:
            self._bulk_client = BulkClient(self.url, self.timeout, self.token)
        return self._bulk_client

    def metrics(self) -> Metrics:
        """Synchronous metrics interface"""
        return Metrics(self.url, self.timeout, self.token)

    # New asynchronous methods
    def async_flow(self) -> AsyncFlow:
        """Asynchronous REST-based flow interface"""
        if self._async_flow is None:
            self._async_flow = AsyncFlow(self.url, self.timeout, self.token)
        return self._async_flow

    def async_socket(self) -> AsyncSocketClient:
        """Asynchronous WebSocket-based interface for streaming operations"""
        if self._async_socket_client is None:
            self._async_socket_client = AsyncSocketClient(self.url, self.timeout, self.token)
        return self._async_socket_client

    def async_bulk(self) -> AsyncBulkClient:
        """Asynchronous bulk operations interface for import/export"""
        if self._async_bulk_client is None:
            self._async_bulk_client = AsyncBulkClient(self.url, self.timeout, self.token)
        return self._async_bulk_client

    def async_metrics(self) -> AsyncMetrics:
        """Asynchronous metrics interface"""
        return AsyncMetrics(self.url, self.timeout, self.token)

    # Resource management
    def close(self) -> None:
        """Close all synchronous connections"""
        if self._socket_client:
            self._socket_client.close()
        if self._bulk_client:
            self._bulk_client.close()

    async def aclose(self) -> None:
        """Close all asynchronous connections"""
        if self._async_socket_client:
            await self._async_socket_client.aclose()
        if self._async_bulk_client:
            await self._async_bulk_client.aclose()
        if self._async_flow:
            await self._async_flow.aclose()

    def __enter__(self):
        return self

    def __exit__(self, *args):
        self.close()

    async def __aenter__(self):
        return self

    async def __aexit__(self, *args):
        await self.aclose()

2. Cliente WebSocket Síncrono

Módulo: trustgraph-base/trustgraph/api/socket_client.py (nuevo)

Clase SocketClient:

class SocketClient:
    """Synchronous WebSocket client"""
    def __init__(self, url: str, timeout: int, token: Optional[str]):
        self.url = self._convert_to_ws_url(url)
        self.timeout = timeout
        self.token = token
        self._connection = None
        self._request_counter = 0

    def flow(self, flow_id: str) -> SocketFlowInstance:
        """Get flow instance for WebSocket operations"""
        return SocketFlowInstance(self, flow_id)

    def _connect(self) -> WebSocket:
        """Establish WebSocket connection (lazy)"""
        # Uses asyncio.run() internally to wrap async websockets library
        pass

    def _send_request(
        self,
        service: str,
        flow: Optional[str],
        request: Dict[str, Any],
        streaming: bool = False
    ) -> Union[Dict[str, Any], Iterator[Dict[str, Any]]]:
        """Send request and handle response/streaming"""
        # Synchronous wrapper around async WebSocket calls
        pass

    def close(self) -> None:
        """Close WebSocket connection"""
        pass

class SocketFlowInstance:
    """Synchronous WebSocket flow instance with same interface as REST FlowInstance"""
    def __init__(self, client: SocketClient, flow_id: str):
        self.client = client
        self.flow_id = flow_id

    # Same method signatures as FlowInstance
    def agent(
        self,
        question: str,
        user: str,
        state: Optional[Dict[str, Any]] = None,
        group: Optional[str] = None,
        history: Optional[List[Dict[str, Any]]] = None,
        streaming: bool = False,
        **kwargs
    ) -> Union[Dict[str, Any], Iterator[Dict[str, Any]]]:
        """Agent with optional streaming"""
        pass

    def text_completion(
        self,
        system: str,
        prompt: str,
        streaming: bool = False,
        **kwargs
    ) -> Union[str, Iterator[str]]:
        """Text completion with optional streaming"""
        pass

    # ... similar for graph_rag, document_rag, prompt, etc.

Características principales: Conexión perezosa (solo se conecta cuando se envía la primera solicitud) Multiplexación de solicitudes (hasta 15 concurrentes) Reconexión automática en caso de desconexión Análisis de respuesta en streaming Operación segura para subprocesos Envoltorio sincrónico alrededor de la biblioteca de websockets asíncrona

3. Cliente WebSocket asíncrono

Módulo: trustgraph-base/trustgraph/api/async_socket_client.py (nuevo)

Clase AsyncSocketClient:

class AsyncSocketClient:
    """Asynchronous WebSocket client"""
    def __init__(self, url: str, timeout: int, token: Optional[str]):
        self.url = self._convert_to_ws_url(url)
        self.timeout = timeout
        self.token = token
        self._connection = None
        self._request_counter = 0

    def flow(self, flow_id: str) -> AsyncSocketFlowInstance:
        """Get async flow instance for WebSocket operations"""
        return AsyncSocketFlowInstance(self, flow_id)

    async def _connect(self) -> WebSocket:
        """Establish WebSocket connection (lazy)"""
        # Native async websockets library
        pass

    async def _send_request(
        self,
        service: str,
        flow: Optional[str],
        request: Dict[str, Any],
        streaming: bool = False
    ) -> Union[Dict[str, Any], AsyncIterator[Dict[str, Any]]]:
        """Send request and handle response/streaming"""
        pass

    async def aclose(self) -> None:
        """Close WebSocket connection"""
        pass

class AsyncSocketFlowInstance:
    """Asynchronous WebSocket flow instance"""
    def __init__(self, client: AsyncSocketClient, flow_id: str):
        self.client = client
        self.flow_id = flow_id

    # Same method signatures as FlowInstance (but async)
    async def agent(
        self,
        question: str,
        user: str,
        state: Optional[Dict[str, Any]] = None,
        group: Optional[str] = None,
        history: Optional[List[Dict[str, Any]]] = None,
        streaming: bool = False,
        **kwargs
    ) -> Union[Dict[str, Any], AsyncIterator[Dict[str, Any]]]:
        """Agent with optional streaming"""
        pass

    async def text_completion(
        self,
        system: str,
        prompt: str,
        streaming: bool = False,
        **kwargs
    ) -> Union[str, AsyncIterator[str]]:
        """Text completion with optional streaming"""
        pass

    # ... similar for graph_rag, document_rag, prompt, etc.

Características principales: Soporte nativo para async/await Eficiente para aplicaciones asíncronas (FastAPI, aiohttp) Sin bloqueo de hilos Misma interfaz que la versión síncrona AsyncIterator para streaming

4. Cliente de Operaciones Masivas Síncronas

Módulo: trustgraph-base/trustgraph/api/bulk_client.py (nuevo)

Clase BulkClient:

class BulkClient:
    """Synchronous bulk operations client"""
    def __init__(self, url: str, timeout: int, token: Optional[str]):
        self.url = self._convert_to_ws_url(url)
        self.timeout = timeout
        self.token = token

    def import_triples(
        self,
        flow: str,
        triples: Iterator[Triple],
        **kwargs
    ) -> None:
        """Bulk import triples via WebSocket"""
        pass

    def export_triples(
        self,
        flow: str,
        **kwargs
    ) -> Iterator[Triple]:
        """Bulk export triples via WebSocket"""
        pass

    def import_graph_embeddings(
        self,
        flow: str,
        embeddings: Iterator[Dict[str, Any]],
        **kwargs
    ) -> None:
        """Bulk import graph embeddings via WebSocket"""
        pass

    def export_graph_embeddings(
        self,
        flow: str,
        **kwargs
    ) -> Iterator[Dict[str, Any]]:
        """Bulk export graph embeddings via WebSocket"""
        pass

    # ... similar for document embeddings, entity contexts, objects

    def close(self) -> None:
        """Close connections"""
        pass

Características principales: Basado en iteradores para un uso constante de memoria. Conexiones WebSocket dedicadas por operación. Seguimiento del progreso (callback opcional). Manejo de errores con informes de éxito parcial.

5. Cliente de operaciones masivas asíncronas

Módulo: trustgraph-base/trustgraph/api/async_bulk_client.py (nuevo)

Clase AsyncBulkClient:

class AsyncBulkClient:
    """Asynchronous bulk operations client"""
    def __init__(self, url: str, timeout: int, token: Optional[str]):
        self.url = self._convert_to_ws_url(url)
        self.timeout = timeout
        self.token = token

    async def import_triples(
        self,
        flow: str,
        triples: AsyncIterator[Triple],
        **kwargs
    ) -> None:
        """Bulk import triples via WebSocket"""
        pass

    async def export_triples(
        self,
        flow: str,
        **kwargs
    ) -> AsyncIterator[Triple]:
        """Bulk export triples via WebSocket"""
        pass

    async def import_graph_embeddings(
        self,
        flow: str,
        embeddings: AsyncIterator[Dict[str, Any]],
        **kwargs
    ) -> None:
        """Bulk import graph embeddings via WebSocket"""
        pass

    async def export_graph_embeddings(
        self,
        flow: str,
        **kwargs
    ) -> AsyncIterator[Dict[str, Any]]:
        """Bulk export graph embeddings via WebSocket"""
        pass

    # ... similar for document embeddings, entity contexts, objects

    async def aclose(self) -> None:
        """Close connections"""
        pass

Características principales: Basado en AsyncIterator para un uso constante de memoria. Eficiente para aplicaciones asíncronas. Soporte nativo para async/await. Misma interfaz que la versión síncrona.

6. API de flujo REST (Síncrono - Sin cambios)

Módulo: trustgraph-base/trustgraph/api/flow.py

La API de flujo REST permanece completamente sin cambios para la compatibilidad con versiones anteriores. Todos los métodos existentes siguen funcionando:

Flow.list(), Flow.start(), Flow.stop(), etc. FlowInstance.agent(), FlowInstance.text_completion(), FlowInstance.graph_rag(), etc. Todas las firmas y tipos de retorno existentes se conservan.

Nuevo: Agregar graph_embeddings_query() a REST FlowInstance para la paridad de funciones:

class FlowInstance:
    # All existing methods unchanged...

    # New: Graph embeddings query (REST)
    def graph_embeddings_query(
        self,
        text: str,
        user: str,
        collection: str,
        limit: int = 10,
        **kwargs
    ) -> List[Dict[str, Any]]:
        """Query graph embeddings for semantic search"""
        # Calls POST /api/v1/flow/{flow}/service/graph-embeddings
        pass

7. API de flujo REST asíncrono

Módulo: trustgraph-base/trustgraph/api/async_flow.py (nuevo)

Clases AsyncFlow y AsyncFlowInstance:

class AsyncFlow:
    """Asynchronous REST-based flow interface"""
    def __init__(self, url: str, timeout: int, token: Optional[str]):
        self.url = url
        self.timeout = timeout
        self.token = token

    async def list(self) -> List[Dict[str, Any]]:
        """List all flows"""
        pass

    async def get(self, id: str) -> Dict[str, Any]:
        """Get flow definition"""
        pass

    async def start(self, class_name: str, id: str, description: str, parameters: Dict) -> None:
        """Start a flow"""
        pass

    async def stop(self, id: str) -> None:
        """Stop a flow"""
        pass

    def id(self, flow_id: str) -> AsyncFlowInstance:
        """Get async flow instance"""
        return AsyncFlowInstance(self.url, self.timeout, self.token, flow_id)

    async def aclose(self) -> None:
        """Close connection"""
        pass

class AsyncFlowInstance:
    """Asynchronous REST flow instance"""

    async def agent(
        self,
        question: str,
        user: str,
        state: Optional[Dict[str, Any]] = None,
        group: Optional[str] = None,
        history: Optional[List[Dict[str, Any]]] = None,
        **kwargs
    ) -> Dict[str, Any]:
        """Async agent execution"""
        pass

    async def text_completion(
        self,
        system: str,
        prompt: str,
        **kwargs
    ) -> str:
        """Async text completion"""
        pass

    async def graph_rag(
        self,
        question: str,
        user: str,
        collection: str,
        **kwargs
    ) -> str:
        """Async graph RAG"""
        pass

    # ... all other FlowInstance methods as async versions

Características principales: HTTP asíncrono nativo utilizando aiohttp o httpx Mismas firmas de método que la API REST sincrónica Sin transmisión (utilice async_socket() para la transmisión) Eficiente para aplicaciones asíncronas

8. API de métricas

Módulo: trustgraph-base/trustgraph/api/metrics.py (nuevo)

Métricas sincrónicas:

class Metrics:
    def __init__(self, url: str, timeout: int, token: Optional[str]):
        self.url = url
        self.timeout = timeout
        self.token = token

    def get(self) -> str:
        """Get Prometheus metrics as text"""
        # Call GET /api/metrics
        pass

Métricas Asíncronas:

class AsyncMetrics:
    def __init__(self, url: str, timeout: int, token: Optional[str]):
        self.url = url
        self.timeout = timeout
        self.token = token

    async def get(self) -> str:
        """Get Prometheus metrics as text"""
        # Call GET /api/metrics
        pass

9. Tipos Mejorados

Módulo: trustgraph-base/trustgraph/api/types.py (modificado)

Nuevos Tipos:

from typing import Iterator, Union, Dict, Any
import dataclasses

@dataclasses.dataclass
class StreamingChunk:
    """Base class for streaming chunks"""
    content: str
    end_of_message: bool = False

@dataclasses.dataclass
class AgentThought(StreamingChunk):
    """Agent reasoning chunk"""
    chunk_type: str = "thought"

@dataclasses.dataclass
class AgentObservation(StreamingChunk):
    """Agent tool observation chunk"""
    chunk_type: str = "observation"

@dataclasses.dataclass
class AgentAnswer(StreamingChunk):
    """Agent final answer chunk"""
    chunk_type: str = "final-answer"
    end_of_dialog: bool = False

@dataclasses.dataclass
class RAGChunk(StreamingChunk):
    """RAG streaming chunk"""
    end_of_stream: bool = False
    error: Optional[Dict[str, str]] = None

# Type aliases for clarity
AgentStream = Iterator[Union[AgentThought, AgentObservation, AgentAnswer]]
RAGStream = Iterator[RAGChunk]
CompletionStream = Iterator[str]

6. API de métricas

Módulo: trustgraph-base/trustgraph/api/metrics.py (nuevo)

class Metrics:
    def __init__(self, url: str, timeout: int, token: Optional[str]):
        self.url = url
        self.timeout = timeout
        self.token = token

    def get(self) -> str:
        """Get Prometheus metrics as text"""
        # Call GET /api/metrics
        pass

Enfoque de Implementación

Fase 1: Mejora del API Central (Semana 1)

  1. Agregar métodos socket(), bulk() y metrics() a la clase Api
  2. Implementar inicialización perezosa para WebSocket y clientes masivos
  3. Agregar soporte para administrador de contexto (__enter__, __exit__)
  4. Agregar método close() para limpieza
  5. Agregar pruebas unitarias para las mejoras del API
  6. Verificar compatibilidad con versiones anteriores

Compatibilidad con versiones anteriores: No hay cambios que rompan la compatibilidad. Solo se agregan nuevos métodos.

Fase 2: Cliente WebSocket (Semanas 2-3)

  1. Implementar clase SocketClient con gestión de conexión
  2. Implementar SocketFlowInstance con las mismas firmas de método que FlowInstance
  3. Agregar soporte para multiplexación de solicitudes (hasta 15 concurrentes)
  4. Agregar análisis de respuesta en streaming para diferentes tipos de fragmentos
  5. Agregar lógica de reconexión automática
  6. Agregar pruebas unitarias e integrales
  7. Documentar patrones de uso de WebSocket

Compatibilidad con versiones anteriores: Nueva interfaz solamente. No tiene impacto en el código existente.

Fase 3: Soporte de Streaming (Semanas 3-4)

  1. Agregar clases de tipo de fragmento de streaming (AgentThought, AgentObservation, AgentAnswer, RAGChunk)
  2. Implementar análisis de respuesta en streaming en SocketClient
  3. Agregar parámetro de streaming a todos los métodos LLM en SocketFlowInstance
  4. Manejar casos de error durante el streaming
  5. Agregar pruebas unitarias e integrales para el streaming
  6. Agregar ejemplos de streaming a la documentación

Compatibilidad con versiones anteriores: Nueva interfaz solamente. El API REST existente no se modifica.

Fase 4: Operaciones Masivas (Semanas 4-5)

  1. Implementar clase BulkClient
  2. Agregar métodos de importación/exportación masiva para triples, incrustaciones, contextos, objetos
  3. Implementar procesamiento basado en iterador para un uso constante de memoria
  4. Agregar seguimiento de progreso (callback opcional)
  5. Agregar manejo de errores con informes de éxito parcial
  6. Agregar pruebas unitarias e integrales
  7. Agregar ejemplos de operaciones masivas

Compatibilidad con versiones anteriores: Nueva interfaz solamente. No tiene impacto en el código existente.

Fase 5: Paridad de Funciones y Pulido (Semana 5)

  1. Agregar graph_embeddings_query() a REST FlowInstance
  2. Implementar clase Metrics
  3. Agregar pruebas de integración exhaustivas
  4. Pruebas de rendimiento
  5. Actualizar toda la documentación
  6. Crear una guía de migración

Compatibilidad con versiones anteriores: Nuevos métodos solamente. No tiene impacto en el código existente.

Modelos de Datos

Selección de Interfaz

# Single API instance, same URL for all interfaces
api = Api(url="http://localhost:8088/")

# Synchronous interfaces
rest_flow = api.flow().id("default")           # Sync REST
socket_flow = api.socket().flow("default")     # Sync WebSocket
bulk = api.bulk()                               # Sync bulk operations
metrics = api.metrics()                         # Sync metrics

# Asynchronous interfaces
async_rest_flow = api.async_flow().id("default")      # Async REST
async_socket_flow = api.async_socket().flow("default") # Async WebSocket
async_bulk = api.async_bulk()                          # Async bulk operations
async_metrics = api.async_metrics()                    # Async metrics

Tipos de respuesta de transmisión

Transmisión del agente:

api = Api(url="http://localhost:8088/")

# REST interface - non-streaming (existing)
rest_flow = api.flow().id("default")
response = rest_flow.agent(question="What is ML?", user="user123")
print(response["response"])

# WebSocket interface - non-streaming (same signature)
socket_flow = api.socket().flow("default")
response = socket_flow.agent(question="What is ML?", user="user123")
print(response["response"])

# WebSocket interface - streaming (new)
for chunk in socket_flow.agent(question="What is ML?", user="user123", streaming=True):
    if isinstance(chunk, AgentThought):
        print(f"Thinking: {chunk.content}")
    elif isinstance(chunk, AgentObservation):
        print(f"Observed: {chunk.content}")
    elif isinstance(chunk, AgentAnswer):
        print(f"Answer: {chunk.content}")
        if chunk.end_of_dialog:
            break

Transmisión RAG:

api = Api(url="http://localhost:8088/")

# REST interface - non-streaming (existing)
rest_flow = api.flow().id("default")
response = rest_flow.graph_rag(question="What is Python?", user="user123", collection="default")
print(response)

# WebSocket interface - streaming (new)
socket_flow = api.socket().flow("default")
for chunk in socket_flow.graph_rag(
    question="What is Python?",
    user="user123",
    collection="default",
    streaming=True
):
    print(chunk.content, end="", flush=True)
    if chunk.end_of_stream:
        break

Operaciones masivas (síncronas):

api = Api(url="http://localhost:8088/")

# Bulk import triples
def triple_generator():
    yield Triple(s="http://ex.com/alice", p="http://ex.com/type", o="Person")
    yield Triple(s="http://ex.com/alice", p="http://ex.com/name", o="Alice")
    yield Triple(s="http://ex.com/bob", p="http://ex.com/type", o="Person")

bulk = api.bulk()
bulk.import_triples(flow="default", triples=triple_generator())

# Bulk export triples
for triple in bulk.export_triples(flow="default"):
    print(f"{triple.s} -> {triple.p} -> {triple.o}")

Operaciones masivas (asíncronas):

import asyncio

async def main():
    api = Api(url="http://localhost:8088/")

    # Async bulk import triples
    async def async_triple_generator():
        yield Triple(s="http://ex.com/alice", p="http://ex.com/type", o="Person")
        yield Triple(s="http://ex.com/alice", p="http://ex.com/name", o="Alice")
        yield Triple(s="http://ex.com/bob", p="http://ex.com/type", o="Person")

    bulk = api.async_bulk()
    await bulk.import_triples(flow="default", triples=async_triple_generator())

    # Async bulk export triples
    async for triple in bulk.export_triples(flow="default"):
        print(f"{triple.s} -> {triple.p} -> {triple.o}")

asyncio.run(main())

Ejemplo de REST asíncrono:

import asyncio

async def main():
    api = Api(url="http://localhost:8088/")

    # Async REST flow operations
    flow = api.async_flow().id("default")
    response = await flow.agent(question="What is ML?", user="user123")
    print(response["response"])

asyncio.run(main())

Ejemplo de transmisión WebSocket asíncrona:

import asyncio

async def main():
    api = Api(url="http://localhost:8088/")

    # Async WebSocket streaming
    socket = api.async_socket()
    flow = socket.flow("default")

    async for chunk in flow.agent(question="What is ML?", user="user123", streaming=True):
        if isinstance(chunk, AgentAnswer):
            print(chunk.content, end="", flush=True)
            if chunk.end_of_dialog:
                break

asyncio.run(main())

APIs

New APIs

  1. Clase API Core: Síncrono: Api.socket() - Obtener cliente WebSocket síncrono Api.bulk() - Obtener cliente de operaciones masivas síncrono Api.metrics() - Obtener cliente de métricas síncrono Api.close() - Cerrar todas las conexiones síncronas Soporte de administrador de contexto (__enter__, __exit__) Asíncrono: Api.async_flow() - Obtener cliente de flujo REST asíncrono Api.async_socket() - Obtener cliente WebSocket asíncrono Api.async_bulk() - Obtener cliente de operaciones masivas asíncrono Api.async_metrics() - Obtener cliente de métricas asíncrono Api.aclose() - Cerrar todas las conexiones asíncronas Soporte de administrador de contexto asíncrono (__aenter__, __aexit__)

  2. Cliente WebSocket Síncrono: SocketClient.flow(flow_id) - Obtener instancia de flujo WebSocket SocketFlowInstance.agent(..., streaming: bool = False) - Agente con transmisión opcional SocketFlowInstance.text_completion(..., streaming: bool = False) - Completar texto con transmisión opcional SocketFlowInstance.graph_rag(..., streaming: bool = False) - RAG de gráfico con transmisión opcional SocketFlowInstance.document_rag(..., streaming: bool = False) - RAG de documento con transmisión opcional SocketFlowInstance.prompt(..., streaming: bool = False) - Prompt con transmisión opcional SocketFlowInstance.graph_embeddings_query() - Consulta de incrustaciones de gráfico Todos los demás métodos de FlowInstance con firmas idénticas

  3. Cliente WebSocket Asíncrono: AsyncSocketClient.flow(flow_id) - Obtener instancia de flujo WebSocket asíncrono AsyncSocketFlowInstance.agent(..., streaming: bool = False) - Agente asíncrono con transmisión opcional AsyncSocketFlowInstance.text_completion(..., streaming: bool = False) - Completar texto asíncrono con transmisión opcional AsyncSocketFlowInstance.graph_rag(..., streaming: bool = False) - RAG de gráfico asíncrono con transmisión opcional AsyncSocketFlowInstance.document_rag(..., streaming: bool = False) - RAG de documento asíncrono con transmisión opcional AsyncSocketFlowInstance.prompt(..., streaming: bool = False) - Prompt asíncrono con transmisión opcional AsyncSocketFlowInstance.graph_embeddings_query() - Consulta de incrustaciones de gráfico asíncrona Todos los demás métodos de FlowInstance como versiones asíncronas

  4. Cliente de Operaciones Masivas Síncrono: BulkClient.import_triples(flow, triples) - Importación masiva de triples BulkClient.export_triples(flow) - Exportación masiva de triples BulkClient.import_graph_embeddings(flow, embeddings) - Importación masiva de incrustaciones de gráfico BulkClient.export_graph_embeddings(flow) - Exportación masiva de incrustaciones de gráfico BulkClient.import_document_embeddings(flow, embeddings) - Importación masiva de incrustaciones de documento BulkClient.export_document_embeddings(flow) - Exportación masiva de incrustaciones de documento BulkClient.import_entity_contexts(flow, contexts) - Importación masiva de contextos de entidades BulkClient.export_entity_contexts(flow) - Exportación masiva de contextos de entidades BulkClient.import_objects(flow, objects) - Importación masiva de objetos

  5. Cliente de Operaciones Masivas Asíncrono: AsyncBulkClient.import_triples(flow, triples) - Importación asíncrona masiva de triples AsyncBulkClient.export_triples(flow) - Exportación asíncrona masiva de triples AsyncBulkClient.import_graph_embeddings(flow, embeddings) - Importación asíncrona masiva de incrustaciones de gráfico AsyncBulkClient.export_graph_embeddings(flow) - Exportación asíncrona masiva de incrustaciones de gráfico AsyncBulkClient.import_document_embeddings(flow, embeddings) - Importación asíncrona masiva de incrustaciones de documento AsyncBulkClient.export_document_embeddings(flow) - Exportación asíncrona masiva de incrustaciones de documento AsyncBulkClient.import_entity_contexts(flow, contexts) - Importación asíncrona masiva de contextos de entidades AsyncBulkClient.export_entity_contexts(flow) - Exportación asíncrona masiva de contextos de entidades AsyncBulkClient.import_objects(flow, objects) - Importación asíncrona masiva de objetos

  6. Cliente de Flujo REST Asíncrono: AsyncFlow.list() - Listar todos los flujos de forma asíncrona AsyncFlow.get(id) - Obtener definición de flujo de forma asíncrona AsyncFlow.start(...) - Iniciar flujo de forma asíncrona AsyncFlow.stop(id) - Detener flujo de forma asíncrona AsyncFlow.id(flow_id) - Obtener instancia de flujo de forma asíncrona AsyncFlowInstance.agent(...) - Ejecución de agente asíncrona AsyncFlowInstance.text_completion(...) - Completar texto de forma asíncrona AsyncFlowInstance.graph_rag(...) - RAG de gráfico asíncrono Todos los demás métodos de FlowInstance como versiones asíncronas

  7. Clientes de Métricas: Metrics.get() - Métricas de Prometheus síncronas AsyncMetrics.get() - Métricas de Prometheus asíncronas

  8. Mejora de la API REST de Flujo: FlowInstance.graph_embeddings_query() - Consulta de incrustaciones de gráfico (paridad de funciones síncronas) AsyncFlowInstance.graph_embeddings_query() - Consulta de incrustaciones de gráfico (paridad de funciones asíncronas)

APIs Modificadas

  1. Constructor (pequeña mejora):

    Api(url: str, timeout: int = 60, token: Optional[str] = None)
    

    Se agregó el parámetro token (opcional, para autenticación). Si None no se especifica (por defecto): No se utiliza autenticación. Si se especifica: Se utiliza como token de tipo "bearer" para REST (Authorization: Bearer <token>), parámetro de consulta para WebSocket (?token=<token>). No se realizaron otros cambios; es totalmente compatible con versiones anteriores.

  2. Sin cambios que rompan la compatibilidad: Todos los métodos de la API REST existentes no se han modificado. Todas las firmas existentes se han conservado. Todos los tipos de retorno existentes se han conservado.

Detalles de implementación

Manejo de errores

Errores de conexión WebSocket:

try:
    api = Api(url="http://localhost:8088/")
    socket = api.socket()
    socket_flow = socket.flow("default")
    response = socket_flow.agent(question="...", user="user123")
except ConnectionError as e:
    print(f"WebSocket connection failed: {e}")
    print("Hint: Ensure Gateway is running and WebSocket endpoint is accessible")

Respaldo Elegante:

api = Api(url="http://localhost:8088/")

try:
    # Try WebSocket streaming first
    socket_flow = api.socket().flow("default")
    for chunk in socket_flow.agent(question="...", user="...", streaming=True):
        print(chunk.content)
except ConnectionError:
    # Fall back to REST non-streaming
    print("WebSocket unavailable, falling back to REST")
    rest_flow = api.flow().id("default")
    response = rest_flow.agent(question="...", user="...")
    print(response["response"])

Errores de transmisión parcial:

api = Api(url="http://localhost:8088/")
socket_flow = api.socket().flow("default")

accumulated = []
try:
    for chunk in socket_flow.graph_rag(question="...", streaming=True):
        accumulated.append(chunk.content)
        if chunk.error:
            print(f"Error occurred: {chunk.error}")
            print(f"Partial response: {''.join(accumulated)}")
            break
except Exception as e:
    print(f"Streaming error: {e}")
    print(f"Partial response: {''.join(accumulated)}")

Gestión de Recursos

Soporte para Administradores de Contexto:

# Automatic cleanup
with Api(url="http://localhost:8088/") as api:
    socket_flow = api.socket().flow("default")
    response = socket_flow.agent(question="...", user="user123")
# All connections automatically closed

# Manual cleanup
api = Api(url="http://localhost:8088/")
try:
    socket_flow = api.socket().flow("default")
    response = socket_flow.agent(question="...", user="user123")
finally:
    api.close()  # Explicitly close all connections (WebSocket, bulk, etc.)

Concurrencia y Subprocesamiento

Seguridad de Subprocesos: Cada instancia de Api mantiene su propia conexión. El transporte WebSocket utiliza bloqueos para el multiplexado de solicitudes, que es seguro para subprocesos. Múltiples subprocesos pueden compartir una instancia de Api de forma segura. Los iteradores de transmisión no son seguros para subprocesos (se deben consumir desde un solo subproceso).

Soporte Asíncrono (consideración futura):

# Phase 2 enhancement (not in initial scope)
import asyncio

async def main():
    api = await AsyncApi(url="ws://localhost:8088/")
    flow = api.flow().id("default")

    async for chunk in flow.agent(question="...", streaming=True):
        print(chunk.content)

    await api.close()

asyncio.run(main())

Consideraciones de seguridad

Autenticación

Parámetro de token:

# No authentication (default)
api = Api(url="http://localhost:8088/")

# With authentication
api = Api(url="http://localhost:8088/", token="mytoken")

Transporte REST: Token del portador a través del encabezado Authorization Se aplica automáticamente a todas las solicitudes REST Formato: Authorization: Bearer <token>

Transporte WebSocket: Token a través de un parámetro de consulta adjunto a la URL de WebSocket Se aplica automáticamente durante el establecimiento de la conexión Formato: ws://localhost:8088/api/v1/socket?token=<token>

Implementación:

class SocketClient:
    def _connect(self) -> WebSocket:
        # Construct WebSocket URL with optional token
        ws_url = f"{self.url}/api/v1/socket"
        if self.token:
            ws_url = f"{ws_url}?token={self.token}"
        # Connect to WebSocket
        return websocket.connect(ws_url)

Ejemplo:

# REST with auth
api = Api(url="http://localhost:8088/", token="mytoken")
flow = api.flow().id("default")
# All REST calls include: Authorization: Bearer mytoken

# WebSocket with auth
socket = api.socket()
# Connects to: ws://localhost:8088/api/v1/socket?token=mytoken

Comunicación Segura

Soporta tanto los esquemas WS (WebSocket) como los de WSS (WebSocket Secure). Validación de certificados TLS para conexiones WSS. Verificación de certificados opcional para desarrollo (con advertencia).

Validación de Datos de Entrada

Validar esquemas de URL (http, https, ws, wss). Validar valores de parámetros de transporte. Validar combinaciones de parámetros de transmisión. Validar tipos de datos para la importación masiva.

Consideraciones de Rendimiento

Mejoras en la Latencia

Operaciones de LLM en Transmisión: Tiempo hasta el primer token: ~500ms (vs ~30s sin transmisión) Mejora: 60 veces más rápido en términos de rendimiento percibido. Aplicable a: Agente, Graph RAG, Document RAG, Completar Texto, Prompt.

Conexiones Persistentes: Sobrecarga de la conexión: Eliminada para solicitudes posteriores. Handshake de WebSocket: Costo único (~100ms). Aplicable a: Todas las operaciones al usar el transporte WebSocket.

Mejoras en el Rendimiento (Throughput)

Operaciones Masivas: Importación de triples: ~10,000 triples/segundo (vs ~100/segundo con REST por elemento). Importación de embeddings: ~5,000 embeddings/segundo (vs ~50/segundo con REST por elemento). Mejora: 100 veces más de rendimiento para operaciones masivas.

Multiplexación de Solicitudes: Solicitudes concurrentes: Hasta 15 solicitudes simultáneas sobre una sola conexión. Reutilización de la conexión: Sin sobrecarga de conexión para operaciones concurrentes.

Consideraciones de Memoria

Respuestas en Transmisión: Uso constante de memoria (procesa los fragmentos a medida que llegan). No se almacena en búfer la respuesta completa. Adecuado para salidas muy largas (>1MB).

Operaciones Masivas: Procesamiento basado en iteradores (uso constante de memoria). No se carga todo el conjunto de datos en la memoria. Adecuado para conjuntos de datos con millones de elementos.

Pruebas de Rendimiento (Esperadas)

Operación REST (existente) WebSocket (en transmisión) Mejora
Agente (tiempo hasta el primer token) 30s 0.5s 60x
Graph RAG (tiempo hasta el primer token) 25s 0.5s 50x
Importar 10K triples 100s 1s 100x
Importar 1M triples 10,000s (2.7h) 100s (1.6m) 100x
10 solicitudes pequeñas concurrentes 5s (secuencial) 0.5s (paralelo) 10x

Estrategia de Pruebas

Pruebas Unitarias

Capa de Transporte (test_transport.py): Probar la solicitud/respuesta de transporte REST Probar la conexión de transporte WebSocket Probar la reconexión de transporte WebSocket Probar el multiplexado de solicitudes Probar el análisis de la respuesta de transmisión Simular un servidor WebSocket para pruebas deterministas

Métodos de la API (test_flow.py, test_library.py, etc.): Probar nuevos métodos con transporte simulado Probar el manejo de parámetros de transmisión Probar iteradores de operaciones masivas Probar el manejo de errores

Tipos (test_types.py): Probar nuevos tipos de fragmentos de transmisión Probar la serialización/deserialización de tipos

Pruebas de Integración

REST de Extremo a Extremo (test_integration_rest.py): Probar todas las operaciones contra la puerta de enlace real (modo REST) Verificar la compatibilidad con versiones anteriores Probar condiciones de error

WebSocket de Extremo a Extremo (test_integration_websocket.py): Probar todas las operaciones contra la puerta de enlace real (modo WebSocket) Probar operaciones de transmisión Probar operaciones masivas Probar solicitudes concurrentes Probar la recuperación de la conexión

Servicios de Transmisión (test_streaming_integration.py): Probar la transmisión de agentes (pensamientos, observaciones, respuestas) Probar la transmisión de RAG (fragmentos incrementales) Probar la transmisión de finalización de texto (token por token) Probar la transmisión de indicaciones Probar el manejo de errores durante la transmisión

Operaciones Masivas (test_bulk_integration.py): Probar la importación/exportación masiva de triples (1K, 10K, 100K elementos) Probar la importación/exportación masiva de incrustaciones Probar el uso de memoria durante las operaciones masivas Probar el seguimiento del progreso

Pruebas de Rendimiento

Mediciones de Latencia (test_performance_latency.py): Medir el tiempo hasta el primer token (transmisión vs. no transmisión) Medir la sobrecarga de la conexión (REST vs WebSocket) Comparar con puntos de referencia esperados

Mediciones de Rendimiento (test_performance_throughput.py): Medir el rendimiento de la importación masiva Medir la eficiencia del multiplexado de solicitudes Comparar con puntos de referencia esperados

Pruebas de Compatibilidad

Compatibilidad con Versiones Anteriores (test_backward_compatibility.py): Ejecutar el conjunto de pruebas existente contra la API refactorizada Verificar la ausencia de cambios que rompan la compatibilidad Probar la ruta de migración para patrones comunes

Plan de Migración

Fase 1: Migración Transparente (Predeterminada)

No se requieren cambios en el código. El código existente continúa funcionando:

# Existing code works unchanged
api = Api(url="http://localhost:8088/")
flow = api.flow().id("default")
response = flow.agent(question="What is ML?", user="user123")

Fase 2: Transmisión por demanda (Simple)

Utilice la interfaz api.socket() para habilitar la transmisión:

# Before: Non-streaming REST
api = Api(url="http://localhost:8088/")
rest_flow = api.flow().id("default")
response = rest_flow.agent(question="What is ML?", user="user123")
print(response["response"])

# After: Streaming WebSocket (same parameters!)
api = Api(url="http://localhost:8088/")  # Same URL
socket_flow = api.socket().flow("default")

for chunk in socket_flow.agent(question="What is ML?", user="user123", streaming=True):
    if isinstance(chunk, AgentAnswer):
        print(chunk.content, end="", flush=True)

Puntos clave: La misma URL para REST y WebSocket. Las mismas firmas de métodos (migración sencilla). Simplemente agregue .socket() y streaming=True.

Fase 3: Operaciones masivas (Nueva funcionalidad)

Utilice la interfaz api.bulk() para conjuntos de datos grandes:

# Before: Inefficient per-item operations
api = Api(url="http://localhost:8088/")
flow = api.flow().id("default")

for triple in my_large_triple_list:
    # Slow per-item operations
    # (no direct bulk insert in REST API)
    pass

# After: Efficient bulk loading
api = Api(url="http://localhost:8088/")  # Same URL
bulk = api.bulk()

# This is fast (10,000 triples/second)
bulk.import_triples(flow="default", triples=iter(my_large_triple_list))

Actualizaciones de la documentación

  1. README.md: Agregar ejemplos de transmisión y WebSocket
  2. Referencia de la API: Documentar todos los nuevos métodos y parámetros
  3. Guía de migración: Guía paso a paso para habilitar la transmisión
  4. Ejemplos: Agregar scripts de ejemplo para patrones comunes
  5. Guía de rendimiento: Documentar las mejoras de rendimiento esperadas

Política de obsolescencia

No hay obsolescencias. Todas las API existentes siguen siendo compatibles. Esto es una mejora pura.

Cronograma

Semana 1: Base

Capa de abstracción de transporte Refactorizar código REST existente Pruebas unitarias para la capa de transporte Verificación de compatibilidad con versiones anteriores

Semana 2: Transporte WebSocket

Implementación del transporte WebSocket Gestión de conexiones y reconexión Multiplexación de solicitudes Pruebas unitarias e de integración

Semana 3: Soporte de transmisión

Agregar parámetro de transmisión a los métodos de LLM Implementar el análisis de respuestas de transmisión Agregar tipos de fragmentos de transmisión Pruebas de integración de transmisión

Semana 4: Operaciones masivas

Agregar métodos de importación/exportación masivos Implementar operaciones basadas en iteradores Pruebas de rendimiento Pruebas de integración de operaciones masivas

Semana 5: Paridad de funciones y documentación

Agregar consulta de incrustaciones de grafos Agregar API de métricas Documentación completa Guía de migración Versión candidata

Semana 6: Lanzamiento

Pruebas de integración finales Pruebas de referencia de rendimiento Documentación de lanzamiento Anuncio a la comunidad

Duración total: 6 semanas

Preguntas abiertas

Preguntas de diseño de la API

  1. Soporte asíncrono: RESUELTO - Soporte asíncrono completo incluido en el lanzamiento inicial Todas las interfaces tienen variantes asíncronas: async_flow(), async_socket(), async_bulk(), async_metrics() Proporciona una simetría completa entre las API sincrónicas y asíncronas Esencial para marcos de trabajo asíncronos modernos (FastAPI, aiohttp)

  2. Seguimiento del progreso: ¿Deben las operaciones masivas admitir devoluciones de llamada de progreso?

    def progress_callback(processed: int, total: Optional[int]):
        print(f"Processed {processed} items")
    
    bulk.import_triples(flow="default", triples=triples, on_progress=progress_callback)
    

    Recomendación: Agregar en la Fase 2. No es crítico para la versión inicial.

  3. Tiempo de espera de la transmisión: ¿Cómo debemos manejar los tiempos de espera para las operaciones de transmisión? Recomendación: Utilizar el mismo tiempo de espera que para las operaciones no de transmisión, pero restablecerlo cada vez que se recibe un fragmento.

  4. Almacenamiento en búfer de fragmentos: ¿Debemos almacenar los fragmentos en búfer o devolverlos inmediatamente? Recomendación: Devolverlos inmediatamente para lograr la menor latencia.

  5. Servicios globales a través de WebSocket: ¿Debería api.socket() admitir servicios globales (biblioteca, conocimiento, colección, configuración) o solo servicios específicos del flujo? Recomendación: Comenzar solo con servicios específicos del flujo (donde la transmisión es importante). Agregar servicios globales si es necesario en la Fase 2.

Preguntas de implementación

  1. Biblioteca de WebSocket: ¿Debemos usar websockets, websocket-client o aiohttp? Recomendación: websockets (asíncrono, maduro, bien mantenido). Envolverlo en una interfaz síncrona utilizando asyncio.run().

  2. Grupo de conexiones: ¿Debemos admitir múltiples instancias concurrentes de Api que compartan un grupo de conexiones? Recomendación: Dejar para la Fase 2. Cada instancia de Api tendrá sus propias conexiones inicialmente.

  3. Reutilización de conexiones: ¿Deben SocketClient y BulkClient compartir la misma conexión de WebSocket, o usar conexiones separadas? Recomendación: Conexiones separadas. Implementación más sencilla, separación de responsabilidades más clara.

  4. Conexión perezosa vs. activa: ¿Se debe establecer la conexión de WebSocket en api.socket() o en la primera solicitud? Recomendación: Perezosa (en la primera solicitud). Evita la sobrecarga de la conexión si el usuario solo utiliza métodos REST.

Preguntas de prueba

  1. Pasarela de simulación: ¿Debemos crear una pasarela de simulación ligera para las pruebas, o probar contra la pasarela real? Recomendación: Ambos. Utilizar simulaciones para pruebas unitarias, y la pasarela real para pruebas de integración.

  2. Pruebas de regresión de rendimiento: ¿Debemos agregar pruebas de regresión de rendimiento automatizadas a CI? Recomendación: Sí, pero con umbrales amplios para tener en cuenta la variabilidad del entorno de CI.

Referencias

Especificaciones técnicas relacionadas

docs/tech-specs/streaming-llm-responses.md - Implementación de transmisión en la pasarela docs/tech-specs/rag-streaming-support.md - Soporte de transmisión RAG

Archivos de implementación

trustgraph-base/trustgraph/api/ - Código fuente de la API de Python trustgraph-flow/trustgraph/gateway/ - Código fuente de la pasarela trustgraph-flow/trustgraph/gateway/dispatch/mux.py - Implementación de referencia de multiplexor de WebSocket

Documentación

docs/apiSpecification.md - Referencia completa de la API docs/api-status-summary.md - Resumen del estado de la API README.websocket - Documentación del protocolo WebSocket STREAMING-IMPLEMENTATION-NOTES.txt - Notas de implementación de transmisión

Bibliotecas externas

websockets - Biblioteca de WebSocket de Python (https://websockets.readthedocs.io/) requests - Biblioteca HTTP de Python (existente)