deepset-ai / deepset-ai/haystack
RFC: Structured Evaluator Uncertainty and Error Semantics
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 26.6k
- Forks
- 3.2k
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 194
Description
1. Context & Motivation
Haystack already provides a mature evaluation layer for RAG and LLM application workflows.
The current evaluator stack includes components such as:
LLMEvaluator;ContextRelevanceEvaluator;FaithfulnessEvaluator;EvaluationRunResult.
These components already expose useful evaluation information through score, individual_scores, and evaluator-specific results.
However, some evaluator states remain compressed into scalar values, None, empty placeholders, or nan.
This RFC proposes a narrow evaluator/reporting improvement: make unresolved evaluator states explicit without changing Haystack's existing score-first evaluation model.
The goal is not to add a broad theory layer to Haystack. The goal is to help users distinguish between:
- a valid supported result;
- a valid unsupported result;
- an unresolved evaluator judgment;
- an evaluator execution or parsing error.
2. Problem Statement
In evaluation workflows, not all non-positive or missing results mean the same thing.
A row may fail because:
- the evaluated answer is unsupported;
- the evaluated context is irrelevant;
- the LLM evaluator returned malformed JSON;
- the evaluator output did not contain the expected fields;
- the evaluator call failed;
- the row could not be judged confidently.
Today, these states can become difficult to separate once they are represented as:
None;- empty result placeholders;
float("nan");- aggregate
score; individual_scores.
This can weaken evaluation reports.
For production users, a low score and an invalid evaluator row require different actions. A low score may suggest retrieval or generation quality issues. An invalid evaluator row may suggest prompt, parser, model, or infrastructure issues.
The current reporting shape can make that distinction harder than necessary.
3. Proposed Solution
Introduce an optional structured evaluator-status channel for LLM evaluator outputs and evaluation reporting.
This should preserve the existing contract:
- keep
score; - keep
individual_scores; - keep evaluator-specific
results; - keep existing scalar-first workflows working.
The additional information should make unresolved states explicit.
Conceptual example:
{
"score": 0.75,
"individual_scores": [1.0, 0.0, float("nan")],
"results": [...],
"statuses": ["supported", "unsupported", "indeterminate"],
"error_count": 1,
"indeterminate_count": 1,
}
The exact field names should be decided by Haystack maintainers.
The key design principle is additive reporting: no breaking change, no global evaluator redesign, no mandatory new abstraction.
4. Academic Foundation
This proposal is inspired by neutrosophic logic, introduced by Prof. Florentin Smarandache.
Neutrosophic logic separates evaluation into three independent dimensions:
- Truth: evidence supporting a proposition;
- Indeterminacy: incomplete, ambiguous, unresolved, or non-decidable evidence;
- Falsity: evidence against a proposition.
For Haystack, this RFC translates the theory into practical evaluator language:
supportedorrelevantcorresponds to evidence for the output;unsupportedorirrelevantcorresponds to evidence against the output;indeterminatecorresponds to unresolved evaluator judgment;errorcorresponds to evaluator execution, parsing, or schema failure.
The public API does not need to use the word neutrosophic. The concept can remain academically grounded while the implementation uses Haystack-native terminology such as evaluator status, uncertainty, or error semantics.
Relevant references from the same neutrosophic research lane used in prior projects:
-
Florentin Smarandache
Neutrosophy: Neutrosophic Probability, Set, and Logic
Foundation of neutrosophic logic, set theory, probability, and statistics. -
Florentin Smarandache & Maissam Ahmad Jdid
Neutrosophic Linear Models and Algorithms to Find Their Optimal Solution
Relevant for optimization and decision-making under incomplete information. -
Maikel Yelandi Leyva-Vázquez & Florentin Smarandache
Breaking the Chains of Probability: Neutrosophic Logic as a New Framework for Epistemic Uncertainty in Large Language Models
Relevant to LLM evaluation because it studies truth, indeterminacy, and falsity in LLM outputs. -
Smarandache, Ye, and collaborators
Work on neutrosophic multi-criteria decision-making and aggregation operators. -
mleyvaz/neutrosophic-llm-logic
Practical reference implementation for prompting LLMs to produce truth/indeterminacy/falsity evaluations.
DOI:10.5281/zenodo.19911845
5. Why Haystack
Haystack is a good fit because the relevant extension points already exist.
This RFC does not require introducing a new framework-wide system. It can attach to evaluator and reporting surfaces that already exist:
LLMEvaluatoralready handles structured evaluator outputs;ContextRelevanceEvaluatoralready reduces LLM evaluator judgments into score-oriented outputs;FaithfulnessEvaluatoralready works with statement-level support judgments;EvaluationRunResultalready provides aggregate and detailed reports.
This makes the evaluator layer the safest first place to discuss uncertainty/status semantics.
Other possible areas, such as retriever confidence, HITL decision states, agent guardrails, or audit receipts, may be interesting later. They are not the right first target because they would broaden the proposal before the evaluator/reporting value is validated.
6. Proposed Plan
Phase 0 - RFC issue first
Open this as a maintainer-facing RFC issue before implementation.
The issue should ask whether maintainers agree that evaluator failures, unresolved evaluator rows, and valid negative judgments should be reported separately.
No code should be pushed upstream before this discussion exists.
The RFC issue should explicitly ask maintainers to guide:
- naming;
- result shape;
- whether
EvaluationRunResultis the right reporting surface; - whether this should attach to
LLMEvaluator, concrete evaluators, or both; - whether the implementation should avoid all public
neutrosophicnaming.
Phase 1 - Narrow implementation branch and PR
If the direction is acceptable, create a Phase 1 branch.
Suggested branch name:
feature/haystack-evaluator-uncertainty-phase1
Phase 1 should be the only upstream PR candidate at first.
It should focus on the smallest reviewable unit:
- preserve
score; - preserve
individual_scores; - add explicit evaluator row status or error visibility;
- add focused tests;
- avoid retriever, agent, HITL, router, or governance changes.
The Phase 1 PR should link back to the RFC issue and clearly state that it is not trying to redesign Haystack evaluation.
After the Phase 1 PR is pushed, protect the branch on the fork:
- disable force-push;
- disable deletion;
- preserve linear history if available;
- keep review comments and branch state stable.
Phase 2 - Local/fork branch only until maintainer feedback
Prepare Phase 2 as a stacked local or fork branch, but do not treat it as final.
Suggested branch name:
feature/haystack-evaluator-reporting-phase2
Phase 2 should depend on what maintainers say about Phase 1.
Likely Phase 2 direction:
- improve
EvaluationRunResultreporting; - expose aggregate counts for valid, indeterminate, and error rows;
- improve detailed reports without changing score semantics.
Phase 2 should not be opened as a normal upstream PR until one of these happens:
- Phase 1 receives maintainer feedback asking for reporting work;
- Phase 1 is accepted or merged;
- maintainers explicitly ask to see the stacked branch.
The branch may be pushed to the fork and protected as evidence of feasibility, but it should be clearly marked as dependent on Phase 1 review.
Phase 3 - Local/fork exploratory branch only
Prepare Phase 3 as a local or fork-visible proof branch, not as an upstream PR.
Suggested branch name:
feature/haystack-statement-uncertainty-phase3
Likely Phase 3 direction:
- explore statement-level uncertainty for evaluators such as
FaithfulnessEvaluator; - distinguish supported, unsupported, indeterminate, and error states at a finer granularity;
- test whether this improves diagnostic value.
Phase 3 is expected to change after maintainer feedback.
It should not be presented as a fixed roadmap. It should be treated as a research branch that proves feasibility and helps us respond intelligently if maintainers ask for deeper evaluator semantics.
Protect the branch if pushed to the fork, but do not pressure maintainers with it.
Phase 4 - Optional future discussion only
Any retriever confidence, router fallback, HITL, agent, or governance work should remain outside this RFC.
If maintainers like the evaluator-status model, a later RFC can discuss whether similar concepts belong elsewhere.
That future work should not be bundled with this proposal.
7. Explicit Constraints
This RFC does not propose:
- replacing existing evaluator scores;
- removing
individual_scores; - breaking current evaluator outputs;
- changing pipeline execution;
- changing retriever score semantics;
- adding a mandatory uncertainty framework;
- adding signed receipts;
- adding a governance middleware;
- changing agent or HITL behavior;
- forcing Haystack to expose neutrosophic terminology in public APIs.
The first public contribution should remain evaluator/reporting-only.
8. Contribution Workflow
The workflow should follow the disciplined Ragas-style case-study pattern:
- Open the RFC issue first.
- Wait for initial maintainer signal or at least make the proposal publicly inspectable.
- Create Phase 1 branch from the correct base.
- Implement only the narrow Phase 1 evaluator-status change.
- Add focused tests.
- Push Phase 1 branch to the fork.
- Open one Phase 1 PR linked to the RFC issue.
- Protect the Phase 1 branch.
- Prepare Phase 2 as a stacked local/fork branch only.
- Protect Phase 2 if pushed to fork.
- Prepare Phase 3 as a local/fork proof branch only.
- Protect Phase 3 if pushed to fork.
- Do not open Phase 2 or Phase 3 upstream until maintainer feedback changes or confirms the path.
- Update the RFC issue with concise milestone comments only when there is real progress.
- Stop when the next honest action depends on maintainer response.
This workflow keeps implementation momentum without creating pressure on maintainers to review a large stack of speculative changes.
9. Prior Art & Uniqueness
Prior art exists in:
- scalar RAG evaluation metrics;
- LLM-as-judge workflows;
- evaluator error handling;
- faithfulness and relevance scoring;
- uncertainty-aware decision-making;
- neutrosophic LLM evaluation research.
The unique contribution here is not simply adding another score.
The unique contribution is making evaluator uncertainty operational inside Haystack's existing evaluation surfaces while preserving compatibility with existing score-based users.
Compared with prior neutrosophic study cases:
- Agent Squad applied the concept to multi-agent response fusion.
- Aden/Hive applied it to worker/Queen swarm decision visibility.
- Ragas applied it to RAG evidence-triplet evaluation.
- Haystack would apply it to evaluator status and evaluation reporting.
That makes the proposal narrower and more natural for Haystack.
10. Open Questions For Maintainers
- Is explicit evaluator row status useful for Haystack users?
- Should unresolved evaluator states be reported separately from valid negative judgments?
- Should this live in evaluator outputs,
meta,EvaluationRunResult, or a combination? - What names best fit Haystack conventions:
statuses,row_statuses,evaluation_statuses,errors, or something else? - Should the first PR target only
LLMEvaluator, or also concrete evaluators likeContextRelevanceEvaluatorandFaithfulnessEvaluator? - Should failed rows remain represented as
nanwhile status fields explain why? - Should public API naming avoid the term
neutrosophicentirely? - Would maintainers prefer this as a small code contribution, a recipe/example, or only a documentation discussion first?
11. Next Step
The next step is to open the RFC issue and ask for maintainer direction.
If maintainers are open to the idea, the first implementation should be a narrow Phase 1 PR that:
- keeps existing score semantics intact;
- adds explicit evaluator row status/error visibility;
- includes focused tests;
- links back to the RFC issue;
- avoids all retriever, agent, router, HITL, and governance changes.
Phase 2 and Phase 3 should be prepared only as protected local/fork branches until maintainer feedback determines whether they should be changed, replaced, or discarded.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the existing LLMEvaluator, ContextRelevanceEvaluator, FaithfulnessEvaluator, and EvaluationRunResult surfaces to understand how score, individual_scores, and results are reported. Use the maintainer discussion to resolve naming, result shape, and ownership before implementation. Done for this RFC means agreement on a narrow, additive Phase 1 change with focused tests and no broader evaluator redesign.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- ai, backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100