Generation Options Reference
Generation options let you control which rails run, which parameters the main large language model (LLM) receives, and which context and logging data the NVIDIA NeMo Guardrails library returns.
To use generation options, provide the options keyword argument to the generate() or generate_async() methods:
Generation options are also available through Chat Completions: Control Generation Options.
Engine Support
Both the LLMRails and IORails engines accept generation options, and both return a structured GenerationResponse object when you pass options.
Because IORails does not run the Colang runtime, the options that read or write Colang state are unavailable on it, and a few GenerationResponse fields are built differently.
Each section below documents the shared behavior first and then the IORails difference.
For the complete field-by-field comparison, refer to IORails and LLMRails Differences.
Passing options to generate() or generate_async() on IORails returns a GenerationResponse object instead of an OpenAI-style message dictionary.
This behavior also applies to a Guardrails facade that selected IORails.
Earlier versions honored the llm_params and rail toggles inside options but always returned a message dictionary.
Update code that reads result["content"] to read result.response[0]["content"].
An empty options={} behaves differently on the two engines.
IORails treats it as an all-defaults GenerationOptions and returns a GenerationResponse.
LLMRails raises TypeError, because an empty dictionary is falsy and does not match its dictionary branch.
Pass options=GenerationOptions() when you want the structured return with default settings on either engine.
Disabling Rails
Use the rails generation option to choose which rail categories to apply.
The supported categories are input, output, dialog, retrieval, tool_input, and tool_output.
By default, all categories are enabled.
IORails runs input, output, and tool rails only.
It ignores the dialog and retrieval categories rather than raising, because a configuration that declares dialog or retrieval rails routes to LLMRails in the first place.
runs the same rails as:
The two calls return different types because passing options selects the structured GenerationResponse return.
The list form is exhaustive: every category you leave out of the list is disabled. To disable one category and keep the rest, use the dictionary form instead.
The rails-only patterns in the following three sections depend on disabling the dialog rails.
This setting suppresses the main LLM call and echoes the supplied message back as the response.
That behavior is specific to LLMRails.
IORails has no dialog rails to disable, so it always calls the main model and returns a generated answer.
To validate messages without generating on either engine, use check() and check_async() instead.
Input Rails Only
To check a user’s input with only the input rails from a guardrails configuration, disable all other rail categories:
The response will be the same string if the input was allowed “as is”:
If some of the rails alter the input, for example, to mask sensitive information, then the returned value is the altered input.
If the input was blocked, you will get the predefined response bot refuse to respond (by default “I’m sorry, I can’t respond to that”).
For more details on what rails was triggered, use the log.activated_rails generation option.
Input and Output Rails Only
If you want to check both the user input and an output that was generated outside of the guardrails configuration, you must disable the dialog rails and the retrieval rails, and provide a bot message as well when making the call:
The response will be the exact bot message provided, if allowed, an altered version if an output rail decides to change it, for example, to remove sensitive information, or the predefined message for bot refuse to respond, if the message was blocked.
For receive details on what rails are triggered, use the log.activated_rails generation option.
Worked Example: Compare All Rails to Input and Output Rails
The topical rails tutorial uses an ABC bot configuration with input, dialog, generation, and output rails. When all rails are enabled, a simple greeting can activate several rails and trigger multiple LLM calls:
The explain() method can show the corresponding LLM call count:
If you only need to validate an already-generated assistant message, provide both the user and assistant messages and set options={"rails": ["input", "output"]}.
This skips dialog, retrieval, and generation rails while still applying the configured input and output checks.
For validation-only use cases, prefer the check() and check_async() APIs, which run input and output rails without invoking full generation.
Output Rails Only
To apply output rails exclusively to an LLM response, disable the input rails and provide an empty input.
Detailed Logging Information
You can obtain detailed information about what happened under the hood during the generation process by setting the log generation option. This option has four different inner-options:
activated_rails: Include detailed information about the rails that were activated during generation.llm_calls: Include the prompt, completion, timing, token usage, request ID, model, and provider information available for each LLM call.internal_events: Include the array of internal generated events.colang_history: Include the history of the conversation in Colang format.
When using the Python API, the log is an object that also has a print_summary method. When called, it will print a simplified version of the log information. Below is a sample output.
Log Options on IORails
IORails supports activated_rails and llm_calls, and it includes stats whenever you request either one, exactly as LLMRails does.
internal_events and colang_history describe Colang runtime state, so IORails raises NotImplementedError when you set either to True rather than returning an empty value.
The following example requests the supported log fields:
IORails synthesizes the log from the record each rail leaves behind, so the structure matches LLMRails but the contents reflect the way IORails executes rails:
- Each activated rail carries exactly one
ExecutedAction, holding the rail’s structured verdict inreturn_valueand up to one LLM or API call.IORailsruns one model-backed check per rail instead of a Colang action chain. activated_rails[].decisionsis always an empty list, because decisions are a Colang construct.- The main model call appears as a rail with
typegeneration,namegeneration, and action namegenerate_bot_message. OnLLMRailsthe equivalent entries come from the Colang dialog rails, such asgenerate user intent. llm_calls[].promptis the conversation serialized as"<role>: <content>"lines. The content matches whatLLMRailslogs, but the formatting differs.- Each call record includes timing and the request ID, token usage, model name, and provider name available from the provider.
The
statsobject aggregates the available values the same way asLLMRails. - A request stopped by a rail still returns the log for the rails that ran before processing stopped.
Output Variables
Output variables are an LLMRails capability.
IORails raises ValueError when you pass output_vars, and its GenerationResponse.output_data is always None.
There is no Colang context for IORails to read.
Some rails can store additional information in Colang 1.0 Language Syntax: Variables. You can return the content of these variables by setting the output_vars generation option to the list of names for all the variables that you are interested in. If you want to return the complete context (this will also include some predefined variables), you can set output_vars to True.
You can find the returned data in the output_data key of the response:
Additional LLM Parameters
To supply additional parameters to the LLM call during final message generation, utilize the llm_params option. The following example demonstrates how to apply a lower value for temperature:
The available parameters are determined by the specific LLM engine in use. The NeMo Guardrails library transmits values defined in the options parameter without modification.
Both engines apply llm_params to the main model call only, not to the models that back the rails.
IORails also accepts llm_params in stream_async(), and it is the supported way to pass tool definitions to the main model.
Additional LLM Output
You can receive additional output from the LLM generation by setting llm_output to True through the options parameter.
GenerationResponse.llm_output is currently None on both engines.
It is populated from LLMCallInfo.raw_response, which no code path assigns.
IORails accepts llm_output: True and ignores it.
To inspect provider-specific response data, use llm_metadata or the log.llm_calls entries instead.
IORails and LLMRails Differences
This section collects the differences between the two engines in one place. For capability differences outside generation options, refer to Engine Feature Support.
Method Signature
IORails.generate() and IORails.generate_async() take the same first three parameters as LLMRails.
Three argument-handling details differ from LLMRails:
- When you pass both
promptandmessages,IORailsusesmessagesand ignoresprompt.LLMRailsraisesValueError. - When you pass a
promptandoptions,LLMRailssetsGenerationResponse.responseto a plain string.IORailsalways sets it to a one-element list holding the assistant message. - An empty
options={}returns aGenerationResponseonIORailsand raisesTypeErroronLLMRails. Passoptions=GenerationOptions()for the structured return with default settings on either engine.
Passing a message list as the first positional argument raises TypeError on IORails, because that slot is prompt.
Pass the list with the messages= keyword.
IORails does not support the state and streaming_handler keyword arguments that LLMRails accepts.
state raises ValueError, because IORails is a stateless input and output rails engine with nothing to persist or resume.
streaming_handler is accepted and ignored.
Use stream_async() to stream from IORails.
GenerationOptions Support
stream_async() accepts options too, but reads only a subset of it and never yields a GenerationResponse.
Refer to Generation Options and Streaming.
Legend: ✓ supported · ✗ not supported (raises) · ◐ accepted but not populated · N/A not applicable to the engine.
The following table compares generation option support for generate() and generate_async():
IORails raises for Colang-dependent options that it cannot honor, including output_vars, log.internal_events, and log.colang_history.
It accepts and ignores llm_output, rails.dialog, and rails.retrieval.
state is a generate() keyword argument rather than a GenerationOptions field.
enforce is commented out in the source and is not a live field on either engine.
GenerationLogOptions Support
The following table compares generation log field support:
GenerationLog.stats is not a GenerationLogOptions field.
Both engines populate it whenever you request either activated_rails or llm_calls.
For the IORails log structure and how it differs from the Colang-derived log, refer to Log Options on IORails.
GenerationResponse Field Support
stream_async() never yields or returns a GenerationResponse on either engine.
The following table compares the fields returned when you pass options to generate() or generate_async():
Reasoning bypasses the output rails on both engines, so output rails check the final answer rather than the reasoning trace.
Requests Stopped by Rails
When a rail blocks content, LLMRails returns the configured refusal message in response.
IORails returns its fixed refusal message for a policy block and an internal-error message for a rail execution failure.
In either IORails case, tool_calls, reasoning_content, and llm_metadata are None.
To inspect records through the rail that stopped processing, request log.activated_rails.
That rail has stop set to True, and its action’s return_value["failed"] value distinguishes a failure from a policy block.
Limitations
- Only supported for the
generate/generate_asyncmethods (not forgenerate_events/generate_events_async). - On
LLMRails, specifying which individual rails of a particular type to activate is not yet supported.IORailssupports it: pass a list of rail names torails.input,rails.output,rails.tool_input, orrails.tool_output. - On
LLMRailswith a Colang 2.x configuration,output_vars,log, andllm_outputraiseValueError.