🔧(evals) add run_eval management command - #481
Open
maxenceh wants to merge 1 commit into
Open
Conversation
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose
This PR introduces a behavioral eval framework for
ConversationAgent. Unlike unit tests, these evals exercise LLM behaviour end-to-end:A failing eval means a documented behaviour has regressed. The system is designed to grow: adding a new dataset requires one YAML file, one config file, and a registry entry.
Proposal
Running evals
make eval/make eval-debug— runs evals inside Docker; debug mode exposes debugpy on port 5678 for VS Code remote attachcommit,branch,dirty) is injected from the host viaEVAL_GIT_*env vars (Docker has no.gitmount)run_evalsmanagement command:--dataset,--case,--runs,--verbose,--no-llm-judge,--save,--comment,--include-outputsLLM_DEFAULT_MODEL_HRID; judge =LLM_EVAL_JUDGE_MODEL_HRID(falls back to default; warns when judge == tested model)--saveis rejected when combined with--case(partial runs would register coverage gaps vs baseline)Datasets (4)
url_hallucinationhttp(s)://URLs; only cites URLs from tool output or user messagefaithfulness_ragdocument_search_rag, must not callweb_searchincertitudetool_selectionweb_search,self_documentation,document_search_rag,summarize) or none — includes adversarial French phrasingself_documentationis covered as cases withintool_selection, not as a standalone dataset.RAG/summarize cases use
inputs.requires_documents: true+ a fake document listing. Per-case stub payloads are staged viatool_stub_responses.py(contextvar) so the model must actually call tools.Evaluators & agent wiring
EvalConfigregistry — each dataset declares rubric, evaluators, and optionalmake_task_fn/agent_classUrlRegexEvaluator— deterministic URL check; strips trailing punctuation; reads runtime tool returns viaset_eval_attributeHasNoMatchingSpan— correct "tool was NOT called" check (avoidsnot_(HasMatchingSpan)false positives)production_agent.py— builds agents with production tool wiring; stubs external calls (no DB/API)Persistence, baselines & comparison
--savewrites JSON runs underchat/evals/runs/(gitignored) with git metadata, dataset hashes, per-case avg scores, repeat pass ratesoverall_pass_rateweighted by case count (not per-dataset average)make eval-baseline— promotes a run to committed baseline (baselines/main.json+main_run.json)make eval-compare— CLI diff with regression detection and coverage-gap handling (--fail-on-regression)make eval-reset— wipe local runs/baselines/dashboard (--keep-baselines,--keep-dashboard,--dry-run)HTML dashboard
make eval-dashboard— self-contained HTML fromtemplate.html+ embedded run datacompare.pysemanticsAlbert API compatibility
AlbertOpenAIChatModel._validate_completion— normalizes Albert non-stream responses for pydantic-ai / pydantic_evals:tool_calls[].type→functionobject/ non-listchoiceson multi-turn tool-call conversationsDocs & tests
chat/evals/README.md— structure, datasets, commands, how to add a datasetTest plan
make eval EVAL_ARGS="--dataset url_hallucination"passes on current default modelmake eval EVAL_ARGS="--dataset tool_selection --runs 3"— repeat aggregation looks sanemake eval EVAL_ARGS='--save --comment "test"'thenmake eval-compare— no unexpected regressions vs baselinemake eval-dashboard— opendashboard.html, verify A/B summary and case drill-downmake eval EVAL_ARGS="--no-llm-judge"works when Albert structured output is unavailablebin/pytest chat/tests/evals/greenSummary by CodeRabbit