FEAT: Adding Json Schema Pipeline to SeedPrompts#1432
Conversation
There was a problem hiding this comment.
Pull request overview
This PR embeds a JSON response schema into the SelfAskRefusalScorer’s seed YAML and plumbs that schema through scoring so compatible prompt targets can request schema-constrained JSON output.
Changes:
- Add
response_json_schematoSeedPromptand populate it in the default refusal scorer YAML. - Update
SelfAskRefusalScorerto load and forward the schema into_score_value_with_llm. - Extend
_score_value_with_llmto accept an optional schema and attach it toprompt_metadatafor JSON-response-capable targets.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| pyrit/score/true_false/self_ask_refusal_scorer.py | Loads schema from the seed prompt and forwards it into LLM scoring + identifier params. |
| pyrit/score/scorer.py | Adds schema parameter and injects it into request metadata for JSON response formatting. |
| pyrit/models/seeds/seed_prompt.py | Introduces a new optional response_json_schema field on SeedPrompt. |
| pyrit/datasets/score/refusal/refusal_default.yaml | Defines the refusal scorer response JSON schema and tightens the schema text in the prompt. |
|
I'm not massively keen on how I've hidden the type of the schema (and this hiding has provoked most of CoPilot's comments). The solution would be defining a |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
You can also share your feedback on Copilot code review. Take the survey.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
You can also share your feedback on Copilot code review. Take the survey.
c679a55 to
04795e5
Compare
rom typing import override is 3.12+; PyRIT supports >=3.10. The project intentionally suppresses the missing-override-decorator rule (see pyproject.toml [tool.ty.rules]) precisely so we don't have to pull in the typing_extensions backport. Aligning this normalizer with the rest of pyrit/message_normalizer/, which override methods without the decorator. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
JSON Schema 'description' is the canonical place for field-level
guidance. Adding them here means:
* Native JSON_SCHEMA targets (OpenAI, Anthropic) pass field
descriptions through to the model as part of the schema metadata.
* When JsonSchemaNormalizer falls back to injecting the pretty-printed
schema into the prompt body, the descriptions ride along automatically
via {schema_json}.
* Scorer prompt YAMLs no longer need to redundantly describe the shape
of each field; that responsibility moves to the schema (single source
of truth) so scorer prompts can focus on the task framing.
Descriptions are intentionally generic so the schema stays reusable
across any future self-ask True/False scorer.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
build_scripts/check_no_rest_roles.py rejects :class:/:func:/:meth:/ :data: cross-reference roles in docstrings and comments; the docs pipeline auto-links bare `Foo` spans against known PyRIT symbols via build_scripts/gen_api_md.py. Switching all sites I introduced in pyrit/models/json_schema_definition.py and pyrit/message_normalizer/json_schema_normalizer.py to plain double-backticks so the pre-commit hook passes and the rendered docs link the same way as the rest of the codebase. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Single ValueError string now fits within line length; ruff-format auto-reformats this on pre-commit. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…/riedgar-ms/PyRIT into riedgar-ms/selfask-jsonschema-01
…lizer When both MULTI_TURN and JSON_SCHEMA need adaptation, the pipeline ran HistorySquashNormalizer first and produced a fresh Message.from_prompt(...) with empty prompt_metadata. The subsequent JsonSchemaNormalizer then saw no schema key and no-oped, so the schema instructions were silently dropped from the squashed text. HistorySquashNormalizer now carries the last message's prompt_metadata onto the squashed piece so downstream normalizers still see request-level metadata. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Same shape as the HistorySquashNormalizer fix: a fresh Message.from_prompt(...) produced by squashing carried empty prompt_metadata, so when both SYSTEM_PROMPT and JSON_SCHEMA needed adaptation, the schema key was silently dropped before JsonSchemaNormalizer ran. Single-system case carries the system piece's metadata; system+user squash carries the user piece's metadata (the user piece represents the current request being sent). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Both squash normalizers (history and system) need to carry the last subsumed message's prompt_metadata onto the fresh Message.from_prompt(...) so downstream normalizers in the pipeline still see request-level metadata such as the JSON schema key. Centralize that rule in pyrit/message_normalizer/_helpers.py so any future squash-style normalizer gets correct propagation by default. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@rlundeen2 @romanlutz first, apologies for accidentally pinging you both on #1346 ; I was updating both PRs, and didn't notice that I was writing in the wrong tab until after I'd hit 'comment' (not that I wouldn't appreciate a review on that PR as well). I think I've merged in the latest changes from |
…onschema-01 # Conflicts: # pyrit/memory/memory_models.py
d280fa9 to
478a33d
Compare
co-authored/hijacked by rlundeen