Skip to content

T6 M0: Technical plan + analysis notebook for multi-objective vector …#61

Open
carlosrod723 wants to merge 7 commits intoAgentOpt:experimentalfrom
carlosrod723:t6-multi-objective-m0
Open

T6 M0: Technical plan + analysis notebook for multi-objective vector …#61
carlosrod723 wants to merge 7 commits intoAgentOpt:experimentalfrom
carlosrod723:t6-multi-objective-m0

Conversation

@carlosrod723
Copy link

M0 delivery for T6 Multi-Objective Vector Scores.

Deliverables:

  • docs/T6_technical_plan.md — Refined tech plan with API signatures, edge cases, test plan
  • examples/notebooks/t6_m0_analysis.ipynb — Colab notebook (no API keys needed)

Notebook demonstrates current baseline behavior and a working prototype of weighted vs Pareto selection with deterministic tie-break validation.

"""
score, _ = self.get_feedback(query, response, reference, **kwargs)
if isinstance(score, dict):
return float(np.mean(list(score.values())))
Copy link
Member

Choose a reason for hiding this comment

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

We should leave this behavior to be configurable from the Objective side.
It should not be hard coded here.

Copy link
Member

Choose a reason for hiding this comment

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

Also why do we need this method from the Guide to begin with? I guess the question is whether we would require passing objective into Guide?
Or asked differently, should the Guide be the one who creates the Objective and sends them around? @allenanie what do you think?

"""
...

def aggregate_vector_scores(scores: list) -> Union[float, Dict[str, float]]:
Copy link
Member

Choose a reason for hiding this comment

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

As above, the logic should be implemented by Objective.

Isolate all multi-objective logic into one new module (`opto/trainer/objectives.py`) containing **pure functions**:

```
normalize_score() → scalar ↔ dict conversion
Copy link
Member

Choose a reason for hiding this comment

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

Let's use a different name. normalize_score implies some sort of scaling or shifting is done.
Let's use something explicit like to_score_dict or some term that is more neutral

Copy link
Member

@chinganc chinganc left a comment

Choose a reason for hiding this comment

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

@doxav
Copy link
Contributor

doxav commented Feb 15, 2026

Hi @chinganc

I propose to address your comments by moving all dict -> scalar + aggregation policy into opto/trainer/objectives.py (Objective side), and making the behavior configurable via ObjectiveConfig.

Concretely:

  • Rename normalize_score -> to_score_dict (with a backwards-compatible alias).
  • Add ObjectiveConfig.scalarize_dict ∈ {"score","mean","weighted"} + score_key so dict→scalar reduction is never silently hard-coded in Guide/Evaluator.
  • Implement dict-> scalar reduction in objectives.py (score_dict_to_scalar / to_scalar_score) and use it in select_best/select_top_k for scalar-mode fallbacks.
  • Move mean-per-metric aggregation into objectives.py (aggregate_score_dicts) and make evaluators.aggregate_vector_scores a thin wrapper.
  • Update the M1 notebook + technical plan to demonstrate scalarize_dict explicitly and to recommend overriding Guide.get_score_dict() (not changing get_feedback() return type).

This keeps Guide responsible for producing raw metrics, and keeps ObjectiveConfig (trainer-side) responsible for aggregation/scalarization/selection, without passing ObjectiveConfig into the Guide.

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.

3 participants