mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-04-25 16:36:21 +02:00
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.
578 lines
21 KiB
Markdown
578 lines
21 KiB
Markdown
---
|
|
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/`
|