trustgraph/docs/tech-specs/rag-streaming-support.pt.md

297 lines
12 KiB
Markdown
Raw Normal View History

---
layout: default
title: "Especificação Técnica de Suporte a Streaming RAG"
parent: "Portuguese (Beta)"
---
# Especificação Técnica de Suporte a Streaming RAG
> **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.
## Visão Geral
Esta especificação descreve a adição de suporte a streaming aos serviços GraphRAG e DocumentRAG, permitindo respostas em tempo real, token por token, para consultas de grafos de conhecimento e recuperação de documentos. Isso estende a arquitetura de streaming existente já implementada para serviços de preenchimento de texto, prompt e agente LLM.
## Objetivos
**Experiência de streaming consistente**: Fornecer a mesma experiência de streaming em todos os serviços TrustGraph.
**Alterações mínimas na API**: Adicionar suporte a streaming com um único sinalizador `streaming`, seguindo padrões estabelecidos.
**Compatibilidade com versões anteriores**: Manter o comportamento padrão existente sem streaming.
**Reutilizar infraestrutura existente**: Aproveitar o streaming do PromptClient já implementado.
**Suporte a gateway**: Permitir o streaming através do gateway WebSocket para aplicativos cliente.
## Contexto
Serviços de streaming atualmente implementados:
**Serviço de preenchimento de texto LLM**: Fase 1 - streaming de provedores LLM.
**Serviço de prompt**: Fase 2 - streaming através de modelos de prompt.
**Serviço de agente**: Fase 3-4 - streaming de respostas ReAct com fragmentos incrementais de pensamento/observação/resposta.
Limitações atuais para serviços RAG:
GraphRAG e DocumentRAG suportam apenas respostas bloqueadas.
Os usuários devem esperar pela resposta completa do LLM antes de ver qualquer saída.
Má experiência do usuário para respostas longas de grafos de conhecimento ou consultas de documentos.
Experiência inconsistente em comparação com outros serviços TrustGraph.
Esta especificação aborda essas lacunas adicionando suporte a streaming ao GraphRAG e ao DocumentRAG. Ao permitir respostas token por token, o TrustGraph pode:
Fornecer uma experiência de streaming consistente em todos os tipos de consulta.
Reduzir a latência percebida para consultas RAG.
Permitir um melhor feedback de progresso para consultas de longa duração.
Suportar a exibição em tempo real em aplicativos cliente.
## Design Técnico
### Arquitetura
A implementação de streaming RAG aproveita a infraestrutura existente:
1. **Streaming do PromptClient** (Já implementado)
`kg_prompt()` e `document_prompt()` já aceitam parâmetros `streaming` e `chunk_callback`.
Isso chama `prompt()` internamente com suporte a streaming.
Não são necessárias alterações no PromptClient.
Módulo: `trustgraph-base/trustgraph/base/prompt_client.py`
2. **Serviço GraphRAG** (Precisa de passagem de parâmetro de streaming)
Adicionar parâmetro `streaming` ao método `query()`.
Passar o sinalizador de streaming e os callbacks para `prompt_client.kg_prompt()`.
O esquema GraphRagRequest precisa do campo `streaming`.
Módulos:
`trustgraph-flow/trustgraph/retrieval/graph_rag/graph_rag.py`
`trustgraph-flow/trustgraph/retrieval/graph_rag/rag.py` (Processador)
`trustgraph-base/trustgraph/schema/graph_rag.py` (Esquema de solicitação)
`trustgraph-flow/trustgraph/gateway/dispatch/graph_rag.py` (Gateway)
3. **Serviço DocumentRAG** (Precisa de passagem de parâmetro de streaming)
Adicionar parâmetro `streaming` ao método `query()`.
Passar o sinalizador de streaming e os callbacks para `prompt_client.document_prompt()`.
O esquema DocumentRagRequest precisa do campo `streaming`.
Módulos:
`trustgraph-flow/trustgraph/retrieval/document_rag/document_rag.py`
`trustgraph-flow/trustgraph/retrieval/document_rag/rag.py` (Processador)
`trustgraph-base/trustgraph/schema/document_rag.py` (Esquema de solicitação)
`trustgraph-flow/trustgraph/gateway/dispatch/document_rag.py` (Gateway)
### Fluxo de Dados
**Não streaming (atual)**:
```
Client → Gateway → RAG Service → PromptClient.kg_prompt(streaming=False)
Prompt Service → LLM
Complete response
Client ← Gateway ← RAG Service ← Response
```
**Streaming (proposto):**
```
Client → Gateway → RAG Service → PromptClient.kg_prompt(streaming=True, chunk_callback=cb)
Prompt Service → LLM (streaming)
Chunk → callback → RAG Response (chunk)
↓ ↓
Client ← Gateway ← ────────────────────────────────── Response stream
```
### APIs
**Alterações no GraphRAG**:
1. **GraphRag.query()** - Adicionar parâmetros de streaming
```python
async def query(
self, query, user, collection,
verbose=False, streaming=False, chunk_callback=None # NEW
):
# ... existing entity/triple retrieval ...
if streaming and chunk_callback:
resp = await self.prompt_client.kg_prompt(
query, kg,
streaming=True,
chunk_callback=chunk_callback
)
else:
resp = await self.prompt_client.kg_prompt(query, kg)
return resp
```
2. **Esquema GraphRagRequest** - Adicionar campo de streaming.
```python
class GraphRagRequest(Record):
query = String()
user = String()
collection = String()
streaming = Boolean() # NEW
```
3. **Esquema GraphRagResponse** - Adicionar campos de streaming (seguir o padrão do Agente).
```python
class GraphRagResponse(Record):
response = String() # Legacy: complete response
chunk = String() # NEW: streaming chunk
end_of_stream = Boolean() # NEW: indicates last chunk
```
4. **Processador** - Permitir a passagem de dados em fluxo contínuo.
```python
async def handle(self, msg):
# ... existing code ...
async def send_chunk(chunk):
await self.respond(GraphRagResponse(
chunk=chunk,
end_of_stream=False,
response=None
))
if request.streaming:
full_response = await self.rag.query(
query=request.query,
user=request.user,
collection=request.collection,
streaming=True,
chunk_callback=send_chunk
)
# Send final message
await self.respond(GraphRagResponse(
chunk=None,
end_of_stream=True,
response=full_response
))
else:
# Existing non-streaming path
response = await self.rag.query(...)
await self.respond(GraphRagResponse(response=response))
```
**Alterações no DocumentRAG:**
Padrão idêntico ao GraphRAG:
1. Adicionar parâmetros `streaming` e `chunk_callback` a `DocumentRag.query()`
2. Adicionar campo `streaming` a `DocumentRagRequest`
3. Adicionar campos `chunk` e `end_of_stream` a `DocumentRagResponse`
4. Atualizar o Processador para lidar com streaming com callbacks
**Alterações no Gateway:**
Tanto `graph_rag.py` quanto `document_rag.py` no gateway/dispatch precisam de atualizações para encaminhar trechos de streaming para o websocket:
```python
async def handle(self, message, session, websocket):
# ... existing code ...
if request.streaming:
async def recipient(resp):
if resp.chunk:
await websocket.send(json.dumps({
"id": message["id"],
"response": {"chunk": resp.chunk},
"complete": resp.end_of_stream
}))
return resp.end_of_stream
await self.rag_client.request(request, recipient=recipient)
else:
# Existing non-streaming path
resp = await self.rag_client.request(request)
await websocket.send(...)
```
### Detalhes de Implementação
**Ordem de implementação**:
1. Adicionar campos de esquema (Request + Response para ambos os serviços RAG)
2. Atualizar os métodos GraphRag.query() e DocumentRag.query()
3. Atualizar Processadores para lidar com streaming
4. Atualizar manipuladores de despacho do Gateway
5. Adicionar `--no-streaming` flags a `tg-invoke-graph-rag` e `tg-invoke-document-rag` (streaming habilitado por padrão, seguindo o padrão da CLI do agente)
**Padrão de callback**:
Seguir o mesmo padrão de callback assíncrono estabelecido no streaming do Agente:
O Processador define o `async def send_chunk(chunk)` callback
Passa o callback para o serviço RAG
O serviço RAG passa o callback para o PromptClient
O PromptClient invoca o callback para cada chunk do LLM
O Processador envia uma mensagem de resposta de streaming para cada chunk
**Tratamento de erros**:
Erros durante o streaming devem enviar uma resposta de erro com `end_of_stream=True`
Seguir os padrões existentes de propagação de erros do streaming do Agente
## Considerações de Segurança
Não há novas considerações de segurança além dos serviços RAG existentes:
As respostas de streaming usam o mesmo isolamento de usuário/coleção
Não há alterações na autenticação ou autorização
Os limites de chunk não expõem dados sensíveis
## Considerações de Desempenho
**Benefícios**:
Latência percebida reduzida (os primeiros tokens chegam mais rápido)
Melhor experiência do usuário para respostas longas
Menor uso de memória (não é necessário armazenar em buffer a resposta completa)
**Preocupações potenciais**:
Mais mensagens Pulsar para respostas de streaming
Ligeiramente maior uso de CPU para a sobrecarga de chunking/callback
Mitigado por: o streaming é opcional, o padrão permanece não-streaming
**Considerações de teste**:
Testar com grafos de conhecimento grandes (muitos triplos)
Testar com muitos documentos recuperados
Medir a sobrecarga do streaming versus não-streaming
## Estratégia de Teste
**Testes unitários**:
Testar GraphRag.query() com streaming=True/False
Testar DocumentRag.query() com streaming=True/False
Simular o PromptClient para verificar as invocações de callback
**Testes de integração**:
Testar o fluxo completo de streaming do GraphRAG (semelhante aos testes existentes de streaming do agente)
Testar o fluxo completo de streaming do DocumentRAG
Testar o encaminhamento de streaming do Gateway
Testar a saída de streaming da CLI
**Testes manuais**:
`tg-invoke-graph-rag -q "What is machine learning?"` (streaming por padrão)
`tg-invoke-document-rag -q "Summarize the documents about AI"` (streaming por padrão)
`tg-invoke-graph-rag --no-streaming -q "..."` (testar o modo não-streaming)
Verificar se a saída incremental aparece no modo de streaming
## Plano de Migração
Nenhuma migração necessária:
O streaming é opcional por meio do parâmetro `streaming` (o padrão é Falso)
Os clientes existentes continuam a funcionar sem alterações
Novos clientes podem optar por usar o streaming
## Cronograma
Tempo estimado de implementação: 4-6 horas
Fase 1 (2 horas): suporte de streaming do GraphRAG
Fase 2 (2 horas): suporte de streaming do DocumentRAG
Fase 3 (1-2 horas): atualizações do Gateway e flags da CLI
Testes: integrados em cada fase
## Perguntas Abertas
Devemos adicionar suporte de streaming ao serviço de consulta NLP também?
Queremos transmitir etapas intermediárias (por exemplo, "Recuperando entidades...", "Consultando o grafo...") ou apenas a saída do LLM?
As respostas do GraphRAG/DocumentRAG devem incluir metadados do chunk (por exemplo, número do chunk, total esperado)?
## Referências
Implementação existente: `docs/tech-specs/streaming-llm-responses.md`
Streaming do Agente: `trustgraph-flow/trustgraph/agent/react/agent_manager.py`
Streaming do PromptClient: `trustgraph-base/trustgraph/base/prompt_client.py`