fix(ragas): serialize concurrency_limit in RagasEvaluator - #3810
fix(ragas): serialize concurrency_limit in RagasEvaluator#3810pcbeingused333 wants to merge 1 commit into
Conversation
to_dict serialized only ragas_metrics, so an evaluator built with a concurrency_limit came back from from_dict at the default of 4. The value sizes the semaphore that caps how many metric evaluations run at once in run_async, and every one of those is an LLM call, so a saved and reloaded evaluation pipeline runs at a different concurrency than the one that was configured.
|
Hi @pcbeingused333, thanks for your interest in contributing to Haystack! 🙏 This is an automated message to help us keep the review queue healthy. |
|
Heads-up for maintainers This PR is from a fork and touches integrations whose integration tests require API keys. Affected integrations:
Please run the integration tests locally ( |
Coverage report (ragas)Click to see where and how coverage changed
This report was generated by python-coverage-comment-action |
||||||||||||||||||||||||
|
Folding this into #3808 together with the same fix in |
Related Issues
to_dictagainst__init__across the integrations.Proposed Changes:
RagasEvaluator.__init__takesconcurrency_limit, stores it, and uses it inrun_asyncto size the semaphore that bounds how many metrics are evaluated at once:to_dictserialized onlyragas_metrics:So an evaluator constructed with, say,
concurrency_limit=16comes back fromfrom_dictat the default of4. Every one of those concurrent evaluations is an LLM call, so the value is what decides whether an evaluation run finishes in a quarter of the time or hits the judge model's rate limit. A pipeline saved and reloaded runs at a concurrency nobody chose, and the serialized dict gives no hint that the setting was ever there.from_dictneeded no change: it rebuilds the metrics and hands the rest ofinit_parameterstodefault_from_dict, which passes the new key straight through to__init__.How did you test it?
test_concurrency_limit_survives_a_serialization_round_trip: builds the evaluator withconcurrency_limit=16, runs it throughto_dictthenfrom_dict, and asserts it is still16.test_to_dict, which compares the whole dict, to expect the new key.evaluator.pyreverted tomainit fails withassert 4 == 16— the round trip falling back to the default, not an incidental assertion mismatch.hatch run test:pytest tests/test_evaluator.py— 27 passed, 8 skipped (the skips are the integration tests that need an API key).hatch run test:typesclean (3 source files),hatch run fmt-checkclean.Notes for the reviewer
concurrency_limitis documented as only affectingrun_async, so the round trip is silent on the sync path — which is part of why it is easy to miss.This came out of a sweep comparing every component's
to_dictagainst its__init__signature. The same class of gap turned up in a few other packages; since each integration ships separately I am opening those as their own PRs rather than one cross-package change.I used an AI assistant while writing this change. I have reviewed it, reproduced the behaviour, and run the tests.
Checklist