Assistants
Assistants are the most underrated object in this domain. They look like an optional convenience layer, they are actually the reason you are not deploying six copies of the same graph, and they carry one API behaviour that will bite you on autopilot.
Configuration, named and versioned
An assistant is a named configuration over a graph. Same compiled code, different settings: a different model, a different system prompt, a different tool allowlist.
Two relationship facts carry the whole design:
- Each graph automatically gets a default assistant. You do not create one to start running. Deploy, and there is already something to call.
- One graph, many assistants. Ship the behaviour once; hang the dial settings off it as many times as you have use cases.
That second one is the point. Without it, varying a prompt per tenant means deploying near-identical code repeatedly, and every copy is another deployment, another revision stream, another thing to keep patched. With it, the graph is the behaviour and the assistant is the settings, and they move independently.
Versions, promote, rollback
Assistants are versioned, and versions can be promoted and rolled back. This is the other versioning concept, the one that pairs with revisions.
Revisions version the deployment: code plus secrets. Versions version the assistant: configuration. Two objects, two version streams. Promoting a bad assistant version is fixed by rolling back, not by redeploying, because no code and no secret changed. Threads and their checkpointed state sit underneath all of it, untouched either way.
The trap that will get you at a keyboard, not just in an exam
Every update API you have ever written does PATCH-style merging. Your fingers will send the delta. Here the delta is the new state, so a four-field update against a five-field assistant silently drops the fifth.
That is an excellent quiz question and you should expect to see it. It is also the sort of thing that produces a production incident with no error message anywhere, because nothing failed. The write succeeded. It just wrote less than you meant.
The reading habit
When a question mentions changing something and asks what was created, run two checks in order. First: is the thing being changed code or environment, or is it configuration over a graph? That answers which versioning system. Second: if it is an assistant update, was the payload complete? That answers what actually survived.
Try it yourself
What happens when you update an assistant
You have an assistant with five configured fields. You send an update containing only the one field you want to change.
{ "config": { "model": "the-new-model" } }Show answer
Correct answer: C — A new assistant version with the four omitted fields gone, because updates do not merge with previous versions
Assistant update requires the entire payload. The documentation is explicit that it does not merge with previous versions, so sending four of five fields creates a version missing the fifth. The tempting wrong answer is the merge option, because almost every other update API in the world does PATCH-style merging and your hands will do it on autopilot. The last option fails for a second reason as well: the update does create a version, which is the whole point of assistants being versioned.
Where the first assistant comes from
You deploy a graph and never touch the assistants API. Do you have an assistant?
Show answer
Correct answer: B — Yes: each graph automatically gets a default assistant
Each graph automatically gets a default assistant, which is why you can deploy and immediately start running without touching the assistants API at all. The tempting wrong answer is the opt-in one, because the assistants API is prominent enough to feel like a required setup step. The last option is a nice distractor built from real config-file familiarity applied to the wrong place: there is no assistants key, because assistants are runtime objects rather than build-time declarations.
Why one graph carries many assistants
This is the design argument, not just a cardinality fact, and the argument is what makes it stick.
What problem does the one-graph-to-many-assistants relationship solve, and what would you otherwise have to do?
Reveal answer
It lets you ship the graph once and hang as many named configurations off it as you have use cases: a different model, a different prompt, a different set of tool permissions, one per tenant or per plan tier or per experiment. Without it you would deploy near-identical copies of the same code purely to vary settings, which multiplies your deployments, your revisions and your operational surface for no behavioural reason. The graph is the behaviour; the assistant is the dial settings on it.
Assistant versions against deployment revisions
You have now met this pair three times. This is the one where you have to place a specific change on the correct side.
A colleague changes the system prompt on an assistant, and separately rotates a provider API key. Which versioning system does each action touch, and why is that split easy to invert?
Reveal answer
The prompt change creates a new assistant version, because a prompt is assistant configuration over the graph. The key rotation creates a new deployment revision, because a revision captures code and secrets together. The split inverts easily because the word configuration honestly describes both a prompt and a secret, so the word cannot be your discriminator. Ask what object is being versioned. If it lives in the environment of the deployed unit, it is revision territory; if it lives on the named configuration over a graph, it is assistant territory.
Reason through a bad promote
Work this one out before checking, it is the practical consequence of everything above.
You can state that a promoted assistant version which turns out to be wrong is fixed by rolling back to the previous version rather than by redeploying, that no new revision is involved because no code or secret changed, that threads and their checkpointed state are untouched throughout, and that a partial payload sent during the fix would compound the problem by dropping fields rather than restoring them.