Recipe: Response Guidance
This recipe detects when the bot is drifting from a character's defined personality or voice, then nudges it back via a Stage Direction — without the user seeing the nudge.
It also demonstrates dynamic response guidance: reading what the user is doing and giving the bot matching writing instructions.
The config
{
"variables": [
{
"name": "userAction",
"initialValue": "\"talking\""
},
{
"name": "driftDetected",
"initialValue": "false"
}
],
"classifiers": [
{
"name": "UserIntent",
"inputTemplate": "{{content}}",
"inputHypothesis": "The user is primarily {}.",
"classifications": [
{
"label": "examining or observing something closely",
"category": "intent",
"threshold": 0.6,
"updates": [{ "variable": "userAction", "setTo": "\"examining\"" }]
},
{
"label": "trying to end the scene or move on",
"category": "intent",
"threshold": 0.6,
"updates": [{ "variable": "userAction", "setTo": "\"transitioning\"" }]
},
{
"label": "taking a direct action or attacking",
"category": "intent",
"threshold": 0.6,
"updates": [{ "variable": "userAction", "setTo": "\"acting\"" }]
},
{
"label": "talking or asking a question",
"category": "intent",
"threshold": 0.5,
"updates": [{ "variable": "userAction", "setTo": "\"talking\"" }]
}
]
},
{
"name": "CharacterDrift",
"responseTemplate": "{{content}}",
"responseHypothesis": "This response sounds {}.",
"classifications": [
{
"label": "out of character or too formal",
"threshold": 0.7,
"updates": [{ "variable": "driftDetected", "setTo": "true" }]
}
]
}
],
"content": [
{
"category": "Stage Direction",
"condition": "userAction == \"examining\"",
"modification": "\"The user is examining something. Write a detailed, sensory description. Focus on what {{char}} notices.\""
},
{
"category": "Stage Direction",
"condition": "userAction == \"transitioning\"",
"modification": "\"The user is trying to move on. Wrap up the current moment naturally and introduce the next scene.\""
},
{
"category": "Stage Direction",
"condition": "userAction == \"acting\"",
"modification": "\"The user is taking action. Write a dynamic, punchy response. React to the action directly.\""
},
{
"category": "Stage Direction",
"condition": "driftDetected",
"modification": "\"Important: stay in character as {{char}}. Speak in their established voice and manner.\""
}
]
}How it works
UserIntentreads the user's message and classifies what they are trying to do. It updatesuserActionto one of four values.Four Stage Direction rules each fire for a different
userActionvalue, giving the bot a specific writing instruction tailored to what the user is doing.CharacterDriftreads the bot's response (noteresponseTemplate) and flags whether it sounds out of character. If so,driftDetectedis set totrue. (Statosphere auto-creates variables that classifiers write to, but declaringdriftDetectedexplicitly invariablesas shown above is good practice — it makes the config easier to read.)A final Stage Direction fires when
driftDetectedis true, reminding the bot to stay in character. This fires on the next turn after drift was detected — Statosphere cannot modify the response that was already generated.
Limitations
The drift detection fires after the response is already shown. It cannot retroactively change the bad reply; it prevents the next one from drifting. For more immediate correction, consider using useLlm: true on the classifier, which may detect tone issues more reliably.
Customizing the character voice reminder
Replace the generic drift reminder with something specific to your character:
{
"category": "Stage Direction",
"condition": "driftDetected",
"modification": "\"Remember: {{char}} speaks in short, clipped sentences. They never apologize and they never explain themselves. Get back on track.\""
}