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.
18 KiB
| layout | title | parent |
|---|---|---|
| default | Especificação Técnica de Saída de Prompt JSONL | Portuguese (Beta) |
<<<<<<< HEAD
Especificação Técnica de Saída de Prompt JSONL
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. =======
Especificação Técnica da Saída de Prompt JSONL
82edf2d (New md files from RunPod)
Visão Geral
Esta especificação descreve a implementação do formato de saída JSONL (JSON Lines) <<<<<<< HEAD para respostas de prompt no TrustGraph. JSONL permite a extração de dados estruturados de forma resiliente à truncagem das respostas de LLM, abordando problemas críticos relacionados à corrupção de saídas de matriz JSON quando as respostas de LLM atingem
para respostas de prompt no TrustGraph. O JSONL permite a extração de dados estruturados de forma resistente a truncamentos das respostas de LLM, abordando problemas críticos relacionados à corrupção de saídas de matrizes JSON quando as respostas de LLM atingem
82edf2d (New md files from RunPod) os limites de tokens de saída.
Esta implementação suporta os seguintes casos de uso:
- Extração Resistente à Truncagem: Extrair resultados parciais válidos mesmo quando a saída do LLM é truncada no meio da resposta.
- Extração em Larga Escala: Lidar com a extração de muitos itens sem risco de falha completa devido a limites de tokens.
- Extração de Tipos Mistos: Suportar a extração de vários tipos de entidades (definições, relacionamentos, entidades, atributos) em um único prompt.
- Saída Compatível com Streaming: Permitir o processamento futuro de streaming/incremental dos resultados da extração.
Objetivos
Compatibilidade com versões anteriores: As instruções existentes que usam response-type: "text" e
response-type: "json" continuam a funcionar sem modificação.
Resiliência à truncagem: Saídas parciais do LLM produzem resultados válidos parciais
em vez de falha completa.
Validação de esquema: Suporte à validação de esquema JSON para objetos individuais.
Uniões discriminadas: Suporte a saídas de tipos mistos usando um campo type
discriminador.
Alterações mínimas na API: Estenda a configuração de instruções existente com um novo
tipo de resposta e chave de esquema.
Contexto
Arquitetura atual
O serviço de instruções suporta dois tipos de resposta:
response-type: "text"- Resposta de texto bruto retornada como está.response-type: "json"- JSON analisado da resposta, validado contra umschemaopcional.
Implementação atual em trustgraph-flow/trustgraph/template/prompt_manager.py:
class Prompt:
def __init__(self, template, response_type = "text", terms=None, schema=None):
self.template = template
self.response_type = response_type
self.terms = terms
self.schema = schema
Limitações Atuais
Quando os prompts de extração solicitam a saída como arrays JSON ([{...}, {...}, ...]):
Corrupção por truncamento: Se o LLM atinge os limites de tokens de saída no meio do array, a resposta inteira se torna JSON inválido e não pode ser analisada. Análise "tudo ou nada": É necessário receber a saída completa antes de analisar. Sem resultados parciais: Uma resposta truncada produz zero dados utilizáveis. Não confiável para grandes extrações: Quanto mais itens extraídos, maior o risco de falha.
<<<<<<< HEAD Esta especificação aborda essas limitações introduzindo o formato JSONL para
Esta especificação aborda essas limitações, introduzindo o formato JSONL para
82edf2d (New md files from RunPod) prompts de extração, onde cada item extraído é um objeto JSON completo em sua própria linha.
Design Técnico
Extensão do Tipo de Resposta
Adicione um novo tipo de resposta "jsonl", juntamente com os tipos existentes "text" e "json".
Alterações de Configuração
Novo valor do tipo de resposta:
"response-type": "jsonl"
Interpretação do esquema:
A chave existente "schema" é usada tanto para o tipo de resposta "json" quanto para o tipo de resposta "jsonl".
A interpretação depende do tipo de resposta:
"json": O esquema descreve toda a resposta (geralmente um array ou objeto).
"jsonl": O esquema descreve cada linha/objeto individual.
{
"response-type": "jsonl",
"schema": {
"type": "object",
"properties": {
"entity": { "type": "string" },
"definition": { "type": "string" }
},
"required": ["entity", "definition"]
}
}
Isso evita alterações nas ferramentas de configuração e nos editores.
Especificação do Formato JSONL
Extração Simples
Para prompts que extraem um único tipo de objeto (definições, relacionamentos, tópicos, linhas), a saída é um objeto JSON por linha, sem wrapper:
Formato de saída do prompt:
{"entity": "photosynthesis", "definition": "Process by which plants convert sunlight"}
{"entity": "chlorophyll", "definition": "Green pigment in plants"}
{"entity": "mitochondria", "definition": "Powerhouse of the cell"}
<<<<<<< HEAD Contraste com o formato anterior de array JSON:
Contraste com o formato de array JSON anterior:
82edf2d (New md files from RunPod)
[
{"entity": "photosynthesis", "definition": "Process by which plants convert sunlight"},
{"entity": "chlorophyll", "definition": "Green pigment in plants"},
{"entity": "mitochondria", "definition": "Powerhouse of the cell"}
]
Se o LLM truncar após a linha 2, o formato de array JSON resulta em JSON inválido, <<<<<<< HEAD enquanto o JSONL produz dois objetos válidos.
enquanto o JSONL gera dois objetos válidos.
82edf2d (New md files from RunPod)
Extração de Tipos Mistos (Uniões Discriminadas)
Para prompts que extraem vários tipos de objetos (por exemplo, definições e
relacionamentos, ou entidades, relacionamentos e atributos), use um campo "type"
como discriminador:
Formato de saída do prompt:
{"type": "definition", "entity": "DNA", "definition": "Molecule carrying genetic instructions"}
{"type": "relationship", "subject": "DNA", "predicate": "located_in", "object": "cell nucleus", "object-entity": true}
{"type": "definition", "entity": "RNA", "definition": "Molecule that carries genetic information"}
{"type": "relationship", "subject": "RNA", "predicate": "transcribed_from", "object": "DNA", "object-entity": true}
Esquema para uniões discriminadas usa oneOf:
{
"response-type": "jsonl",
"schema": {
"oneOf": [
{
"type": "object",
"properties": {
"type": { "const": "definition" },
"entity": { "type": "string" },
"definition": { "type": "string" }
},
"required": ["type", "entity", "definition"]
},
{
"type": "object",
"properties": {
"type": { "const": "relationship" },
"subject": { "type": "string" },
"predicate": { "type": "string" },
"object": { "type": "string" },
"object-entity": { "type": "boolean" }
},
"required": ["type", "subject", "predicate", "object", "object-entity"]
}
]
}
}
Extração de Ontologia
Para extração baseada em ontologia com entidades, relacionamentos e atributos:
Formato de saída do prompt:
{"type": "entity", "entity": "Cornish pasty", "entity_type": "fo/Recipe"}
{"type": "entity", "entity": "beef", "entity_type": "fo/Food"}
{"type": "relationship", "subject": "Cornish pasty", "subject_type": "fo/Recipe", "relation": "fo/has_ingredient", "object": "beef", "object_type": "fo/Food"}
{"type": "attribute", "entity": "Cornish pasty", "entity_type": "fo/Recipe", "attribute": "fo/serves", "value": "4 people"}
Detalhes de Implementação
Classe Prompt
A classe Prompt existente não requer alterações. O campo schema é reutilizado
para JSONL, com sua interpretação determinada por response_type:
class Prompt:
def __init__(self, template, response_type="text", terms=None, schema=None):
self.template = template
self.response_type = response_type
self.terms = terms
self.schema = schema # Interpretation depends on response_type
PromptManager.load_config
<<<<<<< HEAD
Nenhuma alteração necessária - o carregamento da configuração existente já lida com a
schema chave.
Nenhuma alteração necessária - o carregamento da configuração existente já trata da
chave schema.
82edf2d (New md files from RunPod)
Análise de JSONL
Adicionar um novo método de análise para respostas JSONL:
def parse_jsonl(self, text):
"""
Parse JSONL response, returning list of valid objects.
Invalid lines (malformed JSON, empty lines) are skipped with warnings.
This provides truncation resilience - partial output yields partial results.
"""
results = []
for line_num, line in enumerate(text.strip().split('\n'), 1):
line = line.strip()
# Skip empty lines
if not line:
continue
# Skip markdown code fence markers if present
if line.startswith('```'):
continue
try:
obj = json.loads(line)
results.append(obj)
except json.JSONDecodeError as e:
# Log warning but continue - this provides truncation resilience
logger.warning(f"JSONL parse error on line {line_num}: {e}")
return results
Alterações no PromptManager.invoke
Estenda o método invoke para lidar com o novo tipo de resposta:
async def invoke(self, id, input, llm):
logger.debug("Invoking prompt template...")
terms = self.terms | self.prompts[id].terms | input
resp_type = self.prompts[id].response_type
prompt = {
"system": self.system_template.render(terms),
"prompt": self.render(id, input)
}
resp = await llm(**prompt)
if resp_type == "text":
return resp
if resp_type == "json":
try:
obj = self.parse_json(resp)
except:
logger.error(f"JSON parse failed: {resp}")
raise RuntimeError("JSON parse fail")
if self.prompts[id].schema:
try:
validate(instance=obj, schema=self.prompts[id].schema)
logger.debug("Schema validation successful")
except Exception as e:
raise RuntimeError(f"Schema validation fail: {e}")
return obj
if resp_type == "jsonl":
objects = self.parse_jsonl(resp)
if not objects:
logger.warning("JSONL parse returned no valid objects")
return []
# Validate each object against schema if provided
if self.prompts[id].schema:
validated = []
for i, obj in enumerate(objects):
try:
validate(instance=obj, schema=self.prompts[id].schema)
validated.append(obj)
except Exception as e:
logger.warning(f"Object {i} failed schema validation: {e}")
return validated
return objects
raise RuntimeError(f"Response type {resp_type} not known")
Prompts Afetados
Os seguintes prompts devem ser migrados para o formato JSONL:
| ID do Prompt | Descrição | Campo de Tipo |
|---|---|---|
extract-definitions |
Extração de entidade/definição | Não (tipo único) |
extract-relationships |
Extração de relacionamento | Não (tipo único) |
extract-topics |
Extração de tópico/definição | Não (tipo único) |
extract-rows |
Extração de linha estruturada | Não (tipo único) |
agent-kg-extract |
Extração combinada de definição + relacionamento | Sim: "definition", "relationship" |
extract-with-ontologies / ontology-extract |
Extração baseada em ontologia | Sim: "entity", "relationship", "attribute" |
Alterações na API
Perspectiva do Cliente
A análise JSONL é transparente para os chamadores da API do serviço de prompt. A análise ocorre
no lado do servidor no serviço de prompt, e a resposta é retornada através do campo padrão
PromptResponse.object como um array JSON serializado.
Quando os clientes chamam o serviço de prompt (via PromptClient.prompt() ou similar):
response-type: "json" com esquema de array → o cliente recebe list do Python
response-type: "jsonl" → o cliente recebe list do Python
Da perspectiva do cliente, ambos retornam estruturas de dados idênticas. A diferença está inteiramente em como a saída do LLM é analisada no lado do servidor:
Formato de array JSON: Uma única chamada json.loads(); falha completamente se truncado
Formato JSONL: Análise linha por linha; produz resultados parciais se truncado
Isso significa que o código do cliente existente que espera uma lista de prompts de extração não requer alterações ao migrar prompts de JSON para JSONL.
Valor de Retorno do Servidor
Para response-type: "jsonl", o método PromptManager.invoke() retorna um
list[dict] contendo todos os objetos analisados e validados com sucesso. Esta
lista é então serializada para JSON para o campo PromptResponse.object.
Tratamento de Erros
Resultados vazios: Retorna uma lista vazia [] com um log de aviso
Falha parcial na análise: Retorna uma lista de objetos analisados com sucesso com
logs de aviso para as falhas
Falha completa na análise: Retorna uma lista vazia [] com logs de aviso
Isso difere de response-type: "json", que lança RuntimeError em
caso de falha na análise. O comportamento tolerante para JSONL é intencional para fornecer
resiliência à truncagem.
Exemplo de Configuração
Exemplo completo de configuração de prompt:
{
"prompt": "Extract all entities and their definitions from the following text. Output one JSON object per line.\n\nText:\n{{text}}\n\nOutput format per line:\n{\"entity\": \"<name>\", \"definition\": \"<definition>\"}",
"response-type": "jsonl",
"schema": {
"type": "object",
"properties": {
"entity": {
"type": "string",
"description": "The entity name"
},
"definition": {
"type": "string",
"description": "A clear definition of the entity"
}
},
"required": ["entity", "definition"]
}
}
Considerações de Segurança
Validação de Entrada: A análise JSON utiliza o padrão json.loads(), que é seguro
contra ataques de injeção.
Validação de Esquema: Utiliza jsonschema.validate() para a aplicação do esquema.
<<<<<<< HEAD
Sem Nova Superfície de Ataque: A análise de JSONL é estritamente mais segura do que a análise de arrays JSON
Sem Nova Superfície de Ataque: A análise JSONL é estritamente mais segura do que a análise de arrays JSON
82edf2d (New md files from RunPod) devido ao processamento linha por linha.
Considerações de Desempenho
Memória: A análise linha por linha usa menos memória máxima do que o carregamento de arrays JSON completos. Latência: O desempenho da análise é comparável à análise de arrays JSON. Validação: A validação de esquema é executada por objeto, o que adiciona sobrecarga, mas permite resultados parciais em caso de falha na validação.
<<<<<<< HEAD
Estratégia de Testes
=======
Estratégia de Testes
82edf2d (New md files from RunPod)
Testes Unitários
Análise de JSONL com entrada válida
Análise de JSONL com linhas vazias
Análise de JSONL com blocos de código Markdown
Análise de JSONL com linha final truncada
Análise de JSONL com linhas JSON inválidas intercaladas
Validação de esquema com uniões discriminadas oneOf
Compatibilidade com versões anteriores: prompts "text" e "json" existentes permanecem inalterados
Testes de Integração
Extração ponta a ponta com prompts JSONL Extração com truncamento simulado (resposta artificialmente limitada) Extração de tipos mistos com discriminador de tipo Extração de ontologia com todos os três tipos
Testes de Qualidade de Extração
Compare os resultados da extração: formato JSONL versus array JSON. Verifique a resiliência à truncagem: o JSONL produz resultados parciais onde o JSON falha.
Plano de Migração
Fase 1: Implementação
- Implemente o método
parse_jsonl()emPromptManager. - Estenda
invoke()para lidar comresponse-type: "jsonl". - Adicione testes unitários.
Fase 2: Migração de Prompts
- Atualize o prompt e a configuração
extract-definitions. - Atualize o prompt e a configuração
extract-relationships. - Atualize o prompt e a configuração
extract-topics. - Atualize o prompt e a configuração
extract-rows. - Atualize o prompt e a configuração
agent-kg-extract. - Atualize o prompt e a configuração
extract-with-ontologies.
Fase 3: Atualizações para Sistemas Dependentes
- Atualize qualquer código que consuma os resultados da extração para lidar com o tipo de retorno de lista.
- Atualize o código que categoriza extrações de tipos mistos pelo campo
type. <<<<<<< HEAD - Atualize os testes que afirmam o formato da saída da extração. =======
- Atualize os testes que afirmam o formato de saída da extração.
82edf2d (New md files from RunPod)
Perguntas Abertas
Nenhuma neste momento.
Referências
Implementação atual: trustgraph-flow/trustgraph/template/prompt_manager.py
Especificação JSON Lines: https://jsonlines.org/
Esquema JSON oneOf: https://json-schema.org/understanding-json-schema/reference/combining.html#oneof
Especificação relacionada: Streaming LLM Responses (docs/tech-specs/streaming-llm-responses.md)