Skip to content

feat(libsy): allow a deployment-supplied classifier rubric #280

Description

@gburachas

Problem

The llm_classifier route consults a small LLM to decide which tier serves a request. That call
needs instructions — a rubric telling the model what to weigh and what format to answer in.

The rubric is compiled into the binary via include_str!, and there is no way to supply a different
one. It is written for general-purpose capability routing.

A deployment with a narrower task distribution routes measurably better with a rubric written for it.
Today that is simply unavailable: the operator's only options are to accept the built-in rubric or
not use the route.

Proposal

Two equivalent ways to supply a rubric, mutually exclusive:

[routes.<name>]
type = "llm_classifier"
prompt_file = "prompts/coding-agent.md"   # resolved relative to the config file
prompt = "Route coding-agent turns. Answer with the routing JSON only."
  • prompt is the library-level field on TaskClassifierConfig; prompt_file is server-level sugar,
    because a rubric is usually long enough that inlining it into TOML is awkward.
  • File reading stays in the server layer, which is the only one that knows the config's directory.
    Relative paths resolve against it, so a deployment moves as a unit.
  • {{RESPONSE_SCHEMA}} substitution applies to an override exactly as to the packaged rubric, so a
    custom rubric may embed the schema or omit it. The schema is still sent to the model either way.
  • An empty or whitespace-only rubric is rejected at load: it would leave the judge with no
    instructions and fail as an unparseable verdict on every turn rather than loudly.
  • Unset, the packaged rubric is used. No behaviour change for existing deployments.

Scope

6 files, +125/−12. The library change is a config field and one function parameter; the rest is
server plumbing (threading the config directory through build_algorithm), the PyO3 signature, two
tests, and the schema docs.

Validation

Gate Result
cargo test --workspace 642 passed (baseline 640 + 2)
cargo clippy --workspace --all-targets -- -D warnings clean
cargo fmt --check clean
uv run pytest tests/ unchanged

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions