Skip to content

fix(ragas): serialize concurrency_limit in RagasEvaluator - #3810

Closed
pcbeingused333 wants to merge 1 commit into
deepset-ai:mainfrom
pcbeingused333:fix/ragas-evaluator-concurrency-limit-serde
Closed

fix(ragas): serialize concurrency_limit in RagasEvaluator#3810
pcbeingused333 wants to merge 1 commit into
deepset-ai:mainfrom
pcbeingused333:fix/ragas-evaluator-concurrency-limit-serde

Conversation

@pcbeingused333

Copy link
Copy Markdown

Related Issues

  • No issue; found while auditing to_dict against __init__ across the integrations.

Proposed Changes:

RagasEvaluator.__init__ takes concurrency_limit, stores it, and uses it in run_async to size the semaphore that bounds how many metrics are evaluated at once:

sem = Semaphore(max(1, self.concurrency_limit))

to_dict serialized only ragas_metrics:

return default_to_dict(self, ragas_metrics=[_serialize_metric(m) for m in self.metrics])

So an evaluator constructed with, say, concurrency_limit=16 comes back from from_dict at the default of 4. 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_dict needed no change: it rebuilds the metrics and hands the rest of init_parameters to default_from_dict, which passes the new key straight through to __init__.

How did you test it?

  • New unit test test_concurrency_limit_survives_a_serialization_round_trip: builds the evaluator with concurrency_limit=16, runs it through to_dict then from_dict, and asserts it is still 16.
  • Updated test_to_dict, which compares the whole dict, to expect the new key.
  • I checked the regression test is not vacuous: with evaluator.py reverted to main it fails with assert 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:types clean (3 source files), hatch run fmt-check clean.

Notes for the reviewer

concurrency_limit is documented as only affecting run_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_dict against 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

  • I have read the contributors guidelines and the code of conduct
  • I have added unit tests and updated the docstrings.
  • I've used one of the conventional commit types for my PR title.
  • I have documented my code.
  • I have run pre-commit hooks and fixed any issue.

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.
@pcbeingused333
pcbeingused333 requested a review from a team as a code owner August 18, 2026 00:22
@pcbeingused333
pcbeingused333 requested review from sjrl and removed request for a team August 18, 2026 00:22
@github-actions

Copy link
Copy Markdown
Contributor

Hi @pcbeingused333, thanks for your interest in contributing to Haystack! 🙏

⚠️ You currently have 4 open pull requests in this repository (#3809, #3808, #3790 and this one). Our review capacity is limited, so please hold off opening more PRs until we've had a chance to review your first 2 open PRs. This helps us give each contribution the attention it deserves. Thank you!

This is an automated message to help us keep the review queue healthy.

@github-actions

Copy link
Copy Markdown
Contributor

Heads-up for maintainers

This PR is from a fork and touches integrations whose integration tests require API keys.
Those tests are skipped in CI because fork PRs don't have access to repo secrets for security reasons.

Affected integrations:

  • ragas

Please run the integration tests locally (hatch run test:integration inside each folder) before approving.

@github-actions github-actions Bot added the type:documentation Improvements or additions to documentation label Aug 18, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Coverage report (ragas)

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  integrations/ragas/src/haystack_integrations/components/evaluators/ragas
  evaluator.py
Project Total  

This report was generated by python-coverage-comment-action

@pcbeingused333

Copy link
Copy Markdown
Author

Folding this into #3808 together with the same fix in TransformersZeroShotTextRouter and HuggingFaceTEIRanker — it is one class of bug from one sweep, and it reads better reviewed as a whole than as three near-identical PRs. The commit for concurrency_limit is carried over unchanged; closing here to keep the review in one place.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

integration:ragas type:documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant