Skip to content

feat(gooddata-eval): register knowledge_question evaluator - #1763

Open
Tomkess wants to merge 2 commits into
masterfrom
feat/knowledge-question-evaluator
Open

feat(gooddata-eval): register knowledge_question evaluator#1763
Tomkess wants to merge 2 commits into
masterfrom
feat/knowledge-question-evaluator

Conversation

@Tomkess

@Tomkess Tomkess commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary

  • knowledge_question fixtures were reclassified out of general_question (platform/product/policy Q&A that isn't LDM-grounded) but no evaluator was ever registered for the kind, so get_evaluator("knowledge_question") raised KeyError and every item was silently skipped — the downstream repo has kept knowledge_question: false in its test-kind config as a result.
  • Registers knowledge_question in the lazy-evaluator registry, reusing GeneralQuestionEvaluator directly rather than adding a new class: both are free-text-rubric, LLM-judged prose answers, differing only in subject matter (LDM facts vs. platform/policy facts).
  • ItemReport.test_kind is tagged from the dataset item's own test_kind field (runner.py), not from the evaluator class's test_kind attribute, so sharing one evaluator class across both kinds does not mislabel results in reports/dashboards.

Review follow-ups

Two of @hkad98's three nits are addressed:

  • GeneralQuestionEvaluator.test_kind is now inaccurate for half its registrations — added a pointer to the registry comment explaining why it's harmless, so nothing derives an output label from it unaware.
  • supported_test_kinds()'s docstring listed only (general_question, guardrail); now lists all four LLM-judge kinds.

The third (no agentic_knowledge_question dispatch branch, so the kind is single-turn only) is left as scope per the review — likely its own follow-up.

Test plan

  • uv run pytest packages/gooddata-eval/tests/ — 702 passed (rebased onto perf: take Langfuse trace linking off the eval item critical path #1771, which grew the suite)
  • New coverage: get_evaluator("knowledge_question") resolves to GeneralQuestionEvaluator; pass/fail dispatch through the reused evaluator (test_text_evaluators.py)
  • Updated test_run_items_routes_all_supported_kinds's exact-set assertion to include knowledge_question
  • ruff check / ruff format --check clean

Rebase note

Rebased onto 45892f79 after #1771 landed and put this into conflict. The only clash was an import collision in test_text_evaluators.py (#1771 added JudgeResponseError, this PR added get_evaluator) — both kept, nothing semantic.

@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8119dac6-c703-4d33-b13f-de192889b72e

📥 Commits

Reviewing files that changed from the base of the PR and between 8a7cf06 and f7d8ade.

📒 Files selected for processing (3)
  • packages/gooddata-eval/src/gooddata_eval/core/evaluators/__init__.py
  • packages/gooddata-eval/tests/test_runner.py
  • packages/gooddata-eval/tests/test_text_evaluators.py

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The evaluator registry adds knowledge_question as a lazy-loaded kind backed by GeneralQuestionEvaluator. Tests verify supported-kind registration, dispatch, and judge-score outcomes.

Changes

Knowledge question evaluator support

Layer / File(s) Summary
Evaluator registry routing
packages/gooddata-eval/src/gooddata_eval/core/evaluators/__init__.py
The lazy evaluator maps route knowledge_question to GeneralQuestionEvaluator.
Routing and scoring validation
packages/gooddata-eval/tests/test_runner.py, packages/gooddata-eval/tests/test_text_evaluators.py
Tests cover supported-kind registration, evaluator dispatch, and pass/fail results for knowledge-question items.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to f7d8a

The change enables evaluation of knowledge questions instead of skipping them; no actionable merge-blocking risk remains after normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant get_evaluator
  participant GeneralQuestionEvaluator
  participant LLMJudge
  get_evaluator->>GeneralQuestionEvaluator: resolve knowledge_question
  GeneralQuestionEvaluator->>LLMJudge: evaluate answer
  LLMJudge-->>GeneralQuestionEvaluator: return score
Loading

Suggested reviewers: hkad98, lupko, pcerny

Poem

A rabbit found a question bright
The evaluator chose the right
A judge returned a score
Tests checked the route once more
And carrots passed with delight

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 3 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: registering the knowledge_question evaluator in gooddata-eval.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Aug 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 81.60%. Comparing base (45892f7) to head (f213331).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1763      +/-   ##
==========================================
+ Coverage   81.58%   81.60%   +0.02%     
==========================================
  Files         275      275              
  Lines       19863    19863              
==========================================
+ Hits        16205    16210       +5     
+ Misses       3658     3653       -5     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

hkad98
hkad98 previously approved these changes Sep 3, 2026

@hkad98 hkad98 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approving.

Verified the two load-bearing claims in the new comment:

  • ItemReport.test_kind is populated from item.test_kind (runner.py:112), not from the evaluator class, so registering one class under two keys does not mislabel results.
  • GeneralQuestionEvaluator's rubric (_EVALUATION_STEPS) is generic free-text scoring with no LDM- or workspace-specific wording, so it genuinely transfers to platform/product/policy facts.

The lazy-registration path keys off the explicit _LAZY_EVALUATOR_* dicts rather than ev.test_kind, so the double registration is safe as written.

Three non-blocking nits for whenever you next touch this file:

  1. GeneralQuestionEvaluator.test_kind = "general_question" is now inaccurate for half its registrations. Harmless today, but it would mislabel if anything ever derives output labels from evaluator.test_kind instead of item.test_kind. Worth a pointer from the class to the comment you added here.
  2. There is no agentic_knowledge_question branch in _dispatch_agentic (cli/agentic_runner.py), so the kind is single-turn only. Fine as scope, just flagging it as the likely next request.
  3. Pre-existing: supported_test_kinds()'s docstring still lists only "(general_question, guardrail)" and is now two kinds out of date.

Tomkess added a commit that referenced this pull request Sep 3, 2026
…ual test_kind use

Addresses two of hkad98's non-blocking nits on #1763:
- supported_test_kinds()'s docstring only listed (general_question,
  guardrail) as the LLM-judge kinds; dashboard_summary and
  knowledge_question were already excluded by the same check but never
  mentioned.
- GeneralQuestionEvaluator.test_kind is now inaccurate for half its
  registrations (knowledge_question shares the class) -- added a pointer
  to the registry comment explaining why, so a future reader doesn't
  derive an output label from it without realizing.

Third nit (no agentic_knowledge_question dispatch branch) left as scope,
per the review comment's own "fine as scope, likely next request."

Tomkess commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

@hkad98 thanks for the approval and the nits — fixed the first two in 068c393:

  1. Added a comment on GeneralQuestionEvaluator.test_kind pointing to the registry comment explaining it's now shared by two kinds, so nothing derives a label from it unaware.
  2. supported_test_kinds()'s docstring now lists all 4 LLM-judge kinds (general_question, guardrail, dashboard_summary, knowledge_question) instead of the stale 2.

Left the third (agentic_knowledge_question dispatch) out — per your own note, that's scope for a future PR, not this one. 476 passed, lint clean.

knowledge_question had reclassified fixtures (commit 658b9ea6) but no
registered evaluator, so get_evaluator() raised KeyError and every item
was silently skipped -- data/test_kinds.yaml had to keep it disabled.

Reuses GeneralQuestionEvaluator directly: both are free-text-rubric,
LLM-judged prose answers, and ItemReport.test_kind is tagged from the
dataset item's own field rather than the evaluator class, so sharing
one class across both kinds doesn't mislabel results.
…ual test_kind use

Addresses two of hkad98's non-blocking nits on #1763:
- supported_test_kinds()'s docstring only listed (general_question,
  guardrail) as the LLM-judge kinds; dashboard_summary and
  knowledge_question were already excluded by the same check but never
  mentioned.
- GeneralQuestionEvaluator.test_kind is now inaccurate for half its
  registrations (knowledge_question shares the class) -- added a pointer
  to the registry comment explaining why, so a future reader doesn't
  derive an output label from it without realizing.

Third nit (no agentic_knowledge_question dispatch branch) left as scope,
per the review comment's own "fine as scope, likely next request."
@Tomkess
Tomkess force-pushed the feat/knowledge-question-evaluator branch from 068c393 to f213331 Compare September 3, 2026 15:28

Tomkess commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Heads-up: #1771 landing put this into conflict after your approval. Rebased onto 45892f79 as f2133312mergeable_state is back to blocked rather than dirty.

The only conflict was an import collision in test_text_evaluators.py (#1771 added JudgeResponseError, this PR added get_evaluator) — both kept, nothing semantic. The registry change itself didn't conflict.

Re-verified after the rebase: 702 passed (suite grew from 476 with #1771), ruff check/format --check clean. Your two nit fixes from 068c393b are carried through unchanged.

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.

2 participants