Skip to content

Query-stage entity extraction reuses entity_extraction prompt and often fails to produce both hl_keywords and ll_keywords #17

Description

@lixiaoguai11

Question: Query-stage entity extraction and very long retrieved context in default hybrid mode

Hi, thanks for releasing HyperGraphRAG.

While inspecting and using the QA/query pipeline, I noticed two issues in the default query path:

  1. The query-stage keyword/entity extraction in kg_query() appears to reuse the document construction prompt PROMPTS["entity_extraction"], instead of using PROMPTS["keywords_extraction"].
  2. The default retrieval parameters can produce a very large retrieved context in hybrid mode.

1. Query-stage extraction reuses entity_extraction

In hypergraphrag/operate.py, kg_query() builds the query extraction prompt as:

entity_extract_prompt = PROMPTS["entity_extraction"]

hint_prompt = entity_extract_prompt.format(
    **context_base, input_text="{input_text}"
).format(**context_base, input_text=query)

final_result = await use_model_func(hint_prompt)

Then the result is parsed as:

if len(record_attributes) == 3 and record_attributes[0] == '"hyper-relation"':
    hl_keywords.append("<hyperedge>" + clean_str(record_attributes[1]))
elif len(record_attributes) == 5 and record_attributes[0] == '"entity"':
    ll_keywords.append(clean_str(record_attributes[1]).upper())

So the QA/query stage expects the LLM to output both:

  • "hyper-relation" records, which are parsed into hl_keywords
  • "entity" records, which are parsed into ll_keywords

However, in practice, I often find that when the input is a short user query rather than a document chunk, the entity_extraction prompt does not reliably produce valid "hyper-relation" and "entity" tuples. This causes hl_keywords or ll_keywords to be empty.

In the main implementation, this can directly return PROMPTS["fail_response"] in hybrid mode:

if hl_keywords == [] and ll_keywords == []:
    return PROMPTS["fail_response"]

if ll_keywords == [] and query_param.mode in ["hybrid"]:
    return PROMPTS["fail_response"]

if hl_keywords == [] and query_param.mode in ["hybrid"]:
    return PROMPTS["fail_response"]

Since QueryParam.mode defaults to "hybrid", this makes the default QA pipeline very sensitive to whether the LLM follows the tuple format exactly.

2. Default retrieval settings can produce very long contexts

I also noticed that the upstream default query parameters are quite large:

top_k: int = 60
max_token_for_text_unit: int = 4000
max_token_for_global_context: int = 4000
max_token_for_local_context: int = 4000

In my local runs, this can lead to very long retrieved contexts. For example, local retrieval may produce around 60 entities, then expand to all neighboring edges, often around 100-140 relations. After CSV serialization, the context can become approximately:

  • entities section: ~34K characters
  • relations section: ~35K characters
  • sources section: ~22K characters

So the final answer prompt can reach around ~91K characters before generation.

This makes the retrieved context very long and costly, and in some cases may exceed or approach model context limits depending on the backend model.

My questions

  1. Is it intentional that the query-stage extraction reuses PROMPTS["entity_extraction"] instead of PROMPTS["keywords_extraction"]?

  2. Since PROMPTS["keywords_extraction"] already exists and outputs high_level_keywords and low_level_keywords in JSON format, should kg_query() use that prompt for query analysis instead?

  3. Is the expected behavior in hybrid mode that both hl_keywords and ll_keywords must be extracted successfully, otherwise the query should fail?

  4. I noticed that the evaluation/hypergraphrag/operate.py version has a fallback behavior where missing ll_keywords or hl_keywords are replaced by the original query, while the main hypergraphrag/operate.py version directly returns fail_response. Which behavior should be considered the intended one?

  5. Are the default retrieval parameters, especially top_k=60 with 4000-token limits for each context component, intended for normal QA usage? Or are these defaults mainly tuned for the paper evaluation setting?

  6. Is it expected that default local/hybrid retrieval can produce around 90K characters of retrieved context after entity, relation, and source CSV serialization?

  7. Should there be an additional global prompt-length budget or post-serialization truncation step to ensure the final generation prompt stays within a practical context length?

Suggested improvement

Would it make sense to either:

  • use PROMPTS["keywords_extraction"] in kg_query() and parse JSON high_level_keywords / low_level_keywords;
  • or keep PROMPTS["entity_extraction"], but add a fallback when only one side is extracted;
  • or reduce the default top_k / token budgets for general QA usage;
  • or add a final prompt-level token budget after CSV serialization, so the full retrieved context cannot grow unexpectedly large?

I would appreciate clarification on the intended design, especially because the current query prompt seems optimized for document-level extraction rather than short QA queries, and the default retrieval settings can produce very large prompts in local/hybrid mode.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions