How it works
This content is not available in your language yet.
Three things explain most of what you will meet when integrating: how a request becomes an answer, how the agent finds what it cites, and where your data stops being visible to anyone else.
One runtime, many agents
Section titled “One runtime, many agents”The platform runs a single general-purpose agent runtime. An agent is a configuration record it reads at the start of a run — which model, which tools, which knowledge. Nothing is deployed when you create one, and nothing restarts when you change one.
A request travels: your code opens a thread, starts a run on it, and reads the stream. The runtime loads the agent’s configuration, calls the model, runs whatever tools the model asks for, and streams the result back as it happens.
flowchart LR
code["your code"] --> thread["thread<br/>conversation state"]
thread --> run["run"]
run --> model["model"]
model --> tools["tools"]
tools --> model
model --> stream["streamed response"]
The loop between model and tools is the part worth noticing: a single run
may call tools several times before it answers. That is why a run streams
rather than returning once, and why max_steps exists as a ceiling on how
many model calls one run may make.
How an answer finds its sources
Section titled “How an answer finds its sources”When an agent searches, more happens than one lookup. The question is broken into up to three focused sub-queries. Each is answered two ways at once — by meaning, and by exact wording — and the two result sets are combined. That combined set is then re-scored by a model that reads each passage against the question, and only the best few survive to reach the agent.
flowchart TB
q["your question"] --> sub["up to 3 sub-queries"]
sub --> dense["search by meaning"]
sub --> lexical["search by exact wording"]
dense --> fuse["combine"]
lexical --> fuse
fuse --> rerank["re-score against the question"]
rerank --> top["the passages the agent sees"]
top --> answer["answer with citations"]
Two searches rather than one, because they fail differently: searching by
meaning finds a passage that says the same thing in other words, and
searching by exact wording finds the part number or proper noun that means
nothing to a similarity score. Re-scoring is what turns a large rough
candidate set into a small precise one — it is also why rerank_top_n
changes what an agent is able to cite.
If the best passage still looks weak after all that, the query is broadened and retried once. So an agent that finds nothing has usually tried harder than a single failed search.
Where isolation is enforced
Section titled “Where isolation is enforced”Your tenant is taken from the credential on the request, server-side, and applied to every retrieval. It is not a parameter you send, and not something an agent can be persuaded to change. Inside your tenant, an agent can only search the collections named in its own configuration.
flowchart TB
req["request + your API key"] --> id["tenant taken from the key"]
id --> filter["tenant filter applied server-side"]
filter --> ceiling["narrowed to the agent's own collections"]
ceiling --> results["results"]
sent["collections, trust tier, guardrails<br/>and max_steps sent in the request"] -.->|overwritten, not trusted| ceiling
Two independent limits, in that order: the tenant filter decides what exists for you at all, and the agent’s configured collections narrow it further. A run request that tries to widen either is overwritten with the agent’s own stored values before the run starts — so there is no request shape that reaches further, and nothing to get wrong at the call site.
Next: Agents & assistants.
