Hooks are Broadway flows that the runtime runs at defined points of a turn. They let you prepare the context, enforce rules around tool calls, validate the answer and control error messages — with the full power of Broadway and Fabric, and without changing the agent's prompt.
Hook flows also define the agent's inputs: the values a client must provide when it starts a conversation, such as the customer ID.
hooks:
step_start: Banking_CustomerStory
step_end: CheckAnswer
pre_tool_call: GuardTools
post_tool_call: AuditTools
on_error: FriendlyError
Each value is the name of one Broadway flow in the agent's Data Product, or LU__<lu>__<flow> for a flow in another Data Product.
In addition, every hook flow receives the agent inputs as externals.
Per-tool before and after hooks, configured on a single entry of tools:, use the pre_tool_call and post_tool_call contracts. See Tools.
Hooks fail closed: if a hook flow fails, the turn fails. A failing pre_tool_call hook blocks the tool call rather than allowing it. Keep hook flows simple and fast, and handle expected conditions inside the flow.
Each hook type has a pair of Broadway actors, found under the agent_hooks tag:
Place the input actor first and the output actor last, and map the output actor's ports to the flow's output externals as shown.
There is no input-parameter list in agent.yaml. Instead, the external inputs declared by the agent's hook flows are the agent's inputs:
agents web service (input_params), shown in the Studio New chat dialog (Agent inputs).initParams JSON object when calling the agent, for example {"customerId":"1001"}.Do not declare an external with a reserved name — query, step_id, sessionId, agentName, final_answer, tool_name, arguments, tool_call_id, iteration, result, duration_ms, error, default_error_message. Such inputs are ignored, with a warning in the log.
For a sub-agent, an input may also be supplied by the calling LLM in the task or delegate arguments, so hook externals are not a trustworthy source for authorization scope. The AgentInitParams actor returns the inputs that the client passed to the top-level agent, which the model can never change:
initParams — the full map; add an output named after a key (for example customerId) to read it directly.sessionId, stepId, agentName, luName.Use AgentInitParams in any hook or tool flow that needs the customer identity for data access. It works in flows that the runtime calls directly, not in their inner flows.
The most common hook loads the entity the conversation is about, so the query tool works on its data. In the banking demo:
step_start flow, Banking_CustomerStory, declares the mandatory external customerId, loads the customer instance with the GetWithSnap actor (which also supports evaluation snapshots), builds a short customer profile, and returns it together with the user's message as result.step_start flow, LoadCustomerScope, declares the mandatory customerId and loads the instance with FabricGet.Because both flows declare customerId as mandatory, the client must choose the customer before the first message, and the main agent's sub-agent catalog shows inputs: customerId for every specialist.
To make conversations reproducible in Evaluation, load the entity in the main agent's
step_starthook withGetWithSnap, so that snapshots of the data are captured with the test case.
pre_tool_call flow returns BLOCK when tool_name is fabric and the command is not on an allow list.after hook on updateCreditCardLimit writes the arguments and result to an audit table.step_end flow verifies that the answer does not contain account numbers and, if it does, returns "Rewrite the answer without account numbers" as a continuation.on_error flow returns a localized message with a reference number.Next article: Sessions and Context
Hooks are Broadway flows that the runtime runs at defined points of a turn. They let you prepare the context, enforce rules around tool calls, validate the answer and control error messages — with the full power of Broadway and Fabric, and without changing the agent's prompt.
Hook flows also define the agent's inputs: the values a client must provide when it starts a conversation, such as the customer ID.
hooks:
step_start: Banking_CustomerStory
step_end: CheckAnswer
pre_tool_call: GuardTools
post_tool_call: AuditTools
on_error: FriendlyError
Each value is the name of one Broadway flow in the agent's Data Product, or LU__<lu>__<flow> for a flow in another Data Product.
In addition, every hook flow receives the agent inputs as externals.
Per-tool before and after hooks, configured on a single entry of tools:, use the pre_tool_call and post_tool_call contracts. See Tools.
Hooks fail closed: if a hook flow fails, the turn fails. A failing pre_tool_call hook blocks the tool call rather than allowing it. Keep hook flows simple and fast, and handle expected conditions inside the flow.
Each hook type has a pair of Broadway actors, found under the agent_hooks tag:
Place the input actor first and the output actor last, and map the output actor's ports to the flow's output externals as shown.
There is no input-parameter list in agent.yaml. Instead, the external inputs declared by the agent's hook flows are the agent's inputs:
agents web service (input_params), shown in the Studio New chat dialog (Agent inputs).initParams JSON object when calling the agent, for example {"customerId":"1001"}.Do not declare an external with a reserved name — query, step_id, sessionId, agentName, final_answer, tool_name, arguments, tool_call_id, iteration, result, duration_ms, error, default_error_message. Such inputs are ignored, with a warning in the log.
For a sub-agent, an input may also be supplied by the calling LLM in the task or delegate arguments, so hook externals are not a trustworthy source for authorization scope. The AgentInitParams actor returns the inputs that the client passed to the top-level agent, which the model can never change:
initParams — the full map; add an output named after a key (for example customerId) to read it directly.sessionId, stepId, agentName, luName.Use AgentInitParams in any hook or tool flow that needs the customer identity for data access. It works in flows that the runtime calls directly, not in their inner flows.
The most common hook loads the entity the conversation is about, so the query tool works on its data. In the banking demo:
step_start flow, Banking_CustomerStory, declares the mandatory external customerId, loads the customer instance with the GetWithSnap actor (which also supports evaluation snapshots), builds a short customer profile, and returns it together with the user's message as result.step_start flow, LoadCustomerScope, declares the mandatory customerId and loads the instance with FabricGet.Because both flows declare customerId as mandatory, the client must choose the customer before the first message, and the main agent's sub-agent catalog shows inputs: customerId for every specialist.
To make conversations reproducible in Evaluation, load the entity in the main agent's
step_starthook withGetWithSnap, so that snapshots of the data are captured with the test case.
pre_tool_call flow returns BLOCK when tool_name is fabric and the command is not on an allow list.after hook on updateCreditCardLimit writes the arguments and result to an audit table.step_end flow verifies that the answer does not contain account numbers and, if it does, returns "Rewrite the answer without account numbers" as a continuation.on_error flow returns a localized message with a reference number.Next article: Sessions and Context