Deliver explainability triples inline in retrieval response stream (#763)

Provenance triples are now included directly in explain messages from
GraphRAG, DocumentRAG, and Agent services, eliminating the need for
follow-up knowledge graph queries to retrieve explainability details.

Each explain message in the response stream now carries:
- explain_id: root URI for this provenance step (unchanged)
- explain_graph: named graph where triples are stored (unchanged)
- explain_triples: the actual provenance triples for this step (new)

Changes across the stack:
- Schema: added explain_triples field to GraphRagResponse,
  DocumentRagResponse, and AgentResponse
- Services: all explain message call sites pass triples through
  (graph_rag, document_rag, agent react, agent orchestrator)
- Translators: encode explain_triples via TripleTranslator for
  gateway wire format
- Python SDK: ProvenanceEvent now includes parsed ExplainEntity
  and raw triples; expanded event_type detection
- CLI: invoke_graph_rag, invoke_agent, invoke_document_rag use
  inline entity when available, fall back to graph query
- Tech specs updated

Additional explainability test
This commit is contained in:
cybermaggedon 2026-04-07 12:19:05 +01:00 committed by GitHub
parent 2f8d6a3ffb
commit ddd4bd7790
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 521 additions and 49 deletions

View file

@ -243,6 +243,7 @@ class PatternBase:
content="",
explain_id=session_uri,
explain_graph=GRAPH_RETRIEVAL,
explain_triples=triples,
))
async def emit_iteration_triples(self, flow, session_id, iteration_num,
@ -305,6 +306,7 @@ class PatternBase:
content="",
explain_id=iteration_uri,
explain_graph=GRAPH_RETRIEVAL,
explain_triples=iter_triples,
))
async def emit_observation_triples(self, flow, session_id, iteration_num,
@ -360,6 +362,7 @@ class PatternBase:
content="",
explain_id=observation_entity_uri,
explain_graph=GRAPH_RETRIEVAL,
explain_triples=obs_triples,
))
async def emit_final_triples(self, flow, session_id, iteration_num,
@ -416,6 +419,7 @@ class PatternBase:
content="",
explain_id=final_uri,
explain_graph=GRAPH_RETRIEVAL,
explain_triples=final_triples,
))
# ---- Orchestrator provenance helpers ------------------------------------
@ -437,6 +441,7 @@ class PatternBase:
await respond(AgentResponse(
chunk_type="explain", content="",
explain_id=uri, explain_graph=GRAPH_RETRIEVAL,
explain_triples=triples,
))
async def emit_finding_triples(
@ -475,6 +480,7 @@ class PatternBase:
await respond(AgentResponse(
chunk_type="explain", content="",
explain_id=uri, explain_graph=GRAPH_RETRIEVAL,
explain_triples=triples,
))
async def emit_plan_triples(
@ -494,6 +500,7 @@ class PatternBase:
await respond(AgentResponse(
chunk_type="explain", content="",
explain_id=uri, explain_graph=GRAPH_RETRIEVAL,
explain_triples=triples,
))
async def emit_step_result_triples(
@ -526,6 +533,7 @@ class PatternBase:
await respond(AgentResponse(
chunk_type="explain", content="",
explain_id=uri, explain_graph=GRAPH_RETRIEVAL,
explain_triples=triples,
))
async def emit_synthesis_triples(
@ -557,6 +565,7 @@ class PatternBase:
await respond(AgentResponse(
chunk_type="explain", content="",
explain_id=uri, explain_graph=GRAPH_RETRIEVAL,
explain_triples=triples,
))
# ---- Response helpers ---------------------------------------------------

View file

@ -473,6 +473,7 @@ class Processor(AgentService):
content="",
explain_id=session_uri,
explain_graph=GRAPH_RETRIEVAL,
explain_triples=triples,
))
logger.info(f"Question: {request.question}")
@ -640,6 +641,7 @@ class Processor(AgentService):
content="",
explain_id=iter_uri,
explain_graph=GRAPH_RETRIEVAL,
explain_triples=iter_triples,
))
user_context = UserAwareContext(flow, request.user)
@ -717,6 +719,7 @@ class Processor(AgentService):
content="",
explain_id=final_uri,
explain_graph=GRAPH_RETRIEVAL,
explain_triples=final_triples,
))
if streaming:
@ -793,6 +796,7 @@ class Processor(AgentService):
content="",
explain_id=observation_entity_uri,
explain_graph=GRAPH_RETRIEVAL,
explain_triples=obs_triples,
))
history.append(act)

View file

@ -162,12 +162,13 @@ class Processor(FlowProcessor):
triples=triples,
))
# Send explain ID and graph to response queue
# Send explain data to response queue
await flow("response").send(
DocumentRagResponse(
response=None,
explain_id=explain_id,
explain_graph=GRAPH_RETRIEVAL,
explain_triples=triples,
message_type="explain",
),
properties={"id": id}

View file

@ -253,12 +253,13 @@ class Processor(FlowProcessor):
triples=triples,
))
# Send explain ID and graph to response queue
# Send explain data to response queue
await flow("response").send(
GraphRagResponse(
message_type="explain",
explain_id=explain_id,
explain_graph=GRAPH_RETRIEVAL,
explain_triples=triples,
),
properties={"id": id}
)