{
  "claim": "\"Any open model becomes a decision model with a serving flag\" is true on SGLang and false on the other two major open servers. SGLang's /v1/score is the only one of the three that will score caller-chosen token ids on an ordinary generative checkpoint. vLLM has an endpoint with the same name and path, but it refuses to start unless the model is a pooling model — an embedder or a one-label classifier — so it needs a different checkpoint, not a different flag. llama.cpp has no scoring endpoint at all, and its nearest primitive returns the top-N tokens rather than the N you asked about, which is the one thing a decision model cannot use.",
  "method": "Read from source at each project's HEAD on 2026-09-19. SGLang: python/sglang/srt/entrypoints/openai/serving_score.py and python/sglang/srt/managers/tokenizer_manager_score_mixin.py. vLLM: vllm/entrypoints/pooling/scoring/api_router.py and the enable_scoring_api gate in vllm/entrypoints/pooling/utils.py. llama.cpp: tools/server/README.md, the full endpoint list and the n_probs parameter.",
  "source": "https://github.com/sgl-project/sglang/blob/main/python/sglang/srt/managers/tokenizer_manager_score_mixin.py",
  "captured": "2026-09-19",
  "note": "SGLang's score serving landed on 2025-06-21 in PR #7399, \"[OAI refactor] Add rerank and score serving\" — about fifteen months before Jev launched, and built for rerankers and reward models. Nothing in it was designed for this. That is the whole reason the trick is as easy as it is: the capability was already in the box, under a name nobody reads as \"decision model\". You can rebuild SGLang's readout on vLLM client-side, because /v1/completions takes allowed_token_ids and prompt_logprobs; you just have to write it yourself, and nothing serves it as one call.",
  "columns": [
    { "key": "server", "label": "server" },
    { "key": "ep", "label": "endpoint" },
    { "key": "causal", "label": "works on a plain generative checkpoint" },
    { "key": "pick", "label": "you choose which tokens are scored" },
    { "key": "what", "label": "what it returns" }
  ],
  "rows": [
    {
      "server": "SGLang",
      "ep": "/v1/score",
      "causal": "yes",
      "pick": "yes — label_token_ids",
      "what": "one probability per label token, per item; softmax over the candidates is opt-in"
    },
    {
      "server": "SGLang",
      "ep": "/v1/score (classifier)",
      "causal": "n/a — classification head",
      "pick": "n/a — fixed classes",
      "what": "pooled class logits from the head"
    },
    {
      "server": "vLLM",
      "ep": "/score, /v1/score",
      "causal": "no — pooling models only",
      "pick": "no",
      "what": "one relevance score per (query, document) pair"
    },
    {
      "server": "vLLM",
      "ep": "/v1/completions",
      "causal": "yes",
      "pick": "partly — allowed_token_ids restricts, prompt_logprobs reports",
      "what": "logprobs you assemble into a decision yourself"
    },
    {
      "server": "llama.cpp",
      "ep": "/completion",
      "causal": "yes",
      "pick": "no — n_probs returns the top N",
      "what": "the top-N tokens, which may not contain your candidate"
    },
    {
      "server": "llama.cpp",
      "ep": "/reranking",
      "causal": "no — reranker models only",
      "pick": "no",
      "what": "one score per document"
    }
  ]
}
