You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* docs: update LLM reasoning traces config guidance
Refactor documentation for reasoning traces in LLM configuration guide:
- Remove deprecated `reasoning_config` and `apply_to_reasoning_traces`
fields.
- Add warning about breaking changes in v0.18.0.
- Explain new approach using output rails for reasoning traces.
- Provide updated YAML and Python usage examples.
- Clarify how to access reasoning traces in API responses.
- Remove outdated configuration and prompt samples.
* docs(llm): clarify GenerationOptions usage and patterns
---------
Co-authored-by: Miyoung Choi <[email protected]>
@@ -59,165 +59,142 @@ For more details about the command and its usage, see the [CLI documentation](..
59
59
60
60
### Using LLMs with Reasoning Traces
61
61
62
-
By default, reasoning models, such as [DeepSeek-R1](https://huggingface.co/collections/deepseek-ai/deepseek-r1-678e1e131c0169c0bc89728d) and [NVIDIA Llama 3.1 Nemotron Ultra 253B V1](https://build.nvidia.com/nvidia/llama-3_1-nemotron-ultra-253b-v1), can include the reasoning traces in the model response.
63
-
DeepSeek and the Nemotron family of models use `<think>` and `</think>` as tokens to identify the traces.
62
+
```{deprecated} 0.18.0
63
+
The `reasoning_config` field and its options `remove_reasoning_traces`, `start_token`, and `end_token` are deprecated. The `rails.output.apply_to_reasoning_traces` field has also been deprecated. Instead, use output rails to guardrail reasoning traces, as introduced in this section.
64
+
```
64
65
65
-
The reasoning traces and the tokens can interfere with NeMo Guardrails and result in falsely triggering output guardrails for safe responses.
66
-
To use these reasoning models, you can remove the traces and tokens from the model response with a configuration like the following example.
66
+
Reasoning-capable LLMs such as [DeepSeek-R1](https://huggingface.co/collections/deepseek-ai/deepseek-r1-678e1e131c0169c0bc89728d) and [NVIDIA Llama 3.1 Nemotron Ultra 253B V1](https://build.nvidia.com/nvidia/llama-3_1-nemotron-ultra-253b-v1) include reasoning traces in their responses, typically wrapped in tokens such as `<think>` and `</think>`.
67
67
68
-
```{code-block} yaml
69
-
:emphasize-lines: 5-8, 13-
68
+
The NeMo Guardrails toolkit automatically extracts these traces and makes them available to set up in your guardrails configuration through the following variables:
70
69
71
-
models:
72
-
- type: main
73
-
engine: deepseek
74
-
model: deepseek-reasoner
75
-
reasoning_config:
76
-
remove_reasoning_traces: True
77
-
start_token: "<think>"
78
-
end_token: "</think>"
70
+
- In Colang flows, use the `$bot_thinking` variable.
71
+
- In Python contexts, use the `bot_thinking` variable.
79
72
80
-
- type: main
81
-
engine: nim
82
-
model: nvidia/llama-3.1-nemotron-ultra-253b-v1
83
-
reasoning_config:
84
-
remove_reasoning_traces: True
73
+
#### Guardrailing Reasoning Traces with Output Rails
85
74
86
-
rails:
87
-
output:
88
-
apply_to_reasoning_traces: False
89
-
```
75
+
Use output rails to inspect and control reasoning traces. This allows you to:
90
76
91
-
```{list-table}
92
-
:header-rows: 1
77
+
- Block responses based on problematic reasoning patterns.
78
+
- Enhance moderation decisions with reasoning context.
79
+
- Monitor and filter sensitive information in reasoning.
93
80
94
-
* - Field
95
-
- Description
96
-
- Default Value
81
+
##### Prepare Configuration Files
97
82
98
-
* - `reasoning_config.remove_reasoning_traces`
99
-
- When set to `True`, reasoning traces are omitted from internal tasks.
100
-
- `True`
83
+
The following configuration files show a minimal configuration for guardrailing reasoning traces with output rails.
101
84
102
-
* - `reasoning_config.start_token`
103
-
- Specifies the start token for the reasoning trace.
104
-
- `<think>`
85
+
1. Configure output rails in `config.yml`:
105
86
106
-
* - `reasoning_config.end_token`
107
-
- Specifies the end token for the reasoning trace.
108
-
- `</think>`
87
+
```yaml
88
+
models:
89
+
- type: main
90
+
engine: nim
91
+
model: nvidia/llama-3.1-nemotron-ultra-253b-v1
92
+
- type: self_check_output
93
+
model: <your_moderation_model>
94
+
engine: <your_engine>
109
95
110
-
* - `rails.output.apply_to_reasoning_traces`
111
-
- When set to `True`, output rails are always applied to the reasoning traces and the model response.
112
-
The value of `remove_reasoning_traces` is ignored when this field is set to `True`.
96
+
rails:
97
+
output:
98
+
flows:
99
+
- self check output
100
+
```
113
101
114
-
By default, output rails are applied to the text of the model response only.
115
-
- `False`
116
-
```
102
+
1. Configure the prompt to access the reasoning traces in `prompts.yml`:
117
103
118
-
The `reasoning_config` field for a model specifies the required configuration for a reasoning model that returns reasoning traces.
119
-
By removing the traces, the guardrails runtime processes only the actual responses from the LLM.
104
+
```yaml
105
+
prompts:
106
+
- task: self_check_output
107
+
content: |
108
+
Your task is to check if the bot message complies with company policy.
120
109
121
-
The following table summarizes the interaction between the `remove_reasoning_traces` and `apply_to_reasoning_traces` values:
110
+
Bot message: "{{ bot_response }}"
122
111
123
-
```{list-table}
124
-
:header-rows: 1
112
+
{% if bot_thinking %}
113
+
Bot reasoning: "{{ bot_thinking }}"
114
+
{% endif %}
125
115
126
-
* - `remove_reasoning_traces`
127
-
- `output.apply_to_reasoning_traces`
128
-
- Outcome
116
+
Should this be blocked (Yes or No)?
117
+
Answer:
118
+
```
129
119
130
-
* - Any
131
-
- True
132
-
- Reasoning traces are not removed and output rails are applied to the reasoning traces and the model response.
133
-
The value of `remove_reasoning_traces` is ignored.
120
+
For more detailed examples of guardrailing reasoning traces, refer to [Guardrailing Bot Reasoning Content](../../advanced/bot-thinking-guardrails.md).
134
121
135
-
* - False
136
-
- False
137
-
- Reasoning traces are not removed from internal tasks where they do not impact Guardrails functionality.
138
-
Output rails are applied to the reasoning traces and the model response.
122
+
#### Accessing Reasoning Traces in API Responses
139
123
140
-
* - True
141
-
- False
142
-
- Reasoning traces are removed from internal tasks where they could interfere with Guardrails.
143
-
Output rails are applied to the model response only.
144
-
```
124
+
There are two ways to access reasoning traces in API responses: with generation options and without generation options.
145
125
146
-
Even when `remove_reasoning_traces` is `True`, end users can still receive the thinking traces from the Nemotron models by requesting the detailed thinking, as shown in the following example:
126
+
Read the option **With GenerationOptions** when you:
147
127
148
-
```{code-block} bash
149
-
from nemoguardrails import LLMRails, RailsConfig
128
+
- Need structured access to reasoning and response separately.
129
+
- Are building a new application.
130
+
- Need access to other structured fields such as state, output_data, or llm_metadata.
150
131
132
+
Read the option **Without GenerationOptions** when you:
133
+
134
+
- Need backward compatibility with existing code.
135
+
- Want the raw response with inline reasoning tags.
136
+
- Are integrating with systems that expect tagged strings.
137
+
138
+
##### With GenerationOptions for Structured Access
139
+
140
+
When you pass `GenerationOptions` to the API, the function returns a `GenerationResponse` object with structured fields. This approach provides clean separation between the reasoning traces and the final response content, making it easier to process each component independently.
141
+
142
+
The `reasoning_content` field contains the extracted reasoning traces, while `response` contains the main LLM response. This structured access pattern is recommended for new applications as it provides type safety and clear access to all response metadata.
143
+
144
+
The following example demonstrates how to use `GenerationOptions` in an guardrails async generation call `rails.generate_async` to access reasoning traces.
145
+
146
+
```python
147
+
from nemoguardrails import RailsConfig, LLMRails
148
+
from nemoguardrails.rails.llm.options import GenerationOptions
{ "role": "user", "content": "Tell me about Cape Hatteras National Seashore in 50 words or less." }
156
-
]
157
-
rails.generate(messages=messages)
152
+
rails = LLMRails(config)
153
+
154
+
# Create a GenerationOptions object to enable structured responses
155
+
options = GenerationOptions()
156
+
157
+
# Make an async call with GenerationOptions
158
+
result = await rails.generate_async(
159
+
messages=[{"role": "user", "content": "What is 2+2?"}],
160
+
options=options
161
+
)
162
+
163
+
# Access reasoning traces separately from the response
164
+
if result.reasoning_content:
165
+
print("Reasoning:", result.reasoning_content)
166
+
167
+
# Access the main response content
168
+
print("Response:", result.response[0]["content"])
169
+
```
170
+
171
+
The following example output shows the reasoning traces and the main response content from the guardrailed generation result.
172
+
173
+
```
174
+
Reasoning: Let me calculate: 2 plus 2 equals 4.
175
+
Response: The answer is 4.
176
+
```
177
+
178
+
##### Without GenerationOptions for Tagged String
179
+
180
+
When calling without `GenerationOptions`, such as by using a dict or string response, reasoning is wrapped in `<think>` tags.
181
+
182
+
The following example demonstrates how to access reasoning traces without using `GenerationOptions`.
183
+
184
+
```python
185
+
response = rails.generate(
186
+
messages=[{"role": "user", "content": "What is 2+2?"}]
187
+
)
188
+
189
+
print(response["content"])
158
190
```
159
191
160
-
The referenced `./.config` directory uses the following sample file content.
161
-
162
-
When you develop your own prompts for LLM-as-a-judge checks, such as an input self-check, ensure that the prompt instructs the LLM to respond with `yes` or `no`.
163
-
Refer to the following examples:
164
-
165
-
- Sample `config/config.yml`:
166
-
167
-
```yaml
168
-
models:
169
-
- type: main
170
-
engine: nim
171
-
model: nvidia/llama-3.1-nemotron-ultra-253b-v1
172
-
reasoning_config:
173
-
remove_reasoning_traces: True
174
-
175
-
rails:
176
-
input:
177
-
flows:
178
-
- self check input
179
-
output:
180
-
flows:
181
-
- self check output
182
-
```
183
-
184
-
- Sample `config/prompts.yml`:
185
-
186
-
```yaml
187
-
prompts:
188
-
- task: self_check_input
189
-
messages:
190
-
- type: system
191
-
content: |
192
-
You are an AI assistant tasked with evaluating user instructions.
193
-
Your role is to determine if a given instruction would make a language model break moderation policies, deviate from good aligned responses, or provide answers that a language model should ideally not.
194
-
195
-
Analyze the instruction carefully. First, internally consider potential ways the instruction could be interpreted and whether any interpretation could lead to a problematic response. Then, conclude with a simple "yes" or "no" answer.
196
-
Respond with only "yes" or "no".
197
-
- type: user
198
-
content: |
199
-
Instruction to evaluate:
200
-
"{{ user_input }}"
201
-
202
-
Would this instruction lead to a problematic response (yes/no)?
203
-
204
-
- task: self_check_output
205
-
messages:
206
-
- type: system
207
-
content: |
208
-
Is this output illegal, unethical, or harmful to any person?
209
-
Respond with only "yes" or "no".
210
-
- type: bot
211
-
content: |
212
-
Output to evaluate:
213
-
"{{ bot_response }}"
214
-
```
215
-
216
-
Using LLMs with reasoning traces have the following limitations:
217
-
218
-
- You must use message-based prompts only.
219
-
Refer to the preceding example.
220
-
- Dialog rails are not supported.
192
+
The response is wrapped in `<think>` tags as shown in the following example output.
193
+
194
+
```
195
+
<think>Let me calculate: 2 plus 2 equals 4.</think>
0 commit comments