feat(scan): Complete and reorganize quality scan #2563
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a new Contradiction check and refactors the KnowledgeBaseScenarioGenerator into several specialized quality scenario generators, including HallucinationScenarioGenerator, MultiTopicScenarioGenerator, OutOfScopeScenarioGenerator, SplitQuestionsScenarioGenerator, and SycophancyScenarioGenerator. It also updates the groundedness prompt to allow explicit refusals and adds a helper method to retrieve closest documents to arbitrary text. The review feedback suggests improving the _stringify method in the contradiction judge to format lists cleanly, executing document retrieval concurrently using asyncio.gather in the multi-topic generator, and validating against empty or whitespace-only queries in the knowledge base utility.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| turn_contexts = [ | ||
| [ | ||
| document.content | ||
| for document in await params.knowledge_base.closest_documents( | ||
| turn_seed_index, self.context_documents | ||
| ) | ||
| ] | ||
| for turn_seed_index in turn_seed_indices | ||
| ] |
There was a problem hiding this comment.
The closest documents for each turn are currently retrieved sequentially using a list comprehension with await. Since these are independent async calls, they can be executed concurrently using asyncio.gather to improve performance, especially when there are multiple turns.
import asyncio
closest_docs_list = await asyncio.gather(*(
params.knowledge_base.closest_documents(
turn_seed_index, self.context_documents
)
for turn_seed_index in turn_seed_indices
))
turn_contexts = [
[doc.content for doc in docs]
for docs in closest_docs_list
]31495b2 to
d41adad
Compare
| "DEFAULT_KNOWLEDGE_BASE_CONTEXT_DOCUMENTS", | ||
| "DEFAULT_KNOWLEDGE_BASE_MAX_TURNS", | ||
| "DEFAULT_KNOWLEDGE_BASE_SCENARIOS", |
There was a problem hiding this comment.
Might be worth to allow a clean setup of all the DEFAULT_* used in scan.
Maybe using pydantic-settings to allow setting env variables to override GISKARD_SCAN_*?
We can keep it like this and work on this in a separate issue
There was a problem hiding this comment.
That's a good point, I would keep it in a separate PR.
- Extract _document_contents() helper on the base generator, dedup the repeated [doc.content for doc in docs] comprehension across base and out_of_scope generators - Thread the embedding matrix through _closest_indices() instead of re-fetching it from the cache, removing the hidden cache coupling Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ction Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Description
Type of Change
Coding agents
Autonomous agents with no human in the loop must read AUTONOMOUS.md before opening a PR.
PR title: agent-opened PRs must end the title with
🤖🤖🤖🤖(exactly four robot emojis). Do not omit — that suffix is how the expedited agent PR workflow picks up the PR.Checklist
CODE_OF_CONDUCT.mddocument.CONTRIBUTING.mdguide.uv.lockrunninguv lock(only applicable whenpyproject.tomlhas beenmodified)