跳到主要内容
版本:最新版(未发布)

Action Signal

Overview​

action labels each request with the operation it asks for: generate, explain, fix, refactor, test, or other. Declare the actions you route on under routing.signals.actions, and reference one from a decision with type: action.

The classifier reads the latest user message and matches English phrases that name an action. It needs no model.

Key Advantages​

  • Separates requests that share a topic but ask for different work, such as an explanation and an edit of the same code.
  • Gives every request exactly one action, so decisions keyed on two different actions never match the same request.
  • Adds no model inference, so it is cheap enough to combine with any other signal.

What Problem Does It Solve?​

Coding assistants send requests such as "explain this function", "fix this failing test", and "rename these variables". The domain signal files all three under the same subject. An explanation only reads code, while a fix or a refactor edits files and often runs a tool loop, so a deployment may want a small model for the first and a stronger one for the others.

When to Use​

Use action when:

  • coding or agent traffic should split between read-only and editing work
  • one topic needs different models for writing code, fixing it, and testing it
  • follow-ups such as "yes, go ahead" should reach a cheaper route

Configuration​

routing:
signals:
actions:
- name: explain
description: Describe code or answer a question without editing anything.
- name: fix
description: Repair a bug or a failing behavior.

Rule names come from a fixed vocabulary:

ActionThe request asks to
generatewrite new code, configuration, or scripts
explaindescribe code or answer a question without editing anything
fixrepair a bug or a failing behavior
refactorchange existing code without changing what it does
testwrite or extend tests
othernone of the above, for example "yes, go ahead" or "review this PR"

The classifier ignores text inside backticks, so code and logs pasted in a fence do not count. It then finds every phrase that names an action. The earliest phrase decides, and a longer phrase wins when two start at the same place, so "write unit tests" is test rather than generate. A message with no action phrase is other.

The routing preview reports the share of matched phrases that name the chosen action under signal_values. "Fix this and add a test" is fix with action:fix at 0.5; a message that names one action scores 1. The share is a lexical measure, not a model probability, so the signal metrics mark confidence as unavailable.

Example Decision​

routing:
decisions:
- name: explain_code
priority: 100
rules:
operator: AND
conditions:
- type: domain
name: computer science
- type: action
name: explain
modelRefs:
- model: small-code-model

Measuring Accuracy​

bench/data/action_test_data.json holds labeled prompts in the same text and true_label shape as the domain set. It includes requests that ask for two actions, follow-ups with no action, and pasted logs full of action words. When a prompt asks for two actions, the label is the one that decides the work: an edit over an explanation, and otherwise the first one requested.

Score a running Router that declares all six actions:

python tools/calibration/recipe/signal_labeled_set.py \
--router-url http://localhost:8080 \
--dataset bench/data/action_test_data.json

The script sends each prompt through the routing preview API and prints per-action precision and recall, a confusion matrix, and the prompts it missed.

Dependencies and Limitations​

The phrases are English only, and only the latest user message is read, so a follow-up keeps no memory of the action before it. A request that mixes actions gets the earliest one: "explain this, then fix it" is explain. Logs pasted outside a code fence can contain action words that decide the result. See a complete example: config/fragments/signal/action/coding-actions.yaml.