trustgraph/docs/tech-specs/rag-streaming-support.pt.md
Alex Jenkins 8954fa3ad7 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:08:32 +01:00

12 KiB

layout title parent
default Especificação Técnica de Suporte a Streaming RAG 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
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
  1. Esquema GraphRagRequest - Adicionar campo de streaming.
class GraphRagRequest(Record):
    query = String()
    user = String()
    collection = String()
    streaming = Boolean()  # NEW
  1. Esquema GraphRagResponse - Adicionar campos de streaming (seguir o padrão do Agente).
class GraphRagResponse(Record):
    response = String()    # Legacy: complete response
    chunk = String()       # NEW: streaming chunk
    end_of_stream = Boolean()  # NEW: indicates last chunk
  1. Processador - Permitir a passagem de dados em fluxo contínuo.
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:

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