mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-04-26 17:06:22 +02:00
Structure the tech specs directory (#836)
Tech spec some subdirectories for different languages
This commit is contained in:
parent
48da6c5f8b
commit
e7efb673ef
423 changed files with 0 additions and 0 deletions
|
|
@ -1,578 +0,0 @@
|
|||
---
|
||||
layout: default
|
||||
title: "Especificación Técnica de Respuestas de LLM en Streaming"
|
||||
parent: "Spanish (Beta)"
|
||||
---
|
||||
|
||||
# Especificación Técnica de Respuestas de LLM en Streaming
|
||||
|
||||
> **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 la implementación del soporte de streaming para respuestas de LLM
|
||||
en TrustGraph. El streaming permite la entrega en tiempo real de tokens generados
|
||||
a medida que son producidos por el LLM, en lugar de esperar a que se complete
|
||||
la generación de la respuesta.
|
||||
|
||||
Esta implementación admite los siguientes casos de uso:
|
||||
|
||||
1. **Interfaces de Usuario en Tiempo Real**: Transmite tokens a la interfaz de usuario a medida que se generan,
|
||||
proporcionando retroalimentación visual inmediata.
|
||||
2. **Reducción del Tiempo Hasta el Primer Token**: Los usuarios ven la salida inmediatamente
|
||||
en lugar de esperar a que se complete la generación.
|
||||
3. **Manejo de Respuestas Largas**: Maneja salidas muy largas que de otro modo
|
||||
podrían provocar un tiempo de espera o exceder los límites de memoria.
|
||||
4. **Aplicaciones Interactivas**: Permite interfaces de chat y agentes receptivas.
|
||||
|
||||
## Objetivos
|
||||
|
||||
**Compatibilidad con Versiones Anteriores**: Los clientes existentes que no utilizan streaming continúan funcionando
|
||||
sin modificaciones.
|
||||
**Diseño de API Consistente**: El streaming y el no streaming utilizan los mismos patrones de esquema
|
||||
con una divergencia mínima.
|
||||
**Flexibilidad del Proveedor**: Soporte de streaming cuando esté disponible, con una
|
||||
alternativa gradual cuando no esté disponible.
|
||||
**Implementación por Fases**: Implementación incremental para reducir el riesgo.
|
||||
**Soporte de Extremo a Extremo**: Streaming desde el proveedor de LLM hasta las aplicaciones cliente
|
||||
a través de Pulsar, la API de Gateway y la API de Python.
|
||||
|
||||
## Antecedentes
|
||||
|
||||
### Arquitectura Actual
|
||||
|
||||
El flujo actual de finalización de texto de LLM funciona de la siguiente manera:
|
||||
|
||||
1. El cliente envía `TextCompletionRequest` con los campos `system` y `prompt`.
|
||||
2. El servicio de LLM procesa la solicitud y espera a que se complete la generación.
|
||||
3. Se devuelve un único `TextCompletionResponse` con la cadena `response` completa.
|
||||
|
||||
Esquema actual (`trustgraph-base/trustgraph/schema/services/llm.py`):
|
||||
|
||||
```python
|
||||
class TextCompletionRequest(Record):
|
||||
system = String()
|
||||
prompt = String()
|
||||
|
||||
class TextCompletionResponse(Record):
|
||||
error = Error()
|
||||
response = String()
|
||||
in_token = Integer()
|
||||
out_token = Integer()
|
||||
model = String()
|
||||
```
|
||||
|
||||
### Limitaciones actuales
|
||||
|
||||
**Latencia**: Los usuarios deben esperar a que se complete la generación antes de ver cualquier resultado.
|
||||
**Riesgo de tiempo de espera**: Las generaciones largas pueden exceder los umbrales de tiempo de espera del cliente.
|
||||
**Mala experiencia de usuario**: La falta de retroalimentación durante la generación crea la percepción de lentitud.
|
||||
**Uso de recursos**: Las respuestas completas deben almacenarse en búfer en la memoria.
|
||||
|
||||
Esta especificación aborda estas limitaciones al permitir la entrega incremental de respuestas, manteniendo la compatibilidad total con versiones anteriores.
|
||||
|
||||
|
||||
## Diseño técnico
|
||||
|
||||
### Fase 1: Infraestructura
|
||||
|
||||
La Fase 1 establece la base para la transmisión mediante la modificación de esquemas, API y herramientas de línea de comandos.
|
||||
|
||||
|
||||
#### Cambios en el esquema
|
||||
|
||||
##### Esquema de LLM (`trustgraph-base/trustgraph/schema/services/llm.py`)
|
||||
|
||||
**Cambios en la solicitud:**
|
||||
|
||||
```python
|
||||
class TextCompletionRequest(Record):
|
||||
system = String()
|
||||
prompt = String()
|
||||
streaming = Boolean() # NEW: Default false for backward compatibility
|
||||
```
|
||||
|
||||
`streaming`: Cuando `true`, solicita la entrega de la respuesta en modo de transmisión.
|
||||
Predeterminado: `false` (el comportamiento existente se mantiene).
|
||||
|
||||
**Cambios en la respuesta:**
|
||||
|
||||
```python
|
||||
class TextCompletionResponse(Record):
|
||||
error = Error()
|
||||
response = String()
|
||||
in_token = Integer()
|
||||
out_token = Integer()
|
||||
model = String()
|
||||
end_of_stream = Boolean() # NEW: Indicates final message
|
||||
```
|
||||
|
||||
`end_of_stream`: Cuando `true`, indica que esta es la respuesta final (o única).
|
||||
Para solicitudes no de transmisión: Respuesta única con `end_of_stream=true`.
|
||||
Para solicitudes de transmisión: Múltiples respuestas, todas con `end_of_stream=false`
|
||||
excepto la última.
|
||||
|
||||
##### Esquema de la solicitud (`trustgraph-base/trustgraph/schema/services/prompt.py`)
|
||||
|
||||
El servicio de solicitud envuelve la finalización de texto, por lo que refleja el mismo patrón:
|
||||
|
||||
**Cambios en la solicitud:**
|
||||
|
||||
```python
|
||||
class PromptRequest(Record):
|
||||
id = String()
|
||||
terms = Map(String())
|
||||
streaming = Boolean() # NEW: Default false
|
||||
```
|
||||
|
||||
**Cambios en la respuesta:**
|
||||
|
||||
```python
|
||||
class PromptResponse(Record):
|
||||
error = Error()
|
||||
text = String()
|
||||
object = String()
|
||||
end_of_stream = Boolean() # NEW: Indicates final message
|
||||
```
|
||||
|
||||
#### Cambios en la API de Gateway
|
||||
|
||||
La API de Gateway debe exponer capacidades de transmisión a clientes HTTP/WebSocket.
|
||||
|
||||
**Actualizaciones de la API REST:**
|
||||
|
||||
`POST /api/v1/text-completion`: Aceptar el parámetro `streaming` en el cuerpo de la solicitud.
|
||||
El comportamiento de la respuesta depende de la bandera de transmisión:
|
||||
`streaming=false`: Respuesta JSON única (comportamiento actual).
|
||||
`streaming=true`: Flujo de eventos enviados por el servidor (SSE) o mensajes WebSocket.
|
||||
|
||||
**Formato de respuesta (transmisión):**
|
||||
|
||||
Cada fragmento transmitido sigue la misma estructura de esquema:
|
||||
```json
|
||||
{
|
||||
"response": "partial text...",
|
||||
"end_of_stream": false,
|
||||
"model": "model-name"
|
||||
}
|
||||
```
|
||||
|
||||
Fragmento final:
|
||||
```json
|
||||
{
|
||||
"response": "final text chunk",
|
||||
"end_of_stream": true,
|
||||
"in_token": 150,
|
||||
"out_token": 500,
|
||||
"model": "model-name"
|
||||
}
|
||||
```
|
||||
|
||||
#### Cambios en la API de Python
|
||||
|
||||
La API del cliente de Python debe soportar tanto modos de transmisión como no de transmisión
|
||||
manteniendo la compatibilidad con versiones anteriores.
|
||||
|
||||
**Actualizaciones de LlmClient** (`trustgraph-base/trustgraph/clients/llm_client.py`):
|
||||
|
||||
```python
|
||||
class LlmClient(BaseClient):
|
||||
def request(self, system, prompt, timeout=300, streaming=False):
|
||||
"""
|
||||
Non-streaming request (backward compatible).
|
||||
Returns complete response string.
|
||||
"""
|
||||
# Existing behavior when streaming=False
|
||||
|
||||
async def request_stream(self, system, prompt, timeout=300):
|
||||
"""
|
||||
Streaming request.
|
||||
Yields response chunks as they arrive.
|
||||
"""
|
||||
# New async generator method
|
||||
```
|
||||
|
||||
**Actualizaciones de PromptClient** (`trustgraph-base/trustgraph/base/prompt_client.py`):
|
||||
|
||||
Patrón similar con el parámetro `streaming` y la variante de generador asíncrono.
|
||||
|
||||
#### Cambios en la herramienta de línea de comandos
|
||||
|
||||
**tg-invoke-llm** (`trustgraph-cli/trustgraph/cli/invoke_llm.py`):
|
||||
|
||||
```
|
||||
tg-invoke-llm [system] [prompt] [--no-streaming] [-u URL] [-f flow-id]
|
||||
```
|
||||
|
||||
La transmisión está habilitada de forma predeterminada para una mejor experiencia de usuario interactiva.
|
||||
La opción `--no-streaming` desactiva la transmisión.
|
||||
Cuando la transmisión está habilitada: envía los tokens a la salida estándar a medida que llegan.
|
||||
Cuando la transmisión no está habilitada: espera la respuesta completa y luego la muestra.
|
||||
|
||||
**tg-invoke-prompt** (`trustgraph-cli/trustgraph/cli/invoke_prompt.py`):
|
||||
|
||||
```
|
||||
tg-invoke-prompt [template-id] [var=value...] [--no-streaming] [-u URL] [-f flow-id]
|
||||
```
|
||||
|
||||
El mismo patrón que `tg-invoke-llm`.
|
||||
|
||||
#### Cambios en la Clase Base del Servicio LLM
|
||||
|
||||
**LlmService** (`trustgraph-base/trustgraph/base/llm_service.py`):
|
||||
|
||||
```python
|
||||
class LlmService(FlowProcessor):
|
||||
async def on_request(self, msg, consumer, flow):
|
||||
request = msg.value()
|
||||
streaming = getattr(request, 'streaming', False)
|
||||
|
||||
if streaming and self.supports_streaming():
|
||||
async for chunk in self.generate_content_stream(...):
|
||||
await self.send_response(chunk, end_of_stream=False)
|
||||
await self.send_response(final_chunk, end_of_stream=True)
|
||||
else:
|
||||
response = await self.generate_content(...)
|
||||
await self.send_response(response, end_of_stream=True)
|
||||
|
||||
def supports_streaming(self):
|
||||
"""Override in subclass to indicate streaming support."""
|
||||
return False
|
||||
|
||||
async def generate_content_stream(self, system, prompt, model, temperature):
|
||||
"""Override in subclass to implement streaming."""
|
||||
raise NotImplementedError()
|
||||
```
|
||||
|
||||
--
|
||||
|
||||
### Fase 2: Prueba de concepto de VertexAI
|
||||
|
||||
La Fase 2 implementa el streaming en un único proveedor (VertexAI) para validar la
|
||||
infraestructura y habilitar pruebas de extremo a extremo.
|
||||
|
||||
#### Implementación de VertexAI
|
||||
|
||||
**Módulo:** `trustgraph-vertexai/trustgraph/model/text_completion/vertexai/llm.py`
|
||||
|
||||
**Cambios:**
|
||||
|
||||
1. Sobreescribir `supports_streaming()` para devolver `True`
|
||||
2. Implementar generador asíncrono `generate_content_stream()`
|
||||
3. Manejar tanto los modelos Gemini como Claude (a través de la API de VertexAI Anthropic)
|
||||
|
||||
**Streaming de Gemini:**
|
||||
|
||||
```python
|
||||
async def generate_content_stream(self, system, prompt, model, temperature):
|
||||
model_instance = self.get_model(model, temperature)
|
||||
response = model_instance.generate_content(
|
||||
[system, prompt],
|
||||
stream=True # Enable streaming
|
||||
)
|
||||
for chunk in response:
|
||||
yield LlmChunk(
|
||||
text=chunk.text,
|
||||
in_token=None, # Available only in final chunk
|
||||
out_token=None,
|
||||
)
|
||||
# Final chunk includes token counts from response.usage_metadata
|
||||
```
|
||||
|
||||
**Claude (a través de VertexAI Anthropic) en modo de transmisión:**
|
||||
|
||||
```python
|
||||
async def generate_content_stream(self, system, prompt, model, temperature):
|
||||
with self.anthropic_client.messages.stream(...) as stream:
|
||||
for text in stream.text_stream:
|
||||
yield LlmChunk(text=text)
|
||||
# Token counts from stream.get_final_message()
|
||||
```
|
||||
|
||||
#### Pruebas
|
||||
|
||||
Pruebas unitarias para el ensamblaje de respuestas en streaming.
|
||||
Pruebas de integración con VertexAI (Gemini y Claude).
|
||||
Pruebas de extremo a extremo: CLI -> Gateway -> Pulsar -> VertexAI -> back.
|
||||
Pruebas de compatibilidad con versiones anteriores: Las solicitudes no en streaming aún funcionan.
|
||||
|
||||
--
|
||||
|
||||
### Fase 3: Todos los proveedores de LLM
|
||||
|
||||
La fase 3 extiende el soporte de streaming a todos los proveedores de LLM en el sistema.
|
||||
|
||||
#### Estado de implementación del proveedor
|
||||
|
||||
Cada proveedor debe:
|
||||
1. **Soporte completo de streaming**: Implementar `generate_content_stream()`
|
||||
2. **Modo de compatibilidad**: Manejar la bandera `end_of_stream` correctamente
|
||||
(devolver una única respuesta con `end_of_stream=true`)
|
||||
|
||||
| Proveedor | Paquete | Soporte de streaming |
|
||||
|----------|---------|-------------------|
|
||||
| OpenAI | trustgraph-flow | Completo (API de streaming nativo) |
|
||||
| Claude/Anthropic | trustgraph-flow | Completo (API de streaming nativo) |
|
||||
| Ollama | trustgraph-flow | Completo (API de streaming nativo) |
|
||||
| Cohere | trustgraph-flow | Completo (API de streaming nativo) |
|
||||
| Mistral | trustgraph-flow | Completo (API de streaming nativo) |
|
||||
| Azure OpenAI | trustgraph-flow | Completo (API de streaming nativo) |
|
||||
| Google AI Studio | trustgraph-flow | Completo (API de streaming nativo) |
|
||||
| VertexAI | trustgraph-vertexai | Completo (Fase 2) |
|
||||
| Bedrock | trustgraph-bedrock | Completo (API de streaming nativo) |
|
||||
| LM Studio | trustgraph-flow | Completo (compatible con OpenAI) |
|
||||
| LlamaFile | trustgraph-flow | Completo (compatible con OpenAI) |
|
||||
| vLLM | trustgraph-flow | Completo (compatible con OpenAI) |
|
||||
| TGI | trustgraph-flow | Por determinar |
|
||||
| Azure | trustgraph-flow | Por determinar |
|
||||
|
||||
#### Patrón de implementación
|
||||
|
||||
Para proveedores compatibles con OpenAI (OpenAI, LM Studio, LlamaFile, vLLM):
|
||||
|
||||
```python
|
||||
async def generate_content_stream(self, system, prompt, model, temperature):
|
||||
response = await self.client.chat.completions.create(
|
||||
model=model,
|
||||
messages=[
|
||||
{"role": "system", "content": system},
|
||||
{"role": "user", "content": prompt}
|
||||
],
|
||||
temperature=temperature,
|
||||
stream=True
|
||||
)
|
||||
async for chunk in response:
|
||||
if chunk.choices[0].delta.content:
|
||||
yield LlmChunk(text=chunk.choices[0].delta.content)
|
||||
```
|
||||
|
||||
--
|
||||
|
||||
### Fase 4: API del Agente
|
||||
|
||||
La Fase 4 extiende la transmisión a la API del Agente. Esto es más complejo porque
|
||||
la API del Agente ya es inherentemente multi-mensaje (pensamiento → acción → observación
|
||||
→ repetir → respuesta final).
|
||||
|
||||
#### Esquema actual del Agente
|
||||
|
||||
```python
|
||||
class AgentStep(Record):
|
||||
thought = String()
|
||||
action = String()
|
||||
arguments = Map(String())
|
||||
observation = String()
|
||||
user = String()
|
||||
|
||||
class AgentRequest(Record):
|
||||
question = String()
|
||||
state = String()
|
||||
group = Array(String())
|
||||
history = Array(AgentStep())
|
||||
user = String()
|
||||
|
||||
class AgentResponse(Record):
|
||||
answer = String()
|
||||
error = Error()
|
||||
thought = String()
|
||||
observation = String()
|
||||
```
|
||||
|
||||
#### Cambios Propuestos al Esquema del Agente
|
||||
|
||||
**Solicitar Cambios:**
|
||||
|
||||
```python
|
||||
class AgentRequest(Record):
|
||||
question = String()
|
||||
state = String()
|
||||
group = Array(String())
|
||||
history = Array(AgentStep())
|
||||
user = String()
|
||||
streaming = Boolean() # NEW: Default false
|
||||
```
|
||||
|
||||
**Cambios en la respuesta:**
|
||||
|
||||
El agente produce múltiples tipos de salida durante su ciclo de razonamiento:
|
||||
Pensamientos (razonamiento)
|
||||
Acciones (llamadas a herramientas)
|
||||
Observaciones (resultados de las herramientas)
|
||||
Respuesta (respuesta final)
|
||||
Errores
|
||||
|
||||
Dado que `chunk_type` identifica qué tipo de contenido se está enviando, los campos separados
|
||||
`answer`, `error`, `thought` y `observation` se pueden combinar en
|
||||
un único campo `content`:
|
||||
|
||||
```python
|
||||
class AgentResponse(Record):
|
||||
chunk_type = String() # "thought", "action", "observation", "answer", "error"
|
||||
content = String() # The actual content (interpretation depends on chunk_type)
|
||||
end_of_message = Boolean() # Current thought/action/observation/answer is complete
|
||||
end_of_dialog = Boolean() # Entire agent dialog is complete
|
||||
```
|
||||
|
||||
**Semántica de los campos:**
|
||||
|
||||
`chunk_type`: Indica qué tipo de contenido se encuentra en el campo `content`
|
||||
`"thought"`: Razonamiento/pensamiento del agente
|
||||
`"action"`: Herramienta/acción que se está invocando
|
||||
`"observation"`: Resultado de la ejecución de la herramienta
|
||||
`"answer"`: Respuesta final a la pregunta del usuario
|
||||
`"error"`: Mensaje de error
|
||||
|
||||
`content`: El contenido transmitido real, interpretado según `chunk_type`
|
||||
|
||||
`end_of_message`: Cuando `true`, el tipo de fragmento actual está completo
|
||||
Ejemplo: Todos los tokens para el pensamiento actual han sido enviados
|
||||
Permite a los clientes saber cuándo pasar a la siguiente etapa
|
||||
|
||||
`end_of_dialog`: Cuando `true`, la interacción completa del agente ha finalizado
|
||||
Este es el mensaje final en la transmisión
|
||||
|
||||
#### Comportamiento de la transmisión del agente
|
||||
|
||||
Cuando `streaming=true`:
|
||||
|
||||
1. **Transmisión de pensamientos:**
|
||||
Múltiples fragmentos con `chunk_type="thought"`, `end_of_message=false`
|
||||
El fragmento final del pensamiento tiene `end_of_message=true`
|
||||
2. **Notificación de acción:**
|
||||
Un solo fragmento con `chunk_type="action"`, `end_of_message=true`
|
||||
3. **Observación:**
|
||||
Fragmento(s) con `chunk_type="observation"`, el final tiene `end_of_message=true`
|
||||
4. **Repetir** los pasos 1-3 mientras el agente razona
|
||||
5. **Respuesta final:**
|
||||
`chunk_type="answer"` con la respuesta final en `content`
|
||||
El último fragmento tiene `end_of_message=true`, `end_of_dialog=true`
|
||||
|
||||
**Secuencia de ejemplo de la transmisión:**
|
||||
|
||||
```
|
||||
{chunk_type: "thought", content: "I need to", end_of_message: false, end_of_dialog: false}
|
||||
{chunk_type: "thought", content: " search for...", end_of_message: true, end_of_dialog: false}
|
||||
{chunk_type: "action", content: "search", end_of_message: true, end_of_dialog: false}
|
||||
{chunk_type: "observation", content: "Found: ...", end_of_message: true, end_of_dialog: false}
|
||||
{chunk_type: "thought", content: "Based on this", end_of_message: false, end_of_dialog: false}
|
||||
{chunk_type: "thought", content: " I can answer...", end_of_message: true, end_of_dialog: false}
|
||||
{chunk_type: "answer", content: "The answer is...", end_of_message: true, end_of_dialog: true}
|
||||
```
|
||||
|
||||
Cuando `streaming=false`:
|
||||
Comportamiento actual preservado
|
||||
Respuesta única con respuesta completa
|
||||
`end_of_message=true`, `end_of_dialog=true`
|
||||
|
||||
#### Gateway y API de Python
|
||||
|
||||
Gateway: Nuevo punto final SSE/WebSocket para la transmisión de agentes
|
||||
API de Python: Nuevo método de generador asíncrono `agent_stream()`
|
||||
|
||||
--
|
||||
|
||||
## Consideraciones de seguridad
|
||||
|
||||
**Sin nueva superficie de ataque**: La transmisión utiliza la misma autenticación/autorización
|
||||
**Limitación de velocidad**: Aplicar límites de velocidad por token o por fragmento si es necesario
|
||||
**Manejo de conexiones**: Terminar correctamente las transmisiones en caso de desconexión del cliente
|
||||
**Gestión de tiempos de espera**: Las solicitudes de transmisión requieren un manejo adecuado de los tiempos de espera
|
||||
|
||||
## Consideraciones de rendimiento
|
||||
|
||||
**Memoria**: La transmisión reduce el uso máximo de memoria (sin almacenamiento en búfer de la respuesta completa)
|
||||
**Latencia**: El tiempo hasta el primer token se reduce significativamente
|
||||
**Sobrecarga de conexión**: Las conexiones SSE/WebSocket tienen una sobrecarga de mantenimiento activo
|
||||
**Rendimiento de Pulsar**: Múltiples mensajes pequeños frente a un mensaje grande único
|
||||
tradeoff
|
||||
|
||||
## Estrategia de pruebas
|
||||
|
||||
### Pruebas unitarias
|
||||
Serialización/deserialización de esquema con nuevos campos
|
||||
Compatibilidad con versiones anteriores (los campos faltantes utilizan los valores predeterminados)
|
||||
Lógica de ensamblaje de fragmentos
|
||||
|
||||
### Pruebas de integración
|
||||
Implementación de transmisión de cada proveedor de LLM
|
||||
Puntos finales de transmisión de la API de Gateway
|
||||
Métodos de transmisión del cliente de Python
|
||||
|
||||
### Pruebas de extremo a extremo
|
||||
Salida de transmisión de la herramienta de línea de comandos
|
||||
Flujo completo: Cliente → Gateway → Pulsar → LLM → de vuelta
|
||||
Cargas de trabajo mixtas de transmisión/no transmisión
|
||||
|
||||
### Pruebas de compatibilidad con versiones anteriores
|
||||
Los clientes existentes funcionan sin modificaciones
|
||||
Las solicitudes no de transmisión se comportan de la misma manera
|
||||
|
||||
## Plan de migración
|
||||
|
||||
### Fase 1: Infraestructura
|
||||
Implementar cambios de esquema (compatible con versiones anteriores)
|
||||
Implementar actualizaciones de la API de Gateway
|
||||
Implementar actualizaciones de la API de Python
|
||||
Lanzar actualizaciones de la herramienta de línea de comandos
|
||||
|
||||
### Fase 2: VertexAI
|
||||
Implementar la implementación de transmisión de VertexAI
|
||||
Validar con cargas de trabajo de prueba
|
||||
|
||||
### Fase 3: Todos los proveedores
|
||||
Implementar las actualizaciones de los proveedores de forma incremental
|
||||
Monitorear problemas
|
||||
|
||||
### Fase 4: API de agente
|
||||
Implementar cambios de esquema de agente
|
||||
Implementar la implementación de transmisión de agente
|
||||
Actualizar la documentación
|
||||
|
||||
## Cronograma
|
||||
|
||||
| Fase | Descripción | Dependencias |
|
||||
|-------|-------------|--------------|
|
||||
| Fase 1 | Infraestructura | Ninguna |
|
||||
| Fase 2 | PoC de VertexAI | Fase 1 |
|
||||
| Fase 3 | Todos los proveedores | Fase 2 |
|
||||
| Fase 4 | API de agente | Fase 3 |
|
||||
|
||||
## Decisiones de diseño
|
||||
|
||||
Las siguientes preguntas se resolvieron durante la especificación:
|
||||
|
||||
1. **Conteo de tokens en la transmisión**: Los conteos de tokens son deltas, no totales acumulados.
|
||||
Los consumidores pueden sumarlos si es necesario. Esto coincide con la forma en que la mayoría de los proveedores informan
|
||||
el uso y simplifica la implementación.
|
||||
|
||||
2. **Manejo de errores en la transmisión**: Si ocurre un error, el campo `error` se
|
||||
completa y no se necesitan otros campos. Un error siempre es la comunicación final
|
||||
no se permiten ni se esperan mensajes posteriores después de
|
||||
un error. Para las transmisiones de LLM/Prompt, `end_of_stream=true`. Para las transmisiones de agente,
|
||||
`chunk_type="error"` con `end_of_dialog=true`.
|
||||
|
||||
3. **Recuperación de respuesta parcial**: El protocolo de mensajería (Pulsar) es resistente,
|
||||
por lo que no se necesita reintento a nivel de mensaje. Si un cliente pierde el seguimiento de la transmisión
|
||||
o se desconecta, debe reintentar la solicitud completa desde cero.
|
||||
|
||||
4. **Transmisión del servicio de prompt**: La transmisión solo es compatible con texto (`text`)
|
||||
respuestas, no respuestas estructuradas (`object`). El servicio de prompt lo sabe desde
|
||||
el principio si la salida será JSON o texto según la plantilla del prompt. Si se realiza una
|
||||
solicitud de transmisión para un prompt de salida JSON, el
|
||||
servicio debe:
|
||||
Devolver el JSON completo en una sola respuesta con `end_of_stream=true`, o
|
||||
Rechazar la solicitud de transmisión con un error
|
||||
|
||||
## Preguntas abiertas
|
||||
|
||||
Ninguna en este momento.
|
||||
|
||||
## Referencias
|
||||
|
||||
Esquema de LLM actual: `trustgraph-base/trustgraph/schema/services/llm.py`
|
||||
Esquema de prompt actual: `trustgraph-base/trustgraph/schema/services/prompt.py`
|
||||
Esquema de agente actual: `trustgraph-base/trustgraph/schema/services/agent.py`
|
||||
Base del servicio de LLM: `trustgraph-base/trustgraph/base/llm_service.py`
|
||||
Proveedor de VertexAI: `trustgraph-vertexai/trustgraph/model/text_completion/vertexai/llm.py`
|
||||
API de Gateway: `trustgraph-base/trustgraph/api/`
|
||||
Herramientas de CLI: `trustgraph-cli/trustgraph/cli/`
|
||||
Loading…
Add table
Add a link
Reference in a new issue