Why it matters
One agent run is many model calls. The agent loops: it calls the model, the model asks to use a tool, the tool runs, the model is called again with the result, and so on until it produces a final answer. One goal can be many model calls, often across multiple turns and tool steps. Evaluated in isolation, those calls are disconnected events. Reconstruction stitches them into one ordered, replayable session you can investigate and write policy against: the whole conversation, in order, with each turn’s request and response paired.The correlation identifiers
Reconstruction is driven by a small set of headers carried on each evaluation call.
These play two distinct roles:
Grouping a workflow’s calls together (the session id). Set the same
HL-Runtime-Session-Id on every call that belongs to one piece of work, including calls made inside tools, sub-agents, retries, and parallel branches. Nothing in the system can infer that two separate calls are part of the same workflow, so your application generates the session id once when the workflow begins and passes it on every call. If a tool or sub-agent drops it, those calls split off into a separate, fragmented session.
Pairing each request with its response (the roundtrip id). It only needs to match across the two halves of a single call, a request and its response. Whatever makes that call (your code, an AI gateway, or a framework guardrail) has both halves in hand, so it can put the same roundtrip id on each without tracking anything across the wider workflow. HiddenLayer integrations set these headers for you (see How integrations help below). What they cannot do is decide which calls belong to the same workflow; that is the session id, which only your application can supply.
Reconstructing an agentic session
Reconstruction starts with how you instrument your application. To successfully reconstruct a session, there are three things to get right:- When the user’s request begins, create one session id.
- Propagate that same session id on every model call for the request, including calls made inside tools, sub-agents, retries, and parallel branches.
- Pair each turn’s request evaluation and response evaluation with the same roundtrip id.
- Session id: pass
hl_runtime_session_id=session_idtoevaluate_request(...)andevaluate_response(...). Forevaluate_interaction(...), set it asmetadata.external_session_id. - Roundtrip id: there is no named keyword argument. Pass it via
extra_headers={"HL-Roundtrip-Id": roundtrip_id}on both the request and response evaluation of a turn. (If you evaluate a whole turn at once withevaluate_interaction, you don’t need a roundtrip id.)
Example: a deep-research assistant
Consider a deep-research assistant, in the style of open-source agents like GPT Researcher: a lead agent breaks a question into subtopics, spawns a research sub-agent for each one (every sub-agent makes its own model calls), then writes a final report from their findings. One user request becomes many model calls spread across the lead and several sub-agents. They all share one session id, and each turn gets its own roundtrip id. The crucial point: each sub-agent reuses the same session id its lead created. The example below is simplified pseudocode.call_model marks where the call to the model provider is made; block and redact handling is omitted, and the lead uses a fixed list of subtopics rather than generating them.
How integrations help
HiddenLayer integrations help carry the correlation headers, reducing the custom plumbing you write to get reconstructed agentic sessions. Your application still owns propagating the session id across tools and sub-agents; integrations can’t infer which calls belong to the same workflow. See Integrations and Get Started.Next
Policy
Author CEL detection rules and policies in the Console.

