Merge pull request #2218 from danielaskdd/issue-2215

Refact: Improve query result with semantic null returns
This commit is contained in:
Daniel.y
2025-10-15 12:33:52 +08:00
committed by GitHub
2 changed files with 48 additions and 30 deletions

View File

@@ -21,6 +21,7 @@ from typing import (
List,
Dict,
)
from lightrag.prompt import PROMPTS
from lightrag.constants import (
DEFAULT_MAX_GLEANING,
DEFAULT_FORCE_LLM_SUMMARY_ON_MERGE,
@@ -2287,20 +2288,35 @@ class LightRAG:
else:
raise ValueError(f"Unknown mode {data_param.mode}")
# Extract raw_data from QueryResult
final_data = query_result.raw_data if query_result else {}
# Log final result counts - adapt to new data format from convert_to_user_format
if final_data and "data" in final_data:
data_section = final_data["data"]
entities_count = len(data_section.get("entities", []))
relationships_count = len(data_section.get("relationships", []))
chunks_count = len(data_section.get("chunks", []))
logger.debug(
f"[aquery_data] Final result: {entities_count} entities, {relationships_count} relationships, {chunks_count} chunks"
)
if query_result is None:
no_result_message = "Query returned no results"
if data_param.mode == "naive":
no_result_message = "No relevant document chunks found."
final_data: dict[str, Any] = {
"status": "failure",
"message": no_result_message,
"data": {},
"metadata": {
"failure_reason": "no_results",
"mode": data_param.mode,
},
}
logger.info("[aquery_data] Query returned no results.")
else:
logger.warning("[aquery_data] No data section found in query result")
# Extract raw_data from QueryResult
final_data = query_result.raw_data or {}
# Log final result counts - adapt to new data format from convert_to_user_format
if final_data and "data" in final_data:
data_section = final_data["data"]
entities_count = len(data_section.get("entities", []))
relationships_count = len(data_section.get("relationships", []))
chunks_count = len(data_section.get("chunks", []))
logger.debug(
f"[aquery_data] Final result: {entities_count} entities, {relationships_count} relationships, {chunks_count} chunks"
)
else:
logger.warning("[aquery_data] No data section found in query result")
await self._query_done()
return final_data
@@ -2403,16 +2419,19 @@ class LightRAG:
"status": "failure",
"message": "Query returned no results",
"data": {},
"metadata": {},
"metadata": {
"failure_reason": "no_results",
"mode": param.mode,
},
"llm_response": {
"content": None,
"content": PROMPTS["fail_response"],
"response_iterator": None,
"is_streaming": False,
},
}
# Extract structured data from query result
raw_data = query_result.raw_data if query_result else {}
raw_data = query_result.raw_data or {}
raw_data["llm_response"] = {
"content": query_result.content
if not query_result.is_streaming

View File

@@ -2247,7 +2247,7 @@ async def kg_query(
hashing_kv: BaseKVStorage | None = None,
system_prompt: str | None = None,
chunks_vdb: BaseVectorStorage = None,
) -> QueryResult:
) -> QueryResult | None:
"""
Execute knowledge graph query and return unified QueryResult object.
@@ -2264,7 +2264,7 @@ async def kg_query(
chunks_vdb: Document chunks vector database
Returns:
QueryResult: Unified query result object containing:
QueryResult | None: Unified query result object containing:
- content: Non-streaming response text content
- response_iterator: Streaming response iterator
- raw_data: Complete structured data (including references and metadata)
@@ -2275,6 +2275,8 @@ async def kg_query(
- only_need_prompt=True: content contains complete prompt
- stream=True: response_iterator contains streaming response, raw_data contains complete data
- default: content contains LLM response text, raw_data contains complete data
Returns None when no relevant context could be constructed for the query.
"""
if not query:
return QueryResult(content=PROMPTS["fail_response"])
@@ -2322,7 +2324,8 @@ async def kg_query(
)
if context_result is None:
return QueryResult(content=PROMPTS["fail_response"])
logger.info("[kg_query] No query context could be built; returning no-result.")
return None
# Return different content based on query parameters
if query_param.only_need_context and not query_param.only_need_prompt:
@@ -3985,7 +3988,7 @@ async def naive_query(
global_config: dict[str, str],
hashing_kv: BaseKVStorage | None = None,
system_prompt: str | None = None,
) -> QueryResult:
) -> QueryResult | None:
"""
Execute naive query and return unified QueryResult object.
@@ -3998,11 +4001,13 @@ async def naive_query(
system_prompt: System prompt
Returns:
QueryResult: Unified query result object containing:
QueryResult | None: Unified query result object containing:
- content: Non-streaming response text content
- response_iterator: Streaming response iterator
- raw_data: Complete structured data (including references and metadata)
- is_streaming: Whether this is a streaming result
Returns None when no relevant chunks are retrieved.
"""
if not query:
@@ -4023,16 +4028,10 @@ async def naive_query(
chunks = await _get_vector_context(query, chunks_vdb, query_param, None)
if chunks is None or len(chunks) == 0:
# Build empty raw data structure for naive mode
empty_raw_data = convert_to_user_format(
[], # naive mode has no entities
[], # naive mode has no relationships
[], # no chunks
[], # no references
"naive",
logger.info(
"[naive_query] No relevant document chunks found; returning no-result."
)
empty_raw_data["message"] = "No relevant document chunks found."
return QueryResult(content=PROMPTS["fail_response"], raw_data=empty_raw_data)
return None
# Calculate dynamic token limit for chunks
max_total_tokens = getattr(