Skip to content

feat: add per-instance prompt overrides via LightRAG.prompts field#2951

Open
wkpark wants to merge 1 commit intoHKUDS:devfrom
wkpark:feat-per-prompts
Open

feat: add per-instance prompt overrides via LightRAG.prompts field#2951
wkpark wants to merge 1 commit intoHKUDS:devfrom
wkpark:feat-per-prompts

Conversation

@wkpark
Copy link
Copy Markdown
Contributor

@wkpark wkpark commented Apr 18, 2026

Description

Add per-instance prompt override support to LightRAG. Callers can now pass prompts={...} to the LightRAG constructor to override specific prompt templates without mutating the global lightrag.prompt.PROMPTS dict.
This eliminates cross-contamination between multiple LightRAG instances running in the same process with different prompt configurations.

Related Issues

See also #1353

Changes Made

  • lightrag/lightrag.py: Add prompts: dict[str, Any] field to the LightRAG dataclass (default_factory=dict). Included in global_config automatically via asdict(self).
  • lightrag/operate.py: Add _get_prompt(key, global_config=None) helper. Checks global_config["prompts"] first; falls back to global PROMPTS if no override is set. Replace all direct PROMPTS["..."] accesses in extraction and query paths with _get_prompt("...", global_config).

Checklist

  • Changes tested locally
  • Code reviewed
  • Documentation updated (if necessary)
  • Unit tests added (if applicable)

Additional Notes

Backward compatible. Instances that do not pass prompts= behave identically to before — _get_prompt() falls back to the global PROMPTS dict unconditionally when the per-instance override dict is empty.

Two delimiter constants (DEFAULT_TUPLE_DELIMITER, DEFAULT_COMPLETION_DELIMITER) in _rebuild_from_extraction_result() still reference PROMPTS directly, as that function has no access to global_config. Overriding these two keys via prompts= is therefore not supported and would cause a parsing mismatch against cached extraction results. All other prompt keys are fully overridable.

Note: prepared with claude code

@wkpark wkpark force-pushed the feat-per-prompts branch from a581a3a to d050ea4 Compare April 25, 2026 17:22
Add `prompts: dict[str, Any]` field to LightRAG dataclass and
`_get_prompt(key, global_config)` helper in operate.py.

All PROMPTS["..."] lookups in extraction and query paths now go through
`_get_prompt()`, which checks `global_config["prompts"]` first and falls
back to the global PROMPTS dict. Callers can inject per-instance prompt
overrides via `LightRAG(prompts={...})` without mutating the global
`lightrag.prompt.PROMPTS`, eliminating cross-contamination between
multiple LightRAG instances sharing the same process.

Backward compatible: instances without a `prompts` override behave identically to before.
@wkpark wkpark force-pushed the feat-per-prompts branch from d050ea4 to cce2eba Compare May 6, 2026 10:49
@wkpark
Copy link
Copy Markdown
Contributor Author

wkpark commented May 7, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cce2eba90d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread lightrag/operate.py
Comment on lines 3311 to 3315
prompt_profile = resolve_entity_extraction_prompt_profile(
addon_params, use_json_extraction
addon_params,
use_json_extraction,
global_config,
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Apply prompt overrides to cached extraction profile

extract_entities now resolves prompt profiles with global_config only in the prompt_profile is None fallback path, but the normal LightRAG path uses a precomputed _entity_extraction_prompt_profile cache that is still built without per-instance prompts. As a result, overrides like default_entity_types_guidance and entity_extraction_examples are silently ignored for typical instances, so the new per-instance prompt feature does not work for entity extraction defaults unless callers bypass the cached path.

Useful? React with 👍 / 👎.

Comment thread lightrag/prompt.py
def _get_prompt(key: str, global_config: dict | None = None) -> Any:
"""Return per-instance prompt override if set, else fall back to global PROMPTS."""
if global_config:
override = global_config.get("prompts", {}).get(key)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Handle null prompts before override lookup

_get_prompt assumes global_config["prompts"] is a mapping and immediately calls .get(key) on it; if a caller passes prompts=None (common when config values come from YAML/JSON nulls), this raises AttributeError and breaks prompt rendering across query/extraction flows. The helper should validate/coerce prompts to a dict before nested lookup.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant