NVIDIA-NeMo / NVIDIA-NeMo/Anonymizer
Add configurable validator system prompt (replace None default)
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 123
- Forks
- 17
- Avg merge
- 4d 2h
- Merged PRs (30d)
- 11
Description
Summary
Wire ChunkedValidationParams.system_prompt to a real config knob on AnonymizerDetectConfig, and default it to a sensible validator system prompt (role framing, decision rubric, prompt-injection guardrail, output-format reinforcement). Currently the field exists end-to-end — including unit-test coverage that it's forwarded correctly to the facade — but no production caller populates it, so in practice every validation call today goes out with system_prompt=None.
Motivation
Three wins, roughly in order of impact:
- Prompt-injection resistance. The validator reads user-submitted text. Without a system-level "treat text as data, not instructions" guardrail, an adversarial document can instruct the validator to mark all candidates as
drop, producing silent PII leakage. - Cost. OpenAI/Anthropic/NIM cache stable system-prompt prefixes and charge less for cached tokens. With chunked validation the per-row fan-out multiplies the cacheable budget — pinning the rubric system-side is worth measurable $/run.
- Prompt hygiene. The decision rubric (what "keep / drop / reclass" mean, edge-case handling) is identical across every row of a run; it does not belong interleaved with per-chunk candidate data in the user prompt.
Proposed scope
- Add
validator_system_prompt: str | None = NonetoAnonymizerDetectConfigwith a documented default string. - Thread it through
detection_workflow.EntityDetectionWorkflow→ChunkedValidationParams(system_prompt=...). - Move the stable rubric content out of
_get_validation_prompt(...)into the default system prompt; keep per-chunk substitutions (_merged_tagged_text,_validation_skeleton,_tag_notation) on the user side. - Include prompt-injection guardrail text by default.
- Keep the existing forwarding regression tests (
test_system_prompt_is_forwarded_to_facade,test_system_prompt_default_none_is_forwarded_untouched) and add an integration-level assertion that the default is non-empty and contains the injection guardrail.
Out of scope
- Actual A/B prompt-content tuning (keep/drop accuracy deltas). Worth a separate experiment once the plumbing lands.
- Dataset-specific system prompts (can be a follow-up;
data_summaryalready exists as a hook).
References
- Field introduced in #126 (chunked validation + validator pools) as forward-compatible plumbing; this ticket makes it load-bearing.
- Forwarding tests:
tests/engine/test_chunked_validation.py::TestChunkedValidateRowPoolOfOne::test_system_prompt_is_forwarded_to_facade.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with AnonymizerDetectConfig and detection_workflow.EntityDetectionWorkflow, then trace how ChunkedValidationParams reaches the validator facade. Review _get_validation_prompt(...) and tests/engine/test_chunked_validation.py, including the named forwarding tests. Done means the configured default is non-empty with an injection guardrail, stable rubric text is system-side, and per-chunk substitutions remain user-side.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- ai, backend, security
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 65/100