Skip to content

Change Agent Parameters at Runtime

Adjust a node's configuration while the agent is idle — for example to switch personalities by updating system_prompt, or to tune retrieval precision by changing top_k — without recreating the agent.

Prerequisites

  • An agent created and ready to receive messages — see Build a Chat Agent with a Graph.
  • The agent must not be processing a turn when you call ChangeParam / change_param. The server rejects the request with error 3004 AgentBusy if a turn is in progress.

Which parameters can be changed?

Not all parameters are mutable. The rule of thumb: parameters that affect how inference runs (prompt, sampling, routing thresholds) are mutable; parameters that affect which resources are loaded at graph-compile time are not.

Node Mutable keys
Generate system_prompt, stream, all sampling keys (temperature, top_p, top_k, min_p, max_tokens, seed, repeat_penalty, presence_penalty, frequency_penalty)
ToolCall system_prompt, generate_on_no_tool (experimental), notify_client, all sampling keys
Retrieve top_k, threshold
CannedResponse string_storage (rebind to a different session storage), selection_strategy (random | first | round_robin)
HumanMessageGuardrail string_storage (rebind; patterns recompiled immediately)

Attempting to change an immutable parameter (e.g. model_name) returns error 3006 ParamNotMutable. Passing an invalid value (e.g. a negative top_k) returns 3007 InvalidParamValue.

system_prompt and KV-cache rewind

Changing system_prompt does not immediately flush the KV cache. The change is stored and picked up on the next SendMessage call. At that point the projection pipeline detects the new token sequence, trims the stale tail of the cache, and re-decodes only the changed prefix. This is the most efficient path: back-to-back change_param / SendMessage calls impose only one re-decode, not two.


Examples

# Change the personality before the next turn
agent.change_param("answer", "system_prompt", "You are a pirate.")

# Relax the retrieval threshold
agent.change_param("knowledge", "threshold", "0.9")

# Turn on streaming
agent.change_param("answer", "stream", "true")

change_param raises a TryllError on failure (unknown node, immutable param, or invalid value).

// Async — lambda is called when the server acknowledges
agent.ChangeParamAsync("answer", "system_prompt", "You are a pirate.",
    [](const Tryll::TryllError* err) {
        if (err) {
            // handle error
        }
    });

// Synchronous (blocks the calling thread)
agent.ChangeParam("answer", "top_k", "50");
// Via FTryllAgent directly (callback on game thread)
Agent.ChangeParam(
    TEXT("answer"),
    TEXT("system_prompt"),
    TEXT("You are a pirate."),
    [this](const FTryllError& Err)
    {
        if (Err.Code == 0)
            UE_LOG(LogTemp, Log, TEXT("Persona updated"));
        else
            UE_LOG(LogTemp, Warning, TEXT("Error %d: %s"), Err.Code, *Err.Message);
    });

// Via UTryllAgentComponent — result fires OnParamChanged delegate
AgentComponent->ChangeParam(
    TEXT("answer"),
    TEXT("system_prompt"),
    TEXT("You are a pirate."));

Call Change Param on the UTryllAgentComponent node. Bind the On Param Changed event to handle success or error.


Error codes

Code Name Cause
3004 AgentBusy A turn is in progress. Wait for TurnComplete before calling ChangeParam.
3005 UnknownNode node_name does not match any node instance name in the graph.
3006 ParamNotMutable The parameter exists but cannot be changed at runtime on this node type.
3007 InvalidParamValue The parameter is mutable but the supplied value failed validation (e.g. non-numeric string for a float field).